]> git.cameronkatri.com Git - mandoc.git/blobdiff - read.c
Always store the arch in lower-case only.
[mandoc.git] / read.c
diff --git a/read.c b/read.c
index 511ba7dc466deba542e433a2ef1f454785f769e3..0cb75d6bdea22bc89a32f148feb958b479a671b2 100644 (file)
--- a/read.c
+++ b/read.c
@@ -1,7 +1,8 @@
-/*     $Id: read.c,v 1.39 2013/09/16 00:25:07 schwarze Exp $ */
+/*     $Id: read.c,v 1.43 2014/01/06 21:34:31 schwarze Exp $ */
 /*
  * 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
  * purpose with or without fee is hereby granted, provided that the above
@@ -26,6 +27,7 @@
 
 #include <assert.h>
 #include <ctype.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
 #include <stdint.h>
@@ -59,16 +61,17 @@ struct      mparse {
        struct roff      *roff; /* roff parser (!NULL) */
        int               reparse_count; /* finite interp. stack */
        mandocmsg         mmsg; /* warning/error message handler */
-       void             *arg; /* argument to mmsg */
        const char       *file; 
        struct buf       *secondary;
        char             *defos; /* default operating system */
+       int               quick; /* abort the parse early */
 };
 
 static void      resize_buf(struct buf *, size_t);
 static void      mparse_buf_r(struct mparse *, struct buf, int);
 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_parse_buffer(struct mparse *, struct buf,
                        const char *);
@@ -192,6 +195,7 @@ static      const char * const      mandocerrs[MANDOCERR_MAX] = {
 
        "generic fatal error",
 
+       "input too large",
        "not a manual",
        "column syntax is inconsistent",
        "NOT IMPLEMENTED: .Bd -file",
@@ -202,6 +206,11 @@ static     const char * const      mandocerrs[MANDOCERR_MAX] = {
        "no document body",
        "no document prologue",
        "static buffer exhausted",
+
+       /* system errors */
+       "cannot open file",
+       "cannot stat file",
+       "cannot read file",
 };
 
 static const char * const      mandoclevels[MANDOCLEVEL_MAX] = {
@@ -250,13 +259,14 @@ pset(const char *buf, int pos, struct mparse *curp)
        case (MPARSE_MDOC):
                if (NULL == curp->pmdoc) 
                        curp->pmdoc = mdoc_alloc(curp->roff, curp,
-                                       curp->defos);
+                                       curp->defos, curp->quick);
                assert(curp->pmdoc);
                curp->mdoc = curp->pmdoc;
                return;
        case (MPARSE_MAN):
                if (NULL == curp->pman) 
-                       curp->pman = man_alloc(curp->roff, curp);
+                       curp->pman = man_alloc(curp->roff, curp,
+                                       curp->quick);
                assert(curp->pman);
                curp->man = curp->pman;
                return;
@@ -267,14 +277,14 @@ pset(const char *buf, int pos, struct mparse *curp)
        if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3))  {
                if (NULL == curp->pmdoc) 
                        curp->pmdoc = mdoc_alloc(curp->roff, curp,
-                                       curp->defos);
+                                       curp->defos, curp->quick);
                assert(curp->pmdoc);
                curp->mdoc = curp->pmdoc;
                return;
        } 
 
        if (NULL == curp->pman) 
-               curp->pman = man_alloc(curp->roff, curp);
+               curp->pman = man_alloc(curp->roff, curp, curp->quick);
        assert(curp->pman);
        curp->man = curp->pman;
 }
@@ -552,7 +562,8 @@ rerun:
                if (0 == rc) {
                        assert(MANDOCLEVEL_FATAL <= curp->file_status);
                        break;
-               }
+               } else if (2 == rc)
+                       break;
 
                /* Temporary buffers typically are not full. */
 
@@ -568,7 +579,8 @@ rerun:
 }
 
 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;
        ssize_t          ssz;
@@ -576,7 +588,10 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
 #ifdef HAVE_MMAP
        struct stat      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);
        }
 
@@ -589,7 +604,10 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
 
        if (S_ISREG(st.st_mode)) {
                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);
                }
                *with_mmap = 1;
@@ -612,7 +630,11 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
        for (;;) {
                if (off == fb->sz) {
                        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;
                        }
                        resize_buf(fb, 65536);
@@ -623,7 +645,11 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
                        return(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;
                }
                off += (size_t)ssz;
@@ -704,12 +730,15 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
        struct buf       blk;
        int              with_mmap;
 
-       if (-1 == fd)
-               if (-1 == (fd = open(file, O_RDONLY, 0))) {
-                       perror(file);
-                       curp->file_status = MANDOCLEVEL_SYSERR;
-                       goto out;
-               }
+       if (-1 == fd && -1 == (fd = open(file, O_RDONLY, 0))) {
+               curp->file_status = MANDOCLEVEL_SYSERR;
+               if (curp->mmsg)
+                       (*curp->mmsg)(MANDOCERR_SYSOPEN,
+                           curp->file_status,
+                           file, 0, 0, strerror(errno));
+               goto out;
+       }
+
        /*
         * Run for each opened file; may be called more than once for
         * each full parse sequence if the opened file is nested (i.e.,
@@ -717,10 +746,8 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
         * the parse phase for the file.
         */
 
-       if ( ! read_whole_file(file, fd, &blk, &with_mmap)) {
-               curp->file_status = MANDOCLEVEL_SYSERR;
+       if ( ! read_whole_file(curp, file, fd, &blk, &with_mmap))
                goto out;
-       }
 
        mparse_parse_buffer(curp, blk, file);
 
@@ -739,7 +766,7 @@ out:
 
 struct mparse *
 mparse_alloc(enum mparset inttype, enum mandoclevel wlevel,
-               mandocmsg mmsg, void *arg, char *defos)
+               mandocmsg mmsg, char *defos, int quick)
 {
        struct mparse   *curp;
 
@@ -749,11 +776,11 @@ mparse_alloc(enum mparset inttype, enum mandoclevel wlevel,
 
        curp->wlevel = wlevel;
        curp->mmsg = mmsg;
-       curp->arg = arg;
        curp->inttype = inttype;
        curp->defos = defos;
+       curp->quick = quick;
 
-       curp->roff = roff_alloc(inttype, curp);
+       curp->roff = roff_alloc(inttype, curp, curp->quick);
        return(curp);
 }