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

Diff for /mandoc/roff.c between version 1.333 and 1.338

version 1.333, 2018/08/18 02:08:27 version 1.338, 2018/08/21 18:15:22
Line 107  struct roff {
Line 107  struct roff {
         int              rstacksz; /* current size limit of rstack */          int              rstacksz; /* current size limit of rstack */
         int              rstackpos; /* position in rstack */          int              rstackpos; /* position in rstack */
         int              format; /* current file in mdoc or man format */          int              format; /* current file in mdoc or man format */
         int              argc; /* number of args of the last macro */  
         char             control; /* control character */          char             control; /* control character */
         char             escape; /* escape character */          char             escape; /* escape character */
 };  };
Line 1205  roff_res(struct roff *r, struct buf *buf, int ln, int 
Line 1204  roff_res(struct roff *r, struct buf *buf, int ln, int 
                         r->man->next = ROFF_NEXT_SIBLING;                          r->man->next = ROFF_NEXT_SIBLING;
                 }                  }
   
                 /* Discard comments. */                  /* Line continuation with comment. */
   
                 while (stesc > start && stesc[-1] == ' ')                  if (stesc[1] == '#') {
                           *stesc = '\0';
                           return ROFF_APPEND;
                   }
   
                   /* Discard normal comments. */
   
                   while (stesc > start && stesc[-1] == ' ' &&
                       (stesc == start + 1 || stesc[-2] != '\\'))
                         stesc--;                          stesc--;
                 *stesc = '\0';                  *stesc = '\0';
                 break;                  break;
