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

Diff for /mandoc/read.c between version 1.196 and 1.199

version 1.196, 2018/07/28 18:34:15 version 1.199, 2018/08/24 23:12:33
Line 48  struct mparse {
Line 48  struct mparse {
         char             *sodest; /* filename pointed to by .so */          char             *sodest; /* filename pointed to by .so */
         const char       *file; /* filename of current input file */          const char       *file; /* filename of current input file */
         struct buf       *primary; /* buffer currently being parsed */          struct buf       *primary; /* buffer currently being parsed */
         struct buf       *secondary; /* preprocessed copy of input */          struct buf       *secondary; /* copy of top level input */
           struct buf       *loop; /* open .while request line */
         const char       *os_s; /* default operating system */          const char       *os_s; /* default operating system */
         mandocmsg         mmsg; /* warning/error message handler */          mandocmsg         mmsg; /* warning/error message handler */
         enum mandoclevel  file_status; /* status of current parse */          enum mandoclevel  file_status; /* status of current parse */
Line 61  struct mparse {
Line 62  struct mparse {
 };  };
   
 static  void      choose_parser(struct mparse *);  static  void      choose_parser(struct mparse *);
   static  void      free_buf_list(struct buf *);
 static  void      resize_buf(struct buf *, size_t);  static  void      resize_buf(struct buf *, size_t);
 static  int       mparse_buf_r(struct mparse *, struct buf, size_t, int);  static  int       mparse_buf_r(struct mparse *, struct buf, size_t, int);
 static  int       read_whole_file(struct mparse *, const char *, int,  static  int       read_whole_file(struct mparse *, const char *, int,
Line 233  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 235  static const char * const mandocerrs[MANDOCERR_MAX] = 
         "input stack limit exceeded, infinite loop?",          "input stack limit exceeded, infinite loop?",
         "skipping bad character",          "skipping bad character",
         "skipping unknown macro",          "skipping unknown macro",
           "ignoring request outside macro",
         "skipping insecure request",          "skipping insecure request",
         "skipping item outside list",          "skipping item outside list",
         "skipping column outside column list",          "skipping column outside column list",
Line 243  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 246  static const char * const mandocerrs[MANDOCERR_MAX] = 
   
         /* related to request and macro arguments */          /* related to request and macro arguments */
         "escaped character not allowed in a name",          "escaped character not allowed in a name",
           "using macro argument outside macro",
           "argument number is not numeric",
         "NOT IMPLEMENTED: Bd -file",          "NOT IMPLEMENTED: Bd -file",
         "skipping display without arguments",          "skipping display without arguments",
         "missing list type, using -item",          "missing list type, using -item",
Line 251  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 256  static const char * const mandocerrs[MANDOCERR_MAX] = 
         "uname(3) system call failed, using UNKNOWN",          "uname(3) system call failed, using UNKNOWN",
         "unknown standard specifier",          "unknown standard specifier",
         "skipping request without numeric argument",          "skipping request without numeric argument",
           "excessive shift",
         "NOT IMPLEMENTED: .so with absolute path or \"..\"",          "NOT IMPLEMENTED: .so with absolute path or \"..\"",
         ".so request failed",          ".so request failed",
         "skipping all arguments",          "skipping all arguments",
Line 261  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 267  static const char * const mandocerrs[MANDOCERR_MAX] = 
         "input too large",          "input too large",
         "unsupported control character",          "unsupported control character",
         "unsupported roff request",          "unsupported roff request",
           "nested .while loops",
           "end of scope with open .while loop",
           "end of .while loop in inner scope",
           "cannot continue this .while loop",
         "eqn delim option in tbl",          "eqn delim option in tbl",
         "unsupported tbl layout modifier",          "unsupported tbl layout modifier",
         "ignoring macro in table",          "ignoring macro in table",
Line 286  resize_buf(struct buf *buf, size_t initial)
Line 296  resize_buf(struct buf *buf, size_t initial)
 }  }
   
 static void  static void
   free_buf_list(struct buf *buf)
   {
           struct buf *tmp;
   
           while (buf != NULL) {
                   tmp = buf;
                   buf = tmp->next;
                   free(tmp->buf);
                   free(tmp);
           }
   }
   
   static void
 choose_parser(struct mparse *curp)  choose_parser(struct mparse *curp)
 {  {
         char            *cp, *ep;          char            *cp, *ep;
Line 342  static int
Line 365  static int
 mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)  mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
 {  {
         struct buf       ln;          struct buf       ln;
           struct buf      *firstln, *lastln, *thisln, *loop;
         const char      *save_file;          const char      *save_file;
         char            *cp;          char            *cp;
         size_t           pos; /* byte number in the ln buffer */          size_t           pos; /* byte number in the ln buffer */
         enum rofferr     rr;          int              line_result, result;
         int              of;          int              of;
         int              lnn; /* line number in the real file */          int              lnn; /* line number in the real file */
         int              fd;          int              fd;
           int              inloop; /* Saw .while on this level. */
         unsigned char    c;          unsigned char    c;
   
         memset(&ln, 0, sizeof(ln));          ln.sz = 256;
           ln.buf = mandoc_malloc(ln.sz);
           ln.next = NULL;
           firstln = loop = NULL;
         lnn = curp->line;          lnn = curp->line;
         pos = 0;          pos = 0;
           inloop = 0;
           result = ROFF_CONT;
   
         while (i < blk.sz) {          while (i < blk.sz && (blk.buf[i] != '\0' || pos != 0)) {
                 if (0 == pos && '\0' == blk.buf[i])  
                         break;  
   
                 if (start) {                  if (start) {
                         curp->line = lnn;                          curp->line = lnn;
                         curp->reparse_count = 0;                          curp->reparse_count = 0;
Line 389  mparse_buf_r(struct mparse *curp, struct buf blk, size
Line 415  mparse_buf_r(struct mparse *curp, struct buf blk, size
   
                         /*                          /*
                          * Make sure we have space for the worst                           * Make sure we have space for the worst
                          * case of 11 bytes: "\\[u10ffff]\0"                           * case of 12 bytes: "\\[u10ffff]\n\0"
                          */                           */
   
                         if (pos + 11 > ln.sz)                          if (pos + 12 > ln.sz)
                                 resize_buf(&ln, 256);                                  resize_buf(&ln, 256);
   
                         /*                          /*
Line 428  mparse_buf_r(struct mparse *curp, struct buf blk, size
Line 454  mparse_buf_r(struct mparse *curp, struct buf blk, size
   
                         ln.buf[pos++] = blk.buf[i++];                          ln.buf[pos++] = blk.buf[i++];
                 }                  }
                   ln.buf[pos] = '\0';
   
                 if (pos + 1 >= ln.sz)                  /*
                         resize_buf(&ln, 256);                   * Maintain a lookaside buffer of all lines.
                    * parsed from this input source.
                    */
   
                 if (i == blk.sz || blk.buf[i] == '\0')                  thisln = mandoc_malloc(sizeof(*thisln));
                   thisln->buf = mandoc_strdup(ln.buf);
                   thisln->sz = strlen(ln.buf) + 1;
                   thisln->next = NULL;
                   if (firstln == NULL) {
                           firstln = lastln = thisln;
                           if (curp->secondary == NULL)
                                   curp->secondary = firstln;
                   } else {
                           lastln->next = thisln;
                           lastln = thisln;
                   }
   
                   /* XXX Ugly hack to mark the end of the input. */
   
                   if (i == blk.sz || blk.buf[i] == '\0') {
                         ln.buf[pos++] = '\n';                          ln.buf[pos++] = '\n';
                 ln.buf[pos] = '\0';                          ln.buf[pos] = '\0';
                   }
   
                 /*                  /*
                  * A significant amount of complexity is contained by                   * A significant amount of complexity is contained by
Line 446  mparse_buf_r(struct mparse *curp, struct buf blk, size
Line 491  mparse_buf_r(struct mparse *curp, struct buf blk, size
                  */                   */
   
                 of = 0;                  of = 0;
   rerun:
                   line_result = roff_parseln(curp->roff, curp->line, &ln, &of);
   
                 /*                  /* Process options. */
                  * Maintain a lookaside buffer of all parsed lines.  We  
                  * only do this if mparse_keep() has been invoked (the  
                  * buffer may be accessed with mparse_getkeep()).  
                  */  
   
                 if (curp->secondary) {                  if (line_result & ROFF_APPEND)
                         curp->secondary->buf = mandoc_realloc(                          assert(line_result == (ROFF_IGN | ROFF_APPEND));
                             curp->secondary->buf,  
                             curp->secondary->sz + pos + 2);                  if (line_result & ROFF_USERCALL)
                         memcpy(curp->secondary->buf +                          assert((line_result & ROFF_MASK) == ROFF_REPARSE);
                             curp->secondary->sz,  
                             ln.buf, pos);                  if (line_result & ROFF_USERRET) {
                         curp->secondary->sz += pos;                          assert(line_result == (ROFF_IGN | ROFF_USERRET));
                         curp->secondary->buf                          if (start == 0) {
                                 [curp->secondary->sz] = '\n';                                  /* Return from the current macro. */
                         curp->secondary->sz++;                                  result = ROFF_USERRET;
                         curp->secondary->buf                                  goto out;
                                 [curp->secondary->sz] = '\0';                          }
                 }                  }
 rerun:  
                 rr = roff_parseln(curp->roff, curp->line, &ln, &of);  
   
                 switch (rr) {                  switch (line_result & ROFF_LOOPMASK) {
                   case ROFF_IGN:
                           break;
                   case ROFF_WHILE:
                           if (curp->loop != NULL) {
                                   if (loop == curp->loop)
                                           break;
                                   mandoc_msg(MANDOCERR_WHILE_NEST,
                                       curp, curp->line, pos, NULL);
                           }
                           curp->loop = thisln;
                           loop = NULL;
                           inloop = 1;
                           break;
                   case ROFF_LOOPCONT:
                   case ROFF_LOOPEXIT:
                           if (curp->loop == NULL) {
                                   mandoc_msg(MANDOCERR_WHILE_FAIL,
                                       curp, curp->line, pos, NULL);
                                   break;
                           }
                           if (inloop == 0) {
                                   mandoc_msg(MANDOCERR_WHILE_INTO,
                                       curp, curp->line, pos, NULL);
                                   curp->loop = loop = NULL;
                                   break;
                           }
                           if (line_result & ROFF_LOOPCONT)
                                   loop = curp->loop;
                           else {
                                   curp->loop = loop = NULL;
                                   inloop = 0;
                           }
                           break;
                   default:
                           abort();
                   }
   
                   /* Process the main instruction from the roff parser. */
   
                   switch (line_result & ROFF_MASK) {
                   case ROFF_IGN:
                           break;
                   case ROFF_CONT:
                           if (curp->man->macroset == MACROSET_NONE)
                                   choose_parser(curp);
                           if ((curp->man->macroset == MACROSET_MDOC ?
                                mdoc_parseln(curp->man, curp->line, ln.buf, of) :
                                man_parseln(curp->man, curp->line, ln.buf, of)
                               ) == 2)
                                   goto out;
                           break;
                   case ROFF_RERUN:
                           goto rerun;
                 case ROFF_REPARSE:                  case ROFF_REPARSE:
                         if (++curp->reparse_count > REPARSE_LIMIT)                          if (++curp->reparse_count > REPARSE_LIMIT) {
                                   /* Abort and return to the top level. */
                                   result = ROFF_IGN;
                                 mandoc_msg(MANDOCERR_ROFFLOOP, curp,                                  mandoc_msg(MANDOCERR_ROFFLOOP, curp,
                                     curp->line, pos, NULL);                                      curp->line, pos, NULL);
                         else if (mparse_buf_r(curp, ln, of, 0) == 1 ||                                  goto out;
                             start == 1) {  
                                 pos = 0;  
                                 continue;  
                         }                          }
                         free(ln.buf);                          result = mparse_buf_r(curp, ln, of, 0);
                         return 0;                          if (line_result & ROFF_USERCALL) {
                 case ROFF_APPEND:                                  roff_userret(curp->roff);
                         pos = strlen(ln.buf);                                  /* Continue normally. */
                         continue;                                  if (result & ROFF_USERRET)
                 case ROFF_RERUN:                                          result = ROFF_CONT;
                         goto rerun;                          }
                 case ROFF_IGN:                          if (start == 0 && result != ROFF_CONT)
                         pos = 0;                                  goto out;
                         continue;                          break;
                 case ROFF_SO:                  case ROFF_SO:
                         if ( ! (curp->options & MPARSE_SO) &&                          if ( ! (curp->options & MPARSE_SO) &&
                             (i >= blk.sz || blk.buf[i] == '\0')) {                              (i >= blk.sz || blk.buf[i] == '\0')) {
                                 curp->sodest = mandoc_strdup(ln.buf + of);                                  curp->sodest = mandoc_strdup(ln.buf + of);
                                 free(ln.buf);                                  goto out;
                                 return 1;  
                         }                          }
                         /*  
                          * We remove `so' clauses from our lookaside  
                          * buffer because we're going to descend into  
                          * the file recursively.  
                          */  
                         if (curp->secondary)  
                                 curp->secondary->sz -= pos + 1;  
                         save_file = curp->file;                          save_file = curp->file;
                         if ((fd = mparse_open(curp, ln.buf + of)) != -1) {                          if ((fd = mparse_open(curp, ln.buf + of)) != -1) {
                                 mparse_readfd(curp, fd, ln.buf + of);                                  mparse_readfd(curp, fd, ln.buf + of);
Line 522  rerun:
Line 607  rerun:
                                 of = 0;                                  of = 0;
                                 mparse_buf_r(curp, ln, of, 0);                                  mparse_buf_r(curp, ln, of, 0);
                         }                          }
                         pos = 0;  
                         continue;  
                 default:  
                         break;                          break;
                   default:
                           abort();
                 }                  }
   
                 if (curp->man->macroset == MACROSET_NONE)                  /* Start the next input line. */
                         choose_parser(curp);  
   
                 if ((curp->man->macroset == MACROSET_MDOC ?                  if (loop != NULL &&
                     mdoc_parseln(curp->man, curp->line, ln.buf, of) :                      (line_result & ROFF_LOOPMASK) == ROFF_IGN)
                     man_parseln(curp->man, curp->line, ln.buf, of)) == 2)                          loop = loop->next;
                                 break;  
   
                 /* Temporary buffers typically are not full. */                  if (loop != NULL) {
                           if ((line_result & ROFF_APPEND) == 0)
                                   *ln.buf = '\0';
                           if (ln.sz < loop->sz)
                                   resize_buf(&ln, loop->sz);
                           (void)strlcat(ln.buf, loop->buf, ln.sz);
                           of = 0;
                           goto rerun;
                   }
   
                 if (0 == start && '\0' == blk.buf[i])                  pos = (line_result & ROFF_APPEND) ? strlen(ln.buf) : 0;
                         break;  
   
                 /* Start the next input line. */  
   
                 pos = 0;  
         }          }
   out:
           if (inloop) {
                   if (result != ROFF_USERRET)
                           mandoc_msg(MANDOCERR_WHILE_OUTOF, curp,
                               curp->line, pos, NULL);
                   curp->loop = NULL;
           }
         free(ln.buf);          free(ln.buf);
         return 1;          if (firstln != curp->secondary)
                   free_buf_list(firstln);
           return result;
 }  }
   
 static int  static int
Line 817  mparse_reset(struct mparse *curp)
Line 910  mparse_reset(struct mparse *curp)
 {  {
         roff_reset(curp->roff);          roff_reset(curp->roff);
         roff_man_reset(curp->man);          roff_man_reset(curp->man);
           free_buf_list(curp->secondary);
           curp->secondary = NULL;
   
         free(curp->sodest);          free(curp->sodest);
         curp->sodest = NULL;          curp->sodest = NULL;
   
         if (curp->secondary)  
                 curp->secondary->sz = 0;  
   
         curp->file_status = MANDOCLEVEL_OK;          curp->file_status = MANDOCLEVEL_OK;
         curp->gzip = 0;          curp->gzip = 0;
 }  }
Line 831  mparse_reset(struct mparse *curp)
Line 923  mparse_reset(struct mparse *curp)
 void  void
 mparse_free(struct mparse *curp)  mparse_free(struct mparse *curp)
 {  {
   
         roffhash_free(curp->man->mdocmac);          roffhash_free(curp->man->mdocmac);
         roffhash_free(curp->man->manmac);          roffhash_free(curp->man->manmac);
         roff_man_free(curp->man);          roff_man_free(curp->man);
         roff_free(curp->roff);          roff_free(curp->roff);
         if (curp->secondary)          free_buf_list(curp->secondary);
                 free(curp->secondary->buf);  
   
         free(curp->secondary);  
         free(curp->sodest);          free(curp->sodest);
         free(curp);          free(curp);
 }  }
Line 912  mparse_strlevel(enum mandoclevel lvl)
Line 1000  mparse_strlevel(enum mandoclevel lvl)
 }  }
   
 void  void
 mparse_keep(struct mparse *p)  mparse_copy(const struct mparse *p)
 {  {
           struct buf      *buf;
   
         assert(NULL == p->secondary);          for (buf = p->secondary; buf != NULL; buf = buf->next)
         p->secondary = mandoc_calloc(1, sizeof(struct buf));                  puts(buf->buf);
 }  
   
 const char *  
 mparse_getkeep(const struct mparse *p)  
 {  
   
         assert(p->secondary);  
         return p->secondary->sz ? p->secondary->buf : NULL;  
 }  }

Legend:
Removed from v.1.196  
changed lines
  Added in v.1.199

CVSweb