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

Diff for /mandoc/roff.c between version 1.49 and 1.52

version 1.49, 2008/12/07 16:41:04 version 1.52, 2008/12/08 16:29:57
Line 35 
Line 35 
 /* FIXME: First letters of quoted-text interpreted in rofffindtok. */  /* FIXME: First letters of quoted-text interpreted in rofffindtok. */
 /* FIXME: `No' not implemented. */  /* FIXME: `No' not implemented. */
 /* TODO: warn if Pp occurs before/after Sh etc. (see mdoc.samples). */  /* TODO: warn if Pp occurs before/after Sh etc. (see mdoc.samples). */
 /* TODO: warn about "X section only" macros. */  
 /* TODO: warn about empty lists. */  /* TODO: warn about empty lists. */
 /* TODO: (warn) some sections need specific elements. */  /* TODO: (warn) some sections need specific elements. */
 /* TODO: (warn) NAME section has particular order. */  /* TODO: (warn) NAME section has particular order. */
Line 57  struct rofftree {
Line 56  struct rofftree {
         char              name[64];             /* `Nm' results. */          char              name[64];             /* `Nm' results. */
         char              os[64];               /* `Os' results. */          char              os[64];               /* `Os' results. */
         char              title[64];            /* `Dt' results. */          char              title[64];            /* `Dt' results. */
         char              section[64];          /* `Dt' results. */          enum roffmsec     section;
         char              volume[64];           /* `Dt' results. */          char              volume[64];           /* `Dt' results. */
         int               state;          int               state;
 #define ROFF_PRELUDE     (1 << 1)               /* In roff prelude. */  #define ROFF_PRELUDE     (1 << 1)               /* In roff prelude. */
Line 67  struct rofftree {
Line 66  struct rofftree {
 #define ROFF_BODY        (1 << 5)               /* In roff body. */  #define ROFF_BODY        (1 << 5)               /* In roff body. */
         struct roffcb     cb;                   /* Callbacks. */          struct roffcb     cb;                   /* Callbacks. */
         void             *arg;                  /* Callbacks' arg. */          void             *arg;                  /* Callbacks' arg. */
           int               csec;                 /* Current section. */
           int               asec;                 /* Thus-far sections. */
 };  };
   
 static  struct roffnode  *roffnode_new(int, struct rofftree *);  static  struct roffnode  *roffnode_new(int, struct rofftree *);
Line 80  static int    roffscan(int, const int *);
Line 81  static int    roffscan(int, const int *);
 static  int               rofffindtok(const char *);  static  int               rofffindtok(const char *);
 static  int               rofffindarg(const char *);  static  int               rofffindarg(const char *);
 static  int               rofffindcallable(const char *);  static  int               rofffindcallable(const char *);
   static  int               roffismsec(const char *);
   static  int               roffissec(const char **);
   static  int               roffispunct(const char *);
   static  int               roffchecksec(struct rofftree *,
                                   const char *, int);
 static  int               roffargs(const struct rofftree *,  static  int               roffargs(const struct rofftree *,
                                 int, char *, char **);                                  int, char *, char **);
 static  int               roffargok(int, int);  static  int               roffargok(int, int);
Line 88  static int    roffnextopt(const struct rofftree *,
Line 94  static int    roffnextopt(const struct rofftree *,
 static  int               roffparseopts(struct rofftree *, int,  static  int               roffparseopts(struct rofftree *, int,
                                 char ***, int *, char **);                                  char ***, int *, char **);
 static  int               roffcall(struct rofftree *, int, char **);  static  int               roffcall(struct rofftree *, int, char **);
   static  int               roffexit(struct rofftree *, int);
 static  int               roffparse(struct rofftree *, char *);  static  int               roffparse(struct rofftree *, char *);
 static  int               textparse(struct rofftree *, char *);  static  int               textparse(struct rofftree *, char *);
 static  int               roffdata(struct rofftree *, int, char *);  static  int               roffdata(struct rofftree *, int, char *);
Line 121  roff_free(struct rofftree *tree, int flush)
Line 128  roff_free(struct rofftree *tree, int flush)
         if (ROFF_PRELUDE & tree->state) {          if (ROFF_PRELUDE & tree->state) {
                 roff_err(tree, NULL, "prelude never finished");                  roff_err(tree, NULL, "prelude never finished");
                 goto end;                  goto end;
         }          } else if ( ! (ROFFSec_NAME & tree->asec)) {
                   roff_err(tree, NULL, "missing `NAME' section");
                   goto end;
           } else if ( ! (ROFFSec_NMASK & tree->asec))
                   roff_warn(tree, NULL, "missing suggested `NAME', "
                                   "`SYNOPSIS', `DESCRIPTION' sections");
   
         for (n = tree->last; n; n = n->parent) {          for (n = tree->last; n; n = n->parent) {
                 if (0 != tokens[n->tok].ctx)                  if (0 != tokens[n->tok].ctx)
Line 133  roff_free(struct rofftree *tree, int flush)
Line 145  roff_free(struct rofftree *tree, int flush)
   
         while (tree->last) {          while (tree->last) {
                 t = tree->last->tok;                  t = tree->last->tok;
                 if ( ! (*tokens[t].cb)(t, tree, NULL, ROFF_EXIT))                  if ( ! roffexit(tree, t))
                         goto end;                          goto end;
         }          }
   
Line 166  roff_alloc(const struct roffcb *cb, void *args)
Line 178  roff_alloc(const struct roffcb *cb, void *args)
   
         tree->state = ROFF_PRELUDE;          tree->state = ROFF_PRELUDE;
         tree->arg = args;          tree->arg = args;
           tree->section = ROFF_MSEC_MAX;
   
         (void)memcpy(&tree->cb, cb, sizeof(struct roffcb));          (void)memcpy(&tree->cb, cb, sizeof(struct roffcb));
   
Line 324  roffparse(struct rofftree *tree, char *buf)
Line 337  roffparse(struct rofftree *tree, char *buf)
                         return(1);                          return(1);
   
         if (ROFF_MAX == (tok = rofffindtok(buf + 1))) {          if (ROFF_MAX == (tok = rofffindtok(buf + 1))) {
                 roff_err(tree, buf + 1, "bogus line macro");                  roff_err(tree, buf, "bogus line macro");
                 return(0);                  return(0);
         } else if (NULL == tokens[tok].cb) {          } else if ( ! roffargs(tree, tok, buf, argv))
                 roff_err(tree, buf + 1, "unsupported macro `%s'",  
                                 toknames[tok]);  
                 return(0);                  return(0);
         }  
   
         assert(ROFF___ != tok);  
         if ( ! roffargs(tree, tok, buf, argv))  
                 return(0);  
   
         argvp = (char **)argv;          argvp = (char **)argv;
   
         /*          /*
Line 344  roffparse(struct rofftree *tree, char *buf)
Line 350  roffparse(struct rofftree *tree, char *buf)
   
         if (ROFF_PRELUDE & tree->state) {          if (ROFF_PRELUDE & tree->state) {
                 assert(NULL == tree->last);                  assert(NULL == tree->last);
                 return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER));                  return(roffcall(tree, tok, argvp));
         }          }
   
         assert(ROFF_BODY & tree->state);          assert(ROFF_BODY & tree->state);
Line 375  roffparse(struct rofftree *tree, char *buf)
Line 381  roffparse(struct rofftree *tree, char *buf)
          */           */
   
         if (ROFF_LAYOUT != tokens[tok].type)          if (ROFF_LAYOUT != tokens[tok].type)
                 return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER));                  return(roffcall(tree, tok, argvp));
         if (0 == tokens[tok].ctx)          if (0 == tokens[tok].ctx)
                 return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER));                  return(roffcall(tree, tok, argvp));
   
         /*          /*
          * First consider implicit-end tags, like as follows:           * First consider implicit-end tags, like as follows:
Line 419  roffparse(struct rofftree *tree, char *buf)
Line 425  roffparse(struct rofftree *tree, char *buf)
                  */                   */
   
                 if (NULL == n)                  if (NULL == n)
                         return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER));                          return(roffcall(tree, tok, argvp));
   
                 /*                  /*
                  * Close out all intermediary scoped blocks, then hang                   * Close out all intermediary scoped blocks, then hang
Line 428  roffparse(struct rofftree *tree, char *buf)
Line 434  roffparse(struct rofftree *tree, char *buf)
   
                 do {                  do {
                         t = tree->last->tok;                          t = tree->last->tok;
                         if ( ! (*tokens[t].cb)(t, tree, NULL, ROFF_EXIT))                          if ( ! roffexit(tree, t))
                                 return(0);                                  return(0);
                 } while (t != tok);                  } while (t != tok);
   
                 return((*tokens[tok].cb)(tok, tree, argvp, ROFF_ENTER));                  return(roffcall(tree, tok, argvp));
         }          }
   
         /*          /*
Line 468  roffparse(struct rofftree *tree, char *buf)
Line 474  roffparse(struct rofftree *tree, char *buf)
         /* LINTED */          /* LINTED */
         do {          do {
                 t = tree->last->tok;                  t = tree->last->tok;
                 if ( ! (*tokens[t].cb)(t, tree, NULL, ROFF_EXIT))                  if ( ! roffexit(tree, t))
                         return(0);                          return(0);
         } while (t != tokens[tok].ctx);          } while (t != tokens[tok].ctx);
   
