[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.303 and 1.313

version 1.303, 2016/08/10 12:06:41 version 1.313, 2017/01/10 12:53:07
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-2016 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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
Line 67  static void  post_bf(POST_ARGS);
Line 67  static void  post_bf(POST_ARGS);
 static  void     post_bk(POST_ARGS);  static  void     post_bk(POST_ARGS);
 static  void     post_bl(POST_ARGS);  static  void     post_bl(POST_ARGS);
 static  void     post_bl_block(POST_ARGS);  static  void     post_bl_block(POST_ARGS);
 static  void     post_bl_block_tag(POST_ARGS);  
 static  void     post_bl_head(POST_ARGS);  static  void     post_bl_head(POST_ARGS);
 static  void     post_bl_norm(POST_ARGS);  static  void     post_bl_norm(POST_ARGS);
 static  void     post_bx(POST_ARGS);  static  void     post_bx(POST_ARGS);
Line 104  static void  post_sh_authors(POST_ARGS);
Line 103  static void  post_sh_authors(POST_ARGS);
 static  void     post_sm(POST_ARGS);  static  void     post_sm(POST_ARGS);
 static  void     post_st(POST_ARGS);  static  void     post_st(POST_ARGS);
 static  void     post_std(POST_ARGS);  static  void     post_std(POST_ARGS);
   static  void     post_xr(POST_ARGS);
   
 static  v_post mdoc_valids[MDOC_MAX] = {  static  v_post mdoc_valids[MDOC_MAX] = {
         NULL,           /* Ap */          NULL,           /* Ap */
Line 146  static v_post mdoc_valids[MDOC_MAX] = {
Line 146  static v_post mdoc_valids[MDOC_MAX] = {
         post_st,        /* St */          post_st,        /* St */
         NULL,           /* Va */          NULL,           /* Va */
         NULL,           /* Vt */          NULL,           /* Vt */
         NULL,           /* Xr */          post_xr,        /* Xr */
         NULL,           /* %A */          NULL,           /* %A */
         post_hyph,      /* %B */ /* FIXME: can be used outside Rs/Re. */          post_hyph,      /* %B */ /* FIXME: can be used outside Rs/Re. */
         NULL,           /* %D */          NULL,           /* %D */
Line 297  mdoc_node_validate(struct roff_man *mdoc)
Line 297  mdoc_node_validate(struct roff_man *mdoc)
         mdoc->next = ROFF_NEXT_SIBLING;          mdoc->next = ROFF_NEXT_SIBLING;
         switch (n->type) {          switch (n->type) {
         case ROFFT_TEXT:          case ROFFT_TEXT:
                 if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd)                  if (n->sec != SEC_SYNOPSIS ||
                       (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
                         check_text(mdoc, n->line, n->pos, n->string);                          check_text(mdoc, n->line, n->pos, n->string);
                 break;                  break;
         case ROFFT_EQN:          case ROFFT_EQN:
Line 851  post_nm(POST_ARGS)
Line 852  post_nm(POST_ARGS)
              n->last->tok == MDOC_Lp))               n->last->tok == MDOC_Lp))
                 mdoc_node_relink(mdoc, n->last);                  mdoc_node_relink(mdoc, n->last);
   
         if (mdoc->meta.name != NULL)  
                 return;  
   
         deroff(&mdoc->meta.name, n);  
   
         if (mdoc->meta.name == NULL)          if (mdoc->meta.name == NULL)
                   deroff(&mdoc->meta.name, n);
   
           if (mdoc->meta.name == NULL ||
               (mdoc->lastsec == SEC_NAME && n->child == NULL))
                 mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,                  mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,
                     n->line, n->pos, "Nm");                      n->line, n->pos, "Nm");
 }  }
Line 886  post_display(POST_ARGS)
Line 886  post_display(POST_ARGS)
         n = mdoc->last;          n = mdoc->last;
         switch (n->type) {          switch (n->type) {
         case ROFFT_BODY:          case ROFFT_BODY:
                 if (n->end != ENDBODY_NOT)                  if (n->end != ENDBODY_NOT) {
                         break;                          if (n->tok == MDOC_Bd &&
                 if (n->child == NULL)                              n->body->parent->args == NULL)
                                   roff_node_delete(mdoc, n);
                   } else if (n->child == NULL)
                         mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,                          mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,
                             n->line, n->pos, mdoc_macronames[n->tok]);                              n->line, n->pos, mdoc_macronames[n->tok]);
                 else if (n->tok == MDOC_D1)                  else if (n->tok == MDOC_D1)
