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

Diff for /mandoc/roff.c between version 1.180 and 1.181

version 1.180, 2013/10/05 22:08:12 version 1.181, 2013/10/05 22:15:03
Line 97  struct roffkv {
Line 97  struct roffkv {
   
 /*  /*
  * A single number register as part of a singly-linked list.   * A single number register as part of a singly-linked list.
  * Registers are assumed to be unsigned ints for now.  
  */   */
 struct  roffreg {  struct  roffreg {
         struct roffstr   key;          struct roffstr   key;
         unsigned int     u;          int              val;
         struct roffreg  *next;          struct roffreg  *next;
 };  };
   
Line 186  static void   roff_free1(struct roff *);
Line 185  static void   roff_free1(struct roff *);
 static  void             roff_freereg(struct roffreg *);  static  void             roff_freereg(struct roffreg *);
 static  void             roff_freestr(struct roffkv *);  static  void             roff_freestr(struct roffkv *);
 static  char            *roff_getname(struct roff *, char **, int, int);  static  char            *roff_getname(struct roff *, char **, int, int);
   static  int              roff_getregn(const struct roff *,
                                   const char *, size_t);
 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_it(ROFF_ARGS);  static  enum rofferr     roff_it(ROFF_ARGS);
Line 480  roff_alloc(enum mparset type, struct mparse *parse)
Line 481  roff_alloc(enum mparset type, struct mparse *parse)
 }  }
   
 /*  /*
  * Pre-filter each and every line for reserved words (one beginning with   * In the current line, expand user-defined strings ("\*")
  * `\*', e.g., `\*(ab').  These must be handled before the actual line   * and references to number registers ("\n").
  * is processed.   * Also check the syntax of other escape sequences.
  * This also checks the syntax of regular escapes.  
  */   */
 static enum rofferr  static enum rofferr
 roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)  roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 {  {
         enum mandoc_esc  esc;          char             ubuf[12]; /* buffer to print the number */
         const char      *stesc; /* start of an escape sequence ('\\') */          const char      *stesc; /* start of an escape sequence ('\\') */
         const char      *stnam; /* start of the name, after "[(*" */          const char      *stnam; /* start of the name, after "[(*" */
         const char      *cp;    /* end of the name, e.g. before ']' */          const char      *cp;    /* end of the name, e.g. before ']' */
         const char      *res;   /* the string to be substituted */          const char      *res;   /* the string to be substituted */
         int              i, maxl, expand_count;          char            *nbuf;  /* new buffer to copy bufp to */
         size_t           nsz;          size_t           nsz;   /* size of the new buffer */
         char            *n;          size_t           maxl;  /* expected length of the escape name */
           size_t           naml;  /* actual length of the escape name */
           int              expand_count;  /* to avoid infinite loops */
   
         expand_count = 0;          expand_count = 0;
   
Line 505  again:
Line 507  again:
                 stesc = cp++;                  stesc = cp++;
   
                 /*                  /*
                  * The second character must be an asterisk.                   * The second character must be an asterisk or an n.
                  * If it isn't, skip it anyway:  It is escaped,                   * If it isn't, skip it anyway:  It is escaped,
                  * so it can't start another escape sequence.                   * so it can't start another escape sequence.
                  */                   */
Line 513  again:
Line 515  again:
                 if ('\0' == *cp)                  if ('\0' == *cp)
                         return(ROFF_CONT);                          return(ROFF_CONT);
   
                 if ('*' != *cp) {                  switch (*cp) {
                         res = cp;                  case ('*'):
                         esc = mandoc_escape(&cp, NULL, NULL);                          res = NULL;
                         if (ESCAPE_ERROR != esc)                          break;
                   case ('n'):
                           res = ubuf;
                           break;
                   default:
                           if (ESCAPE_ERROR != mandoc_escape(&cp, NULL, NULL))
                                 continue;                                  continue;
                         cp = res;  
                         mandoc_msg                          mandoc_msg
                                 (MANDOCERR_BADESCAPE, r->parse,                                  (MANDOCERR_BADESCAPE, r->parse,
                                  ln, (int)(stesc - *bufp), NULL);                                   ln, (int)(stesc - *bufp), NULL);
Line 529  again:
Line 535  again:
   
                 /*                  /*
                  * The third character decides the length                   * The third character decides the length
                  * of the name of the string.                   * of the name of the string or register.
                  * Save a pointer to the name.                   * Save a pointer to the name.
                  */                   */
   
Line 552  again:
Line 558  again:
   
                 /* Advance to the end of the name. */                  /* Advance to the end of the name. */
   
                 for (i = 0; 0 == maxl || i < maxl; i++, cp++) {                  for (naml = 0; 0 == maxl || naml < maxl; naml++, cp++) {
                         if ('\0' == *cp) {                          if ('\0' == *cp) {
                                 mandoc_msg                                  mandoc_msg
                                         (MANDOCERR_BADESCAPE,                                          (MANDOCERR_BADESCAPE,
Line 569  again:
Line 575  again:
                  * undefined, resume searching for escapes.                   * undefined, resume searching for escapes.
                  */                   */
   
                 res = roff_getstrn(r, stnam, (size_t)i);                  if (NULL == res)
                           res = roff_getstrn(r, stnam, naml);
                   else
                           snprintf(ubuf, sizeof(ubuf), "%d",
                               roff_getregn(r, stnam, naml));
   
                 if (NULL == res) {                  if (NULL == res) {
                         mandoc_msg                          mandoc_msg
Line 583  again:
Line 593  again:
                 pos = stesc - *bufp;                  pos = stesc - *bufp;
   
                 nsz = *szp + strlen(res) + 1;                  nsz = *szp + strlen(res) + 1;
                 n = mandoc_malloc(nsz);                  nbuf = mandoc_malloc(nsz);
   
                 strlcpy(n, *bufp, (size_t)(stesc - *bufp + 1));                  strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1));
                 strlcat(n, res, nsz);                  strlcat(nbuf, res, nsz);
                 strlcat(n, cp + (maxl ? 0 : 1), nsz);                  strlcat(nbuf, cp + (maxl ? 0 : 1), nsz);
   
                 free(*bufp);                  free(*bufp);
   
                 *bufp = n;                  *bufp = nbuf;
                 *szp = nsz;                  *szp = nsz;
   
                 if (EXPAND_LIMIT >= ++expand_count)                  if (EXPAND_LIMIT >= ++expand_count)
Line 1263  roff_ds(ROFF_ARGS)
Line 1273  roff_ds(ROFF_ARGS)
 }  }
   
 void  void
 roff_setreg(struct roff *r, const char *name, unsigned int val)  roff_setreg(struct roff *r, const char *name, int val)
 {  {
         struct roffreg  *reg;          struct roffreg  *reg;
   
Line 1282  roff_setreg(struct roff *r, const char *name, unsigned
Line 1292  roff_setreg(struct roff *r, const char *name, unsigned
                 r->regtab = reg;                  r->regtab = reg;
         }          }
   
         reg->u = val;          reg->val = val;
 }  }
   
 unsigned int  int
 roff_getreg(const struct roff *r, const char *name)  roff_getreg(const struct roff *r, const char *name)
 {  {
         struct roffreg  *reg;          struct roffreg  *reg;
   
         for (reg = r->regtab; reg; reg = reg->next)          for (reg = r->regtab; reg; reg = reg->next)
                 if (0 == strcmp(name, reg->key.p))                  if (0 == strcmp(name, reg->key.p))
                         return(reg->u);                          return(reg->val);
   
         return(0);          return(0);
 }  }
   
   static int
   roff_getregn(const struct roff *r, const char *name, size_t len)
   {
           struct roffreg  *reg;
   
           for (reg = r->regtab; reg; reg = reg->next)
                   if (len == reg->key.sz &&
                       0 == strncmp(name, reg->key.p, len))
                           return(reg->val);
   
           return(0);
   }
   
 static void  static void
 roff_freereg(struct roffreg *reg)  roff_freereg(struct roffreg *reg)
 {  {
Line 1322  roff_nr(ROFF_ARGS)
Line 1345  roff_nr(ROFF_ARGS)
         key = roff_getname(r, &val, ln, pos);          key = roff_getname(r, &val, ln, pos);
   
         iv = mandoc_strntoi(val, strlen(val), 10);          iv = mandoc_strntoi(val, strlen(val), 10);
         if (0 > iv)  
                 iv = 0;  
   
         roff_setreg(r, key, (unsigned)iv);          roff_setreg(r, key, iv);
   
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }

Legend:
Removed from v.1.180  
changed lines
  Added in v.1.181

CVSweb