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

Diff for /mandoc/roff.c between version 1.251 and 1.263

version 1.251, 2015/01/20 21:16:51 version 1.263, 2015/02/21 14:46:58
Line 179  enum rofft {
Line 179  enum rofft {
         ROFF_minss,          ROFF_minss,
         ROFF_mk,          ROFF_mk,
         ROFF_mso,          ROFF_mso,
         /* MAN_na; ignored in mdoc(7) */          ROFF_na,
         ROFF_ne,          ROFF_ne,
         /* MAN_nf; ignored in mdoc(7) */          /* MAN_nf; ignored in mdoc(7) */
         ROFF_nh,          ROFF_nh,
Line 396  static int   roff_evalcond(struct roff *r, int,
Line 396  static int   roff_evalcond(struct roff *r, int,
 static  int              roff_evalnum(struct roff *, int,  static  int              roff_evalnum(struct roff *, int,
                                 const char *, int *, int *, int);                                  const char *, int *, int *, int);
 static  int              roff_evalpar(struct roff *, int,  static  int              roff_evalpar(struct roff *, int,
                                 const char *, int *, int *);                                  const char *, int *, int *, int);
 static  int              roff_evalstrcond(const char *, int *);  static  int              roff_evalstrcond(const char *, int *);
 static  void             roff_free1(struct roff *);  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  size_t           roff_getname(struct roff *, char **, int, int);  static  size_t           roff_getname(struct roff *, char **, int, int);
 static  int              roff_getnum(const char *, int *, int *);  static  int              roff_getnum(const char *, int *, int *, int);
 static  int              roff_getop(const char *, int *, char *);  static  int              roff_getop(const char *, int *, char *);
 static  int              roff_getregn(const struct roff *,  static  int              roff_getregn(const struct roff *,
                                 const char *, size_t);                                  const char *, size_t);
Line 441  static enum rofferr  roff_userdef(ROFF_ARGS);
Line 441  static enum rofferr  roff_userdef(ROFF_ARGS);
 #define ASCII_LO         33  #define ASCII_LO         33
 #define HASHWIDTH       (ASCII_HI - ASCII_LO + 1)  #define HASHWIDTH       (ASCII_HI - ASCII_LO + 1)
   
   #define ROFFNUM_SCALE   (1 << 0)  /* Honour scaling in roff_getnum(). */
   #define ROFFNUM_WHITE   (1 << 1)  /* Skip whitespace in roff_evalnum(). */
   
 static  struct roffmac  *hash[HASHWIDTH];  static  struct roffmac  *hash[HASHWIDTH];
   
 static  struct roffmac   roffs[ROFF_MAX] = {  static  struct roffmac   roffs[ROFF_MAX] = {
Line 580  static struct roffmac  roffs[ROFF_MAX] = {
Line 583  static struct roffmac  roffs[ROFF_MAX] = {
         { "minss", roff_line_ignore, NULL, NULL, 0, NULL },          { "minss", roff_line_ignore, NULL, NULL, 0, NULL },
         { "mk", roff_line_ignore, NULL, NULL, 0, NULL },          { "mk", roff_line_ignore, NULL, NULL, 0, NULL },
         { "mso", roff_insec, NULL, NULL, 0, NULL },          { "mso", roff_insec, NULL, NULL, 0, NULL },
           { "na", 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 },
         { "nhychar", roff_line_ignore, NULL, NULL, 0, NULL },          { "nhychar", roff_line_ignore, NULL, NULL, 0, NULL },
Line 608  static struct roffmac  roffs[ROFF_MAX] = {
Line 612  static struct roffmac  roffs[ROFF_MAX] = {
         { "po", roff_line_ignore, NULL, NULL, 0, NULL },          { "po", roff_line_ignore, NULL, NULL, 0, NULL },
         { "ps", roff_line_ignore, NULL, NULL, 0, NULL },          { "ps", roff_line_ignore, NULL, NULL, 0, NULL },
         { "psbb", roff_unsupp, NULL, NULL, 0, NULL },          { "psbb", roff_unsupp, NULL, NULL, 0, NULL },
         { "pshape", roff_line_ignore, NULL, NULL, 0, NULL },          { "pshape", roff_unsupp, NULL, NULL, 0, NULL },
         { "pso", roff_insec, NULL, NULL, 0, NULL },          { "pso", roff_insec, NULL, NULL, 0, NULL },
         { "ptr", roff_line_ignore, NULL, NULL, 0, NULL },          { "ptr", roff_line_ignore, NULL, NULL, 0, NULL },
         { "pvs", roff_line_ignore, NULL, NULL, 0, NULL },          { "pvs", roff_line_ignore, NULL, NULL, 0, NULL },
Line 640  static struct roffmac  roffs[ROFF_MAX] = {
Line 644  static struct roffmac  roffs[ROFF_MAX] = {
         { "sv", roff_line_ignore, NULL, NULL, 0, NULL },          { "sv", roff_line_ignore, NULL, NULL, 0, NULL },
         { "sy", roff_insec, NULL, NULL, 0, NULL },          { "sy", roff_insec, NULL, NULL, 0, NULL },
         { "T&", roff_T_, NULL, NULL, 0, NULL },          { "T&", roff_T_, NULL, NULL, 0, NULL },
         { "ta", roff_line_ignore, NULL, NULL, 0, NULL },          { "ta", roff_unsupp, NULL, NULL, 0, NULL },
         { "tc", roff_unsupp, NULL, NULL, 0, NULL },          { "tc", roff_unsupp, NULL, NULL, 0, NULL },
         { "TE", roff_TE, NULL, NULL, 0, NULL },          { "TE", roff_TE, NULL, NULL, 0, NULL },
         { "TH", roff_TH, NULL, NULL, 0, NULL },          { "TH", roff_TH, NULL, NULL, 0, NULL },
         { "ti", roff_line_ignore, NULL, NULL, 0, NULL },          { "ti", roff_unsupp, NULL, NULL, 0, NULL },
         { "tkf", roff_line_ignore, NULL, NULL, 0, NULL },          { "tkf", roff_line_ignore, NULL, NULL, 0, NULL },
         { "tl", roff_unsupp, NULL, NULL, 0, NULL },          { "tl", roff_unsupp, NULL, NULL, 0, NULL },
         { "tm", roff_line_ignore, NULL, NULL, 0, NULL },          { "tm", roff_line_ignore, NULL, NULL, 0, NULL },
Line 1004  roff_res(struct roff *r, struct buf *buf, int ln, int 
Line 1008  roff_res(struct roff *r, struct buf *buf, int ln, int 
   
                 /* Advance to the end of the name. */                  /* Advance to the end of the name. */
   
                   naml = 0;
                 arg_complete = 1;                  arg_complete = 1;
                 for (naml = 0; maxl == 0 || naml < maxl; naml++, cp++) {                  while (maxl == 0 || naml < maxl) {
                         if (*cp == '\0') {                          if (*cp == '\0') {
                                 mandoc_msg(MANDOCERR_ESC_BAD, r->parse,                                  mandoc_msg(MANDOCERR_ESC_BAD, r->parse,
                                     ln, (int)(stesc - buf->buf), stesc);                                      ln, (int)(stesc - buf->buf), stesc);
Line 1016  roff_res(struct roff *r, struct buf *buf, int ln, int 
Line 1021  roff_res(struct roff *r, struct buf *buf, int ln, int 
                                 cp++;                                  cp++;
                                 break;                                  break;
                         }                          }
                           if (*cp++ != '\\' || stesc[1] != 'w') {
                                   naml++;
                                   continue;
                           }
                           switch (mandoc_escape(&cp, NULL, NULL)) {
                           case ESCAPE_SPECIAL:
                                   /* FALLTHROUGH */
                           case ESCAPE_UNICODE:
                                   /* FALLTHROUGH */
                           case ESCAPE_NUMBERED:
                                   /* FALLTHROUGH */
                           case ESCAPE_OVERSTRIKE:
                                   naml++;
                                   break;
                           default:
                                   break;
                           }
                 }                  }
   
                 /*                  /*
Line 1031  roff_res(struct roff *r, struct buf *buf, int ln, int 
Line 1053  roff_res(struct roff *r, struct buf *buf, int ln, int 
                 case 'B':                  case 'B':
                         npos = 0;                          npos = 0;
                         ubuf[0] = arg_complete &&                          ubuf[0] = arg_complete &&
                             roff_evalnum(r, ln, stnam, &npos, NULL, 0) &&                              roff_evalnum(r, ln, stnam, &npos,
                                 NULL, ROFFNUM_SCALE) &&
                             stnam + npos + 1 == cp ? '1' : '0';                              stnam + npos + 1 == cp ? '1' : '0';
                         ubuf[1] = '\0';                          ubuf[1] = '\0';
                         break;                          break;
Line 1166  roff_parseln(struct roff *r, int ln, struct buf *buf, 
Line 1189  roff_parseln(struct roff *r, int ln, struct buf *buf, 
   
         /*          /*
          * 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.
          * we're not a macro, just let it through.           * Equations process all content themselves.
          * Finally, if there's an equation scope open, divert it into it           * Tables process almost all content themselves, but we want
          * no matter our state.           * to warn about macros before passing it there.
          */           */
   
         if (r->last && ! ctl) {          if (r->last != NULL && ! ctl) {
                 t = r->last->tok;                  t = r->last->tok;
                 assert(roffs[t].text);                  assert(roffs[t].text);
                 e = (*roffs[t].text)(r, t, buf, ln, pos, pos, offs);                  e = (*roffs[t].text)(r, t, buf, ln, pos, pos, offs);
Line 1180  roff_parseln(struct roff *r, int ln, struct buf *buf, 
Line 1203  roff_parseln(struct roff *r, int ln, struct buf *buf, 
                 if (e != ROFF_CONT)                  if (e != ROFF_CONT)
                         return(e);                          return(e);
         }          }
         if (r->eqn)          if (r->eqn != NULL)
                 return(eqn_read(&r->eqn, ln, buf->buf, ppos, offs));                  return(eqn_read(&r->eqn, ln, buf->buf, ppos, offs));
         if ( ! ctl) {          if (r->tbl != NULL && ( ! ctl || buf->buf[pos] == '\0'))
                 if (r->tbl)                  return(tbl_read(r->tbl, ln, buf->buf, ppos));
                         return(tbl_read(r->tbl, ln, buf->buf, pos));          if ( ! ctl)
                 return(roff_parsetext(buf, pos, offs));                  return(roff_parsetext(buf, pos, offs));
         }  
   
         /* Skip empty request lines. */          /* Skip empty request lines. */
   
Line 1219  roff_parseln(struct roff *r, int ln, struct buf *buf, 
Line 1241  roff_parseln(struct roff *r, int ln, struct buf *buf, 
         if (r->tbl != NULL && (t == ROFF_MAX || t == ROFF_TS)) {          if (r->tbl != NULL && (t == ROFF_MAX || t == ROFF_TS)) {
                 mandoc_msg(MANDOCERR_TBLMACRO, r->parse,                  mandoc_msg(MANDOCERR_TBLMACRO, r->parse,
                     ln, pos, buf->buf + spos);                      ln, pos, buf->buf + spos);
                 return(ROFF_IGN);                  if (t == ROFF_TS)
                           return(ROFF_IGN);
                   while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ')
                           pos++;
                   while (buf->buf[pos] != '\0' && buf->buf[pos] == ' ')
                           pos++;
                   return(tbl_read(r->tbl, ln, buf->buf, pos));
         }          }
   
         /*          /*
Line 1604  roff_cond_text(ROFF_ARGS)
Line 1632  roff_cond_text(ROFF_ARGS)
  * Ignore overflows, treat them just like the C language.   * Ignore overflows, treat them just like the C language.
  */   */
 static int  static int
 roff_getnum(const char *v, int *pos, int *res)  roff_getnum(const char *v, int *pos, int *res, int flags)
 {  {
         int      myres, n, p;          int      myres, scaled, n, p;
   
         if (NULL == res)          if (NULL == res)
                 res = &myres;                  res = &myres;
   
         p = *pos;          p = *pos;
         n = v[p] == '-';          n = v[p] == '-';
         if (n)          if (n || v[p] == '+')
                 p++;                  p++;
   
           if (flags & ROFFNUM_WHITE)
                   while (isspace((unsigned char)v[p]))
                           p++;
   
         for (*res = 0; isdigit((unsigned char)v[p]); p++)          for (*res = 0; isdigit((unsigned char)v[p]); p++)
                 *res = 10 * *res + v[p] - '0';                  *res = 10 * *res + v[p] - '0';
         if (p == *pos + n)          if (p == *pos + n)
Line 1624  roff_getnum(const char *v, int *pos, int *res)
Line 1656  roff_getnum(const char *v, int *pos, int *res)
         if (n)          if (n)
                 *res = -*res;                  *res = -*res;
   
         *pos = p;          /* Each number may be followed by one optional scaling unit. */
         return 1;  
           switch (v[p]) {
           case 'f':
                   scaled = *res * 65536;
                   break;
           case 'i':
                   scaled = *res * 240;
                   break;
           case 'c':
                   scaled = *res * 240 / 2.54;
                   break;
           case 'v':
                   /* FALLTROUGH */
           case 'P':
                   scaled = *res * 40;
                   break;
           case 'm':
                   /* FALLTROUGH */
           case 'n':
                   scaled = *res * 24;
                   break;
           case 'p':
                   scaled = *res * 10 / 3;
                   break;
           case 'u':
                   scaled = *res;
                   break;
           case 'M':
                   scaled = *res * 6 / 25;
                   break;
           default:
                   scaled = *res;
                   p--;
                   break;
           }
           if (flags & ROFFNUM_SCALE)
                   *res = scaled;
   
           *pos = p + 1;
           return(1);
 }  }
   
 /*  /*
Line 1712  roff_evalcond(struct roff *r, int ln, const char *v, i
Line 1783  roff_evalcond(struct roff *r, int ln, const char *v, i
         }          }
   
         savepos = *pos;          savepos = *pos;
         if (roff_evalnum(r, ln, v, pos, &number, 0))          if (roff_evalnum(r, ln, v, pos, &number, ROFFNUM_SCALE))
                 return((number > 0) == wanttrue);                  return((number > 0) == wanttrue);
         else if (*pos == savepos)          else if (*pos == savepos)
                 return(roff_evalstrcond(v, pos) == wanttrue);                  return(roff_evalstrcond(v, pos) == wanttrue);
Line 1935  roff_getop(const char *v, int *pos, char *res)
Line 2006  roff_getop(const char *v, int *pos, char *res)
  */   */
 static int  static int
 roff_evalpar(struct roff *r, int ln,  roff_evalpar(struct roff *r, int ln,
         const char *v, int *pos, int *res)          const char *v, int *pos, int *res, int flags)
 {  {
   
         if ('(' != v[*pos])          if ('(' != v[*pos])
                 return(roff_getnum(v, pos, res));                  return(roff_getnum(v, pos, res, flags));
   
         (*pos)++;          (*pos)++;
         if ( ! roff_evalnum(r, ln, v, pos, res, 1))          if ( ! roff_evalnum(r, ln, v, pos, res, flags | ROFFNUM_WHITE))
                 return(0);                  return(0);
   
         /*          /*
Line 1965  roff_evalpar(struct roff *r, int ln,
Line 2036  roff_evalpar(struct roff *r, int ln,
  */   */
 static int  static int
 roff_evalnum(struct roff *r, int ln, const char *v,  roff_evalnum(struct roff *r, int ln, const char *v,
         int *pos, int *res, int skipwhite)          int *pos, int *res, int flags)
 {  {
         int              mypos, operand2;          int              mypos, operand2;
         char             operator;          char             operator;
Line 1975  roff_evalnum(struct roff *r, int ln, const char *v,
Line 2046  roff_evalnum(struct roff *r, int ln, const char *v,
                 pos = &mypos;                  pos = &mypos;
         }          }
   
         if (skipwhite)          if (flags & ROFFNUM_WHITE)
                 while (isspace((unsigned char)v[*pos]))                  while (isspace((unsigned char)v[*pos]))
                         (*pos)++;                          (*pos)++;
   
         if ( ! roff_evalpar(r, ln, v, pos, res))          if ( ! roff_evalpar(r, ln, v, pos, res, flags))
                 return(0);                  return(0);
   
         while (1) {          while (1) {
                 if (skipwhite)                  if (flags & ROFFNUM_WHITE)
                         while (isspace((unsigned char)v[*pos]))                          while (isspace((unsigned char)v[*pos]))
                                 (*pos)++;                                  (*pos)++;
   
                 if ( ! roff_getop(v, pos, &operator))                  if ( ! roff_getop(v, pos, &operator))
                         break;                          break;
   
                 if (skipwhite)                  if (flags & ROFFNUM_WHITE)
                         while (isspace((unsigned char)v[*pos]))                          while (isspace((unsigned char)v[*pos]))
                                 (*pos)++;                                  (*pos)++;
   
                 if ( ! roff_evalpar(r, ln, v, pos, &operand2))                  if ( ! roff_evalpar(r, ln, v, pos, &operand2, flags))
                         return(0);                          return(0);
   
                 if (skipwhite)                  if (flags & ROFFNUM_WHITE)
                         while (isspace((unsigned char)v[*pos]))                          while (isspace((unsigned char)v[*pos]))
                                 (*pos)++;                                  (*pos)++;
   
Line 2201  roff_nr(ROFF_ARGS)
Line 2272  roff_nr(ROFF_ARGS)
         if (sign == '+' || sign == '-')          if (sign == '+' || sign == '-')
                 val++;                  val++;
   
         if (roff_evalnum(r, ln, val, NULL, &iv, 0))          if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE))
                 roff_setreg(r, key, iv, sign);                  roff_setreg(r, key, iv, sign);
   
         return(ROFF_IGN);          return(ROFF_IGN);
Line 2256  roff_rm(ROFF_ARGS)
Line 2327  roff_rm(ROFF_ARGS)
 static enum rofferr  static enum rofferr
 roff_it(ROFF_ARGS)  roff_it(ROFF_ARGS)
 {  {
         char            *cp;  
         size_t           len;  
         int              iv;          int              iv;
   
         /* Parse the number of lines. */          /* Parse the number of lines. */
         cp = buf->buf + pos;  
         len = strcspn(cp, " \t");          if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) {
         cp[len] = '\0';  
         if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) {  
                 mandoc_msg(MANDOCERR_IT_NONUM, r->parse,                  mandoc_msg(MANDOCERR_IT_NONUM, r->parse,
                     ln, ppos, buf->buf + 1);                      ln, ppos, buf->buf + 1);
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
         cp += len + 1;  
   
         /* Arm the input line trap. */          while (isspace((unsigned char)buf->buf[pos]))
                   pos++;
   
           /*
            * Arm the input line trap.
            * Special-casing "an-trap" is an ugly workaround to cope
            * with DocBook stupidly fiddling with man(7) internals.
            */
   
         roffit_lines = iv;          roffit_lines = iv;
         roffit_macro = mandoc_strdup(cp);          roffit_macro = mandoc_strdup(iv != 1 ||
               strcmp(buf->buf + pos, "an-trap") ?
               buf->buf + pos : "br");
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
   
Line 2314  roff_TE(ROFF_ARGS)
Line 2390  roff_TE(ROFF_ARGS)
         if (NULL == r->tbl)          if (NULL == r->tbl)
                 mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,                  mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse,
                     ln, ppos, "TE");                      ln, ppos, "TE");
         else          else if ( ! tbl_end(&r->tbl)) {
                 tbl_end(&r->tbl);                  free(buf->buf);
                   buf->buf = mandoc_strdup(".sp");
                   buf->sz = 4;
                   return(ROFF_REPARSE);
           }
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
   
Line 2473  roff_cc(ROFF_ARGS)
Line 2552  roff_cc(ROFF_ARGS)
                 r->control = 0;                  r->control = 0;
   
         if (*p != '\0')          if (*p != '\0')
                 mandoc_msg(MANDOCERR_ARGCOUNT, r->parse, ln, ppos, NULL);                  mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse,
                       ln, p - buf->buf, "cc ... %s", p);
   
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
Line 2488  roff_tr(ROFF_ARGS)
Line 2568  roff_tr(ROFF_ARGS)
         p = buf->buf + pos;          p = buf->buf + pos;
   
         if (*p == '\0') {          if (*p == '\0') {
                 mandoc_msg(MANDOCERR_ARGCOUNT, r->parse, ln, ppos, NULL);                  mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse, ln, ppos, "tr");
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
Line 2516  roff_tr(ROFF_ARGS)
Line 2596  roff_tr(ROFF_ARGS)
                         }                          }
                         ssz = (size_t)(p - second);                          ssz = (size_t)(p - second);
                 } else if (*second == '\0') {                  } else if (*second == '\0') {
                         mandoc_msg(MANDOCERR_ARGCOUNT, r->parse,                          mandoc_vmsg(MANDOCERR_TR_ODD, r->parse,
                             ln, (int)(p - buf->buf), NULL);                              ln, first - buf->buf, "tr %s", first);
                         second = " ";                          second = " ";
                         p--;                          p--;
                 }                  }
Line 2573  roff_so(ROFF_ARGS)
Line 2653  roff_so(ROFF_ARGS)
 static enum rofferr  static enum rofferr
 roff_userdef(ROFF_ARGS)  roff_userdef(ROFF_ARGS)
 {  {
         const char       *arg[9];          const char       *arg[9], *ap;
         char             *cp, *n1, *n2;          char             *cp, *n1, *n2;
         int               i;          int               i;
           size_t            asz, rsz;
   
         /*          /*
          * Collect pointers to macro argument strings           * Collect pointers to macro argument strings
          * and NUL-terminate them.           * and NUL-terminate them.
          */           */
   
         cp = buf->buf + pos;          cp = buf->buf + pos;
         for (i = 0; i < 9; i++)          for (i = 0; i < 9; i++)
                 arg[i] = *cp == '\0' ? "" :                  arg[i] = *cp == '\0' ? "" :
Line 2589  roff_userdef(ROFF_ARGS)
Line 2671  roff_userdef(ROFF_ARGS)
         /*          /*
          * Expand macro arguments.           * Expand macro arguments.
          */           */
         buf->sz = 0;  
         n1 = cp = mandoc_strdup(r->current_string);          buf->sz = strlen(r->current_string) + 1;
         while ((cp = strstr(cp, "\\$")) != NULL) {          n1 = cp = mandoc_malloc(buf->sz);
                 i = cp[2] - '1';          memcpy(n1, r->current_string, buf->sz);
                 if (0 > i || 8 < i) {          while (*cp != '\0') {
                         /* Not an argument invocation. */  
                         cp += 2;                  /* Scan ahead for the next argument invocation. */
   
                   if (*cp++ != '\\')
                         continue;                          continue;
                   if (*cp++ != '$')
                           continue;
                   i = *cp - '1';
                   if (0 > i || 8 < i)
                           continue;
                   cp -= 2;
   
                   /*
                    * Determine the size of the expanded argument,
                    * taking escaping of quotes into account.
                    */
   
                   asz = 0;
                   for (ap = arg[i]; *ap != '\0'; ap++) {
                           asz++;
                           if (*ap == '"')
                                   asz += 3;
                 }                  }
                 *cp = '\0';                  if (asz != 3) {
                 buf->sz = mandoc_asprintf(&n2, "%s%s%s",  
                     n1, arg[i], cp + 3) + 1;                          /*
                 cp = n2 + (cp - n1);                           * Determine the size of the rest of the
                 free(n1);                           * unexpanded macro, including the NUL.
                 n1 = n2;                           */
   
                           rsz = buf->sz - (cp - n1) - 3;
   
                           /*
                            * When shrinking, move before
                            * releasing the storage.
                            */
   
                           if (asz < 3)
                                   memmove(cp + asz, cp + 3, rsz);
   
                           /*
                            * Resize the storage for the macro
                            * and readjust the parse pointer.
                            */
   
                           buf->sz += asz - 3;
                           n2 = mandoc_realloc(n1, buf->sz);
                           cp = n2 + (cp - n1);
                           n1 = n2;
   
                           /*
                            * When growing, make room
                            * for the expanded argument.
                            */
   
                           if (asz > 3)
                                   memmove(cp + asz, cp + 3, rsz);
                   }
   
                   /* Copy the expanded argument, escaping quotes. */
   
                   n2 = cp;
                   for (ap = arg[i]; *ap != '\0'; ap++) {
                           if (*ap == '"') {
                                   memcpy(n2, "\\(dq", 4);
                                   n2 += 4;
                           } else
                                   *n2++ = *ap;
                   }
         }          }
   
         /*          /*
          * Replace the macro invocation           * Replace the macro invocation
          * by the expanded macro.           * by the expanded macro.
          */           */
   
         free(buf->buf);          free(buf->buf);
         buf->buf = n1;          buf->buf = n1;
         if (buf->sz == 0)  
                 buf->sz = strlen(buf->buf) + 1;  
         *offs = 0;          *offs = 0;
   
         return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?          return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?

Legend:
Removed from v.1.251  
changed lines
  Added in v.1.263

CVSweb