Line 943  post_defaults(POST_ARGS)
Line 945  post_defaults(POST_ARGS)
         case MDOC_Ar:          case MDOC_Ar:
                 mdoc->next = ROFF_NEXT_CHILD;                  mdoc->next = ROFF_NEXT_CHILD;
                 roff_word_alloc(mdoc, nn->line, nn->pos, "file");                  roff_word_alloc(mdoc, nn->line, nn->pos, "file");
                   mdoc->last->flags |= NODE_NOSRC;
                 roff_word_alloc(mdoc, nn->line, nn->pos, "...");                  roff_word_alloc(mdoc, nn->line, nn->pos, "...");
                   mdoc->last->flags |= NODE_NOSRC;
                 break;                  break;
         case MDOC_Pa:          case MDOC_Pa:
         case MDOC_Mt:          case MDOC_Mt:
                 mdoc->next = ROFF_NEXT_CHILD;                  mdoc->next = ROFF_NEXT_CHILD;
                 roff_word_alloc(mdoc, nn->line, nn->pos, "~");                  roff_word_alloc(mdoc, nn->line, nn->pos, "~");
                   mdoc->last->flags |= NODE_NOSRC;
                 break;                  break;
         default:          default:
                 abort();                  abort();
Line 1064  post_it(POST_ARGS)
Line 1069  post_it(POST_ARGS)
                             mdoc_argnames[nbl->args->argv[0].arg]);                              mdoc_argnames[nbl->args->argv[0].arg]);
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         case LIST_item:          case LIST_item:
                 if (nit->head->child != NULL)                  if ((nch = nit->head->child) != NULL)
                         mandoc_vmsg(MANDOCERR_ARG_SKIP,                          mandoc_vmsg(MANDOCERR_ARG_SKIP,
                             mdoc->parse, nit->line, nit->pos,                              mdoc->parse, nit->line, nit->pos,
                             "It %s", nit->head->child->string);                              "It %s", nch->string == NULL ?
                               mdoc_macronames[nch->tok] : nch->string);
                 break;                  break;
         case LIST_column:          case LIST_column:
                 cols = (int)nbl->norm->Bl.ncols;                  cols = (int)nbl->norm->Bl.ncols;
