=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.196 retrieving revision 1.209 diff -u -p -r1.196 -r1.209 --- mandoc/mdoc_validate.c 2013/10/06 22:46:15 1.196 +++ mandoc/mdoc_validate.c 2014/04/15 00:41:09 1.209 @@ -1,7 +1,8 @@ -/* $Id: mdoc_validate.c,v 1.196 2013/10/06 22:46:15 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.209 2014/04/15 00:41:09 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze + * Copyright (c) 2010-2014 Ingo Schwarze + * Copyright (c) 2010 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,6 +36,7 @@ #include "mdoc.h" #include "mandoc.h" +#include "mandoc_aux.h" #include "libmdoc.h" #include "libmandoc.h" @@ -44,7 +46,6 @@ #define POST_ARGS struct mdoc *mdoc #define NUMSIZ 32 -#define DATESIZE 32 enum check_ineq { CHECK_LT, @@ -72,7 +73,6 @@ static void check_text(struct mdoc *, int, int, char 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); @@ -304,6 +304,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, posts_sp }, /* sp */ { NULL, posts_text1 }, /* %U */ { NULL, NULL }, /* Ta */ + { NULL, NULL }, /* ll */ }; #define RSORD_MAX 14 /* Number of `Rs' blocks. */ @@ -331,6 +332,7 @@ static const char * const secnames[SEC__MAX] = { "LIBRARY", "SYNOPSIS", "DESCRIPTION", + "CONTEXT", "IMPLEMENTATION NOTES", "RETURN VALUES", "ENVIRONMENT", @@ -1121,31 +1123,15 @@ post_vt(POST_ARGS) 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); } @@ -1674,10 +1660,16 @@ ebool(struct mdoc *mdoc) assert(MDOC_TEXT == mdoc->last->child->type); - if (0 == strcmp(mdoc->last->child->string, "on")) + if (0 == strcmp(mdoc->last->child->string, "on")) { + if (MDOC_Sm == mdoc->last->tok) + mdoc->flags &= ~MDOC_SMOFF; return(1); - if (0 == strcmp(mdoc->last->child->string, "off")) + } + if (0 == strcmp(mdoc->last->child->string, "off")) { + if (MDOC_Sm == mdoc->last->tok) + mdoc->flags |= MDOC_SMOFF; return(1); + } mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL); return(1); @@ -1887,7 +1879,7 @@ post_hyph(POST_ARGS) if (MDOC_TEXT != nch->type) continue; cp = nch->string; - if (3 > strnlen(cp, 3)) + if ('\0' == *cp) continue; while ('\0' != *(++cp)) if ('-' == *cp && @@ -1957,10 +1949,9 @@ post_sh_body(POST_ARGS) 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 @@ -1969,13 +1960,10 @@ post_sh_head(POST_ARGS) * 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. */ @@ -1985,10 +1973,10 @@ post_sh_head(POST_ARGS) /* The SYNOPSIS gets special attention in other areas. */ if (SEC_SYNOPSIS == sec) { - roff_setreg(mdoc->roff, "nS", 1); + roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; } else { - roff_setreg(mdoc->roff, "nS", 0); + roff_setreg(mdoc->roff, "nS", 0, '='); mdoc->flags &= ~MDOC_SYNOPSIS; } @@ -2012,8 +2000,10 @@ post_sh_head(POST_ARGS) /* 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 @@ -2035,24 +2025,29 @@ post_sh_head(POST_ARGS) 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); } @@ -2168,30 +2163,28 @@ pre_literal(PRE_ARGS) 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); n = mdoc->last; if (NULL == n->child || '\0' == n->child->string[0]) { - mdoc->meta.date = mandoc_normdate - (mdoc->parse, NULL, n->line, n->pos); + mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : + mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); 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 = mandoc_normdate - (mdoc->parse, buf, n->line, n->pos); - return(1); } @@ -2341,12 +2334,11 @@ post_bx(POST_ARGS) static int post_os(POST_ARGS) { - struct mdoc_node *n; - char buf[BUFSIZ]; - int c; #ifndef OSNAME struct utsname utsname; + static char *defbuf; #endif + struct mdoc_node *n; n = mdoc->last; @@ -2360,48 +2352,29 @@ post_os(POST_ARGS) */ free(mdoc->meta.os); + mdoc->meta.os = NULL; + mdoc_deroff(&mdoc->meta.os, n); + if (mdoc->meta.os) + return(1); - buf[0] = '\0'; - if (-1 == (c = concat(buf, n->child, BUFSIZ))) { - mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM); - return(0); + if (mdoc->defos) { + mdoc->meta.os = mandoc_strdup(mdoc->defos); + return(1); } - assert(c); - - if ('\0' == buf[0]) { - if (mdoc->defos) { - mdoc->meta.os = mandoc_strdup(mdoc->defos); - return(1); - } #ifdef OSNAME - if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) { - mdoc_nmsg(mdoc, n, MANDOCERR_MEM); - return(0); - } + mdoc->meta.os = mandoc_strdup(OSNAME); #else /*!OSNAME */ + if (NULL == defbuf) { if (-1 == uname(&utsname)) { mdoc_nmsg(mdoc, n, MANDOCERR_UNAME); - mdoc->meta.os = mandoc_strdup("UNKNOWN"); - return(post_prol(mdoc)); - } - - if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) { - mdoc_nmsg(mdoc, n, MANDOCERR_MEM); - return(0); - } - if (strlcat(buf, " ", BUFSIZ) >= BUFSIZ) { - mdoc_nmsg(mdoc, n, MANDOCERR_MEM); - return(0); - } - if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) { - mdoc_nmsg(mdoc, n, MANDOCERR_MEM); - return(0); - } -#endif /*!OSNAME*/ + defbuf = mandoc_strdup("UNKNOWN"); + } else + mandoc_asprintf(&defbuf, "%s %s", + utsname.sysname, utsname.release); } - - mdoc->meta.os = mandoc_strdup(buf); + mdoc->meta.os = mandoc_strdup(defbuf); +#endif /*!OSNAME*/ return(1); } @@ -2431,29 +2404,6 @@ post_std(POST_ARGS) return(0); mdoc->last = nn; - 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); }