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