-/* $Id: main.c,v 1.164 2011/09/17 15:00:51 schwarze Exp $ */
+/* $Id: main.c,v 1.178 2014/08/10 23:54:41 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* 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 <stdio.h>
#include <unistd.h>
#include "mandoc.h"
+#include "mandoc_aux.h"
#include "main.h"
#include "mdoc.h"
#include "man.h"
struct mparse *mp;
enum mandoclevel wlevel; /* ignore messages below this */
int wstop; /* stop after a file with a warning */
- enum outt outtype; /* which output to use */
+ enum outt outtype; /* which output to use */
out_mdoc outmdoc; /* mdoc output ptr */
- out_man outman; /* man output ptr */
+ out_man outman; /* man output ptr */
out_free outfree; /* free output ptr */
void *outdata; /* data for output */
char outopts[BUFSIZ]; /* buf of output opts */
};
-static int moptions(enum mparset *, char *);
+static int moptions(int *, char *);
static void mmsg(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
-static void parse(struct curparse *, int,
+static void parse(struct curparse *, int,
const char *, enum mandoclevel *);
static int toptions(struct curparse *, char *);
static void usage(void) __attribute__((noreturn));
static const char *progname;
+
int
main(int argc, char *argv[])
{
int c;
struct curparse curp;
- enum mparset type;
+ int options;
enum mandoclevel rc;
+ char *defos;
progname = strrchr(argv[0], '/');
if (progname == NULL)
memset(&curp, 0, sizeof(struct curparse));
- type = MPARSE_AUTO;
+ options = MPARSE_SO;
curp.outtype = OUTT_ASCII;
curp.wlevel = MANDOCLEVEL_FATAL;
+ defos = NULL;
- /* LINTED */
- while (-1 != (c = getopt(argc, argv, "m:O:T:VW:")))
+ while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:")))
switch (c) {
- case ('m'):
- if ( ! moptions(&type, optarg))
+ case 'I':
+ if (strncmp(optarg, "os=", 3)) {
+ fprintf(stderr,
+ "%s: -I%s: Bad argument\n",
+ progname, optarg);
+ return((int)MANDOCLEVEL_BADARG);
+ }
+ if (defos) {
+ fprintf(stderr,
+ "%s: -I%s: Duplicate argument\n",
+ progname, optarg);
return((int)MANDOCLEVEL_BADARG);
+ }
+ defos = mandoc_strdup(optarg + 3);
break;
- case ('O'):
+ case 'm':
+ if ( ! moptions(&options, optarg))
+ return((int)MANDOCLEVEL_BADARG);
+ break;
+ case 'O':
(void)strlcat(curp.outopts, optarg, BUFSIZ);
(void)strlcat(curp.outopts, ",", BUFSIZ);
break;
- case ('T'):
+ case 'T':
if ( ! toptions(&curp, optarg))
return((int)MANDOCLEVEL_BADARG);
break;
- case ('W'):
+ case 'W':
if ( ! woptions(&curp, optarg))
return((int)MANDOCLEVEL_BADARG);
break;
- case ('V'):
+ case 'V':
version();
/* NOTREACHED */
default:
/* NOTREACHED */
}
- curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp);
+ curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
+
+ /*
+ * Conditionally start up the lookaside buffer before parsing.
+ */
+ if (OUTT_MAN == curp.outtype)
+ mparse_keep(curp.mp);
argc -= optind;
argv += optind;
(*curp.outfree)(curp.outdata);
if (curp.mp)
mparse_free(curp.mp);
+ free(defos);
return((int)rc);
}
fprintf(stderr, "usage: %s "
"[-V] "
- "[-foption] "
+ "[-Ios=name] "
"[-mformat] "
"[-Ooption] "
"[-Toutput] "
- "[-Wlevel] "
- "[file...]\n",
+ "[-Wlevel]\n"
+ "\t [file ...]\n",
progname);
exit((int)MANDOCLEVEL_BADARG);
}
static void
-parse(struct curparse *curp, int fd,
- const char *file, enum mandoclevel *level)
+parse(struct curparse *curp, int fd, const char *file,
+ enum mandoclevel *level)
{
enum mandoclevel rc;
struct mdoc *mdoc;
if ( ! (curp->outman && curp->outmdoc)) {
switch (curp->outtype) {
- case (OUTT_XHTML):
+ case OUTT_XHTML:
curp->outdata = xhtml_alloc(curp->outopts);
curp->outfree = html_free;
break;
- case (OUTT_HTML):
+ case OUTT_HTML:
curp->outdata = html_alloc(curp->outopts);
curp->outfree = html_free;
break;
- case (OUTT_UTF8):
+ case OUTT_UTF8:
curp->outdata = utf8_alloc(curp->outopts);
curp->outfree = ascii_free;
break;
- case (OUTT_LOCALE):
+ case OUTT_LOCALE:
curp->outdata = locale_alloc(curp->outopts);
curp->outfree = ascii_free;
break;
- case (OUTT_ASCII):
+ case OUTT_ASCII:
curp->outdata = ascii_alloc(curp->outopts);
curp->outfree = ascii_free;
break;
- case (OUTT_PDF):
+ case OUTT_PDF:
curp->outdata = pdf_alloc(curp->outopts);
curp->outfree = pspdf_free;
break;
- case (OUTT_PS):
+ case OUTT_PS:
curp->outdata = ps_alloc(curp->outopts);
curp->outfree = pspdf_free;
break;
}
switch (curp->outtype) {
- case (OUTT_HTML):
+ case OUTT_HTML:
/* FALLTHROUGH */
- case (OUTT_XHTML):
+ case OUTT_XHTML:
curp->outman = html_man;
curp->outmdoc = html_mdoc;
break;
- case (OUTT_TREE):
+ case OUTT_TREE:
curp->outman = tree_man;
curp->outmdoc = tree_mdoc;
break;
- case (OUTT_MAN):
+ case OUTT_MAN:
curp->outmdoc = man_mdoc;
+ curp->outman = man_man;
break;
- case (OUTT_PDF):
+ case OUTT_PDF:
/* FALLTHROUGH */
- case (OUTT_ASCII):
+ case OUTT_ASCII:
/* FALLTHROUGH */
- case (OUTT_UTF8):
+ case OUTT_UTF8:
/* FALLTHROUGH */
- case (OUTT_LOCALE):
+ case OUTT_LOCALE:
/* FALLTHROUGH */
- case (OUTT_PS):
+ case OUTT_PS:
curp->outman = terminal_man;
curp->outmdoc = terminal_mdoc;
break;
}
}
- mparse_result(curp->mp, &mdoc, &man);
+ mparse_result(curp->mp, &mdoc, &man, NULL);
/* Execute the out device, if it exists. */
}
static int
-moptions(enum mparset *tflags, char *arg)
+moptions(int *options, char *arg)
{
if (0 == strcmp(arg, "doc"))
- *tflags = MPARSE_MDOC;
+ *options |= MPARSE_MDOC;
else if (0 == strcmp(arg, "andoc"))
- *tflags = MPARSE_AUTO;
+ /* nothing to do */;
else if (0 == strcmp(arg, "an"))
- *tflags = MPARSE_MAN;
+ *options |= MPARSE_MAN;
else {
- fprintf(stderr, "%s: Bad argument\n", arg);
+ fprintf(stderr, "%s: -m%s: Bad argument\n",
+ progname, arg);
return(0);
}
else if (0 == strcmp(arg, "pdf"))
curp->outtype = OUTT_PDF;
else {
- fprintf(stderr, "%s: Bad argument\n", arg);
+ fprintf(stderr, "%s: -T%s: Bad argument\n",
+ progname, arg);
return(0);
}
woptions(struct curparse *curp, char *arg)
{
char *v, *o;
- const char *toks[6];
+ const char *toks[6];
toks[0] = "stop";
toks[1] = "all";
while (*arg) {
o = arg;
switch (getsubopt(&arg, UNCONST(toks), &v)) {
- case (0):
+ case 0:
curp->wstop = 1;
break;
- case (1):
+ case 1:
/* FALLTHROUGH */
- case (2):
+ case 2:
curp->wlevel = MANDOCLEVEL_WARNING;
break;
- case (3):
+ case 3:
curp->wlevel = MANDOCLEVEL_ERROR;
break;
- case (4):
+ case 4:
curp->wlevel = MANDOCLEVEL_FATAL;
break;
default:
- fprintf(stderr, "-W%s: Bad argument\n", o);
+ fprintf(stderr, "%s: -W%s: Bad argument\n",
+ progname, o);
return(0);
}
}
}
static void
-mmsg(enum mandocerr t, enum mandoclevel lvl,
+mmsg(enum mandocerr t, enum mandoclevel lvl,
const char *file, int line, int col, const char *msg)
{
+ const char *mparse_msg;
+
+ fprintf(stderr, "%s: %s:", progname, file);
+
+ if (line)
+ fprintf(stderr, "%d:%d:", line, col + 1);
+
+ fprintf(stderr, " %s", mparse_strlevel(lvl));
- fprintf(stderr, "%s:%d:%d: %s: %s",
- file, line, col + 1,
- mparse_strlevel(lvl),
- mparse_strerror(t));
+ if (NULL != (mparse_msg = mparse_strerror(t)))
+ fprintf(stderr, ": %s", mparse_msg);
if (msg)
fprintf(stderr, ": %s", msg);