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

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

version 1.198, 2018/08/23 19:33:27 version 1.199, 2018/08/24 23:12:33
Line 49  struct mparse {
Line 49  struct mparse {
         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; /* copy of top level 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 63  struct mparse {
Line 64  struct mparse {
 static  void      choose_parser(struct mparse *);  static  void      choose_parser(struct mparse *);
 static  void      free_buf_list(struct buf *);  static  void      free_buf_list(struct buf *);
 static  void      resize_buf(struct buf *, size_t);  static  void      resize_buf(struct buf *, size_t);
 static  enum rofferr 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,
                                 struct buf *, int *);                                  struct buf *, int *);
 static  void      mparse_end(struct mparse *);  static  void      mparse_end(struct mparse *);
Line 266  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 356  choose_parser(struct mparse *curp)
Line 361  choose_parser(struct mparse *curp)
  * macros, inline equations, and input line traps)   * macros, inline equations, and input line traps)
  * and indirectly (for .so file inclusion).   * and indirectly (for .so file inclusion).
  */   */
 static enum rofferr  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;          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     line_result, result;          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;
   
         ln.sz = 256;          ln.sz = 256;
         ln.buf = mandoc_malloc(ln.sz);          ln.buf = mandoc_malloc(ln.sz);
         ln.next = NULL;          ln.next = NULL;
         firstln = NULL;          firstln = loop = NULL;
         lnn = curp->line;          lnn = curp->line;
         pos = 0;          pos = 0;
           inloop = 0;
         result = ROFF_CONT;          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 490  mparse_buf_r(struct mparse *curp, struct buf blk, size
Line 494  mparse_buf_r(struct mparse *curp, struct buf blk, size
 rerun:  rerun:
                 line_result = roff_parseln(curp->roff, curp->line, &ln, &of);                  line_result = roff_parseln(curp->roff, curp->line, &ln, &of);
   
                 switch (line_result) {                  /* Process options. */
   
                   if (line_result & ROFF_APPEND)
                           assert(line_result == (ROFF_IGN | ROFF_APPEND));
   
                   if (line_result & ROFF_USERCALL)
                           assert((line_result & ROFF_MASK) == ROFF_REPARSE);
   
                   if (line_result & ROFF_USERRET) {
                           assert(line_result == (ROFF_IGN | ROFF_USERRET));
                           if (start == 0) {
                                   /* Return from the current macro. */
                                   result = ROFF_USERRET;
                                   goto out;
                           }
                   }
   
                   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:
                 case ROFF_USERCALL:  
                         if (++curp->reparse_count > REPARSE_LIMIT) {                          if (++curp->reparse_count > REPARSE_LIMIT) {
                                   /* Abort and return to the top level. */
                                 result = ROFF_IGN;                                  result = ROFF_IGN;
                                 mandoc_msg(MANDOCERR_ROFFLOOP, curp,                                  mandoc_msg(MANDOCERR_ROFFLOOP, curp,
                                     curp->line, pos, NULL);                                      curp->line, pos, NULL);
                         } else {                                  goto out;
                                 result = mparse_buf_r(curp, ln, of, 0);  
                                 if (line_result == ROFF_USERCALL) {  
                                         if (result == ROFF_USERRET)  
                                                 result = ROFF_CONT;  
                                         roff_userret(curp->roff);  
                                 }  
                                 if (start || result == ROFF_CONT) {  
                                         pos = 0;  
                                         continue;  
                                 }  
                         }                          }
                         goto out;                          result = mparse_buf_r(curp, ln, of, 0);
                 case ROFF_USERRET:                          if (line_result & ROFF_USERCALL) {
                         if (start) {                                  roff_userret(curp->roff);
                                 pos = 0;                                  /* Continue normally. */
                                 continue;                                  if (result & ROFF_USERRET)
                                           result = ROFF_CONT;
                         }                          }
                         result = ROFF_USERRET;                          if (start == 0 && result != ROFF_CONT)
                         goto out;                                  goto out;
                 case ROFF_APPEND:                          break;
                         pos = strlen(ln.buf);  
                         continue;  
                 case ROFF_RERUN:  
                         goto rerun;  
                 case ROFF_IGN:  
                         pos = 0;  
                         continue;  
                 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')) {
Line 549  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:  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);
         if (firstln != curp->secondary)          if (firstln != curp->secondary)
                 free_buf_list(firstln);                  free_buf_list(firstln);

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

CVSweb