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

Diff for /mandoc/main.c between version 1.121 and 1.140

version 1.121, 2010/12/06 16:55:35 version 1.140, 2011/01/24 23:41:55
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010, 2011 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 41 
Line 41 
 #define MAP_FILE        0  #define MAP_FILE        0
 #endif  #endif
   
   #define REPARSE_LIMIT   1000
 #define UNCONST(a)      ((void *)(uintptr_t)(const void *)(a))  #define UNCONST(a)      ((void *)(uintptr_t)(const void *)(a))
   
 /* FIXME: Intel's compiler?  LLVM?  pcc?  */  /* FIXME: Intel's compiler?  LLVM?  pcc?  */
Line 89  struct curparse {
Line 90  struct curparse {
         struct mdoc      *mdoc;         /* mdoc parser */          struct mdoc      *mdoc;         /* mdoc parser */
         struct roff      *roff;         /* roff parser (!NULL) */          struct roff      *roff;         /* roff parser (!NULL) */
         struct regset     regs;         /* roff registers */          struct regset     regs;         /* roff registers */
           int               reparse_count; /* finite interpolation stack */
         enum outt         outtype;      /* which output to use */          enum outt         outtype;      /* which output to use */
         out_mdoc          outmdoc;      /* mdoc output ptr */          out_mdoc          outmdoc;      /* mdoc output ptr */
         out_man           outman;       /* man output ptr */          out_man           outman;       /* man output ptr */
Line 151  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 153  static const char * const mandocerrs[MANDOCERR_MAX] = 
   
         /* related to missing macro arguments */          /* related to missing macro arguments */
         "skipping empty macro",          "skipping empty macro",
           "argument count wrong",
         "missing display type",          "missing display type",
         "list type must come first",          "list type must come first",
         "tag lists require a width argument",          "tag lists require a width argument",
         "missing font type",          "missing font type",
           "skipping end of block that is not open",
   
         /* related to bad macro arguments */          /* related to bad macro arguments */
         "skipping argument",          "skipping argument",
Line 174  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 178  static const char * const mandocerrs[MANDOCERR_MAX] = 
         "bad comment style",          "bad comment style",
         "unknown escape sequence",          "unknown escape sequence",
         "unterminated quoted string",          "unterminated quoted string",
   
         "generic error",          "generic error",
   
           /* related to tables */
           "bad table syntax",
           "bad table option",
           "bad table layout",
           "no table layout cells specified",
           "no table data cells specified",
           "ignore data in cell",
           "data block still open",
           "ignoring extra data cells",
   
           "input stack limit exceeded, infinite loop?",
         "skipping bad character",          "skipping bad character",
           "escaped character not allowed in a name",
         "skipping text before the first section header",          "skipping text before the first section header",
         "skipping unknown macro",          "skipping unknown macro",
         "NOT IMPLEMENTED: skipping request",          "NOT IMPLEMENTED, please use groff: skipping request",
         "line scope broken",          "line scope broken",
         "argument count wrong",          "argument count wrong",
         "skipping end of block that is not open",          "skipping end of block that is not open",
Line 386  static void
Line 402  static void
 resize_buf(struct buf *buf, size_t initial)  resize_buf(struct buf *buf, size_t initial)
 {  {
   
         buf->sz = buf->sz ? 2 * buf->sz : initial;          buf->sz = buf->sz > initial/2 ? 2 * buf->sz : initial;
         buf->buf = realloc(buf->buf, buf->sz);          buf->buf = realloc(buf->buf, buf->sz);
         if (NULL == buf->buf) {          if (NULL == buf->buf) {
                 perror(NULL);                  perror(NULL);
Line 519  fdesc(struct curparse *curp)
Line 535  fdesc(struct curparse *curp)
         }          }
   
         assert(curp->roff);          assert(curp->roff);
         if ( ! roff_endparse(curp->roff)) {          roff_endparse(curp->roff);
                 assert(MANDOCLEVEL_FATAL <= file_status);  
                 goto cleanup;  
         }  
   
         /*          /*
          * With -Wstop and warnings or errors of at least           * With -Wstop and warnings or errors of at least
Line 665  parsebuf(struct curparse *curp, struct buf blk, int st
Line 678  parsebuf(struct curparse *curp, struct buf blk, int st
                 if (0 == pos && '\0' == blk.buf[i])                  if (0 == pos && '\0' == blk.buf[i])
                         break;                          break;
   
                 if (start)                  if (start) {
                         curp->line = lnn;                          curp->line = lnn;
                           curp->reparse_count = 0;
                   }
   
                 while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {                  while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {
   
                           /*
                            * When finding an unescaped newline character,
                            * leave the character loop to process the line.
                            * Skip a preceding carriage return, if any.
                            */
   
                           if ('\r' == blk.buf[i] && i + 1 < (int)blk.sz &&
                               '\n' == blk.buf[i + 1])
                                   ++i;
                         if ('\n' == blk.buf[i]) {                          if ('\n' == blk.buf[i]) {
                                 ++i;                                  ++i;
                                 ++lnn;                                  ++lnn;
Line 703  parsebuf(struct curparse *curp, struct buf blk, int st
Line 728  parsebuf(struct curparse *curp, struct buf blk, int st
                                 continue;                                  continue;
                         }                          }
   
                         /* Found escape & at least one other char. */                          /*
                            * Found escape and at least one other character.
                            * When it's a newline character, skip it.
                            * When there is a carriage return in between,
                            * skip that one as well.
                            */
   
                           if ('\r' == blk.buf[i + 1] && i + 2 < (int)blk.sz &&
                               '\n' == blk.buf[i + 2])
                                   ++i;
                         if ('\n' == blk.buf[i + 1]) {                          if ('\n' == blk.buf[i + 1]) {
                                 i += 2;                                  i += 2;
                                 /* Escaped newlines are skipped over */  
                                 ++lnn;                                  ++lnn;
                                 continue;                                  continue;
                         }                          }
Line 765  rerun:
Line 797  rerun:
   
                 switch (rr) {                  switch (rr) {
                 case (ROFF_REPARSE):                  case (ROFF_REPARSE):
                         parsebuf(curp, ln, 0);                          if (REPARSE_LIMIT >= ++curp->reparse_count)
                                   parsebuf(curp, ln, 0);
                           else
                                   mmsg(MANDOCERR_ROFFLOOP, curp,
                                       curp->line, pos, NULL);
                         pos = 0;                          pos = 0;
                         continue;                          continue;
                 case (ROFF_APPEND):                  case (ROFF_APPEND):
Line 785  rerun:
Line 821  rerun:
                                 continue;                                  continue;
                         } else                          } else
                                 break;                                  break;
                 case (ROFF_CONT):                  default:
                         break;                          break;
                 }                  }
   
                 /*                  /*
                    * If we encounter errors in the recursive parsebuf()
                    * call, make sure we don't continue parsing.
                    */
   
                   if (MANDOCLEVEL_FATAL <= file_status)
                           break;
   
                   /*
                  * If input parsers have not been allocated, do so now.                   * If input parsers have not been allocated, do so now.
                  * We keep these instanced betwen parsers, but set them                   * We keep these instanced betwen parsers, but set them
                  * locally per parse routine since we can use different                   * locally per parse routine since we can use different
Line 803  rerun:
Line 847  rerun:
                  * Lastly, push down into the parsers themselves.  One                   * Lastly, push down into the parsers themselves.  One
                  * of these will have already been set in the pset()                   * of these will have already been set in the pset()
                  * routine.                   * routine.
                    * If libroff returns ROFF_TBL, then add it to the
                    * currently open parse.  Since we only get here if
                    * there does exist data (see tbl_data.c), we're
                    * guaranteed that something's been allocated.
                  */                   */
   
                 if (curp->man || curp->mdoc) {                  if (ROFF_TBL == rr) {
                           assert(curp->man || curp->mdoc);
                           if (curp->man)
                                   man_addspan(curp->man, roff_span(curp->roff));
                           else
                                   mdoc_addspan(curp->mdoc, roff_span(curp->roff));
   
                   } else if (curp->man || curp->mdoc) {
                         rc = curp->man ?                          rc = curp->man ?
                                 man_parseln(curp->man,                                  man_parseln(curp->man,
                                         curp->line, ln.buf, of) :                                          curp->line, ln.buf, of) :

Legend:
Removed from v.1.121  
changed lines
  Added in v.1.140

CVSweb