Annotation of mandoc/main.c, Revision 1.38
1.38 ! kristaps 1: /* $Id: main.c,v 1.37 2009/07/06 13:08:12 kristaps Exp $ */
1.1 kristaps 2: /*
1.26 kristaps 3: * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
1.1 kristaps 4: *
5: * Permission to use, copy, modify, and distribute this software for any
1.25 kristaps 6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 8: *
1.25 kristaps 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 kristaps 16: */
17: #include <sys/stat.h>
18:
19: #include <assert.h>
20: #include <err.h>
21: #include <fcntl.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #include <unistd.h>
26:
27: #include "mdoc.h"
1.10 kristaps 28: #include "man.h"
1.1 kristaps 29:
1.16 kristaps 30: /* Account for FreeBSD and Linux in our declarations. */
31:
1.3 kristaps 32: #ifdef __linux__
33: extern int getsubopt(char **, char * const *, char **);
34: # ifndef __dead
35: # define __dead __attribute__((__noreturn__))
36: # endif
1.13 kristaps 37: #elif defined(__dead2)
1.10 kristaps 38: # ifndef __dead
39: # define __dead __dead2
40: # endif
1.3 kristaps 41: #endif
42:
1.22 kristaps 43: typedef int (*out_mdoc)(void *, const struct mdoc *);
44: typedef int (*out_man)(void *, const struct man *);
45: typedef void (*out_free)(void *);
46:
1.5 kristaps 47: struct buf {
48: char *buf;
49: size_t sz;
50: };
51:
1.19 kristaps 52: enum intt {
53: INTT_AUTO,
54: INTT_MDOC,
55: INTT_MAN
56: };
57:
58: enum outt {
59: OUTT_ASCII = 0,
60: OUTT_TREE,
61: OUTT_LINT
62: };
63:
1.5 kristaps 64: struct curparse {
1.22 kristaps 65: const char *file; /* Current parse. */
66: int fd; /* Current parse. */
1.5 kristaps 67: int wflags;
1.36 kristaps 68: #define WARN_WALL (1 << 0) /* All-warnings mask. */
1.1 kristaps 69: #define WARN_WERR (1 << 2) /* Warnings->errors. */
1.23 kristaps 70: int fflags;
71: #define IGN_SCOPE (1 << 0) /* Ignore scope errors. */
1.24 kristaps 72: #define NO_IGN_ESCAPE (1 << 1) /* Don't ignore bad escapes. */
73: #define NO_IGN_MACRO (1 << 2) /* Don't ignore bad macros. */
74: #define NO_IGN_CHARS (1 << 3) /* Don't ignore bad chars. */
1.29 kristaps 75: enum intt inttype; /* Input parsers... */
1.19 kristaps 76: struct man *man;
1.22 kristaps 77: struct man *lastman;
1.19 kristaps 78: struct mdoc *mdoc;
1.22 kristaps 79: struct mdoc *lastmdoc;
1.29 kristaps 80: enum outt outtype; /* Output devices... */
1.22 kristaps 81: out_mdoc outmdoc;
82: out_man outman;
83: out_free outfree;
84: void *outdata;
1.5 kristaps 85: };
1.1 kristaps 86:
87: extern void *ascii_alloc(void);
1.22 kristaps 88: extern int tree_mdoc(void *, const struct mdoc *);
89: extern int tree_man(void *, const struct man *);
90: extern int terminal_mdoc(void *, const struct mdoc *);
91: extern int terminal_man(void *, const struct man *);
1.1 kristaps 92: extern void terminal_free(void *);
93:
94: static int foptions(int *, char *);
95: static int toptions(enum outt *, char *);
1.10 kristaps 96: static int moptions(enum intt *, char *);
1.1 kristaps 97: static int woptions(int *, char *);
98: static int merr(void *, int, int, const char *);
1.37 kristaps 99: static int mwarn(void *, int, int, const char *);
1.19 kristaps 100: static int ffile(struct buf *, struct buf *,
101: const char *, struct curparse *);
1.5 kristaps 102: static int fdesc(struct buf *, struct buf *,
1.19 kristaps 103: struct curparse *);
1.22 kristaps 104: static int pset(const char *, int, struct curparse *,
1.19 kristaps 105: struct man **, struct mdoc **);
106: static struct man *man_init(struct curparse *);
107: static struct mdoc *mdoc_init(struct curparse *);
1.10 kristaps 108: __dead static void version(void);
109: __dead static void usage(void);
1.1 kristaps 110:
1.22 kristaps 111: extern char *__progname;
112:
1.1 kristaps 113:
114: int
115: main(int argc, char *argv[])
116: {
1.19 kristaps 117: int c, rc;
1.5 kristaps 118: struct buf ln, blk;
119: struct curparse curp;
1.1 kristaps 120:
1.5 kristaps 121: bzero(&curp, sizeof(struct curparse));
122:
1.19 kristaps 123: curp.inttype = INTT_AUTO;
1.22 kristaps 124: curp.outtype = OUTT_ASCII;
1.19 kristaps 125:
1.1 kristaps 126: /* LINTED */
1.10 kristaps 127: while (-1 != (c = getopt(argc, argv, "f:m:VW:T:")))
1.1 kristaps 128: switch (c) {
129: case ('f'):
1.19 kristaps 130: if ( ! foptions(&curp.fflags, optarg))
1.32 kristaps 131: return(EXIT_FAILURE);
1.1 kristaps 132: break;
1.10 kristaps 133: case ('m'):
1.19 kristaps 134: if ( ! moptions(&curp.inttype, optarg))
1.32 kristaps 135: return(EXIT_FAILURE);
1.10 kristaps 136: break;
1.1 kristaps 137: case ('T'):
1.22 kristaps 138: if ( ! toptions(&curp.outtype, optarg))
1.32 kristaps 139: return(EXIT_FAILURE);
1.1 kristaps 140: break;
141: case ('W'):
1.5 kristaps 142: if ( ! woptions(&curp.wflags, optarg))
1.32 kristaps 143: return(EXIT_FAILURE);
1.1 kristaps 144: break;
145: case ('V'):
146: version();
147: /* NOTREACHED */
148: default:
149: usage();
150: /* NOTREACHED */
151: }
152:
153: argc -= optind;
154: argv += optind;
155:
1.5 kristaps 156: bzero(&ln, sizeof(struct buf));
157: bzero(&blk, sizeof(struct buf));
1.1 kristaps 158:
1.22 kristaps 159: rc = 1;
1.1 kristaps 160:
1.30 kristaps 161: if (NULL == *argv) {
162: curp.file = "<stdin>";
163: curp.fd = STDIN_FILENO;
164: if ( ! fdesc(&blk, &ln, &curp))
1.22 kristaps 165: rc = 0;
1.30 kristaps 166: }
1.22 kristaps 167:
168: while (rc && *argv) {
169: if ( ! ffile(&blk, &ln, *argv, &curp))
170: rc = 0;
171: argv++;
172: if (*argv && rc) {
173: if (curp.lastman)
174: if ( ! man_reset(curp.lastman))
175: rc = 0;
176: if (curp.lastmdoc)
177: if ( ! mdoc_reset(curp.lastmdoc))
178: rc = 0;
179: curp.lastman = NULL;
180: curp.lastmdoc = NULL;
1.4 kristaps 181: }
1.1 kristaps 182: }
183:
1.5 kristaps 184: if (blk.buf)
185: free(blk.buf);
186: if (ln.buf)
187: free(ln.buf);
1.22 kristaps 188: if (curp.outfree)
189: (*curp.outfree)(curp.outdata);
1.19 kristaps 190: if (curp.mdoc)
191: mdoc_free(curp.mdoc);
192: if (curp.man)
193: man_free(curp.man);
1.1 kristaps 194:
195: return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
196: }
197:
198:
199: __dead static void
200: version(void)
201: {
202:
203: (void)printf("%s %s\n", __progname, VERSION);
1.18 kristaps 204: exit(EXIT_SUCCESS);
1.1 kristaps 205: }
206:
207:
208: __dead static void
209: usage(void)
210: {
211:
1.12 kristaps 212: (void)fprintf(stderr, "usage: %s [-V] [-foption...] "
213: "[-mformat] [-Toutput] [-Werr...]\n",
214: __progname);
1.18 kristaps 215: exit(EXIT_FAILURE);
1.1 kristaps 216: }
217:
218:
1.19 kristaps 219: static struct man *
220: man_init(struct curparse *curp)
221: {
222: int pflags;
223: struct man *man;
224: struct man_cb mancb;
225:
226: mancb.man_err = merr;
1.37 kristaps 227: mancb.man_warn = mwarn;
1.19 kristaps 228:
1.30 kristaps 229: /* Defaults from mandoc.1. */
1.27 kristaps 230:
1.33 kristaps 231: pflags = MAN_IGN_MACRO | MAN_IGN_ESCAPE | MAN_IGN_CHARS;
1.27 kristaps 232:
1.20 kristaps 233: if (curp->fflags & NO_IGN_MACRO)
234: pflags &= ~MAN_IGN_MACRO;
1.31 kristaps 235: if (curp->fflags & NO_IGN_CHARS)
236: pflags &= ~MAN_IGN_CHARS;
1.33 kristaps 237: if (curp->fflags & NO_IGN_ESCAPE)
238: pflags &= ~MAN_IGN_ESCAPE;
1.19 kristaps 239:
240: if (NULL == (man = man_alloc(curp, pflags, &mancb)))
241: warnx("memory exhausted");
242:
243: return(man);
244: }
245:
246:
247: static struct mdoc *
248: mdoc_init(struct curparse *curp)
249: {
250: int pflags;
251: struct mdoc *mdoc;
252: struct mdoc_cb mdoccb;
253:
254: mdoccb.mdoc_err = merr;
1.37 kristaps 255: mdoccb.mdoc_warn = mwarn;
1.19 kristaps 256:
1.30 kristaps 257: /* Defaults from mandoc.1. */
1.27 kristaps 258:
1.24 kristaps 259: pflags = MDOC_IGN_MACRO | MDOC_IGN_ESCAPE | MDOC_IGN_CHARS;
1.19 kristaps 260:
261: if (curp->fflags & IGN_SCOPE)
262: pflags |= MDOC_IGN_SCOPE;
1.24 kristaps 263: if (curp->fflags & NO_IGN_ESCAPE)
264: pflags &= ~MDOC_IGN_ESCAPE;
265: if (curp->fflags & NO_IGN_MACRO)
266: pflags &= ~MDOC_IGN_MACRO;
267: if (curp->fflags & NO_IGN_CHARS)
268: pflags &= ~MDOC_IGN_CHARS;
1.19 kristaps 269:
270: if (NULL == (mdoc = mdoc_alloc(curp, pflags, &mdoccb)))
1.24 kristaps 271: warnx("memory exhausted");
1.19 kristaps 272:
273: return(mdoc);
274: }
275:
276:
277: static int
278: ffile(struct buf *blk, struct buf *ln,
279: const char *file, struct curparse *curp)
1.1 kristaps 280: {
1.19 kristaps 281: int c;
1.1 kristaps 282:
1.19 kristaps 283: curp->file = file;
284: if (-1 == (curp->fd = open(curp->file, O_RDONLY, 0))) {
285: warn("%s", curp->file);
1.1 kristaps 286: return(0);
287: }
288:
1.19 kristaps 289: c = fdesc(blk, ln, curp);
1.1 kristaps 290:
1.19 kristaps 291: if (-1 == close(curp->fd))
292: warn("%s", curp->file);
1.1 kristaps 293:
294: return(c);
295: }
296:
297:
298: static int
1.19 kristaps 299: fdesc(struct buf *blk, struct buf *ln, struct curparse *curp)
1.1 kristaps 300: {
301: size_t sz;
302: ssize_t ssz;
303: struct stat st;
1.29 kristaps 304: int j, i, pos, lnn, comment;
1.19 kristaps 305: struct man *man;
306: struct mdoc *mdoc;
1.10 kristaps 307:
1.19 kristaps 308: sz = BUFSIZ;
309: man = NULL;
310: mdoc = NULL;
1.1 kristaps 311:
312: /*
1.19 kristaps 313: * Two buffers: ln and buf. buf is the input buffer optimised
314: * here for each file's block size. ln is a line buffer. Both
1.1 kristaps 315: * growable, hence passed in by ptr-ptr.
316: */
317:
1.19 kristaps 318: if (-1 == fstat(curp->fd, &st))
1.32 kristaps 319: warn("%s", curp->file);
1.6 kristaps 320: else if ((size_t)st.st_blksize > sz)
321: sz = st.st_blksize;
1.1 kristaps 322:
1.5 kristaps 323: if (sz > blk->sz) {
324: blk->buf = realloc(blk->buf, sz);
1.19 kristaps 325: if (NULL == blk->buf) {
326: warn("realloc");
327: return(0);
328: }
1.5 kristaps 329: blk->sz = sz;
1.1 kristaps 330: }
331:
1.19 kristaps 332: /* Fill buf with file blocksize. */
1.1 kristaps 333:
1.29 kristaps 334: for (lnn = pos = comment = 0; ; ) {
1.19 kristaps 335: if (-1 == (ssz = read(curp->fd, blk->buf, sz))) {
336: warn("%s", curp->file);
1.1 kristaps 337: return(0);
338: } else if (0 == ssz)
339: break;
340:
1.19 kristaps 341: /* Parse the read block into partial or full lines. */
342:
1.1 kristaps 343: for (i = 0; i < (int)ssz; i++) {
1.5 kristaps 344: if (pos >= (int)ln->sz) {
345: ln->sz += 256; /* Step-size. */
346: ln->buf = realloc(ln->buf, ln->sz);
1.19 kristaps 347: if (NULL == ln->buf) {
348: warn("realloc");
349: return(0);
350: }
1.1 kristaps 351: }
352:
1.5 kristaps 353: if ('\n' != blk->buf[i]) {
1.29 kristaps 354: if (comment)
355: continue;
1.5 kristaps 356: ln->buf[pos++] = blk->buf[i];
1.29 kristaps 357:
358: /* Handle in-line `\"' comments. */
359:
360: if (1 == pos || '\"' != ln->buf[pos - 1])
361: continue;
362:
363: for (j = pos - 2; j >= 0; j--)
364: if ('\\' != ln->buf[j])
365: break;
366:
367: if ( ! ((pos - 2 - j) % 2))
368: continue;
369:
370: comment = 1;
371: pos -= 2;
1.1 kristaps 372: continue;
1.29 kristaps 373: }
1.1 kristaps 374:
1.29 kristaps 375: /* Handle escaped `\\n' newlines. */
1.1 kristaps 376:
1.29 kristaps 377: if (pos > 0 && 0 == comment &&
378: '\\' == ln->buf[pos - 1]) {
1.1 kristaps 379: for (j = pos - 1; j >= 0; j--)
1.5 kristaps 380: if ('\\' != ln->buf[j])
1.1 kristaps 381: break;
382: if ( ! ((pos - j) % 2)) {
383: pos--;
384: lnn++;
385: continue;
386: }
387: }
388:
1.5 kristaps 389: ln->buf[pos] = 0;
1.19 kristaps 390: lnn++;
1.29 kristaps 391:
392: /* If unset, assign parser in pset(). */
1.19 kristaps 393:
394: if ( ! (man || mdoc) && ! pset(ln->buf,
395: pos, curp, &man, &mdoc))
1.10 kristaps 396: return(0);
1.19 kristaps 397:
1.29 kristaps 398: pos = comment = 0;
1.19 kristaps 399:
1.30 kristaps 400: /* Pass down into parsers. */
401:
1.10 kristaps 402: if (man && ! man_parseln(man, lnn, ln->buf))
1.1 kristaps 403: return(0);
1.19 kristaps 404: if (mdoc && ! mdoc_parseln(mdoc, lnn, ln->buf))
405: return(0);
1.1 kristaps 406: }
407: }
408:
1.29 kristaps 409: /* NOTE a parser may not have been assigned, yet. */
1.19 kristaps 410:
1.22 kristaps 411: if ( ! (man || mdoc)) {
412: warnx("%s: not a manual", curp->file);
413: return(0);
414: }
415:
416: if (mdoc && ! mdoc_endparse(mdoc))
417: return(0);
418: if (man && ! man_endparse(man))
419: return(0);
1.19 kristaps 420:
1.29 kristaps 421: /* If unset, allocate output dev now (if applicable). */
1.22 kristaps 422:
423: if ( ! (curp->outman && curp->outmdoc)) {
424: switch (curp->outtype) {
425: case (OUTT_TREE):
426: curp->outman = tree_man;
427: curp->outmdoc = tree_mdoc;
428: break;
429: case (OUTT_LINT):
430: break;
431: default:
432: curp->outdata = ascii_alloc();
433: curp->outman = terminal_man;
434: curp->outmdoc = terminal_mdoc;
435: curp->outfree = terminal_free;
436: break;
437: }
438: }
439:
440: /* Execute the out device, if it exists. */
441:
442: if (man && curp->outman)
443: if ( ! (*curp->outman)(curp->outdata, man))
444: return(0);
445: if (mdoc && curp->outmdoc)
446: if ( ! (*curp->outmdoc)(curp->outdata, mdoc))
447: return(0);
448:
449: return(1);
1.19 kristaps 450: }
451:
452:
453: static int
1.22 kristaps 454: pset(const char *buf, int pos, struct curparse *curp,
1.19 kristaps 455: struct man **man, struct mdoc **mdoc)
456: {
1.29 kristaps 457: int i;
1.19 kristaps 458:
459: /*
460: * Try to intuit which kind of manual parser should be used. If
461: * passed in by command-line (-man, -mdoc), then use that
462: * explicitly. If passed as -mandoc, then try to guess from the
1.30 kristaps 463: * line: either skip dot-lines, use -mdoc when finding `.Dt', or
1.19 kristaps 464: * default to -man, which is more lenient.
465: */
466:
1.29 kristaps 467: if (buf[0] == '.') {
468: for (i = 1; buf[i]; i++)
469: if (' ' != buf[i] && '\t' != buf[i])
470: break;
471: if (0 == buf[i])
472: return(1);
473: }
1.10 kristaps 474:
1.19 kristaps 475: switch (curp->inttype) {
476: case (INTT_MDOC):
477: if (NULL == curp->mdoc)
478: curp->mdoc = mdoc_init(curp);
479: if (NULL == (*mdoc = curp->mdoc))
480: return(0);
1.22 kristaps 481: curp->lastmdoc = *mdoc;
1.19 kristaps 482: return(1);
483: case (INTT_MAN):
484: if (NULL == curp->man)
485: curp->man = man_init(curp);
486: if (NULL == (*man = curp->man))
487: return(0);
1.22 kristaps 488: curp->lastman = *man;
1.19 kristaps 489: return(1);
490: default:
491: break;
492: }
493:
494: if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
495: if (NULL == curp->mdoc)
496: curp->mdoc = mdoc_init(curp);
497: if (NULL == (*mdoc = curp->mdoc))
498: return(0);
1.22 kristaps 499: curp->lastmdoc = *mdoc;
1.19 kristaps 500: return(1);
501: }
502:
503: if (NULL == curp->man)
504: curp->man = man_init(curp);
505: if (NULL == (*man = curp->man))
506: return(0);
1.22 kristaps 507: curp->lastman = *man;
1.19 kristaps 508: return(1);
1.10 kristaps 509: }
510:
511:
512: static int
513: moptions(enum intt *tflags, char *arg)
514: {
515:
1.17 kristaps 516: if (0 == strcmp(arg, "doc"))
1.10 kristaps 517: *tflags = INTT_MDOC;
1.19 kristaps 518: else if (0 == strcmp(arg, "andoc"))
519: *tflags = INTT_AUTO;
1.17 kristaps 520: else if (0 == strcmp(arg, "an"))
1.10 kristaps 521: *tflags = INTT_MAN;
522: else {
523: warnx("bad argument: -m%s", arg);
524: return(0);
525: }
526:
527: return(1);
1.1 kristaps 528: }
529:
530:
531: static int
532: toptions(enum outt *tflags, char *arg)
533: {
534:
535: if (0 == strcmp(arg, "ascii"))
536: *tflags = OUTT_ASCII;
537: else if (0 == strcmp(arg, "lint"))
538: *tflags = OUTT_LINT;
539: else if (0 == strcmp(arg, "tree"))
540: *tflags = OUTT_TREE;
541: else {
542: warnx("bad argument: -T%s", arg);
543: return(0);
544: }
545:
546: return(1);
547: }
548:
549:
550: static int
551: foptions(int *fflags, char *arg)
552: {
1.34 kristaps 553: char *v, *o;
1.24 kristaps 554: char *toks[6];
1.1 kristaps 555:
556: toks[0] = "ign-scope";
1.24 kristaps 557: toks[1] = "no-ign-escape";
558: toks[2] = "no-ign-macro";
559: toks[3] = "no-ign-chars";
560: toks[4] = "strict";
561: toks[5] = NULL;
1.1 kristaps 562:
1.34 kristaps 563: while (*arg) {
564: o = arg;
1.1 kristaps 565: switch (getsubopt(&arg, toks, &v)) {
566: case (0):
1.15 kristaps 567: *fflags |= IGN_SCOPE;
1.1 kristaps 568: break;
569: case (1):
1.24 kristaps 570: *fflags |= NO_IGN_ESCAPE;
1.1 kristaps 571: break;
572: case (2):
1.24 kristaps 573: *fflags |= NO_IGN_MACRO;
1.1 kristaps 574: break;
1.20 kristaps 575: case (3):
1.24 kristaps 576: *fflags |= NO_IGN_CHARS;
577: break;
578: case (4):
579: *fflags |= NO_IGN_ESCAPE |
580: NO_IGN_MACRO | NO_IGN_CHARS;
1.20 kristaps 581: break;
1.1 kristaps 582: default:
1.34 kristaps 583: warnx("bad argument: -f%s", o);
1.1 kristaps 584: return(0);
585: }
1.34 kristaps 586: }
1.1 kristaps 587:
588: return(1);
589: }
590:
591:
592: static int
593: woptions(int *wflags, char *arg)
594: {
1.34 kristaps 595: char *v, *o;
1.36 kristaps 596: char *toks[3];
1.1 kristaps 597:
598: toks[0] = "all";
1.36 kristaps 599: toks[1] = "error";
600: toks[2] = NULL;
1.1 kristaps 601:
1.34 kristaps 602: while (*arg) {
603: o = arg;
1.1 kristaps 604: switch (getsubopt(&arg, toks, &v)) {
605: case (0):
606: *wflags |= WARN_WALL;
607: break;
608: case (1):
609: *wflags |= WARN_WERR;
610: break;
611: default:
1.34 kristaps 612: warnx("bad argument: -W%s", o);
1.1 kristaps 613: return(0);
614: }
1.34 kristaps 615: }
1.1 kristaps 616:
617: return(1);
618: }
619:
620:
1.2 kristaps 621: /* ARGSUSED */
1.1 kristaps 622: static int
623: merr(void *arg, int line, int col, const char *msg)
624: {
1.5 kristaps 625: struct curparse *curp;
626:
627: curp = (struct curparse *)arg;
1.36 kristaps 628:
1.5 kristaps 629: warnx("%s:%d: error: %s (column %d)",
630: curp->file, line, msg, col);
1.27 kristaps 631:
1.1 kristaps 632: return(0);
633: }
634:
635:
636: static int
1.37 kristaps 637: mwarn(void *arg, int line, int col, const char *msg)
1.1 kristaps 638: {
1.5 kristaps 639: struct curparse *curp;
1.1 kristaps 640:
1.5 kristaps 641: curp = (struct curparse *)arg;
1.1 kristaps 642:
1.36 kristaps 643: if ( ! (curp->wflags & WARN_WALL))
644: return(1);
645:
1.38 ! kristaps 646: warnx("%s:%d: warning: %s (column %d)",
1.35 kristaps 647: curp->file, line, msg, col);
1.1 kristaps 648:
1.5 kristaps 649: if ( ! (curp->wflags & WARN_WERR))
1.1 kristaps 650: return(1);
1.27 kristaps 651:
1.30 kristaps 652: warnx("considering warnings as errors");
1.1 kristaps 653: return(0);
654: }
655:
CVSweb