Line 520  rofffindtok(const char *buf)
Line 526  rofffindtok(const char *buf)
   
   
 static int  static int
   roffchecksec(struct rofftree *tree, const char *start, int sec)
   {
           int              prior;
   
           switch (sec) {
           case(ROFFSec_SYNOP):
                   if ((prior = ROFFSec_NAME) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_DESC):
                   if ((prior = ROFFSec_SYNOP) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_RETVAL):
                   if ((prior = ROFFSec_DESC) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_ENV):
                   if ((prior = ROFFSec_RETVAL) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_FILES):
                   if ((prior = ROFFSec_ENV) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_EX):
                   if ((prior = ROFFSec_FILES) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_DIAG):
                   if ((prior = ROFFSec_EX) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_ERRS):
                   if ((prior = ROFFSec_DIAG) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_SEEALSO):
                   if ((prior = ROFFSec_ERRS) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_STAND):
                   if ((prior = ROFFSec_SEEALSO) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_HIST):
                   if ((prior = ROFFSec_STAND) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_AUTH):
                   if ((prior = ROFFSec_HIST) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_CAVEATS):
                   if ((prior = ROFFSec_AUTH) & tree->asec)
                           return(1);
                   break;
           case(ROFFSec_BUGS):
                   if ((prior = ROFFSec_CAVEATS) & tree->asec)
                           return(1);
                   break;
           default:
                   return(1);
           }
   
           roff_warn(tree, start, "section violates conventional order");
           return(1);
   }
   
   
   static int
   roffissec(const char **p)
   {
   
           assert(*p);
           if (NULL != *(p + 1)) {
                   if (NULL != *(p + 2))
                           return(ROFFSec_OTHER);
                   if (0 == strcmp(*p, "RETURN") &&
                                   0 == strcmp(*(p + 1), "VALUES"))
                           return(ROFFSec_RETVAL);
                   if (0 == strcmp(*p, "SEE") &&
                                   0 == strcmp(*(p + 1), "ALSO"))
                           return(ROFFSec_SEEALSO);
                   return(ROFFSec_OTHER);
           }
   
           if (0 == strcmp(*p, "NAME"))
                   return(ROFFSec_NAME);
           else if (0 == strcmp(*p, "SYNOPSIS"))
                   return(ROFFSec_SYNOP);
           else if (0 == strcmp(*p, "DESCRIPTION"))
                   return(ROFFSec_DESC);
           else if (0 == strcmp(*p, "ENVIRONMENT"))
                   return(ROFFSec_ENV);
           else if (0 == strcmp(*p, "FILES"))
                   return(ROFFSec_FILES);
           else if (0 == strcmp(*p, "EXAMPLES"))
                   return(ROFFSec_EX);
           else if (0 == strcmp(*p, "DIAGNOSTICS"))
                   return(ROFFSec_DIAG);
           else if (0 == strcmp(*p, "ERRORS"))
                   return(ROFFSec_ERRS);
           else if (0 == strcmp(*p, "STANDARDS"))
                   return(ROFFSec_STAND);
           else if (0 == strcmp(*p, "HISTORY"))
                   return(ROFFSec_HIST);
           else if (0 == strcmp(*p, "AUTHORS"))
                   return(ROFFSec_AUTH);
           else if (0 == strcmp(*p, "CAVEATS"))
                   return(ROFFSec_CAVEATS);
           else if (0 == strcmp(*p, "BUGS"))
                   return(ROFFSec_BUGS);
   
           return(ROFFSec_OTHER);
   }
   
   
   static int
   roffismsec(const char *p)
   {
   
           if (0 == strcmp(p, "1"))
                   return(ROFF_MSEC_1);
           else if (0 == strcmp(p, "2"))
                   return(ROFF_MSEC_2);
           else if (0 == strcmp(p, "3"))
                   return(ROFF_MSEC_3);
           else if (0 == strcmp(p, "3p"))
                   return(ROFF_MSEC_3p);
           else if (0 == strcmp(p, "4"))
                   return(ROFF_MSEC_4);
           else if (0 == strcmp(p, "5"))
                   return(ROFF_MSEC_5);
           else if (0 == strcmp(p, "6"))
                   return(ROFF_MSEC_6);
           else if (0 == strcmp(p, "7"))
                   return(ROFF_MSEC_7);
           else if (0 == strcmp(p, "8"))
                   return(ROFF_MSEC_8);
           else if (0 == strcmp(p, "9"))
                   return(ROFF_MSEC_9);
           else if (0 == strcmp(p, "unass"))
                   return(ROFF_MSEC_UNASS);
           else if (0 == strcmp(p, "draft"))
                   return(ROFF_MSEC_DRAFT);
           else if (0 == strcmp(p, "paper"))
                   return(ROFF_MSEC_PAPER);
   
           return(ROFF_MSEC_MAX);
   }
   
   
   static int
 roffispunct(const char *p)  roffispunct(const char *p)
 {  {
   
Line 628  roffspecial(struct rofftree *tree, int tok, const char
Line 788  roffspecial(struct rofftree *tree, int tok, const char
         case (ROFF_At):          case (ROFF_At):
                 if (0 == sz)                  if (0 == sz)
                         break;                          break;
                 if (0 == strcmp(*ordp, "v6"))                  if (0 == strcmp(*ordp, "v1"))
                         break;                          break;
                   else if (0 == strcmp(*ordp, "v2"))
                           break;
                   else if (0 == strcmp(*ordp, "v3"))
                           break;
                   else if (0 == strcmp(*ordp, "v6"))
                           break;
                 else if (0 == strcmp(*ordp, "v7"))                  else if (0 == strcmp(*ordp, "v7"))
                         break;                          break;
                 else if (0 == strcmp(*ordp, "32v"))                  else if (0 == strcmp(*ordp, "32v"))
Line 638  roffspecial(struct rofftree *tree, int tok, const char
Line 804  roffspecial(struct rofftree *tree, int tok, const char
                         break;                          break;
                 else if (0 == strcmp(*ordp, "V.4"))                  else if (0 == strcmp(*ordp, "V.4"))
                         break;                          break;
                 roff_err(tree, start, "invalid `At' arg");                  roff_err(tree, *ordp, "invalid `At' arg");
                 return(0);                  return(0);
   
           case (ROFF_Xr):
                   if (2 == sz) {
                           assert(ordp[1]);
                           if (ROFF_MSEC_MAX != roffismsec(ordp[1]))
                                   break;
                           roff_warn(tree, start, "invalid `%s' manual "
                                           "section", toknames[tok]);
                   }
                   /* FALLTHROUGH */
   
           case (ROFF_Sx):
                   /* FALLTHROUGH*/
         case (ROFF_Fn):          case (ROFF_Fn):
                 if (0 != sz)                  if (0 != sz)
                         break;                          break;
Line 662  roffspecial(struct rofftree *tree, int tok, const char
Line 840  roffspecial(struct rofftree *tree, int tok, const char
   
         case (ROFF_Rv):          case (ROFF_Rv):
                 /* FALLTHROUGH*/                  /* FALLTHROUGH*/
         case (ROFF_Sx):  
                 /* FALLTHROUGH*/  
         case (ROFF_Ex):          case (ROFF_Ex):
                 if (1 == sz)                  if (1 == sz)
                         break;                          break;
Line 699  roffspecial(struct rofftree *tree, int tok, const char
Line 875  roffspecial(struct rofftree *tree, int tok, const char
                 break;                  break;
         }          }
   
         return((*tree->cb.roffspecial)(tree->arg, tok,          return((*tree->cb.roffspecial)(tree->arg, tok, tree->cur,
                                 tree->cur, argc, argv, ordp));                                  argc, argv, (const char **)ordp));
 }  }
   
   
 static int  static int
   roffexit(struct rofftree *tree, int tok)
   {
   
           assert(tokens[tok].cb);
           return((*tokens[tok].cb)(tok, tree, NULL, ROFF_EXIT));
   }
   
   
   static int
 roffcall(struct rofftree *tree, int tok, char **argv)  roffcall(struct rofftree *tree, int tok, char **argv)
 {  {
           int              i;
           enum roffmsec    c;
   
         if (NULL == tokens[tok].cb) {          if (NULL == tokens[tok].cb) {
                 roff_err(tree, *argv, "unsupported macro `%s'",                  roff_err(tree, *argv, "`%s' is unsupported",
                                 toknames[tok]);                                  toknames[tok]);
                 return(0);                  return(0);
         }          }
         if ( ! (*tokens[tok].cb)(tok, tree, argv, ROFF_ENTER))          if (tokens[tok].sections && ROFF_MSEC_MAX != tree->section) {
                 return(0);                  i = 0;
         return(1);                  while (ROFF_MSEC_MAX !=
                                   (c = tokens[tok].sections[i++]))
                           if (c == tree->section)
                                   break;
                   if (ROFF_MSEC_MAX == c) {
                           roff_warn(tree, *argv, "`%s' is not a valid "
                                           "macro in this manual section",
                                           toknames[tok]);
                   }
           }
   
           return((*tokens[tok].cb)(tok, tree, argv, ROFF_ENTER));
 }  }
   
   
Line 942  roff_Dt(ROFFCALL_ARGS)
Line 1140  roff_Dt(ROFFCALL_ARGS)
         if (NULL == *argv) {          if (NULL == *argv) {
                 roff_err(tree, *argv, "`Dt' needs section");                  roff_err(tree, *argv, "`Dt' needs section");
                 return(0);                  return(0);
         } else if (strlcpy(tree->section, *argv, sizeof(tree->section))          }
                         >= sizeof(tree->section)) {  
                 roff_err(tree, *argv, "`Dt' section too long");          if (ROFF_MSEC_MAX == (tree->section = roffismsec(*argv))) {
                   roff_err(tree, *argv, "bad `Dt' section");
                 return(0);                  return(0);
         }          }
   
Line 1075  roff_Os(ROFFCALL_ARGS)
Line 1274  roff_Os(ROFFCALL_ARGS)
         tree->state &= ~ROFF_PRELUDE;          tree->state &= ~ROFF_PRELUDE;
         tree->state |= ROFF_BODY;          tree->state |= ROFF_BODY;
   
           assert(ROFF_MSEC_MAX != tree->section);
           assert(0 != tree->title[0]);
           assert(0 != tree->os[0]);
   
         assert(NULL == tree->last);          assert(NULL == tree->last);
   
         return((*tree->cb.roffhead)(tree->arg, &tree->tm,          return((*tree->cb.roffhead)(tree->arg, &tree->tm,
Line 1090  roff_layout(ROFFCALL_ARGS) 
Line 1293  roff_layout(ROFFCALL_ARGS) 
         int              i, c, argcp[ROFF_MAXLINEARG];          int              i, c, argcp[ROFF_MAXLINEARG];
         char            *argvp[ROFF_MAXLINEARG];          char            *argvp[ROFF_MAXLINEARG];
   
           /*
            * The roff_layout function is for multi-line macros.  A layout
            * has a start and end point, which is either declared
            * explicitly or implicitly.  An explicit start and end is
            * embodied by `.Bl' and `.El', with the former being the start
            * and the latter being an end.  The `.Sh' and `.Ss' tags, on
            * the other hand, are implicit.  The scope of a layout is the
            * space between start and end.  Explicit layouts may not close
            * out implicit ones and vice versa; implicit layouts may close
            * out other implicit layouts.
            */
   
           assert( ! (ROFF_CALLABLE & tokens[tok].flags));
   
         if (ROFF_PRELUDE & tree->state) {          if (ROFF_PRELUDE & tree->state) {
                 roff_err(tree, *argv, "bad `%s' in prelude",                  roff_err(tree, *argv, "bad `%s' in prelude",
                                 toknames[tok]);                                  toknames[tok]);
Line 1114  roff_layout(ROFFCALL_ARGS) 
Line 1331  roff_layout(ROFFCALL_ARGS) 
          * Layouts have two parts: the layout body and header.  The           * Layouts have two parts: the layout body and header.  The
          * layout header is the trailing text of the line macro, while           * layout header is the trailing text of the line macro, while
          * the layout body is everything following until termination.           * the layout body is everything following until termination.
            * Example:
            *
            * .It Fl f ) ;
            * Bar.
            *
            * ...Produces...
            *
            * <block>
            *      <head>
            *              <!Fl f!> ;
            *      </head>
            *
            *      <body>
            *              Bar.
            *      </body>
            * </block>
          */           */
   
         if ( ! (*tree->cb.roffblkin)(tree->arg, tok, argcp, argvp))          if ( ! (*tree->cb.roffblkin)(tree->arg, tok, argcp,
                                   (const char **)argvp))
                 return(0);                  return(0);
   
           /* +++ Begin run macro-specific hooks over argv. */
   
           switch (tok) {
           case (ROFF_Sh):
                   if (NULL == *argv) {
                           roff_err(tree, *(argv - 1),
                                           "`Sh' expects arguments");
                           return(0);
                   }
                   tree->csec = roffissec((const char **)argv);
                   if ( ! (ROFFSec_OTHER & tree->csec) &&
                                   tree->asec & tree->csec)
                           roff_warn(tree, *argv, "section repeated");
                   if (0 == tree->asec && ! (ROFFSec_NAME & tree->csec)) {
                           roff_err(tree, *argv, "`NAME' section "
                                           "must be first");
                           return(0);
                   } else if ( ! roffchecksec(tree, *argv, tree->csec))
                           return(0);
   
                   tree->asec |= tree->csec;
                   break;
           default:
                   break;
           }
   
           /* --- End run macro-specific hooks over argv. */
   
         if (NULL == *argv)          if (NULL == *argv)
                 return((*tree->cb.roffblkbodyin)                  return((*tree->cb.roffblkbodyin)
                                 (tree->arg, tok, argcp, argvp));                                  (tree->arg, tok, argcp,
                                    (const char **)argvp));
   
         if ( ! (*tree->cb.roffblkheadin)(tree->arg, tok, argcp, argvp))          if ( ! (*tree->cb.roffblkheadin)(tree->arg, tok, argcp,
                                   (const char **)argvp))
                 return(0);                  return(0);
   
         /*          /*
Line 1138  roff_layout(ROFFCALL_ARGS) 
Line 1403  roff_layout(ROFFCALL_ARGS) 
   
                 if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))                  if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))
                         return(0);                          return(0);
                 return((*tree->cb.roffblkbodyin)                  return((*tree->cb.roffblkbodyin)(tree->arg, tok, argcp,
                                 (tree->arg, tok, argcp, argvp));                                   (const char **)argvp));
         }          }
   
         /*          /*
Line 1170  roff_layout(ROFFCALL_ARGS) 
Line 1435  roff_layout(ROFFCALL_ARGS) 
                 if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))                  if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))
                         return(0);                          return(0);
                 return((*tree->cb.roffblkbodyin)                  return((*tree->cb.roffblkbodyin)
                                 (tree->arg, tok, argcp, argvp));                                  (tree->arg, tok, argcp,
                                    (const char **)argvp));
         }          }
   
         /*          /*
Line 1180  roff_layout(ROFFCALL_ARGS) 
Line 1446  roff_layout(ROFFCALL_ARGS) 
   
         if ( ! roffpurgepunct(tree, argv))          if ( ! roffpurgepunct(tree, argv))
                 return(0);                  return(0);
   
         if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))          if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))
                 return(0);                  return(0);
         return((*tree->cb.roffblkbodyin)          return((*tree->cb.roffblkbodyin)(tree->arg,
                         (tree->arg, tok, argcp, argvp));                                  tok, argcp, (const char **)argvp));
 }  }
   
   
Line 1196  roff_ordered(ROFFCALL_ARGS) 
Line 1461  roff_ordered(ROFFCALL_ARGS) 
         char            *ordp[ROFF_MAXLINEARG], *p,          char            *ordp[ROFF_MAXLINEARG], *p,
                         *argvp[ROFF_MAXLINEARG];                          *argvp[ROFF_MAXLINEARG];
   
           /*
            * Ordered macros pass their arguments directly to handlers,
            * instead of considering it free-form text.  Thus, the
            * following macro looks as follows:
            *
            * .Xr foo 1 ) ,
            *
            * .Xr arg1 arg2 punctuation
            */
   
         if (ROFF_PRELUDE & tree->state) {          if (ROFF_PRELUDE & tree->state) {
                 roff_err(tree, *argv, "`%s' disallowed in prelude",                  roff_err(tree, *argv, "`%s' disallowed in prelude",
                                 toknames[tok]);                                  toknames[tok]);
Line 1204  roff_ordered(ROFFCALL_ARGS) 
Line 1479  roff_ordered(ROFFCALL_ARGS) 
   
         first = (*argv == tree->cur);          first = (*argv == tree->cur);
         p = *argv++;          p = *argv++;
           ordp[0] = NULL;
   
         if ( ! roffparseopts(tree, tok, &argv, argcp, argvp))          if ( ! roffparseopts(tree, tok, &argv, argcp, argvp))
                 return(0);                  return(0);
   
         if (NULL == *argv) {          if (NULL == *argv)
                 ordp[0] = NULL;  
                 return(roffspecial(tree, tok, p, argcp,                  return(roffspecial(tree, tok, p, argcp,
                                         (const char **)argvp, 0, ordp));                                          (const char **)argvp, 0, ordp));
         }  
   
         i = 0;          i = 0;
         while (*argv && i < ROFF_MAXLINEARG) {          while (*argv && i < ROFF_MAXLINEARG) {
Line 1260  roff_text(ROFFCALL_ARGS) 
Line 1534  roff_text(ROFFCALL_ARGS) 
         int              i, j, first, c, argcp[ROFF_MAXLINEARG];          int              i, j, first, c, argcp[ROFF_MAXLINEARG];
         char            *argvp[ROFF_MAXLINEARG];          char            *argvp[ROFF_MAXLINEARG];
   
           /*
            * Text macros are similar to special tokens, except that
            * arguments are instead flushed as pure data: we're only
            * concerned with the macro and its arguments.  Example:
            *
            * .Fl v W f ;
            *
            * ...Produces...
            *
            * <fl> v W f </fl> ;
            */
   
         if (ROFF_PRELUDE & tree->state) {          if (ROFF_PRELUDE & tree->state) {
                 roff_err(tree, *argv, "`%s' disallowed in prelude",                  roff_err(tree, *argv, "`%s' disallowed in prelude",
                                 toknames[tok]);                                  toknames[tok]);
Line 1271  roff_text(ROFFCALL_ARGS) 
Line 1557  roff_text(ROFFCALL_ARGS) 
   
         if ( ! roffparseopts(tree, tok, &argv, argcp, argvp))          if ( ! roffparseopts(tree, tok, &argv, argcp, argvp))
                 return(0);                  return(0);
         if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp, argvp))          if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp,
                                   (const char **)argvp))
                 return(0);                  return(0);
         if (NULL == *argv)          if (NULL == *argv)
                 return((*tree->cb.roffout)(tree->arg, tok));                  return((*tree->cb.roffout)(tree->arg, tok));
Line 1332  roff_text(ROFFCALL_ARGS) 
Line 1619  roff_text(ROFFCALL_ARGS) 
                                 return(0);                                  return(0);
                         if ( ! roffdata(tree, 0, *argv++))                          if ( ! roffdata(tree, 0, *argv++))
                                 return(0);                                  return(0);
                         if ( ! (*tree->cb.roffin)(tree->arg, tok,                          if ( ! (*tree->cb.roffin)(tree->arg, tok,
                                                 argcp, argvp))                                                  argcp,
                                                   (const char **)argvp))
                                 return(0);                                  return(0);
   
                         i = 0;                          i = 0;

Legend:
Removed from v.1.49  
changed lines
  Added in v.1.52

CVSweb