]> git.cameronkatri.com Git - mandoc.git/blobdiff - man.c
Added some new manuals (mdoc.3 mandoc_char.7).
[mandoc.git] / man.c
diff --git a/man.c b/man.c
index d3223e6957f59da0c12449af5274a4bb4db189e8..56822f40b64fea5b1baa550e45b24c268603e247 100644 (file)
--- a/man.c
+++ b/man.c
@@ -1,4 +1,4 @@
-/* $Id: man.c,v 1.8 2009/03/25 21:46:24 kristaps Exp $ */
+/* $Id: man.c,v 1.13 2009/03/27 14:56:15 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
  *
@@ -31,7 +31,8 @@ const char *const __man_macronames[MAN_MAX] = {
        "TP",           "LP",           "PP",           "P",
        "IP",           "HP",           "SM",           "SB",
        "BI",           "IB",           "BR",           "RB",
-       "R",            "B",            "I",            "IR"
+       "R",            "B",            "I",            "IR",
+       "RI",           "br"
        };
 
 const  char * const *man_macronames = __man_macronames;
@@ -268,6 +269,25 @@ man_ptext(struct man *m, int line, char *buf)
        if ( ! man_word_alloc(m, line, 0, buf))
                return(0);
        m->next = MAN_NEXT_SIBLING;
+
+       /*
+        * If this is one of the zany NLINE macros that consumes the
+        * next line of input as being influenced, then close out the
+        * existing macro "scope" and continue processing.
+        */
+
+       if ( ! (MAN_NLINE & m->flags))
+               return(1);
+
+       m->flags &= ~MAN_NLINE;
+       m->last = m->last->parent;
+
+       assert(MAN_ROOT != m->last->type);
+       if ( ! man_valid_post(m))
+               return(0);
+       if ( ! man_action_post(m))
+               return(0);
+
        return(1);
 }
 
@@ -275,56 +295,65 @@ man_ptext(struct man *m, int line, char *buf)
 int
 man_pmacro(struct man *m, int ln, char *buf)
 {
-       int               i, c;
+       int               i, j, c, ppos, fl;
        char              mac[5];
+       struct man_node  *n;
 
        /* Comments and empties are quickly ignored. */
 
+       n = m->last;
+       fl = MAN_NLINE & m->flags;
+
        if (0 == buf[1])
-               return(1);
+               goto out;
 
-       if (' ' == buf[1]) {
-               i = 2;
+       i = 1;
+
+       if (' ' == buf[i]) {
+               i++;
                while (buf[i] && ' ' == buf[i])
                        i++;
                if (0 == buf[i])
-                       return(1);
-               return(man_vwarn(m, ln, 0, "invalid syntax"));
+                       goto out;
        }
 
-       if (buf[1] && '\\' == buf[1])
-               if (buf[2] && '\"' == buf[2])
-                       return(1);
+       ppos = i;
+
+       if (buf[i] && '\\' == buf[i])
+               if (buf[i + 1] && '\"' == buf[i + 1])
+                       goto out;
 
        /* Copy the first word into a nil-terminated buffer. */
 
-       for (i = 1; i < 5; i++) {
-               if (0 == (mac[i - 1] = buf[i]))
+       for (j = 0; j < 4; j++, i++) {
+               if (0 == (mac[j] = buf[i]))
                        break;
                else if (' ' == buf[i])
                        break;
        }
 
-       mac[i - 1] = 0;
+       mac[j] = 0;
 
-       if (i == 5 || i <= 1) {
+       if (j == 4 || j < 1) {
                if ( ! (MAN_IGN_MACRO & m->pflags)) {
-                       (void)man_verr(m, ln, 1
+                       (void)man_verr(m, ln, ppos
                                "ill-formed macro: %s", mac);
                        goto err;
                } 
-               if ( ! man_vwarn(m, ln, 1, "ill-formed macro: %s", mac))
+               if ( ! man_vwarn(m, ln, ppos, 
+                               "ill-formed macro: %s", mac))
                        goto err;
                return(1);
        }
        
        if (MAN_MAX == (c = man_hash_find(m->htab, mac))) {
                if ( ! (MAN_IGN_MACRO & m->pflags)) {
-                       (void)man_verr(m, ln, 1
+                       (void)man_verr(m, ln, ppos
                                "unknown macro: %s", mac);
                        goto err;
                } 
-               if ( ! man_vwarn(m, ln, 1, "unknown macro: %s", mac))
+               if ( ! man_vwarn(m, ln, ppos, 
+                               "unknown macro: %s", mac))
                        goto err;
                return(1);
        }
@@ -336,9 +365,31 @@ man_pmacro(struct man *m, int ln, char *buf)
 
        /* Begin recursive parse sequence. */
 
-       if ( ! man_macro(m, c, ln, 1, &i, buf))
+       if ( ! man_macro(m, c, ln, ppos, &i, buf))
                goto err;
 
+out:
+       if (fl) {
+               /*
+                * A NLINE macro has been immediately followed with
+                * another.  Close out the preceeding macro's scope, and
+                * continue.
+                */
+               assert(MAN_ROOT != m->last->type);
+               assert(m->last->parent);
+               assert(MAN_ROOT != m->last->parent->type);
+
+               if (n != m->last)
+                       m->last = m->last->parent;
+
+               if ( ! man_valid_post(m))
+                       return(0);
+               if ( ! man_action_post(m))
+                       return(0);
+               m->next = MAN_NEXT_SIBLING;
+               m->flags &= ~MAN_NLINE;
+       } 
+
        return(1);
 
 err:   /* Error out. */