[BACK]Return to mdoc_validate.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/mdoc_validate.c between version 1.192 and 1.209

version 1.192, 2013/08/05 14:36:01 version 1.209, 2014/04/15 00:41:09
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
    * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 19 
Line 20 
 #include "config.h"  #include "config.h"
 #endif  #endif
   
 #ifndef OSNAME  #ifndef OSNAME
 #include <sys/utsname.h>  #include <sys/utsname.h>
 #endif  #endif
   
Line 35 
Line 36 
   
 #include "mdoc.h"  #include "mdoc.h"
 #include "mandoc.h"  #include "mandoc.h"
   #include "mandoc_aux.h"
 #include "libmdoc.h"  #include "libmdoc.h"
 #include "libmandoc.h"  #include "libmandoc.h"
   
Line 44 
Line 46 
 #define POST_ARGS struct mdoc *mdoc  #define POST_ARGS struct mdoc *mdoc
   
 #define NUMSIZ    32  #define NUMSIZ    32
 #define DATESIZE  32  
   
 enum    check_ineq {  enum    check_ineq {
         CHECK_LT,          CHECK_LT,
Line 72  static void  check_text(struct mdoc *, int, int, char 
Line 73  static void  check_text(struct mdoc *, int, int, char 
 static  void     check_argv(struct mdoc *,  static  void     check_argv(struct mdoc *,
                         struct mdoc_node *, struct mdoc_argv *);                          struct mdoc_node *, struct mdoc_argv *);
 static  void     check_args(struct mdoc *, struct mdoc_node *);  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  enum mdoc_sec   a2sec(const char *);
 static  size_t          macro2len(enum mdoct);  static  size_t          macro2len(enum mdoct);
   
Line 97  static int  post_bl_block_width(POST_ARGS);
Line 97  static int  post_bl_block_width(POST_ARGS);
 static  int      post_bl_block_tag(POST_ARGS);  static  int      post_bl_block_tag(POST_ARGS);
 static  int      post_bl_head(POST_ARGS);  static  int      post_bl_head(POST_ARGS);
 static  int      post_bx(POST_ARGS);  static  int      post_bx(POST_ARGS);
   static  int      post_defaults(POST_ARGS);
 static  int      post_dd(POST_ARGS);  static  int      post_dd(POST_ARGS);
 static  int      post_dt(POST_ARGS);  static  int      post_dt(POST_ARGS);
 static  int      post_defaults(POST_ARGS);  
 static  int      post_literal(POST_ARGS);  
 static  int      post_eoln(POST_ARGS);  static  int      post_eoln(POST_ARGS);
   static  int      post_hyph(POST_ARGS);
   static  int      post_ignpar(POST_ARGS);
 static  int      post_it(POST_ARGS);  static  int      post_it(POST_ARGS);
 static  int      post_lb(POST_ARGS);  static  int      post_lb(POST_ARGS);
   static  int      post_literal(POST_ARGS);
 static  int      post_nm(POST_ARGS);  static  int      post_nm(POST_ARGS);
 static  int      post_ns(POST_ARGS);  static  int      post_ns(POST_ARGS);
 static  int      post_os(POST_ARGS);  static  int      post_os(POST_ARGS);
 static  int      post_par(POST_ARGS);  static  int      post_par(POST_ARGS);
 static  int      post_ignpar(POST_ARGS);  
 static  int      post_prol(POST_ARGS);  static  int      post_prol(POST_ARGS);
 static  int      post_root(POST_ARGS);  static  int      post_root(POST_ARGS);
 static  int      post_rs(POST_ARGS);  static  int      post_rs(POST_ARGS);
Line 142  static v_post  posts_bx[] = { post_bx, NULL };
Line 143  static v_post  posts_bx[] = { post_bx, NULL };
 static  v_post   posts_bool[] = { ebool, NULL };  static  v_post   posts_bool[] = { ebool, NULL };
 static  v_post   posts_eoln[] = { post_eoln, NULL };  static  v_post   posts_eoln[] = { post_eoln, NULL };
 static  v_post   posts_defaults[] = { post_defaults, NULL };  static  v_post   posts_defaults[] = { post_defaults, NULL };
   static  v_post   posts_d1[] = { bwarn_ge1, post_hyph, NULL };
 static  v_post   posts_dd[] = { post_dd, post_prol, NULL };  static  v_post   posts_dd[] = { post_dd, post_prol, NULL };
 static  v_post   posts_dl[] = { post_literal, bwarn_ge1, NULL };  static  v_post   posts_dl[] = { post_literal, bwarn_ge1, NULL };
 static  v_post   posts_dt[] = { post_dt, post_prol, NULL };  static  v_post   posts_dt[] = { post_dt, post_prol, NULL };
 static  v_post   posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };  static  v_post   posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };
   static  v_post   posts_hyph[] = { post_hyph, NULL };
   static  v_post   posts_hyphtext[] = { ewarn_ge1, post_hyph, NULL };
 static  v_post   posts_it[] = { post_it, NULL };  static  v_post   posts_it[] = { post_it, NULL };
 static  v_post   posts_lb[] = { post_lb, NULL };  static  v_post   posts_lb[] = { post_lb, NULL };
 static  v_post   posts_nd[] = { berr_ge1, NULL };  static  v_post   posts_nd[] = { berr_ge1, post_hyph, NULL };
 static  v_post   posts_nm[] = { post_nm, NULL };  static  v_post   posts_nm[] = { post_nm, NULL };
 static  v_post   posts_notext[] = { ewarn_eq0, NULL };  static  v_post   posts_notext[] = { ewarn_eq0, NULL };
 static  v_post   posts_ns[] = { post_ns, NULL };  static  v_post   posts_ns[] = { post_ns, NULL };
 static  v_post   posts_os[] = { post_os, post_prol, NULL };  static  v_post   posts_os[] = { post_os, post_prol, NULL };
 static  v_post   posts_pp[] = { post_par, ewarn_eq0, NULL };  static  v_post   posts_pp[] = { post_par, ewarn_eq0, NULL };
 static  v_post   posts_rs[] = { post_rs, NULL };  static  v_post   posts_rs[] = { post_rs, NULL };
 static  v_post   posts_sh[] = { post_ignpar, hwarn_ge1, post_sh, NULL };  static  v_post   posts_sh[] = { post_ignpar,hwarn_ge1,post_sh,post_hyph,NULL };
 static  v_post   posts_sp[] = { post_par, ewarn_le1, NULL };  static  v_post   posts_sp[] = { post_par, ewarn_le1, NULL };
 static  v_post   posts_ss[] = { post_ignpar, hwarn_ge1, NULL };  static  v_post   posts_ss[] = { post_ignpar, hwarn_ge1, post_hyph, NULL };
 static  v_post   posts_st[] = { post_st, NULL };  static  v_post   posts_st[] = { post_st, NULL };
 static  v_post   posts_std[] = { post_std, NULL };  static  v_post   posts_std[] = { post_std, NULL };
 static  v_post   posts_text[] = { ewarn_ge1, NULL };  static  v_post   posts_text[] = { ewarn_ge1, NULL };
 static  v_post   posts_text1[] = { ewarn_eq1, NULL };  static  v_post   posts_text1[] = { ewarn_eq1, NULL };
 static  v_post   posts_vt[] = { post_vt, NULL };  static  v_post   posts_vt[] = { post_vt, NULL };
 static  v_post   posts_wline[] = { bwarn_ge1, NULL };  
 static  v_pre    pres_an[] = { pre_an, NULL };  static  v_pre    pres_an[] = { pre_an, NULL };
 static  v_pre    pres_bd[] = { pre_display, pre_bd, pre_literal, pre_par, NULL };  static  v_pre    pres_bd[] = { pre_display, pre_bd, pre_literal, pre_par, NULL };
 static  v_pre    pres_bl[] = { pre_bl, pre_par, NULL };  static  v_pre    pres_bl[] = { pre_bl, pre_par, NULL };
Line 171  static v_pre  pres_d1[] = { pre_display, NULL };
Line 174  static v_pre  pres_d1[] = { pre_display, NULL };
 static  v_pre    pres_dl[] = { pre_literal, pre_display, NULL };  static  v_pre    pres_dl[] = { pre_literal, pre_display, NULL };
 static  v_pre    pres_dd[] = { pre_dd, NULL };  static  v_pre    pres_dd[] = { pre_dd, NULL };
 static  v_pre    pres_dt[] = { pre_dt, NULL };  static  v_pre    pres_dt[] = { pre_dt, NULL };
 static  v_pre    pres_er[] = { NULL, NULL };  
 static  v_pre    pres_fd[] = { NULL, NULL };  
 static  v_pre    pres_it[] = { pre_it, pre_par, NULL };  static  v_pre    pres_it[] = { pre_it, pre_par, NULL };
 static  v_pre    pres_os[] = { pre_os, NULL };  static  v_pre    pres_os[] = { pre_os, NULL };
 static  v_pre    pres_pp[] = { pre_par, NULL };  static  v_pre    pres_pp[] = { pre_par, NULL };
Line 188  static const struct valids mdoc_valids[MDOC_MAX] = {
Line 189  static const struct valids mdoc_valids[MDOC_MAX] = {
         { pres_sh, posts_sh },                  /* Sh */          { pres_sh, posts_sh },                  /* Sh */
         { pres_ss, posts_ss },                  /* Ss */          { pres_ss, posts_ss },                  /* Ss */
         { pres_pp, posts_pp },                  /* Pp */          { pres_pp, posts_pp },                  /* Pp */
         { pres_d1, posts_wline },               /* D1 */          { pres_d1, posts_d1 },                  /* D1 */
         { pres_dl, posts_dl },                  /* Dl */          { pres_dl, posts_dl },                  /* Dl */
         { pres_bd, posts_bd },                  /* Bd */          { pres_bd, posts_bd },                  /* Bd */
         { NULL, NULL },                         /* Ed */          { NULL, NULL },                         /* Ed */
Line 201  static const struct valids mdoc_valids[MDOC_MAX] = {
Line 202  static const struct valids mdoc_valids[MDOC_MAX] = {
         { NULL, NULL },                         /* Cd */          { NULL, NULL },                         /* Cd */
         { NULL, NULL },                         /* Cm */          { NULL, NULL },                         /* Cm */
         { NULL, NULL },                         /* Dv */          { NULL, NULL },                         /* Dv */
         { pres_er, NULL },                      /* Er */          { NULL, NULL },                         /* Er */
         { NULL, NULL },                         /* Ev */          { NULL, NULL },                         /* Ev */
         { pres_std, posts_std },                /* Ex */          { pres_std, posts_std },                /* Ex */
         { NULL, NULL },                         /* Fa */          { NULL, NULL },                         /* Fa */
         { pres_fd, posts_text },                /* Fd */          { NULL, posts_text },                   /* Fd */
         { NULL, NULL },                         /* Fl */          { NULL, NULL },                         /* Fl */
         { NULL, NULL },                         /* Fn */          { NULL, NULL },                         /* Fn */
         { NULL, NULL },                         /* Ft */          { NULL, NULL },                         /* Ft */
Line 223  static const struct valids mdoc_valids[MDOC_MAX] = {
Line 224  static const struct valids mdoc_valids[MDOC_MAX] = {
         { NULL, posts_vt },                     /* Vt */          { NULL, posts_vt },                     /* Vt */
         { NULL, posts_text },                   /* Xr */          { NULL, posts_text },                   /* Xr */
         { NULL, posts_text },                   /* %A */          { NULL, posts_text },                   /* %A */
         { NULL, posts_text },                   /* %B */ /* FIXME: can be used outside Rs/Re. */          { NULL, posts_hyphtext },               /* %B */ /* FIXME: can be used outside Rs/Re. */
         { NULL, posts_text },                   /* %D */          { NULL, posts_text },                   /* %D */
         { NULL, posts_text },                   /* %I */          { NULL, posts_text },                   /* %I */
         { NULL, posts_text },                   /* %J */          { NULL, posts_text },                   /* %J */
         { NULL, posts_text },                   /* %N */          { NULL, posts_hyphtext },               /* %N */
         { NULL, posts_text },                   /* %O */          { NULL, posts_hyphtext },               /* %O */
         { NULL, posts_text },                   /* %P */          { NULL, posts_text },                   /* %P */
         { NULL, posts_text },                   /* %R */          { NULL, posts_hyphtext },               /* %R */
         { NULL, posts_text },                   /* %T */ /* FIXME: can be used outside Rs/Re. */          { NULL, posts_hyphtext },               /* %T */ /* FIXME: can be used outside Rs/Re. */
         { NULL, posts_text },                   /* %V */          { NULL, posts_text },                   /* %V */
         { NULL, NULL },                         /* Ac */          { NULL, NULL },                         /* Ac */
         { NULL, NULL },                         /* Ao */          { NULL, NULL },                         /* Ao */
Line 271  static const struct valids mdoc_valids[MDOC_MAX] = {
Line 272  static const struct valids mdoc_valids[MDOC_MAX] = {
         { NULL, NULL },                         /* So */          { NULL, NULL },                         /* So */
         { NULL, NULL },                         /* Sq */          { NULL, NULL },                         /* Sq */
         { NULL, posts_bool },                   /* Sm */          { NULL, posts_bool },                   /* Sm */
         { NULL, NULL },                         /* Sx */          { NULL, posts_hyph },                   /* Sx */
         { NULL, NULL },                         /* Sy */          { NULL, NULL },                         /* Sy */
         { NULL, NULL },                         /* Tn */          { NULL, NULL },                         /* Tn */
         { NULL, NULL },                         /* Ux */          { NULL, NULL },                         /* Ux */
Line 303  static const struct valids mdoc_valids[MDOC_MAX] = {
Line 304  static const struct valids mdoc_valids[MDOC_MAX] = {
         { NULL, posts_sp },                     /* sp */          { NULL, posts_sp },                     /* sp */
         { NULL, posts_text1 },                  /* %U */          { NULL, posts_text1 },                  /* %U */
         { NULL, NULL },                         /* Ta */          { NULL, NULL },                         /* Ta */
           { NULL, NULL },                         /* ll */
 };  };
   
 #define RSORD_MAX 14 /* Number of `Rs' blocks. */  #define RSORD_MAX 14 /* Number of `Rs' blocks. */
Line 330  static const char * const secnames[SEC__MAX] = {
Line 332  static const char * const secnames[SEC__MAX] = {
         "LIBRARY",          "LIBRARY",
         "SYNOPSIS",          "SYNOPSIS",
         "DESCRIPTION",          "DESCRIPTION",
           "CONTEXT",
         "IMPLEMENTATION NOTES",          "IMPLEMENTATION NOTES",
         "RETURN VALUES",          "RETURN VALUES",
         "ENVIRONMENT",          "ENVIRONMENT",
Line 888  pre_sh(PRE_ARGS)
Line 891  pre_sh(PRE_ARGS)
   
         if (MDOC_BLOCK != n->type)          if (MDOC_BLOCK != n->type)
                 return(1);                  return(1);
   
         roff_regunset(mdoc->roff, REG_nS);  
         return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT));          return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT));
 }  }
   
Line 1122  post_vt(POST_ARGS)
Line 1123  post_vt(POST_ARGS)
 static int  static int
 post_nm(POST_ARGS)  post_nm(POST_ARGS)
 {  {
         char             buf[BUFSIZ];  
         int              c;  
   
         if (NULL != mdoc->meta.name)          if (NULL != mdoc->meta.name)
                 return(1);                  return(1);
   
         /* Try to use our children for setting the meta name. */          mdoc_deroff(&mdoc->meta.name, mdoc->last);
   
         if (NULL != mdoc->last->child) {          if (NULL == mdoc->meta.name) {
                 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):  
                 mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME);                  mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME);
                 mdoc->meta.name = mandoc_strdup("UNKNOWN");                  mdoc->meta.name = mandoc_strdup("UNKNOWN");
                 break;  
         default:  
                 mdoc->meta.name = mandoc_strdup(buf);  
                 break;  
         }          }
         return(1);          return(1);
 }  }
Line 1592  post_bl_head(POST_ARGS) 
Line 1577  post_bl_head(POST_ARGS) 
 static int  static int
 post_bl(POST_ARGS)  post_bl(POST_ARGS)
 {  {
         struct mdoc_node        *n;          struct mdoc_node        *nparent, *nprev; /* of the Bl block */
           struct mdoc_node        *nblock, *nbody;  /* of the Bl */
           struct mdoc_node        *nchild, *nnext;  /* of the Bl body */
   
         if (MDOC_HEAD == mdoc->last->type)          nbody = mdoc->last;
                 return(post_bl_head(mdoc));          switch (nbody->type) {
         if (MDOC_BLOCK == mdoc->last->type)          case (MDOC_BLOCK):
                 return(post_bl_block(mdoc));                  return(post_bl_block(mdoc));
         if (MDOC_BODY != mdoc->last->type)          case (MDOC_HEAD):
                   return(post_bl_head(mdoc));
           case (MDOC_BODY):
                   break;
           default:
                 return(1);                  return(1);
           }
   
         for (n = mdoc->last->child; n; n = n->next) {          nchild = nbody->child;
                 switch (n->tok) {          while (NULL != nchild) {
                 case (MDOC_Lp):                  if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) {
                         /* FALLTHROUGH */                          nchild = nchild->next;
                 case (MDOC_Pp):  
                         mdoc_nmsg(mdoc, n, MANDOCERR_CHILD);  
                         /* FALLTHROUGH */  
                 case (MDOC_It):  
                         /* FALLTHROUGH */  
                 case (MDOC_Sm):  
                         continue;                          continue;
                 default:  
                         break;  
                 }                  }
   
                 mdoc_nmsg(mdoc, n, MANDOCERR_SYNTCHILD);                  mdoc_nmsg(mdoc, nchild, MANDOCERR_CHILD);
                 return(0);  
                   /*
                    * Move the node out of the Bl block.
                    * First, collect all required node pointers.
                    */
   
                   nblock  = nbody->parent;
                   nprev   = nblock->prev;
                   nparent = nblock->parent;
                   nnext   = nchild->next;
   
                   /*
                    * Unlink this child.
                    */
   
                   assert(NULL == nchild->prev);
                   if (0 == --nbody->nchild) {
                           nbody->child = NULL;
                           nbody->last  = NULL;
                           assert(NULL == nnext);
                   } else {
                           nbody->child = nnext;
                           nnext->prev = NULL;
                   }
   
                   /*
                    * Relink this child.
                    */
   
                   nchild->parent = nparent;
                   nchild->prev   = nprev;
                   nchild->next   = nblock;
   
                   nblock->prev = nchild;
                   nparent->nchild++;
                   if (NULL == nprev)
                           nparent->child = nchild;
                   else
                           nprev->next = nchild;
   
                   nchild = nnext;
         }          }
   
         return(1);          return(1);
Line 1636  ebool(struct mdoc *mdoc)
Line 1660  ebool(struct mdoc *mdoc)
   
         assert(MDOC_TEXT == mdoc->last->child->type);          assert(MDOC_TEXT == mdoc->last->child->type);
   
         if (0 == strcmp(mdoc->last->child->string, "on"))          if (0 == strcmp(mdoc->last->child->string, "on")) {
                   if (MDOC_Sm == mdoc->last->tok)
                           mdoc->flags &= ~MDOC_SMOFF;
                 return(1);                  return(1);
         if (0 == strcmp(mdoc->last->child->string, "off"))          }
           if (0 == strcmp(mdoc->last->child->string, "off")) {
                   if (MDOC_Sm == mdoc->last->tok)
                           mdoc->flags |= MDOC_SMOFF;
                 return(1);                  return(1);
           }
   
         mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL);          mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL);
         return(1);          return(1);
Line 1819  post_rs(POST_ARGS)
Line 1849  post_rs(POST_ARGS)
         return(1);          return(1);
 }  }
   
   /*
    * For some arguments of some macros,
    * convert all breakable hyphens into ASCII_HYPH.
    */
 static int  static int
   post_hyph(POST_ARGS)
   {
           struct mdoc_node        *n, *nch;
           char                    *cp;
   
           n = mdoc->last;
           switch (n->type) {
           case (MDOC_HEAD):
                   if (MDOC_Sh == n->tok || MDOC_Ss == n->tok)
                           break;
                   return(1);
           case (MDOC_BODY):
                   if (MDOC_D1 == n->tok || MDOC_Nd == n->tok)
                           break;
                   return(1);
           case (MDOC_ELEM):
                   break;
           default:
                   return(1);
           }
   
           for (nch = n->child; nch; nch = nch->next) {
                   if (MDOC_TEXT != nch->type)
                           continue;
                   cp = nch->string;
                   if ('\0' == *cp)
                           continue;
                   while ('\0' != *(++cp))
                           if ('-' == *cp &&
                               isalpha((unsigned char)cp[-1]) &&
                               isalpha((unsigned char)cp[1]))
                                   *cp = ASCII_HYPH;
           }
           return(1);
   }
   
   static int
 post_ns(POST_ARGS)  post_ns(POST_ARGS)
 {  {
   
Line 1878  post_sh_body(POST_ARGS)
Line 1949  post_sh_body(POST_ARGS)
 static int  static int
 post_sh_head(POST_ARGS)  post_sh_head(POST_ARGS)
 {  {
         char             buf[BUFSIZ];  
         struct mdoc_node *n;          struct mdoc_node *n;
           char            *secname;
         enum mdoc_sec    sec;          enum mdoc_sec    sec;
         int              c;  
   
         /*          /*
          * Process a new section.  Sections are either "named" or           * Process a new section.  Sections are either "named" or
Line 1890  post_sh_head(POST_ARGS)
Line 1960  post_sh_head(POST_ARGS)
          * manual sections.           * manual sections.
          */           */
   
           secname = NULL;
         sec = SEC_CUSTOM;          sec = SEC_CUSTOM;
         buf[0] = '\0';          mdoc_deroff(&secname, mdoc->last);
         if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) {          sec = NULL == secname ? SEC_CUSTOM : a2sec(secname);
                 mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);  
                 return(0);  
         } else if (1 == c)  
                 sec = a2sec(buf);  
   
         /* The NAME should be first. */          /* The NAME should be first. */
   
Line 1905  post_sh_head(POST_ARGS)
Line 1972  post_sh_head(POST_ARGS)
   
         /* The SYNOPSIS gets special attention in other areas. */          /* The SYNOPSIS gets special attention in other areas. */
   
         if (SEC_SYNOPSIS == sec)          if (SEC_SYNOPSIS == sec) {
                   roff_setreg(mdoc->roff, "nS", 1, '=');
                 mdoc->flags |= MDOC_SYNOPSIS;                  mdoc->flags |= MDOC_SYNOPSIS;
         else          } else {
                   roff_setreg(mdoc->roff, "nS", 0, '=');
                 mdoc->flags &= ~MDOC_SYNOPSIS;                  mdoc->flags &= ~MDOC_SYNOPSIS;
           }
   
         /* Mark our last section. */          /* Mark our last section. */
   
Line 1930  post_sh_head(POST_ARGS)
Line 2000  post_sh_head(POST_ARGS)
   
         /* We don't care about custom sections after this. */          /* We don't care about custom sections after this. */
   
         if (SEC_CUSTOM == sec)          if (SEC_CUSTOM == sec) {
                   free(secname);
                 return(1);                  return(1);
           }
   
         /*          /*
          * Check whether our non-custom section is being repeated or is           * Check whether our non-custom section is being repeated or is
Line 1953  post_sh_head(POST_ARGS)
Line 2025  post_sh_head(POST_ARGS)
         assert(mdoc->meta.msec);          assert(mdoc->meta.msec);
   
         switch (sec) {          switch (sec) {
         case (SEC_RETURN_VALUES):  
                 /* FALLTHROUGH */  
         case (SEC_ERRORS):          case (SEC_ERRORS):
                   if (*mdoc->meta.msec == '4')
                           break;
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
           case (SEC_RETURN_VALUES):
                   /* FALLTHROUGH */
         case (SEC_LIBRARY):          case (SEC_LIBRARY):
                 if (*mdoc->meta.msec == '2')                  if (*mdoc->meta.msec == '2')
                         break;                          break;
                 if (*mdoc->meta.msec == '3')                  if (*mdoc->meta.msec == '3')
                         break;                          break;
                   /* FALLTHROUGH */
           case (SEC_CONTEXT):
                 if (*mdoc->meta.msec == '9')                  if (*mdoc->meta.msec == '9')
                         break;                          break;
                 mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECMSEC);                  mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse,
                       mdoc->last->line, mdoc->last->pos, secname);
                 break;                  break;
         default:          default:
                 break;                  break;
         }          }
   
           free(secname);
         return(1);          return(1);
 }  }
   
