Annotation of mandoc/tbl_opts.c, Revision 1.22
1.22 ! schwarze 1: /* $Id: tbl_opts.c,v 1.21 2015/09/26 00:54:04 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.22 ! schwarze 28: #include "tbl.h"
1.10 kristaps 29: #include "libmandoc.h"
1.1 kristaps 30: #include "libroff.h"
31:
1.18 schwarze 32: #define KEY_DPOINT 0
33: #define KEY_DELIM 1
34: #define KEY_LINESIZE 2
35: #define KEY_TAB 3
1.1 kristaps 36:
37: struct tbl_phrase {
38: const char *name;
39: int key;
40: };
41:
1.18 schwarze 42: static const struct tbl_phrase keys[] = {
43: {"decimalpoint", 0},
44: {"delim", 0},
45: {"linesize", 0},
46: {"tab", 0},
47: {"allbox", TBL_OPT_ALLBOX | TBL_OPT_BOX},
48: {"box", TBL_OPT_BOX},
49: {"frame", TBL_OPT_BOX},
50: {"center", TBL_OPT_CENTRE},
51: {"centre", TBL_OPT_CENTRE},
52: {"doublebox", TBL_OPT_DBOX},
53: {"doubleframe", TBL_OPT_DBOX},
54: {"expand", TBL_OPT_EXPAND},
55: {"nokeep", TBL_OPT_NOKEEP},
56: {"nospaces", TBL_OPT_NOSPACE},
57: {"nowarn", TBL_OPT_NOWARN},
58: };
1.1 kristaps 59:
1.18 schwarze 60: #define KEY_MAXKEYS ((int)(sizeof(keys)/sizeof(keys[0])))
1.1 kristaps 61:
1.18 schwarze 62: static void arg(struct tbl_node *, int, const char *, int *, int);
1.1 kristaps 63:
1.13 schwarze 64:
1.17 schwarze 65: static void
1.18 schwarze 66: arg(struct tbl_node *tbl, int ln, const char *p, int *pos, int key)
1.1 kristaps 67: {
1.17 schwarze 68: int len, want;
1.1 kristaps 69:
1.18 schwarze 70: while (p[*pos] == ' ' || p[*pos] == '\t')
1.3 kristaps 71: (*pos)++;
1.1 kristaps 72:
1.17 schwarze 73: /* Arguments are enclosed in parentheses. */
1.3 kristaps 74:
1.17 schwarze 75: len = 0;
76: if (p[*pos] == '(') {
77: (*pos)++;
78: while (p[*pos + len] != ')')
79: len++;
1.1 kristaps 80: }
81:
82: switch (key) {
1.13 schwarze 83: case KEY_DELIM:
1.20 schwarze 84: mandoc_vmsg(MANDOCERR_TBLOPT_EQN, tbl->parse,
85: ln, *pos, "%.*s", len, p + *pos);
1.17 schwarze 86: want = 2;
1.1 kristaps 87: break;
1.13 schwarze 88: case KEY_TAB:
1.17 schwarze 89: want = 1;
90: if (len == want)
91: tbl->opts.tab = p[*pos];
92: break;
1.13 schwarze 93: case KEY_LINESIZE:
1.17 schwarze 94: want = 0;
95: break;
1.13 schwarze 96: case KEY_DPOINT:
1.17 schwarze 97: want = 1;
98: if (len == want)
99: tbl->opts.decimal = p[*pos];
100: break;
1.1 kristaps 101: default:
102: abort();
103: }
104:
1.17 schwarze 105: if (len == 0)
106: mandoc_msg(MANDOCERR_TBLOPT_NOARG,
1.18 schwarze 107: tbl->parse, ln, *pos, keys[key].name);
1.17 schwarze 108: else if (want && len != want)
109: mandoc_vmsg(MANDOCERR_TBLOPT_ARGSZ,
1.18 schwarze 110: tbl->parse, ln, *pos, "%s want %d have %d",
111: keys[key].name, want, len);
1.1 kristaps 112:
1.17 schwarze 113: *pos += len;
114: if (p[*pos] == ')')
115: (*pos)++;
1.1 kristaps 116: }
117:
1.17 schwarze 118: /*
119: * Parse one line of options up to the semicolon.
120: * Each option can be preceded by blanks and/or commas,
121: * and some options are followed by arguments.
122: */
123: void
1.19 schwarze 124: tbl_option(struct tbl_node *tbl, int ln, const char *p, int *offs)
1.1 kristaps 125: {
1.17 schwarze 126: int i, pos, len;
1.1 kristaps 127:
1.19 schwarze 128: pos = *offs;
1.17 schwarze 129: for (;;) {
1.18 schwarze 130: while (p[pos] == ' ' || p[pos] == '\t' || p[pos] == ',')
1.17 schwarze 131: pos++;
1.1 kristaps 132:
1.19 schwarze 133: if (p[pos] == ';') {
134: *offs = pos + 1;
1.17 schwarze 135: return;
1.19 schwarze 136: }
1.3 kristaps 137:
1.17 schwarze 138: /* Parse one option name. */
1.3 kristaps 139:
1.17 schwarze 140: len = 0;
141: while (isalpha((unsigned char)p[pos + len]))
142: len++;
143:
144: if (len == 0) {
145: mandoc_vmsg(MANDOCERR_TBLOPT_ALPHA,
146: tbl->parse, ln, pos, "%c", p[pos]);
147: pos++;
148: continue;
149: }
1.3 kristaps 150:
1.17 schwarze 151: /* Look up the option name. */
1.3 kristaps 152:
1.17 schwarze 153: i = 0;
154: while (i < KEY_MAXKEYS &&
155: (strncasecmp(p + pos, keys[i].name, len) ||
156: keys[i].name[len] != '\0'))
157: i++;
158:
159: if (i == KEY_MAXKEYS) {
160: mandoc_vmsg(MANDOCERR_TBLOPT_BAD, tbl->parse,
161: ln, pos, "%.*s", len, p + pos);
162: pos += len;
1.1 kristaps 163: continue;
1.17 schwarze 164: }
1.3 kristaps 165:
1.17 schwarze 166: /* Handle the option. */
1.3 kristaps 167:
1.17 schwarze 168: pos += len;
1.13 schwarze 169: if (keys[i].key)
1.5 kristaps 170: tbl->opts.opts |= keys[i].key;
1.17 schwarze 171: else
1.18 schwarze 172: arg(tbl, ln, p, &pos, i);
1.1 kristaps 173: }
174: }
CVSweb