Line 1096  post_bl_block(POST_ARGS)
Line 1102  post_bl_block(POST_ARGS)
   
         post_prevpar(mdoc);          post_prevpar(mdoc);
   
         /*  
          * These are fairly complicated, so we've broken them into two  
          * functions.  post_bl_block_tag() is called when a -tag is  
          * specified, but no -width (it must be guessed).  The second  
          * when a -width is specified (macro indicators must be  
          * rewritten into real lengths).  
          */  
   
         n = mdoc->last;          n = mdoc->last;
   
         if (n->norm->Bl.type == LIST_tag &&  
             n->norm->Bl.width == NULL) {  
                 post_bl_block_tag(mdoc);  
                 assert(n->norm->Bl.width != NULL);  
         }  
   
         for (ni = n->body->child; ni != NULL; ni = ni->next) {          for (ni = n->body->child; ni != NULL; ni = ni->next) {
                 if (ni->body == NULL)                  if (ni->body == NULL)
                         continue;                          continue;
Line 1169  rewrite_macro2len(char **arg)
Line 1160  rewrite_macro2len(char **arg)
 }  }
   
 static void  static void
 post_bl_block_tag(POST_ARGS)  
 {  
         struct roff_node *n, *nn;  
         size_t            sz, ssz;  
         int               i;  
         char              buf[24];  
   
         /*  
          * Calculate the -width for a `Bl -tag' list if it hasn't been  
          * provided.  Uses the first head macro.  NOTE AGAIN: this is  
          * ONLY if the -width argument has NOT been provided.  See  
          * rewrite_macro2len() for converting the -width string.  
          */  
   
         sz = 10;  
         n = mdoc->last;  
   
         for (nn = n->body->child; nn != NULL; nn = nn->next) {  
                 if (nn->tok != MDOC_It)  
                         continue;  
   
                 assert(nn->type == ROFFT_BLOCK);  
                 nn = nn->head->child;  
   
                 if (nn == NULL)  
                         break;  
   
                 if (nn->type == ROFFT_TEXT) {  
                         sz = strlen(nn->string) + 1;  
                         break;  
                 }  
   
                 if (0 != (ssz = macro2len(nn->tok)))  
                         sz = ssz;  
   
                 break;  
         }  
   
         /* Defaults to ten ens. */  
   
         (void)snprintf(buf, sizeof(buf), "%un", (unsigned int)sz);  
   
         /*  
          * We have to dynamically add this to the macro's argument list.  
          * We're guaranteed that a MDOC_Width doesn't already exist.  
          */  
   
         assert(n->args != NULL);  
         i = (int)(n->args->argc)++;  
   
         n->args->argv = mandoc_reallocarray(n->args->argv,  
             n->args->argc, sizeof(struct mdoc_argv));  
   
         n->args->argv[i].arg = MDOC_Width;  
         n->args->argv[i].line = n->line;  
         n->args->argv[i].pos = n->pos;  
         n->args->argv[i].sz = 1;  
         n->args->argv[i].value = mandoc_malloc(sizeof(char *));  
         n->args->argv[i].value[0] = mandoc_strdup(buf);  
   
         /* Set our width! */  
         n->norm->Bl.width = n->args->argv[i].value[0];  
 }  
   
 static void  
 post_bl_head(POST_ARGS)  post_bl_head(POST_ARGS)
 {  {
         struct roff_node *nbl, *nh, *nch, *nnext;          struct roff_node *nbl, *nh, *nch, *nnext;
Line 1326  post_bl(POST_ARGS)
Line 1252  post_bl(POST_ARGS)
                 return;                  return;
         }          }
         while (nchild != NULL) {          while (nchild != NULL) {
                   nnext = nchild->next;
                 if (nchild->tok == MDOC_It ||                  if (nchild->tok == MDOC_It ||
                     (nchild->tok == MDOC_Sm &&                      (nchild->tok == MDOC_Sm &&
                      nchild->next != NULL &&                       nnext != NULL && nnext->tok == MDOC_It)) {
                      nchild->next->tok == MDOC_It)) {                          nchild = nnext;
                         nchild = nchild->next;  
                         continue;                          continue;
                 }                  }
   
                   /*
                    * In .Bl -column, the first rows may be implicit,
                    * that is, they may not start with .It macros.
                    * Such rows may be followed by nodes generated on the
                    * roff level, for example .TS, which cannot be moved
                    * out of the list.  In that case, wrap such roff nodes
                    * into an implicit row.
                    */
   
                   if (nchild->prev != NULL) {
                           mdoc->last = nchild;
                           mdoc->next = ROFF_NEXT_SIBLING;
                           roff_block_alloc(mdoc, nchild->line,
                               nchild->pos, MDOC_It);
                           roff_head_alloc(mdoc, nchild->line,
                               nchild->pos, MDOC_It);
                           mdoc->next = ROFF_NEXT_SIBLING;
                           roff_body_alloc(mdoc, nchild->line,
                               nchild->pos, MDOC_It);
                           while (nchild->tok != MDOC_It) {
                                   mdoc_node_relink(mdoc, nchild);
                                   if ((nchild = nnext) == NULL)
                                           break;
                                   nnext = nchild->next;
                                   mdoc->next = ROFF_NEXT_SIBLING;
                           }
                           mdoc->last = nbody;
                           continue;
                   }
   
                 mandoc_msg(MANDOCERR_BL_MOVE, mdoc->parse,                  mandoc_msg(MANDOCERR_BL_MOVE, mdoc->parse,
                     nchild->line, nchild->pos,                      nchild->line, nchild->pos,
                     mdoc_macronames[nchild->tok]);                      mdoc_macronames[nchild->tok]);
Line 1346  post_bl(POST_ARGS)
Line 1302  post_bl(POST_ARGS)
                 nblock  = nbody->parent;                  nblock  = nbody->parent;
                 nprev   = nblock->prev;                  nprev   = nblock->prev;
                 nparent = nblock->parent;                  nparent = nblock->parent;
                 nnext   = nchild->next;  
   
                 /*                  /*
                  * Unlink this child.                   * Unlink this child.
                  */                   */
   
                 assert(nchild->prev == NULL);  
                 nbody->child = nnext;                  nbody->child = nnext;
                 if (nnext == NULL)                  if (nnext == NULL)
                         nbody->last  = NULL;                          nbody->last  = NULL;
Line 1647  post_sh_name(POST_ARGS)
Line 1601  post_sh_name(POST_ARGS)
         for (n = mdoc->last->child; n != NULL; n = n->next) {          for (n = mdoc->last->child; n != NULL; n = n->next) {
                 switch (n->tok) {                  switch (n->tok) {
                 case MDOC_Nm:                  case MDOC_Nm:
                           if (hasnm && n->child != NULL)
                                   mandoc_vmsg(MANDOCERR_NAMESEC_PUNCT,
                                       mdoc->parse, n->line, n->pos,
                                       "Nm %s", n->child->string);
                         hasnm = 1;                          hasnm = 1;
                         break;                          continue;
                 case MDOC_Nd:                  case MDOC_Nd:
                         hasnd = 1;                          hasnd = 1;
                         if (n->next != NULL)                          if (n->next != NULL)
Line 1656  post_sh_name(POST_ARGS)
Line 1614  post_sh_name(POST_ARGS)
                                     mdoc->parse, n->line, n->pos, NULL);                                      mdoc->parse, n->line, n->pos, NULL);
                         break;                          break;
                 case TOKEN_NONE:                  case TOKEN_NONE:
                         if (hasnm)                          if (n->type == ROFFT_TEXT &&
                                 break;                              n->string[0] == ',' && n->string[1] == '\0' &&
                               n->next != NULL && n->next->tok == MDOC_Nm) {
                                   n = n->next;
                                   continue;
                           }
                         /* FALLTHROUGH */                          /* FALLTHROUGH */
                 default:                  default:
                         mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,                          mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,
                             n->line, n->pos, mdoc_macronames[n->tok]);                              n->line, n->pos, mdoc_macronames[n->tok]);
                         break;                          continue;
                 }                  }
                   break;
         }          }
   
         if ( ! hasnm)          if ( ! hasnm)
