=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.179 retrieving revision 1.187 diff -u -p -r1.179 -r1.187 --- mandoc/mdoc_validate.c 2011/11/19 13:29:47 1.179 +++ mandoc/mdoc_validate.c 2012/07/12 15:11:14 1.187 @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.179 2011/11/19 13:29:47 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.187 2012/07/12 15:11:14 schwarze Exp $ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2011 Ingo Schwarze + * Copyright (c) 2008-2012 Kristaps Dzonsons + * Copyright (c) 2010, 2011, 2012 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -314,12 +314,12 @@ static const enum mdoct rsord[RSORD_MAX] = { MDOC__R, MDOC__N, MDOC__V, + MDOC__U, MDOC__P, MDOC__Q, MDOC__D, MDOC__O, - MDOC__C, - MDOC__U + MDOC__C }; static const char * const secnames[SEC__MAX] = { @@ -661,8 +661,13 @@ pre_bl(PRE_ARGS) comp = 1; break; case (MDOC_Width): - dup = (NULL != n->norm->Bl.width); - width = n->args->argv[i].value[0]; + /* NB: this can be empty! */ + if (n->args->argv[i].sz) { + width = n->args->argv[i].value[0]; + dup = (NULL != n->norm->Bl.width); + break; + } + mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); break; case (MDOC_Offset): /* NB: this can be empty! */ @@ -728,14 +733,14 @@ pre_bl(PRE_ARGS) /* * Validate the width field. Some list types don't need width * types and should be warned about them. Others should have it - * and must also be warned. + * and must also be warned. Yet others have a default and need + * no warning. */ switch (n->norm->Bl.type) { case (LIST_tag): - if (n->norm->Bl.width) - break; - mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG); + if (NULL == n->norm->Bl.width) + mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG); break; case (LIST_column): /* FALLTHROUGH */ @@ -749,6 +754,18 @@ pre_bl(PRE_ARGS) if (n->norm->Bl.width) mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); break; + case (LIST_bullet): + /* FALLTHROUGH */ + case (LIST_dash): + /* FALLTHROUGH */ + case (LIST_hyphen): + if (NULL == n->norm->Bl.width) + n->norm->Bl.width = "2n"; + break; + case (LIST_enum): + if (NULL == n->norm->Bl.width) + n->norm->Bl.width = "3n"; + break; default: break; } @@ -1106,24 +1123,29 @@ post_nm(POST_ARGS) char buf[BUFSIZ]; int c; - /* If no child specified, make sure we have the meta name. */ - - if (NULL == mdoc->last->child && NULL == mdoc->meta.name) { - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME); + if (NULL != mdoc->meta.name) return(1); - } else if (mdoc->meta.name) - return(1); - /* If no meta name, set it from the child. */ + /* Try to use our children for setting the meta name. */ - buf[0] = '\0'; - if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) { + 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): + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME); + mdoc->meta.name = mandoc_strdup("UNKNOWN"); + break; + default: + mdoc->meta.name = mandoc_strdup(buf); + break; } - - assert(c); - mdoc->meta.name = mandoc_strdup(buf); return(1); } @@ -1826,6 +1848,7 @@ static int post_sh_head(POST_ARGS) { char buf[BUFSIZ]; + struct mdoc_node *n; enum mdoc_sec sec; int c; @@ -1860,6 +1883,20 @@ post_sh_head(POST_ARGS) mdoc->lastsec = sec; + /* + * Set the section attribute for the current HEAD, for its + * parent BLOCK, and for the HEAD children; the latter can + * only be TEXT nodes, so no recursion is needed. + * For other blocks and elements, including .Sh BODY, this is + * done when allocating the node data structures, but for .Sh + * BLOCK and HEAD, the section is still unknown at that time. + */ + + mdoc->last->parent->sec = sec; + mdoc->last->sec = sec; + for (n = mdoc->last->child; n; n = n->next) + n->sec = sec; + /* We don't care about custom sections after this. */ if (SEC_CUSTOM == sec) @@ -2084,7 +2121,7 @@ post_dt(POST_ARGS) * arch = NULL */ - cp = mdoc_a2msec(nn->string); + cp = mandoc_a2msec(nn->string); if (cp) { mdoc->meta.vol = mandoc_strdup(cp); mdoc->meta.msec = mandoc_strdup(nn->string); @@ -2172,14 +2209,15 @@ post_os(POST_ARGS) n = mdoc->last; /* - * Set the operating system by way of the `Os' macro. Note that - * if an argument isn't provided and -DOSNAME="\"foo\"" is - * provided during compilation, this value will be used instead - * of filling in "sysname release" from uname(). + * Set the operating system by way of the `Os' macro. + * The order of precedence is: + * 1. the argument of the `Os' macro, unless empty + * 2. the -Ios=foo command line argument, if provided + * 3. -DOSNAME="\"foo\"", if provided during compilation + * 4. "sysname release" from uname(3) */ - if (mdoc->meta.os) - free(mdoc->meta.os); + free(mdoc->meta.os); buf[0] = '\0'; if (-1 == (c = concat(buf, n->child, BUFSIZ))) { @@ -2189,11 +2227,11 @@ post_os(POST_ARGS) assert(c); - /* XXX: yes, these can all be dynamically-adjusted buffers, but - * it's really not worth the extra hackery. - */ - 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);