-/* $Id: mdoc_validate.c,v 1.202 2014/01/11 22:16:10 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.209 2014/04/15 00:41:09 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
#include "mdoc.h"
#include "mandoc.h"
+#include "mandoc_aux.h"
#include "libmdoc.h"
#include "libmandoc.h"
#define POST_ARGS struct mdoc *mdoc
#define NUMSIZ 32
-#define DATESIZE 32
enum check_ineq {
CHECK_LT,
static void check_argv(struct mdoc *,
struct mdoc_node *, struct mdoc_argv *);
static void check_args(struct mdoc *, struct mdoc_node *);
-static int concat(char *, const struct mdoc_node *, size_t);
static enum mdoc_sec a2sec(const char *);
static size_t macro2len(enum mdoct);
{ NULL, posts_sp }, /* sp */
{ NULL, posts_text1 }, /* %U */
{ NULL, NULL }, /* Ta */
+ { NULL, NULL }, /* ll */
};
#define RSORD_MAX 14 /* Number of `Rs' blocks. */
"LIBRARY",
"SYNOPSIS",
"DESCRIPTION",
+ "CONTEXT",
"IMPLEMENTATION NOTES",
"RETURN VALUES",
"ENVIRONMENT",
static int
post_nm(POST_ARGS)
{
- char buf[BUFSIZ];
- int c;
if (NULL != mdoc->meta.name)
return(1);
- /* Try to use our children for setting the meta name. */
+ mdoc_deroff(&mdoc->meta.name, mdoc->last);
- if (NULL != mdoc->last->child) {
- buf[0] = '\0';
- c = concat(buf, mdoc->last->child, BUFSIZ);
- } else
- c = 0;
-
- switch (c) {
- case (-1):
- mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);
- return(0);
- case (0):
+ if (NULL == mdoc->meta.name) {
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME);
mdoc->meta.name = mandoc_strdup("UNKNOWN");
- break;
- default:
- mdoc->meta.name = mandoc_strdup(buf);
- break;
}
return(1);
}
static int
post_sh_head(POST_ARGS)
{
- char buf[BUFSIZ];
struct mdoc_node *n;
+ char *secname;
enum mdoc_sec sec;
- int c;
/*
* Process a new section. Sections are either "named" or
* manual sections.
*/
+ secname = NULL;
sec = SEC_CUSTOM;
- buf[0] = '\0';
- if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) {
- mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);
- return(0);
- } else if (1 == c)
- sec = a2sec(buf);
+ mdoc_deroff(&secname, mdoc->last);
+ sec = NULL == secname ? SEC_CUSTOM : a2sec(secname);
/* The NAME should be first. */
/* We don't care about custom sections after this. */
- if (SEC_CUSTOM == sec)
+ if (SEC_CUSTOM == sec) {
+ free(secname);
return(1);
+ }
/*
* Check whether our non-custom section is being repeated or is
assert(mdoc->meta.msec);
switch (sec) {
- case (SEC_RETURN_VALUES):
- /* FALLTHROUGH */
case (SEC_ERRORS):
+ if (*mdoc->meta.msec == '4')
+ break;
+ /* FALLTHROUGH */
+ case (SEC_RETURN_VALUES):
/* FALLTHROUGH */
case (SEC_LIBRARY):
if (*mdoc->meta.msec == '2')
break;
if (*mdoc->meta.msec == '3')
break;
+ /* FALLTHROUGH */
+ case (SEC_CONTEXT):
if (*mdoc->meta.msec == '9')
break;
mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse,
- mdoc->last->line, mdoc->last->pos, buf);
+ mdoc->last->line, mdoc->last->pos, secname);
break;
default:
break;
}
+ free(secname);
return(1);
}
static int
post_dd(POST_ARGS)
{
- char buf[DATESIZE];
struct mdoc_node *n;
- int c;
+ char *datestr;
if (mdoc->meta.date)
free(mdoc->meta.date);
return(1);
}
- buf[0] = '\0';
- if (-1 == (c = concat(buf, n->child, DATESIZE))) {
- mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);
- return(0);
+ datestr = NULL;
+ mdoc_deroff(&datestr, n);
+ if (mdoc->quick)
+ mdoc->meta.date = datestr;
+ else {
+ mdoc->meta.date = mandoc_normdate(mdoc->parse,
+ datestr, n->line, n->pos);
+ free(datestr);
}
-
- assert(c);
- mdoc->meta.date = mdoc->quick ? mandoc_strdup(buf) :
- mandoc_normdate(mdoc->parse, buf, n->line, n->pos);
-
return(1);
}
static int
post_os(POST_ARGS)
{
- char buf[BUFSIZ];
#ifndef OSNAME
struct utsname utsname;
static char *defbuf;
#endif
struct mdoc_node *n;
- int c;
n = mdoc->last;
*/
free(mdoc->meta.os);
-
- buf[0] = '\0';
- if (-1 == (c = concat(buf, n->child, BUFSIZ))) {
- mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);
- return(0);
- }
-
- assert(c);
-
- if ('\0' != *buf) {
- mdoc->meta.os = mandoc_strdup(buf);
+ mdoc->meta.os = NULL;
+ mdoc_deroff(&mdoc->meta.os, n);
+ if (mdoc->meta.os)
return(1);
- }
if (mdoc->defos) {
mdoc->meta.os = mandoc_strdup(mdoc->defos);
if (-1 == uname(&utsname)) {
mdoc_nmsg(mdoc, n, MANDOCERR_UNAME);
defbuf = mandoc_strdup("UNKNOWN");
- } else if (-1 == asprintf(&defbuf, "%s %s",
- utsname.sysname, utsname.release)) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
+ } else
+ mandoc_asprintf(&defbuf, "%s %s",
+ utsname.sysname, utsname.release);
}
mdoc->meta.os = mandoc_strdup(defbuf);
#endif /*!OSNAME*/
return(1);
}
-/*
- * Concatenate a node, stopping at the first non-text.
- * Concatenation is separated by a single whitespace.
- * Returns -1 on fatal (string overrun) error, 0 if child nodes were
- * encountered, 1 otherwise.
- */
-static int
-concat(char *p, const struct mdoc_node *n, size_t sz)
-{
-
- for ( ; NULL != n; n = n->next) {
- if (MDOC_TEXT != n->type)
- return(0);
- if ('\0' != p[0] && strlcat(p, " ", sz) >= sz)
- return(-1);
- if (strlcat(p, n->string, sz) >= sz)
- return(-1);
- concat(p, n->child, sz);
- }
-
- return(1);
-}
-
static enum mdoc_sec
a2sec(const char *p)
{