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

Diff for /mandoc/read.c between version 1.1 and 1.11

version 1.1, 2011/03/20 11:41:24 version 1.11, 2011/04/04 23:04:38
Line 15 
Line 15 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
 #include <sys/mman.h>  #ifdef HAVE_CONFIG_H
   #include "config.h"
   #endif
   
 #include <sys/stat.h>  #include <sys/stat.h>
   #include <sys/mman.h>
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
 #include <fcntl.h>  #include <fcntl.h>
   #include <stdarg.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   
 #include "mandoc.h"  #include "mandoc.h"
   #include "libmandoc.h"
 #include "mdoc.h"  #include "mdoc.h"
 #include "man.h"  #include "man.h"
 #include "roff.h"  
   
 #ifndef MAP_FILE  #ifndef MAP_FILE
 #define MAP_FILE        0  #define MAP_FILE        0
Line 44  struct buf {
Line 49  struct buf {
   
 struct  mparse {  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 */
         int               line; /* line number in the file */          int               line; /* line number in the file */
         enum mparset      inttype; /* which parser to use */          enum mparset      inttype; /* which parser to use */
         struct man       *pman; /* persistent man parser */          struct man       *pman; /* persistent man parser */
Line 55  struct mparse {
Line 61  struct mparse {
         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 */          void             *arg; /* argument to mmsg */
         mevt_open         evt_open; /* file-open event */          const char       *file;
         mevt_close        evt_close; /* file-close event */  
         const char       *svfile;  
 };  };
   
 static  void      resize_buf(struct buf *, size_t);  static  void      resize_buf(struct buf *, size_t);
Line 68  static void   pdesc(struct mparse *, const char *, int
Line 72  static void   pdesc(struct mparse *, const char *, int
 static  int       read_whole_file(const char *, int, struct buf *, int *);  static  int       read_whole_file(const char *, int, struct buf *, int *);
 static  void      mparse_end(struct mparse *);  static  void      mparse_end(struct mparse *);
   
   static  const enum mandocerr    mandoclimits[MANDOCLEVEL_MAX] = {
           MANDOCERR_OK,
           MANDOCERR_WARNING,
           MANDOCERR_WARNING,
           MANDOCERR_ERROR,
           MANDOCERR_FATAL,
           MANDOCERR_MAX,
           MANDOCERR_MAX
   };
   
   static  const char * const      mandocerrs[MANDOCERR_MAX] = {
           "ok",
   
           "generic warning",
   
           /* related to the prologue */
           "no title in document",
           "document title should be all caps",
           "unknown manual section",
           "date missing, using today's date",
           "cannot parse date, using it verbatim",
           "prologue macros out of order",
           "duplicate prologue macro",
           "macro not allowed in prologue",
           "macro not allowed in body",
   
           /* related to document structure */
           ".so is fragile, better use ln(1)",
           "NAME section must come first",
           "bad NAME section contents",
           "manual name not yet set",
           "sections out of conventional order",
           "duplicate section name",
           "section not in conventional manual section",
   
           /* related to macros and nesting */
           "skipping obsolete macro",
           "skipping paragraph macro",
           "skipping no-space macro",
           "blocks badly nested",
           "child violates parent syntax",
           "nested displays are not portable",
           "already in literal mode",
           "line scope broken",
   
           /* related to missing macro arguments */
           "skipping empty macro",
           "argument count wrong",
           "missing display type",
           "list type must come first",
           "tag lists require a width argument",
           "missing font type",
           "skipping end of block that is not open",
   
           /* related to bad macro arguments */
           "skipping argument",
           "duplicate argument",
           "duplicate display type",
           "duplicate list type",
           "unknown AT&T UNIX version",
           "bad Boolean value",
           "unknown font",
           "unknown standard specifier",
           "bad width argument",
   
           /* related to plain text */
           "blank line in non-literal context",
           "tab in non-literal context",
           "end of line whitespace",
           "bad comment style",
           "unknown escape sequence",
           "unterminated quoted string",
   
           "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",
           "escaped character not allowed in a name",
           "skipping text before the first section header",
           "skipping unknown macro",
           "NOT IMPLEMENTED, please use groff: skipping request",
           "argument count wrong",
           "skipping end of block that is not open",
           "missing end of block",
           "scope open on exit",
           "uname(3) system call failed",
           "macro requires line argument(s)",
           "macro requires body argument(s)",
           "macro requires argument(s)",
           "missing list type",
           "line argument(s) will be lost",
           "body argument(s) will be lost",
   
           "generic fatal error",
   
           "not a manual",
           "column syntax is inconsistent",
           "NOT IMPLEMENTED: .Bd -file",
           "line scope broken, syntax violated",
           "argument count wrong, violates syntax",
           "child violates parent syntax",
           "argument count wrong, violates syntax",
           "NOT IMPLEMENTED: .so with absolute path or \"..\"",
           "no document body",
           "no document prologue",
           "static buffer exhausted",
   };
   
   static  const char * const      mandoclevels[MANDOCLEVEL_MAX] = {
           "SUCCESS",
           "RESERVED",
           "WARNING",
           "ERROR",
           "FATAL",
           "BADARG",
           "SYSERR"
   };
   
 static void  static void
 resize_buf(struct buf *buf, size_t initial)  resize_buf(struct buf *buf, size_t initial)
 {  {
Line 103  pset(const char *buf, int pos, struct mparse *curp)
Line 235  pset(const char *buf, int pos, struct mparse *curp)
         switch (curp->inttype) {          switch (curp->inttype) {
         case (MPARSE_MDOC):          case (MPARSE_MDOC):
                 if (NULL == curp->pmdoc)                  if (NULL == curp->pmdoc)
                         curp->pmdoc = mdoc_alloc                          curp->pmdoc = mdoc_alloc(&curp->regs, curp);
                                 (&curp->regs, curp->arg, curp->mmsg);  
                 assert(curp->pmdoc);                  assert(curp->pmdoc);
                 curp->mdoc = curp->pmdoc;                  curp->mdoc = curp->pmdoc;
                 return;                  return;
         case (MPARSE_MAN):          case (MPARSE_MAN):
                 if (NULL == curp->pman)                  if (NULL == curp->pman)
                         curp->pman = man_alloc                          curp->pman = man_alloc(&curp->regs, curp);
                                 (&curp->regs, curp->arg, curp->mmsg);  
                 assert(curp->pman);                  assert(curp->pman);
                 curp->man = curp->pman;                  curp->man = curp->pman;
                 return;                  return;
Line 121  pset(const char *buf, int pos, struct mparse *curp)
Line 251  pset(const char *buf, int pos, struct mparse *curp)
   
         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->pmdoc = mdoc_alloc(&curp->regs, curp);
                                 (&curp->regs, curp->arg, curp->mmsg);  
                 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->pman = man_alloc(&curp->regs, curp);
                         (&curp->regs, curp->arg, curp->mmsg);  
         assert(curp->pman);          assert(curp->pman);
         curp->man = curp->pman;          curp->man = curp->pman;
 }  }
Line 195  mparse_buf_r(struct mparse *curp, struct buf blk, int 
Line 323  mparse_buf_r(struct mparse *curp, struct buf blk, int 
   
                         if ( ! (isascii(c) &&                          if ( ! (isascii(c) &&
                                         (isgraph(c) || isblank(c)))) {                                          (isgraph(c) || isblank(c)))) {
                                 curp->mmsg(MANDOCERR_BADCHAR, curp->arg,                                  mandoc_msg(MANDOCERR_BADCHAR, curp,
                                                 curp->line, pos, "ignoring byte");                                                  curp->line, pos, "ignoring byte");
                                 i++;                                  i++;
                                 continue;                                  continue;
Line 282  rerun:
Line 410  rerun:
                         if (REPARSE_LIMIT >= ++curp->reparse_count)                          if (REPARSE_LIMIT >= ++curp->reparse_count)
                                 mparse_buf_r(curp, ln, 0);                                  mparse_buf_r(curp, ln, 0);
                         else                          else
                                 curp->mmsg(MANDOCERR_ROFFLOOP, curp->arg,                                  mandoc_msg(MANDOCERR_ROFFLOOP, curp,
                                         curp->line, pos, NULL);                                          curp->line, pos, NULL);
                         pos = 0;                          pos = 0;
                         continue;                          continue;
Line 490  mparse_end(struct mparse *curp)
Line 618  mparse_end(struct mparse *curp)
                 return;                  return;
         }          }
   
 #if 0  
         /* NOTE a parser may not have been assigned, yet. */  
   
         if ( ! (curp->man || curp->mdoc)) {          if ( ! (curp->man || curp->mdoc)) {
                 /* FIXME: make into an mandoc.h error. */                  mandoc_msg(MANDOCERR_NOTMANUAL, curp, 1, 0, NULL);
                 fprintf(stderr, "%s: Not a manual\n", curp->file);  
                 curp->file_status = MANDOCLEVEL_FATAL;                  curp->file_status = MANDOCLEVEL_FATAL;
                 goto cleanup;                  return;
         }          }
 #endif  
   
         roff_endparse(curp->roff);          roff_endparse(curp->roff);
 }  }
Line 509  mparse_readfd_r(struct mparse *curp, int fd, const cha
Line 632  mparse_readfd_r(struct mparse *curp, int fd, const cha
 {  {
         const char      *svfile;          const char      *svfile;
   
         if ( ! (*curp->evt_open)(curp->arg, file)) {  
                 curp->file_status = MANDOCLEVEL_SYSERR;  
                 return;  
         }  
   
         if (-1 == fd)          if (-1 == fd)
                 if (-1 == (fd = open(file, O_RDONLY, 0))) {                  if (-1 == (fd = open(file, O_RDONLY, 0))) {
                         perror(file);                          perror(file);
Line 521  mparse_readfd_r(struct mparse *curp, int fd, const cha
Line 639  mparse_readfd_r(struct mparse *curp, int fd, const cha
                         return;                          return;
                 }                  }
   
         svfile = curp->svfile;          svfile = curp->file;
         curp->svfile = file;          curp->file = file;
   
         pdesc(curp, file, fd);          pdesc(curp, file, fd);
   
Line 532  mparse_readfd_r(struct mparse *curp, int fd, const cha
Line 650  mparse_readfd_r(struct mparse *curp, int fd, const cha
         if (STDIN_FILENO != fd && -1 == close(fd))          if (STDIN_FILENO != fd && -1 == close(fd))
                 perror(file);                  perror(file);
   
         (*curp->evt_close)(curp->arg, svfile);          curp->file = svfile;
         curp->svfile = svfile;  
 }  }
   
 enum mandoclevel  enum mandoclevel
Line 544  mparse_readfd(struct mparse *curp, int fd, const char 
Line 661  mparse_readfd(struct mparse *curp, int fd, const char 
         return(curp->file_status);          return(curp->file_status);
 }  }
   
 void  
 mparse_setstatus(struct mparse *curp, enum mandoclevel lvl)  
 {  
   
         if (curp->file_status < lvl)  
                 curp->file_status = lvl;  
 }  
   
 struct mparse *  struct mparse *
 mparse_alloc(enum mparset inttype, mevt_open eopen,  mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, mandocmsg mmsg, void *arg)
                 mevt_close eclose, mandocmsg mmsg, void *arg)  
 {  {
         struct mparse   *curp;          struct mparse   *curp;
   
           assert(wlevel <= MANDOCLEVEL_FATAL);
   
         curp = mandoc_calloc(1, sizeof(struct mparse));          curp = mandoc_calloc(1, sizeof(struct mparse));
   
           curp->wlevel = wlevel;
         curp->mmsg = mmsg;          curp->mmsg = mmsg;
         curp->arg = arg;          curp->arg = arg;
         curp->inttype = inttype;          curp->inttype = inttype;
         curp->evt_open = eopen;  
         curp->evt_close = eclose;  
   
         curp->roff = roff_alloc(&curp->regs, arg, mmsg);          curp->roff = roff_alloc(&curp->regs, curp);
         return(curp);          return(curp);
 }  }
   
Line 606  void
Line 715  void
 mparse_result(struct mparse *curp, struct mdoc **mdoc, struct man **man)  mparse_result(struct mparse *curp, struct mdoc **mdoc, struct man **man)
 {  {
   
         *mdoc = curp->mdoc;          if (mdoc)
         *man = curp->man;                  *mdoc = curp->mdoc;
           if (man)
                   *man = curp->man;
   }
   
   void
   mandoc_vmsg(enum mandocerr t, struct mparse *m,
                   int ln, int pos, const char *fmt, ...)
   {
           char             buf[256];
           va_list          ap;
   
           va_start(ap, fmt);
           vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
           va_end(ap);
   
           mandoc_msg(t, m, ln, pos, buf);
   }
   
   void
   mandoc_msg(enum mandocerr er, struct mparse *m,
                   int ln, int col, const char *msg)
   {
           enum mandoclevel level;
   
           level = MANDOCLEVEL_FATAL;
           while (er < mandoclimits[level])
                   level--;
   
           if (level < m->wlevel)
                   return;
   
           if (m->mmsg)
                   (*m->mmsg)(er, level, m->file, ln, col, msg);
   
           if (m->file_status < level)
                   m->file_status = level;
   }
   
   const char *
   mparse_strerror(enum mandocerr er)
   {
   
           return(mandocerrs[er]);
   }
   
   const char *
   mparse_strlevel(enum mandoclevel lvl)
   {
           return(mandoclevels[lvl]);
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.11

CVSweb