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

Diff for /mandoc/roff.c between version 1.163 and 1.164

version 1.163, 2011/07/27 20:55:28 version 1.164, 2011/07/28 14:17:11
Line 95  struct roff {
Line 95  struct roff {
         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 reg       regs[REG__MAX];          struct reg       regs[REG__MAX];
         struct roffstr  *first_string; /* user-defined strings & macros */          struct roffstr  *strtab; /* user-defined strings & macros */
           struct roffstr  *chrtab; /* user-defined characters */
         const char      *current_string; /* value of last called user macro */          const char      *current_string; /* value of last called user macro */
         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 */
Line 162  static enum rofferr  roff_cond_sub(ROFF_ARGS);
Line 163  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_free1(struct roff *);  static  void             roff_free1(struct roff *);
 static  void             roff_freestr(struct roff *);  static  void             roff_freestr(struct roffstr **);
 static  char            *roff_getname(struct roff *, char **, int, int);  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);
Line 177  static void   roff_res(struct roff *, 
Line 178  static void   roff_res(struct roff *, 
 static  enum rofferr     roff_rm(ROFF_ARGS);  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  void             roff_setstrn(struct roffstr **, const char *,
                                   size_t, const char *, size_t, int);
 static  enum rofferr     roff_so(ROFF_ARGS);  static  enum rofferr     roff_so(ROFF_ARGS);
   static  enum rofferr     roff_tr(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_EQ(ROFF_ARGS);
Line 216  static struct roffmac  roffs[ROFF_MAX] = {
Line 220  static struct roffmac  roffs[ROFF_MAX] = {
         { "rm", roff_rm, 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 },          { "ta", roff_line_ignore, NULL, NULL, 0, NULL },
         { "tr", roff_line_ignore, NULL, NULL, 0, NULL },          { "tr", roff_tr, 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 },
Line 354  roff_free1(struct roff *r)
Line 358  roff_free1(struct roff *r)
         while (r->last)          while (r->last)
                 roffnode_pop(r);                  roffnode_pop(r);
   
         roff_freestr(r);          roff_freestr(&r->strtab);
           roff_freestr(&r->chrtab);
 }  }
   
   
Line 1340  roff_TS(ROFF_ARGS)
Line 1345  roff_TS(ROFF_ARGS)
   
 /* ARGSUSED */  /* ARGSUSED */
 static enum rofferr  static enum rofferr
   roff_tr(ROFF_ARGS)
   {
           const char      *p, *first, *second;
           size_t           fsz, ssz;
           enum mandoc_esc  esc;
   
           p = *bufp + pos;
   
           if ('\0' == *p) {
                   mandoc_msg(MANDOCERR_ARGCOUNT, r->parse, ln, ppos, NULL);
                   return(ROFF_IGN);
           }
   
           while ('\0' != *p) {
                   fsz = ssz = 1;
   
                   first = p++;
                   if ('\\' == *first) {
                           esc = mandoc_escape(&p, NULL, NULL);
                           if (ESCAPE_ERROR == esc) {
                                   mandoc_msg
                                           (MANDOCERR_BADESCAPE, r->parse,
                                            ln, (int)(p - *bufp), NULL);
                                   return(ROFF_IGN);
                           }
                           fsz = (size_t)(p - first);
                   }
   
                   second = p++;
                   if ('\\' == *second) {
                           esc = mandoc_escape(&p, NULL, NULL);
                           if (ESCAPE_ERROR == esc) {
                                   mandoc_msg
                                           (MANDOCERR_BADESCAPE, r->parse,
                                            ln, (int)(p - *bufp), NULL);
                                   return(ROFF_IGN);
                           }
                           ssz = (size_t)(p - second);
                   } else if ('\0' == *p) {
                           mandoc_msg(MANDOCERR_ARGCOUNT, r->parse,
                                           ln, (int)(p - *bufp), NULL);
                           second = " ";
                   }
   
                   roff_setstrn(&r->chrtab, first, fsz, second, ssz, 0);
           }
   
           return(ROFF_IGN);
   }
   
   /* ARGSUSED */
   static enum rofferr
 roff_so(ROFF_ARGS)  roff_so(ROFF_ARGS)
 {  {
         char *name;          char *name;
Line 1461  static void
Line 1518  static void
 roff_setstr(struct roff *r, const char *name, const char *string,  roff_setstr(struct roff *r, const char *name, const char *string,
         int multiline)          int multiline)
 {  {
         struct roffstr   *n;  
         char             *c;  
         size_t            oldch, newch;  
   
           roff_setstrn(&r->strtab, name, strlen(name), string,
                           string ? strlen(string) : 0, multiline);
   }
   
   static void
   roff_setstrn(struct roffstr **r, const char *name, size_t namesz,
                   const char *string, size_t stringsz, int multiline)
   {
           struct roffstr  *n;
           char            *c;
           int              i;
           size_t           oldch, newch;
   
         /* Search for an existing string with the same name. */          /* Search for an existing string with the same name. */
         n = r->first_string;          n = *r;
   
         while (n && strcmp(name, n->key))          while (n && strcmp(name, n->key))
                 n = n->next;                  n = n->next;
   
         if (NULL == n) {          if (NULL == n) {
                 /* Create a new string table entry. */                  /* Create a new string table entry. */
                 n = mandoc_malloc(sizeof(struct roffstr));                  n = mandoc_malloc(sizeof(struct roffstr));
                 n->key = mandoc_strdup(name);                  n->key = mandoc_strndup(name, namesz);
                 n->keysz = strlen(name);                  n->keysz = namesz;
                 n->val = NULL;                  n->val = NULL;
                 n->valsz = 0;                  n->valsz = 0;
                 n->next = r->first_string;                  n->next = *r;
                 r->first_string = n;                  *r = n;
         } else if (0 == multiline) {          } else if (0 == multiline) {
                 /* In multiline mode, append; else replace. */                  /* In multiline mode, append; else replace. */
                 free(n->val);                  free(n->val);
Line 1493  roff_setstr(struct roff *r, const char *name, const ch
Line 1561  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 ? 2u : 1u);          newch = stringsz + (multiline ? 2u : 1u);
   
         if (NULL == n->val) {          if (NULL == n->val) {
                 n->val = mandoc_malloc(newch);                  n->val = mandoc_malloc(newch);
                 *n->val = '\0';                  *n->val = '\0';
Line 1507  roff_setstr(struct roff *r, const char *name, const ch
Line 1576  roff_setstr(struct roff *r, const char *name, const ch
         c = n->val + (int)oldch;          c = n->val + (int)oldch;
   
         /* Append new content to the destination buffer. */          /* Append new content to the destination buffer. */
         while (*string) {          i = 0;
           while (i < (int)stringsz) {
                 /*                  /*
                  * Rudimentary roff copy mode:                   * Rudimentary roff copy mode:
                  * Handle escaped backslashes.                   * Handle escaped backslashes.
                  */                   */
                 if ('\\' == *string && '\\' == *(string + 1))                  if ('\\' == string[i] && '\\' == string[i + 1])
                         string++;                          i++;
                 *c++ = *string++;                  *c++ = string[i++];
         }          }
   
         /* Append terminating bytes. */          /* Append terminating bytes. */
Line 1530  roff_getstrn(const struct roff *r, const char *name, s
Line 1600  roff_getstrn(const struct roff *r, const char *name, s
 {  {
         const struct roffstr *n;          const struct roffstr *n;
   
         for (n = r->first_string; n; n = n->next)          for (n = r->strtab; n; n = n->next)
                 if (0 == strncmp(name, n->key, len) &&                  if (0 == strncmp(name, n->key, len) &&
                                 '\0' == n->key[(int)len])                                  '\0' == n->key[(int)len])
                         return(n->val);                          return(n->val);
Line 1539  roff_getstrn(const struct roff *r, const char *name, s
Line 1609  roff_getstrn(const struct roff *r, const char *name, s
 }  }
   
 static void  static void
 roff_freestr(struct roff *r)  roff_freestr(struct roffstr **r)
 {  {
         struct roffstr   *n, *nn;          struct roffstr   *n, *nn;
   
         for (n = r->first_string; n; n = nn) {          for (n = *r; n; n = nn) {
                 free(n->key);                  free(n->key);
                 free(n->val);                  free(n->val);
                 nn = n->next;                  nn = n->next;
                 free(n);                  free(n);
         }          }
   
         r->first_string = NULL;          *r = NULL;
 }  }
   
 const struct tbl_span *  const struct tbl_span *
Line 1572  roff_eqndelim(const struct roff *r)
Line 1642  roff_eqndelim(const struct roff *r)
 {  {
   
         return('\0');          return('\0');
   }
   
   /*
    * Duplicate an input string, making the appropriate character
    * conversations (as stipulated by `tr') along the way.
    * Returns a heap-allocated string with all the replacements made.
    */
   char *
   roff_strdup(const struct roff *r, const char *p)
   {
           const struct roffstr *cp;
           char            *res;
           const char      *pp;
           size_t           ssz, sz;
           enum mandoc_esc  esc;
   
           if (NULL == r->chrtab)
                   return(mandoc_strdup(p));
           else if ('\0' == *p)
                   return(mandoc_strdup(""));
   
           /*
            * Step through each character looking for term matches
            * (remember that a `tr' can be invoked with an escape, which is
            * a glyph but the escape is multi-character).
            * We only do this if the character hash has been initialised
            * and the string is >0 length.
            */
   
           res = NULL;
           ssz = 0;
   
           while ('\0' != *p) {
                   /* Search for term matches. */
                   for (cp = r->chrtab; cp; cp = cp->next)
                           if (0 == strncmp(p, cp->key, cp->keysz))
                                   break;
   
                   if (NULL != cp) {
                           /*
                            * A match has been found.
                            * Append the match to the array and move
                            * forward by its keysize.
                            */
                           res = mandoc_realloc(res, ssz + cp->valsz + 1);
                           memcpy(res + ssz, cp->val, cp->valsz);
                           ssz += cp->valsz;
                           p += (int)cp->keysz;
                           continue;
                   }
   
                   if ('\\' == *p) {
                           /*
                            * Handle escapes carefully: we need to copy
                            * over just the escape itself, or else we might
                            * do replacements within the escape itself.
                            * Make sure to pass along the bogus string.
                            */
                           pp = p++;
                           esc = mandoc_escape(&p, NULL, NULL);
                           if (ESCAPE_ERROR == esc) {
                                   sz = strlen(pp);
                                   res = mandoc_realloc(res, ssz + sz + 1);
                                   memcpy(res + ssz, pp, sz);
                                   break;
                           }
                           /*
                            * We bail out on bad escapes.
                            * No need to warn: we already did so when
                            * roff_res() was called.
                            */
                           sz = (int)(p - pp);
                           res = mandoc_realloc(res, ssz + sz + 1);
                           memcpy(res + ssz, pp, sz);
                           ssz += sz;
                           continue;
                   }
   
                   /* Just append the charater. */
                   res = mandoc_realloc(res, ssz + 2);
                   res[ssz++] = *p++;
           }
   
           res[(int)ssz] = '\0';
           return(res);
 }  }

Legend:
Removed from v.1.163  
changed lines
  Added in v.1.164

CVSweb