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

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

version 1.329, 2018/08/01 15:40:17 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 197  static enum rofferr  roff_line_ignore(ROFF_ARGS);
Line 196  static enum rofferr  roff_line_ignore(ROFF_ARGS);
 static  void             roff_man_alloc1(struct roff_man *);  static  void             roff_man_alloc1(struct roff_man *);
 static  void             roff_man_free1(struct roff_man *);  static  void             roff_man_free1(struct roff_man *);
 static  enum rofferr     roff_manyarg(ROFF_ARGS);  static  enum rofferr     roff_manyarg(ROFF_ARGS);
   static  enum rofferr     roff_nop(ROFF_ARGS);
 static  enum rofferr     roff_nr(ROFF_ARGS);  static  enum rofferr     roff_nr(ROFF_ARGS);
 static  enum rofferr     roff_onearg(ROFF_ARGS);  static  enum rofferr     roff_onearg(ROFF_ARGS);
 static  enum roff_tok    roff_parse(struct roff *, char *, int *,  static  enum roff_tok    roff_parse(struct roff *, char *, int *,
Line 326  const char *__roff_name[MAN_MAX + 1] = {
Line 326  const char *__roff_name[MAN_MAX + 1] = {
         "Dx",           "%Q",           "%U",           "Ta",          "Dx",           "%Q",           "%U",           "Ta",
         NULL,          NULL,
         "TH",           "SH",           "SS",           "TP",          "TH",           "SH",           "SS",           "TP",
           "TQ",
         "LP",           "PP",           "P",            "IP",          "LP",           "PP",           "P",            "IP",
         "HP",           "SM",           "SB",           "BI",          "HP",           "SM",           "SB",           "BI",
         "IB",           "BR",           "RB",           "R",          "IB",           "BR",           "RB",           "R",
Line 333  const char *__roff_name[MAN_MAX + 1] = {
Line 334  const char *__roff_name[MAN_MAX + 1] = {
         "nf",           "fi",          "nf",           "fi",
         "RE",           "RS",           "DT",           "UC",          "RE",           "RS",           "DT",           "UC",
         "PD",           "AT",           "in",          "PD",           "AT",           "in",
         "OP",           "EX",           "EE",           "UR",          "SY",           "YS",           "OP",
           "EX",           "EE",           "UR",
         "UE",           "MT",           "ME",           NULL          "UE",           "MT",           "ME",           NULL
 };  };
 const   char *const *roff_name = __roff_name;  const   char *const *roff_name = __roff_name;
Line 490  static struct roffmac  roffs[TOKEN_NONE] = {
Line 492  static struct roffmac  roffs[TOKEN_NONE] = {
         { roff_line_ignore, NULL, NULL, 0 },  /* nhychar */          { roff_line_ignore, NULL, NULL, 0 },  /* nhychar */
         { roff_unsupp, NULL, NULL, 0 },  /* nm */          { roff_unsupp, NULL, NULL, 0 },  /* nm */
         { roff_unsupp, NULL, NULL, 0 },  /* nn */          { roff_unsupp, NULL, NULL, 0 },  /* nn */
         { roff_unsupp, NULL, NULL, 0 },  /* nop */          { roff_nop, NULL, NULL, 0 },  /* nop */
         { roff_nr, NULL, NULL, 0 },  /* nr */          { roff_nr, NULL, NULL, 0 },  /* nr */
         { roff_unsupp, NULL, NULL, 0 },  /* nrf */          { roff_unsupp, NULL, NULL, 0 },  /* nrf */
         { roff_line_ignore, NULL, NULL, 0 },  /* nroff */          { roff_line_ignore, NULL, NULL, 0 },  /* nroff */
Line 1202  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 1366  roff_res(struct roff *r, struct buf *buf, int ln, int 
Line 1376  roff_res(struct roff *r, struct buf *buf, int ln, int 
                         if (arg_complete) {                          if (arg_complete) {
                                 deftype = ROFFDEF_USER | ROFFDEF_PRE;                                  deftype = ROFFDEF_USER | ROFFDEF_PRE;
                                 res = roff_getstrn(r, stnam, naml, &deftype);                                  res = roff_getstrn(r, stnam, naml, &deftype);
   
                                   /*
                                    * If not overriden, let \*(.T
                                    * through to the formatters.
                                    */
   
                                   if (res == NULL && naml == 2 &&
                                       stnam[0] == '.' && stnam[1] == 'T') {
                                           roff_setstrn(&r->strtab,
                                               ".T", 2, NULL, 0, 0);
                                           stesc--;
                                           continue;
                                   }
                         }                          }
                         break;                          break;
                 case 'B':                  case 'B':
Line 2144  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 2161  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 2600  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 3094  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 3161  roff_eo(ROFF_ARGS)
Line 3223  roff_eo(ROFF_ARGS)
 }  }
   
 static enum rofferr  static enum rofferr
   roff_nop(ROFF_ARGS)
   {
           while (buf->buf[pos] == ' ')
                   pos++;
           *offs = pos;
           return ROFF_RERUN;
   }
   
   static enum rofferr
 roff_tr(ROFF_ARGS)  roff_tr(ROFF_ARGS)
 {  {
         const char      *p, *first, *second;          const char      *p, *first, *second;
Line 3309  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 3344  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 3376  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 3422  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 3429  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.329  
changed lines
  Added in v.1.338

CVSweb