Line 2085  pre_literal(PRE_ARGS)
Line 2163  pre_literal(PRE_ARGS)
 static int  static int
 post_dd(POST_ARGS)  post_dd(POST_ARGS)
 {  {
         char              buf[DATESIZE];  
         struct mdoc_node *n;          struct mdoc_node *n;
         int               c;          char             *datestr;
   
         if (mdoc->meta.date)          if (mdoc->meta.date)
                 free(mdoc->meta.date);                  free(mdoc->meta.date);
   
         n = mdoc->last;          n = mdoc->last;
         if (NULL == n->child || '\0' == n->child->string[0]) {          if (NULL == n->child || '\0' == n->child->string[0]) {
                 mdoc->meta.date = mandoc_normdate                  mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
                         (mdoc->parse, NULL, n->line, n->pos);                      mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
                 return(1);                  return(1);
         }          }
   
         buf[0] = '\0';          datestr = NULL;
         if (-1 == (c = concat(buf, n->child, DATESIZE))) {          mdoc_deroff(&datestr, n);
                 mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);          if (mdoc->quick)
                 return(0);                  mdoc->meta.date = datestr;
           else {
                   mdoc->meta.date = mandoc_normdate(mdoc->parse,
                       datestr, n->line, n->pos);
                   free(datestr);
         }          }
   
         assert(c);  
         mdoc->meta.date = mandoc_normdate  
                 (mdoc->parse, buf, n->line, n->pos);  
   
         return(1);          return(1);
 }  }
   
