=================================================================== RCS file: /cvs/mandoc/mdoc.c,v retrieving revision 1.38 retrieving revision 1.42 diff -u -p -r1.38 -r1.42 --- mandoc/mdoc.c 2009/01/19 17:53:54 1.38 +++ mandoc/mdoc.c 2009/01/20 13:49:36 1.42 @@ -1,4 +1,4 @@ -/* $Id: mdoc.c,v 1.38 2009/01/19 17:53:54 kristaps Exp $ */ +/* $Id: mdoc.c,v 1.42 2009/01/20 13:49:36 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -26,6 +26,12 @@ #include "private.h" +/* + * Main caller in the libmdoc library. This begins the parsing routine, + * handles allocation of data, and so forth. Most of the "work" is done + * in macro.c, but this orchestrates who does what, when. + */ + const char *const __mdoc_macronames[MDOC_MAX] = { "\\\"", "Dd", "Dt", "Os", "Sh", "Ss", "Pp", "D1", @@ -83,11 +89,13 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = { "emphasis", "symbolic", }; +/* Central table of library: who gets parsed how. */ + const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { NULL, 0 }, /* \" */ - { macro_constant, MDOC_PROLOGUE | MDOC_NOKEEP }, /* Dd */ - { macro_constant, MDOC_PROLOGUE | MDOC_NOKEEP }, /* Dt */ - { macro_constant, MDOC_PROLOGUE | MDOC_NOKEEP }, /* Os */ + { macro_constant, MDOC_PROLOGUE }, /* Dd */ + { macro_constant, MDOC_PROLOGUE }, /* Dt */ + { macro_constant, MDOC_PROLOGUE }, /* Os */ { macro_scoped, 0 }, /* Sh */ { macro_scoped, 0 }, /* Ss */ { macro_text, 0 }, /* Pp */ @@ -199,7 +207,6 @@ const char * const *mdoc_macronames = __mdoc_macroname const char * const *mdoc_argnames = __mdoc_argnames; const struct mdoc_macro * const mdoc_macros = __mdoc_macros; - static struct mdoc_arg *argdup(size_t, const struct mdoc_arg *); static void argfree(size_t, struct mdoc_arg *); static void argcpy(struct mdoc_arg *, @@ -295,14 +302,15 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) if (MDOC_HALT & mdoc->flags) return(0); + mdoc->linetok = 0; + if ('.' != *buf) { - if (SEC_PROLOGUE != mdoc->sec_lastn) { - if ( ! mdoc_word_alloc(mdoc, line, 0, buf)) - return(0); - mdoc->next = MDOC_NEXT_SIBLING; - return(1); - } - return(mdoc_perr(mdoc, line, 0, "text disallowed")); + if ( ! (MDOC_BODYPARSE & mdoc->flags)) + return(mdoc_perr(mdoc, line, 0, "text disallowed")); + if ( ! mdoc_word_alloc(mdoc, line, 0, buf)) + return(0); + mdoc->next = MDOC_NEXT_SIBLING; + return(1); } if (buf[1] && '\\' == buf[1]) @@ -310,7 +318,7 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) return(1); i = 1; - while (buf[i] && ! isspace(buf[i]) && i < (int)sizeof(tmp)) + while (buf[i] && ! isspace((int)buf[i]) && i < (int)sizeof(tmp)) i++; if (i == (int)sizeof(tmp)) { @@ -331,7 +339,7 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) return(mdoc_perr(mdoc, line, 1, "unknown macro")); } - while (buf[i] && isspace(buf[i])) + while (buf[i] && isspace((int)buf[i])) i++; if ( ! mdoc_macro(mdoc, c, line, 1, &i, buf)) { @@ -400,8 +408,8 @@ mdoc_macro(struct mdoc *mdoc, int tok, assert(mdoc_macros[tok].fp); if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && - SEC_PROLOGUE == mdoc->sec_lastn) - return(mdoc_perr(mdoc, ln, ppos, "macro disallowed in document prologue")); + ! (MDOC_BODYPARSE & mdoc->flags)) + return(mdoc_perr(mdoc, ln, ppos, "macro disallowed: not in document body")); if (1 != ppos && ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) return(mdoc_perr(mdoc, ln, ppos, "macro not callable")); return((*mdoc_macros[tok].fp)(mdoc, tok, ln, ppos, pos, buf)); @@ -416,6 +424,27 @@ mdoc_node_append(struct mdoc *mdoc, struct mdoc_node * assert(mdoc->last); assert(mdoc->first); assert(MDOC_ROOT != p->type); + + /* See if we exceed the suggest line-max. */ + + switch (p->type) { + case (MDOC_TEXT): + /* FALLTHROUGH */ + case (MDOC_ELEM): + /* FALLTHROUGH */ + case (MDOC_BLOCK): + mdoc->linetok++; + break; + default: + break; + } + + /* This sort-of works (re-opening of text macros...). */ + if (mdoc->linetok > MDOC_LINEARG_SOFTMAX) + if ( ! mdoc_nwarn(mdoc, p, WARN_COMPAT, + "suggested %d tokens per line exceeded (has %d)", + MDOC_LINEARG_SOFTMAX, mdoc->linetok)) + return(0); if (MDOC_TEXT == mdoc->last->type) on = "";