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

Annotation of mandoc/roff_validate.c, Revision 1.20

1.20    ! schwarze    1: /* $Id: roff_validate.c,v 1.19 2020/02/27 01:43:52 schwarze Exp $ */
1.1       schwarze    2: /*
1.19      schwarze    3:  * Copyright (c) 2010, 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org>
1.1       schwarze    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 above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      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.
                     16:  */
1.20    ! schwarze   17: #include "config.h"
        !            18:
1.1       schwarze   19: #include <sys/types.h>
                     20:
                     21: #include <assert.h>
1.13      schwarze   22: #include <stdio.h>
1.10      schwarze   23: #include <string.h>
1.1       schwarze   24:
                     25: #include "mandoc.h"
                     26: #include "roff.h"
                     27: #include "libmandoc.h"
                     28: #include "roff_int.h"
                     29:
                     30: #define        ROFF_VALID_ARGS struct roff_man *man, struct roff_node *n
                     31:
                     32: typedef        void    (*roff_valid_fp)(ROFF_VALID_ARGS);
                     33:
1.11      schwarze   34: static void      roff_valid_br(ROFF_VALID_ARGS);
1.16      schwarze   35: static void      roff_valid_fi(ROFF_VALID_ARGS);
1.1       schwarze   36: static void      roff_valid_ft(ROFF_VALID_ARGS);
1.16      schwarze   37: static void      roff_valid_nf(ROFF_VALID_ARGS);
1.11      schwarze   38: static void      roff_valid_sp(ROFF_VALID_ARGS);
1.1       schwarze   39:
                     40: static const roff_valid_fp roff_valids[ROFF_MAX] = {
1.11      schwarze   41:        roff_valid_br,  /* br */
1.7       schwarze   42:        NULL,  /* ce */
1.16      schwarze   43:        roff_valid_fi,  /* fi */
1.1       schwarze   44:        roff_valid_ft,  /* ft */
1.2       schwarze   45:        NULL,  /* ll */
1.6       schwarze   46:        NULL,  /* mc */
1.16      schwarze   47:        roff_valid_nf,  /* nf */
1.9       schwarze   48:        NULL,  /* po */
1.8       schwarze   49:        NULL,  /* rj */
1.11      schwarze   50:        roff_valid_sp,  /* sp */
1.4       schwarze   51:        NULL,  /* ta */
1.5       schwarze   52:        NULL,  /* ti */
1.1       schwarze   53: };
                     54:
                     55:
                     56: void
                     57: roff_validate(struct roff_man *man)
                     58: {
                     59:        struct roff_node        *n;
                     60:
                     61:        n = man->last;
                     62:        assert(n->tok < ROFF_MAX);
                     63:        if (roff_valids[n->tok] != NULL)
                     64:                (*roff_valids[n->tok])(man, n);
                     65: }
                     66:
                     67: static void
1.11      schwarze   68: roff_valid_br(ROFF_VALID_ARGS)
                     69: {
                     70:        struct roff_node        *np;
                     71:
1.12      schwarze   72:        if (n->next != NULL && n->next->type == ROFFT_TEXT &&
                     73:            *n->next->string == ' ') {
1.14      schwarze   74:                mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos,
1.12      schwarze   75:                    "br before text line with leading blank");
                     76:                roff_node_delete(man, n);
                     77:                return;
                     78:        }
1.11      schwarze   79:
1.19      schwarze   80:        if ((np = roff_node_prev(n)) == NULL)
1.11      schwarze   81:                return;
                     82:
                     83:        switch (np->tok) {
                     84:        case ROFF_br:
                     85:        case ROFF_sp:
                     86:        case MDOC_Pp:
1.14      schwarze   87:                mandoc_msg(MANDOCERR_PAR_SKIP,
1.11      schwarze   88:                    n->line, n->pos, "br after %s", roff_name[np->tok]);
                     89:                roff_node_delete(man, n);
                     90:                break;
                     91:        default:
                     92:                break;
                     93:        }
                     94: }
                     95:
                     96: static void
1.16      schwarze   97: roff_valid_fi(ROFF_VALID_ARGS)
                     98: {
1.17      schwarze   99:        if ((n->flags & NODE_NOFILL) == 0)
1.16      schwarze  100:                mandoc_msg(MANDOCERR_FI_SKIP, n->line, n->pos, "fi");
                    101: }
                    102:
                    103: static void
1.1       schwarze  104: roff_valid_ft(ROFF_VALID_ARGS)
                    105: {
1.10      schwarze  106:        const char              *cp;
1.1       schwarze  107:
                    108:        if (n->child == NULL) {
                    109:                man->next = ROFF_NEXT_CHILD;
                    110:                roff_word_alloc(man, n->line, n->pos, "P");
                    111:                man->last = n;
                    112:                return;
                    113:        }
                    114:
                    115:        cp = n->child->string;
1.15      schwarze  116:        if (mandoc_font(cp, (int)strlen(cp)) != ESCAPE_ERROR)
                    117:                return;
1.14      schwarze  118:        mandoc_msg(MANDOCERR_FT_BAD, n->line, n->pos, "ft %s", cp);
1.1       schwarze  119:        roff_node_delete(man, n);
1.11      schwarze  120: }
                    121:
                    122: static void
1.16      schwarze  123: roff_valid_nf(ROFF_VALID_ARGS)
                    124: {
1.18      schwarze  125:        if (n->flags & NODE_NOFILL)
1.16      schwarze  126:                mandoc_msg(MANDOCERR_NF_SKIP, n->line, n->pos, "nf");
                    127: }
                    128:
                    129: static void
1.11      schwarze  130: roff_valid_sp(ROFF_VALID_ARGS)
                    131: {
                    132:        struct roff_node        *np;
                    133:
1.19      schwarze  134:        if ((np = roff_node_prev(n)) == NULL)
1.11      schwarze  135:                return;
                    136:
                    137:        switch (np->tok) {
                    138:        case ROFF_br:
1.14      schwarze  139:                mandoc_msg(MANDOCERR_PAR_SKIP,
1.11      schwarze  140:                    np->line, np->pos, "br before sp");
                    141:                roff_node_delete(man, np);
                    142:                break;
                    143:        case MDOC_Pp:
1.14      schwarze  144:                mandoc_msg(MANDOCERR_PAR_SKIP,
1.11      schwarze  145:                    n->line, n->pos, "sp after Pp");
                    146:                roff_node_delete(man, n);
                    147:                break;
                    148:        default:
                    149:                break;
                    150:        }
1.1       schwarze  151: }

CVSweb