* docbook2mdoc: The file docbook2mdoc.c is still large, so split out the
@ 2019-03-26 19:17 schwarze
0 siblings, 0 replies; only message in thread
From: schwarze @ 2019-03-26 19:17 UTC (permalink / raw)
To: source
Log Message:
-----------
The file docbook2mdoc.c is still large,
so split out the macro line formatter,
which is quite self-contained.
Modified Files:
--------------
docbook2mdoc:
Makefile
docbook2mdoc.c
Added Files:
-----------
docbook2mdoc:
macro.c
macro.h
Revision Data
-------------
--- /dev/null
+++ macro.h
@@ -0,0 +1,48 @@
+/* $Id: macro.h,v 1.1 2019/03/26 19:17:29 schwarze Exp $ */
+/*
+ * Copyright (c) 2019 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * 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 AUTHORS DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
+ */
+
+/*
+ * The interface of the macro line formatter,
+ * a part of the mdoc(7) formatter.
+ */
+
+enum linestate {
+ LINE_NEW = 0, /* At the beginning of a new line. */
+ LINE_TEXT, /* In the middle of a text line. */
+ LINE_MACRO /* In the middle of a macro line. */
+};
+
+struct format {
+ int level; /* Header level, starting at 1. */
+ enum linestate linestate;
+};
+
+#define ARG_SPACE 1 /* Insert whitespace before this argument. */
+#define ARG_SINGLE 2 /* Quote argument if it contains whitespace. */
+#define ARG_QUOTED 4 /* We are already in a quoted argument. */
+#define ARG_UPPER 8 /* Covert argument to upper case. */
+
+
+void macro_open(struct format *, const char *);
+void macro_close(struct format *);
+void macro_line(struct format *, const char *);
+void macro_closepunct(struct format *, struct pnode *);
+
+void macro_addarg(struct format *, const char *, int);
+void macro_argline(struct format *, const char *, const char *);
+void macro_addnode(struct format *, struct pnode *, int);
+void macro_nodeline(struct format *, const char *, struct pnode *, int);
Index: docbook2mdoc.c
===================================================================
RCS file: /home/cvs/mdocml/docbook2mdoc/docbook2mdoc.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -Ldocbook2mdoc.c -Ldocbook2mdoc.c -u -p -r1.74 -r1.75
--- docbook2mdoc.c
+++ docbook2mdoc.c
@@ -21,215 +21,15 @@
#include <stdlib.h>
#include "node.h"
+#include "macro.h"
#include "format.h"
/*
* The implementation of the mdoc(7) formatter.
*/
-enum linestate {
- LINE_NEW = 0,
- LINE_TEXT,
- LINE_MACRO
-};
-
-struct format {
- int level; /* Header level, starting at 1. */
- enum linestate linestate;
-};
-
static void pnode_print(struct format *, struct pnode *);
-
-static void
-macro_open(struct format *p, const char *name)
-{
- switch (p->linestate) {
- case LINE_TEXT:
- putchar('\n');
- /* FALLTHROUGH */
- case LINE_NEW:
- putchar('.');
- p->linestate = LINE_MACRO;
- break;
- case LINE_MACRO:
- putchar(' ');
- break;
- }
- fputs(name, stdout);
-}
-
-static void
-macro_close(struct format *p)
-{
- assert(p->linestate == LINE_MACRO);
- putchar('\n');
- p->linestate = LINE_NEW;
-}
-
-static void
-macro_line(struct format *p, const char *name)
-{
- macro_open(p, name);
- macro_close(p);
-}
-
-#define ARG_SPACE 1 /* Insert whitespace before this argument. */
-#define ARG_SINGLE 2 /* Quote argument if it contains whitespace. */
-#define ARG_QUOTED 4 /* We are already in a quoted argument. */
-#define ARG_UPPER 8 /* Covert argument to upper case. */
-/*
- * Print an argument string on a macro line, collapsing whitespace.
- */
-static void
-macro_addarg(struct format *p, const char *arg, int flags)
-{
- const char *cp;
-
- assert(p->linestate == LINE_MACRO);
-
- /* Quote if requested and necessary. */
-
- if ((flags & (ARG_SINGLE | ARG_QUOTED)) == ARG_SINGLE) {
- for (cp = arg; *cp != '\0'; cp++)
- if (isspace((unsigned char)*cp))
- break;
- if (*cp != '\0') {
- if (flags & ARG_SPACE) {
- putchar(' ');
- flags &= ~ ARG_SPACE;
- }
- putchar('"');
- flags = ARG_QUOTED;
- }
- }
-
- for (cp = arg; *cp != '\0'; cp++) {
-
- /* Collapse whitespace. */
-
- if (isspace((unsigned char)*cp)) {
- flags |= ARG_SPACE;
- continue;
- } else if (flags & ARG_SPACE) {
- putchar(' ');
- flags &= ~ ARG_SPACE;
- }
-
- /* Escape us if we look like a macro. */
-
- if ((flags & ARG_QUOTED) == 0 &&
- (cp == arg || isspace((unsigned char)cp[-1])) &&
- isupper((unsigned char)cp[0]) &&
- islower((unsigned char)cp[1]) &&
- (cp[2] == '\0' || cp[2] == ' ' ||
- (islower((unsigned char)cp[2]) &&
- (cp[3] == '\0' || cp[3] == ' '))))
- fputs("\\&", stdout);
-
- if (*cp == '"')
- fputs("\\(dq", stdout);
- else if (flags & ARG_UPPER)
- putchar(toupper((unsigned char)*cp));
- else
- putchar(*cp);
- if (*cp == '\\')
- putchar('e');
- }
-}
-
-static void
-macro_argline(struct format *p, const char *name, const char *arg)
-{
- macro_open(p, name);
- macro_addarg(p, arg, ARG_SPACE);
- macro_close(p);
-}
-
-/*
- * Recursively append text from the children of a node to a macro line.
- */
-static void
-macro_addnode(struct format *p, struct pnode *pn, int flags)
-{
- int quote_now;
-
- assert(p->linestate == LINE_MACRO);
-
- /*
- * If the only child is a text node, just add that text,
- * letting macro_addarg() decide about quoting.
- */
-
- pn = TAILQ_FIRST(&pn->childq);
- if (pn != NULL && pn->node == NODE_TEXT &&
- TAILQ_NEXT(pn, child) == NULL) {
- macro_addarg(p, pn->b, flags);
- return;
- }
-
- /*
- * If we want the argument quoted and are not already
- * in a quoted context, quote now.
- */
-
- quote_now = 0;
- if (flags & ARG_SINGLE) {
- if ((flags & ARG_QUOTED) == 0) {
- if (flags & ARG_SPACE) {
- putchar(' ');
- flags &= ~ARG_SPACE;
- }
- putchar('"');
- flags |= ARG_QUOTED;
- quote_now = 1;
- }
- flags &= ~ARG_SINGLE;
- }
-
- /*
- * Iterate to child and sibling nodes,
- * inserting whitespace between nodes.
- */
-
- while (pn != NULL) {
- if (pn->node == NODE_TEXT)
- macro_addarg(p, pn->b, flags);
- else
- macro_addnode(p, pn, flags);
- pn = TAILQ_NEXT(pn, child);
- flags |= ARG_SPACE;
- }
- if (quote_now)
- putchar('"');
-}
-
-static void
-macro_nodeline(struct format *p, const char *name, struct pnode *pn, int flags)
-{
- macro_open(p, name);
- macro_addnode(p, pn, ARG_SPACE | flags);
- macro_close(p);
-}
-
-/*
- * If the next node is a text node starting with closing punctuation,
- * emit the closing punctuation as a trailing macro argument.
- */
-static void
-macro_closepunct(struct format *p, struct pnode *pn)
-{
- if ((pn = TAILQ_NEXT(pn, child)) != NULL &&
- pn->node == NODE_TEXT && pn->bsz > 0 &&
- (pn->b[0] == ',' || pn->b[0] == '.') &&
- (pn->bsz == 1 || isspace((unsigned char)pn->b[1]))) {
- putchar(' ');
- putchar(pn->b[0]);
- pn->b++;
- pn->bsz--;
- }
- macro_close(p);
-}
static void
print_text(struct format *p, const char *word)
Index: Makefile
===================================================================
RCS file: /home/cvs/mdocml/docbook2mdoc/Makefile,v
retrieving revision 1.18
retrieving revision 1.19
diff -LMakefile -LMakefile -u -p -r1.18 -r1.19
--- Makefile
+++ Makefile
@@ -3,9 +3,9 @@ CFLAGS += -g -W -Wall -Wstrict-prototype
WWWPREFIX = /usr/vhosts/mdocml.bsd.lv/www/htdocs/docbook2mdoc
PREFIX = /usr/local
-HEADS = node.h parse.h format.h
-SRCS = node.c parse.c docbook2mdoc.c main.c
-OBJS = node.o parse.o docbook2mdoc.o main.o
+HEADS = node.h parse.h macro.h format.h
+SRCS = node.c parse.c macro.c docbook2mdoc.c main.c
+OBJS = node.o parse.o macro.o docbook2mdoc.o main.o
all: docbook2mdoc
--- /dev/null
+++ macro.c
@@ -0,0 +1,213 @@
+/* $Id: macro.c,v 1.1 2019/03/26 19:17:29 schwarze Exp $ */
+/*
+ * Copyright (c) 2019 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * 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 AUTHORS DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "node.h"
+#include "macro.h"
+
+/*
+ * The implementation of the macro line formatter,
+ * a part of the mdoc(7) formatter.
+ */
+
+void
+macro_open(struct format *f, const char *name)
+{
+ switch (f->linestate) {
+ case LINE_TEXT:
+ putchar('\n');
+ /* FALLTHROUGH */
+ case LINE_NEW:
+ putchar('.');
+ f->linestate = LINE_MACRO;
+ break;
+ case LINE_MACRO:
+ putchar(' ');
+ break;
+ }
+ fputs(name, stdout);
+}
+
+void
+macro_close(struct format *f)
+{
+ assert(f->linestate == LINE_MACRO);
+ putchar('\n');
+ f->linestate = LINE_NEW;
+}
+
+void
+macro_line(struct format *f, const char *name)
+{
+ macro_open(f, name);
+ macro_close(f);
+}
+
+/*
+ * If the next node is a text node starting with closing punctuation,
+ * emit the closing punctuation as a trailing macro argument.
+ */
+void
+macro_closepunct(struct format *f, struct pnode *pn)
+{
+ if ((pn = TAILQ_NEXT(pn, child)) != NULL &&
+ pn->node == NODE_TEXT && pn->bsz > 0 &&
+ (pn->b[0] == ',' || pn->b[0] == '.') &&
+ (pn->bsz == 1 || isspace((unsigned char)pn->b[1]))) {
+ putchar(' ');
+ putchar(pn->b[0]);
+ pn->b++;
+ pn->bsz--;
+ }
+ macro_close(f);
+}
+
+/*
+ * Print an argument string on a macro line, collapsing whitespace.
+ */
+void
+macro_addarg(struct format *f, const char *arg, int flags)
+{
+ const char *cp;
+
+ assert(f->linestate == LINE_MACRO);
+
+ /* Quote if requested and necessary. */
+
+ if ((flags & (ARG_SINGLE | ARG_QUOTED)) == ARG_SINGLE) {
+ for (cp = arg; *cp != '\0'; cp++)
+ if (isspace((unsigned char)*cp))
+ break;
+ if (*cp != '\0') {
+ if (flags & ARG_SPACE) {
+ putchar(' ');
+ flags &= ~ ARG_SPACE;
+ }
+ putchar('"');
+ flags = ARG_QUOTED;
+ }
+ }
+
+ for (cp = arg; *cp != '\0'; cp++) {
+
+ /* Collapse whitespace. */
+
+ if (isspace((unsigned char)*cp)) {
+ flags |= ARG_SPACE;
+ continue;
+ } else if (flags & ARG_SPACE) {
+ putchar(' ');
+ flags &= ~ ARG_SPACE;
+ }
+
+ /* Escape us if we look like a macro. */
+
+ if ((flags & ARG_QUOTED) == 0 &&
+ (cp == arg || isspace((unsigned char)cp[-1])) &&
+ isupper((unsigned char)cp[0]) &&
+ islower((unsigned char)cp[1]) &&
+ (cp[2] == '\0' || cp[2] == ' ' ||
+ (islower((unsigned char)cp[2]) &&
+ (cp[3] == '\0' || cp[3] == ' '))))
+ fputs("\\&", stdout);
+
+ if (*cp == '"')
+ fputs("\\(dq", stdout);
+ else if (flags & ARG_UPPER)
+ putchar(toupper((unsigned char)*cp));
+ else
+ putchar(*cp);
+ if (*cp == '\\')
+ putchar('e');
+ }
+}
+
+void
+macro_argline(struct format *f, const char *name, const char *arg)
+{
+ macro_open(f, name);
+ macro_addarg(f, arg, ARG_SPACE);
+ macro_close(f);
+}
+
+/*
+ * Recursively append text from the children of a node to a macro line.
+ */
+void
+macro_addnode(struct format *f, struct pnode *pn, int flags)
+{
+ int quote_now;
+
+ assert(f->linestate == LINE_MACRO);
+
+ /*
+ * If the only child is a text node, just add that text,
+ * letting macro_addarg() decide about quoting.
+ */
+
+ pn = TAILQ_FIRST(&pn->childq);
+ if (pn != NULL && pn->node == NODE_TEXT &&
+ TAILQ_NEXT(pn, child) == NULL) {
+ macro_addarg(f, pn->b, flags);
+ return;
+ }
+
+ /*
+ * If we want the argument quoted and are not already
+ * in a quoted context, quote now.
+ */
+
+ quote_now = 0;
+ if (flags & ARG_SINGLE) {
+ if ((flags & ARG_QUOTED) == 0) {
+ if (flags & ARG_SPACE) {
+ putchar(' ');
+ flags &= ~ARG_SPACE;
+ }
+ putchar('"');
+ flags |= ARG_QUOTED;
+ quote_now = 1;
+ }
+ flags &= ~ARG_SINGLE;
+ }
+
+ /*
+ * Iterate to child and sibling nodes,
+ * inserting whitespace between nodes.
+ */
+
+ while (pn != NULL) {
+ if (pn->node == NODE_TEXT)
+ macro_addarg(f, pn->b, flags);
+ else
+ macro_addnode(f, pn, flags);
+ pn = TAILQ_NEXT(pn, child);
+ flags |= ARG_SPACE;
+ }
+ if (quote_now)
+ putchar('"');
+}
+
+void
+macro_nodeline(struct format *f, const char *name, struct pnode *pn, int flags)
+{
+ macro_open(f, name);
+ macro_addnode(f, pn, ARG_SPACE | flags);
+ macro_close(f);
+}
--
To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2019-03-26 19:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-26 19:17 docbook2mdoc: The file docbook2mdoc.c is still large, so split out the schwarze
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).