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

Diff for /mandoc/roff.c between version 1.238 and 1.250

version 1.238, 2014/11/01 06:03:13 version 1.250, 2015/01/16 16:53:49
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2010, 2011, 2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 21 
Line 21 
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
   #include <limits.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
Line 74  enum rofft {
Line 75  enum rofft {
         ROFF_T_,          ROFF_T_,
         ROFF_EQ,          ROFF_EQ,
         ROFF_EN,          ROFF_EN,
           ROFF_IX,
         ROFF_cblock,          ROFF_cblock,
         ROFF_USERDEF,          ROFF_USERDEF,
         ROFF_MAX          ROFF_MAX
Line 273  static struct roffmac  roffs[ROFF_MAX] = {
Line 275  static struct roffmac  roffs[ROFF_MAX] = {
         { "T&", roff_T_, NULL, NULL, 0, NULL },          { "T&", roff_T_, NULL, NULL, 0, NULL },
         { "EQ", roff_EQ, NULL, NULL, 0, NULL },          { "EQ", roff_EQ, NULL, NULL, 0, NULL },
         { "EN", roff_EN, NULL, NULL, 0, NULL },          { "EN", roff_EN, NULL, NULL, 0, NULL },
           { "IX", roff_line_ignore, NULL, NULL, 0, NULL },
         { ".", roff_cblock, NULL, NULL, 0, NULL },          { ".", roff_cblock, NULL, NULL, 0, NULL },
         { NULL, roff_userdef, NULL, NULL, 0, NULL },          { NULL, roff_userdef, NULL, NULL, 0, NULL },
 };  };
Line 650  roff_res(struct roff *r, struct buf *buf, int ln, int 
Line 653  roff_res(struct roff *r, struct buf *buf, int ln, int 
                             r->parse, ln, (int)(stesc - buf->buf),                              r->parse, ln, (int)(stesc - buf->buf),
                             "%.*s", (int)naml, stnam);                              "%.*s", (int)naml, stnam);
                         res = "";                          res = "";
                   } else if (buf->sz + strlen(res) > SHRT_MAX) {
                           mandoc_msg(MANDOCERR_ROFFLOOP, r->parse,
                               ln, (int)(stesc - buf->buf), NULL);
                           return(ROFF_IGN);
                 }                  }
   
                 /* Replace the escape sequence by the string. */                  /* Replace the escape sequence by the string. */
Line 730  roff_parseln(struct roff *r, int ln, struct buf *buf, 
Line 737  roff_parseln(struct roff *r, int ln, struct buf *buf, 
         enum rofft       t;          enum rofft       t;
         enum rofferr     e;          enum rofferr     e;
         int              pos;   /* parse point */          int              pos;   /* parse point */
           int              spos;  /* saved parse point for messages */
         int              ppos;  /* original offset in buf->buf */          int              ppos;  /* original offset in buf->buf */
         int              ctl;   /* macro line (boolean) */          int              ctl;   /* macro line (boolean) */
   
Line 800  roff_parseln(struct roff *r, int ln, struct buf *buf, 
Line 808  roff_parseln(struct roff *r, int ln, struct buf *buf, 
                 return((*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs));                  return((*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs));
         }          }
   
           /* No scope is open.  This is a new request or macro. */
   
           spos = pos;
           t = roff_parse(r, buf->buf, &pos, ln, ppos);
   
           /* Tables ignore most macros. */
   
           if (r->tbl != NULL && (t == ROFF_MAX || t == ROFF_TS)) {
                   mandoc_msg(MANDOCERR_TBLMACRO, r->parse,
                       ln, pos, buf->buf + spos);
                   return(ROFF_IGN);
           }
   
         /*          /*
          * Lastly, as we've no scope open, try to look up and execute           * This is neither a roff request nor a user-defined macro.
          * the new macro.  If no macro is found, simply return and let           * Let the standard macro set parsers handle it.
          * the compilers handle it.  
          */           */
   
         if ((t = roff_parse(r, buf->buf, &pos, ln, ppos)) == ROFF_MAX)          if (t == ROFF_MAX)
                 return(ROFF_CONT);                  return(ROFF_CONT);
   
           /* Execute a roff request or a user defined macro. */
   
         assert(roffs[t].proc);          assert(roffs[t].proc);
         return((*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs));          return((*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs));
 }  }
Line 1143  roff_cond_sub(ROFF_ARGS)
Line 1165  roff_cond_sub(ROFF_ARGS)
                         *ep = '&';                          *ep = '&';
                         roff_ccond(r, ln, ep - buf->buf - 1);                          roff_ccond(r, ln, ep - buf->buf - 1);
                 }                  }
                 ++ep;                  if (*ep != '\0')
                           ++ep;
         }          }
         return(rr ? ROFF_CONT : ROFF_IGN);          return(rr ? ROFF_CONT : ROFF_IGN);
 }  }
Line 1163  roff_cond_text(ROFF_ARGS)
Line 1186  roff_cond_text(ROFF_ARGS)
                         *ep = '&';                          *ep = '&';
                         roff_ccond(r, ln, ep - buf->buf - 1);                          roff_ccond(r, ln, ep - buf->buf - 1);
                 }                  }
                 ++ep;                  if (*ep != '\0')
                           ++ep;
         }          }
         return(rr ? ROFF_CONT : ROFF_IGN);          return(rr ? ROFF_CONT : ROFF_IGN);
 }  }
