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