]> git.cameronkatri.com Git - mandoc.git/blobdiff - main.c
Plan9 has a man(7) implementation that looks extremely archaic,
[mandoc.git] / main.c
diff --git a/main.c b/main.c
index b8f244168d2b82088218b6307614ff543612abb3..5e5080cca4c45b9d69e8b75e2de85ced0df086e1 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/*     $Id: main.c,v 1.115 2010/12/02 20:41:46 schwarze Exp $ */
+/*     $Id: main.c,v 1.127 2010/12/29 14:38:14 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -41,6 +41,7 @@
 #define        MAP_FILE        0
 #endif
 
+#define        REPARSE_LIMIT   1000
 #define        UNCONST(a)      ((void *)(uintptr_t)(const void *)(a))
 
 /* FIXME: Intel's compiler?  LLVM?  pcc?  */
@@ -89,6 +90,7 @@ struct        curparse {
        struct mdoc      *mdoc;         /* mdoc parser */
        struct roff      *roff;         /* roff parser (!NULL) */
        struct regset     regs;         /* roff registers */
+       int               reparse_count; /* finite interpolation stack */
        enum outt         outtype;      /* which output to use */
        out_mdoc          outmdoc;      /* mdoc output ptr */
        out_man           outman;       /* man output ptr */
@@ -122,71 +124,87 @@ static    const char * const      mandocerrs[MANDOCERR_MAX] = {
 
        "generic warning",
 
+       /* related to the prologue */
+       "no title in document",
+       "document title should be all caps",
+       "unknown manual section",
+       "cannot parse date argument",
+       "prologue macros out of order",
+       "duplicate prologue macro",
+       "macro not allowed in prologue",
+       "macro not allowed in body",
+
+       /* related to document structure */
        ".so is fragile, better use ln(1)",
-       "text should be uppercase",
+       "NAME section must come first",
+       "bad NAME section contents",
+       "manual name not yet set",
        "sections out of conventional order",
-       "section name repeats",
-       "out of order prologue",
-       "repeated prologue entry",
-       "list type must come first",
-       "tab in non-literal context",
-       "bad escape sequence",
-       "unterminated quoted string",
-       "argument requires the width argument",
-       "superfluous width argument",
-       "bad date argument",
-       "bad width argument",
-       "unknown manual section",
+       "duplicate section name",
        "section not in conventional manual section",
-       "end of line whitespace",
+
+       /* related to macros and nesting */
+       "skipping obsolete macro",
+       "skipping paragraph macro",
        "blocks badly nested",
+       "child violates parent syntax",
+       "nested displays are not portable",
+       "already in literal mode",
 
-       "generic error",
+       /* related to missing macro arguments */
+       "skipping empty macro",
+       "missing display type",
+       "list type must come first",
+       "tag lists require a width argument",
+       "missing font type",
 
-       "NAME section must come first",
+       /* related to bad macro arguments */
+       "skipping argument",
+       "duplicate argument",
+       "duplicate display type",
+       "duplicate list type",
+       "unknown AT&T UNIX version",
        "bad Boolean value",
-       "child violates parent syntax",
-       "bad AT&T symbol",
-       "bad standard",
-       "list type repeated",
-       "display type repeated",
-       "argument repeated",
-       "ignoring argument",
-       "manual name not yet set",
-       "obsolete macro ignored",
-       "empty macro ignored",
-       "macro not allowed in body",
-       "macro not allowed in prologue",
-       "bad character",
-       "bad NAME section contents",
-       "no blank lines",
-       "no text in this context",
+       "unknown font",
+       "unknown standard specifier",
+       "bad width argument",
+
+       /* related to plain text */
+       "blank line in non-literal context",
+       "tab in non-literal context",
+       "end of line whitespace",
        "bad comment style",
-       "unknown macro will be lost",
+       "unknown escape sequence",
+       "unterminated quoted string",
+
+       "generic error",
+
+       "bad table syntax",
+       "bad table option",
+       "bad table layout",
+       "no table layout cells specified",
+       "input stack limit exceeded, infinite loop?",
+       "skipping bad character",
+       "skipping text before the first section header",
+       "skipping unknown macro",
        "NOT IMPLEMENTED: skipping request",
        "line scope broken",
        "argument count wrong",
-       "request scope close w/none open",
-       "scope already open",
+       "skipping end of block that is not open",
+       "missing end of block",
        "scope open on exit",
+       "uname(3) system call failed",
        "macro requires line argument(s)",
        "macro requires body argument(s)",
        "macro requires argument(s)",
-       "no title in document",
        "missing list type",
-       "missing display type",
-       "missing font type",
        "line argument(s) will be lost",
        "body argument(s) will be lost",
-       "paragraph macro ignored",
 
        "generic fatal error",
 
        "column syntax is inconsistent",
-       "displays may not be nested",
-       "unsupported display type",
-       "blocks badly nested",
-       "no such block is open",
+       "NOT IMPLEMENTED: .Bd -file",
        "line scope broken, syntax violated",
        "argument count wrong, violates syntax",
        "child violates parent syntax",
@@ -194,7 +212,6 @@ static      const char * const      mandocerrs[MANDOCERR_MAX] = {
        "NOT IMPLEMENTED: .so with absolute path or \"..\"",
        "no document body",
        "no document prologue",
-       "utsname system call failed",
        "static buffer exhausted",
 };
 
@@ -376,7 +393,7 @@ static void
 resize_buf(struct buf *buf, size_t initial)
 {
 
-       buf->sz = buf->sz ? 2 * buf->sz : initial;
+       buf->sz = buf->sz > initial/2 ? 2 * buf->sz : initial;
        buf->buf = realloc(buf->buf, buf->sz);
        if (NULL == buf->buf) {
                perror(NULL);
@@ -655,8 +672,10 @@ parsebuf(struct curparse *curp, struct buf blk, int start)
                if (0 == pos && '\0' == blk.buf[i])
                        break;
 
-               if (start)
+               if (start) {
                        curp->line = lnn;
+                       curp->reparse_count = 0;
+               }
 
                while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {
                        if ('\n' == blk.buf[i]) {
@@ -755,7 +774,11 @@ rerun:
 
                switch (rr) {
                case (ROFF_REPARSE):
-                       parsebuf(curp, ln, 0);
+                       if (REPARSE_LIMIT >= ++curp->reparse_count)
+                               parsebuf(curp, ln, 0);
+                       else
+                               mmsg(MANDOCERR_ROFFLOOP, curp, 
+                                   curp->line, pos, NULL);
                        pos = 0;
                        continue;
                case (ROFF_APPEND):