[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.9 and 1.16

version 1.9, 2009/06/12 09:18:00 version 1.16, 2009/06/18 20:46:19
Line 42  enum merr {
Line 42  enum merr {
         ELISTTYPE,          ELISTTYPE,
         EDISPTYPE,          EDISPTYPE,
         EMULTIDISP,          EMULTIDISP,
           ESECNAME,
         EMULTILIST,          EMULTILIST,
         EARGREP,          EARGREP,
         EBOOL,          EBOOL,
           ECOLMIS,
         ENESTDISP          ENESTDISP
 };  };
   
Line 53  enum mwarn {
Line 55  enum mwarn {
         WNOWIDTH,          WNOWIDTH,
         WMISSWIDTH,          WMISSWIDTH,
         WESCAPE,          WESCAPE,
           WDEPESC,
         WDEPCOL,          WDEPCOL,
         WWRONGMSEC,          WWRONGMSEC,
         WSECOOO,          WSECOOO,
Line 96  static int err_child_gt(struct mdoc *, const char *, i
Line 99  static int err_child_gt(struct mdoc *, const char *, i
 static  int     warn_child_gt(struct mdoc *, const char *, int);  static  int     warn_child_gt(struct mdoc *, const char *, int);
 static  int     err_child_eq(struct mdoc *, const char *, int);  static  int     err_child_eq(struct mdoc *, const char *, int);
 static  int     warn_child_eq(struct mdoc *, const char *, int);  static  int     warn_child_eq(struct mdoc *, const char *, int);
 static  int     count_child(struct mdoc *);  
 static  int     warn_print(struct mdoc *, int, int);  static  int     warn_print(struct mdoc *, int, int);
 static  int     warn_count(struct mdoc *, const char *,  static  int     warn_count(struct mdoc *, const char *,
                         int, const char *, int);                          int, const char *, int);
Line 115  static int pre_fd(PRE_ARGS);
Line 117  static int pre_fd(PRE_ARGS);
 static  int     pre_it(PRE_ARGS);  static  int     pre_it(PRE_ARGS);
 static  int     pre_lb(PRE_ARGS);  static  int     pre_lb(PRE_ARGS);
 static  int     pre_os(PRE_ARGS);  static  int     pre_os(PRE_ARGS);
 static  int     pre_prologue(PRE_ARGS);  
 static  int     pre_rv(PRE_ARGS);  static  int     pre_rv(PRE_ARGS);
 static  int     pre_sh(PRE_ARGS);  static  int     pre_sh(PRE_ARGS);
 static  int     pre_ss(PRE_ARGS);  static  int     pre_ss(PRE_ARGS);
Line 137  static int post_args(POST_ARGS);
Line 138  static int post_args(POST_ARGS);
 static  int     post_at(POST_ARGS);  static  int     post_at(POST_ARGS);
 static  int     post_bf(POST_ARGS);  static  int     post_bf(POST_ARGS);
 static  int     post_bl(POST_ARGS);  static  int     post_bl(POST_ARGS);
   static  int     post_bl_head(POST_ARGS);
 static  int     post_it(POST_ARGS);  static  int     post_it(POST_ARGS);
 static  int     post_nm(POST_ARGS);  static  int     post_nm(POST_ARGS);
 static  int     post_root(POST_ARGS);  static  int     post_root(POST_ARGS);
Line 154  static v_pre pres_an[] = { pre_an, NULL };
Line 156  static v_pre pres_an[] = { pre_an, NULL };
 static  v_pre   pres_bd[] = { pre_display, pre_bd, NULL };  static  v_pre   pres_bd[] = { pre_display, pre_bd, NULL };
 static  v_pre   pres_bl[] = { pre_bl, NULL };  static  v_pre   pres_bl[] = { pre_bl, NULL };
 static  v_pre   pres_cd[] = { pre_cd, NULL };  static  v_pre   pres_cd[] = { pre_cd, NULL };
 static  v_pre   pres_dd[] = { pre_prologue, pre_dd, NULL };  static  v_pre   pres_dd[] = { pre_dd, NULL };
 static  v_pre   pres_d1[] = { pre_display, NULL };  static  v_pre   pres_d1[] = { pre_display, NULL };
 static  v_pre   pres_dt[] = { pre_prologue, pre_dt, NULL };  static  v_pre   pres_dt[] = { pre_dt, NULL };
 static  v_pre   pres_er[] = { pre_er, NULL };  static  v_pre   pres_er[] = { pre_er, NULL };
 static  v_pre   pres_ex[] = { pre_ex, NULL };  static  v_pre   pres_ex[] = { pre_ex, NULL };
 static  v_pre   pres_fd[] = { pre_fd, NULL };  static  v_pre   pres_fd[] = { pre_fd, NULL };
 static  v_pre   pres_it[] = { pre_it, NULL };  static  v_pre   pres_it[] = { pre_it, NULL };
 static  v_pre   pres_lb[] = { pre_lb, NULL };  static  v_pre   pres_lb[] = { pre_lb, NULL };
 static  v_pre   pres_os[] = { pre_prologue, pre_os, NULL };  static  v_pre   pres_os[] = { pre_os, NULL };
 static  v_pre   pres_rv[] = { pre_rv, NULL };  static  v_pre   pres_rv[] = { pre_rv, NULL };
 static  v_pre   pres_sh[] = { pre_sh, NULL };  static  v_pre   pres_sh[] = { pre_sh, NULL };
 static  v_pre   pres_ss[] = { pre_ss, NULL };  static  v_pre   pres_ss[] = { pre_ss, NULL };
Line 173  static v_post posts_wtext[] = { ewarn_ge1, NULL };
Line 175  static v_post posts_wtext[] = { ewarn_ge1, NULL };
 static  v_post  posts_notext[] = { eerr_eq0, NULL };  static  v_post  posts_notext[] = { eerr_eq0, NULL };
 static  v_post  posts_wline[] = { bwarn_ge1, herr_eq0, NULL };  static  v_post  posts_wline[] = { bwarn_ge1, herr_eq0, NULL };
 static  v_post  posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL };  static  v_post  posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL };
 static  v_post  posts_bl[] = { herr_eq0, bwarn_ge1, post_bl, NULL };  static  v_post  posts_bl[] = { bwarn_ge1, post_bl, NULL };
 static  v_post  posts_it[] = { post_it, NULL };  static  v_post  posts_it[] = { post_it, NULL };
 static  v_post  posts_in[] = { ewarn_eq1, NULL };  static  v_post  posts_in[] = { ewarn_eq1, NULL };
 static  v_post  posts_ss[] = { herr_ge1, NULL };  static  v_post  posts_ss[] = { herr_ge1, NULL };
Line 191  static v_post posts_bf[] = { hwarn_le1, post_bf, NULL 
Line 193  static v_post posts_bf[] = { hwarn_le1, post_bf, NULL 
 static  v_post  posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };  static  v_post  posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };
   
 const   struct valids mdoc_valids[MDOC_MAX] = {  const   struct valids mdoc_valids[MDOC_MAX] = {
         { NULL, NULL },                         /* \" */          { NULL, NULL },                         /* Ap */
         { pres_dd, posts_text },                /* Dd */          { pres_dd, posts_text },                /* Dd */
         { pres_dt, NULL },                      /* Dt */          { pres_dt, NULL },                      /* Dt */
         { pres_os, NULL },                      /* Os */          { pres_os, NULL },                      /* Os */
Line 298  const struct valids mdoc_valids[MDOC_MAX] = {
Line 300  const struct valids mdoc_valids[MDOC_MAX] = {
         { NULL, NULL },                         /* Fr */          { NULL, NULL },                         /* Fr */
         { NULL, posts_notext },                 /* Ud */          { NULL, posts_notext },                 /* Ud */
         { pres_lb, posts_lb },                  /* Lb */          { pres_lb, posts_lb },                  /* Lb */
         { NULL, NULL },                         /* Ap */  
         { NULL, posts_pp },                     /* Lp */          { NULL, posts_pp },                     /* Lp */
         { NULL, NULL },                         /* Lk */          { NULL, NULL },                         /* Lk */
         { NULL, posts_text },                   /* Mt */          { NULL, posts_text },                   /* Mt */
Line 413  perr(struct mdoc *m, int line, int pos, enum merr type
Line 414  perr(struct mdoc *m, int line, int pos, enum merr type
         case (EDISPTYPE):          case (EDISPTYPE):
                 p = "missing display type";                  p = "missing display type";
                 break;                  break;
           case (ESECNAME):
                   p = "the NAME section must come first";
                   break;
         case (ELINE):          case (ELINE):
                 p = "expected line arguments";                  p = "expected line arguments";
                 break;                  break;
Line 422  perr(struct mdoc *m, int line, int pos, enum merr type
Line 426  perr(struct mdoc *m, int line, int pos, enum merr type
         case (ENODATA):          case (ENODATA):
                 p = "document has no data";                  p = "document has no data";
                 break;                  break;
           case (ECOLMIS):
                   p = "column syntax style mismatch";
                   break;
         case (EATT):          case (EATT):
                 p = "expected valid AT&T symbol";                  p = "expected valid AT&T symbol";
                 break;                  break;
Line 479  pwarn(struct mdoc *m, int line, int pos, enum mwarn ty
Line 486  pwarn(struct mdoc *m, int line, int pos, enum mwarn ty
         case (WESCAPE):          case (WESCAPE):
                 p = "invalid escape sequence";                  p = "invalid escape sequence";
                 break;                  break;
           case (WDEPESC):
                   p = "deprecated special-character escape";
                   break;
         case (WNOLINE):          case (WNOLINE):
                 p = "suggested no line arguments";                  p = "suggested no line arguments";
                 break;                  break;
Line 542  err_count(struct mdoc *m, const char *k,
Line 552  err_count(struct mdoc *m, const char *k,
 }  }
   
   
 static inline int  
 count_child(struct mdoc *mdoc)  
 {  
         int               i;  
         struct mdoc_node *n;  
   
         for (i = 0, n = mdoc->last->child; n; n = n->next, i++)  
                 /* Do nothing */ ;  
   
         return(i);  
 }  
   
   
 /*  /*
  * Build these up with macros because they're basically the same check   * Build these up with macros because they're basically the same check
  * for different inequalities.  Yes, this could be done with functions,   * for different inequalities.  Yes, this could be done with functions,
Line 565  count_child(struct mdoc *mdoc)
Line 562  count_child(struct mdoc *mdoc)
 static int                                                      \  static int                                                      \
 lvl##_child_##name(struct mdoc *mdoc, const char *p, int sz)    \  lvl##_child_##name(struct mdoc *mdoc, const char *p, int sz)    \
 {                                                               \  {                                                               \
         int i;                                                  \          if (mdoc->last->nchild ineq sz)                         \
         if ((i = count_child(mdoc)) ineq sz)                    \  
                 return(1);                                      \                  return(1);                                      \
         return(lvl##_count(mdoc, #ineq, sz, p, i));             \          return(lvl##_count(mdoc, #ineq, sz, p, mdoc->last->nchild)); \
 }  }
   
 #define CHECK_BODY_DEFN(name, lvl, func, num)                   \  #define CHECK_BODY_DEFN(name, lvl, func, num)                   \
Line 718  check_text(struct mdoc *mdoc, int line, int pos, const
Line 714  check_text(struct mdoc *mdoc, int line, int pos, const
 {  {
         size_t           c;          size_t           c;
   
         /* FIXME: indicate deprecated escapes \*(xx and \*x. */  
   
         for ( ; *p; p++) {          for ( ; *p; p++) {
                 if ('\t' == *p) {                  if ('\t' == *p) {
                         if ( ! (MDOC_LITERAL & mdoc->flags))                          if ( ! (MDOC_LITERAL & mdoc->flags))
Line 734  check_text(struct mdoc *mdoc, int line, int pos, const
Line 728  check_text(struct mdoc *mdoc, int line, int pos, const
   
                 c = mdoc_isescape(p);                  c = mdoc_isescape(p);
                 if (c) {                  if (c) {
                           /* See if form is deprecated. */
                           if ('*' == p[1])
                                   if ( ! pwarn(mdoc, line, pos, WDEPESC))
                                           return(0);
                         p += (int)c - 1;                          p += (int)c - 1;
                         continue;                          continue;
                 }                  }
Line 789  pre_display(PRE_ARGS)
Line 787  pre_display(PRE_ARGS)
 static int  static int
 pre_bl(PRE_ARGS)  pre_bl(PRE_ARGS)
 {  {
         int              pos, col, type, width, offset;          int              pos, type, width, offset;
   
         if (MDOC_BLOCK != n->type)          if (MDOC_BLOCK != n->type)
                 return(1);                  return(1);
Line 798  pre_bl(PRE_ARGS)
Line 796  pre_bl(PRE_ARGS)
   
         /* Make sure that only one type of list is specified.  */          /* Make sure that only one type of list is specified.  */
   
         type = offset = width = col = -1;          type = offset = width = -1;
   
         /* LINTED */          /* LINTED */
         for (pos = 0; pos < (int)n->args->argc; pos++)          for (pos = 0; pos < (int)n->args->argc; pos++)
Line 827  pre_bl(PRE_ARGS)
Line 825  pre_bl(PRE_ARGS)
                         if (-1 != type)                          if (-1 != type)
                                 return(nerr(mdoc, n, EMULTILIST));                                  return(nerr(mdoc, n, EMULTILIST));
                         type = n->args->argv[pos].arg;                          type = n->args->argv[pos].arg;
                         col = pos;  
                         break;                          break;
                 case (MDOC_Width):                  case (MDOC_Width):
                         if (-1 != width)                          if (-1 != width)
Line 871  pre_bl(PRE_ARGS)
Line 868  pre_bl(PRE_ARGS)
                 break;                  break;
         }          }
   
         /*  
          * General validation of fields.  
          */  
   
         switch (type) {  
         case (MDOC_Column):  
                 assert(col >= 0);  
                 if (0 == n->args->argv[col].sz)  
                         break;  
                 if ( ! nwarn(mdoc, n, WDEPCOL))  
                         return(0);  
                 break;  
         default:  
                 break;  
         }  
   
         return(1);          return(1);
 }  }
   
Line 1014  pre_cd(PRE_ARGS)
Line 995  pre_cd(PRE_ARGS)
   
   
 static int  static int
 pre_prologue(PRE_ARGS)  
 {  
   
         return(check_sec(mdoc, n, SEC_PROLOGUE, SEC_CUSTOM));  
 }  
   
   
 static int  
 pre_dt(PRE_ARGS)  pre_dt(PRE_ARGS)
 {  {
   
Line 1074  post_bf(POST_ARGS)
Line 1047  post_bf(POST_ARGS)
   
         head = mdoc->last->head;          head = mdoc->last->head;
   
         if (NULL == mdoc->last->args) {          if (mdoc->last->args && head->child)
                 if (NULL == head->child ||                  return(mdoc_err(mdoc, "one argument expected"));
                                 MDOC_TEXT != head->child->type)          else if (mdoc->last->args)
                         return(mdoc_err(mdoc, "text argument expected"));                  return(1);
   
                 p = head->child->string;          if (NULL == head->child || MDOC_TEXT != head->child->type)
                 if (0 == strcmp(p, "Em"))                  return(mdoc_err(mdoc, "text argument expected"));
                         return(1);  
                 else if (0 == strcmp(p, "Li"))  
                         return(1);  
                 else if (0 == strcmp(p, "Sm"))  
                         return(1);  
                 return(mdoc_nerr(mdoc, head->child, "invalid font"));  
         }  
   
         if (head->child)          p = head->child->string;
                 return(mdoc_err(mdoc, "one argument expected"));  
   
         return(1);          if (0 == strcmp(p, "Em"))
                   return(1);
           else if (0 == strcmp(p, "Li"))
                   return(1);
           else if (0 == strcmp(p, "Sm"))
                   return(1);
   
           return(mdoc_nerr(mdoc, head->child, "invalid font mode"));
 }  }
   
   
Line 1258  post_it(POST_ARGS)
Line 1230  post_it(POST_ARGS)
   
   
 static int  static int
   post_bl_head(POST_ARGS)
   {
           int                     i;
           const struct mdoc_node *n;
   
           n = mdoc->last->parent;
           assert(n->args);
   
           for (i = 0; i < (int)n->args->argc; i++)
                   if (n->args->argv[i].arg == MDOC_Column)
                           break;
   
           if (i == (int)n->args->argc)
                   return(1);
   
           if (n->args->argv[i].sz && mdoc->last->child)
                   return(nerr(mdoc, n, ECOLMIS));
   
           return(1);
   }
   
   
   static int
 post_bl(POST_ARGS)  post_bl(POST_ARGS)
 {  {
         struct mdoc_node        *n;          struct mdoc_node        *n;
   
           if (MDOC_HEAD == mdoc->last->type)
                   return(post_bl_head(mdoc));
         if (MDOC_BODY != mdoc->last->type)          if (MDOC_BODY != mdoc->last->type)
                 return(1);                  return(1);
         if (NULL == mdoc->last->child)          if (NULL == mdoc->last->child)
Line 1308  post_root(POST_ARGS)
Line 1305  post_root(POST_ARGS)
   
         if (NULL == mdoc->first->child)          if (NULL == mdoc->first->child)
                 return(verr(mdoc, ENODATA));                  return(verr(mdoc, ENODATA));
         if (SEC_PROLOGUE == mdoc->lastnamed)          if ( ! (MDOC_PBODY & mdoc->flags))
                 return(verr(mdoc, ENOPROLOGUE));                  return(verr(mdoc, ENOPROLOGUE));
   
         if (MDOC_BLOCK != mdoc->first->child->type)          if (MDOC_BLOCK != mdoc->first->child->type)
Line 1389  post_sh_head(POST_ARGS)
Line 1386  post_sh_head(POST_ARGS)
          * certain manual sections.           * certain manual sections.
          */           */
   
         assert(MDOC_Sh == mdoc->last->tok);  
   
         /* This is just concat() inlined, which is irritating. */  
   
         buf[0] = 0;          buf[0] = 0;
   
         for (n = mdoc->last->child; n; n = n->next) {          for (n = mdoc->last->child; n; n = n->next) {
                   /* XXX - copied from compact(). */
                 assert(MDOC_TEXT == n->type);                  assert(MDOC_TEXT == n->type);
   
                 if (strlcat(buf, n->string, 64) >= 64)                  if (strlcat(buf, n->string, 64) >= 64)
                         return(nerr(mdoc, n, ETOOLONG));                          return(nerr(mdoc, n, ETOOLONG));
                 if (NULL == n->next)                  if (NULL == n->next)
Line 1406  post_sh_head(POST_ARGS)
Line 1402  post_sh_head(POST_ARGS)
   
         sec = mdoc_atosec(buf);          sec = mdoc_atosec(buf);
   
         /* The NAME section should always be first. */          /*
            * Check: NAME should always be first, CUSTOM has no roles,
            * non-CUSTOM has a conventional order to be followed.
            */
   
         if (SEC_BODY == mdoc->lastnamed && SEC_NAME != sec)          if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed)
                 return(vwarn(mdoc, WSECOOO));                  return(verr(mdoc, ESECNAME));
         if (SEC_CUSTOM == sec)          if (SEC_CUSTOM == sec)
                 return(1);                  return(1);
   
         /* Check for repeated or out-of-order sections. */  
   
         if (sec == mdoc->lastnamed)          if (sec == mdoc->lastnamed)
                 return(vwarn(mdoc, WSECREP));                  return(vwarn(mdoc, WSECREP));
         if (sec < mdoc->lastnamed)          if (sec < mdoc->lastnamed)
                 return(vwarn(mdoc, WSECOOO));                  return(vwarn(mdoc, WSECOOO));
   
         /* Check particular section/manual section conventions. */          /*
            * Check particular section/manual conventions.  LIBRARY can
            * only occur in msec 2, 3 (TODO: are there more of these?).
            */
   
         switch (sec) {          switch (sec) {
         case (SEC_LIBRARY):          case (SEC_LIBRARY):

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.16

CVSweb