summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--html.c104
-rw-r--r--libmdocml.c1
-rw-r--r--literals.c321
-rw-r--r--mdocml.114
-rw-r--r--mdocml.c9
-rw-r--r--ml.c1
-rw-r--r--ml.h3
-rw-r--r--mlg.c64
-rw-r--r--private.h24
-rw-r--r--roff.c517
-rw-r--r--tokens.c1
-rw-r--r--xml.c1
13 files changed, 613 insertions, 453 deletions
diff --git a/Makefile b/Makefile
index b035ff17..42b194ba 100644
--- a/Makefile
+++ b/Makefile
@@ -71,13 +71,13 @@ clean:
rm -f $(CLEAN)
index.html: index.7 mdocml.css
- ./mdocml -W -fhtml -e -o $@ index.7
+ ./mdocml -Wall -fhtml -e -o $@ index.7
index.xml: index.7 mdocml.css
- ./mdocml -W -o $@ index.7
+ ./mdocml -Wall -o $@ index.7
mdocml.html: mdocml.1 mdocml.css
- ./mdocml -W -fhtml -e -o $@ mdocml.1
+ ./mdocml -Wall -fhtml -e -o $@ mdocml.1
install-www: www dist
install -m 0644 mdocml.tgz $(PREFIX)/mdocml-$(VERSION).tgz
diff --git a/html.c b/html.c
index 615dc743..ab5fb2cc 100644
--- a/html.c
+++ b/html.c
@@ -27,10 +27,27 @@
#include <string.h>
#include <unistd.h>
-#include "libmdocml.h"
#include "private.h"
#include "ml.h"
+#define TAG_HTML "<html>"
+#define TAG_BODY "<body>"
+#define TAG_DIV_MDOC "<div class=\"mdoc\">"
+#define TAG_STYLE_CSS "<style type=\"text/css\"><!--"
+#define TAG_STYLE_END "--></style>"
+#define TAG_HEAD "<head>"
+#define TAG_HEAD_END "</head>"
+#define TAG_TITLE "<title>"
+#define TAG_TITLE_END "</title>"
+#define TAG_LINK_CSS "<link rel=\"stylesheet\" " \
+ "type=\"text/css\" href=\"%s\">"
+#define TAG_DOCTYPE "<!DOCTYPE HTML PUBLIC " \
+ "\"-//W3C//DTD HTML 4.01//EN\" " \
+ "\"http://www.w3.org/TR/html4/strict.dtd\">"
+#define TAG_RESTYPE "<meta name=\"resource-type\" " \
+ "content=\"document\">"
+#define TAG_CONTTYPE "<meta http-equiv=\"Content-Type\" " \
+ "content=\"text/html;charset=utf-8\">"
/* TODO: allow head/tail-less invocations (just "div" start). */
@@ -357,55 +374,72 @@ html_begin(struct md_mbuf *mbuf, const struct md_args *args,
const char *title, enum roffmsec section,
const char *vol)
{
- const char *preamble, *css, *trail;
- char buf[512];
+ char mtitle[128], css[128];
size_t res;
- preamble =
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n"
- " \"http://www.w3.org/TR/html4/strict.dtd\">\n"
- "<html>\n"
- "<head>\n"
- " <meta http-equiv=\"Content-Type\"\n"
- " content=\"text/html;charset=utf-8\">\n"
- " <meta name=\"resource-type\" content=\"document\">\n"
- " <title>Manual Page for %s(%s)</title>\n";
-
- css =
- " <link rel=\"stylesheet\" type=\"text/css\"\n"
- " href=\"%s\">\n";
- trail =
- "</head>\n"
- "<body>\n"
- "<div class=\"mdoc\">";
+ (void)snprintf(mtitle, sizeof(mtitle),
+ "Manual Page for %s(%s)",
+ title, roff_msecname(section));
+ (void)snprintf(css, sizeof(css),
+ TAG_LINK_CSS, args->params.html.css);
res = 0;
- (void)snprintf(buf, sizeof(buf) - 1,
- preamble, title, ml_section(section));
-
- if ( ! ml_puts(mbuf, buf, &res))
+ if ( ! ml_puts(mbuf, TAG_DOCTYPE, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_HTML, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_BODY, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_CONTTYPE, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_RESTYPE, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_TITLE, &res))
+ return(0);
+ if ( ! ml_putstring(mbuf, mtitle, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_TITLE_END, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
return(0);
- assert(args->params.html.css);
if (HTML_CSS_EMBED & args->params.html.flags) {
- if ( ! ml_puts(mbuf, " <style type=\"text/css\"><!--\n", &res))
+ if ( ! ml_puts(mbuf, TAG_STYLE_CSS, &res))
return(0);
- if ( ! html_loadcss(mbuf, args->params.html.css))
+ if ( ! ml_puts(mbuf, "\n", &res))
return(0);
- if ( ! ml_puts(mbuf, " --!></style>\n", &res))
+ if ( ! html_loadcss(mbuf, args->params.html.css))
return(0);
- } else {
- (void)snprintf(buf, sizeof(buf) - 1, css,
- args->params.html.css);
- if ( ! ml_puts(mbuf, buf, &res))
+ if ( ! ml_puts(mbuf, TAG_STYLE_END, &res))
return(0);
- }
+ } else if ( ! ml_puts(mbuf, css, &res))
+ return(0);
- if ( ! ml_puts(mbuf, trail, &res))
+ if ( ! ml_puts(mbuf, "\n", &res))
return(0);
- return(1);
+ if ( ! ml_puts(mbuf, TAG_HEAD_END, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_BODY, &res))
+ return(0);
+ if ( ! ml_nputs(mbuf, "\n", 1, &res))
+ return(0);
+ if ( ! ml_puts(mbuf, TAG_DIV_MDOC, &res))
+ return(0);
+ return(ml_nputs(mbuf, "\n", 1, &res));
}
diff --git a/libmdocml.c b/libmdocml.c
index 5dbc6364..5c28e408 100644
--- a/libmdocml.c
+++ b/libmdocml.c
@@ -25,7 +25,6 @@
#include <string.h>
#include <unistd.h>
-#include "libmdocml.h"
#include "private.h"
static int md_run_enter(const struct md_args *,
diff --git a/literals.c b/literals.c
index 8a9ec1db..dfb45360 100644
--- a/literals.c
+++ b/literals.c
@@ -20,44 +20,170 @@
#include <string.h>
#include <stdlib.h>
-#include "libmdocml.h"
#include "private.h"
-#include "ml.h"
-/* FIXME: make this roff_section and so on. */
+#define ROFF_ATTname_V1 "v1"
+#define ROFF_ATTname_V2 "v1"
+#define ROFF_ATTname_V3 "v3"
+#define ROFF_ATTname_V6 "v6"
+#define ROFF_ATTname_V7 "v7"
+#define ROFF_ATTname_32V "32v"
+#define ROFF_ATTname_V_1 "V.1"
+#define ROFF_ATTname_V_4 "V.4"
+
+#define ROFFSecname_NAME "NAME"
+#define ROFFSecname_SYNOP "SYNOPSIS"
+#define ROFFSecname_DESC "DESCRIPTION"
+#define ROFFSecname_ENV "ENVIRONMENT"
+#define ROFFSecname_FILES "FILES"
+#define ROFFSecname_EX "EXAMPLES"
+#define ROFFSecname_DIAG "DIAGNOSTICS"
+#define ROFFSecname_ERRS "ERRORS"
+#define ROFFSecname_STAND "STANDARDS"
+#define ROFFSecname_HIST "HISTORY"
+#define ROFFSecname_AUTH "AUTHORS"
+#define ROFFSecname_CAVEATS "CAVEATS"
+#define ROFFSecname_BUGS "BUGS"
+#define ROFFSecname_RETVAL "RETURN VALUES"
+#define ROFFSecname_RETVAL1 "RETURN"
+#define ROFFSecname_RETVAL2 "VALUES"
+#define ROFFSecname_SEEALSO "SEE ALSO"
+#define ROFFSecname_SEEALSO1 "SEE"
+#define ROFFSecname_SEEALSO2 "ALSO"
+
+#define ROFF_MSECname_1 "1"
+#define ROFF_MSECname_2 "2"
+#define ROFF_MSECname_3 "3"
+#define ROFF_MSECname_3p "3p"
+#define ROFF_MSECname_4 "4"
+#define ROFF_MSECname_5 "5"
+#define ROFF_MSECname_6 "6"
+#define ROFF_MSECname_7 "7"
+#define ROFF_MSECname_8 "8"
+#define ROFF_MSECname_9 "9"
+#define ROFF_MSECname_UNASS "unass"
+#define ROFF_MSECname_DRAFT "draft"
+#define ROFF_MSECname_PAPER "paper"
+
+int
+roff_sec(const char **p)
+{
+
+ assert(*p);
+ if (NULL != *(p + 1)) {
+ if (NULL != *(p + 2))
+ return(ROFFSec_OTHER);
+ if (0 == strcmp(*p, ROFFSecname_RETVAL1) &&
+ 0 == strcmp(*(p + 1), ROFFSecname_RETVAL2))
+ return(ROFFSec_RETVAL);
+ if (0 == strcmp(*p, ROFFSecname_SEEALSO1) &&
+ 0 == strcmp(*(p + 1), ROFFSecname_SEEALSO2))
+ return(ROFFSec_SEEALSO);
+ return(ROFFSec_OTHER);
+ }
+
+ if (0 == strcmp(*p, ROFFSecname_NAME))
+ return(ROFFSec_NAME);
+ else if (0 == strcmp(*p, ROFFSecname_SYNOP))
+ return(ROFFSec_SYNOP);
+ else if (0 == strcmp(*p, ROFFSecname_DESC))
+ return(ROFFSec_DESC);
+ else if (0 == strcmp(*p, ROFFSecname_ENV))
+ return(ROFFSec_ENV);
+ else if (0 == strcmp(*p, ROFFSecname_FILES))
+ return(ROFFSec_FILES);
+ else if (0 == strcmp(*p, ROFFSecname_EX))
+ return(ROFFSec_EX);
+ else if (0 == strcmp(*p, ROFFSecname_DIAG))
+ return(ROFFSec_DIAG);
+ else if (0 == strcmp(*p, ROFFSecname_ERRS))
+ return(ROFFSec_ERRS);
+ else if (0 == strcmp(*p, ROFFSecname_STAND))
+ return(ROFFSec_STAND);
+ else if (0 == strcmp(*p, ROFFSecname_HIST))
+ return(ROFFSec_HIST);
+ else if (0 == strcmp(*p, ROFFSecname_AUTH))
+ return(ROFFSec_AUTH);
+ else if (0 == strcmp(*p, ROFFSecname_CAVEATS))
+ return(ROFFSec_CAVEATS);
+ else if (0 == strcmp(*p, ROFFSecname_BUGS))
+ return(ROFFSec_BUGS);
+ else if (0 == strcmp(*p, ROFFSecname_RETVAL))
+ return(ROFFSec_RETVAL);
+ else if (0 == strcmp(*p, ROFFSecname_SEEALSO))
+ return(ROFFSec_SEEALSO);
+
+ return(ROFFSec_OTHER);
+}
+
+
+enum roffmsec
+roff_msec(const char *p)
+{
+
+ assert(p);
+ if (0 == strcmp(p, ROFF_MSECname_1))
+ return(ROFF_MSEC_1);
+ else if (0 == strcmp(p, ROFF_MSECname_2))
+ return(ROFF_MSEC_2);
+ else if (0 == strcmp(p, ROFF_MSECname_3))
+ return(ROFF_MSEC_3);
+ else if (0 == strcmp(p, ROFF_MSECname_3p))
+ return(ROFF_MSEC_3p);
+ else if (0 == strcmp(p, ROFF_MSECname_4))
+ return(ROFF_MSEC_4);
+ else if (0 == strcmp(p, ROFF_MSECname_5))
+ return(ROFF_MSEC_5);
+ else if (0 == strcmp(p, ROFF_MSECname_6))
+ return(ROFF_MSEC_6);
+ else if (0 == strcmp(p, ROFF_MSECname_7))
+ return(ROFF_MSEC_7);
+ else if (0 == strcmp(p, ROFF_MSECname_8))
+ return(ROFF_MSEC_8);
+ else if (0 == strcmp(p, ROFF_MSECname_9))
+ return(ROFF_MSEC_9);
+ else if (0 == strcmp(p, ROFF_MSECname_UNASS))
+ return(ROFF_MSEC_UNASS);
+ else if (0 == strcmp(p, ROFF_MSECname_DRAFT))
+ return(ROFF_MSEC_DRAFT);
+ else if (0 == strcmp(p, ROFF_MSECname_PAPER))
+ return(ROFF_MSEC_PAPER);
+
+ return(ROFF_MSEC_MAX);
+}
char *
-ml_section(enum roffmsec sec)
+roff_msecname(enum roffmsec sec)
{
switch (sec) {
case(ROFF_MSEC_1):
- return("1");
+ return(ROFF_MSECname_1);
case(ROFF_MSEC_2):
- return("2");
+ return(ROFF_MSECname_2);
case(ROFF_MSEC_3):
- return("3");
+ return(ROFF_MSECname_3);
case(ROFF_MSEC_3p):
- return("3p");
+ return(ROFF_MSECname_3p);
case(ROFF_MSEC_4):
- return("4");
+ return(ROFF_MSECname_4);
case(ROFF_MSEC_5):
- return("5");
+ return(ROFF_MSECname_5);
case(ROFF_MSEC_6):
- return("6");
+ return(ROFF_MSECname_6);
case(ROFF_MSEC_7):
- return("7");
+ return(ROFF_MSECname_7);
case(ROFF_MSEC_8):
- return("8");
+ return(ROFF_MSECname_8);
case(ROFF_MSEC_9):
- return("9");
+ return(ROFF_MSECname_9);
case(ROFF_MSEC_UNASS):
- return("unass");
+ return(ROFF_MSECname_UNASS);
case(ROFF_MSEC_DRAFT):
- return("draft");
+ return(ROFF_MSECname_DRAFT);
case(ROFF_MSEC_PAPER):
- return("paper");
+ return(ROFF_MSECname_PAPER);
default:
break;
}
@@ -68,151 +194,170 @@ ml_section(enum roffmsec sec)
char *
-ml_literal(int tok, const int *argc,
- const char **argv, const char **morep)
+roff_fmtstring(int tok)
{
switch (tok) {
case (ROFF_Ex):
return ("The %s utility exits 0 on success, and "
- "&gt;0 if an error occurs.");
+ ">0 if an error occurs.");
case (ROFF_Rv):
return ("The %s() function returns the value 0 if "
"successful; otherwise the value -1 "
"is returned and the global variable "
- "<span class=\"inline-Va\">errno</span> "
- "is set to indicate the error.");
+ "errno is set to indicate the error.");
case (ROFF_In):
- return("#include &lt;%s&gt;");
+ return("#include \\*(Lt%s\\*(Gt");
+ default:
+ break;
+ }
+
+ abort();
+ /* NOTREACHED */
+}
+
+
+char *
+roff_literal(int tok, const int *argc,
+ const char **argv, const char **morep)
+{
+
+ switch (tok) {
case (ROFF_At):
- /* FIXME: this should be in roff.c. */
assert(NULL == *argv);
assert(ROFF_ARGMAX == *argc);
if (NULL == *morep)
- return("AT&amp;T UNIX");
- if (0 == strcmp(*morep, "v1"))
- return("Version 1 AT&amp;T UNIX");
- else if (0 == strcmp(*morep, "v2"))
- return("Version 2 AT&amp;T UNIX");
- else if (0 == strcmp(*morep, "v3"))
- return("Version 3 AT&amp;T UNIX");
- else if (0 == strcmp(*morep, "v6"))
- return("Version 6 AT&amp;T UNIX");
- else if (0 == strcmp(*morep, "v7"))
- return("Version 7 AT&amp;T UNIX");
- else if (0 == strcmp(*morep, "32v"))
- return("Version 32v AT&amp;T UNIX");
- else if (0 == strcmp(*morep, "V.1"))
- return("AT&amp;T System V.1 UNIX");
- else if (0 == strcmp(*morep, "V.4"))
- return("AT&amp;T System V.4 UNIX");
+ return("AT&T UNIX");
+
+ switch (roff_att(*morep)) {
+ case (ROFF_ATT_V1):
+ return("Version 1 AT&T UNIX");
+ case (ROFF_ATT_V2):
+ return("Version 2 AT&T UNIX");
+ case (ROFF_ATT_V3):
+ return("Version 3 AT&T UNIX");
+ case (ROFF_ATT_V6):
+ return("Version 6 AT&T UNIX");
+ case (ROFF_ATT_V7):
+ return("Version 7 AT&T UNIX");
+ case (ROFF_ATT_32V):
+ return("Version 32v AT&T UNIX");
+ case (ROFF_ATT_V_1):
+ return("AT&T System V.1 UNIX");
+ case (ROFF_ATT_V_4):
+ return("AT&T System V.4 UNIX");
+ default:
+ break;
+ }
+
abort();
/* NOTREACHED */
+
case (ROFF_St):
assert(ROFF_ARGMAX != *argc);
assert(NULL == *argv);
switch (*argc) {
case(ROFF_p1003_1_88):
return("IEEE Std 1003.1-1988 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1_90):
return("IEEE Std 1003.1-1990 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1_96):
return("ISO/IEC 9945-1:1996 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1_2001):
return("IEEE Std 1003.1-2001 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1_2004):
return("IEEE Std 1003.1-2004 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1):
return("IEEE Std 1003.1 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1b):
return("IEEE Std 1003.1b "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1b_93):
return("IEEE Std 1003.1b-1993 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1c_95):
return("IEEE Std 1003.1c-1995 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_1g_2000):
return("IEEE Std 1003.1g-2000 "
- "(&#8220;POSIX&#8221;)");
+ "(\\*(LqPOSIX\\*(Rq)");
case(ROFF_p1003_2_92):
return("IEEE Std 1003.2-1992 "
- "(&#8220;POSIX.2&#8221;)");
+ "(\\*(LqPOSIX.2\\*(Rq)");
case(ROFF_p1387_2_95):
return("IEEE Std 1387.2-1995 "
- "(&#8220;POSIX.7.2&#8221;)");
+ "(\\*(LqPOSIX.7.2\\*(Rq)");
case(ROFF_p1003_2):
return("IEEE Std 1003.2 "
- "(&#8220;POSIX.2&#8221;)");
+ "(\\*(LqPOSIX.2\\*(Rq)");
case(ROFF_p1387_2):
return("IEEE Std 1387.2 "
- "(&#8220;POSIX.7.2&#8221;)");
+ "(\\*(LqPOSIX.7.2\\*(Rq)");
case(ROFF_isoC_90):
return("ISO/IEC 9899:1990 "
- "(&#8220;ISO C90&#8221;)");
+ "(\\*(LqISO C90\\*(Rq)");
case(ROFF_isoC_amd1):
return("ISO/IEC 9899/AMD1:1995 "
- "(&#8220;ISO C90&#8221;)");
+ "(\\*(LqISO C90\\*(Rq)");
case(ROFF_isoC_tcor1):
return("ISO/IEC 9899/TCOR1:1994 "
- "(&#8220;ISO C90&#8221;)");
+ "(\\*(LqISO C90\\*(Rq)");
case(ROFF_isoC_tcor2):
return("ISO/IEC 9899/TCOR2:1995 "
- "(&#8220;ISO C90&#8221;)");
+ "(\\*(LqISO C90\\*(Rq)");
case(ROFF_isoC_99):
return("ISO/IEC 9899:1999 "
- "(&#8220;ISO C99&#8221;)");
+ "(\\*(LqISO C99\\*(Rq)");
case(ROFF_ansiC):
return("ANSI X3.159-1989 "
- "(&#8220;ANSI C&#8221;)");
+ "(\\*(LqANSI C\\*(Rq)");
case(ROFF_ansiC_89):
return("ANSI X3.159-1989 "
- "(&#8220;ANSI C&#8221;)");
+ "(\\*(LqANSI C\\*(Rq)");
case(ROFF_ansiC_99):
return("ANSI/ISO/IEC 9899-1999 "
- "(&#8220;ANSI C99&#8221;)");
+ "(\\*(LqANSI C99\\*(Rq)");
case(ROFF_ieee754):
return("IEEE Std 754-1985");
case(ROFF_iso8802_3):
return("ISO 8802-3: 1989");
case(ROFF_xpg3):
return("X/Open Portability Guide Issue 3 "
- "(&#8220;XPG3&#8221;)");
+ "(\\*(LqXPG3\\*(Rq)");
case(ROFF_xpg4):
return("X/Open Portability Guide Issue 4 "
- "(&#8220;XPG4&#8221;)");
+ "(\\*(LqXPG4\\*(Rq)");
case(ROFF_xpg4_2):
return("X/Open Portability Guide Issue 4.2 "
- "(&#8220;XPG4.2&#8221;)");
+ "(\\*(LqXPG4.2\\*(Rq)");
case(ROFF_xpg4_3):
return("X/Open Portability Guide Issue 4.3 "
- "(&#8220;XPG4.3&#8221;)");
+ "(\\*(LqXPG4.3\\*(Rq)");
case(ROFF_xbd5):
return("X/Open System Interface Definitions "
- "Issue 5 (&#8220;XBD5&#8221;)");
+ "Issue 5 (\\*(LqXBD5\\*(Rq)");
case(ROFF_xcu5):
return("X/Open Commands and Utilities Issue 5 "
- "(&#8220;XCU5&#8221;)");
+ "(\\*(LqXCU5\\*(Rq)");
case(ROFF_xsh5):
return("X/Open System Interfaces and Headers "
- "Issue 5 (&#8220;XSH5&#8221;)");
+ "Issue 5 (\\*(LqXSH5\\*(Rq)");
case(ROFF_xns5):
return("X/Open Networking Services Issue 5 "
- "(&#8220;XNS5&#8221;)");
+ "(\\*(LqXNS5\\*(Rq)");
case(ROFF_xns5_2d2_0):
return("X/Open Networking Services "
"Issue 5.2 Draft 2.0 "
- "(&#8220;XNS5.2D2.0&#8221;)");
+ "(\\*(LqXNS5.2D2.0\\*(Rq)");
case(ROFF_xcurses4_2):
return("X/Open Curses Issue 4 Version 2 "
- "(&#8220;XCURSES4.2&#8221;)");
+ "(\\*(LqXCURSES4.2\\*(Rq)");
case(ROFF_susv2):
return("Version 2 of the Single "
"UNIX Specification");
@@ -221,12 +366,13 @@ ml_literal(int tok, const int *argc,
"UNIX Specification");
case(ROFF_svid4):
return("System V Interface Definition, Fourth "
- "Edition (&#8220;SVID4&#8221;)");
+ "Edition (\\*(LqSVID4\\*(Rq)");
default:
break;
}
abort();
/* NOTREACHED */
+
case (ROFF_Bt):
return("is currently in beta test.");
case (ROFF_Ud):
@@ -246,7 +392,34 @@ ml_literal(int tok, const int *argc,
default:
break;
}
+
abort();
/* NOTREACHED */
}
+
+enum roffatt
+roff_att(const char *p)
+{
+
+ assert(p);
+ if (0 == strcmp(p, ROFF_ATTname_V1))
+ return(ROFF_ATT_V1);
+ else if (0 == strcmp(p, ROFF_ATTname_V2))
+ return(ROFF_ATT_V2);
+ else if (0 == strcmp(p, ROFF_ATTname_V3))
+ return(ROFF_ATT_V3);
+ else if (0 == strcmp(p, ROFF_ATTname_V6))
+ return(ROFF_ATT_V6);
+ else if (0 == strcmp(p, ROFF_ATTname_V7))
+ return(ROFF_ATT_V7);
+ else if (0 == strcmp(p, ROFF_ATTname_32V))
+ return(ROFF_ATT_32V);
+ else if (0 == strcmp(p, ROFF_ATTname_V_1))
+ return(ROFF_ATT_V_1);
+ else if (0 == strcmp(p, ROFF_ATTname_V_4))
+ return(ROFF_ATT_V_4);
+
+ return(ROFF_ATT_MAX);
+}
+
diff --git a/mdocml.1 b/mdocml.1
index a40336a1..fb507abd 100644
--- a/mdocml.1
+++ b/mdocml.1
@@ -9,7 +9,8 @@
.\"
.Sh SYNOPSIS
.Nm mdocml
-.Op Fl vW
+.Op Fl v
+.Op Fl W Ns Ar err...
.Op Fl f Ar filter
.Op Fl o Ar outfile
.Op Ar infile
@@ -32,8 +33,15 @@ Write output to
which may be
.Dq \-
for stdout.
-.It Fl W
-Print warnings to stderr.
+.It Fl W Ns Ar err...
+Print warning messages. If set to
+.Fl W Ns Ar all ,
+all warnings are printed; if
+.Fl W Ns Ar error ,
+warnings are considered errors and cause utility termination. Multiple
+.Fl W
+arguments may be comma-separated, such as
+.Fl W Ns Ar error,all .
.It Fl v
Make warning and error messages verbose.
.It Ar infile
diff --git a/mdocml.c b/mdocml.c
index a9a7a047..936665f9 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -50,6 +50,10 @@ static int begin_bufs(const struct md_args *,
static int leave_bufs(const struct md_buf *,
const struct md_buf *, int);
+#ifdef __linux__
+extern int getsubopt(char **, char *const *, char **);
+#endif
+
int
main(int argc, char *argv[])
{
@@ -265,7 +269,8 @@ usage(void)
{
extern char *__progname;
- (void)printf("usage: %s [-v] [-Wwarn...] [-f filter] "
- "[-o outfile] [infile]\n", __progname);
+ (void)fprintf(stderr, "usage: %s [-v] [-Wwarn...] "
+ "[-f filter] [-o outfile] [infile]\n",
+ __progname);
}
diff --git a/ml.c b/ml.c
index e3b8ed29..46f10ce9 100644
--- a/ml.c
+++ b/ml.c
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
-#include "libmdocml.h"
#include "private.h"
#include "ml.h"
diff --git a/ml.h b/ml.h
index 58a78ad6..621049c3 100644
--- a/ml.h
+++ b/ml.h
@@ -65,9 +65,6 @@ int ml_nputs(struct md_mbuf *,
int ml_puts(struct md_mbuf *, const char *, size_t *);
int ml_putchars(struct md_mbuf *,
char, size_t, size_t *);
-char *ml_literal(int, const int *,
- const char **, const char **);
-char *ml_section(enum roffmsec);
struct md_mlg *mlg_alloc(const struct md_args *,
const struct md_rbuf *, struct md_mbuf *,
diff --git a/mlg.c b/mlg.c
index 7c9ab1a7..780167b4 100644
--- a/mlg.c
+++ b/mlg.c
@@ -24,7 +24,6 @@
#include <stdio.h>
#include <string.h>
-#include "libmdocml.h"
#include "private.h"
#include "ml.h"
@@ -59,7 +58,7 @@ struct md_mlg {
void *data;
};
-static void mlg_roffmsg(void *arg,
+static int mlg_roffmsg(void *arg,
enum roffmsg, const char *,
const char *, const char *);
static int mlg_roffhead(void *, const struct tm *,
@@ -87,7 +86,7 @@ static int mlg_roffblkbodyout(void *, int);
static int mlg_ref_special(struct md_mlg *, int,
const char *, const char **);
static int mlg_formatted_special(struct md_mlg *,
- int, const int *,
+ int, const char *, const int *,
const char **, const char **);
static int mlg_literal_special(struct md_mlg *,
int, const char *, const int *,
@@ -109,12 +108,12 @@ static int mlg_string(struct md_mlg *,
const char *, const char *);
static int mlg_data(struct md_mlg *, int,
const char *, const char *);
-static void mlg_err(struct md_mlg *, const char *,
+static int mlg_err(struct md_mlg *, const char *,
const char *, const char *, ...);
-static void mlg_msg(struct md_mlg *,
+static int mlg_msg(struct md_mlg *,
enum roffmsg, const char *,
const char *, const char *);
-static void mlg_vmsg(struct md_mlg *, enum roffmsg,
+static int mlg_vmsg(struct md_mlg *, enum roffmsg,
const char *, const char *,
const char *, va_list);
@@ -291,11 +290,10 @@ mlg_nstring(struct md_mlg *p, const char *start,
if (-1 == res)
return(0);
- if (0 == (c = ml_nputstring(p->mbuf, buf, sz, &p->pos))) {
- mlg_err(p, start, buf, "bad string "
- "encoding: `%s'", buf);
- return(0);
- } else if (-1 == c)
+ if (0 == (c = ml_nputstring(p->mbuf, buf, sz, &p->pos)))
+ return(mlg_err(p, start, buf, "bad string "
+ "encoding: `%s'", buf));
+ else if (-1 == c)
return(0);
res = (*p->cbs.ml_endstring)(p->mbuf, p->args, buf, sz);
@@ -462,13 +460,12 @@ mlg_literal_special(struct md_mlg *p, int tok, const char *start,
if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
return(0);
- /* FIXME: must be ml-filtered. */
-
- lit = ml_literal(tok, argc, argv, more);
+ lit = roff_literal(tok, argc, argv, more);
assert(lit);
- if ( ! ml_puts(p->mbuf, lit, &p->pos))
+ if ( ! mlg_string(p, start, lit))
return(0);
+
while (*more) {
if ( ! ml_nputs(p->mbuf, " ", 1, &p->pos))
return(0);
@@ -507,7 +504,7 @@ mlg_ref_special(struct md_mlg *p, int tok,
static int
-mlg_formatted_special(struct md_mlg *p, int tok,
+mlg_formatted_special(struct md_mlg *p, int tok, const char *start,
const int *argc, const char **argv, const char **more)
{
char buf[256], *lit;
@@ -515,16 +512,14 @@ mlg_formatted_special(struct md_mlg *p, int tok,
if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
return(0);
- /* FIXME: must be ml-filtered. */
-
- lit = ml_literal(tok, argc, argv, more);
+ lit = roff_fmtstring(tok);
assert(lit);
assert(*more);
(void)snprintf(buf, sizeof(buf), lit, *more++);
assert(NULL == *more);
- if ( ! ml_puts(p->mbuf, buf, &p->pos))
+ if ( ! mlg_string(p, start, buf))
return(0);
return(mlg_endtag(p, MD_NS_INLINE, tok));
@@ -631,7 +626,7 @@ mlg_roffspecial(void *arg, int tok, const char *start,
case (ROFF_Ex):
/* NOTREACHED */
case (ROFF_Rv):
- return(mlg_formatted_special(p, tok,
+ return(mlg_formatted_special(p, tok, start,
argc, argv, more));
case (ROFF_At):
@@ -659,9 +654,8 @@ mlg_roffspecial(void *arg, int tok, const char *start,
break;
}
- mlg_err(p, start, start, "`%s' not yet supported",
- toknames[tok]);
- return(0);
+ return(mlg_err(p, start, start, "`%s' not yet supported",
+ toknames[tok]));
}
@@ -736,12 +730,12 @@ mlg_roffout(void *arg, int tok)
}
-static void
+static int
mlg_roffmsg(void *arg, enum roffmsg lvl, const char *buf,
const char *pos, const char *msg)
{
- mlg_msg((struct md_mlg *)arg, lvl, buf, pos, msg);
+ return(mlg_msg((struct md_mlg *)arg, lvl, buf, pos, msg));
}
@@ -762,30 +756,32 @@ mlg_roffdata(void *arg, int space,
}
-static void
+static int
mlg_vmsg(struct md_mlg *p, enum roffmsg lvl, const char *start,
const char *pos, const char *fmt, va_list ap)
{
char buf[128];
(void)vsnprintf(buf, sizeof(buf), fmt, ap);
- mlg_msg(p, lvl, start, pos, buf);
+ return(mlg_msg(p, lvl, start, pos, buf));
}
-static void
+static int
mlg_err(struct md_mlg *p, const char *start,
const char *pos, const char *fmt, ...)
{
va_list ap;
+ int c;
va_start(ap, fmt);
- mlg_vmsg(p, ROFF_ERROR, start, pos, fmt, ap);
+ c = mlg_vmsg(p, ROFF_ERROR, start, pos, fmt, ap);
va_end(ap);
+ return(c);
}
-static void
+static int
mlg_msg(struct md_mlg *p, enum roffmsg lvl,
const char *buf, const char *pos, const char *msg)
{
@@ -795,15 +791,16 @@ mlg_msg(struct md_mlg *p, enum roffmsg lvl,
switch (lvl) {
case (ROFF_WARN):
- if ( ! (MD_WARN_ALL & p->args->warnings))
- return;
level = "warning";
+ if ( ! (MD_WARN_ALL & p->args->warnings))
+ return(1);
break;
case (ROFF_ERROR):
level = "error";
break;
default:
abort();
+ /* NOTREACHED */
}
if (pos) {
@@ -831,5 +828,6 @@ mlg_msg(struct md_mlg *p, enum roffmsg lvl,
p->rbuf->name, level, msg);
(void)fprintf(stderr, "%s\n", b);
+ return(lvl == ROFF_WARN ? 1 : 0);
}
diff --git a/private.h b/private.h
index 8c5f375c..029a83fe 100644
--- a/private.h
+++ b/private.h
@@ -22,6 +22,8 @@
#include <stdio.h>
#include <time.h>
+#include "libmdocml.h"
+
struct md_rbuf {
int fd; /* Open descriptor. */
char *name; /* Name of file. */
@@ -269,6 +271,18 @@ enum roffmsec {
ROFF_MSEC_MAX
};
+enum roffatt {
+ ROFF_ATT_V1,
+ ROFF_ATT_V2,
+ ROFF_ATT_V3,
+ ROFF_ATT_V6,
+ ROFF_ATT_V7,
+ ROFF_ATT_32V,
+ ROFF_ATT_V_1,
+ ROFF_ATT_V_4,
+ ROFF_ATT_MAX
+};
+
#define ROFFSec_NMASK (0x07)
#define ROFFSec_NAME (1 << 0)
@@ -289,7 +303,7 @@ enum roffmsec {
#define ROFFSec_OTHER (1 << 15)
struct roffcb {
- void (*roffmsg)(void *, enum roffmsg,
+ int (*roffmsg)(void *, enum roffmsg,
const char *, const char *, const char *);
int (*roffhead)(void *, const struct tm *, const char *,
const char *, enum roffmsec, const char *);
@@ -336,6 +350,14 @@ int roff_free(struct rofftree *, int);
int rofftok_scan(const char *, int *);
+char *roff_literal(int, const int *,
+ const char **, const char **);
+char *roff_fmtstring(int);
+char *roff_msecname(enum roffmsec);
+enum roffmsec roff_msec(const char *);
+int roff_sec(const char **);
+enum roffatt roff_att(const char *);
+
__END_DECLS
#endif /*!PRIVATE_H*/
diff --git a/roff.c b/roff.c
index 9dc1c7a4..4e31ce0c 100644
--- a/roff.c
+++ b/roff.c
@@ -28,7 +28,6 @@
#include <string.h>
#include <time.h>
-#include "libmdocml.h"
#include "private.h"
#include "roff.h"
@@ -38,15 +37,29 @@
/* TODO: warn about empty lists. */
/* TODO: (warn) some sections need specific elements. */
/* TODO: (warn) NAME section has particular order. */
-/* TODO: unify empty-content tags a la <br />. */
/* TODO: macros with a set number of arguments? */
/* TODO: validate Dt macro arguments. */
/* FIXME: Bl -diag supposed to ignore callable children. */
-/* FIXME: Nm has newline when used in NAME section. */
struct roffnode {
- int tok; /* Token id. */
- struct roffnode *parent; /* Parent (or NULL). */
+ int tok; /* Token id. */
+ struct roffnode *parent; /* Parent (or NULL). */
+};
+
+enum rofferr {
+ ERR_ARGEQ1, /* Macro requires arg == 1. */
+ ERR_ARGEQ0, /* Macro requires arg == 0. */
+ ERR_ARGGE1, /* Macro requires arg >= 1. */
+ ERR_ARGGE2, /* Macro requires arg >= 2. */
+ ERR_ARGLEN, /* Macro argument too long. */
+ ERR_BADARG, /* Macro has bad arg. */
+ ERR_ARGMNY, /* Too many macro arguments. */
+ ERR_NOTSUP, /* Macro not supported. */
+ ERR_DEPREC, /* Macro deprecated. */
+ ERR_PR_OOO, /* Prelude macro bad order. */
+ ERR_PR_REP, /* Prelude macro repeated. */
+ ERR_NOT_PR, /* Not allowed in prelude. */
+ WRN_SECORD, /* Sections out-of-order. */
};
struct rofftree {
@@ -59,7 +72,7 @@ struct rofftree {
enum roffmsec section;
char volume[64]; /* `Dt' results. */
int state;
-#define ROFF_PRELUDE (1 << 1) /* In roff prelude. */
+#define ROFF_PRELUDE (1 << 1) /* In roff prelude. */ /* FIXME: put into asec. */
#define ROFF_PRELUDE_Os (1 << 2) /* `Os' is parsed. */
#define ROFF_PRELUDE_Dt (1 << 3) /* `Dt' is parsed. */
#define ROFF_PRELUDE_Dd (1 << 4) /* `Dd' is parsed. */
@@ -72,19 +85,20 @@ struct rofftree {
static struct roffnode *roffnode_new(int, struct rofftree *);
static void roffnode_free(struct rofftree *);
-static void roff_warn(const struct rofftree *,
+static int roff_warn(const struct rofftree *,
const char *, char *, ...);
-static void roff_err(const struct rofftree *,
+static int roff_warnp(const struct rofftree *,
+ const char *, int, enum rofferr);
+static int roff_err(const struct rofftree *,
const char *, char *, ...);
+static int roff_errp(const struct rofftree *,
+ const char *, int, enum rofferr);
static int roffpurgepunct(struct rofftree *, char **);
static int roffscan(int, const int *);
static int rofffindtok(const char *);
static int rofffindarg(const char *);
static int rofffindcallable(const char *);
-static int roffismsec(const char *);
-static int roffissec(const char **);
static int roffispunct(const char *);
-static int roffisatt(const char *);
static int roffchecksec(struct rofftree *,
const char *, int);
static int roffargs(const struct rofftree *,
@@ -133,7 +147,7 @@ roff_free(struct rofftree *tree, int flush)
(void)roff_err(tree, NULL, "missing `NAME' section");
goto end;
} else if ( ! (ROFFSec_NMASK & tree->asec))
- roff_warn(tree, NULL, "missing suggested `NAME', "
+ (void)roff_warn(tree, NULL, "missing suggested `NAME', "
"`SYNOPSIS', `DESCRIPTION' sections");
for (n = tree->last; n; n = n->parent) {
@@ -576,120 +590,7 @@ roffchecksec(struct rofftree *tree, const char *start, int sec)
return(1);
}
- roff_warn(tree, start, "section violates conventional order");
- return(1);
-}
-
-
-/* FIXME: move this into literals.c. */
-static int
-roffissec(const char **p)
-{
-
- assert(*p);
- if (NULL != *(p + 1)) {
- if (NULL != *(p + 2))
- return(ROFFSec_OTHER);
- if (0 == strcmp(*p, "RETURN") &&
- 0 == strcmp(*(p + 1), "VALUES"))
- return(ROFFSec_RETVAL);
- if (0 == strcmp(*p, "SEE") &&
- 0 == strcmp(*(p + 1), "ALSO"))
- return(ROFFSec_SEEALSO);
- return(ROFFSec_OTHER);
- }
-
- if (0 == strcmp(*p, "NAME"))
- return(ROFFSec_NAME);
- else if (0 == strcmp(*p, "SYNOPSIS"))
- return(ROFFSec_SYNOP);
- else if (0 == strcmp(*p, "DESCRIPTION"))
- return(ROFFSec_DESC);
- else if (0 == strcmp(*p, "ENVIRONMENT"))
- return(ROFFSec_ENV);
- else if (0 == strcmp(*p, "FILES"))
- return(ROFFSec_FILES);
- else if (0 == strcmp(*p, "EXAMPLES"))
- return(ROFFSec_EX);
- else if (0 == strcmp(*p, "DIAGNOSTICS"))
- return(ROFFSec_DIAG);
- else if (0 == strcmp(*p, "ERRORS"))
- return(ROFFSec_ERRS);
- else if (0 == strcmp(*p, "STANDARDS"))
- return(ROFFSec_STAND);
- else if (0 == strcmp(*p, "HISTORY"))
- return(ROFFSec_HIST);
- else if (0 == strcmp(*p, "AUTHORS"))
- return(ROFFSec_AUTH);
- else if (0 == strcmp(*p, "CAVEATS"))
- return(ROFFSec_CAVEATS);
- else if (0 == strcmp(*p, "BUGS"))
- return(ROFFSec_BUGS);
-
- return(ROFFSec_OTHER);
-}
-
-
-/* FIXME: move this into literals.c. */
-static int
-roffismsec(const char *p)
-{
-
- if (0 == strcmp(p, "1"))
- return(ROFF_MSEC_1);
- else if (0 == strcmp(p, "2"))
- return(ROFF_MSEC_2);
- else if (0 == strcmp(p, "3"))
- return(ROFF_MSEC_3);
- else if (0 == strcmp(p, "3p"))
- return(ROFF_MSEC_3p);
- else if (0 == strcmp(p, "4"))
- return(ROFF_MSEC_4);
- else if (0 == strcmp(p, "5"))
- return(ROFF_MSEC_5);
- else if (0 == strcmp(p, "6"))
- return(ROFF_MSEC_6);
- else if (0 == strcmp(p, "7"))
- return(ROFF_MSEC_7);
- else if (0 == strcmp(p, "8"))
- return(ROFF_MSEC_8);
- else if (0 == strcmp(p, "9"))
- return(ROFF_MSEC_9);
- else if (0 == strcmp(p, "unass"))
- return(ROFF_MSEC_UNASS);
- else if (0 == strcmp(p, "draft"))
- return(ROFF_MSEC_DRAFT);
- else if (0 == strcmp(p, "paper"))
- return(ROFF_MSEC_PAPER);
-
- return(ROFF_MSEC_MAX);
-}
-
-
-/* FIXME: move this into literals.c. */
-static int
-roffisatt(const char *p)
-{
-
- assert(p);
- if (0 == strcmp(p, "v1"))
- return(1);
- else if (0 == strcmp(p, "v2"))
- return(1);
- else if (0 == strcmp(p, "v3"))
- return(1);
- else if (0 == strcmp(p, "v6"))
- return(1);
- else if (0 == strcmp(p, "v7"))
- return(1);
- else if (0 == strcmp(p, "32v"))
- return(1);
- else if (0 == strcmp(p, "V.1"))
- return(1);
- else if (0 == strcmp(p, "V.4"))
- return(1);
-
- return(0);
+ return(roff_warnp(tree, start, ROFF_Sh, WRN_SECORD));
}
@@ -803,17 +704,18 @@ roffspecial(struct rofftree *tree, int tok, const char *start,
case (ROFF_At):
if (0 == sz)
break;
- if (roffisatt(*ordp))
+ if (ROFF_ATT_MAX == roff_att(*ordp))
break;
- return(roff_err(tree, *ordp, "invalid `At' arg"));
+ return(roff_errp(tree, *ordp, tok, ERR_BADARG));
case (ROFF_Xr):
if (2 == sz) {
assert(ordp[1]);
- if (ROFF_MSEC_MAX != roffismsec(ordp[1]))
+ if (ROFF_MSEC_MAX != roff_msec(ordp[1]))
break;
- roff_warn(tree, start, "invalid `%s' manual "
- "section", toknames[tok]);
+ if ( ! roff_warn(tree, start, "invalid `%s' manual "
+ "section", toknames[tok]))
+ return(0);
}
/* FALLTHROUGH */
@@ -822,17 +724,16 @@ roffspecial(struct rofftree *tree, int tok, const char *start,
case (ROFF_Fn):
if (0 != sz)
break;
- return(roff_err(tree, start, "`%s' expects at least "
- "one arg", toknames[tok]));
+ return(roff_errp(tree, start, tok, ERR_ARGGE1));
case (ROFF_Nm):
if (0 == sz) {
- if (0 == tree->name[0]) {
- roff_err(tree, start, "`Nm' not set");
- return(0);
+ if (0 != tree->name[0]) {
+ ordp[0] = tree->name;
+ ordp[1] = NULL;
+ break;
}
- ordp[0] = tree->name;
- ordp[1] = NULL;
+ return(roff_err(tree, start, "`Nm' not set"));
} else if ( ! roffsetname(tree, ordp))
return(0);
break;
@@ -842,34 +743,24 @@ roffspecial(struct rofftree *tree, int tok, const char *start,
case (ROFF_Ex):
if (1 == sz)
break;
- roff_err(tree, start, "`%s' expects one arg",
- toknames[tok]);
- return(0);
+ return(roff_errp(tree, start, tok, ERR_ARGEQ1));
case (ROFF_Sm):
- if (1 != sz) {
- roff_err(tree, start, "`Sm' expects one arg");
- return(0);
- }
-
- if (0 != strcmp(ordp[0], "on") &&
- 0 != strcmp(ordp[0], "off")) {
- roff_err(tree, start, "`Sm' has invalid argument");
- return(0);
- }
- break;
+ if (1 != sz)
+ return(roff_errp(tree, start, tok, ERR_ARGEQ1));
+ else if (0 == strcmp(ordp[0], "on") ||
+ 0 == strcmp(ordp[0], "off"))
+ break;
+ return(roff_errp(tree, *ordp, tok, ERR_BADARG));
case (ROFF_Ud):
/* FALLTHROUGH */
case (ROFF_Ux):
/* FALLTHROUGH */
case (ROFF_Bt):
- if (0 != sz) {
- roff_err(tree, start, "`%s' expects no args",
- toknames[tok]);
- return(0);
- }
- break;
+ if (0 == sz)
+ break;
+ return(roff_errp(tree, start, tok, ERR_ARGEQ0));
default:
break;
}
@@ -894,11 +785,9 @@ roffcall(struct rofftree *tree, int tok, char **argv)
int i;
enum roffmsec c;
- if (NULL == tokens[tok].cb) {
- roff_err(tree, *argv, "`%s' is unsupported",
- toknames[tok]);
- return(0);
- }
+ if (NULL == tokens[tok].cb)
+ return(roff_errp(tree, *argv, tok, ERR_NOTSUP));
+
if (tokens[tok].sections && ROFF_MSEC_MAX != tree->section) {
i = 0;
while (ROFF_MSEC_MAX !=
@@ -906,9 +795,10 @@ roffcall(struct rofftree *tree, int tok, char **argv)
if (c == tree->section)
break;
if (ROFF_MSEC_MAX == c) {
- roff_warn(tree, *argv, "`%s' is not a valid "
+ if ( ! roff_warn(tree, *argv, "`%s' is not a valid "
"macro in this manual section",
- toknames[tok]);
+ toknames[tok]))
+ return(0);
}
}
@@ -933,14 +823,16 @@ roffnextopt(const struct rofftree *tree, int tok,
return(-1);
if (ROFF_ARGMAX == (v = rofffindarg(arg + 1))) {
- roff_warn(tree, arg, "argument-like parameter `%s' to "
- "`%s'", arg, toknames[tok]);
+ if ( ! roff_warn(tree, arg, "argument-like parameter `%s' to "
+ "`%s'", arg, toknames[tok]))
+ return(ROFF_ARGMAX);
return(-1);
}
if ( ! roffargok(tok, v)) {
- roff_warn(tree, arg, "invalid argument parameter `%s' to "
- "`%s'", tokargnames[v], toknames[tok]);
+ if ( ! roff_warn(tree, arg, "invalid argument parameter `%s' to "
+ "`%s'", tokargnames[v], toknames[tok]))
+ return(ROFF_ARGMAX);
return(-1);
}
@@ -950,7 +842,7 @@ roffnextopt(const struct rofftree *tree, int tok,
*in = ++argv;
if (NULL == *argv) {
- roff_err(tree, arg, "empty value of `%s' for `%s'",
+ (void)roff_err(tree, arg, "empty value of `%s' for `%s'",
tokargnames[v], toknames[tok]);
return(ROFF_ARGMAX);
}
@@ -1024,6 +916,7 @@ roff_Dd(ROFFCALL_ARGS)
{
time_t t;
char *p, buf[32];
+ size_t sz;
if (ROFF_BODY & tree->state) {
assert( ! (ROFF_PRELUDE & tree->state));
@@ -1034,18 +927,21 @@ roff_Dd(ROFFCALL_ARGS)
assert(ROFF_PRELUDE & tree->state);
assert( ! (ROFF_BODY & tree->state));
- if (ROFF_PRELUDE_Dd & tree->state) {
- roff_err(tree, *argv, "repeated `Dd' in prelude");
- return(0);
- } else if (ROFF_PRELUDE_Dt & tree->state) {
- roff_err(tree, *argv, "out-of-order `Dd' in prelude");
- return(0);
- }
+ if (ROFF_PRELUDE_Dd & tree->state)
+ return(roff_errp(tree, *argv, tok, ERR_PR_REP));
+ if (ROFF_PRELUDE_Dt & tree->state)
+ return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
assert(NULL == tree->last);
argv++;
+ /*
+ * This is a bit complex because there are many forms the date
+ * can be in: it can be simply $Mdocdate$, $Mdocdate <date>$,
+ * or a raw date. Process accordingly.
+ */
+
if (0 == strcmp(*argv, "$Mdocdate$")) {
t = time(NULL);
if (NULL == localtime_r(&t, &tree->tm))
@@ -1054,49 +950,36 @@ roff_Dd(ROFFCALL_ARGS)
return(1);
}
- /* Build this from Mdocdate or raw date. */
-
buf[0] = 0;
p = *argv;
+ sz = sizeof(buf);
if (0 != strcmp(*argv, "$Mdocdate:")) {
while (*argv) {
- if (strlcat(buf, *argv++, sizeof(buf))
- < sizeof(buf))
+ if (strlcat(buf, *argv++, sz) < sz)
continue;
- roff_err(tree, p, "bad `Dd' date");
- return(0);
+ return(roff_errp(tree, p, tok, ERR_BADARG));
}
if (strptime(buf, "%b%d,%Y", &tree->tm)) {
tree->state |= ROFF_PRELUDE_Dd;
return(1);
}
- roff_err(tree, *argv, "bad `Dd' date");
- return(0);
+ return(roff_errp(tree, p, tok, ERR_BADARG));
}
argv++;
+
while (*argv && **argv != '$') {
- if (strlcat(buf, *argv++, sizeof(buf))
- >= sizeof(buf)) {
- roff_err(tree, p, "bad `Dd' Mdocdate");
- return(0);
- }
- if (strlcat(buf, " ", sizeof(buf))
- >= sizeof(buf)) {
- roff_err(tree, p, "bad `Dd' Mdocdate");
- return(0);
- }
- }
- if (NULL == *argv) {
- roff_err(tree, p, "bad `Dd' Mdocdate");
- return(0);
+ if (strlcat(buf, *argv++, sz) >= sz)
+ return(roff_errp(tree, p, tok, ERR_BADARG));
+ if (strlcat(buf, " ", sz) >= sz)
+ return(roff_errp(tree, p, tok, ERR_BADARG));
}
- if (NULL == strptime(buf, "%b %d %Y", &tree->tm)) {
- roff_err(tree, *argv, "bad `Dd' Mdocdate");
- return(0);
- }
+ if (NULL == *argv)
+ return(roff_errp(tree, p, tok, ERR_BADARG));
+ if (NULL == strptime(buf, "%b %d %Y", &tree->tm))
+ return(roff_errp(tree, p, tok, ERR_BADARG));
tree->state |= ROFF_PRELUDE_Dd;
return(1);
@@ -1107,6 +990,7 @@ roff_Dd(ROFFCALL_ARGS)
static int
roff_Dt(ROFFCALL_ARGS)
{
+ size_t sz;
if (ROFF_BODY & tree->state) {
assert( ! (ROFF_PRELUDE & tree->state));
@@ -1117,43 +1001,33 @@ roff_Dt(ROFFCALL_ARGS)
assert(ROFF_PRELUDE & tree->state);
assert( ! (ROFF_BODY & tree->state));
- if ( ! (ROFF_PRELUDE_Dd & tree->state)) {
- roff_err(tree, *argv, "out-of-order `Dt' in prelude");
- return(0);
- } else if (ROFF_PRELUDE_Dt & tree->state) {
- roff_err(tree, *argv, "repeated `Dt' in prelude");
- return(0);
- }
+ if ( ! (ROFF_PRELUDE_Dd & tree->state))
+ return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
+ if (ROFF_PRELUDE_Dt & tree->state)
+ return(roff_errp(tree, *argv, tok, ERR_PR_REP));
argv++;
- if (NULL == *argv) {
- roff_err(tree, *argv, "`Dt' needs document title");
- return(0);
- } else if (strlcpy(tree->title, *argv, sizeof(tree->title))
- >= sizeof(tree->title)) {
- roff_err(tree, *argv, "`Dt' document title too long");
- return(0);
- }
+ sz = sizeof(tree->title);
+
+ if (NULL == *argv)
+ return(roff_errp(tree, *argv, tok, ERR_ARGGE2));
+ if (strlcpy(tree->title, *argv, sz) >= sz)
+ return(roff_errp(tree, *argv, tok, ERR_ARGLEN));
argv++;
- if (NULL == *argv) {
- roff_err(tree, *argv, "`Dt' needs section");
- return(0);
- }
+ if (NULL == *argv)
+ return(roff_errp(tree, *argv, tok, ERR_ARGGE2));
- if (ROFF_MSEC_MAX == (tree->section = roffismsec(*argv))) {
- roff_err(tree, *argv, "bad `Dt' section");
- return(0);
- }
+ if (ROFF_MSEC_MAX == (tree->section = roff_msec(*argv)))
+ return(roff_errp(tree, *argv, tok, ERR_BADARG));
argv++;
+ sz = sizeof(tree->volume);
+
if (NULL == *argv) {
tree->volume[0] = 0;
- } else if (strlcpy(tree->volume, *argv, sizeof(tree->volume))
- >= sizeof(tree->volume)) {
- roff_err(tree, *argv, "`Dt' volume too long");
- return(0);
- }
+ } else if (strlcpy(tree->volume, *argv, sz) >= sz)
+ return(roff_errp(tree, *argv, tok, ERR_ARGLEN));
assert(NULL == tree->last);
tree->state |= ROFF_PRELUDE_Dt;
@@ -1165,21 +1039,18 @@ roff_Dt(ROFFCALL_ARGS)
static int
roffsetname(struct rofftree *tree, char **ordp)
{
+ size_t sz;
assert(*ordp);
/* FIXME: not all sections can set this. */
- if (NULL != *(ordp + 1)) {
- roff_err(tree, *ordp, "too many `Nm' args");
- return(0);
- }
+ if (NULL != *(ordp + 1))
+ return(roff_errp(tree, *ordp, ROFF_Nm, ERR_ARGMNY));
- if (strlcpy(tree->name, *ordp, sizeof(tree->name))
- >= sizeof(tree->name)) {
- roff_err(tree, *ordp, "`Nm' arg too long");
- return(0);
- }
+ sz = sizeof(tree->name);
+ if (strlcpy(tree->name, *ordp, sz) >= sz)
+ return(roff_errp(tree, *ordp, ROFF_Nm, ERR_ARGLEN));
return(1);
}
@@ -1236,6 +1107,7 @@ static int
roff_Os(ROFFCALL_ARGS)
{
char *p;
+ size_t sz;
if (ROFF_BODY & tree->state) {
assert( ! (ROFF_PRELUDE & tree->state));
@@ -1245,29 +1117,21 @@ roff_Os(ROFFCALL_ARGS)
assert(ROFF_PRELUDE & tree->state);
if ( ! (ROFF_PRELUDE_Dt & tree->state) ||
- ! (ROFF_PRELUDE_Dd & tree->state)) {
- roff_err(tree, *argv, "out-of-order `Os' in prelude");
- return(0);
- }
+ ! (ROFF_PRELUDE_Dd & tree->state))
+ return(roff_errp(tree, *argv, tok, ERR_PR_OOO));
tree->os[0] = 0;
p = *++argv;
+ sz = sizeof(tree->os);
- while (*argv) {
- if (strlcat(tree->os, *argv++, sizeof(tree->os))
- < sizeof(tree->os))
- continue;
- roff_err(tree, p, "`Os' value too long");
- return(0);
- }
+ while (*argv)
+ if (strlcat(tree->os, *argv++, sz) >= sz)
+ return(roff_errp(tree, p, tok, ERR_ARGLEN));
if (0 == tree->os[0])
- if (strlcpy(tree->os, "LOCAL", sizeof(tree->os))
- >= sizeof(tree->os)) {
- roff_err(tree, p, "`Os' value too long");
- return(0);
- }
+ if (strlcpy(tree->os, "LOCAL", sz) >= sz)
+ return(roff_errp(tree, p, tok, ERR_ARGLEN));
tree->state |= ROFF_PRELUDE_Os;
tree->state &= ~ROFF_PRELUDE;
@@ -1280,8 +1144,8 @@ roff_Os(ROFFCALL_ARGS)
assert(NULL == tree->last);
return((*tree->cb.roffhead)(tree->arg, &tree->tm,
- tree->os, tree->title, tree->section,
- tree->volume));
+ tree->os, tree->title,
+ tree->section, tree->volume));
}
@@ -1306,11 +1170,10 @@ roff_layout(ROFFCALL_ARGS)
assert( ! (ROFF_CALLABLE & tokens[tok].flags));
- if (ROFF_PRELUDE & tree->state) {
- roff_err(tree, *argv, "bad `%s' in prelude",
- toknames[tok]);
- return(0);
- } else if (ROFF_EXIT == type) {
+ if (ROFF_PRELUDE & tree->state)
+ return(roff_errp(tree, *argv, tok, ERR_NOT_PR));
+
+ if (ROFF_EXIT == type) {
roffnode_free(tree);
if ( ! (*tree->cb.roffblkbodyout)(tree->arg, tok))
return(0);
@@ -1357,19 +1220,21 @@ roff_layout(ROFFCALL_ARGS)
switch (tok) {
case (ROFF_Sh):
if (NULL == *argv) {
- roff_err(tree, *(argv - 1),
- "`Sh' expects arguments");
- return(0);
+ argv--;
+ return(roff_errp(tree, *argv, tok, ERR_ARGGE1));
}
- tree->csec = roffissec((const char **)argv);
+
+ tree->csec = roff_sec((const char **)argv);
+
if ( ! (ROFFSec_OTHER & tree->csec) &&
tree->asec & tree->csec)
- roff_warn(tree, *argv, "section repeated");
- if (0 == tree->asec && ! (ROFFSec_NAME & tree->csec)) {
- roff_err(tree, *argv, "`NAME' section "
- "must be first");
- return(0);
- } else if ( ! roffchecksec(tree, *argv, tree->csec))
+ if ( ! roff_warn(tree, *argv, "section repeated"))
+ return(0);
+
+ if (0 == tree->asec && ! (ROFFSec_NAME & tree->csec))
+ return(roff_err(tree, *argv, "`NAME' section "
+ "must be first"));
+ if ( ! roffchecksec(tree, *argv, tree->csec))
return(0);
tree->asec |= tree->csec;
@@ -1470,11 +1335,8 @@ roff_ordered(ROFFCALL_ARGS)
* .Xr arg1 arg2 punctuation
*/
- if (ROFF_PRELUDE & tree->state) {
- roff_err(tree, *argv, "`%s' disallowed in prelude",
- toknames[tok]);
- return(0);
- }
+ if (ROFF_PRELUDE & tree->state)
+ return(roff_errp(tree, *argv, tok, ERR_NOT_PR));
first = (*argv == tree->cur);
p = *argv++;
@@ -1545,11 +1407,8 @@ roff_text(ROFFCALL_ARGS)
* <fl> v W f </fl> ;
*/
- if (ROFF_PRELUDE & tree->state) {
- roff_err(tree, *argv, "`%s' disallowed in prelude",
- toknames[tok]);
- return(0);
- }
+ if (ROFF_PRELUDE & tree->state)
+ return(roff_errp(tree, *argv, tok, ERR_NOT_PR));
first = (*argv == tree->cur);
argv++;
@@ -1567,7 +1426,6 @@ roff_text(ROFFCALL_ARGS)
while (*argv)
if ( ! roffdata(tree, i++, *argv++))
return(0);
-
return((*tree->cb.roffout)(tree->arg, tok));
}
@@ -1589,11 +1447,9 @@ roff_text(ROFFCALL_ARGS)
if ( ! roffcall(tree, c, argv))
return(0);
-
if (ROFF_LSCOPE & tokens[tok].flags)
if ( ! (*tree->cb.roffout)(tree->arg, tok))
return(0);
-
break;
}
@@ -1655,12 +1511,30 @@ static int
roff_depr(ROFFCALL_ARGS)
{
- roff_err(tree, *argv, "`%s' is deprecated", toknames[tok]);
- return(0);
+ return(roff_errp(tree, *argv, tok, ERR_DEPREC));
}
-static void
+static int
+roff_warnp(const struct rofftree *tree, const char *pos,
+ int tok, enum rofferr type)
+{
+ char *p;
+
+ switch (type) {
+ case (WRN_SECORD):
+ p = "section at `%s' out of order";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ return(roff_warn(tree, pos, p, toknames[tok]));
+}
+
+
+static int
roff_warn(const struct rofftree *tree, const char *pos, char *fmt, ...)
{
va_list ap;
@@ -1670,22 +1544,75 @@ roff_warn(const struct rofftree *tree, const char *pos, char *fmt, ...)
(void)vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- (*tree->cb.roffmsg)(tree->arg,
- ROFF_WARN, tree->cur, pos, buf);
+ return((*tree->cb.roffmsg)(tree->arg,
+ ROFF_WARN, tree->cur, pos, buf));
}
-static void
+static int
+roff_errp(const struct rofftree *tree, const char *pos,
+ int tok, enum rofferr type)
+{
+ char *p;
+
+ switch (type) {
+ case (ERR_ARGEQ1):
+ p = "`%s' expects exactly one argument";
+ break;
+ case (ERR_ARGEQ0):
+ p = "`%s' expects exactly zero arguments";
+ break;
+ case (ERR_ARGGE1):
+ p = "`%s' expects one or more arguments";
+ break;
+ case (ERR_ARGGE2):
+ p = "`%s' expects two or more arguments";
+ break;
+ case (ERR_BADARG):
+ p = "invalid argument for `%s'";
+ break;
+ case (ERR_NOTSUP):
+ p = "macro `%s' is not supported";
+ break;
+ case(ERR_PR_OOO):
+ p = "prelude macro `%s' is out of order";
+ break;
+ case(ERR_PR_REP):
+ p = "prelude macro `%s' repeated";
+ break;
+ case(ERR_ARGLEN):
+ p = "macro argument for `%s' is too long";
+ break;
+ case(ERR_DEPREC):
+ p = "macro `%s' is deprecated";
+ break;
+ case(ERR_NOT_PR):
+ p = "macro `%s' disallowed in prelude";
+ break;
+ case(ERR_ARGMNY):
+ p = "too many arguments for macro `%s'";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ return(roff_err(tree, pos, p, toknames[tok]));
+}
+
+
+static int
roff_err(const struct rofftree *tree, const char *pos, char *fmt, ...)
{
va_list ap;
char buf[128];
va_start(ap, fmt);
- (void)vsnprintf(buf, sizeof(buf), fmt, ap);
+ if (-1 == vsnprintf(buf, sizeof(buf), fmt, ap))
+ err(1, "vsnprintf");
va_end(ap);
- (*tree->cb.roffmsg)(tree->arg,
- ROFF_ERROR, tree->cur, pos, buf);
+ return((*tree->cb.roffmsg)
+ (tree->arg, ROFF_ERROR, tree->cur, pos, buf));
}
diff --git a/tokens.c b/tokens.c
index 0ea4e113..ce46d335 100644
--- a/tokens.c
+++ b/tokens.c
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
-#include "libmdocml.h"
#include "private.h"
diff --git a/xml.c b/xml.c
index 9d8a6693..64ce7ce4 100644
--- a/xml.c
+++ b/xml.c
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
-#include "libmdocml.h"
#include "private.h"
#include "ml.h"