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

Diff for /mandoc/read.c between version 1.39 and 1.46

version 1.39, 2013/09/16 00:25:07 version 1.46, 2014/03/23 11:25:26
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
    * Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.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 26 
Line 27 
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
   #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <stdarg.h>  #include <stdarg.h>
 #include <stdint.h>  #include <stdint.h>
Line 35 
Line 37 
 #include <unistd.h>  #include <unistd.h>
   
 #include "mandoc.h"  #include "mandoc.h"
   #include "mandoc_aux.h"
 #include "libmandoc.h"  #include "libmandoc.h"
 #include "mdoc.h"  #include "mdoc.h"
 #include "man.h"  #include "man.h"
Line 51  struct mparse {
Line 54  struct mparse {
         enum mandoclevel  file_status; /* status of current parse */          enum mandoclevel  file_status; /* status of current parse */
         enum mandoclevel  wlevel; /* ignore messages below this */          enum mandoclevel  wlevel; /* ignore messages below this */
         int               line; /* line number in the file */          int               line; /* line number in the file */
         enum mparset      inttype; /* which parser to use */          int               options; /* parser options */
         struct man       *pman; /* persistent man parser */          struct man       *pman; /* persistent man parser */
         struct mdoc      *pmdoc; /* persistent mdoc parser */          struct mdoc      *pmdoc; /* persistent mdoc parser */
         struct man       *man; /* man parser */          struct man       *man; /* man parser */
         struct mdoc      *mdoc; /* mdoc parser */          struct mdoc      *mdoc; /* mdoc parser */
         struct roff      *roff; /* roff parser (!NULL) */          struct roff      *roff; /* roff parser (!NULL) */
           char             *sodest; /* filename pointed to by .so */
         int               reparse_count; /* finite interp. stack */          int               reparse_count; /* finite interp. stack */
         mandocmsg         mmsg; /* warning/error message handler */          mandocmsg         mmsg; /* warning/error message handler */
         void             *arg; /* argument to mmsg */  
         const char       *file;          const char       *file;
         struct buf       *secondary;          struct buf       *secondary;
         char             *defos; /* default operating system */          char             *defos; /* default operating system */
Line 68  struct mparse {
Line 71  struct mparse {
 static  void      resize_buf(struct buf *, size_t);  static  void      resize_buf(struct buf *, size_t);
 static  void      mparse_buf_r(struct mparse *, struct buf, int);  static  void      mparse_buf_r(struct mparse *, struct buf, int);
 static  void      pset(const char *, int, struct mparse *);  static  void      pset(const char *, int, struct mparse *);
 static  int       read_whole_file(const char *, int, struct buf *, int *);  static  int       read_whole_file(struct mparse *, const char *, int,
                                   struct buf *, int *);
 static  void      mparse_end(struct mparse *);  static  void      mparse_end(struct mparse *);
 static  void      mparse_parse_buffer(struct mparse *, struct buf,  static  void      mparse_parse_buffer(struct mparse *, struct buf,
                         const char *);                          const char *);
Line 192  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 196  static const char * const mandocerrs[MANDOCERR_MAX] = 
   
         "generic fatal error",          "generic fatal error",
   
           "input too large",
         "not a manual",          "not a manual",
         "column syntax is inconsistent",          "column syntax is inconsistent",
         "NOT IMPLEMENTED: .Bd -file",          "NOT IMPLEMENTED: .Bd -file",
Line 202  static const char * const mandocerrs[MANDOCERR_MAX] = 
Line 207  static const char * const mandocerrs[MANDOCERR_MAX] = 
         "no document body",          "no document body",
         "no document prologue",          "no document prologue",
         "static buffer exhausted",          "static buffer exhausted",
   
           /* system errors */
           "cannot open file",
           "cannot stat file",
           "cannot read file",
 };  };
   
 static  const char * const      mandoclevels[MANDOCLEVEL_MAX] = {  static  const char * const      mandoclevels[MANDOCLEVEL_MAX] = {
Line 246  pset(const char *buf, int pos, struct mparse *curp)
Line 256  pset(const char *buf, int pos, struct mparse *curp)
                         return;                          return;
         }          }
   
         switch (curp->inttype) {          if (MPARSE_MDOC & curp->options) {
         case (MPARSE_MDOC):  
                 if (NULL == curp->pmdoc)                  if (NULL == curp->pmdoc)
                         curp->pmdoc = mdoc_alloc(curp->roff, curp,                          curp->pmdoc = mdoc_alloc(
                                         curp->defos);                              curp->roff, curp, curp->defos,
                               MPARSE_QUICK & curp->options ? 1 : 0);
                 assert(curp->pmdoc);                  assert(curp->pmdoc);
                 curp->mdoc = curp->pmdoc;                  curp->mdoc = curp->pmdoc;
                 return;                  return;
         case (MPARSE_MAN):          } else if (MPARSE_MAN & curp->options) {
                 if (NULL == curp->pman)                  if (NULL == curp->pman)
                         curp->pman = man_alloc(curp->roff, curp);                          curp->pman = man_alloc(curp->roff, curp,
                               MPARSE_QUICK & curp->options ? 1 : 0);
                 assert(curp->pman);                  assert(curp->pman);
                 curp->man = curp->pman;                  curp->man = curp->pman;
                 return;                  return;
         default:  
                 break;  
         }          }
   
         if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3))  {          if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3))  {
                 if (NULL == curp->pmdoc)                  if (NULL == curp->pmdoc)
                         curp->pmdoc = mdoc_alloc(curp->roff, curp,                          curp->pmdoc = mdoc_alloc(
                                         curp->defos);                              curp->roff, curp, curp->defos,
                               MPARSE_QUICK & curp->options ? 1 : 0);
                 assert(curp->pmdoc);                  assert(curp->pmdoc);
                 curp->mdoc = curp->pmdoc;                  curp->mdoc = curp->pmdoc;
                 return;                  return;
         }          }
   
         if (NULL == curp->pman)          if (NULL == curp->pman)
                 curp->pman = man_alloc(curp->roff, curp);                  curp->pman = man_alloc(curp->roff, curp,
                       MPARSE_QUICK & curp->options ? 1 : 0);
         assert(curp->pman);          assert(curp->pman);
         curp->man = curp->pman;          curp->man = curp->pman;
 }  }
