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

Diff for /mandoc/roff.c between version 1.14 and 1.15

version 1.14, 2008/11/28 11:21:12 version 1.15, 2008/11/28 15:25:49
Line 80  struct roffarg {
Line 80  struct roffarg {
 struct  roffnode {  struct  roffnode {
         int               tok;                  /* Token id. */          int               tok;                  /* Token id. */
         struct roffnode  *parent;               /* Parent (or NULL). */          struct roffnode  *parent;               /* Parent (or NULL). */
         size_t            line;                 /* Parsed at line. */  
 };  };
   
 struct  rofftree {  struct  rofftree {
Line 100  struct rofftree {
Line 99  struct rofftree {
 #define ROFF_PRELUDE_Dd  (1 << 4)               /* `Dd' is parsed. */  #define ROFF_PRELUDE_Dd  (1 << 4)               /* `Dd' is parsed. */
 #define ROFF_BODY        (1 << 5)               /* In roff body. */  #define ROFF_BODY        (1 << 5)               /* In roff body. */
   
         struct md_mbuf          *mbuf;          /* Output (or NULL). */          struct roffcb     cb;
         const struct md_args    *args;          /* Global args. */          void             *arg;
         const struct md_rbuf    *rbuf;          /* Input. */  
         const struct roffcb     *cb;  
 };  };
   
 static  int               roff_Dd(ROFFCALL_ARGS);  static  int               roff_Dd(ROFFCALL_ARGS);
Line 117  static int    roff_close(ROFFCALL_ARGS);
Line 114  static int    roff_close(ROFFCALL_ARGS);
 static  int               roff_special(ROFFCALL_ARGS);  static  int               roff_special(ROFFCALL_ARGS);
   
 static  struct roffnode  *roffnode_new(int, struct rofftree *);  static  struct roffnode  *roffnode_new(int, struct rofftree *);
 static  void              roffnode_free(int, struct rofftree *);  static  void              roffnode_free(struct rofftree *);
   
 static  void              roff_warn(const struct rofftree *,  static  void              roff_warn(const struct rofftree *,
                                 const char *, char *, ...);                                  const char *, char *, ...);
Line 360  const char *const *tokargnames = tokargnamesp;
Line 357  const char *const *tokargnames = tokargnamesp;
 int  int
 roff_free(struct rofftree *tree, int flush)  roff_free(struct rofftree *tree, int flush)
 {  {
         int              error, tok;          int              error;
           struct roffnode *n;
   
         assert(tree->mbuf);          error = 0;
         if ( ! flush)  
                 tree->mbuf = NULL;  
   
         /* LINTED */          for (n = tree->last; n->parent; n = n->parent)
         while (tree->last) {                  if (tokens[n->tok].ctx == 0) {
                 if (tree->last->parent) {                          roff_warn(tree, NULL, "closing explicit scope "
                         tok = tree->last->tok;                                          "of `%s'", toknames[n->tok]);
                         if (tokens[tok].ctx == 0) {                          error = 1;
                                 warnx("%s: closing out explicit scope "  
                                                 "of `%s' from line %zu",  
                                                 tree->rbuf->name,  
                                                 toknames[tok],  
                                                 tree->last->line);  
                                 tree->mbuf = NULL;  
                         }  
                 }                  }
                 if ( ! (*tokens[tree->last->tok].cb)  
                                 (tree->last->tok, tree, NULL, ROFF_EXIT))  
                         /* Disallow flushing. */  
                         tree->mbuf = NULL;  
         }  
   
         error = tree->mbuf ? 0 : 1;          if (0 == error && (ROFF_PRELUDE & tree->state)) {
                   roff_warn(tree, NULL, "prelude never finished");
         if (tree->mbuf && (ROFF_PRELUDE & tree->state)) {  
                 warnx("%s: prelude never finished",  
                                 tree->rbuf->name);  
                 error = 1;                  error = 1;
         }          }
   
           while (tree->last)
                   roffnode_free(tree);
   
         free(tree);          free(tree);
         return(error ? 0 : 1);          return(error ? 0 : 1);
 }  }
   
   
 struct rofftree *  struct rofftree *
 roff_alloc(const struct md_args *args, struct md_mbuf *out,  roff_alloc(const struct roffcb *cb, void *args)
                 const struct md_rbuf *in, const struct roffcb *cb)  
 {  {
         struct rofftree *tree;          struct rofftree *tree;
   
Line 408  roff_alloc(const struct md_args *args, struct md_mbuf 
Line 391  roff_alloc(const struct md_args *args, struct md_mbuf 
                 err(1, "calloc");                  err(1, "calloc");
   
         tree->state = ROFF_PRELUDE;          tree->state = ROFF_PRELUDE;
         tree->args = args;          tree->arg = args;
         tree->mbuf = out;  
         tree->rbuf = in;  
         tree->cb = cb;  
   
           (void)memcpy(&tree->cb, cb, sizeof(struct roffcb));
   
         return(tree);          return(tree);
 }  }
   
Line 550  roffparse(struct rofftree *tree, char *buf, size_t sz)
Line 532  roffparse(struct rofftree *tree, char *buf, size_t sz)
          */           */
   
         if ( ! roffscan(tree->last->tok, tokens[tok].parents)) {          if ( ! roffscan(tree->last->tok, tokens[tok].parents)) {
                 roff_err(tree, *argvp, "`%s' has invalid parent `%s' "                  roff_err(tree, *argvp, "`%s' has invalid parent `%s'",
                                 "from line %zu", toknames[tok],                                  toknames[tok],
                                 toknames[tree->rbuf->line],                                  toknames[tree->last->tok]);
                                 tree->rbuf->line);  
                 return(0);                  return(0);
         }          }
   
         if ( ! roffscan(tok, tokens[tree->last->tok].children)) {          if ( ! roffscan(tok, tokens[tree->last->tok].children)) {
                 roff_err(tree, *argvp, "`%s' is invalid child for "                  roff_err(tree, *argvp, "`%s' is invalid child `%s'",
                                 "`%s' from line %zu", toknames[tok],                                  toknames[tree->last->tok],
                                 toknames[tree->rbuf->line],                                  toknames[tok]);
                                 tree->rbuf->line);  
                 return(0);                  return(0);
         }          }
   
Line 717  roffnode_new(int tokid, struct rofftree *tree)
Line 697  roffnode_new(int tokid, struct rofftree *tree)
         if (NULL == (p = malloc(sizeof(struct roffnode))))          if (NULL == (p = malloc(sizeof(struct roffnode))))
                 err(1, "malloc");                  err(1, "malloc");
   
         p->line = tree->rbuf->line;  
         p->tok = tokid;          p->tok = tokid;
         p->parent = tree->last;          p->parent = tree->last;
         tree->last = p;          tree->last = p;
Line 743  roffargok(int tokid, int argid)
Line 722  roffargok(int tokid, int argid)
   
   
 static void  static void
 roffnode_free(int tokid, struct rofftree *tree)  roffnode_free(struct rofftree *tree)
 {  {
         struct roffnode *p;          struct roffnode *p;
   
         assert(tree->last);          assert(tree->last);
         assert(tree->last->tok == tokid);  
   
         p = tree->last;          p = tree->last;
         tree->last = tree->last->parent;          tree->last = tree->last->parent;
Line 908  roff_layout(ROFFCALL_ARGS) 
Line 886  roff_layout(ROFFCALL_ARGS) 
         }          }
   
         if (ROFF_EXIT == type) {          if (ROFF_EXIT == type) {
                 roffnode_free(tok, tree);                  roffnode_free(tree);
                 return((*tree->cb->roffblkout)(tree->args, tok));                  return((*tree->cb.roffblkout)(tree->arg, tok));
         }          }
   
         assert(tree->mbuf);  
   
         i = 0;          i = 0;
         argv++;          argv++;
   
Line 933  roff_layout(ROFFCALL_ARGS) 
Line 909  roff_layout(ROFFCALL_ARGS) 
         if (NULL == roffnode_new(tok, tree))          if (NULL == roffnode_new(tok, tree))
                 return(0);                  return(0);
   
         if ( ! (*tree->cb->roffin)(tree->args, tok, argcp, argvp))          if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp, argvp))
                 return(0);                  return(0);
   
         if ( ! (ROFF_PARSED & tokens[tok].flags)) {          if ( ! (ROFF_PARSED & tokens[tok].flags)) {
                 while (*argv) {                  while (*argv) {
                         if ( ! md_buf_putstring(tree->mbuf, *argv++))                          if ( ! (*tree->cb.roffdata)
                                           (tree->arg, *argv++))
                                 return(0);                                  return(0);
                         if ( ! md_buf_putchar(tree->mbuf, ' '))  
                                 return(0);  
                 }                  }
   
                 if ( ! md_buf_putchar(tree->mbuf, '\n'))                  if ( ! ((*tree->cb.roffout)(tree->arg, tok)))
                         return(0);                          return(0);
                   return((*tree->cb.roffblkin)(tree->arg, tok));
                 if ( ! ((*tree->cb->roffout)(tree->args, tok)))  
                         return(0);  
                 return((*tree->cb->roffblkin)(tree->args, tok));  
         }          }
   
         while (*argv) {          while (*argv) {
Line 965  roff_layout(ROFFCALL_ARGS) 
Line 937  roff_layout(ROFFCALL_ARGS) 
                         break;                          break;
                 }                  }
   
                 if ( ! md_buf_putstring(tree->mbuf, *argv++))                  if ( ! (*tree->cb.roffdata)(tree->arg, *argv++))
                         return(0);                          return(0);
                 if ( ! md_buf_putchar(tree->mbuf, ' '))  
                         return(0);  
         }          }
   
         if (NULL == *argv && ! md_buf_putchar(tree->mbuf, '\n'))          if ( ! ((*tree->cb.roffout)(tree->arg, tok)))
                 return(0);                  return(0);
           return((*tree->cb.roffblkin)(tree->arg, tok));
         if ( ! ((*tree->cb->roffout)(tree->args, tok)))  
                 return(0);  
         return((*tree->cb->roffblkin)(tree->args, tok));  
 }  }
   
   
