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

Annotation of mandoc/tbl_opts.c, Revision 1.17

1.17    ! schwarze    1: /*     $Id: tbl_opts.c,v 1.16 2015/01/14 22:44:55 schwarze Exp $ */
1.1       kristaps    2: /*
1.12      schwarze    3:  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.17    ! schwarze    4:  * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
1.1       kristaps    5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
1.11      kristaps   18: #include "config.h"
1.14      schwarze   19:
                     20: #include <sys/types.h>
1.11      kristaps   21:
1.3       kristaps   22: #include <ctype.h>
1.1       kristaps   23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26:
1.3       kristaps   27: #include "mandoc.h"
1.10      kristaps   28: #include "libmandoc.h"
1.1       kristaps   29: #include "libroff.h"
                     30:
                     31: enum   tbl_ident {
                     32:        KEY_CENTRE = 0,
                     33:        KEY_DELIM,
                     34:        KEY_EXPAND,
                     35:        KEY_BOX,
                     36:        KEY_DBOX,
                     37:        KEY_ALLBOX,
                     38:        KEY_TAB,
                     39:        KEY_LINESIZE,
                     40:        KEY_NOKEEP,
                     41:        KEY_DPOINT,
                     42:        KEY_NOSPACE,
                     43:        KEY_FRAME,
                     44:        KEY_DFRAME,
                     45:        KEY_MAX
                     46: };
                     47:
                     48: struct tbl_phrase {
                     49:        const char      *name;
                     50:        int              key;
                     51:        enum tbl_ident   ident;
                     52: };
                     53:
                     54: /* Handle Commonwealth/American spellings. */
                     55: #define        KEY_MAXKEYS      14
                     56:
                     57: static const struct tbl_phrase keys[KEY_MAXKEYS] = {
                     58:        { "center",      TBL_OPT_CENTRE,        KEY_CENTRE},
                     59:        { "centre",      TBL_OPT_CENTRE,        KEY_CENTRE},
1.13      schwarze   60:        { "delim",       0,                     KEY_DELIM},
1.1       kristaps   61:        { "expand",      TBL_OPT_EXPAND,        KEY_EXPAND},
1.13      schwarze   62:        { "box",         TBL_OPT_BOX,           KEY_BOX},
                     63:        { "doublebox",   TBL_OPT_DBOX,          KEY_DBOX},
1.1       kristaps   64:        { "allbox",      TBL_OPT_ALLBOX,        KEY_ALLBOX},
                     65:        { "frame",       TBL_OPT_BOX,           KEY_FRAME},
                     66:        { "doubleframe", TBL_OPT_DBOX,          KEY_DFRAME},
                     67:        { "tab",         0,                     KEY_TAB},
                     68:        { "linesize",    0,                     KEY_LINESIZE},
                     69:        { "nokeep",      TBL_OPT_NOKEEP,        KEY_NOKEEP},
                     70:        { "decimalpoint", 0,                    KEY_DPOINT},
                     71:        { "nospaces",    TBL_OPT_NOSPACE,       KEY_NOSPACE},
                     72: };
                     73:
