]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_validate.c
At the end of mansearch(), fchdir() back to where we started from;
[mandoc.git] / mdoc_validate.c
index bf6b5ffca0c2d9b3be44f4ea81f2ac604f40c24b..8c8d06f68d0e370edc3747ecc26ffe10391b5870 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.202 2014/01/11 22:16:10 schwarze Exp $ */
+/*     $Id: mdoc_validate.c,v 1.209 2014/04/15 00:41:09 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -36,6 +36,7 @@
 
 #include "mdoc.h"
 #include "mandoc.h"
+#include "mandoc_aux.h"
 #include "libmdoc.h"
 #include "libmandoc.h"
 
@@ -45,7 +46,6 @@
 #define        POST_ARGS struct mdoc *mdoc
 
 #define        NUMSIZ    32
-#define        DATESIZE  32
 
 enum   check_ineq {
        CHECK_LT,
@@ -73,7 +73,6 @@ static        void     check_text(struct mdoc *, int, int, char *);
 static void     check_argv(struct mdoc *, 
                        struct mdoc_node *, struct mdoc_argv *);
 static void     check_args(struct mdoc *, struct mdoc_node *);
-static int      concat(char *, const struct mdoc_node *, size_t);
 static enum mdoc_sec   a2sec(const char *);
 static size_t          macro2len(enum mdoct);
 
@@ -305,6 +304,7 @@ static      const struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, posts_sp },                     /* sp */
        { NULL, posts_text1 },                  /* %U */
        { NULL, NULL },                         /* Ta */
+       { NULL, NULL },                         /* ll */
 };
 
 #define        RSORD_MAX 14 /* Number of `Rs' blocks. */
@@ -332,6 +332,7 @@ static      const char * const secnames[SEC__MAX] = {
        "LIBRARY",
        "SYNOPSIS",
        "DESCRIPTION",
+       "CONTEXT",
        "IMPLEMENTATION NOTES",
        "RETURN VALUES",
        "ENVIRONMENT",
@@ -1122,31 +1123,15 @@ post_vt(POST_ARGS)
 static int
 post_nm(POST_ARGS)
 {
-       char             buf[BUFSIZ];
-       int              c;
 
        if (NULL != mdoc->meta.name)
                return(1);
 
-       /* Try to use our children for setting the meta name. */
+       mdoc_deroff(&mdoc->meta.name, mdoc->last);
 
-       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):
+       if (NULL == mdoc->meta.name) {
                mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME);
                mdoc->meta.name = mandoc_strdup("UNKNOWN");
-               break;
-       default:
-               mdoc->meta.name = mandoc_strdup(buf);
-               break;
        }
        return(1);
 }
@@ -1964,10 +1949,9 @@ post_sh_body(POST_ARGS)
 static int
 post_sh_head(POST_ARGS)
 {
-       char             buf[BUFSIZ];
        struct mdoc_node *n;
+       char            *secname;
        enum mdoc_sec    sec;
-       int              c;
 
        /*
         * Process a new section.  Sections are either "named" or
@@ -1976,13 +1960,10 @@ post_sh_head(POST_ARGS)
         * manual sections.
         */
 
+       secname = NULL;
        sec = SEC_CUSTOM;
-       buf[0] = '\0';
-       if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) {
-               mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);
-               return(0);
-       } else if (1 == c)
-               sec = a2sec(buf);
+       mdoc_deroff(&secname, mdoc->last);
+       sec = NULL == secname ? SEC_CUSTOM : a2sec(secname);
 
        /* The NAME should be first. */
 
@@ -2019,8 +2000,10 @@ post_sh_head(POST_ARGS)
 
        /* We don't care about custom sections after this. */
 
-       if (SEC_CUSTOM == sec)
+       if (SEC_CUSTOM == sec) {
+               free(secname);
                return(1);
+       }
 
        /*
         * Check whether our non-custom section is being repeated or is
@@ -2042,24 +2025,29 @@ post_sh_head(POST_ARGS)
        assert(mdoc->meta.msec);
 
        switch (sec) {
-       case (SEC_RETURN_VALUES):
-               /* FALLTHROUGH */
        case (SEC_ERRORS):
+               if (*mdoc->meta.msec == '4')
+                       break;
+               /* FALLTHROUGH */
+       case (SEC_RETURN_VALUES):
                /* FALLTHROUGH */
        case (SEC_LIBRARY):
                if (*mdoc->meta.msec == '2')
                        break;
                if (*mdoc->meta.msec == '3')
                        break;