Line 987  roff_text(ROFFCALL_ARGS) 
Line 954  roff_text(ROFFCALL_ARGS) 
         int              i, c, argcp[ROFF_MAXARG];          int              i, c, argcp[ROFF_MAXARG];
         char            *v, *argvp[ROFF_MAXARG];          char            *v, *argvp[ROFF_MAXARG];
   
         assert(tree->mbuf);  
   
         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 1011  roff_text(ROFFCALL_ARGS) 
Line 976  roff_text(ROFFCALL_ARGS) 
         argcp[i] = ROFF_ARGMAX;          argcp[i] = ROFF_ARGMAX;
         argvp[i] = NULL;          argvp[i] = NULL;
   
         if ( ! (*tree->cb->roffin)(tree->args, tok, argcp, argvp))          if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp, argvp))
                 return(0);                  return(0);
   
         if ( ! (ROFF_PARSED & tokens[tok].flags)) {          if ( ! (ROFF_PARSED & tokens[tok].flags)) {
                 while (*argv) {                  while (*argv) {
                         if ( ! md_buf_putstring(tree->mbuf, *argv++))                          if ( ! (*tree->cb.roffdata)(tree->arg, *argv++))
                                 return(0);                                  return(0);
                         if ( ! md_buf_putchar(tree->mbuf, ' '))  
                                 return(0);  
                 }                  }
                 if ( ! md_buf_putchar(tree->mbuf, '\n'))                  return((*tree->cb.roffout)(tree->arg, tok));
                         return(0);  
                 return((*tree->cb->roffout)(tree->args, tok));  
         }          }
   
         while (*argv) {          while (*argv) {
Line 1039  roff_text(ROFFCALL_ARGS) 
Line 1000  roff_text(ROFFCALL_ARGS) 
                                 return(0);                                  return(0);
                         break;                          break;
                 }                  }
                   if ( ! (*tree->cb.roffdata)(tree->arg, *argv++))
                 if ( ! md_buf_putstring(tree->mbuf, *argv++))  
                         return(0);                          return(0);
                 if ( ! md_buf_putchar(tree->mbuf, ' '))  
                         return(0);  
         }          }
   
         if (NULL == *argv && ! md_buf_putchar(tree->mbuf, '\n'))          return((*tree->cb.roffout)(tree->arg, tok));
                 return(0);  
   
         return((*tree->cb->roffout)(tree->args, tok));  
 }  }
   
   
