diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-03-15 07:08:52 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-03-15 07:08:52 +0000 |
commit | 885216263c7b90bf8b3fe9284d6f22d75a7ad7b4 (patch) | |
tree | 6a0f1485e03b97dd0e4b7357cf346656f85ede72 | |
parent | c4b5d8a0192a406d9f04a23e2c8a768a29e01371 (diff) | |
download | mandoc-885216263c7b90bf8b3fe9284d6f22d75a7ad7b4.tar.gz |
mdoclint accepts multiple files
mdocterm punts to nroff if it fails parsing
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | mdoclint.1 | 7 | ||||
-rw-r--r-- | mdoclint.c | 17 | ||||
-rw-r--r-- | mdocterm.1 | 70 | ||||
-rw-r--r-- | mdocterm.c | 160 | ||||
-rw-r--r-- | mdoctree.c | 16 | ||||
-rw-r--r-- | mmain.c | 95 | ||||
-rw-r--r-- | mmain.h | 12 | ||||
-rw-r--r-- | term.h | 3 |
9 files changed, 294 insertions, 90 deletions
@@ -1,7 +1,7 @@ .SUFFIXES: .html .sgml -VERSION = 1.4.16 -VDATE = 14 March 2009 +VERSION = 1.5.01 +VDATE = 15 March 2009 BINDIR = $(PREFIX)/bin INCLUDEDIR = $(PREFIX)/include @@ -29,7 +29,7 @@ .Op Fl vV .Op Fl f Ns Ar options... .Op Fl W Ns Ar err... -.Op Ar infile +.Op Ar infile... .\" SECTION .Sh DESCRIPTION The @@ -71,7 +71,10 @@ Read input from .Ar infile , which may be .Dq \- -for stdin. +for stdin. If multiple +.Ar infile +arguments are specified, each is processed and the system will exit on +the first failure. .El .\" PARAGRAPH .Pp @@ -29,16 +29,21 @@ main(int argc, char *argv[]) { struct mmain *p; int c; - const struct mdoc *mdoc; p = mmain_alloc(); - c = mmain_getopt(p, argc, argv, NULL, NULL, NULL, NULL); - if (1 != c) - mmain_exit(p, -1 == c ? 1 : 0); + c = mmain_getopt(p, argc, argv, NULL, + "[infile...]", NULL, NULL, NULL); - if (NULL == (mdoc = mmain_mdoc(p))) - mmain_exit(p, 1); + argv += c; + if (0 == (argc -= c)) + mmain_exit(p, NULL != mmain_mdoc(p, "-")); + + while (c-- > 0) { + if (NULL == mmain_mdoc(p, *argv++)) + mmain_exit(p, 1); + mmain_reset(p); + } mmain_exit(p, 0); /* NOTREACHED */ @@ -21,16 +21,24 @@ .Os .\" SECTION .Sh NAME -.Nm mdocmterm +.Nm mdocterm .Nd mdoc macro compiler .\" SECTION .Sh SYNOPSIS -.Nm mdocmterm +.Nm mdocterm .Op Fl vV .Op Fl f Ns Ar option... .Op Fl O Ns Ar option... .Op Fl W Ns Ar err... .Op Ar infile +.Nm mdocterm +.Op Fl hi +.Op Fl m Ns Ar name +.Op Fl n Ns Ar num +.Op Fl o Ns Ar list +.Op Fl r Ns Ar cn +.Op Fl T Ns Ar name +.Op Ar infile .\" SECTION .Sh DESCRIPTION The @@ -52,13 +60,9 @@ Override default compiler behaviour. See for details. .\" ITEM .It Fl O Ns Ar option... -Terminal-encoding options. May be set to -.Fl O Ns Ar ansi -for ANSI/VT100-encoded output (the default) or -.Fl O Ns Ar nroff -for nroff-encoded -.Qq backspace -output. +Terminal-encoding options. See +.Sx Front-end Options +for details. .\" ITEM .It Fl W Ns Ar err... Print warning messages. May be set to @@ -84,6 +88,15 @@ for stdin. .El .\" PARAGRAPH .Pp +If +.Xr nroff 1 +arguments are supplied on the command line +.Pq Fl himnorT , +these are ignored unless +.Xr nroff 1 +is invoked on parse failure. +.\" PARAGRAPH +.Pp The .Nm utility is a formatting front-end for @@ -95,16 +108,40 @@ input, documented at and .Xr mdoc.samples 7 , into an abstract syntax tree. +.\" PARAGRAPH .Pp By default, .Nm -reads from stdin and prints ANSI -.Qq raw +reads from stdin and prints nroff +.Qq backspace terminal-encoded output to stdout, at this time to a fixed column with -of 78 characters. +of 78 characters. If +.Ar infile +can't be parsed (isn't valid mdoc, doesn't contain valid syntax, etc.), +.Xr nroff 1 +is invoked. If no +.Xr nroff 1 +command-line argumnets aren't provided, +.Fl m Ar Ns andoc +is implied. .\" PARAGRAPH .Pp -.Ex -std mdocmterm +.Ex -std mdocterm +.\" SUB-SECTION +.Ss Front-end Options +The default behaviour may be overriden with the +.Fl O +flag. The available options are as follows: +.Bl -tag -width XXXXXXXXXXXX -offset XXXX +.It Fl O Ns Ar nopunt +Don't punt to +.Xr nroff 1 +if +.Ar infile +may not be parsed. +.It Fl O Ns Ar ansi +Use ANSI/VT100 output encoding instead of backspaces. +.El .\" SUB-SECTION .Ss Compiler Options Default compiler behaviour may be overriden with the @@ -125,6 +162,8 @@ As with the .Fl W flag, multiple .Fl f +and +.Fl O options may be grouped and delimited with a comma. Using .Fl f Ns Ar ign-scope,ign-escape , for example, will try to ignore scope and character-escape errors. @@ -260,17 +299,16 @@ the more general syntax. To display this manual page on ANSI-capable terminal: .\" PARAGRAPH .Pp -.D1 % mdocmterm \-Wall,error mdocmterm.1 +.D1 % mdocterm \-Wall,error mdocterm.1 .\" PARAGRAPH .Pp To pipe a manual page to the pager: .Pp -.D1 % mdocterm -Onroff mdocterm.1 | less +.D1 % mdocterm mdocterm.1 | less .\" SECTION .Sh SEE ALSO .Xr mdoctree 1 , .Xr mdoclint 1 , -.Xr mdoc.samples 7 , .Xr mdoc 7 , .Xr mdoc 3 .\" @@ -25,16 +25,30 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "mmain.h" #include "term.h" +struct nroffopt { + int fl_h; + int fl_i; + char *arg_m; + char *arg_n; + char *arg_o; + char *arg_r; + char *arg_T; + struct termp *termp; /* Ephemeral. */ +}; + struct termseq { const char *enc; int sym; }; -static int option(void *, int, const char *); +dead_pre void punt(struct nroffopt *, char *) dead_post; +static int option(void *, int, char *); +static int optsopt(struct termp *, char *); static void body(struct termp *, struct termpair *, const struct mdoc_meta *, @@ -126,6 +140,7 @@ static struct termseq termenc2[] = { { NULL, 0 } }; +/* FIXME: abstract to dynamically-compiled table. */ static struct termsym termsym_ascii[TERMSYM_MAX] = { { "]", 1 }, /* TERMSYM_RBRACK */ { "[", 1 }, /* TERMSYM_LBRACK */ @@ -170,33 +185,49 @@ static struct termsym termsym_ascii[TERMSYM_MAX] = { { "}", 1 }, /* TERMSYM_RBRACE */ }; - int main(int argc, char *argv[]) { struct mmain *p; - int c; const struct mdoc *mdoc; + struct nroffopt nroff; struct termp termp; + int c; + char *in; (void)memset(&termp, 0, sizeof(struct termp)); + (void)memset(&nroff, 0, sizeof(struct nroffopt)); - termp.maxrmargin = termp.rmargin = 78; /* XXX */ - termp.maxcols = 1024; + termp.maxrmargin = termp.rmargin = 78; /* FIXME */ + termp.maxcols = 1024; /* FIXME */ termp.offset = termp.col = 0; termp.flags = TERMP_NOSPACE; termp.symtab = termsym_ascii; - termp.enc = TERMENC_ANSI; + termp.enc = TERMENC_NROFF; - p = mmain_alloc(); - c = mmain_getopt(p, argc, argv, "[-Ooption...]", - "O:", &termp, option); + nroff.termp = &termp; - if (1 != c) - mmain_exit(p, -1 == c ? 1 : 0); + p = mmain_alloc(); - if (NULL == (mdoc = mmain_mdoc(p))) - mmain_exit(p, 1); + c = mmain_getopt(p, argc, argv, "[-Ooption...]", + "[infile]", "him:n:o:r:T:O:", &nroff, option); + + /* FIXME: this needs to accept multiple outputs. */ + argv += c; + if ((argc -= c) > 0) + in = *argv++; + else + in = "-"; + + mmain_prepare(p, in); + + if (NULL == (mdoc = mmain_process(p))) { + if (TERMP_NOPUNT & termp.iflags) + mmain_exit(p, 1); + mmain_free(p); + punt(&nroff, in); + /* NOTREACHED */ + } if (NULL == (termp.buf = malloc(termp.maxcols))) err(1, "malloc"); @@ -212,23 +243,67 @@ main(int argc, char *argv[]) } -int -option(void *ptr, int c, const char *arg) +static int +optsopt(struct termp *p, char *arg) { - struct termp *p; + char *v; + char *toks[] = { "ansi", "nopunt", NULL }; - p = (struct termp *)ptr; + while (*arg) + switch (getsubopt(&arg, toks, &v)) { + case (0): + p->enc = TERMENC_ANSI; + break; + case (2): + p->iflags |= TERMP_NOPUNT; + break; + default: + warnx("unknown -O argument"); + return(0); + } + + return(1); +} - if (0 == strcmp(arg, "nroff")) { - p->enc = TERMENC_NROFF; - return(1); - } else if (0 == strcmp(arg, "ansi")) { - p->enc = TERMENC_ANSI; - return(1); + +static int +option(void *ptr, int c, char *arg) +{ + struct termp *termp; + struct nroffopt *nroff; + + nroff = (struct nroffopt *)ptr; + termp = nroff->termp; + + switch (c) { + case ('h'): + nroff->fl_h = 1; + break; + case ('i'): + nroff->fl_i = 1; + break; + case ('m'): + nroff->arg_m = arg; + break; + case ('n'): + nroff->arg_n = arg; + break; + case ('o'): + nroff->arg_o = arg; + break; + case ('r'): + nroff->arg_r = arg; + break; + case ('T'): + nroff->arg_T = arg; + break; + case ('O'): + return(optsopt(termp, arg)); + default: + break; } - warnx("unknown option: -O%s", arg); - return(0); + return(1); } @@ -1014,3 +1089,38 @@ sanity(const struct mdoc_node *n) } } + +dead_pre void +punt(struct nroffopt *nroff, char *in) +{ + char *args[32]; + char arg0[32], argm[32]; + int i; + + warnx("punting to nroff!"); + + i = 0; + + (void)strlcpy(arg0, "nroff", 32); + args[i++] = arg0; + + if (nroff->fl_h) + args[i++] = "-h"; + if (nroff->fl_i) + args[i++] = "-i"; + + if (nroff->arg_m) { + (void)strlcpy(argm, "-m", 32); + (void)strlcat(argm, nroff->arg_m, 32); + args[i++] = argm; + } else + args[i++] = "-mandoc"; + + args[i++] = in; + args[i++] = (char *)NULL; + + (void)execvp("nroff", args); + errx(1, "exec"); + /* NOTREACHED */ +} + @@ -32,16 +32,22 @@ int main(int argc, char *argv[]) { struct mmain *p; - int c; const struct mdoc *mdoc; + int c; + char *in; p = mmain_alloc(); - c = mmain_getopt(p, argc, argv, NULL, NULL, NULL, NULL); - if (1 != c) - mmain_exit(p, -1 == c ? 1 : 0); + c = mmain_getopt(p, argc, argv, NULL, + "[infile]", NULL, NULL, NULL); + + argv += c; + if ((argc -= c) > 0) + in = *argv++; + else + in = "-"; - if (NULL == (mdoc = mmain_mdoc(p))) + if (NULL == (mdoc = mmain_mdoc(p, in))) mmain_exit(p, 1); doprint(mdoc_node(mdoc), 0); @@ -42,13 +42,14 @@ struct mmain { struct mdoc *mdoc; /* Active parser. */ char *buf; /* Input buffer. */ size_t bufsz; /* Input buffer size. */ - char *in; /* Input file name. */ + const char *in; /* Input file name. */ int fdin; /* Input file desc. */ int pflags; /* Parse flags. */ }; extern char *__progname; +static void usage(const char *, const char *); static int optswarn(struct mmain *, char *); static int optsopt(struct mmain *, char *); static int parse(struct mmain *); @@ -68,11 +69,13 @@ extern size_t strlcat(char *, const char *, size_t); * Print our and our caller's usage message. */ void -mmain_usage(const char *help) +usage(const char *help, const char *args) { - warnx("usage: %s %s%s[-v] [-foption...] [-Wwarn...] [infile]", __progname, - help ? help : "", help ? " " : ""); + warnx("usage: %s %s%s[-v] [-foption...] [-Wwarn...]%s%s", + __progname, + help ? help : "", help ? " " : "", + args ? " " : "", args ? args : ""); } @@ -87,9 +90,6 @@ mmain_alloc(void) if (NULL == (p = calloc(1, sizeof(struct mmain)))) err(1, "malloc"); - p->in = "-"; - p->fdin = STDIN_FILENO; - return(p); } @@ -102,8 +102,9 @@ mmain_alloc(void) */ int mmain_getopt(struct mmain *p, int argc, char *argv[], - const char *help, const char *u, void *arg, - int (*getopt_cb)(void *, int, const char *)) + const char *help, const char *args, + const char *u, void *arg, + int (*getopt_cb)(void *, int, char *)) { int c; char opts[32]; /* XXX */ @@ -126,62 +127,76 @@ mmain_getopt(struct mmain *p, int argc, char *argv[], switch (c) { case ('f'): if ( ! optsopt(p, optarg)) - return(-1); + mmain_exit(p, 1); break; case ('v'): p->dbg++; break; case ('V'): (void)printf("%s %s\n", __progname, VERSION); - return(0); + mmain_exit(p, 0); + /* NOTREACHED */ case ('W'): if ( ! optswarn(p, optarg)) - return(-1); + mmain_exit(p, 1); break; case ('?'): - mmain_usage(help); - return(-1); + usage(help, args); + mmain_exit(p, 1); + /* NOTREACHED */ default: assert(getopt_cb); if ((*getopt_cb)(arg, c, optarg)) break; - return(-1); + mmain_exit(p, 1); + /* NOTREACHED */ } - argv += optind; - if ((argc -= optind) > 0) - p->in = *argv++; + return(optind); +} - return(1); + +void +mmain_reset(struct mmain *p) +{ + + if (p->mdoc) + mdoc_free(p->mdoc); + p->mdoc = NULL; } -dead_pre void -mmain_exit(struct mmain *p, int code) +void +mmain_free(struct mmain *p) { if (p->mdoc) mdoc_free(p->mdoc); free(p); +} + + +dead_pre void +mmain_exit(struct mmain *p, int code) +{ + + mmain_free(p); exit(code); } -struct mdoc * -mmain_mdoc(struct mmain *p) +void +mmain_prepare(struct mmain *p, const char *in) { struct stat st; - int c; - struct mdoc_cb cb; - cb.mdoc_err = msg_err; - cb.mdoc_warn = msg_warn; - cb.mdoc_msg = msg_msg; + p->in = in; + p->fdin = STDIN_FILENO; if (0 != strcmp(p->in, "-")) if (-1 == (p->fdin = open(p->in, O_RDONLY, 0))) { warn("%s", p->in); - return(0); + mmain_exit(p, 1); } /* Allocate a buffer to be BUFSIZ/block size. */ @@ -195,6 +210,19 @@ mmain_mdoc(struct mmain *p) p->buf = malloc(p->bufsz); if (NULL == p->buf) err(1, "malloc"); +} + + +struct mdoc * +mmain_process(struct mmain *p) +{ + int c; + struct mdoc_cb cb; + + /* XXX - in mmain_alloc.*/ + cb.mdoc_err = msg_err; + cb.mdoc_warn = msg_warn; + cb.mdoc_msg = msg_msg; /* Allocate the parser. */ @@ -213,6 +241,15 @@ mmain_mdoc(struct mmain *p) } +struct mdoc * +mmain_mdoc(struct mmain *p, const char *in) +{ + + mmain_prepare(p, in); + return(mmain_process(p)); +} + + static int optsopt(struct mmain *p, char *arg) { @@ -47,10 +47,14 @@ struct mmain; struct mmain *mmain_alloc(void); dead_pre void mmain_exit(struct mmain *, int) dead_post; int mmain_getopt(struct mmain *, int, char *[], - const char *, const char *, void *, - int (*)(void *, int, const char *)); -struct mdoc *mmain_mdoc(struct mmain *); -void mmain_usage(const char *); + const char *, const char *, + const char *, void *, + int (*)(void *, int, char *)); +struct mdoc *mmain_mdoc(struct mmain *, const char *); +void mmain_reset(struct mmain *); +void mmain_free(struct mmain *); +void mmain_prepare(struct mmain *, const char *); +struct mdoc *mmain_process(struct mmain *); __END_DECLS @@ -86,6 +86,8 @@ struct termp { size_t maxcols; size_t offset; size_t col; + int iflags; +#define TERMP_NOPUNT (1 << 0) int flags; #define TERMP_NOSPACE (1 << 0) /* No space before words. */ #define TERMP_NOLPAD (1 << 1) /* No leftpad before flush. */ @@ -94,7 +96,6 @@ struct termp { #define TERMP_IGNDELIM (1 << 4) /* Delims like regulars. */ #define TERMP_NONOSPACE (1 << 5) /* No space (no autounset). */ #define TERMP_NONOBREAK (1 << 7) /* Don't newln NOBREAK. */ - #define TERMP_STYLE 0xff00 /* Style mask. */ #define TERMP_BOLD (1 << 8) /* Styles... */ #define TERMP_UNDER (1 << 9) |