source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Broke ascii_*() functions into term_ascii.c  Made low-level
@ 2010-06-08 15:00 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-06-08 15:00 UTC (permalink / raw)
  To: source

Log Message:
-----------
Broke ascii_*() functions into term_ascii.c

Made low-level engine functions into function pointers.

Modified Files:
--------------
    mdocml:
        Makefile
        term.c
        term.h
        term_ps.c

Added Files:
-----------
    mdocml:
        term_ascii.c

Revision Data
-------------
Index: term.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term.c,v
retrieving revision 1.145
retrieving revision 1.146
diff -Lterm.c -Lterm.c -u -p -r1.145 -r1.146
--- term.c
+++ term.c
@@ -22,12 +22,10 @@
 
 #include <assert.h>
 #include <ctype.h>
-#include <getopt.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
 
 #include "mandoc.h"
 #include "chars.h"
@@ -37,64 +35,12 @@
 #include "mdoc.h"
 #include "main.h"
 
-#define	PS_CHAR_WIDTH	  6
-#define	PS_CHAR_HEIGHT	  12
-#define	PS_CHAR_TOPMARG	 (792 - 24)
-#define	PS_CHAR_TOP	 (PS_CHAR_TOPMARG - 36)
-#define	PS_CHAR_LEFT	  36
-#define	PS_CHAR_BOTMARG	  24
-#define	PS_CHAR_BOT	 (PS_CHAR_BOTMARG + 36)
-
 static	void		  spec(struct termp *, const char *, size_t);
 static	void		  res(struct termp *, const char *, size_t);
 static	void		  buffera(struct termp *, const char *, size_t);
 static	void		  bufferc(struct termp *, char);
 static	void		  adjbuf(struct termp *p, size_t);
 static	void		  encode(struct termp *, const char *, size_t);
-static	void		  advance(struct termp *, size_t);
-static	void		  endline(struct termp *);
-static	void		  letter(struct termp *, char);
-static	void		  pageopen(struct termp *);
-
-
-void *
-ascii_alloc(char *outopts)
-{
-	struct termp	*p;
-	const char	*toks[2];
-	char		*v;
-
-	if (NULL == (p = term_alloc(TERMENC_ASCII)))
-		return(NULL);
-
-	p->type = TERMTYPE_CHAR;
-
-	toks[0] = "width";
-	toks[1] = NULL;
-
-	while (outopts && *outopts)
-		switch (getsubopt(&outopts, UNCONST(toks), &v)) {
-		case (0):
-			p->defrmargin = (size_t)atoi(v);
-			break;
-		default:
-			break;
-		}
-
-	/* Enforce a lower boundary. */
-	if (p->defrmargin < 58)
-		p->defrmargin = 58;
-
-	return(p);
-}
-
-
-void
-ascii_free(void *arg)
-{
-
-	term_free((struct termp *)arg);
-}
 
 
 void
@@ -110,61 +56,6 @@ term_free(struct termp *p)
 }
 
 
-/*
- * Push a single letter into our output engine.
- */
-static void
-letter(struct termp *p, char c)
-{
-	
-	if (TERMTYPE_CHAR == p->type) {
-		/*
-		 * If using the terminal device, just push the letter
-		 * out into the screen.
-		 */
-		putchar(c);
-		return;
-	}
-
-	if ( ! (PS_INLINE & p->psstate)) {
-		/*
-		 * If we're not in a PostScript "word" context, then
-		 * open one now at the current cursor.
-		 */
-		printf("%zu %zu moveto\n", p->pscol, p->psrow);
-		putchar('(');
-		p->psstate |= PS_INLINE;
-	}
-
-	/*
-	 * We need to escape these characters as per the PostScript
-	 * specification.  We would also escape non-graphable characters
-	 * (like tabs), but none of them would get to this point and
-	 * it's superfluous to abort() on them.
-	 */
-
-	switch (c) {
-	case ('('):
-		/* FALLTHROUGH */
-	case (')'):
-		/* FALLTHROUGH */
-	case ('\\'):
-		putchar('\\');
-		break;
-	default:
-		break;
-	}
-
-	/* Write the character and adjust where we are on the page. */
-	putchar(c);
-	p->pscol += PS_CHAR_WIDTH;
-}
-
-
-/*
- * Begin a "terminal" context.  Since terminal encompasses PostScript,
- * the actual terminal, etc., there are a few things we can do here.
- */
 void
 term_begin(struct termp *p, term_margin head, 
 		term_margin foot, const void *arg)