1.17    ! schwarze   74: static void             arg(struct tbl_node *, int,
1.7       kristaps   75:                                const char *, int *, enum tbl_ident);
1.1       kristaps   76:
1.13      schwarze   77:
1.17    ! schwarze   78: static void
1.7       kristaps   79: arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
1.1       kristaps   80: {
1.17    ! schwarze   81:        const char      *optname;
        !            82:        int              len, want;
1.1       kristaps   83:
1.3       kristaps   84:        while (isspace((unsigned char)p[*pos]))
                     85:                (*pos)++;
1.1       kristaps   86:
1.17    ! schwarze   87:        /* Arguments are enclosed in parentheses. */
1.3       kristaps   88:
1.17    ! schwarze   89:        len = 0;
        !            90:        if (p[*pos] == '(') {
        !            91:                (*pos)++;
        !            92:                while (p[*pos + len] != ')')
        !            93:                        len++;
1.1       kristaps   94:        }
                     95:
                     96:        switch (key) {
1.13      schwarze   97:        case KEY_DELIM:
1.17    ! schwarze   98:                optname = "delim";
        !            99:                want = 2;
1.1       kristaps  100:                break;
1.13      schwarze  101:        case KEY_TAB:
1.17    ! schwarze  102:                optname = "tab";
        !           103:                want = 1;
        !           104:                if (len == want)
        !           105:                        tbl->opts.tab = p[*pos];
        !           106:                break;
1.13      schwarze  107:        case KEY_LINESIZE:
1.17    ! schwarze  108:                optname = "linesize";
        !           109:                want = 0;
        !           110:                break;
1.13      schwarze  111:        case KEY_DPOINT:
1.17    ! schwarze  112:                optname = "decimalpoint";
        !           113:                want = 1;
        !           114:                if (len == want)
        !           115:                        tbl->opts.decimal = p[*pos];
        !           116:                break;
1.1       kristaps  117:        default:
                    118:                abort();
1.3       kristaps  119:                /* NOTREACHED */
1.1       kristaps  120:        }
                    121:
1.17    ! schwarze  122:        if (len == 0)
        !           123:                mandoc_msg(MANDOCERR_TBLOPT_NOARG,
        !           124:                    tbl->parse, ln, *pos, optname);
        !           125:        else if (want && len != want)
        !           126:                mandoc_vmsg(MANDOCERR_TBLOPT_ARGSZ,
        !           127:                    tbl->parse, ln, *pos,
        !           128:                    "%s want %d have %d", optname, want, len);
1.1       kristaps  129:
1.17    ! schwarze  130:        *pos += len;
        !           131:        if (p[*pos] == ')')
        !           132:                (*pos)++;
1.1       kristaps  133: }
                    134:
1.17    ! schwarze  135: /*
        !           136:  * Parse one line of options up to the semicolon.
        !           137:  * Each option can be preceded by blanks and/or commas,
        !           138:  * and some options are followed by arguments.
        !           139:  */
        !           140: void
        !           141: tbl_option(struct tbl_node *tbl, int ln, const char *p)
1.1       kristaps  142: {
1.17    ! schwarze  143:        int              i, pos, len;
1.1       kristaps  144:
1.17    ! schwarze  145:        pos = 0;
        !           146:        for (;;) {
        !           147:                while (isspace((unsigned char)p[pos]) || p[pos] == ',')
        !           148:                        pos++;
1.1       kristaps  149:
1.17    ! schwarze  150:                if (p[pos] == ';')
        !           151:                        return;
1.3       kristaps  152:
1.17    ! schwarze  153:                /* Parse one option name. */
1.3       kristaps  154:
1.17    ! schwarze  155:                len = 0;
        !           156:                while (isalpha((unsigned char)p[pos + len]))
        !           157:                        len++;
        !           158:
        !           159:                if (len == 0) {
        !           160:                        mandoc_vmsg(MANDOCERR_TBLOPT_ALPHA,
        !           161:                            tbl->parse, ln, pos, "%c", p[pos]);
        !           162:                        pos++;
        !           163:                        continue;
        !           164:                }
1.3       kristaps  165:
1.17    ! schwarze  166:                /* Look up the option name. */
1.3       kristaps  167:
1.17    ! schwarze  168:                i = 0;
        !           169:                while (i < KEY_MAXKEYS &&
        !           170:                    (strncasecmp(p + pos, keys[i].name, len) ||
        !           171:                     keys[i].name[len] != '\0'))
        !           172:                        i++;
        !           173:
        !           174:                if (i == KEY_MAXKEYS) {
        !           175:                        mandoc_vmsg(MANDOCERR_TBLOPT_BAD, tbl->parse,
        !           176:                            ln, pos, "%.*s", len, p + pos);
        !           177:                        pos += len;
1.1       kristaps  178:                        continue;
1.17    ! schwarze  179:                }
1.3       kristaps  180:
1.17    ! schwarze  181:                /* Handle the option. */
1.3       kristaps  182:
1.17    ! schwarze  183:                pos += len;
1.13      schwarze  184:                if (keys[i].key)
1.5       kristaps  185:                        tbl->opts.opts |= keys[i].key;
1.17    ! schwarze  186:                else
        !           187:                        arg(tbl, ln, p, &pos, keys[i].ident);
1.1       kristaps  188:        }
                    189: }

CVSweb