Line 1760  post_sh_authors(POST_ARGS)
Line 1723  post_sh_authors(POST_ARGS)
 static void  static void
 post_sh_head(POST_ARGS)  post_sh_head(POST_ARGS)
 {  {
         const char      *goodsec;          struct roff_node        *nch;
         enum roff_sec    sec;          const char              *goodsec;
           enum roff_sec            sec;
   
         /*          /*
          * Process a new section.  Sections are either "named" or           * Process a new section.  Sections are either "named" or
Line 1777  post_sh_head(POST_ARGS)
Line 1741  post_sh_head(POST_ARGS)
         if (sec != SEC_NAME && mdoc->lastnamed == SEC_NONE)          if (sec != SEC_NAME && mdoc->lastnamed == SEC_NONE)
                 mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse,                  mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse,
                     mdoc->last->line, mdoc->last->pos, "Sh %s",                      mdoc->last->line, mdoc->last->pos, "Sh %s",
                     sec == SEC_CUSTOM ? mdoc->last->child->string :                      sec != SEC_CUSTOM ? secnames[sec] :
                     secnames[sec]);                      (nch = mdoc->last->child) == NULL ? "" :
                       nch->type == ROFFT_TEXT ? nch->string :
                       mdoc_macronames[nch->tok]);
   
         /* The SYNOPSIS gets special attention in other areas. */          /* The SYNOPSIS gets special attention in other areas. */
   
Line 1854  post_sh_head(POST_ARGS)
Line 1820  post_sh_head(POST_ARGS)
 }  }
   
 static void  static void
   post_xr(POST_ARGS)
   {
           struct roff_node *n, *nch;
   
           n = mdoc->last;
           nch = n->child;
           if (nch->next == NULL) {
                   mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse,
                       n->line, n->pos, "Xr %s", nch->string);
                   return;
           }
           assert(nch->next == n->last);
   }
   
   static void
 post_ignpar(POST_ARGS)  post_ignpar(POST_ARGS)
 {  {
         struct roff_node *np;          struct roff_node *np;
Line 1963  post_dd(POST_ARGS)
Line 1944  post_dd(POST_ARGS)
         char             *datestr;          char             *datestr;
   
         n = mdoc->last;          n = mdoc->last;
           n->flags |= NODE_NOPRT;
   
         if (mdoc->meta.date != NULL) {          if (mdoc->meta.date != NULL) {
                 mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,                  mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
                     n->line, n->pos, "Dd");                      n->line, n->pos, "Dd");
Line 1980  post_dd(POST_ARGS)
Line 1963  post_dd(POST_ARGS)
         if (n->child == NULL || n->child->string[0] == '\0') {          if (n->child == NULL || n->child->string[0] == '\0') {
                 mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :                  mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
                     mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);                      mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
                 goto out;                  return;
         }          }
   
         datestr = NULL;          datestr = NULL;
Line 1992  post_dd(POST_ARGS)
Line 1975  post_dd(POST_ARGS)
                     datestr, n->line, n->pos);                      datestr, n->line, n->pos);
                 free(datestr);                  free(datestr);
         }          }
 out:  
         roff_node_delete(mdoc, n);  
 }  }
   
 static void  static void