+               /* FALLTHROUGH */
+       case (SEC_CONTEXT):
                if (*mdoc->meta.msec == '9')
                        break;
                mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse,
-                               mdoc->last->line, mdoc->last->pos, buf);
+                   mdoc->last->line, mdoc->last->pos, secname);
                break;
        default:
                break;
        }
 
+       free(secname);
        return(1);
 }
 
@@ -2175,9 +2163,8 @@ pre_literal(PRE_ARGS)
 static int
 post_dd(POST_ARGS)
 {
-       char              buf[DATESIZE];
        struct mdoc_node *n;
-       int               c;
+       char             *datestr;
 
        if (mdoc->meta.date)
                free(mdoc->meta.date);
@@ -2189,16 +2176,15 @@ post_dd(POST_ARGS)
                return(1);
        }
 
-       buf[0] = '\0';
-       if (-1 == (c = concat(buf, n->child, DATESIZE))) {
-               mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);
-               return(0);
+       datestr = NULL;
+       mdoc_deroff(&datestr, n);
+       if (mdoc->quick)
+               mdoc->meta.date = datestr;
+       else {
+               mdoc->meta.date = mandoc_normdate(mdoc->parse,
+                   datestr, n->line, n->pos);
+               free(datestr);
        }
-
-       assert(c);
-       mdoc->meta.date = mdoc->quick ? mandoc_strdup(buf) :
-           mandoc_normdate(mdoc->parse, buf, n->line, n->pos);
-
        return(1);
 }
 
@@ -2348,13 +2334,11 @@ post_bx(POST_ARGS)
 static int
 post_os(POST_ARGS)
 {
-       char              buf[BUFSIZ];
 #ifndef OSNAME
        struct utsname    utsname;
        static char      *defbuf;
 #endif
        struct mdoc_node *n;
-       int               c;
 
        n = mdoc->last;
 
@@ -2368,19 +2352,10 @@ post_os(POST_ARGS)
         */
 
        free(mdoc->meta.os);
-
-       buf[0] = '\0';
-       if (-1 == (c = concat(buf, n->child, BUFSIZ))) {
-               mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);
-               return(0);
-       }
-
-       assert(c);
-
-       if ('\0' != *buf) {
-               mdoc->meta.os = mandoc_strdup(buf);
+       mdoc->meta.os = NULL;
+       mdoc_deroff(&mdoc->meta.os, n);
+       if (mdoc->meta.os)
                return(1);
-       }
 
        if (mdoc->defos) {
                mdoc->meta.os = mandoc_strdup(mdoc->defos);
@@ -2394,11 +2369,9 @@ post_os(POST_ARGS)
                if (-1 == uname(&utsname)) {
                        mdoc_nmsg(mdoc, n, MANDOCERR_UNAME);
                         defbuf = mandoc_strdup("UNKNOWN");
-                } else if (-1 == asprintf(&defbuf, "%s %s",
-                   utsname.sysname, utsname.release)) {
-                       perror(NULL);
-                       exit((int)MANDOCLEVEL_SYSERR);
-               }
+                } else
+                       mandoc_asprintf(&defbuf, "%s %s",
+                           utsname.sysname, utsname.release);
        }
        mdoc->meta.os = mandoc_strdup(defbuf);
 #endif /*!OSNAME*/
@@ -2434,29 +2407,6 @@ post_std(POST_ARGS)
        return(1);
 }
 
-/*
- * Concatenate a node, stopping at the first non-text.
- * Concatenation is separated by a single whitespace.  
- * Returns -1 on fatal (string overrun) error, 0 if child nodes were
- * encountered, 1 otherwise.
- */
-static int
-concat(char *p, const struct mdoc_node *n, size_t sz)
-{
-
-       for ( ; NULL != n; n = n->next) {
-               if (MDOC_TEXT != n->type) 
-                       return(0);
-               if ('\0' != p[0] && strlcat(p, " ", sz) >= sz)
-                       return(-1);
-               if (strlcat(p, n->string, sz) >= sz)
-                       return(-1);
-               concat(p, n->child, sz);
-       }
-
-       return(1);
-}
-
 static enum mdoc_sec 
 a2sec(const char *p)
 {