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

Diff for /mandoc/roff.c between version 1.127 and 1.131

version 1.127, 2011/03/15 16:23:51 version 1.131, 2011/04/05 22:22:33
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"
   
 #define RSTACK_MAX      128  #define RSTACK_MAX      128
   
 #define ROFF_CTL(c) \  
         ('.' == (c) || '\'' == (c))  
   
 enum    rofft {  enum    rofft {
         ROFF_ad,          ROFF_ad,
         ROFF_am,          ROFF_am,
Line 84  struct roffstr {
Line 80  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 361  roff_free(struct roff *r)
Line 356  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 479  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 473  roff_parseln(struct roff *r, int ln, char **bufp, 
 {  {
         enum rofft       t;          enum rofft       t;
         enum rofferr     e;          enum rofferr     e;
         int              ppos;          int              ppos, ctl;
   
         /*          /*
          * Run the reserved-word filter only if we have some reserved           * Run the reserved-word filter only if we have some reserved
Line 489  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 483  roff_parseln(struct roff *r, int ln, char **bufp, 
         if (r->first_string && ! roff_res(r, bufp, szp, pos))          if (r->first_string && ! roff_res(r, bufp, szp, pos))
                 return(ROFF_REPARSE);                  return(ROFF_REPARSE);
   
           ppos = pos;
           ctl = mandoc_getcontrol(*bufp, &pos);
   
         /*          /*
          * 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
Line 497  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 494  roff_parseln(struct roff *r, int ln, char **bufp, 
          * no matter our state.           * no matter our state.
          */           */
   
         if (r->last && ! ROFF_CTL((*bufp)[pos])) {          if (r->last && ! ctl) {
                 t = r->last->tok;                  t = r->last->tok;
                 assert(roffs[t].text);                  assert(roffs[t].text);
                 e = (*roffs[t].text)                  e = (*roffs[t].text)
Line 506  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 503  roff_parseln(struct roff *r, int ln, char **bufp, 
                 if (ROFF_CONT != e)                  if (ROFF_CONT != e)
                         return(e);                          return(e);
                 if (r->eqn)                  if (r->eqn)
                         return(eqn_read(&r->eqn, ln, *bufp, *offs));                          return(eqn_read(&r->eqn, ln, *bufp, pos));
                 if (r->tbl)                  if (r->tbl)
                         return(tbl_read(r->tbl, ln, *bufp, *offs));                          return(tbl_read(r->tbl, ln, *bufp, pos));
                 return(ROFF_CONT);                  return(ROFF_CONT);
         } else if ( ! ROFF_CTL((*bufp)[pos])) {          } else if ( ! ctl) {
                 if (r->eqn)                  if (r->eqn)
                         return(eqn_read(&r->eqn, ln, *bufp, *offs));                          return(eqn_read(&r->eqn, ln, *bufp, pos));
                 if (r->tbl)                  if (r->tbl)
                         return(tbl_read(r->tbl, ln, *bufp, *offs));                          return(tbl_read(r->tbl, ln, *bufp, pos));
                 return(ROFF_CONT);                  return(ROFF_CONT);
         } else if (r->eqn)          } else if (r->eqn)
                 return(eqn_read(&r->eqn, ln, *bufp, *offs));                  return(eqn_read(&r->eqn, ln, *bufp, ppos));
   
         /*          /*
          * 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,
Line 530  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 527  roff_parseln(struct roff *r, int ln, char **bufp, 
                 assert(roffs[t].sub);                  assert(roffs[t].sub);
                 return((*roffs[t].sub)                  return((*roffs[t].sub)
                                 (r, t, bufp, szp,                                  (r, t, bufp, szp,
                                  ln, pos, pos, offs));                                   ln, ppos, pos, offs));
         }          }
   
         /*          /*
Line 539  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 536  roff_parseln(struct roff *r, int ln, char **bufp, 
          * the compilers handle it.           * the compilers handle it.
          */           */
   
         ppos = pos;  
         if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos)))          if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos)))
                 return(ROFF_CONT);                  return(ROFF_CONT);
   
Line 555  roff_endparse(struct roff *r)
Line 551  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) {          if (r->eqn) {
                 (*r->msg)(MANDOCERR_SCOPEEXIT, r->data,                  mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
                                 r->eqn->eqn.line, r->eqn->eqn.pos, NULL);                                  r->eqn->eqn.line, r->eqn->eqn.pos, NULL);
                 eqn_end(r->eqn);                  eqn_end(r->eqn);
                 r->eqn = NULL;                  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;
         }          }
 }  }
   
   
 /*  /*
  * Parse a roff node's type from the input buffer.  This must be in the   * Parse a roff node's type from the input buffer.  This must be in the
  * form of ".foo xxx" in the usual way.   * form of ".foo xxx" in the usual way.
Line 585  roff_parse(struct roff *r, const char *buf, int *pos)
Line 580  roff_parse(struct roff *r, const char *buf, int *pos)
         size_t           maclen;          size_t           maclen;
         enum rofft       t;          enum rofft       t;
   
         assert(ROFF_CTL(buf[*pos]));          if ('\0' == buf[*pos] || '"' == buf[*pos])
         (*pos)++;  
   
         while (' ' == buf[*pos] || '\t' == buf[*pos])  
                 (*pos)++;  
   
         if ('\0' == buf[*pos])  
                 return(ROFF_MAX);                  return(ROFF_MAX);
   
         mac = buf + *pos;          mac = buf + *pos;
Line 601  roff_parse(struct roff *r, const char *buf, int *pos)
Line 590  roff_parse(struct roff *r, const char *buf, int *pos)
             ? ROFF_USERDEF : roff_hash_find(mac, maclen);              ? ROFF_USERDEF : roff_hash_find(mac, maclen);
   
         *pos += (int)maclen;          *pos += (int)maclen;
   
         while (buf[*pos] && ' ' == buf[*pos])          while (buf[*pos] && ' ' == buf[*pos])
                 (*pos)++;                  (*pos)++;
   
Line 639  roff_cblock(ROFF_ARGS)
Line 629  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 658  roff_cblock(ROFF_ARGS)
Line 648  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 690  roff_ccond(ROFF_ARGS)
Line 680  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 702  roff_ccond(ROFF_ARGS)
Line 692  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 732  roff_block(ROFF_ARGS)
Line 722  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 746  roff_block(ROFF_ARGS)
Line 736  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] && ! isspace((unsigned char)(*bufp)[pos]))
                         pos++;                          pos++;
   
                 while (' ' == (*bufp)[pos])                  while (isspace((unsigned char)(*bufp)[pos]))
                         (*bufp)[pos++] = '\0';                          (*bufp)[pos++] = '\0';
         }          }
   
Line 773  roff_block(ROFF_ARGS)
Line 763  roff_block(ROFF_ARGS)
         /* If present, process the custom end-of-line marker. */          /* If present, process the custom end-of-line marker. */
   
         sv = pos;          sv = pos;
         while ((*bufp)[pos] &&          while ((*bufp)[pos] && ! isspace((unsigned char)(*bufp)[pos]))
                         ' ' != (*bufp)[pos] &&  
                         '\t' != (*bufp)[pos])  
                 pos++;                  pos++;
   
         /*          /*
Line 796  roff_block(ROFF_ARGS)
Line 784  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 819  roff_block_sub(ROFF_ARGS)
Line 807  roff_block_sub(ROFF_ARGS)
          */           */
   
         if (r->last->end) {          if (r->last->end) {
                 i = pos + 1;                  for (i = pos, j = 0; r->last->end[j]; j++, i++)
                 while (' ' == (*bufp)[i] || '\t' == (*bufp)[i])  
                         i++;  
   
                 for (j = 0; r->last->end[j]; j++, i++)  
                         if ((*bufp)[i] != r->last->end[j])                          if ((*bufp)[i] != r->last->end[j])
                                 break;                                  break;
   
Line 834  roff_block_sub(ROFF_ARGS)
Line 818  roff_block_sub(ROFF_ARGS)
                         roffnode_pop(r);                          roffnode_pop(r);
                         roffnode_cleanscope(r);                          roffnode_cleanscope(r);
   
                           while (' ' == (*bufp)[i] || '\t' == (*bufp)[i])
                                   i++;
   
                           pos = i;
                         if (ROFF_MAX != roff_parse(r, *bufp, &pos))                          if (ROFF_MAX != roff_parse(r, *bufp, &pos))
                                 return(ROFF_RERUN);                                  return(ROFF_RERUN);
                         return(ROFF_IGN);                          return(ROFF_IGN);
Line 845  roff_block_sub(ROFF_ARGS)
Line 833  roff_block_sub(ROFF_ARGS)
          * pulling it out of the hashtable.           * pulling it out of the hashtable.
          */           */
   
         ppos = pos;          if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos)))
         t = roff_parse(r, *bufp, &pos);                  return(ROFF_IGN);
   
         /*          /*
          * Macros other than block-end are only significant           * Macros other than block-end are only significant
Line 883  roff_cond_sub(ROFF_ARGS)
Line 871  roff_cond_sub(ROFF_ARGS)
         enum rofft       t;          enum rofft       t;
         enum roffrule    rr;          enum roffrule    rr;
   
         ppos = pos;  
         rr = r->last->rule;          rr = r->last->rule;
   
         /*          /*
Line 977  roff_line_ignore(ROFF_ARGS)
Line 964  roff_line_ignore(ROFF_ARGS)
 {  {
   
         if (ROFF_it == tok)          if (ROFF_it == tok)
                 (*r->msg)(MANDOCERR_REQUEST, r->data, ln, ppos, "it");                  mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, "it");
   
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
Line 992  roff_cond(ROFF_ARGS)
Line 979  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 1023  roff_cond(ROFF_ARGS)
Line 1010  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 1150  roff_TE(ROFF_ARGS)
Line 1137  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 1164  roff_T_(ROFF_ARGS)
Line 1151  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 1194  static enum rofferr
Line 1181  static enum rofferr
 roff_EN(ROFF_ARGS)  roff_EN(ROFF_ARGS)
 {  {
   
         (*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 1205  roff_TS(ROFF_ARGS)
Line 1192  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 1226  roff_so(ROFF_ARGS)
Line 1213  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 1237  roff_so(ROFF_ARGS)
Line 1224  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 1260  roff_userdef(ROFF_ARGS)
Line 1247  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 1316  roff_getname(struct roff *r, char **cpp, int ln, int p
Line 1303  roff_getname(struct roff *r, char **cpp, int ln, int p
                 cp++;                  cp++;
                 if ('\\' == *cp)                  if ('\\' == *cp)
                         continue;                          continue;
                 (*r->msg)(MANDOCERR_NAMESC, r->data, ln, pos, NULL);                  mandoc_msg(MANDOCERR_NAMESC, r->parse, ln, pos, NULL);
                 *cp = '\0';                  *cp = '\0';
                 name = cp;                  name = cp;
         }          }

Legend:
Removed from v.1.127  
changed lines
  Added in v.1.131

CVSweb