Line 1076  static int
Line 1031  static int
 roff_special(ROFFCALL_ARGS)  roff_special(ROFFCALL_ARGS)
 {  {
   
         return((*tree->cb->roffspecial)(tree->args, tok));          return((*tree->cb.roffspecial)(tree->arg, tok));
 }  }
   
   
Line 1090  roff_warn(const struct rofftree *tree, const char *pos
Line 1045  roff_warn(const struct rofftree *tree, const char *pos
         (void)vsnprintf(buf, sizeof(buf), fmt, ap);          (void)vsnprintf(buf, sizeof(buf), fmt, ap);
         va_end(ap);          va_end(ap);
   
         (*tree->cb->roffmsg)(tree->args, ROFF_WARN, tree->cur, pos,          (*tree->cb.roffmsg)(tree->arg,
                         tree->rbuf->name, tree->rbuf->line, buf);                          ROFF_WARN, tree->cur, pos, buf);
 }  }
   
   
Line 1105  roff_err(const struct rofftree *tree, const char *pos,
Line 1060  roff_err(const struct rofftree *tree, const char *pos,
         (void)vsnprintf(buf, sizeof(buf), fmt, ap);          (void)vsnprintf(buf, sizeof(buf), fmt, ap);
         va_end(ap);          va_end(ap);
   
         (*tree->cb->roffmsg)(tree->args, ROFF_ERROR, tree->cur, pos,          (*tree->cb.roffmsg)(tree->arg,
                         tree->rbuf->name, tree->rbuf->line, buf);                          ROFF_ERROR, tree->cur, pos, buf);
 }  }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

CVSweb