[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/main.c, Revision 1.19

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

CVSweb