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

Annotation of mandoc/man_validate.c, Revision 1.15

1.15    ! kristaps    1: /*     $Id: man_validate.c,v 1.14 2009/06/22 13:09:17 kristaps Exp $ */
1.1       kristaps    2: /*
1.9       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.8       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.8       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/types.h>
                     18:
                     19: #include <assert.h>
                     20: #include <ctype.h>
                     21: #include <stdarg.h>
                     22: #include <stdlib.h>
                     23:
                     24: #include "libman.h"
1.15    ! kristaps   25: #include "libmandoc.h"
1.1       kristaps   26:
1.11      kristaps   27: #define        POSTARGS  struct man *m, const struct man_node *n
1.1       kristaps   28:
                     29: typedef        int     (*v_post)(POSTARGS);
                     30:
                     31: struct man_valid {
                     32:        v_post   *posts;
                     33: };
                     34:
                     35: static int       check_eq0(POSTARGS);
                     36: static int       check_ge1(POSTARGS);
                     37: static int       check_ge2(POSTARGS);
                     38: static int       check_le1(POSTARGS);
                     39: static int       check_le2(POSTARGS);
                     40: static int       check_le5(POSTARGS);
1.11      kristaps   41: static int       check_text(POSTARGS);
1.14      kristaps   42: static int       check_root(POSTARGS);
1.1       kristaps   43:
                     44: static v_post    posts_le1[] = { check_le1, NULL };
                     45: static v_post    posts_le2[] = { check_le2, NULL };
                     46: static v_post    posts_ge1[] = { check_ge1, NULL };
                     47: static v_post    posts_eq0[] = { check_eq0, NULL };
                     48: static v_post    posts_ge2_le5[] = { check_ge2, check_le5, NULL };
                     49:
                     50: static const struct man_valid man_valids[MAN_MAX] = {
1.10      kristaps   51:        { posts_eq0 }, /* br */
1.1       kristaps   52:        { posts_ge2_le5 }, /* TH */
                     53:        { posts_ge1 }, /* SH */
                     54:        { posts_ge1 }, /* SS */
1.4       kristaps   55:        { NULL }, /* TP */
1.1       kristaps   56:        { posts_eq0 }, /* LP */
                     57:        { posts_eq0 }, /* PP */
                     58:        { posts_eq0 }, /* P */
                     59:        { posts_le2 }, /* IP */
                     60:        { posts_le1 }, /* HP */
                     61:        { NULL }, /* SM */
                     62:        { NULL }, /* SB */
                     63:        { NULL }, /* BI */
                     64:        { NULL }, /* IB */
                     65:        { NULL }, /* BR */
                     66:        { NULL }, /* RB */
                     67:        { NULL }, /* R */
                     68:        { NULL }, /* B */
                     69:        { NULL }, /* I */
                     70:        { NULL }, /* IR */
1.4       kristaps   71:        { NULL }, /* RI */
1.6       kristaps   72:        { posts_eq0 }, /* na */
1.7       kristaps   73:        { NULL }, /* i */
1.1       kristaps   74: };
                     75:
                     76:
                     77: int
                     78: man_valid_post(struct man *m)
                     79: {
                     80:        v_post          *cp;
                     81:
                     82:        if (MAN_VALID & m->last->flags)
                     83:                return(1);
                     84:        m->last->flags |= MAN_VALID;
                     85:
                     86:        switch (m->last->type) {
                     87:        case (MAN_TEXT):
1.11      kristaps   88:                return(check_text(m, m->last));
1.1       kristaps   89:        case (MAN_ROOT):
1.14      kristaps   90:                return(check_root(m, m->last));
1.1       kristaps   91:        default:
                     92:                break;
                     93:        }
                     94:
                     95:        if (NULL == (cp = man_valids[m->last->tok].posts))
                     96:                return(1);
                     97:        for ( ; *cp; cp++)
                     98:                if ( ! (*cp)(m, m->last))
                     99:                        return(0);
                    100:
                    101:        return(1);
                    102: }
                    103:
                    104:
1.11      kristaps  105: static int
1.14      kristaps  106: check_root(POSTARGS)
                    107: {
                    108:
                    109:        if (NULL == m->first->child)
                    110:                return(man_nerr(m, n, WNODATA));
                    111:        if (NULL == m->meta.title)
                    112:                return(man_nerr(m, n, WNOTITLE));
                    113:
                    114:        return(1);
                    115: }
                    116:
                    117:
                    118: static int
1.11      kristaps  119: check_text(POSTARGS)
                    120: {
                    121:        const char      *p;
1.15    ! kristaps  122:        int              pos, c;
1.11      kristaps  123:
                    124:        assert(n->string);
                    125:
                    126:        for (p = n->string, pos = n->pos + 1; *p; p++, pos++) {
1.15    ! kristaps  127:                if ('\\' == *p) {
        !           128:                        c = mandoc_special(p);
        !           129:                        if (c) {
        !           130:                                p += c - 1;
        !           131:                                pos += c - 1;
        !           132:                                continue;
        !           133:                        }
        !           134:                        if ( ! (MAN_IGN_ESCAPE & m->pflags))
        !           135:                                return(man_perr(m, n->line, pos, WESCAPE));
        !           136:                        if ( ! man_pwarn(m, n->line, pos, WESCAPE))
        !           137:                                return(0);
        !           138:                        continue;
        !           139:                }
        !           140:
        !           141:                if ('\t' == *p || isprint((u_char)*p))
1.11      kristaps  142:                        continue;
                    143:
                    144:                if (MAN_IGN_CHARS & m->pflags)
1.12      kristaps  145:                        return(man_pwarn(m, n->line, pos, WNPRINT));
                    146:                return(man_perr(m, n->line, pos, WNPRINT));
1.11      kristaps  147:        }
                    148:
                    149:        return(1);
1.1       kristaps  150: }
                    151:
                    152:
                    153: #define        INEQ_DEFINE(x, ineq, name) \
                    154: static int \
                    155: check_##name(POSTARGS) \
                    156: { \
1.11      kristaps  157:        if (n->nchild ineq (x)) \
1.1       kristaps  158:                return(1); \
1.4       kristaps  159:        return(man_verr(m, n->line, n->pos, \
1.1       kristaps  160:                        "expected line arguments %s %d, have %d", \
1.11      kristaps  161:                        #ineq, (x), n->nchild)); \
1.1       kristaps  162: }
                    163:
                    164: INEQ_DEFINE(0, ==, eq0)
                    165: INEQ_DEFINE(1, >=, ge1)
                    166: INEQ_DEFINE(2, >=, ge2)
                    167: INEQ_DEFINE(1, <=, le1)
                    168: INEQ_DEFINE(2, <=, le2)
                    169: INEQ_DEFINE(5, <=, le5)
                    170:

CVSweb