Line 2258  post_bx(POST_ARGS)
Line 2334  post_bx(POST_ARGS)
 static int  static int
 post_os(POST_ARGS)  post_os(POST_ARGS)
 {  {
         struct mdoc_node *n;  
         char              buf[BUFSIZ];  
         int               c;  
 #ifndef OSNAME  #ifndef OSNAME
         struct utsname    utsname;          struct utsname    utsname;
           static char      *defbuf;
 #endif  #endif
           struct mdoc_node *n;
   
         n = mdoc->last;          n = mdoc->last;
   
Line 2277  post_os(POST_ARGS)
Line 2352  post_os(POST_ARGS)
          */           */
   
         free(mdoc->meta.os);          free(mdoc->meta.os);
           mdoc->meta.os = NULL;
           mdoc_deroff(&mdoc->meta.os, n);
           if (mdoc->meta.os)
                   return(1);
   
         buf[0] = '\0';          if (mdoc->defos) {
         if (-1 == (c = concat(buf, n->child, BUFSIZ))) {                  mdoc->meta.os = mandoc_strdup(mdoc->defos);
                 mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);                  return(1);
                 return(0);  
         }          }
   
         assert(c);  
   
         if ('\0' == buf[0]) {  
                 if (mdoc->defos) {  
                         mdoc->meta.os = mandoc_strdup(mdoc->defos);  
                         return(1);  
                 }  
 #ifdef OSNAME  #ifdef OSNAME
                 if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) {          mdoc->meta.os = mandoc_strdup(OSNAME);
                         mdoc_nmsg(mdoc, n, MANDOCERR_MEM);  
                         return(0);  
                 }  
 #else /*!OSNAME */  #else /*!OSNAME */
           if (NULL == defbuf) {
                 if (-1 == uname(&utsname)) {                  if (-1 == uname(&utsname)) {
                         mdoc_nmsg(mdoc, n, MANDOCERR_UNAME);                          mdoc_nmsg(mdoc, n, MANDOCERR_UNAME);
                         mdoc->meta.os = mandoc_strdup("UNKNOWN");                          defbuf = mandoc_strdup("UNKNOWN");
                         return(post_prol(mdoc));                  } else
                 }                          mandoc_asprintf(&defbuf, "%s %s",
                               utsname.sysname, utsname.release);
                 if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) {  
                         mdoc_nmsg(mdoc, n, MANDOCERR_MEM);  
                         return(0);  
                 }  
                 if (strlcat(buf, " ", BUFSIZ) >= BUFSIZ) {  
                         mdoc_nmsg(mdoc, n, MANDOCERR_MEM);  
                         return(0);  
                 }  
                 if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) {  
                         mdoc_nmsg(mdoc, n, MANDOCERR_MEM);  
                         return(0);  
                 }  
 #endif /*!OSNAME*/  
         }          }
           mdoc->meta.os = mandoc_strdup(defbuf);
         mdoc->meta.os = mandoc_strdup(buf);  #endif /*!OSNAME*/
         return(1);          return(1);
 }  }
   
Line 2348  post_std(POST_ARGS)
Line 2404  post_std(POST_ARGS)
                 return(0);                  return(0);
   
         mdoc->last = nn;          mdoc->last = nn;
         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);          return(1);
 }  }
   

Legend:
Removed from v.1.192  
changed lines
  Added in v.1.209

CVSweb