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

Diff for /mandoc/roff.c between version 1.120 and 1.129

version 1.120, 2011/01/03 23:24:16 version 1.129, 2011/03/22 09:50:11
Line 28 
Line 28 
 #include <stdio.h>  #include <stdio.h>
   
 #include "mandoc.h"  #include "mandoc.h"
 #include "roff.h"  
 #include "libroff.h"  #include "libroff.h"
 #include "libmandoc.h"  #include "libmandoc.h"
   
Line 51  enum rofft {
Line 50  enum rofft {
         ROFF_ie,          ROFF_ie,
         ROFF_if,          ROFF_if,
         ROFF_ig,          ROFF_ig,
           ROFF_it,
         ROFF_ne,          ROFF_ne,
         ROFF_nh,          ROFF_nh,
         ROFF_nr,          ROFF_nr,
           ROFF_ns,
           ROFF_ps,
         ROFF_rm,          ROFF_rm,
         ROFF_so,          ROFF_so,
           ROFF_ta,
         ROFF_tr,          ROFF_tr,
         ROFF_TS,          ROFF_TS,
         ROFF_TE,          ROFF_TE,
         ROFF_T_,          ROFF_T_,
           ROFF_EQ,
           ROFF_EN,
         ROFF_cblock,          ROFF_cblock,
         ROFF_ccond, /* FIXME: remove this. */          ROFF_ccond, /* FIXME: remove this. */
         ROFF_USERDEF,          ROFF_USERDEF,
Line 78  struct roffstr {
Line 83  struct roffstr {
 };  };
   
 struct  roff {  struct  roff {
           struct mparse   *parse; /* parse point */
         struct roffnode *last; /* leaf of stack */          struct roffnode *last; /* leaf of stack */
         mandocmsg        msg; /* err/warn/fatal messages */  
         void            *data; /* privdata for messages */  
         enum roffrule    rstack[RSTACK_MAX]; /* stack of !`ie' rules */          enum roffrule    rstack[RSTACK_MAX]; /* stack of !`ie' rules */
         int              rstackpos; /* position in rstack */          int              rstackpos; /* position in rstack */
         struct regset   *regs; /* read/writable registers */          struct regset   *regs; /* read/writable registers */
Line 89  struct roff {
Line 93  struct roff {
         struct tbl_node *first_tbl; /* first table parsed */          struct tbl_node *first_tbl; /* first table parsed */
         struct tbl_node *last_tbl; /* last table parsed */          struct tbl_node *last_tbl; /* last table parsed */
         struct tbl_node *tbl; /* current table being parsed */          struct tbl_node *tbl; /* current table being parsed */
           struct eqn_node *last_eqn; /* last equation parsed */
           struct eqn_node *first_eqn; /* first equation parsed */
           struct eqn_node *eqn; /* current equation being parsed */
 };  };
   
 struct  roffnode {  struct  roffnode {
Line 134  static enum rofferr  roff_cond_sub(ROFF_ARGS);
Line 141  static enum rofferr  roff_cond_sub(ROFF_ARGS);
 static  enum rofferr     roff_ds(ROFF_ARGS);  static  enum rofferr     roff_ds(ROFF_ARGS);
 static  enum roffrule    roff_evalcond(const char *, int *);  static  enum roffrule    roff_evalcond(const char *, int *);
 static  void             roff_freestr(struct roff *);  static  void             roff_freestr(struct roff *);
   static  char            *roff_getname(struct roff *, char **, int, int);
 static  const char      *roff_getstrn(const struct roff *,  static  const char      *roff_getstrn(const struct roff *,
                                 const char *, size_t);                                  const char *, size_t);
 static  enum rofferr     roff_line_ignore(ROFF_ARGS);  static  enum rofferr     roff_line_ignore(ROFF_ARGS);
 static  enum rofferr     roff_line_error(ROFF_ARGS);  
 static  enum rofferr     roff_nr(ROFF_ARGS);  static  enum rofferr     roff_nr(ROFF_ARGS);
 static  int              roff_res(struct roff *,  static  int              roff_res(struct roff *,
                                 char **, size_t *, int);                                  char **, size_t *, int);
   static  enum rofferr     roff_rm(ROFF_ARGS);
 static  void             roff_setstr(struct roff *,  static  void             roff_setstr(struct roff *,
                                 const char *, const char *, int);                                  const char *, const char *, int);
 static  enum rofferr     roff_so(ROFF_ARGS);  static  enum rofferr     roff_so(ROFF_ARGS);
 static  enum rofferr     roff_TE(ROFF_ARGS);  static  enum rofferr     roff_TE(ROFF_ARGS);
 static  enum rofferr     roff_TS(ROFF_ARGS);  static  enum rofferr     roff_TS(ROFF_ARGS);
   static  enum rofferr     roff_EQ(ROFF_ARGS);
   static  enum rofferr     roff_EN(ROFF_ARGS);
 static  enum rofferr     roff_T_(ROFF_ARGS);  static  enum rofferr     roff_T_(ROFF_ARGS);
 static  enum rofferr     roff_userdef(ROFF_ARGS);  static  enum rofferr     roff_userdef(ROFF_ARGS);
   
Line 171  static struct roffmac  roffs[ROFF_MAX] = {
Line 181  static struct roffmac  roffs[ROFF_MAX] = {
         { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },          { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
         { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },          { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
         { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },          { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },
           { "it", roff_line_ignore, NULL, NULL, 0, NULL },
         { "ne", roff_line_ignore, NULL, NULL, 0, NULL },          { "ne", roff_line_ignore, NULL, NULL, 0, NULL },
         { "nh", roff_line_ignore, NULL, NULL, 0, NULL },          { "nh", roff_line_ignore, NULL, NULL, 0, NULL },
         { "nr", roff_nr, NULL, NULL, 0, NULL },          { "nr", roff_nr, NULL, NULL, 0, NULL },
         { "rm", roff_line_error, NULL, NULL, 0, NULL },          { "ns", roff_line_ignore, NULL, NULL, 0, NULL },
           { "ps", roff_line_ignore, NULL, NULL, 0, NULL },
           { "rm", roff_rm, NULL, NULL, 0, NULL },
         { "so", roff_so, NULL, NULL, 0, NULL },          { "so", roff_so, NULL, NULL, 0, NULL },
           { "ta", roff_line_ignore, NULL, NULL, 0, NULL },
         { "tr", roff_line_ignore, NULL, NULL, 0, NULL },          { "tr", roff_line_ignore, NULL, NULL, 0, NULL },
         { "TS", roff_TS, NULL, NULL, 0, NULL },          { "TS", roff_TS, NULL, NULL, 0, NULL },
         { "TE", roff_TE, NULL, NULL, 0, NULL },          { "TE", roff_TE, NULL, NULL, 0, NULL },
         { "T&", roff_T_, NULL, NULL, 0, NULL },          { "T&", roff_T_, NULL, NULL, 0, NULL },
           { "EQ", roff_EQ, NULL, NULL, 0, NULL },
           { "EN", roff_EN, NULL, NULL, 0, NULL },
         { ".", roff_cblock, NULL, NULL, 0, NULL },          { ".", roff_cblock, NULL, NULL, 0, NULL },
         { "\\}", roff_ccond, NULL, NULL, 0, NULL },          { "\\}", roff_ccond, NULL, NULL, 0, NULL },
         { NULL, roff_userdef, NULL, NULL, 0, NULL },          { NULL, roff_userdef, NULL, NULL, 0, NULL },
Line 302  static void
Line 318  static void
 roff_free1(struct roff *r)  roff_free1(struct roff *r)
 {  {
         struct tbl_node *t;          struct tbl_node *t;
           struct eqn_node *e;
   
         while (r->first_tbl) {          while (NULL != (t = r->first_tbl)) {
                 t = r->first_tbl;  
                 r->first_tbl = t->next;                  r->first_tbl = t->next;
                 tbl_free(t);                  tbl_free(t);
         }          }
   
         r->first_tbl = r->last_tbl = r->tbl = NULL;          r->first_tbl = r->last_tbl = r->tbl = NULL;
   
           while (NULL != (e = r->first_eqn)) {
                   r->first_eqn = e->next;
                   eqn_free(e);
           }
   
           r->first_eqn = r->last_eqn = r->eqn = NULL;
   
         while (r->last)          while (r->last)
                 roffnode_pop(r);                  roffnode_pop(r);
   
Line 336  roff_free(struct roff *r)
Line 359  roff_free(struct roff *r)
   
   
 struct roff *  struct roff *
 roff_alloc(struct regset *regs, void *data, const mandocmsg msg)  roff_alloc(struct regset *regs, struct mparse *parse)
 {  {
         struct roff     *r;          struct roff     *r;
   
         r = mandoc_calloc(1, sizeof(struct roff));          r = mandoc_calloc(1, sizeof(struct roff));
         r->regs = regs;          r->regs = regs;
         r->msg = msg;          r->parse = parse;
         r->data = data;  
         r->rstackpos = -1;          r->rstackpos = -1;
   
         roff_hash_init();          roff_hash_init();
Line 468  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 490  roff_parseln(struct roff *r, int ln, char **bufp, 
          * First, if a scope is open and we're not a macro, pass the           * First, if a scope is open and we're not a macro, pass the
          * text through the macro's filter.  If a scope isn't open and           * text through the macro's filter.  If a scope isn't open and
          * we're not a macro, just let it through.           * we're not a macro, just let it through.
            * Finally, if there's an equation scope open, divert it into it
            * no matter our state.
          */           */
   
         if (r->last && ! ROFF_CTL((*bufp)[pos])) {          if (r->last && ! ROFF_CTL((*bufp)[pos])) {
Line 476  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 500  roff_parseln(struct roff *r, int ln, char **bufp, 
                 e = (*roffs[t].text)                  e = (*roffs[t].text)
                         (r, t, bufp, szp, ln, pos, pos, offs);                          (r, t, bufp, szp, ln, pos, pos, offs);
                 assert(ROFF_IGN == e || ROFF_CONT == e);                  assert(ROFF_IGN == e || ROFF_CONT == e);
                 if (ROFF_CONT == e && r->tbl)                  if (ROFF_CONT != e)
                           return(e);
                   if (r->eqn)
                           return(eqn_read(&r->eqn, ln, *bufp, *offs));
                   if (r->tbl)
                         return(tbl_read(r->tbl, ln, *bufp, *offs));                          return(tbl_read(r->tbl, ln, *bufp, *offs));
                 return(e);                  return(ROFF_CONT);
         } else if ( ! ROFF_CTL((*bufp)[pos])) {          } else if ( ! ROFF_CTL((*bufp)[pos])) {
                   if (r->eqn)
                           return(eqn_read(&r->eqn, ln, *bufp, *offs));
                 if (r->tbl)                  if (r->tbl)
                         return(tbl_read(r->tbl, ln, *bufp, *offs));                          return(tbl_read(r->tbl, ln, *bufp, *offs));
                 return(ROFF_CONT);                  return(ROFF_CONT);
         }          } else if (r->eqn)
                   return(eqn_read(&r->eqn, ln, *bufp, *offs));
   
         /*          /*
          * If a scope is open, go to the child handler for that macro,           * If a scope is open, go to the child handler for that macro,
          * as it may want to preprocess before doing anything with it.           * as it may want to preprocess before doing anything with it.
            * Don't do so if an equation is open.
          */           */
   
         if (r->last) {          if (r->last) {
Line 520  roff_endparse(struct roff *r)
Line 552  roff_endparse(struct roff *r)
 {  {
   
         if (r->last)          if (r->last)
                 (*r->msg)(MANDOCERR_SCOPEEXIT, r->data,                  mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
                                 r->last->line, r->last->col, NULL);                                  r->last->line, r->last->col, NULL);
   
           if (r->eqn) {
                   mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
                                   r->eqn->eqn.line, r->eqn->eqn.pos, NULL);
                   eqn_end(r->eqn);
                   r->eqn = NULL;
           }
   
         if (r->tbl) {          if (r->tbl) {
                 (*r->msg)(MANDOCERR_SCOPEEXIT, r->data,                  mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
                                 r->tbl->line, r->tbl->pos, NULL);                                  r->tbl->line, r->tbl->pos, NULL);
                 tbl_end(r->tbl);                  tbl_end(r->tbl);
                 r->tbl = NULL;                  r->tbl = NULL;
Line 558  roff_parse(struct roff *r, const char *buf, int *pos)
Line 597  roff_parse(struct roff *r, const char *buf, int *pos)
         t = (r->current_string = roff_getstrn(r, mac, maclen))          t = (r->current_string = roff_getstrn(r, mac, maclen))
             ? ROFF_USERDEF : roff_hash_find(mac, maclen);              ? ROFF_USERDEF : roff_hash_find(mac, maclen);
   
         *pos += maclen;          *pos += (int)maclen;
         while (buf[*pos] && ' ' == buf[*pos])          while (buf[*pos] && ' ' == buf[*pos])
                 (*pos)++;                  (*pos)++;
   
Line 597  roff_cblock(ROFF_ARGS)
Line 636  roff_cblock(ROFF_ARGS)
          */           */
   
         if (NULL == r->last) {          if (NULL == r->last) {
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
Line 616  roff_cblock(ROFF_ARGS)
Line 655  roff_cblock(ROFF_ARGS)
         case (ROFF_ig):          case (ROFF_ig):
                 break;                  break;
         default:          default:
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
         if ((*bufp)[pos])          if ((*bufp)[pos])
                 (*r->msg)(MANDOCERR_ARGSLOST, r->data, ln, pos, NULL);                  mandoc_msg(MANDOCERR_ARGSLOST, r->parse, ln, pos, NULL);
   
         roffnode_pop(r);          roffnode_pop(r);
         roffnode_cleanscope(r);          roffnode_cleanscope(r);
Line 648  roff_ccond(ROFF_ARGS)
Line 687  roff_ccond(ROFF_ARGS)
 {  {
   
         if (NULL == r->last) {          if (NULL == r->last) {
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
Line 660  roff_ccond(ROFF_ARGS)
Line 699  roff_ccond(ROFF_ARGS)
         case (ROFF_if):          case (ROFF_if):
                 break;                  break;
         default:          default:
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
         if (r->last->endspan > -1) {          if (r->last->endspan > -1) {
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
         if ((*bufp)[pos])          if ((*bufp)[pos])
                 (*r->msg)(MANDOCERR_ARGSLOST, r->data, ln, pos, NULL);                  mandoc_msg(MANDOCERR_ARGSLOST, r->parse, ln, pos, NULL);
   
         roffnode_pop(r);          roffnode_pop(r);
         roffnode_cleanscope(r);          roffnode_cleanscope(r);
Line 690  roff_block(ROFF_ARGS)
Line 729  roff_block(ROFF_ARGS)
   
         if (ROFF_ig != tok) {          if (ROFF_ig != tok) {
                 if ('\0' == (*bufp)[pos]) {                  if ('\0' == (*bufp)[pos]) {
                         (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL);                          mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL);
                         return(ROFF_IGN);                          return(ROFF_IGN);
                 }                  }
   
Line 704  roff_block(ROFF_ARGS)
Line 743  roff_block(ROFF_ARGS)
                 if (ROFF_de == tok)                  if (ROFF_de == tok)
                         name = *bufp + pos;                          name = *bufp + pos;
                 else                  else
                         (*r->msg)(MANDOCERR_REQUEST, r->data, ln, ppos,                          mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos,
                             roffs[tok].name);                              roffs[tok].name);
   
                 while ((*bufp)[pos] && ' ' != (*bufp)[pos])                  while ((*bufp)[pos] && ' ' != (*bufp)[pos])
Line 754  roff_block(ROFF_ARGS)
Line 793  roff_block(ROFF_ARGS)
         r->last->end[(int)sz] = '\0';          r->last->end[(int)sz] = '\0';
   
         if ((*bufp)[pos])          if ((*bufp)[pos])
                 (*r->msg)(MANDOCERR_ARGSLOST, r->data, ln, pos, NULL);                  mandoc_msg(MANDOCERR_ARGSLOST, r->parse, ln, pos, NULL);
   
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
Line 934  static enum rofferr
Line 973  static enum rofferr
 roff_line_ignore(ROFF_ARGS)  roff_line_ignore(ROFF_ARGS)
 {  {
   
         return(ROFF_IGN);          if (ROFF_it == tok)
 }                  mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, "it");
   
 /* ARGSUSED */  
 static enum rofferr  
 roff_line_error(ROFF_ARGS)  
 {  
   
         (*r->msg)(MANDOCERR_REQUEST, r->data, ln, ppos, roffs[tok].name);  
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
   
Line 956  roff_cond(ROFF_ARGS)
Line 989  roff_cond(ROFF_ARGS)
         /* Stack overflow! */          /* Stack overflow! */
   
         if (ROFF_ie == tok && r->rstackpos == RSTACK_MAX - 1) {          if (ROFF_ie == tok && r->rstackpos == RSTACK_MAX - 1) {
                 (*r->msg)(MANDOCERR_MEM, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_MEM, r->parse, ln, ppos, NULL);
                 return(ROFF_ERR);                  return(ROFF_ERR);
         }          }
   
Line 987  roff_cond(ROFF_ARGS)
Line 1020  roff_cond(ROFF_ARGS)
          */           */
   
         if ('\0' == (*bufp)[pos] && sv != pos) {          if ('\0' == (*bufp)[pos] && sv != pos) {
                 (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
Line 1056  roff_ds(ROFF_ARGS)
Line 1089  roff_ds(ROFF_ARGS)
          * will have `bar  "     ' as its value.           * will have `bar  "     ' as its value.
          */           */
   
         name = *bufp + pos;          string = *bufp + pos;
           name = roff_getname(r, &string, ln, pos);
         if ('\0' == *name)          if ('\0' == *name)
                 return(ROFF_IGN);                  return(ROFF_IGN);
   
         string = name;          /* Read past initial double-quote. */
         /* Read until end of name. */          if ('"' == *string)
         while (*string && ' ' != *string)  
                 string++;                  string++;
   
         /* Nil-terminate name. */  
         if (*string)  
                 *(string++) = '\0';  
   
         /* Read past spaces. */  
         while (*string && ' ' == *string)  
                 string++;  
   
         /* Read passed initial double-quote. */  
         if (*string && '"' == *string)  
                 string++;  
   
         /* The rest is the value. */          /* The rest is the value. */
         roff_setstr(r, name, string, 0);          roff_setstr(r, name, string, 0);
         return(ROFF_IGN);          return(ROFF_IGN);
Line 1087  roff_ds(ROFF_ARGS)
Line 1108  roff_ds(ROFF_ARGS)
 static enum rofferr  static enum rofferr
 roff_nr(ROFF_ARGS)  roff_nr(ROFF_ARGS)
 {  {
         const char      *key, *val;          const char      *key;
           char            *val;
         struct reg      *rg;          struct reg      *rg;
   
         key = &(*bufp)[pos];          val = *bufp + pos;
           key = roff_getname(r, &val, ln, pos);
         rg = r->regs->regs;          rg = r->regs->regs;
   
         /* Parse register request. */  
         while ((*bufp)[pos] && ' ' != (*bufp)[pos])  
                 pos++;  
   
         /*  
          * Set our nil terminator.  Because this line is going to be  
          * ignored anyway, we can munge it as we please.  
          */  
         if ((*bufp)[pos])  
                 (*bufp)[pos++] = '\0';  
   
         /* Skip whitespace to register token. */  
         while ((*bufp)[pos] && ' ' == (*bufp)[pos])  
                 pos++;  
   
         val = &(*bufp)[pos];  
   
         /* Process register token. */  
   
         if (0 == strcmp(key, "nS")) {          if (0 == strcmp(key, "nS")) {
                 rg[(int)REG_nS].set = 1;                  rg[(int)REG_nS].set = 1;
                 if ( ! roff_parse_nat(val, &rg[(int)REG_nS].v.u))                  if ( ! roff_parse_nat(val, &rg[(int)REG_nS].v.u))
Line 1123  roff_nr(ROFF_ARGS)
Line 1127  roff_nr(ROFF_ARGS)
   
 /* ARGSUSED */  /* ARGSUSED */
 static enum rofferr  static enum rofferr
   roff_rm(ROFF_ARGS)
   {
           const char       *name;
           char             *cp;
   
           cp = *bufp + pos;
           while ('\0' != *cp) {
                   name = roff_getname(r, &cp, ln, (int)(cp - *bufp));
                   if ('\0' != *name)
                           roff_setstr(r, name, NULL, 0);
           }
           return(ROFF_IGN);
   }
   
   /* ARGSUSED */
   static enum rofferr
 roff_TE(ROFF_ARGS)  roff_TE(ROFF_ARGS)
 {  {
   
         if (NULL == r->tbl)          if (NULL == r->tbl)
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
         else          else
                 tbl_end(r->tbl);                  tbl_end(r->tbl);
   
Line 1141  roff_T_(ROFF_ARGS)
Line 1161  roff_T_(ROFF_ARGS)
 {  {
   
         if (NULL == r->tbl)          if (NULL == r->tbl)
                 (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
         else          else
                 tbl_restart(ppos, ln, r->tbl);                  tbl_restart(ppos, ln, r->tbl);
   
Line 1150  roff_T_(ROFF_ARGS)
Line 1170  roff_T_(ROFF_ARGS)
   
 /* ARGSUSED */  /* ARGSUSED */
 static enum rofferr  static enum rofferr
   roff_EQ(ROFF_ARGS)
   {
           struct eqn_node *e;
   
           assert(NULL == r->eqn);
           e = eqn_alloc(ppos, ln);
   
           if (r->last_eqn)
                   r->last_eqn->next = e;
           else
                   r->first_eqn = r->last_eqn = e;
   
           r->eqn = r->last_eqn = e;
           return(ROFF_IGN);
   }
   
   /* ARGSUSED */
   static enum rofferr
   roff_EN(ROFF_ARGS)
   {
   
           mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
           return(ROFF_IGN);
   }
   
   /* ARGSUSED */
   static enum rofferr
 roff_TS(ROFF_ARGS)  roff_TS(ROFF_ARGS)
 {  {
         struct tbl_node *t;          struct tbl_node *t;
   
         if (r->tbl) {          if (r->tbl) {
                 (*r->msg)(MANDOCERR_SCOPEBROKEN, r->data, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_SCOPEBROKEN, r->parse, ln, ppos, NULL);
                 tbl_end(r->tbl);                  tbl_end(r->tbl);
         }          }
   
         t = tbl_alloc(ppos, ln, r->data, r->msg);          t = tbl_alloc(ppos, ln, r->parse);
   
         if (r->last_tbl)          if (r->last_tbl)
                 r->last_tbl->next = t;                  r->last_tbl->next = t;
Line 1176  roff_so(ROFF_ARGS)
Line 1223  roff_so(ROFF_ARGS)
 {  {
         char *name;          char *name;
   
         (*r->msg)(MANDOCERR_SO, r->data, ln, ppos, NULL);          mandoc_msg(MANDOCERR_SO, r->parse, ln, ppos, NULL);
   
         /*          /*
          * Handle `so'.  Be EXTREMELY careful, as we shouldn't be           * Handle `so'.  Be EXTREMELY careful, as we shouldn't be
Line 1187  roff_so(ROFF_ARGS)
Line 1234  roff_so(ROFF_ARGS)
   
         name = *bufp + pos;          name = *bufp + pos;
         if ('/' == *name || strstr(name, "../") || strstr(name, "/..")) {          if ('/' == *name || strstr(name, "../") || strstr(name, "/..")) {
                 (*r->msg)(MANDOCERR_SOPATH, r->data, ln, pos, NULL);                  mandoc_msg(MANDOCERR_SOPATH, r->parse, ln, pos, NULL);
                 return(ROFF_ERR);                  return(ROFF_ERR);
         }          }
   
Line 1210  roff_userdef(ROFF_ARGS)
Line 1257  roff_userdef(ROFF_ARGS)
         cp = *bufp + pos;          cp = *bufp + pos;
         for (i = 0; i < 9; i++)          for (i = 0; i < 9; i++)
                 arg[i] = '\0' == *cp ? "" :                  arg[i] = '\0' == *cp ? "" :
                     mandoc_getarg(&cp, r->msg, r->data, ln, &pos);                      mandoc_getarg(r->parse, &cp, ln, &pos);
   
         /*          /*
          * Expand macro arguments.           * Expand macro arguments.
Line 1250  roff_userdef(ROFF_ARGS)
Line 1297  roff_userdef(ROFF_ARGS)
            ROFF_REPARSE : ROFF_APPEND);             ROFF_REPARSE : ROFF_APPEND);
 }  }
   
   static char *
   roff_getname(struct roff *r, char **cpp, int ln, int pos)
   {
           char     *name, *cp;
   
           name = *cpp;
           if ('\0' == *name)
                   return(name);
   
           /* Read until end of name. */
           for (cp = name; '\0' != *cp && ' ' != *cp; cp++) {
                   if ('\\' != *cp)
                           continue;
                   cp++;
                   if ('\\' == *cp)
                           continue;
                   mandoc_msg(MANDOCERR_NAMESC, r->parse, ln, pos, NULL);
                   *cp = '\0';
                   name = cp;
           }
   
           /* Nil-terminate name. */
           if ('\0' != *cp)
                   *(cp++) = '\0';
   
           /* Read past spaces. */
           while (' ' == *cp)
                   cp++;
   
           *cpp = cp;
           return(name);
   }
   
 /*  /*
  * Store *string into the user-defined string called *name.   * Store *string into the user-defined string called *name.
  * In multiline mode, append to an existing entry and append '\n';   * In multiline mode, append to an existing entry and append '\n';
Line 1289  roff_setstr(struct roff *r, const char *name, const ch
Line 1369  roff_setstr(struct roff *r, const char *name, const ch
          * One additional byte for the '\n' in multiline mode,           * One additional byte for the '\n' in multiline mode,
          * and one for the terminating '\0'.           * and one for the terminating '\0'.
          */           */
         newch = strlen(string) + (multiline ? 2 : 1);          newch = strlen(string) + (multiline ? 2u : 1u);
         if (NULL == n->string) {          if (NULL == n->string) {
                 n->string = mandoc_malloc(newch);                  n->string = mandoc_malloc(newch);
                 *n->string = '\0';                  *n->string = '\0';
Line 1300  roff_setstr(struct roff *r, const char *name, const ch
Line 1380  roff_setstr(struct roff *r, const char *name, const ch
         }          }
   
         /* Skip existing content in the destination buffer. */          /* Skip existing content in the destination buffer. */
         c = n->string + oldch;          c = n->string + (int)oldch;
   
         /* Append new content to the destination buffer. */          /* Append new content to the destination buffer. */
         while (*string) {          while (*string) {
Line 1319  roff_setstr(struct roff *r, const char *name, const ch
Line 1399  roff_setstr(struct roff *r, const char *name, const ch
         *c = '\0';          *c = '\0';
 }  }
   
   
 static const char *  static const char *
 roff_getstrn(const struct roff *r, const char *name, size_t len)  roff_getstrn(const struct roff *r, const char *name, size_t len)
 {  {
Line 1332  roff_getstrn(const struct roff *r, const char *name, s
Line 1411  roff_getstrn(const struct roff *r, const char *name, s
         return(n ? n->string : NULL);          return(n ? n->string : NULL);
 }  }
   
   
 static void  static void
 roff_freestr(struct roff *r)  roff_freestr(struct roff *r)
 {  {
Line 1353  roff_span(const struct roff *r)
Line 1431  roff_span(const struct roff *r)
 {  {
   
         return(r->tbl ? tbl_span(r->tbl) : NULL);          return(r->tbl ? tbl_span(r->tbl) : NULL);
   }
   
   const struct eqn *
   roff_eqn(const struct roff *r)
   {
   
           return(r->last_eqn ? &r->last_eqn->eqn : NULL);
 }  }

Legend:
Removed from v.1.120  
changed lines
  Added in v.1.129

CVSweb