]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_action.c
Cache all of `Bd's resolved arguments into mdoc_bd, which is stashed in
[mandoc.git] / mdoc_action.c
index dcc07a9ef433dff952f561324f8276727b4c3627..e103eb980068d028f121a5f7033e2c99acbdbbf7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_action.c,v 1.58 2010/05/15 16:24:38 kristaps Exp $ */
+/*     $Id: mdoc_action.c,v 1.67 2010/06/12 11:21:44 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
 #include <string.h>
 #include <time.h>
 
+#include "mandoc.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
 #define        POST_ARGS struct mdoc *m, struct mdoc_node *n
-#define        PRE_ARGS  struct mdoc *m, const struct mdoc_node *n
+#define        PRE_ARGS  struct mdoc *m, struct mdoc_node *n
 
 #define        NUMSIZ    32
 #define        DATESIZ   32
@@ -56,6 +57,7 @@ static        int       post_dd(POST_ARGS);
 static int       post_display(POST_ARGS);
 static int       post_dt(POST_ARGS);
 static int       post_lb(POST_ARGS);
+static int       post_li(POST_ARGS);
 static int       post_nm(POST_ARGS);
 static int       post_os(POST_ARGS);
 static int       post_pa(POST_ARGS);
@@ -101,7 +103,7 @@ static      const struct actions mdoc_actions[MDOC_MAX] = {
        { NULL, NULL }, /* Ft */ 
        { NULL, NULL }, /* Ic */ 
        { NULL, NULL }, /* In */ 
-       { NULL, NULL }, /* Li */
+       { NULL, post_li }, /* Li */
        { NULL, NULL }, /* Nd */ 
        { NULL, post_nm }, /* Nm */ 
        { NULL, NULL }, /* Op */
@@ -192,6 +194,7 @@ static      const struct actions mdoc_actions[MDOC_MAX] = {
        { NULL, NULL }, /* br */
        { NULL, NULL }, /* sp */
        { NULL, NULL }, /* %U */
+       { NULL, NULL }, /* Ta */
 };
 
 #define        RSORD_MAX 14
@@ -215,7 +218,7 @@ static      const enum mdoct rsord[RSORD_MAX] = {
 
 
 int
-mdoc_action_pre(struct mdoc *m, const struct mdoc_node *n)
+mdoc_action_pre(struct mdoc *m, struct mdoc_node *n)
 {
 
        switch (n->type) {
@@ -269,12 +272,21 @@ concat(struct mdoc *m, char *p, const struct mdoc_node *n, size_t sz)
        p[0] = '\0';
        for ( ; n; n = n->next) {
                assert(MDOC_TEXT == n->type);
-               if (strlcat(p, n->string, sz) >= sz)
-                       return(mdoc_nerr(m, n, ETOOLONG));
+               /*
+                * XXX: yes, these can technically be resized, but it's
+                * highly unlikely that we're going to get here, so let
+                * it slip for now.
+                */
+               if (strlcat(p, n->string, sz) >= sz) {
+                       mdoc_nmsg(m, n, MANDOCERR_MEM);
+                       return(0);
+               }
                if (NULL == n->next)
                        continue;
-               if (strlcat(p, " ", sz) >= sz)
-                       return(mdoc_nerr(m, n, ETOOLONG));
+               if (strlcat(p, " ", sz) >= sz) {
+                       mdoc_nmsg(m, n, MANDOCERR_MEM);
+                       return(0);
+               }
        }
 
        return(1);
@@ -288,14 +300,16 @@ concat(struct mdoc *m, char *p, const struct mdoc_node *n, size_t sz)
 static int
 post_std(POST_ARGS)
 {
-       struct mdoc_node        *nn;
+       struct mdoc_node *nn;
 
        if (n->child)
                return(1);
+       if (NULL == m->meta.name)
+               return(1);
        
        nn = n;
        m->next = MDOC_NEXT_CHILD;
-       assert(m->meta.name);
+
        if ( ! mdoc_word_alloc(m, n->line, n->pos, m->meta.name))
                return(0);
        m->last = nn;
@@ -453,7 +467,7 @@ post_sh(POST_ARGS)
                        break;
                if (*m->meta.msec == '9')
                        break;
-               return(mdoc_nwarn(m, n, EWRONGMSEC));
+               return(mdoc_nmsg(m, n, MANDOCERR_SECMSEC));
        default:
                break;
        }
@@ -486,8 +500,8 @@ post_dt(POST_ARGS)
        if (NULL == (nn = n->child)) {
                /* XXX: make these macro values. */
                /* FIXME: warn about missing values. */
-               m->meta.title = mandoc_strdup("unknown");
-               m->meta.vol = mandoc_strdup("local");
+               m->meta.title = mandoc_strdup("UNKNOWN");
+               m->meta.vol = mandoc_strdup("LOCAL");
                m->meta.msec = mandoc_strdup("1");
                return(post_prol(m, n));
        }
@@ -496,12 +510,13 @@ post_dt(POST_ARGS)
         *   --> title = TITLE, volume = local, msec = 0, arch = NULL
         */
 
-       m->meta.title = mandoc_strdup(nn->string);
+       m->meta.title = mandoc_strdup
+               ('\0' == nn->string[0] ? "UNKNOWN" : nn->string);
 
        if (NULL == (nn = nn->next)) {
                /* FIXME: warn about missing msec. */
                /* XXX: make this a macro value. */
-               m->meta.vol = mandoc_strdup("local");
+               m->meta.vol = mandoc_strdup("LOCAL");
                m->meta.msec = mandoc_strdup("1");
                return(post_prol(m, n));
        }
@@ -517,7 +532,7 @@ post_dt(POST_ARGS)
        if (cp) {
                m->meta.vol = mandoc_strdup(cp);
                m->meta.msec = mandoc_strdup(nn->string);
-       } else if (mdoc_nwarn(m, n, EBADMSEC)) {
+       } else if (mdoc_nmsg(m, n, MANDOCERR_BADMSEC)) {
                m->meta.vol = mandoc_strdup(nn->string);
                m->meta.msec = mandoc_strdup(nn->string);
        } else
@@ -574,19 +589,32 @@ post_os(POST_ARGS)
        if ( ! concat(m, buf, n->child, BUFSIZ))
                return(0);
 
+       /* XXX: yes, these can all be dynamically-adjusted buffers, but
+        * it's really not worth the extra hackery.
+        */
+
        if ('\0' == buf[0]) {
 #ifdef OSNAME
-               if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ)
-                       return(mdoc_nerr(m, n, EUTSNAME));
+               if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) {
+                       mdoc_nmsg(m, n, MANDOCERR_MEM);
+                       return(0);
+               }
 #else /*!OSNAME */
                if (-1 == uname(&utsname))
-                       return(mdoc_nerr(m, n, EUTSNAME));
-               if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ)
-                       return(mdoc_nerr(m, n, ETOOLONG));
-               if (strlcat(buf, " ", 64) >= BUFSIZ)
-                       return(mdoc_nerr(m, n, ETOOLONG));
-               if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ)
-                       return(mdoc_nerr(m, n, ETOOLONG));
+                       return(mdoc_nmsg(m, n, MANDOCERR_UTSNAME));
+
+               if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) {
+                       mdoc_nmsg(m, n, MANDOCERR_MEM);
+                       return(0);
+               }
+               if (strlcat(buf, " ", 64) >= BUFSIZ) {
+                       mdoc_nmsg(m, n, MANDOCERR_MEM);
+                       return(0);
+               }
+               if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) {
+                       mdoc_nmsg(m, n, MANDOCERR_MEM);
+                       return(0);
+               }
 #endif /*!OSNAME*/
        }
 
@@ -612,16 +640,19 @@ post_bl_tagwidth(POST_ARGS)
        /* Defaults to ten ens. */
 
        sz = 10; /* XXX: make this a macro value. */
-       nn = n->body->child;
+
+       for (nn = n->body->child; nn; nn = nn->next) {
+               if (MDOC_It == nn->tok)
+                       break;
+       }
 
        if (nn) {
                assert(MDOC_BLOCK == nn->type);
-               assert(MDOC_It == nn->tok);
                nn = nn->head->child;
                if (MDOC_TEXT != nn->type) {
                        sz = mdoc_macro2len(nn->tok);
                        if (sz == 0) {
-                               if ( ! mdoc_nwarn(m, n, ENOWIDTH))
+                               if ( ! mdoc_nmsg(m, n, MANDOCERR_NOWIDTHARG))
                                        return(0);
                                sz = 10;
                        }
@@ -684,12 +715,11 @@ post_bl_width(POST_ARGS)
         */
 
        if (0 == strcmp(p, "Ds"))
-               /* XXX: make into a macro. */
                width = 6;
        else if (MDOC_MAX == (tok = mdoc_hash_find(p)))
                return(1);
        else if (0 == (width = mdoc_macro2len(tok))) 
-               return(mdoc_nwarn(m, n, ENOWIDTH));
+               return(mdoc_nmsg(m, n, MANDOCERR_BADWIDTH));
 
        /* The value already exists: free and reallocate it. */
 
@@ -809,6 +839,27 @@ post_pa(POST_ARGS)
 }
 
 
+/*
+ * Empty `Li' macros get an empty string to make front-ends add an extra
+ * space.
+ */
+static int
+post_li(POST_ARGS)
+{
+       struct mdoc_node *np;
+
+       if (n->child)
+               return(1);
+       
+       np = n;
+       m->next = MDOC_NEXT_CHILD;
+       if ( ! mdoc_word_alloc(m, n->line, n->pos, ""))
+               return(0);
+       m->last = np;
+       return(1);
+}
+
+
 /*
  * The `Ar' macro defaults to two strings "file ..." if no value is
  * provided as an argument.
@@ -848,7 +899,7 @@ post_dd(POST_ARGS)
                (MTIME_MDOCDATE | MTIME_CANONICAL, buf);
 
        if (0 == m->meta.date) {
-               if ( ! mdoc_nwarn(m, n, EBADDATE))
+               if ( ! mdoc_nmsg(m, n, MANDOCERR_BADDATE))
                        return(0);
                m->meta.date = time(NULL);
        }
@@ -897,8 +948,7 @@ pre_offset(PRE_ARGS)
         * stipulated by mdoc.samples. 
         */
 