Line 481  rerun:
Line 492  rerun:
                         assert(MANDOCLEVEL_FATAL <= curp->file_status);                          assert(MANDOCLEVEL_FATAL <= curp->file_status);
                         break;                          break;
                 case (ROFF_SO):                  case (ROFF_SO):
                           if (0 == (MPARSE_SO & curp->options) &&
                               (i >= (int)blk.sz || '\0' == blk.buf[i])) {
                                   curp->sodest = mandoc_strdup(ln.buf + of);
                                   free(ln.buf);
                                   return;
                           }
                         /*                          /*
                          * We remove `so' clauses from our lookaside                           * We remove `so' clauses from our lookaside
                          * buffer because we're going to descend into                           * buffer because we're going to descend into
Line 552  rerun:
Line 569  rerun:
                 if (0 == rc) {                  if (0 == rc) {
                         assert(MANDOCLEVEL_FATAL <= curp->file_status);                          assert(MANDOCLEVEL_FATAL <= curp->file_status);
                         break;                          break;
                 }                  } else if (2 == rc)
                           break;
   
                 /* Temporary buffers typically are not full. */                  /* Temporary buffers typically are not full. */
   
Line 568  rerun:
Line 586  rerun:
 }  }
   
 static int  static int
 read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)  read_whole_file(struct mparse *curp, const char *file, int fd,
                   struct buf *fb, int *with_mmap)
 {  {
         size_t           off;          size_t           off;
         ssize_t          ssz;          ssize_t          ssz;
Line 576  read_whole_file(const char *file, int fd, struct buf *
Line 595  read_whole_file(const char *file, int fd, struct buf *
 #ifdef  HAVE_MMAP  #ifdef  HAVE_MMAP
         struct stat      st;          struct stat      st;
         if (-1 == fstat(fd, &st)) {          if (-1 == fstat(fd, &st)) {
                 perror(file);                  curp->file_status = MANDOCLEVEL_SYSERR;
                   if (curp->mmsg)
                           (*curp->mmsg)(MANDOCERR_SYSSTAT, curp->file_status,
                               file, 0, 0, strerror(errno));
                 return(0);                  return(0);
         }          }
   
Line 589  read_whole_file(const char *file, int fd, struct buf *
Line 611  read_whole_file(const char *file, int fd, struct buf *
   
         if (S_ISREG(st.st_mode)) {          if (S_ISREG(st.st_mode)) {
                 if (st.st_size >= (1U << 31)) {                  if (st.st_size >= (1U << 31)) {
                         fprintf(stderr, "%s: input too large\n", file);                          curp->file_status = MANDOCLEVEL_FATAL;
                           if (curp->mmsg)
                                   (*curp->mmsg)(MANDOCERR_TOOLARGE,
                                       curp->file_status, file, 0, 0, NULL);
                         return(0);                          return(0);
                 }                  }
                 *with_mmap = 1;                  *with_mmap = 1;
Line 612  read_whole_file(const char *file, int fd, struct buf *
Line 637  read_whole_file(const char *file, int fd, struct buf *
         for (;;) {          for (;;) {
                 if (off == fb->sz) {                  if (off == fb->sz) {
                         if (fb->sz == (1U << 31)) {                          if (fb->sz == (1U << 31)) {
                                 fprintf(stderr, "%s: input too large\n", file);                                  curp->file_status = MANDOCLEVEL_FATAL;
                                   if (curp->mmsg)
                                           (*curp->mmsg)(MANDOCERR_TOOLARGE,
                                               curp->file_status,
                                               file, 0, 0, NULL);
                                 break;                                  break;
                         }                          }
                         resize_buf(fb, 65536);                          resize_buf(fb, 65536);
Line 623  read_whole_file(const char *file, int fd, struct buf *
Line 652  read_whole_file(const char *file, int fd, struct buf *
                         return(1);                          return(1);
                 }                  }
                 if (ssz == -1) {                  if (ssz == -1) {
                         perror(file);                          curp->file_status = MANDOCLEVEL_SYSERR;
                           if (curp->mmsg)
                                   (*curp->mmsg)(MANDOCERR_SYSREAD,
                                       curp->file_status, file, 0, 0,
                                       strerror(errno));
                         break;                          break;
                 }                  }
                 off += (size_t)ssz;                  off += (size_t)ssz;
Line 651  mparse_end(struct mparse *curp)
Line 684  mparse_end(struct mparse *curp)
                 return;                  return;
         }          }
   
         if ( ! (curp->man || curp->mdoc)) {          if ( ! (curp->mdoc || curp->man || curp->sodest)) {
                 mandoc_msg(MANDOCERR_NOTMANUAL, curp, 1, 0, NULL);                  mandoc_msg(MANDOCERR_NOTMANUAL, curp, 1, 0, NULL);
                 curp->file_status = MANDOCLEVEL_FATAL;                  curp->file_status = MANDOCLEVEL_FATAL;
                 return;                  return;
Line 704  mparse_readfd(struct mparse *curp, int fd, const char 
Line 737  mparse_readfd(struct mparse *curp, int fd, const char 
         struct buf       blk;          struct buf       blk;
         int              with_mmap;          int              with_mmap;
   
         if (-1 == fd)          if (-1 == fd && -1 == (fd = open(file, O_RDONLY, 0))) {
                 if (-1 == (fd = open(file, O_RDONLY, 0))) {                  curp->file_status = MANDOCLEVEL_SYSERR;
                         perror(file);                  if (curp->mmsg)
                         curp->file_status = MANDOCLEVEL_SYSERR;                          (*curp->mmsg)(MANDOCERR_SYSOPEN,
                         goto out;                              curp->file_status,
                 }                              file, 0, 0, strerror(errno));
                   goto out;
           }
   
         /*          /*
          * Run for each opened file; may be called more than once for           * Run for each opened file; may be called more than once for
          * each full parse sequence if the opened file is nested (i.e.,           * each full parse sequence if the opened file is nested (i.e.,
Line 717  mparse_readfd(struct mparse *curp, int fd, const char 
Line 753  mparse_readfd(struct mparse *curp, int fd, const char 
          * the parse phase for the file.           * the parse phase for the file.
          */           */
   
         if ( ! read_whole_file(file, fd, &blk, &with_mmap)) {          if ( ! read_whole_file(curp, file, fd, &blk, &with_mmap))
                 curp->file_status = MANDOCLEVEL_SYSERR;  
                 goto out;                  goto out;
         }  
   
         mparse_parse_buffer(curp, blk, file);          mparse_parse_buffer(curp, blk, file);
   
Line 738  out:
Line 772  out:
 }  }
   
 struct mparse *  struct mparse *
 mparse_alloc(enum mparset inttype, enum mandoclevel wlevel,  mparse_alloc(int options, enum mandoclevel wlevel,
                 mandocmsg mmsg, void *arg, char *defos)                  mandocmsg mmsg, char *defos)
 {  {
         struct mparse   *curp;          struct mparse   *curp;
   
Line 747  mparse_alloc(enum mparset inttype, enum mandoclevel wl
Line 781  mparse_alloc(enum mparset inttype, enum mandoclevel wl
   
         curp = mandoc_calloc(1, sizeof(struct mparse));          curp = mandoc_calloc(1, sizeof(struct mparse));
   
           curp->options = options;
         curp->wlevel = wlevel;          curp->wlevel = wlevel;
         curp->mmsg = mmsg;          curp->mmsg = mmsg;
         curp->arg = arg;  
         curp->inttype = inttype;  
         curp->defos = defos;          curp->defos = defos;
   
         curp->roff = roff_alloc(inttype, curp);          curp->roff = roff_alloc(curp, options);
         return(curp);          return(curp);
 }  }
   
Line 773  mparse_reset(struct mparse *curp)
Line 806  mparse_reset(struct mparse *curp)
         curp->file_status = MANDOCLEVEL_OK;          curp->file_status = MANDOCLEVEL_OK;
         curp->mdoc = NULL;          curp->mdoc = NULL;
         curp->man = NULL;          curp->man = NULL;
   
           free(curp->sodest);
           curp->sodest = NULL;
 }  }
   
 void  void
Line 789  mparse_free(struct mparse *curp)
Line 825  mparse_free(struct mparse *curp)
                 free(curp->secondary->buf);                  free(curp->secondary->buf);
   
         free(curp->secondary);          free(curp->secondary);
           free(curp->sodest);
         free(curp);          free(curp);
 }  }
   
 void  void
 mparse_result(struct mparse *curp, struct mdoc **mdoc, struct man **man)  mparse_result(struct mparse *curp,
           struct mdoc **mdoc, struct man **man, char **sodest)
 {  {
   
           if (sodest && NULL != (*sodest = curp->sodest)) {
                   *mdoc = NULL;
                   *man = NULL;
                   return;
           }
         if (mdoc)          if (mdoc)
                 *mdoc = curp->mdoc;                  *mdoc = curp->mdoc;
         if (man)          if (man)

Legend:
Removed from v.1.39  
changed lines
  Added in v.1.46

CVSweb