xref: /titanic_50/usr/src/cmd/mandoc/main.c (revision 95c635efb7c3b86efc493e0447eaec7aecca3f0f)
1*95c635efSGarrett D'Amore /*	$Id: main.c,v 1.165 2011/10/06 22:29:12 kristaps Exp $ */
2*95c635efSGarrett D'Amore /*
3*95c635efSGarrett D'Amore  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4*95c635efSGarrett D'Amore  * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
5*95c635efSGarrett D'Amore  *
6*95c635efSGarrett D'Amore  * Permission to use, copy, modify, and distribute this software for any
7*95c635efSGarrett D'Amore  * purpose with or without fee is hereby granted, provided that the above
8*95c635efSGarrett D'Amore  * copyright notice and this permission notice appear in all copies.
9*95c635efSGarrett D'Amore  *
10*95c635efSGarrett D'Amore  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*95c635efSGarrett D'Amore  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*95c635efSGarrett D'Amore  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*95c635efSGarrett D'Amore  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*95c635efSGarrett D'Amore  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*95c635efSGarrett D'Amore  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*95c635efSGarrett D'Amore  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*95c635efSGarrett D'Amore  */
18*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H
19*95c635efSGarrett D'Amore #include "config.h"
20*95c635efSGarrett D'Amore #endif
21*95c635efSGarrett D'Amore 
22*95c635efSGarrett D'Amore #include <assert.h>
23*95c635efSGarrett D'Amore #include <stdio.h>
24*95c635efSGarrett D'Amore #include <stdint.h>
25*95c635efSGarrett D'Amore #include <stdlib.h>
26*95c635efSGarrett D'Amore #include <string.h>
27*95c635efSGarrett D'Amore #include <unistd.h>
28*95c635efSGarrett D'Amore 
29*95c635efSGarrett D'Amore #include "mandoc.h"
30*95c635efSGarrett D'Amore #include "main.h"
31*95c635efSGarrett D'Amore #include "mdoc.h"
32*95c635efSGarrett D'Amore #include "man.h"
33*95c635efSGarrett D'Amore 
34*95c635efSGarrett D'Amore #if !defined(__GNUC__) || (__GNUC__ < 2)
35*95c635efSGarrett D'Amore # if !defined(lint)
36*95c635efSGarrett D'Amore #  define __attribute__(x)
37*95c635efSGarrett D'Amore # endif
38*95c635efSGarrett D'Amore #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
39*95c635efSGarrett D'Amore 
40*95c635efSGarrett D'Amore typedef	void		(*out_mdoc)(void *, const struct mdoc *);
41*95c635efSGarrett D'Amore typedef	void		(*out_man)(void *, const struct man *);
42*95c635efSGarrett D'Amore typedef	void		(*out_free)(void *);
43*95c635efSGarrett D'Amore 
44*95c635efSGarrett D'Amore enum	outt {
45*95c635efSGarrett D'Amore 	OUTT_ASCII = 0,	/* -Tascii */
46*95c635efSGarrett D'Amore 	OUTT_LOCALE,	/* -Tlocale */
47*95c635efSGarrett D'Amore 	OUTT_UTF8,	/* -Tutf8 */
48*95c635efSGarrett D'Amore 	OUTT_TREE,	/* -Ttree */
49*95c635efSGarrett D'Amore 	OUTT_MAN,	/* -Tman */
50*95c635efSGarrett D'Amore 	OUTT_HTML,	/* -Thtml */
51*95c635efSGarrett D'Amore 	OUTT_XHTML,	/* -Txhtml */
52*95c635efSGarrett D'Amore 	OUTT_LINT,	/* -Tlint */
53*95c635efSGarrett D'Amore 	OUTT_PS,	/* -Tps */
54*95c635efSGarrett D'Amore 	OUTT_PDF	/* -Tpdf */
55*95c635efSGarrett D'Amore };
56*95c635efSGarrett D'Amore 
57*95c635efSGarrett D'Amore struct	curparse {
58*95c635efSGarrett D'Amore 	struct mparse	 *mp;
59*95c635efSGarrett D'Amore 	enum mandoclevel  wlevel;	/* ignore messages below this */
60*95c635efSGarrett D'Amore 	int		  wstop;	/* stop after a file with a warning */
61*95c635efSGarrett D'Amore 	enum outt	  outtype; 	/* which output to use */
62*95c635efSGarrett D'Amore 	out_mdoc	  outmdoc;	/* mdoc output ptr */
63*95c635efSGarrett D'Amore 	out_man	  	  outman;	/* man output ptr */
64*95c635efSGarrett D'Amore 	out_free	  outfree;	/* free output ptr */
65*95c635efSGarrett D'Amore 	void		 *outdata;	/* data for output */
66*95c635efSGarrett D'Amore 	char		  outopts[BUFSIZ]; /* buf of output opts */
67*95c635efSGarrett D'Amore };
68*95c635efSGarrett D'Amore 
69*95c635efSGarrett D'Amore static	int		  moptions(enum mparset *, char *);
70*95c635efSGarrett D'Amore static	void		  mmsg(enum mandocerr, enum mandoclevel,
71*95c635efSGarrett D'Amore 				const char *, int, int, const char *);
72*95c635efSGarrett D'Amore static	void		  parse(struct curparse *, int,
73*95c635efSGarrett D'Amore 				const char *, enum mandoclevel *);
74*95c635efSGarrett D'Amore static	int		  toptions(struct curparse *, char *);
75*95c635efSGarrett D'Amore static	void		  usage(void) __attribute__((noreturn));
76*95c635efSGarrett D'Amore static	void		  version(void) __attribute__((noreturn));
77*95c635efSGarrett D'Amore static	int		  woptions(struct curparse *, char *);
78*95c635efSGarrett D'Amore 
79*95c635efSGarrett D'Amore static	const char	 *progname;
80*95c635efSGarrett D'Amore 
81*95c635efSGarrett D'Amore int
82*95c635efSGarrett D'Amore main(int argc, char *argv[])
83*95c635efSGarrett D'Amore {
84*95c635efSGarrett D'Amore 	int		 c;
85*95c635efSGarrett D'Amore 	struct curparse	 curp;
86*95c635efSGarrett D'Amore 	enum mparset	 type;
87*95c635efSGarrett D'Amore 	enum mandoclevel rc;
88*95c635efSGarrett D'Amore 
89*95c635efSGarrett D'Amore 	progname = strrchr(argv[0], '/');
90*95c635efSGarrett D'Amore 	if (progname == NULL)
91*95c635efSGarrett D'Amore 		progname = argv[0];
92*95c635efSGarrett D'Amore 	else
93*95c635efSGarrett D'Amore 		++progname;
94*95c635efSGarrett D'Amore 
95*95c635efSGarrett D'Amore 	memset(&curp, 0, sizeof(struct curparse));
96*95c635efSGarrett D'Amore 
97*95c635efSGarrett D'Amore 	type = MPARSE_AUTO;
98*95c635efSGarrett D'Amore 	curp.outtype = OUTT_ASCII;
99*95c635efSGarrett D'Amore 	curp.wlevel  = MANDOCLEVEL_FATAL;
100*95c635efSGarrett D'Amore 
101*95c635efSGarrett D'Amore 	/* LINTED */
102*95c635efSGarrett D'Amore 	while (-1 != (c = getopt(argc, argv, "m:O:T:VW:")))
103*95c635efSGarrett D'Amore 		switch (c) {
104*95c635efSGarrett D'Amore 		case ('m'):
105*95c635efSGarrett D'Amore 			if ( ! moptions(&type, optarg))
106*95c635efSGarrett D'Amore 				return((int)MANDOCLEVEL_BADARG);
107*95c635efSGarrett D'Amore 			break;
108*95c635efSGarrett D'Amore 		case ('O'):
109*95c635efSGarrett D'Amore 			(void)strlcat(curp.outopts, optarg, BUFSIZ);
110*95c635efSGarrett D'Amore 			(void)strlcat(curp.outopts, ",", BUFSIZ);
111*95c635efSGarrett D'Amore 			break;
112*95c635efSGarrett D'Amore 		case ('T'):
113*95c635efSGarrett D'Amore 			if ( ! toptions(&curp, optarg))
114*95c635efSGarrett D'Amore 				return((int)MANDOCLEVEL_BADARG);
115*95c635efSGarrett D'Amore 			break;
116*95c635efSGarrett D'Amore 		case ('W'):
117*95c635efSGarrett D'Amore 			if ( ! woptions(&curp, optarg))
118*95c635efSGarrett D'Amore 				return((int)MANDOCLEVEL_BADARG);
119*95c635efSGarrett D'Amore 			break;
120*95c635efSGarrett D'Amore 		case ('V'):
121*95c635efSGarrett D'Amore 			version();
122*95c635efSGarrett D'Amore 			/* NOTREACHED */
123*95c635efSGarrett D'Amore 		default:
124*95c635efSGarrett D'Amore 			usage();
125*95c635efSGarrett D'Amore 			/* NOTREACHED */
126*95c635efSGarrett D'Amore 		}
127*95c635efSGarrett D'Amore 
128*95c635efSGarrett D'Amore 	curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp);
129*95c635efSGarrett D'Amore 
130*95c635efSGarrett D'Amore 	/*
131*95c635efSGarrett D'Amore 	 * Conditionally start up the lookaside buffer before parsing.
132*95c635efSGarrett D'Amore 	 */
133*95c635efSGarrett D'Amore 	if (OUTT_MAN == curp.outtype)
134*95c635efSGarrett D'Amore 		mparse_keep(curp.mp);
135*95c635efSGarrett D'Amore 
136*95c635efSGarrett D'Amore 	argc -= optind;
137*95c635efSGarrett D'Amore 	argv += optind;
138*95c635efSGarrett D'Amore 
139*95c635efSGarrett D'Amore 	rc = MANDOCLEVEL_OK;
140*95c635efSGarrett D'Amore 
141*95c635efSGarrett D'Amore 	if (NULL == *argv)
142*95c635efSGarrett D'Amore 		parse(&curp, STDIN_FILENO, "<stdin>", &rc);
143*95c635efSGarrett D'Amore 
144*95c635efSGarrett D'Amore 	while (*argv) {
145*95c635efSGarrett D'Amore 		parse(&curp, -1, *argv, &rc);
146*95c635efSGarrett D'Amore 		if (MANDOCLEVEL_OK != rc && curp.wstop)
147*95c635efSGarrett D'Amore 			break;
148*95c635efSGarrett D'Amore 		++argv;
149*95c635efSGarrett D'Amore 	}
150*95c635efSGarrett D'Amore 
151*95c635efSGarrett D'Amore 	if (curp.outfree)
152*95c635efSGarrett D'Amore 		(*curp.outfree)(curp.outdata);
153*95c635efSGarrett D'Amore 	if (curp.mp)
154*95c635efSGarrett D'Amore 		mparse_free(curp.mp);
155*95c635efSGarrett D'Amore 
156*95c635efSGarrett D'Amore 	return((int)rc);
157*95c635efSGarrett D'Amore }
158*95c635efSGarrett D'Amore 
159*95c635efSGarrett D'Amore static void
160*95c635efSGarrett D'Amore version(void)
161*95c635efSGarrett D'Amore {
162*95c635efSGarrett D'Amore 
163*95c635efSGarrett D'Amore 	printf("%s %s\n", progname, VERSION);
164*95c635efSGarrett D'Amore 	exit((int)MANDOCLEVEL_OK);
165*95c635efSGarrett D'Amore }
166*95c635efSGarrett D'Amore 
167*95c635efSGarrett D'Amore static void
168*95c635efSGarrett D'Amore usage(void)
169*95c635efSGarrett D'Amore {
170*95c635efSGarrett D'Amore 
171*95c635efSGarrett D'Amore 	fprintf(stderr, "usage: %s "
172*95c635efSGarrett D'Amore 			"[-V] "
173*95c635efSGarrett D'Amore 			"[-foption] "
174*95c635efSGarrett D'Amore 			"[-mformat] "
175*95c635efSGarrett D'Amore 			"[-Ooption] "
176*95c635efSGarrett D'Amore 			"[-Toutput] "
177*95c635efSGarrett D'Amore 			"[-Wlevel] "
178*95c635efSGarrett D'Amore 			"[file...]\n",
179*95c635efSGarrett D'Amore 			progname);
180*95c635efSGarrett D'Amore 
181*95c635efSGarrett D'Amore 	exit((int)MANDOCLEVEL_BADARG);
182*95c635efSGarrett D'Amore }
183*95c635efSGarrett D'Amore 
184*95c635efSGarrett D'Amore static void
185*95c635efSGarrett D'Amore parse(struct curparse *curp, int fd,
186*95c635efSGarrett D'Amore 		const char *file, enum mandoclevel *level)
187*95c635efSGarrett D'Amore {
188*95c635efSGarrett D'Amore 	enum mandoclevel  rc;
189*95c635efSGarrett D'Amore 	struct mdoc	 *mdoc;
190*95c635efSGarrett D'Amore 	struct man	 *man;
191*95c635efSGarrett D'Amore 
192*95c635efSGarrett D'Amore 	/* Begin by parsing the file itself. */
193*95c635efSGarrett D'Amore 
194*95c635efSGarrett D'Amore 	assert(file);
195*95c635efSGarrett D'Amore 	assert(fd >= -1);
196*95c635efSGarrett D'Amore 
197*95c635efSGarrett D'Amore 	rc = mparse_readfd(curp->mp, fd, file);
198*95c635efSGarrett D'Amore 
199*95c635efSGarrett D'Amore 	/* Stop immediately if the parse has failed. */
200*95c635efSGarrett D'Amore 
201*95c635efSGarrett D'Amore 	if (MANDOCLEVEL_FATAL <= rc)
202*95c635efSGarrett D'Amore 		goto cleanup;
203*95c635efSGarrett D'Amore 
204*95c635efSGarrett D'Amore 	/*
205*95c635efSGarrett D'Amore 	 * With -Wstop and warnings or errors of at least the requested
206*95c635efSGarrett D'Amore 	 * level, do not produce output.
207*95c635efSGarrett D'Amore 	 */
208*95c635efSGarrett D'Amore 
209*95c635efSGarrett D'Amore 	if (MANDOCLEVEL_OK != rc && curp->wstop)
210*95c635efSGarrett D'Amore 		goto cleanup;
211*95c635efSGarrett D'Amore 
212*95c635efSGarrett D'Amore 	/* If unset, allocate output dev now (if applicable). */
213*95c635efSGarrett D'Amore 
214*95c635efSGarrett D'Amore 	if ( ! (curp->outman && curp->outmdoc)) {
215*95c635efSGarrett D'Amore 		switch (curp->outtype) {
216*95c635efSGarrett D'Amore 		case (OUTT_XHTML):
217*95c635efSGarrett D'Amore 			curp->outdata = xhtml_alloc(curp->outopts);
218*95c635efSGarrett D'Amore 			curp->outfree = html_free;
219*95c635efSGarrett D'Amore 			break;
220*95c635efSGarrett D'Amore 		case (OUTT_HTML):
221*95c635efSGarrett D'Amore 			curp->outdata = html_alloc(curp->outopts);
222*95c635efSGarrett D'Amore 			curp->outfree = html_free;
223*95c635efSGarrett D'Amore 			break;
224*95c635efSGarrett D'Amore 		case (OUTT_UTF8):
225*95c635efSGarrett D'Amore 			curp->outdata = utf8_alloc(curp->outopts);
226*95c635efSGarrett D'Amore 			curp->outfree = ascii_free;
227*95c635efSGarrett D'Amore 			break;
228*95c635efSGarrett D'Amore 		case (OUTT_LOCALE):
229*95c635efSGarrett D'Amore 			curp->outdata = locale_alloc(curp->outopts);
230*95c635efSGarrett D'Amore 			curp->outfree = ascii_free;
231*95c635efSGarrett D'Amore 			break;
232*95c635efSGarrett D'Amore 		case (OUTT_ASCII):
233*95c635efSGarrett D'Amore 			curp->outdata = ascii_alloc(curp->outopts);
234*95c635efSGarrett D'Amore 			curp->outfree = ascii_free;
235*95c635efSGarrett D'Amore 			break;
236*95c635efSGarrett D'Amore 		case (OUTT_PDF):
237*95c635efSGarrett D'Amore 			curp->outdata = pdf_alloc(curp->outopts);
238*95c635efSGarrett D'Amore 			curp->outfree = pspdf_free;
239*95c635efSGarrett D'Amore 			break;
240*95c635efSGarrett D'Amore 		case (OUTT_PS):
241*95c635efSGarrett D'Amore 			curp->outdata = ps_alloc(curp->outopts);
242*95c635efSGarrett D'Amore 			curp->outfree = pspdf_free;
243*95c635efSGarrett D'Amore 			break;
244*95c635efSGarrett D'Amore 		default:
245*95c635efSGarrett D'Amore 			break;
246*95c635efSGarrett D'Amore 		}
247*95c635efSGarrett D'Amore 
248*95c635efSGarrett D'Amore 		switch (curp->outtype) {
249*95c635efSGarrett D'Amore 		case (OUTT_HTML):
250*95c635efSGarrett D'Amore 			/* FALLTHROUGH */
251*95c635efSGarrett D'Amore 		case (OUTT_XHTML):
252*95c635efSGarrett D'Amore 			curp->outman = html_man;
253*95c635efSGarrett D'Amore 			curp->outmdoc = html_mdoc;
254*95c635efSGarrett D'Amore 			break;
255*95c635efSGarrett D'Amore 		case (OUTT_TREE):
256*95c635efSGarrett D'Amore 			curp->outman = tree_man;
257*95c635efSGarrett D'Amore 			curp->outmdoc = tree_mdoc;
258*95c635efSGarrett D'Amore 			break;
259*95c635efSGarrett D'Amore 		case (OUTT_MAN):
260*95c635efSGarrett D'Amore 			curp->outmdoc = man_mdoc;
261*95c635efSGarrett D'Amore 			curp->outman = man_man;
262*95c635efSGarrett D'Amore 			break;
263*95c635efSGarrett D'Amore 		case (OUTT_PDF):
264*95c635efSGarrett D'Amore 			/* FALLTHROUGH */
265*95c635efSGarrett D'Amore 		case (OUTT_ASCII):
266*95c635efSGarrett D'Amore 			/* FALLTHROUGH */
267*95c635efSGarrett D'Amore 		case (OUTT_UTF8):
268*95c635efSGarrett D'Amore 			/* FALLTHROUGH */
269*95c635efSGarrett D'Amore 		case (OUTT_LOCALE):
270*95c635efSGarrett D'Amore 			/* FALLTHROUGH */
271*95c635efSGarrett D'Amore 		case (OUTT_PS):
272*95c635efSGarrett D'Amore 			curp->outman = terminal_man;
273*95c635efSGarrett D'Amore 			curp->outmdoc = terminal_mdoc;
274*95c635efSGarrett D'Amore 			break;
275*95c635efSGarrett D'Amore 		default:
276*95c635efSGarrett D'Amore 			break;
277*95c635efSGarrett D'Amore 		}
278*95c635efSGarrett D'Amore 	}
279*95c635efSGarrett D'Amore 
280*95c635efSGarrett D'Amore 	mparse_result(curp->mp, &mdoc, &man);
281*95c635efSGarrett D'Amore 
282*95c635efSGarrett D'Amore 	/* Execute the out device, if it exists. */
283*95c635efSGarrett D'Amore 
284*95c635efSGarrett D'Amore 	if (man && curp->outman)
285*95c635efSGarrett D'Amore 		(*curp->outman)(curp->outdata, man);
286*95c635efSGarrett D'Amore 	if (mdoc && curp->outmdoc)
287*95c635efSGarrett D'Amore 		(*curp->outmdoc)(curp->outdata, mdoc);
288*95c635efSGarrett D'Amore 
289*95c635efSGarrett D'Amore  cleanup:
290*95c635efSGarrett D'Amore 
291*95c635efSGarrett D'Amore 	mparse_reset(curp->mp);
292*95c635efSGarrett D'Amore 
293*95c635efSGarrett D'Amore 	if (*level < rc)
294*95c635efSGarrett D'Amore 		*level = rc;
295*95c635efSGarrett D'Amore }
296*95c635efSGarrett D'Amore 
297*95c635efSGarrett D'Amore static int
298*95c635efSGarrett D'Amore moptions(enum mparset *tflags, char *arg)
299*95c635efSGarrett D'Amore {
300*95c635efSGarrett D'Amore 
301*95c635efSGarrett D'Amore 	if (0 == strcmp(arg, "doc"))
302*95c635efSGarrett D'Amore 		*tflags = MPARSE_MDOC;
303*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "andoc"))
304*95c635efSGarrett D'Amore 		*tflags = MPARSE_AUTO;
305*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "an"))
306*95c635efSGarrett D'Amore 		*tflags = MPARSE_MAN;
307*95c635efSGarrett D'Amore 	else {
308*95c635efSGarrett D'Amore 		fprintf(stderr, "%s: Bad argument\n", arg);
309*95c635efSGarrett D'Amore 		return(0);
310*95c635efSGarrett D'Amore 	}
311*95c635efSGarrett D'Amore 
312*95c635efSGarrett D'Amore 	return(1);
313*95c635efSGarrett D'Amore }
314*95c635efSGarrett D'Amore 
315*95c635efSGarrett D'Amore static int
316*95c635efSGarrett D'Amore toptions(struct curparse *curp, char *arg)
317*95c635efSGarrett D'Amore {
318*95c635efSGarrett D'Amore 
319*95c635efSGarrett D'Amore 	if (0 == strcmp(arg, "ascii"))
320*95c635efSGarrett D'Amore 		curp->outtype = OUTT_ASCII;
321*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "lint")) {
322*95c635efSGarrett D'Amore 		curp->outtype = OUTT_LINT;
323*95c635efSGarrett D'Amore 		curp->wlevel  = MANDOCLEVEL_WARNING;
324*95c635efSGarrett D'Amore 	} else if (0 == strcmp(arg, "tree"))
325*95c635efSGarrett D'Amore 		curp->outtype = OUTT_TREE;
326*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "man"))
327*95c635efSGarrett D'Amore 		curp->outtype = OUTT_MAN;
328*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "html"))
329*95c635efSGarrett D'Amore 		curp->outtype = OUTT_HTML;
330*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "utf8"))
331*95c635efSGarrett D'Amore 		curp->outtype = OUTT_UTF8;
332*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "locale"))
333*95c635efSGarrett D'Amore 		curp->outtype = OUTT_LOCALE;
334*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "xhtml"))
335*95c635efSGarrett D'Amore 		curp->outtype = OUTT_XHTML;
336*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "ps"))
337*95c635efSGarrett D'Amore 		curp->outtype = OUTT_PS;
338*95c635efSGarrett D'Amore 	else if (0 == strcmp(arg, "pdf"))
339*95c635efSGarrett D'Amore 		curp->outtype = OUTT_PDF;
340*95c635efSGarrett D'Amore 	else {
341*95c635efSGarrett D'Amore 		fprintf(stderr, "%s: Bad argument\n", arg);
342*95c635efSGarrett D'Amore 		return(0);
343*95c635efSGarrett D'Amore 	}
344*95c635efSGarrett D'Amore 
345*95c635efSGarrett D'Amore 	return(1);
346*95c635efSGarrett D'Amore }
347*95c635efSGarrett D'Amore 
348*95c635efSGarrett D'Amore static int
349*95c635efSGarrett D'Amore woptions(struct curparse *curp, char *arg)
350*95c635efSGarrett D'Amore {
351*95c635efSGarrett D'Amore 	char		*v, *o;
352*95c635efSGarrett D'Amore 	const char	*toks[6];
353*95c635efSGarrett D'Amore 
354*95c635efSGarrett D'Amore 	toks[0] = "stop";
355*95c635efSGarrett D'Amore 	toks[1] = "all";
356*95c635efSGarrett D'Amore 	toks[2] = "warning";
357*95c635efSGarrett D'Amore 	toks[3] = "error";
358*95c635efSGarrett D'Amore 	toks[4] = "fatal";
359*95c635efSGarrett D'Amore 	toks[5] = NULL;
360*95c635efSGarrett D'Amore 
361*95c635efSGarrett D'Amore 	while (*arg) {
362*95c635efSGarrett D'Amore 		o = arg;
363*95c635efSGarrett D'Amore 		switch (getsubopt(&arg, UNCONST(toks), &v)) {
364*95c635efSGarrett D'Amore 		case (0):
365*95c635efSGarrett D'Amore 			curp->wstop = 1;
366*95c635efSGarrett D'Amore 			break;
367*95c635efSGarrett D'Amore 		case (1):
368*95c635efSGarrett D'Amore 			/* FALLTHROUGH */
369*95c635efSGarrett D'Amore 		case (2):
370*95c635efSGarrett D'Amore 			curp->wlevel = MANDOCLEVEL_WARNING;
371*95c635efSGarrett D'Amore 			break;
372*95c635efSGarrett D'Amore 		case (3):
373*95c635efSGarrett D'Amore 			curp->wlevel = MANDOCLEVEL_ERROR;
374*95c635efSGarrett D'Amore 			break;
375*95c635efSGarrett D'Amore 		case (4):
376*95c635efSGarrett D'Amore 			curp->wlevel = MANDOCLEVEL_FATAL;
377*95c635efSGarrett D'Amore 			break;
378*95c635efSGarrett D'Amore 		default:
379*95c635efSGarrett D'Amore 			fprintf(stderr, "-W%s: Bad argument\n", o);
380*95c635efSGarrett D'Amore 			return(0);
381*95c635efSGarrett D'Amore 		}
382*95c635efSGarrett D'Amore 	}
383*95c635efSGarrett D'Amore 
384*95c635efSGarrett D'Amore 	return(1);
385*95c635efSGarrett D'Amore }
386*95c635efSGarrett D'Amore 
387*95c635efSGarrett D'Amore static void
388*95c635efSGarrett D'Amore mmsg(enum mandocerr t, enum mandoclevel lvl,
389*95c635efSGarrett D'Amore 		const char *file, int line, int col, const char *msg)
390*95c635efSGarrett D'Amore {
391*95c635efSGarrett D'Amore 
392*95c635efSGarrett D'Amore 	fprintf(stderr, "%s:%d:%d: %s: %s",
393*95c635efSGarrett D'Amore 			file, line, col + 1,
394*95c635efSGarrett D'Amore 			mparse_strlevel(lvl),
395*95c635efSGarrett D'Amore 			mparse_strerror(t));
396*95c635efSGarrett D'Amore 
397*95c635efSGarrett D'Amore 	if (msg)
398*95c635efSGarrett D'Amore 		fprintf(stderr, ": %s", msg);
399*95c635efSGarrett D'Amore 
400*95c635efSGarrett D'Amore 	fputc('\n', stderr);
401*95c635efSGarrett D'Amore }
402