Line 2160  out:
Line 2167  out:
 static int  static int
 roff_evalcond(struct roff *r, int ln, char *v, int *pos)  roff_evalcond(struct roff *r, int ln, char *v, int *pos)
 {  {
         char    *cp, *name;          const char      *start, *end;
         size_t   sz;          char            *cp, *name;
         int      deftype, number, savepos, istrue, wanttrue;          size_t           sz;
           int              deftype, len, number, savepos, istrue, wanttrue;
   
         if ('!' == v[*pos]) {          if ('!' == v[*pos]) {
                 wanttrue = 0;                  wanttrue = 0;
Line 2177  roff_evalcond(struct roff *r, int ln, char *v, int *po
Line 2185  roff_evalcond(struct roff *r, int ln, char *v, int *po
         case 'o':          case 'o':
                 (*pos)++;                  (*pos)++;
                 return wanttrue;                  return wanttrue;
         case 'c':  
         case 'e':          case 'e':
         case 't':          case 't':
         case 'v':          case 'v':
                 (*pos)++;                  (*pos)++;
                 return !wanttrue;                  return !wanttrue;
           case 'c':
                   do {
                           (*pos)++;
                   } while (v[*pos] == ' ');
   
                   /*
                    * Quirk for groff compatibility:
                    * The horizontal tab is neither available nor unavailable.
                    */
   
                   if (v[*pos] == '\t') {
                           (*pos)++;
                           return 0;
                   }
   
                   /* Printable ASCII characters are available. */
   
                   if (v[*pos] != '\\') {
                           (*pos)++;
                           return wanttrue;
                   }
   
                   end = v + ++*pos;
                   switch (mandoc_escape(&end, &start, &len)) {
                   case ESCAPE_SPECIAL:
                           istrue = mchars_spec2cp(start, len) != -1;
                           break;
                   case ESCAPE_UNICODE:
                           istrue = 1;
                           break;
                   case ESCAPE_NUMBERED:
                           istrue = mchars_num2char(start, len) != -1;
                           break;
                   default:
                           istrue = !wanttrue;
                           break;
                   }
                   *pos = end - v;
                   return istrue == wanttrue;
         case 'd':          case 'd':
         case 'r':          case 'r':
                 cp = v + *pos + 1;                  cp = v + *pos + 1;
Line 2616  roff_getregro(const struct roff *r, const char *name)
Line 2662  roff_getregro(const struct roff *r, const char *name)
   
         switch (*name) {          switch (*name) {
         case '$':  /* Number of arguments of the last macro evaluated. */          case '$':  /* Number of arguments of the last macro evaluated. */
                 return r->argc;                  return 0;
         case 'A':  /* ASCII approximation mode is always off. */          case 'A':  /* ASCII approximation mode is always off. */
                 return 0;                  return 0;
         case 'g':  /* Groff compatibility mode is always on. */          case 'g':  /* Groff compatibility mode is always on. */
Line 3110  roff_als(ROFF_ARGS)
Line 3156  roff_als(ROFF_ARGS)
         if (oldsz == 0)          if (oldsz == 0)
                 return ROFF_IGN;                  return ROFF_IGN;
   
         valsz = mandoc_asprintf(&value, ".%.*s \\$*\\\"\n",          valsz = mandoc_asprintf(&value, ".%.*s \\$@\\\"\n",
             (int)oldsz, oldn);              (int)oldsz, oldn);
         roff_setstrn(&r->strtab, newn, newsz, value, valsz, 0);          roff_setstrn(&r->strtab, newn, newsz, value, valsz, 0);
         roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0);          roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0);
Line 3334  roff_userdef(ROFF_ARGS)
Line 3380  roff_userdef(ROFF_ARGS)
 {  {
         const char       *arg[16], *ap;          const char       *arg[16], *ap;
         char             *cp, *n1, *n2;          char             *cp, *n1, *n2;
         int               expand_count, i, ib, ie;          int               argc, expand_count, i, ib, ie, quote_args;
         size_t            asz, rsz;          size_t            asz, esz, rsz;
   
         /*          /*
          * Collect pointers to macro argument strings           * Collect pointers to macro argument strings
          * and NUL-terminate them.           * and NUL-terminate them.
          */           */
   
         r->argc = 0;          argc = 0;
         cp = buf->buf + pos;          cp = buf->buf + pos;
         for (i = 0; i < 16; i++) {          for (i = 0; i < 16; i++) {
                 if (*cp == '\0')                  if (*cp == '\0')
                         arg[i] = "";                          arg[i] = "";
                 else {                  else {
                         arg[i] = mandoc_getarg(r->parse, &cp, ln, &pos);                          arg[i] = mandoc_getarg(r->parse, &cp, ln, &pos);
                         r->argc = i + 1;                          argc = i + 1;
                 }                  }
         }          }
   
Line 3369  roff_userdef(ROFF_ARGS)
Line 3415  roff_userdef(ROFF_ARGS)
                         continue;                          continue;
                 if (*cp++ != '$')                  if (*cp++ != '$')
                         continue;                          continue;
                 if (*cp == '*') {  /* \\$* inserts all arguments */  
                   quote_args = 0;
                   switch (*cp) {
                   case '@':  /* \\$@ inserts all arguments, quoted */
                           quote_args = 1;
                           /* FALLTHROUGH */
                   case '*':  /* \\$* inserts all arguments, unquoted */
                         ib = 0;                          ib = 0;
                         ie = r->argc - 1;                          ie = argc - 1;
                 } else {  /* \\$1 .. \\$9 insert one argument */                          break;
                   default:  /* \\$1 .. \\$9 insert one argument */
                         ib = ie = *cp - '1';                          ib = ie = *cp - '1';
                         if (ib < 0 || ib > 8)                          if (ib < 0 || ib > 8)
                                 continue;                                  continue;
                           break;
                 }                  }
                 cp -= 2;                  cp -= 2;
   
Line 3401  roff_userdef(ROFF_ARGS)
Line 3455  roff_userdef(ROFF_ARGS)
   
                 asz = ie > ib ? ie - ib : 0;  /* for blanks */                  asz = ie > ib ? ie - ib : 0;  /* for blanks */
                 for (i = ib; i <= ie; i++) {                  for (i = ib; i <= ie; i++) {
                           if (quote_args)
                                   asz += 2;
                         for (ap = arg[i]; *ap != '\0'; ap++) {                          for (ap = arg[i]; *ap != '\0'; ap++) {
                                 asz++;                                  asz++;
                                 if (*ap == '"')                                  if (*ap == '"')
Line 3447  roff_userdef(ROFF_ARGS)
Line 3503  roff_userdef(ROFF_ARGS)
   
                 n2 = cp;                  n2 = cp;
                 for (i = ib; i <= ie; i++) {                  for (i = ib; i <= ie; i++) {
                           if (quote_args)
                                   *n2++ = '"';
                         for (ap = arg[i]; *ap != '\0'; ap++) {                          for (ap = arg[i]; *ap != '\0'; ap++) {
                                 if (*ap == '"') {                                  if (*ap == '"') {
                                         memcpy(n2, "\\(dq", 4);                                          memcpy(n2, "\\(dq", 4);
Line 3454  roff_userdef(ROFF_ARGS)
Line 3512  roff_userdef(ROFF_ARGS)
                                 } else                                  } else
                                         *n2++ = *ap;                                          *n2++ = *ap;
                         }                          }
                           if (quote_args)
                                   *n2++ = '"';
                         if (i < ie)                          if (i < ie)
                                 *n2++ = ' ';                                  *n2++ = ' ';
                 }                  }
           }
   
           /*
            * Expand the number of arguments, if it is used.
            * This never makes the expanded macro longer.
            */
   
           for (cp = n1; *cp != '\0'; cp++) {
                   if (cp[0] != '\\')
                           continue;
                   if (cp[1] == '\\') {
                           cp++;
                           continue;
                   }
                   if (strncmp(cp + 1, "n(.$", 4) == 0)
                           esz = 5;
                   else if (strncmp(cp + 1, "n[.$]", 5) == 0)
                           esz = 6;
                   else
                           continue;
                   asz = snprintf(cp, esz, "%d", argc);
                   assert(asz < esz);
                   rsz = buf->sz - (cp - n1) - esz;
                   memmove(cp + asz, cp + esz, rsz);
                   buf->sz -= esz - asz;
                   n2 = mandoc_realloc(n1, buf->sz);
                   cp = n2 + (cp - n1) + asz;
                   n1 = n2;
         }          }
   
         /*          /*

Legend:
Removed from v.1.333  
changed lines
  Added in v.1.338

CVSweb