Line 2004  post_dt(POST_ARGS)
Line 1985  post_dt(POST_ARGS)
         char             *p;          char             *p;
   
         n = mdoc->last;          n = mdoc->last;
           n->flags |= NODE_NOPRT;
   
         if (mdoc->flags & MDOC_PBODY) {          if (mdoc->flags & MDOC_PBODY) {
                 mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse,                  mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse,
                     n->line, n->pos, "Dt");                      n->line, n->pos, "Dt");
                 goto out;                  return;
         }          }
   
         if (mdoc->meta.title != NULL)          if (mdoc->meta.title != NULL)
Line 2049  post_dt(POST_ARGS)
Line 2032  post_dt(POST_ARGS)
                         }                          }
         }          }
   
         /* Mandatory second argument: section. */          /* Mandatory second argument: section. */
   
         if (nn != NULL)          if (nn != NULL)
                 nn = nn->next;                  nn = nn->next;
Line 2059  post_dt(POST_ARGS)
Line 2042  post_dt(POST_ARGS)
                     mdoc->parse, n->line, n->pos,                      mdoc->parse, n->line, n->pos,
                     "Dt %s", mdoc->meta.title);                      "Dt %s", mdoc->meta.title);
                 mdoc->meta.vol = mandoc_strdup("LOCAL");                  mdoc->meta.vol = mandoc_strdup("LOCAL");
                 goto out;  /* msec and arch remain NULL. */                  return;  /* msec and arch remain NULL. */
         }          }
   
         mdoc->meta.msec = mandoc_strdup(nn->string);          mdoc->meta.msec = mandoc_strdup(nn->string);
Line 2077  post_dt(POST_ARGS)
Line 2060  post_dt(POST_ARGS)
         /* Optional third argument: architecture. */          /* Optional third argument: architecture. */
   
         if ((nn = nn->next) == NULL)          if ((nn = nn->next) == NULL)
                 goto out;                  return;
   
         for (p = nn->string; *p != '\0'; p++)          for (p = nn->string; *p != '\0'; p++)
                 *p = tolower((unsigned char)*p);                  *p = tolower((unsigned char)*p);
Line 2088  post_dt(POST_ARGS)
Line 2071  post_dt(POST_ARGS)
         if ((nn = nn->next) != NULL)          if ((nn = nn->next) != NULL)
                 mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,                  mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
                     nn->line, nn->pos, "Dt ... %s", nn->string);                      nn->line, nn->pos, "Dt ... %s", nn->string);
   
 out:  
         roff_node_delete(mdoc, n);  
 }  }
   
 static void  static void
Line 2118  post_os(POST_ARGS)
Line 2098  post_os(POST_ARGS)
         struct roff_node *n;          struct roff_node *n;
   
         n = mdoc->last;          n = mdoc->last;
           n->flags |= NODE_NOPRT;
   
         if (mdoc->meta.os != NULL)          if (mdoc->meta.os != NULL)
                 mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,                  mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
                     n->line, n->pos, "Os");                      n->line, n->pos, "Os");
Line 2138  post_os(POST_ARGS)
Line 2120  post_os(POST_ARGS)
         mdoc->meta.os = NULL;          mdoc->meta.os = NULL;
         deroff(&mdoc->meta.os, n);          deroff(&mdoc->meta.os, n);
         if (mdoc->meta.os)          if (mdoc->meta.os)
                 goto out;                  return;
   
         if (mdoc->defos) {          if (mdoc->defos) {
                 mdoc->meta.os = mandoc_strdup(mdoc->defos);                  mdoc->meta.os = mandoc_strdup(mdoc->defos);
                 goto out;                  return;
         }          }
   
 #ifdef OSNAME  #ifdef OSNAME
Line 2159  post_os(POST_ARGS)
Line 2141  post_os(POST_ARGS)
         }          }
         mdoc->meta.os = mandoc_strdup(defbuf);          mdoc->meta.os = mandoc_strdup(defbuf);
 #endif /*!OSNAME*/  #endif /*!OSNAME*/
   
 out:  
         roff_node_delete(mdoc, n);  
 }  }
   
 /*  /*

Legend:
Removed from v.1.303  
changed lines
  Added in v.1.313

CVSweb