-       assert(n->args);
-       for (i = 0; i < (int)n->args->argc; i++) {
+       for (i = 0; n->args && i < (int)n->args->argc; i++) {
                if (MDOC_Offset != n->args->argv[i].arg) 
                        continue;
                if (n->args->argv[i].sz)
@@ -919,27 +969,23 @@ static int
 pre_bl(PRE_ARGS)
 {
 
-       return(MDOC_BLOCK == n->type ? pre_offset(m, n) : 1);
+       if (MDOC_BLOCK == n->type)
+               return(pre_offset(m, n));
+       return(1);
 }
 
 
 static int
 pre_bd(PRE_ARGS)
 {
-       int              i;
 
-       if (MDOC_BLOCK == n->type)
-               return(pre_offset(m, n));
        if (MDOC_BODY != n->type)
                return(1);
 
-       /* Enter literal context if `Bd -literal' or `-unfilled'. */
-
-       for (n = n->parent, i = 0; i < (int)n->args->argc; i++)
-               if (MDOC_Literal == n->args->argv[i].arg)
-                       m->flags |= MDOC_LITERAL;
-               else if (MDOC_Unfilled == n->args->argv[i].arg)
-                       m->flags |= MDOC_LITERAL;
+       if (DISP_literal == n->data.Bd.type)
+               m->flags |= MDOC_LITERAL;
+       if (DISP_unfilled == n->data.Bd.type)
+               m->flags |= MDOC_LITERAL;
 
        return(1);
 }