source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Merge restructuring of main.c code.
@ 2010-12-01 15:09 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-12-01 15:09 UTC (permalink / raw)
  To: source

Log Message:
-----------
Merge restructuring of main.c code.  This provided by schwarze@ and inspected
carefully by joerg@.  Merge roff.h header for compilation's sake (this is not
yet implemented in roff.c.).

THIS IS A BUGGY CHECK-IN.  The manual type is erroneously kept between runs
of the compiler.  This is a known bug.

Modified Files:
--------------
    mdocml:
        main.c
        roff.h

Revision Data
-------------
Index: roff.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -Lroff.h -Lroff.h -u -p -r1.18 -r1.19
--- roff.h
+++ roff.h
@@ -20,6 +20,9 @@
 enum	rofferr {
 	ROFF_CONT, /* continue processing line */
 	ROFF_RERUN, /* re-run roff interpreter with offset */
+	ROFF_APPEND, /* re-run main parser, appending next line */
+	ROFF_REPARSE, /* re-run main parser on the result */
+	ROFF_SO, /* include another file */
 	ROFF_IGN, /* ignore current line */
 	ROFF_ERR /* badness: puke and stop */
 };
Index: main.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -Lmain.c -Lmain.c -u -p -r1.110 -r1.111
--- main.c
+++ main.c
@@ -79,6 +79,7 @@ enum	outt {
 struct	curparse {
 	const char	 *file;		/* Current parse. */
 	int		  fd;		/* Current parse. */
+	int		  line;		/* Line number in the file. */
 	enum mandoclevel  wlevel;	/* Ignore messages below this. */
 	int		  wstop;	/* Stop after a file with a warning. */
 	enum intt	  inttype;	/* which parser to use */
@@ -193,8 +194,11 @@ static	const char * const	mandocerrs[MAN
 	"static buffer exhausted",
 };
 
+static	void		  parsebuf(struct curparse *, struct buf, int);
+static	void		  pdesc(struct curparse *);
 static	void		  fdesc(struct curparse *);
 static	void		  ffile(const char *, struct curparse *);
+static	int		  pfile(const char *, struct curparse *);
 static	int		  moptions(enum intt *, char *);
 static	int		  mmsg(enum mandocerr, void *, 
 				int, int, const char *);
@@ -320,6 +324,35 @@ ffile(const char *file, struct curparse 
 		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
 resize_buf(struct buf *buf, size_t initial)
@@ -406,25 +439,127 @@ read_whole_file(struct curparse *curp, s
 static void
 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 mdoc	*mdoc;
 	struct roff	*roff;
 
-	man = NULL;
-	mdoc = NULL;
-	roff = NULL;
+	pdesc(curp);
 
-	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
-	 * memory mapped.  ln is a line buffer and grows on-demand.
+	 * 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;
+		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)) {
 		exit_status = MANDOCLEVEL_SYSERR;
 		return;
@@ -433,12 +568,42 @@ fdesc(struct curparse *curp)
 	if (NULL == curp->roff) 
 		curp->roff = roff_alloc(&curp->regs, curp, mmsg);
 	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;
 
-	for (i = 0, lnn = 1; i < (int)blk.sz;) {
-		pos = 0;
-		lnn_start = lnn;
-		while (i < (int)blk.sz) {
+	memset(&ln, 0, sizeof(struct buf));
+
+	lnn = curp->line;  /* line number in the real file */
+	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]) {
 				++i;
 				++lnn;
@@ -457,7 +622,7 @@ fdesc(struct curparse *curp)
 			c = (unsigned char) blk.buf[i];
 			if ( ! (isascii(c) && (isgraph(c) || isblank(c)))) {
 				mmsg(MANDOCERR_BADCHAR, curp, 
-				    lnn_start, pos, "ignoring byte");
+				    curp->line, pos, "ignoring byte");
 				i++;
 				continue;
 			}
@@ -517,16 +682,32 @@ fdesc(struct curparse *curp)
 		 */
 
 		of = 0;
-		do {
-			re = roff_parseln(roff, lnn_start, 
-					&ln.buf, &ln.sz, of, &of);
-		} while (ROFF_RERUN == re);
-
-		if (ROFF_IGN == re) {
+rerun:
+		switch (roff_parseln(roff, curp->line, &ln.buf, &ln.sz,
+		    of, &of)) {
+		case (ROFF_REPARSE):
+			parsebuf(curp, ln, 0);
+			pos = 0;
+			continue;
+		case (ROFF_APPEND):
+			pos = strlen(ln.buf);
 			continue;
-		} else if (ROFF_ERR == re) {
+		case (ROFF_RERUN):
+			goto rerun;
+		case (ROFF_IGN):
+			pos = 0;
+			continue;
+		case (ROFF_ERR):
 			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;
 		}
 
 		/*
@@ -541,121 +722,24 @@ fdesc(struct curparse *curp)
 
 		/* 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);
-			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);
-			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;
-		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;
+		/* Temporary buffers typically are not full. */
+		if (0 == start && '\0' == blk.buf[i])
 			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);
-	if (ln.buf)
-		free(ln.buf);
-	if (with_mmap)
-		munmap(blk.buf, blk.sz);
-	else
-		free(blk.buf);
+		/* Start the next input line. */
+		pos = 0;
+	}
 
-	return;
+	free(ln.buf);
 }
 
 
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-12-01 15:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-01 15:09 mdocml: Merge restructuring of main.c code kristaps

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).