Line 1236  roff_evalstrcond(const char *v, int *pos)
Line 1260  roff_evalstrcond(const char *v, int *pos)
 out:  out:
         if (NULL == s3)          if (NULL == s3)
                 s3 = strchr(s2, '\0');                  s3 = strchr(s2, '\0');
         else          else if (*s3 != '\0')
                 s3++;                  s3++;
         *pos = s3 - v;          *pos = s3 - v;
         return(match);          return(match);
Line 1249  out:
Line 1273  out:
 static int  static int
 roff_evalcond(struct roff *r, int ln, const char *v, int *pos)  roff_evalcond(struct roff *r, int ln, const char *v, int *pos)
 {  {
         int      wanttrue, number;          int      number, savepos, wanttrue;
   
         if ('!' == v[*pos]) {          if ('!' == v[*pos]) {
                 wanttrue = 0;                  wanttrue = 0;
Line 1258  roff_evalcond(struct roff *r, int ln, const char *v, i
Line 1282  roff_evalcond(struct roff *r, int ln, const char *v, i
                 wanttrue = 1;                  wanttrue = 1;
   
         switch (v[*pos]) {          switch (v[*pos]) {
           case '\0':
                   return(0);
         case 'n':          case 'n':
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         case 'o':          case 'o':
Line 1272  roff_evalcond(struct roff *r, int ln, const char *v, i
Line 1298  roff_evalcond(struct roff *r, int ln, const char *v, i
         case 'r':          case 'r':
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         case 't':          case 't':
                   /* FALLTHROUGH */
           case 'v':
                 (*pos)++;                  (*pos)++;
                 return(!wanttrue);                  return(!wanttrue);
         default:          default:
                 break;                  break;
         }          }
   
           savepos = *pos;
         if (roff_evalnum(r, ln, v, pos, &number, 0))          if (roff_evalnum(r, ln, v, pos, &number, 0))
                 return((number > 0) == wanttrue);                  return((number > 0) == wanttrue);
         else          else if (*pos == savepos)
                 return(roff_evalstrcond(v, pos) == wanttrue);                  return(roff_evalstrcond(v, pos) == wanttrue);
           else
                   return (0);
 }  }
   
 static enum rofferr  static enum rofferr
Line 1554  roff_evalnum(struct roff *r, int ln, const char *v,
Line 1585  roff_evalnum(struct roff *r, int ln, const char *v,
                         *res *= operand2;                          *res *= operand2;
                         break;                          break;
                 case '/':                  case '/':
                         if (0 == operand2) {                          if (operand2 == 0) {
                                 mandoc_msg(MANDOCERR_DIVZERO,                                  mandoc_msg(MANDOCERR_DIVZERO,
                                         r->parse, ln, *pos, v);                                          r->parse, ln, *pos, v);
                                 *res = 0;                                  *res = 0;
Line 1563  roff_evalnum(struct roff *r, int ln, const char *v,
Line 1594  roff_evalnum(struct roff *r, int ln, const char *v,
                         *res /= operand2;                          *res /= operand2;
                         break;                          break;
                 case '%':                  case '%':
                           if (operand2 == 0) {
                                   mandoc_msg(MANDOCERR_DIVZERO,
                                           r->parse, ln, *pos, v);
                                   *res = 0;
                                   break;
                           }
                         *res %= operand2;                          *res %= operand2;
                         break;                          break;
                 case '<':                  case '<':
Line 2068  roff_tr(ROFF_ARGS)
Line 2105  roff_tr(ROFF_ARGS)
 static enum rofferr  static enum rofferr
 roff_so(ROFF_ARGS)  roff_so(ROFF_ARGS)
 {  {
         char *name;          char *name, *cp;
   
         name = buf->buf + pos;          name = buf->buf + pos;
         mandoc_vmsg(MANDOCERR_SO, r->parse, ln, ppos, "so %s", name);          mandoc_vmsg(MANDOCERR_SO, r->parse, ln, ppos, "so %s", name);
Line 2083  roff_so(ROFF_ARGS)
Line 2120  roff_so(ROFF_ARGS)
         if (*name == '/' || strstr(name, "../") || strstr(name, "/..")) {          if (*name == '/' || strstr(name, "../") || strstr(name, "/..")) {
                 mandoc_vmsg(MANDOCERR_SO_PATH, r->parse, ln, ppos,                  mandoc_vmsg(MANDOCERR_SO_PATH, r->parse, ln, ppos,
                     ".so %s", name);                      ".so %s", name);
                 return(ROFF_ERR);                  buf->sz = mandoc_asprintf(&cp,
                       ".sp\nSee the file %s.\n.sp", name) + 1;
                   free(buf->buf);
                   buf->buf = cp;
                   *offs = 0;
                   return(ROFF_REPARSE);
         }          }
   
         *offs = pos;          *offs = pos;
Line 2134  roff_userdef(ROFF_ARGS)
Line 2176  roff_userdef(ROFF_ARGS)
         buf->buf = n1;          buf->buf = n1;
         if (buf->sz == 0)          if (buf->sz == 0)
                 buf->sz = strlen(buf->buf) + 1;                  buf->sz = strlen(buf->buf) + 1;
           *offs = 0;
   
         return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?          return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?
            ROFF_REPARSE : ROFF_APPEND);             ROFF_REPARSE : ROFF_APPEND);

Legend:
Removed from v.1.238  
changed lines
  Added in v.1.250

CVSweb