Annotation of mandoc/main.c, Revision 1.182
1.182 ! schwarze 1: /* $Id: main.c,v 1.181 2014/08/20 21:04:35 schwarze Exp $ */
1.1 kristaps 2: /*
1.133 schwarze 3: * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.170 schwarze 4: * Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
1.169 schwarze 5: * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
1.1 kristaps 6: *
7: * Permission to use, copy, modify, and distribute this software for any
1.25 kristaps 8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 10: *
1.25 kristaps 11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 kristaps 18: */
1.58 kristaps 19: #include "config.h"
1.178 schwarze 20:
21: #include <sys/types.h>
1.58 kristaps 22:
1.1 kristaps 23: #include <assert.h>
24: #include <stdio.h>
1.45 kristaps 25: #include <stdint.h>
1.1 kristaps 26: #include <stdlib.h>
27: #include <string.h>
28: #include <unistd.h>
29:
1.71 kristaps 30: #include "mandoc.h"
1.172 schwarze 31: #include "mandoc_aux.h"
1.90 kristaps 32: #include "main.h"
1.1 kristaps 33: #include "mdoc.h"
1.10 kristaps 34: #include "man.h"
1.180 schwarze 35: #include "manpath.h"
36: #include "mansearch.h"
1.101 joerg 37:
1.55 kristaps 38: #if !defined(__GNUC__) || (__GNUC__ < 2)
1.56 kristaps 39: # if !defined(lint)
40: # define __attribute__(x)
41: # endif
1.55 kristaps 42: #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
1.16 kristaps 43:
1.181 schwarze 44: enum outmode {
45: OUTMODE_DEF = 0,
46: OUTMODE_FLN,
47: OUTMODE_LST,
48: OUTMODE_ALL,
49: OUTMODE_INT,
50: OUTMODE_ONE
51: };
52:
1.42 kristaps 53: typedef void (*out_mdoc)(void *, const struct mdoc *);
54: typedef void (*out_man)(void *, const struct man *);
1.22 kristaps 55: typedef void (*out_free)(void *);
56:
1.19 kristaps 57: enum outt {
1.154 kristaps 58: OUTT_ASCII = 0, /* -Tascii */
1.162 kristaps 59: OUTT_LOCALE, /* -Tlocale */
1.163 kristaps 60: OUTT_UTF8, /* -Tutf8 */
1.154 kristaps 61: OUTT_TREE, /* -Ttree */
1.164 schwarze 62: OUTT_MAN, /* -Tman */
1.154 kristaps 63: OUTT_HTML, /* -Thtml */
64: OUTT_XHTML, /* -Txhtml */
65: OUTT_LINT, /* -Tlint */
66: OUTT_PS, /* -Tps */
67: OUTT_PDF /* -Tpdf */
1.19 kristaps 68: };
69:
1.5 kristaps 70: struct curparse {
1.154 kristaps 71: struct mparse *mp;
1.148 kristaps 72: enum mandoclevel wlevel; /* ignore messages below this */
73: int wstop; /* stop after a file with a warning */
1.173 schwarze 74: enum outt outtype; /* which output to use */
1.79 kristaps 75: out_mdoc outmdoc; /* mdoc output ptr */
1.173 schwarze 76: out_man outman; /* man output ptr */
1.79 kristaps 77: out_free outfree; /* free output ptr */
78: void *outdata; /* data for output */
79: char outopts[BUFSIZ]; /* buf of output opts */
80: };
81:
1.170 schwarze 82: static int moptions(int *, char *);
1.155 kristaps 83: static void mmsg(enum mandocerr, enum mandoclevel,
84: const char *, int, int, const char *);
1.173 schwarze 85: static void parse(struct curparse *, int,
1.154 kristaps 86: const char *, enum mandoclevel *);
1.66 kristaps 87: static int toptions(struct curparse *, char *);
1.180 schwarze 88: static void usage(enum argmode) __attribute__((noreturn));
1.55 kristaps 89: static void version(void) __attribute__((noreturn));
1.103 schwarze 90: static int woptions(struct curparse *, char *);
1.1 kristaps 91:
1.182 ! schwarze 92: static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
1.54 kristaps 93: static const char *progname;
1.1 kristaps 94:
1.173 schwarze 95:
1.1 kristaps 96: int
97: main(int argc, char *argv[])
98: {
1.5 kristaps 99: struct curparse curp;
1.180 schwarze 100: struct mansearch search;
101: struct manpaths paths;
102: char *conf_file, *defpaths, *auxpaths;
103: char *defos;
104: #if HAVE_SQLITE3
105: struct manpage *res;
1.182 ! schwarze 106: char **auxargv;
! 107: size_t isec, i, sz;
! 108: int prio, best_prio;
! 109: char sec;
1.180 schwarze 110: #endif
111: enum mandoclevel rc;
1.181 schwarze 112: enum outmode outmode;
1.180 schwarze 113: int show_usage;
1.170 schwarze 114: int options;
1.180 schwarze 115: int c;
1.1 kristaps 116:
1.54 kristaps 117: progname = strrchr(argv[0], '/');
118: if (progname == NULL)
119: progname = argv[0];
120: else
121: ++progname;
1.179 schwarze 122:
1.180 schwarze 123: /* Search options. */
124:
125: memset(&paths, 0, sizeof(struct manpaths));
126: conf_file = defpaths = auxpaths = NULL;
127:
128: memset(&search, 0, sizeof(struct mansearch));
129: search.outkey = "Nd";
130:
131: if (strcmp(progname, "man") == 0)
132: search.argmode = ARG_NAME;
133: else if (strncmp(progname, "apropos", 7) == 0)
134: search.argmode = ARG_EXPR;
135: else if (strncmp(progname, "whatis", 6) == 0)
136: search.argmode = ARG_WORD;
137: else
138: search.argmode = ARG_FILE;
139:
140: /* Parser and formatter options. */
1.54 kristaps 141:
1.51 kristaps 142: memset(&curp, 0, sizeof(struct curparse));
1.22 kristaps 143: curp.outtype = OUTT_ASCII;
1.103 schwarze 144: curp.wlevel = MANDOCLEVEL_FATAL;
1.180 schwarze 145: options = MPARSE_SO;
1.166 schwarze 146: defos = NULL;
1.19 kristaps 147:
1.180 schwarze 148: show_usage = 0;
1.181 schwarze 149: outmode = OUTMODE_DEF;
150: while (-1 != (c = getopt(argc, argv, "aC:fI:ikM:m:O:S:s:T:VW:w"))) {
1.1 kristaps 151: switch (c) {
1.181 schwarze 152: case 'a':
153: outmode = OUTMODE_ALL;
154: break;
1.180 schwarze 155: case 'C':
156: conf_file = optarg;
157: break;
158: case 'f':
159: search.argmode = ARG_WORD;
160: break;
1.173 schwarze 161: case 'I':
1.166 schwarze 162: if (strncmp(optarg, "os=", 3)) {
1.173 schwarze 163: fprintf(stderr,
1.176 schwarze 164: "%s: -I%s: Bad argument\n",
165: progname, optarg);
1.166 schwarze 166: return((int)MANDOCLEVEL_BADARG);
167: }
168: if (defos) {
1.173 schwarze 169: fprintf(stderr,
1.176 schwarze 170: "%s: -I%s: Duplicate argument\n",
171: progname, optarg);
1.166 schwarze 172: return((int)MANDOCLEVEL_BADARG);
173: }
174: defos = mandoc_strdup(optarg + 3);
175: break;
1.181 schwarze 176: case 'i':
177: outmode = OUTMODE_INT;
178: break;
1.180 schwarze 179: case 'k':
180: search.argmode = ARG_EXPR;
181: break;
182: case 'M':
183: defpaths = optarg;
184: break;
1.173 schwarze 185: case 'm':
1.180 schwarze 186: auxpaths = optarg;
1.10 kristaps 187: break;
1.173 schwarze 188: case 'O':
1.180 schwarze 189: search.outkey = optarg;
1.49 kristaps 190: (void)strlcat(curp.outopts, optarg, BUFSIZ);
191: (void)strlcat(curp.outopts, ",", BUFSIZ);
1.44 kristaps 192: break;
1.180 schwarze 193: case 'S':
194: search.arch = optarg;
195: break;
196: case 's':
197: search.sec = optarg;
198: break;
1.173 schwarze 199: case 'T':
1.60 kristaps 200: if ( ! toptions(&curp, optarg))
1.105 kristaps 201: return((int)MANDOCLEVEL_BADARG);
1.1 kristaps 202: break;
1.173 schwarze 203: case 'W':
1.103 schwarze 204: if ( ! woptions(&curp, optarg))
1.105 kristaps 205: return((int)MANDOCLEVEL_BADARG);
1.1 kristaps 206: break;
1.181 schwarze 207: case 'w':
208: outmode = OUTMODE_FLN;
209: break;
1.173 schwarze 210: case 'V':
1.1 kristaps 211: version();
212: /* NOTREACHED */
213: default:
1.180 schwarze 214: show_usage = 1;
215: break;
1.1 kristaps 216: }
1.180 schwarze 217: }
218:
219: if (show_usage)
220: usage(search.argmode);
221:
1.181 schwarze 222: if (outmode == OUTMODE_DEF) {
223: switch (search.argmode) {
224: case ARG_FILE:
225: outmode = OUTMODE_ALL;
226: break;
227: case ARG_NAME:
228: outmode = OUTMODE_ONE;
229: break;
230: default:
231: outmode = OUTMODE_LST;
232: break;
233: }
234: }
235:
1.180 schwarze 236: argc -= optind;
237: argv += optind;
1.182 ! schwarze 238: #if HAVE_SQLITE3
! 239: auxargv = NULL;
! 240: #endif
! 241:
! 242: rc = MANDOCLEVEL_OK;
1.180 schwarze 243:
244: /* man(1), whatis(1), apropos(1) */
245:
246: if (search.argmode != ARG_FILE) {
247: #if HAVE_SQLITE3
248: if (argc == 0)
249: usage(search.argmode);
1.182 ! schwarze 250:
! 251: /* Access the mandoc database. */
! 252:
1.180 schwarze 253: manpath_parse(&paths, conf_file, defpaths, auxpaths);
254: mansearch_setup(1);
255: if( ! mansearch(&search, &paths, argc, argv, &res, &sz))
256: usage(search.argmode);
257: manpath_free(&paths);
1.182 ! schwarze 258:
! 259: /*
! 260: * For standard man(1) and -a output mode,
! 261: * prepare for copying filename pointers
! 262: * into the program parameter array.
! 263: */
! 264:
! 265: if (outmode == OUTMODE_ONE) {
! 266: argc = 1;
! 267: argv[0] = res[0].file;
! 268: argv[1] = NULL;
! 269: best_prio = 10;
! 270: } else if (outmode == OUTMODE_ALL) {
! 271: argc = (int)sz;
! 272: argv = auxargv = mandoc_reallocarray(
! 273: NULL, sz + 1, sizeof(char *));
! 274: argv[argc] = NULL;
! 275: }
! 276:
! 277: /* Iterate all matching manuals. */
! 278:
1.181 schwarze 279: for (i = 0; i < sz; i++) {
280: if (outmode == OUTMODE_FLN)
281: puts(res[i].file);
1.182 ! schwarze 282: else if (outmode == OUTMODE_LST)
1.181 schwarze 283: printf("%s - %s\n", res[i].names,
284: res[i].output == NULL ? "" :
285: res[i].output);
1.182 ! schwarze 286: else if (outmode == OUTMODE_ALL)
! 287: argv[i] = res[i].file;
! 288: else {
! 289: /* Search for the best section. */
! 290: isec = strcspn(res[i].file, "123456789");
! 291: sec = res[i].file[isec];
! 292: if ('\0' == sec)
! 293: continue;
! 294: prio = sec_prios[sec - '1'];
! 295: if (prio >= best_prio)
! 296: continue;
! 297: best_prio = prio;
! 298: argv[0] = res[i].file;
! 299: }
1.181 schwarze 300: }
1.182 ! schwarze 301:
! 302: /*
! 303: * For man(1), -a and -i output mode, fall through
! 304: * to the main mandoc(1) code iterating files
! 305: * and running the parsers on each of them.
! 306: */
! 307:
! 308: if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST)
! 309: goto out;
1.180 schwarze 310: #else
311: fputs("mandoc: database support not compiled in\n",
312: stderr);
313: return((int)MANDOCLEVEL_BADARG);
314: #endif
315: }
316:
317: /* mandoc(1) */
318:
319: if ( ! moptions(&options, auxpaths))
320: return((int)MANDOCLEVEL_BADARG);
1.1 kristaps 321:
1.170 schwarze 322: curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
1.154 kristaps 323:
1.165 kristaps 324: /*
325: * Conditionally start up the lookaside buffer before parsing.
326: */
327: if (OUTT_MAN == curp.outtype)
328: mparse_keep(curp.mp);
329:
1.154 kristaps 330: if (NULL == *argv)
331: parse(&curp, STDIN_FILENO, "<stdin>", &rc);
1.64 kristaps 332:
333: while (*argv) {
1.154 kristaps 334: parse(&curp, -1, *argv, &rc);
335: if (MANDOCLEVEL_OK != rc && curp.wstop)
1.64 kristaps 336: break;
337: ++argv;
1.1 kristaps 338: }
339:
1.22 kristaps 340: if (curp.outfree)
341: (*curp.outfree)(curp.outdata);
1.154 kristaps 342: if (curp.mp)
343: mparse_free(curp.mp);
1.182 ! schwarze 344:
! 345: #if HAVE_SQLITE3
! 346: out:
! 347: if (search.argmode != ARG_FILE) {
! 348: mansearch_free(res, sz);
! 349: mansearch_setup(0);
! 350: free(auxargv);
! 351: }
! 352: #endif
! 353:
1.166 schwarze 354: free(defos);
1.1 kristaps 355:
1.154 kristaps 356: return((int)rc);
1.1 kristaps 357: }
358:
1.55 kristaps 359: static void
1.1 kristaps 360: version(void)
361: {
362:
1.180 schwarze 363: printf("mandoc %s\n", VERSION);
1.105 kristaps 364: exit((int)MANDOCLEVEL_OK);
1.1 kristaps 365: }
366:
1.55 kristaps 367: static void
1.180 schwarze 368: usage(enum argmode argmode)
1.1 kristaps 369: {
370:
1.180 schwarze 371: switch (argmode) {
372: case ARG_FILE:
373: fputs("usage: mandoc [-V] [-Ios=name] [-mformat]"
374: " [-Ooption] [-Toutput] [-Wlevel]\n"
375: "\t [file ...]\n", stderr);
376: break;
377: case ARG_NAME:
378: fputs("usage: man [-acfhkVw] [-C file] "
379: "[-M path] [-m path] [-S arch] [-s section]\n"
380: "\t [section] name ...\n", stderr);
381: break;
382: case ARG_WORD:
383: fputs("usage: whatis [-V] [-C file] [-M path] [-m path] "
384: "[-S arch] [-s section] name ...\n", stderr);
385: break;
386: case ARG_EXPR:
387: fputs("usage: apropos [-V] [-C file] [-M path] [-m path] "
388: "[-O outkey] [-S arch]\n"
389: "\t [-s section] expression ...\n", stderr);
390: break;
391: }
1.105 kristaps 392: exit((int)MANDOCLEVEL_BADARG);
1.68 joerg 393: }
394:
1.64 kristaps 395: static void
1.173 schwarze 396: parse(struct curparse *curp, int fd, const char *file,
397: enum mandoclevel *level)
1.1 kristaps 398: {
1.154 kristaps 399: enum mandoclevel rc;
400: struct mdoc *mdoc;
401: struct man *man;
1.112 kristaps 402:
1.154 kristaps 403: /* Begin by parsing the file itself. */
1.112 kristaps 404:
1.154 kristaps 405: assert(file);
406: assert(fd >= -1);
1.112 kristaps 407:
1.154 kristaps 408: rc = mparse_readfd(curp->mp, fd, file);
1.112 kristaps 409:
1.154 kristaps 410: /* Stop immediately if the parse has failed. */
1.92 kristaps 411:
1.154 kristaps 412: if (MANDOCLEVEL_FATAL <= rc)
1.111 kristaps 413: goto cleanup;
414:
1.1 kristaps 415: /*
1.154 kristaps 416: * With -Wstop and warnings or errors of at least the requested
417: * level, do not produce output.
1.1 kristaps 418: */
419:
1.154 kristaps 420: if (MANDOCLEVEL_OK != rc && curp->wstop)
1.111 kristaps 421: goto cleanup;
422:
423: /* If unset, allocate output dev now (if applicable). */
424:
425: if ( ! (curp->outman && curp->outmdoc)) {
426: switch (curp->outtype) {
1.173 schwarze 427: case OUTT_XHTML:
1.111 kristaps 428: curp->outdata = xhtml_alloc(curp->outopts);
1.162 kristaps 429: curp->outfree = html_free;
1.111 kristaps 430: break;
1.173 schwarze 431: case OUTT_HTML:
1.111 kristaps 432: curp->outdata = html_alloc(curp->outopts);
1.162 kristaps 433: curp->outfree = html_free;
434: break;
1.173 schwarze 435: case OUTT_UTF8:
1.163 kristaps 436: curp->outdata = utf8_alloc(curp->outopts);
437: curp->outfree = ascii_free;
438: break;
1.173 schwarze 439: case OUTT_LOCALE:
1.162 kristaps 440: curp->outdata = locale_alloc(curp->outopts);
441: curp->outfree = ascii_free;
1.111 kristaps 442: break;
1.173 schwarze 443: case OUTT_ASCII:
1.111 kristaps 444: curp->outdata = ascii_alloc(curp->outopts);
445: curp->outfree = ascii_free;
446: break;
1.173 schwarze 447: case OUTT_PDF:
1.111 kristaps 448: curp->outdata = pdf_alloc(curp->outopts);
449: curp->outfree = pspdf_free;
450: break;
1.173 schwarze 451: case OUTT_PS:
1.111 kristaps 452: curp->outdata = ps_alloc(curp->outopts);
453: curp->outfree = pspdf_free;
454: break;
455: default:
456: break;
457: }
458:
459: switch (curp->outtype) {
1.173 schwarze 460: case OUTT_HTML:
1.111 kristaps 461: /* FALLTHROUGH */
1.173 schwarze 462: case OUTT_XHTML:
1.111 kristaps 463: curp->outman = html_man;
464: curp->outmdoc = html_mdoc;
465: break;
1.173 schwarze 466: case OUTT_TREE:
1.111 kristaps 467: curp->outman = tree_man;
468: curp->outmdoc = tree_mdoc;
469: break;
1.173 schwarze 470: case OUTT_MAN:
1.164 schwarze 471: curp->outmdoc = man_mdoc;
1.165 kristaps 472: curp->outman = man_man;
1.164 schwarze 473: break;
1.173 schwarze 474: case OUTT_PDF:
1.111 kristaps 475: /* FALLTHROUGH */
1.173 schwarze 476: case OUTT_ASCII:
1.111 kristaps 477: /* FALLTHROUGH */
1.173 schwarze 478: case OUTT_UTF8:
1.163 kristaps 479: /* FALLTHROUGH */
1.173 schwarze 480: case OUTT_LOCALE:
1.162 kristaps 481: /* FALLTHROUGH */
1.173 schwarze 482: case OUTT_PS:
1.111 kristaps 483: curp->outman = terminal_man;
484: curp->outmdoc = terminal_mdoc;
485: break;
486: default:
487: break;
488: }
489: }
490:
1.171 schwarze 491: mparse_result(curp->mp, &mdoc, &man, NULL);
1.154 kristaps 492:
1.111 kristaps 493: /* Execute the out device, if it exists. */
494:
1.154 kristaps 495: if (man && curp->outman)
496: (*curp->outman)(curp->outdata, man);
497: if (mdoc && curp->outmdoc)
498: (*curp->outmdoc)(curp->outdata, mdoc);
1.111 kristaps 499:
500: cleanup:
1.112 kristaps 501:
1.154 kristaps 502: mparse_reset(curp->mp);
1.111 kristaps 503:
1.154 kristaps 504: if (*level < rc)
505: *level = rc;
1.10 kristaps 506: }
507:
508: static int
1.170 schwarze 509: moptions(int *options, char *arg)
1.10 kristaps 510: {
511:
1.180 schwarze 512: if (arg == NULL)
513: /* nothing to do */;
514: else if (0 == strcmp(arg, "doc"))
1.170 schwarze 515: *options |= MPARSE_MDOC;
1.19 kristaps 516: else if (0 == strcmp(arg, "andoc"))
1.170 schwarze 517: /* nothing to do */;
1.17 kristaps 518: else if (0 == strcmp(arg, "an"))
1.170 schwarze 519: *options |= MPARSE_MAN;
1.10 kristaps 520: else {
1.176 schwarze 521: fprintf(stderr, "%s: -m%s: Bad argument\n",
522: progname, arg);
1.10 kristaps 523: return(0);
524: }
525:
526: return(1);
1.1 kristaps 527: }
528:
529: static int
1.60 kristaps 530: toptions(struct curparse *curp, char *arg)
1.1 kristaps 531: {
532:
533: if (0 == strcmp(arg, "ascii"))
1.60 kristaps 534: curp->outtype = OUTT_ASCII;
535: else if (0 == strcmp(arg, "lint")) {
536: curp->outtype = OUTT_LINT;
1.103 schwarze 537: curp->wlevel = MANDOCLEVEL_WARNING;
1.154 kristaps 538: } else if (0 == strcmp(arg, "tree"))
1.60 kristaps 539: curp->outtype = OUTT_TREE;
1.164 schwarze 540: else if (0 == strcmp(arg, "man"))
541: curp->outtype = OUTT_MAN;
1.43 kristaps 542: else if (0 == strcmp(arg, "html"))
1.60 kristaps 543: curp->outtype = OUTT_HTML;
1.163 kristaps 544: else if (0 == strcmp(arg, "utf8"))
545: curp->outtype = OUTT_UTF8;
1.162 kristaps 546: else if (0 == strcmp(arg, "locale"))
547: curp->outtype = OUTT_LOCALE;
1.59 kristaps 548: else if (0 == strcmp(arg, "xhtml"))
1.60 kristaps 549: curp->outtype = OUTT_XHTML;
1.85 kristaps 550: else if (0 == strcmp(arg, "ps"))
551: curp->outtype = OUTT_PS;
1.100 kristaps 552: else if (0 == strcmp(arg, "pdf"))
553: curp->outtype = OUTT_PDF;
1.1 kristaps 554: else {
1.176 schwarze 555: fprintf(stderr, "%s: -T%s: Bad argument\n",
556: progname, arg);
1.1 kristaps 557: return(0);
558: }
559:
560: return(1);
561: }
562:
563: static int
1.103 schwarze 564: woptions(struct curparse *curp, char *arg)
1.1 kristaps 565: {
1.34 kristaps 566: char *v, *o;
1.173 schwarze 567: const char *toks[6];
1.1 kristaps 568:
1.103 schwarze 569: toks[0] = "stop";
570: toks[1] = "all";
571: toks[2] = "warning";
572: toks[3] = "error";
573: toks[4] = "fatal";
574: toks[5] = NULL;
1.1 kristaps 575:
1.34 kristaps 576: while (*arg) {
577: o = arg;
1.45 kristaps 578: switch (getsubopt(&arg, UNCONST(toks), &v)) {
1.173 schwarze 579: case 0:
1.103 schwarze 580: curp->wstop = 1;
1.1 kristaps 581: break;
1.173 schwarze 582: case 1:
1.103 schwarze 583: /* FALLTHROUGH */
1.173 schwarze 584: case 2:
1.103 schwarze 585: curp->wlevel = MANDOCLEVEL_WARNING;
1.1 kristaps 586: break;
1.173 schwarze 587: case 3:
1.103 schwarze 588: curp->wlevel = MANDOCLEVEL_ERROR;
1.24 kristaps 589: break;
1.173 schwarze 590: case 4:
1.103 schwarze 591: curp->wlevel = MANDOCLEVEL_FATAL;
1.50 kristaps 592: break;
1.1 kristaps 593: default:
1.176 schwarze 594: fprintf(stderr, "%s: -W%s: Bad argument\n",
595: progname, o);
1.1 kristaps 596: return(0);
597: }
1.34 kristaps 598: }
1.1 kristaps 599:
600: return(1);
601: }
602:
1.153 kristaps 603: static void
1.173 schwarze 604: mmsg(enum mandocerr t, enum mandoclevel lvl,
1.155 kristaps 605: const char *file, int line, int col, const char *msg)
1.71 kristaps 606: {
1.177 schwarze 607: const char *mparse_msg;
1.103 schwarze 608:
1.175 schwarze 609: fprintf(stderr, "%s: %s:", progname, file);
610:
611: if (line)
612: fprintf(stderr, "%d:%d:", line, col + 1);
613:
1.177 schwarze 614: fprintf(stderr, " %s", mparse_strlevel(lvl));
615:
616: if (NULL != (mparse_msg = mparse_strerror(t)))
617: fprintf(stderr, ": %s", mparse_msg);
1.154 kristaps 618:
1.73 kristaps 619: if (msg)
620: fprintf(stderr, ": %s", msg);
1.154 kristaps 621:
1.73 kristaps 622: fputc('\n', stderr);
1.71 kristaps 623: }
CVSweb