@@ -173,64 +64,7 @@ term_begin(struct termp *p, term_margin 
 	p->headf = head;
 	p->footf = foot;
 	p->argf = arg;
-
-	if (TERMTYPE_CHAR == p->type) {
-		/* Emit the header and be done. */
-		(*p->headf)(p, p->argf);
-		return;
-	}
-	
-	/*
-	 * Emit the standard PostScript prologue, set our initial page
-	 * position, then run pageopen() on the initial page.
-	 */
-
-	printf("%s\n", "%!PS");
-	printf("%s\n", "/Courier");
-	printf("%s\n", "10 selectfont");
-
-	p->pspage = 1;
-	p->psstate = 0;
-	pageopen(p);
-}
-
-
-/*
- * Open a page.  This is only used for -Tps at the moment.  It opens a
- * page context, printing the header and the footer.  THE OUTPUT BUFFER
- * MUST BE EMPTY.  If it is not, output will ghost on the next line and
- * we'll be all gross and out of state.
- */
-static void
-pageopen(struct termp *p)
-{
-	
-	assert(TERMTYPE_PS == p->type);
-	assert(0 == p->psstate);
-
-	p->pscol = PS_CHAR_LEFT;
-	p->psrow = PS_CHAR_TOPMARG;
-	p->psstate |= PS_MARGINS;
-
-	(*p->headf)(p, p->argf);
-	endline(p);
-
-	p->psstate &= ~PS_MARGINS;
-	assert(0 == p->psstate);
-
-	p->pscol = PS_CHAR_LEFT;
-	p->psrow = PS_CHAR_BOTMARG;
-	p->psstate |= PS_MARGINS;
-
-	(*p->footf)(p, p->argf);
-	endline(p);
-
-	p->psstate &= ~PS_MARGINS;
-	assert(0 == p->psstate);
-
-	p->pscol = PS_CHAR_LEFT;
-	p->psrow = PS_CHAR_TOP;
-
+	(*p->begin)(p);
 }
 
 
@@ -238,70 +72,7 @@ void
 term_end(struct termp *p)
 {
 
-	if (TERMTYPE_CHAR == p->type) {
-		(*p->footf)(p, p->argf);
-		return;
-	}
-
-	printf("%s\n", "%%END");
-}
-
-
-static void
-endline(struct termp *p)
-{
-
-	if (TERMTYPE_CHAR == p->type) {
-		putchar('\n');
-		return;
-	}
-
-	if (PS_INLINE & p->psstate) {
-		printf(") show\n");
-		p->psstate &= ~PS_INLINE;
-	} 
-
-	if (PS_MARGINS & p->psstate)
-		return;
-
-	p->pscol = PS_CHAR_LEFT;
-	if (p->psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {
-		p->psrow -= PS_CHAR_HEIGHT;
-		return;
-	}
-
-	/* 
-	 * XXX: can't run pageopen() until we're certain a flushln() has
-	 * occured, else the buf will reopen in an awkward state on the
-	 * next line.
-	 */
-	printf("showpage\n");
-	p->psrow = PS_CHAR_TOP;
-}
-
-
-/*
- * Advance the output engine by a certain amount of whitespace.
- */
-static void
-advance(struct termp *p, size_t len)
-{
-	size_t	 	i;
-
-	if (TERMTYPE_CHAR == p->type) {
-		/* Just print whitespace on the terminal. */
-		for (i = 0; i < len; i++)
-			putchar(' ');
-		return;
-	}
-
-	if (PS_INLINE & p->psstate) {
-		/* Dump out any existing line scope. */
-		printf(") show\n");
-		p->psstate &= ~PS_INLINE;
-	}
-
-	p->pscol += len ? len * PS_CHAR_WIDTH : 0;
+	(*p->end)(p);
 }
 
 
@@ -438,10 +209,10 @@ term_flushln(struct termp *p)
 		 */
 		if (vend > bp && 0 == jhy && vis > 0) {
 			vend -= vis;
-			endline(p);
+			(*p->endline)(p);
 			if (TERMP_NOBREAK & p->flags) {
 				p->viscol = p->rmargin;
-				advance(p, p->rmargin);
+				(*p->advance)(p, p->rmargin);
 				vend += p->rmargin - p->offset;
 			} else {
 				p->viscol = 0;
@@ -485,15 +256,15 @@ term_flushln(struct termp *p)
 			 * so write preceding white space now.
 			 */
 			if (vbl) {
-				advance(p, vbl);
+				(*p->advance)(p, vbl);
 				p->viscol += vbl;
 				vbl = 0;
 			}
 
 			if (ASCII_HYPH == p->buf[i])
-				letter(p, '-');
+				(*p->letter)(p, '-');
 			else
-				letter(p, p->buf[i]);
+				(*p->letter)(p, p->buf[i]);
 
 			p->viscol += 1;
 		}
@@ -506,7 +277,7 @@ term_flushln(struct termp *p)
 
 	if ( ! (TERMP_NOBREAK & p->flags)) {
 		p->viscol = 0;
-		endline(p);
+		(*p->endline)(p);
 		return;
 	}
 
@@ -539,12 +310,12 @@ term_flushln(struct termp *p)
 	if (maxvis > vis + /* LINTED */
 			((TERMP_TWOSPACE & p->flags) ? 1 : 0)) {
 		p->viscol += maxvis - vis;
-		advance(p, maxvis - vis);
+		(*p->advance)(p, maxvis - vis);
 		vis += (maxvis - vis);
 	} else {	/* ...or newline break. */
-		endline(p);
+		(*p->endline)(p);
 		p->viscol = p->rmargin;
-		advance(p, p->rmargin);
+		(*p->advance)(p, p->rmargin);
 	}
 }
 
@@ -580,7 +351,7 @@ term_vspace(struct termp *p)
 
 	term_newln(p);
 	p->viscol = 0;
-	endline(p);
+	(*p->endline)(p);
 }
 
 
