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

Diff for /mandoc/main.c between version 1.110 and 1.111

version 1.110, 2010/12/01 10:31:34 version 1.111, 2010/12/01 15:09:01
Line 79  enum outt {
Line 79  enum outt {
 struct  curparse {  struct  curparse {
         const char       *file;         /* Current parse. */          const char       *file;         /* Current parse. */
         int               fd;           /* Current parse. */          int               fd;           /* Current parse. */
           int               line;         /* Line number in the file. */
         enum mandoclevel  wlevel;       /* Ignore messages below this. */          enum mandoclevel  wlevel;       /* Ignore messages below this. */
         int               wstop;        /* Stop after a file with a warning. */          int               wstop;        /* Stop after a file with a warning. */
         enum intt         inttype;      /* which parser to use */          enum intt         inttype;      /* which parser to use */
Line 193  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 194  static const char * const mandocerrs[MANDOCERR_MAX] = 
         "static buffer exhausted",          "static buffer exhausted",
 };  };
   
   static  void              parsebuf(struct curparse *, struct buf, int);
   static  void              pdesc(struct curparse *);
 static  void              fdesc(struct curparse *);  static  void              fdesc(struct curparse *);
 static  void              ffile(const char *, struct curparse *);  static  void              ffile(const char *, struct curparse *);
   static  int               pfile(const char *, struct curparse *);
 static  int               moptions(enum intt *, char *);  static  int               moptions(enum intt *, char *);
 static  int               mmsg(enum mandocerr, void *,  static  int               mmsg(enum mandocerr, void *,
                                 int, int, const char *);                                  int, int, const char *);
Line 320  ffile(const char *file, struct curparse *curp)
Line 324  ffile(const char *file, struct curparse *curp)
                 perror(curp->file);                  perror(curp->file);
 }  }
   
   static int
   pfile(const char *file, struct curparse *curp)
   {
           const char      *savefile;
           int              fd, savefd;
   
           if (-1 == (fd = open(file, O_RDONLY, 0))) {
                   perror(file);
                   exit_status = MANDOCLEVEL_SYSERR;
                   return(0);
           }
   
           savefile = curp->file;
           savefd = curp->fd;
   
           curp->file = file;
           curp->fd = fd;
   
           pdesc(curp);
   
           curp->file = savefile;
           curp->fd = savefd;
   
           if (-1 == close(fd))
                   perror(file);
   
           return(MANDOCLEVEL_FATAL > exit_status ? 1 : 0);
   }
   
   
 static void  static void
 resize_buf(struct buf *buf, size_t initial)  resize_buf(struct buf *buf, size_t initial)
 {  {
Line 406  read_whole_file(struct curparse *curp, struct buf *fb,
Line 439  read_whole_file(struct curparse *curp, struct buf *fb,
 static void  static void
 fdesc(struct curparse *curp)  fdesc(struct curparse *curp)
 {  {
         struct buf       ln, blk;  
         int              i, pos, lnn, lnn_start, with_mmap, of;  
         enum rofferr     re;  
         unsigned char    c;  
         struct man      *man;          struct man      *man;
         struct mdoc     *mdoc;          struct mdoc     *mdoc;
         struct roff     *roff;          struct roff     *roff;
   
         man = NULL;          pdesc(curp);
         mdoc = NULL;  
         roff = NULL;  
   
         memset(&ln, 0, sizeof(struct buf));          man  = curp->man;
           mdoc = curp->mdoc;
           roff = curp->roff;
   
           if (MANDOCLEVEL_FATAL <= exit_status)
                   goto cleanup;
   
           /* NOTE a parser may not have been assigned, yet. */
   
           if ( ! (man || mdoc)) {
                   fprintf(stderr, "%s: Not a manual\n", curp->file);
                   exit_status = MANDOCLEVEL_FATAL;
                   goto cleanup;
           }
   
           /* Clean up the parse routine ASTs. */
   
           if (mdoc && ! mdoc_endparse(mdoc)) {
                   assert(MANDOCLEVEL_FATAL <= exit_status);
                   goto cleanup;
           }
           if (man && ! man_endparse(man)) {
                   assert(MANDOCLEVEL_FATAL <= exit_status);
                   goto cleanup;
           }
           if (roff && ! roff_endparse(roff)) {
                   assert(MANDOCLEVEL_FATAL <= exit_status);
                   goto cleanup;
           }
   
         /*          /*
          * Two buffers: ln and buf.  buf is the input file and may be           * With -Wstop and warnings or errors of at least
          * memory mapped.  ln is a line buffer and grows on-demand.           * the requested level, do not produce output.
          */           */
   
           if (MANDOCLEVEL_OK != exit_status && curp->wstop)
                   goto cleanup;
   
           /* If unset, allocate output dev now (if applicable). */
   
           if ( ! (curp->outman && curp->outmdoc)) {
                   switch (curp->outtype) {
                   case (OUTT_XHTML):
                           curp->outdata = xhtml_alloc(curp->outopts);
                           break;
                   case (OUTT_HTML):
                           curp->outdata = html_alloc(curp->outopts);
                           break;
                   case (OUTT_ASCII):
                           curp->outdata = ascii_alloc(curp->outopts);
                           curp->outfree = ascii_free;
                           break;
                   case (OUTT_PDF):
                           curp->outdata = pdf_alloc(curp->outopts);
                           curp->outfree = pspdf_free;
                           break;
                   case (OUTT_PS):
                           curp->outdata = ps_alloc(curp->outopts);
                           curp->outfree = pspdf_free;
                           break;
                   default:
                           break;
                   }
   
                   switch (curp->outtype) {
                   case (OUTT_HTML):
                           /* FALLTHROUGH */
                   case (OUTT_XHTML):
                           curp->outman = html_man;
                           curp->outmdoc = html_mdoc;
                           curp->outfree = html_free;
                           break;
                   case (OUTT_TREE):
                           curp->outman = tree_man;
                           curp->outmdoc = tree_mdoc;
                           break;
                   case (OUTT_PDF):
                           /* FALLTHROUGH */
                   case (OUTT_ASCII):
                           /* FALLTHROUGH */
                   case (OUTT_PS):
                           curp->outman = terminal_man;
                           curp->outmdoc = terminal_mdoc;
                           break;
                   default:
                           break;
                   }
           }
   
           /* Execute the out device, if it exists. */
   
           if (man && curp->outman)
                   (*curp->outman)(curp->outdata, man);
           if (mdoc && curp->outmdoc)
                   (*curp->outmdoc)(curp->outdata, mdoc);
   
    cleanup:
           memset(&curp->regs, 0, sizeof(struct regset));
           if (mdoc)
                   mdoc_reset(mdoc);
           if (man)
                   man_reset(man);
           if (roff)
                   roff_reset(roff);
   
           return;
   }
   
   
   static void
   pdesc(struct curparse *curp)
   {
           struct buf       blk;
           int              with_mmap;
   
         if ( ! read_whole_file(curp, &blk, &with_mmap)) {          if ( ! read_whole_file(curp, &blk, &with_mmap)) {
                 exit_status = MANDOCLEVEL_SYSERR;                  exit_status = MANDOCLEVEL_SYSERR;
                 return;                  return;
Line 433  fdesc(struct curparse *curp)
Line 568  fdesc(struct curparse *curp)
         if (NULL == curp->roff)          if (NULL == curp->roff)
                 curp->roff = roff_alloc(&curp->regs, curp, mmsg);                  curp->roff = roff_alloc(&curp->regs, curp, mmsg);
         assert(curp->roff);          assert(curp->roff);
   
           curp->line = 1;
           parsebuf(curp, blk, 1);
   
           if (with_mmap)
                   munmap(blk.buf, blk.sz);
           else
                   free(blk.buf);
   }
   
   static void
   parsebuf(struct curparse *curp, struct buf blk, int start)
   {
           struct buf       ln;
           int              i, pos, lnn, of;
           unsigned char    c;
           struct man      *man;
           struct mdoc     *mdoc;
           struct roff     *roff;
   
           man  = curp->man;
           mdoc = curp->mdoc;
         roff = curp->roff;          roff = curp->roff;
   
         for (i = 0, lnn = 1; i < (int)blk.sz;) {          memset(&ln, 0, sizeof(struct buf));
                 pos = 0;  
                 lnn_start = lnn;          lnn = curp->line;  /* line number in the real file */
                 while (i < (int)blk.sz) {          pos = 0;  /* byte number in the ln buffer */
   
           for (i = 0; i < (int)blk.sz;) {
                   if (0 == pos && '\0' == blk.buf[i])
                           break;
                   if (start)
                           curp->line = lnn;
   
                   while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {
                         if ('\n' == blk.buf[i]) {                          if ('\n' == blk.buf[i]) {
                                 ++i;                                  ++i;
                                 ++lnn;                                  ++lnn;
Line 457  fdesc(struct curparse *curp)
Line 622  fdesc(struct curparse *curp)
                         c = (unsigned char) blk.buf[i];                          c = (unsigned char) blk.buf[i];
                         if ( ! (isascii(c) && (isgraph(c) || isblank(c)))) {                          if ( ! (isascii(c) && (isgraph(c) || isblank(c)))) {
                                 mmsg(MANDOCERR_BADCHAR, curp,                                  mmsg(MANDOCERR_BADCHAR, curp,
                                     lnn_start, pos, "ignoring byte");                                      curp->line, pos, "ignoring byte");
                                 i++;                                  i++;
                                 continue;                                  continue;
                         }                          }
Line 517  fdesc(struct curparse *curp)
Line 682  fdesc(struct curparse *curp)
                  */                   */
   
                 of = 0;                  of = 0;
                 do {  rerun:
                         re = roff_parseln(roff, lnn_start,                  switch (roff_parseln(roff, curp->line, &ln.buf, &ln.sz,
                                         &ln.buf, &ln.sz, of, &of);                      of, &of)) {
                 } while (ROFF_RERUN == re);                  case (ROFF_REPARSE):
                           parsebuf(curp, ln, 0);
                 if (ROFF_IGN == re) {                          pos = 0;
                         continue;                          continue;
                 } else if (ROFF_ERR == re) {                  case (ROFF_APPEND):
                           pos = strlen(ln.buf);
                           continue;
                   case (ROFF_RERUN):
                           goto rerun;
                   case (ROFF_IGN):
                           pos = 0;
                           continue;
                   case (ROFF_ERR):
                         assert(MANDOCLEVEL_FATAL <= exit_status);                          assert(MANDOCLEVEL_FATAL <= exit_status);
                         goto cleanup;                          break;
                   case (ROFF_SO):
                           if (pfile(ln.buf + of, curp)) {
                                   pos = 0;
                                   continue;
                           } else
                                   break;
                   case (ROFF_CONT):
                           break;
                 }                  }
   
                 /*                  /*
Line 541  fdesc(struct curparse *curp)
Line 722  fdesc(struct curparse *curp)
   
                 /* Lastly, push down into the parsers themselves. */                  /* Lastly, push down into the parsers themselves. */
   
                 if (man && ! man_parseln(man, lnn_start, ln.buf, of)) {                  if (man && ! man_parseln(man, curp->line, ln.buf, of)) {
                         assert(MANDOCLEVEL_FATAL <= exit_status);                          assert(MANDOCLEVEL_FATAL <= exit_status);
                         goto cleanup;                          break;
                 }                  }
                 if (mdoc && ! mdoc_parseln(mdoc, lnn_start, ln.buf, of)) {                  if (mdoc && ! mdoc_parseln(mdoc, curp->line, ln.buf, of)) {
                         assert(MANDOCLEVEL_FATAL <= exit_status);                          assert(MANDOCLEVEL_FATAL <= exit_status);
                         goto cleanup;  
                 }  
         }  
   
         /* NOTE a parser may not have been assigned, yet. */  
   
         if ( ! (man || mdoc)) {  
                 fprintf(stderr, "%s: Not a manual\n", curp->file);  
                 exit_status = MANDOCLEVEL_FATAL;  
                 goto cleanup;  
         }  
   
         /* Clean up the parse routine ASTs. */  
   
         if (mdoc && ! mdoc_endparse(mdoc)) {  
                 assert(MANDOCLEVEL_FATAL <= exit_status);  
                 goto cleanup;  
         }  
         if (man && ! man_endparse(man)) {  
                 assert(MANDOCLEVEL_FATAL <= exit_status);  
                 goto cleanup;  
         }  
         if (roff && ! roff_endparse(roff)) {  
                 assert(MANDOCLEVEL_FATAL <= exit_status);  
                 goto cleanup;  
         }  
   
         /*  
          * With -Wstop and warnings or errors of at least  
          * the requested level, do not produce output.  
          */  
   
         if (MANDOCLEVEL_OK != exit_status && curp->wstop)  
                 goto cleanup;  
   
         /* If unset, allocate output dev now (if applicable). */  
   
         if ( ! (curp->outman && curp->outmdoc)) {  
                 switch (curp->outtype) {  
                 case (OUTT_XHTML):  
                         curp->outdata = xhtml_alloc(curp->outopts);  
                         break;                          break;
                 case (OUTT_HTML):  
                         curp->outdata = html_alloc(curp->outopts);  
                         break;  
                 case (OUTT_ASCII):  
                         curp->outdata = ascii_alloc(curp->outopts);  
                         curp->outfree = ascii_free;  
                         break;  
                 case (OUTT_PDF):  
                         curp->outdata = pdf_alloc(curp->outopts);  
                         curp->outfree = pspdf_free;  
                         break;  
                 case (OUTT_PS):  
                         curp->outdata = ps_alloc(curp->outopts);  
                         curp->outfree = pspdf_free;  
                         break;  
                 default:  
                         break;  
                 }                  }
   
                 switch (curp->outtype) {                  /* Temporary buffers typically are not full. */
                 case (OUTT_HTML):                  if (0 == start && '\0' == blk.buf[i])
                         /* FALLTHROUGH */  
                 case (OUTT_XHTML):  
                         curp->outman = html_man;  
                         curp->outmdoc = html_mdoc;  
                         curp->outfree = html_free;  
                         break;                          break;
                 case (OUTT_TREE):  
                         curp->outman = tree_man;                  /* Start the next input line. */
                         curp->outmdoc = tree_mdoc;                  pos = 0;
                         break;  
                 case (OUTT_PDF):  
                         /* FALLTHROUGH */  
                 case (OUTT_ASCII):  
                         /* FALLTHROUGH */  
                 case (OUTT_PS):  
                         curp->outman = terminal_man;  
                         curp->outmdoc = terminal_mdoc;  
                         break;  
                 default:  
                         break;  
                 }  
         }          }
   
         /* Execute the out device, if it exists. */          free(ln.buf);
   
         if (man && curp->outman)  
                 (*curp->outman)(curp->outdata, man);  
         if (mdoc && curp->outmdoc)  
                 (*curp->outmdoc)(curp->outdata, mdoc);  
   
  cleanup:  
         memset(&curp->regs, 0, sizeof(struct regset));  
         if (mdoc)  
                 mdoc_reset(mdoc);  
         if (man)  
                 man_reset(man);  
         if (roff)  
                 roff_reset(roff);  
         if (ln.buf)  
                 free(ln.buf);  
         if (with_mmap)  
                 munmap(blk.buf, blk.sz);  
         else  
                 free(blk.buf);  
   
         return;  
 }  }
   
   

Legend:
Removed from v.1.110  
changed lines
  Added in v.1.111

CVSweb