Index: term.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term.h,v
retrieving revision 1.59
retrieving revision 1.60
diff -Lterm.h -Lterm.h -u -p -r1.59 -r1.60
--- term.h
+++ term.h
@@ -40,6 +40,15 @@ enum	termfont {
 
 typedef void	(*term_margin)(struct termp *, const void *);
 
+struct	termp_ps {
+	int		  psstate;	/* -Tps: state of ps output */
+#define	PS_INLINE	 (1 << 0)	
+#define	PS_MARGINS	 (1 << 1)	
+	size_t		  pscol;	/* -Tps: visible column */
+	size_t		  psrow;	/* -Tps: visible row */
+	size_t		  pspage;	/* -Tps: current page */
+};
+
 struct	termp {
 	enum termtype	  type;
 	size_t		  defrmargin;	/* Right margin of the device.. */
@@ -72,13 +81,15 @@ struct	termp {
 	int		  fonti;	/* Index of font stack. */
 	term_margin	  headf;	/* invoked to print head */
 	term_margin	  footf;	/* invoked to print foot */
+	void		(*letter)(struct termp *, char);
+	void		(*begin)(struct termp *);
+	void		(*end)(struct termp *);
+	void		(*endline)(struct termp *);
+	void		(*advance)(struct termp *, size_t);
 	const void	 *argf;		/* arg for headf/footf */
-	int		  psstate;	/* -Tps: state of ps output */
-#define	PS_INLINE	 (1 << 0)	
-#define	PS_MARGINS	 (1 << 1)	
-	size_t		  pscol;	/* -Tps: visible column */
-	size_t		  psrow;	/* -Tps: visible row */
-	size_t		  pspage;	/* -Tps: current page */
+	union {
+		struct termp_ps ps;
+	} engine;
 };
 
 struct termp	 *term_alloc(enum termenc);
--- /dev/null
+++ term_ascii.c
@@ -0,0 +1,128 @@
+/*	$Id: term_ascii.c,v 1.1 2010/06/08 15:00:17 kristaps Exp $ */
+/*
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "out.h"
+#include "term.h"
+#include "main.h"
+
+static	void		  ascii_endline(struct termp *);
+static	void		  ascii_letter(struct termp *, char);
+static	void		  ascii_begin(struct termp *);
+static	void		  ascii_advance(struct termp *, size_t);
+static	void		  ascii_end(struct termp *);
+
+
+void *
+ascii_alloc(char *outopts)
+{
+	struct termp	*p;
+	const char	*toks[2];
+	char		*v;
+
+	if (NULL == (p = term_alloc(TERMENC_ASCII)))
+		return(NULL);
+
+	p->type = TERMTYPE_CHAR;
+	p->letter = ascii_letter;
+	p->begin = ascii_begin;
+	p->end = ascii_end;
+	p->endline = ascii_endline;
+	p->advance = ascii_advance;
+
+	toks[0] = "width";
+	toks[1] = NULL;
+
+	while (outopts && *outopts)
+		switch (getsubopt(&outopts, UNCONST(toks), &v)) {
+		case (0):
+			p->defrmargin = (size_t)atoi(v);
+			break;
+		default:
+			break;
+		}
+
+	/* Enforce a lower boundary. */
+	if (p->defrmargin < 58)
+		p->defrmargin = 58;
+
+	return(p);
+}
+
+
+void
+ascii_free(void *arg)
+{
+
+	term_free((struct termp *)arg);
+}
+
+
+/* ARGSUSED */
+static void
+ascii_letter(struct termp *p, char c)
+{
+	
+	/* Just push onto the screen. */
+	putchar(c);
+}
+
+
+static void
+ascii_begin(struct termp *p)
+{
+
+	(*p->headf)(p, p->argf);
+}
+
+
+static void
+ascii_end(struct termp *p)
+{
+
+	(*p->footf)(p, p->argf);
+}
+
+
+/* ARGSUSED */
+static void
+ascii_endline(struct termp *p)
+{
+
+	putchar('\n');
+}
+
+
+/* ARGSUSED */
+static void
+ascii_advance(struct termp *p, size_t len)
+{
+	size_t	 	i;
+
+	/* Just print whitespace on the terminal. */
+	for (i = 0; i < len; i++)
+		putchar(' ');
+}
Index: term_ps.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term_ps.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lterm_ps.c -Lterm_ps.c -u -p -r1.1 -r1.2
--- term_ps.c
+++ term_ps.c
@@ -18,12 +18,30 @@
 #include "config.h"
 #endif
 
+#include <assert.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "out.h"
 #include "main.h"
 #include "term.h"
 
+#define	PS_CHAR_WIDTH	  6
+#define	PS_CHAR_HEIGHT	  12
+#define	PS_CHAR_TOPMARG	 (792 - 24)
+#define	PS_CHAR_TOP	 (PS_CHAR_TOPMARG - 36)
+#define	PS_CHAR_LEFT	  36
+#define	PS_CHAR_BOTMARG	  24
+#define	PS_CHAR_BOT	 (PS_CHAR_BOTMARG + 36)
+
+static	void		  ps_letter(struct termp *, char);
+static	void		  ps_begin(struct termp *);
+static	void		  ps_end(struct termp *);
+static	void		  ps_pageopen(struct termp *);
+static	void		  ps_advance(struct termp *, size_t);
+static	void		  ps_endline(struct termp *);
+
+
 void *
 ps_alloc(void)
 {
@@ -33,6 +51,11 @@ ps_alloc(void)
 		return(NULL);
 
 	p->type = TERMTYPE_PS;
+	p->letter = ps_letter;
+	p->begin = ps_begin;
+	p->end = ps_end;
+	p->advance = ps_advance;
+	p->endline = ps_endline;
 	return(p);
 }
 
@@ -42,4 +65,153 @@ ps_free(void *arg)
 {
 
 	term_free((struct termp *)arg);
+}
+
+
+static void
+ps_end(struct termp *p)
+{
+
+	printf("%s\n", "%%EOF");
+}
+
+
+static void
+ps_begin(struct termp *p)
+{
+
+	/*
+	 * Emit the standard PostScript prologue, set our initial page
+	 * position, then run pageopen() on the initial page.
+	 */
+
+	printf("%s\n", "%!PS");
+	printf("%s\n", "/Courier");
+	printf("%s\n", "10 selectfont");
+
+	p->engine.ps.pspage = 1;
+	p->engine.ps.psstate = 0;
+	ps_pageopen(p);
+}
+
+
+static void
+ps_letter(struct termp *p, char c)
+{
+	
+	if ( ! (PS_INLINE & p->engine.ps.psstate)) {
+		/*
+		 * If we're not in a PostScript "word" context, then
+		 * open one now at the current cursor.
+		 */
+		printf("%zu %zu moveto\n", 
+				p->engine.ps.pscol, 
+				p->engine.ps.psrow);
+		putchar('(');
+		p->engine.ps.psstate |= PS_INLINE;
+	}
+
+	/*
+	 * We need to escape these characters as per the PostScript
+	 * specification.  We would also escape non-graphable characters
+	 * (like tabs), but none of them would get to this point and
+	 * it's superfluous to abort() on them.
+	 */
+
+	switch (c) {
+	case ('('):
+		/* FALLTHROUGH */
+	case (')'):
+		/* FALLTHROUGH */
+	case ('\\'):
+		putchar('\\');
+		break;
+	default:
+		break;
+	}
+
+	/* Write the character and adjust where we are on the page. */
+	putchar(c);
+	p->engine.ps.pscol += PS_CHAR_WIDTH;
+}
+
+
+/*
+ * Open a page.  This is only used for -Tps at the moment.  It opens a
+ * page context, printing the header and the footer.  THE OUTPUT BUFFER
+ * MUST BE EMPTY.  If it is not, output will ghost on the next line and
+ * we'll be all gross and out of state.
+ */
+static void
+ps_pageopen(struct termp *p)
+{
+	
+	assert(TERMTYPE_PS == p->type);
+	assert(0 == p->engine.ps.psstate);
+
+	p->engine.ps.pscol = PS_CHAR_LEFT;
+	p->engine.ps.psrow = PS_CHAR_TOPMARG;
+	p->engine.ps.psstate |= PS_MARGINS;
+
+	(*p->headf)(p, p->argf);
+	(*p->endline)(p);
+
+	p->engine.ps.psstate &= ~PS_MARGINS;
+	assert(0 == p->engine.ps.psstate);
+
+	p->engine.ps.pscol = PS_CHAR_LEFT;
+	p->engine.ps.psrow = PS_CHAR_BOTMARG;
+	p->engine.ps.psstate |= PS_MARGINS;
+
+	(*p->footf)(p, p->argf);
+	(*p->endline)(p);
+
+	p->engine.ps.psstate &= ~PS_MARGINS;
+	assert(0 == p->engine.ps.psstate);
+
+	p->engine.ps.pscol = PS_CHAR_LEFT;
+	p->engine.ps.psrow = PS_CHAR_TOP;
+
+}
+
+
+static void
+ps_advance(struct termp *p, size_t len)
+{
+
+	if (PS_INLINE & p->engine.ps.psstate) {
+		/* Dump out any existing line scope. */
+		printf(") show\n");
+		p->engine.ps.psstate &= ~PS_INLINE;
+	}
+
+	p->engine.ps.pscol += len ? len * PS_CHAR_WIDTH : 0;
+}
+
+
+static void
+ps_endline(struct termp *p)
+{
+
+	if (PS_INLINE & p->engine.ps.psstate) {
+		printf(") show\n");
+		p->engine.ps.psstate &= ~PS_INLINE;
+	} 
+
+	if (PS_MARGINS & p->engine.ps.psstate)
+		return;
+
+	p->engine.ps.pscol = PS_CHAR_LEFT;
+	if (p->engine.ps.psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {
+		p->engine.ps.psrow -= PS_CHAR_HEIGHT;
+		return;
+	}
+
+	/* 
+	 * XXX: can't run pageopen() until we're certain a flushln() has
+	 * occured, else the buf will reopen in an awkward state on the
+	 * next line.
+	 */
+	printf("showpage\n");
+	p->engine.ps.psrow = PS_CHAR_TOP;
 }
Index: Makefile
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/Makefile,v
retrieving revision 1.278
retrieving revision 1.279
diff -LMakefile -LMakefile -u -p -r1.278 -r1.279
--- Makefile
+++ Makefile
@@ -69,15 +69,15 @@ MANSRCS	   = man_macro.c man.c man_hash.
 
 MAINLNS	   = main.ln mdoc_term.ln chars.ln term.ln tree.ln \
 	     compat.ln man_term.ln html.ln mdoc_html.ln \
-	     man_html.ln out.ln term_ps.ln
+	     man_html.ln out.ln term_ps.ln term_ascii.ln
 
 MAINOBJS   = main.o mdoc_term.o chars.o term.o tree.o compat.o \
 	     man_term.o html.o mdoc_html.o man_html.o out.o \
-	     term_ps.o
+	     term_ps.o term_ascii.o
 
 MAINSRCS   = main.c mdoc_term.c chars.c term.c tree.c compat.c \
 	     man_term.c html.c mdoc_html.c man_html.c out.c \
-	     term_ps.c
+	     term_ps.c term_ascii.c
 
 LLNS	   = llib-llibmdoc.ln llib-llibman.ln llib-lmandoc.ln \
 	     llib-llibmandoc.ln llib-llibroff.ln
@@ -226,6 +226,8 @@ compat.ln compat.o: compat.c 
 term.ln term.o: term.c term.h man.h mdoc.h chars.h
 
 term_ps.ln term_ps.o: term_ps.c term.h main.h
+
+term_ascii.ln term_ascii.o: term_ascii.c term.h main.h
 
 html.ln html.o: html.c html.h chars.h
 
--
 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-06-08 15:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-08 15:00 mdocml: Broke ascii_*() functions into term_ascii.c Made low-level 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).