From 5d69c6a2661bba0a22f3ecfd517e2e9767a38346 Mon Sep 17 00:00:00 2001 From: Cem Keylan Date: Fri, 16 Oct 2020 17:47:01 +0300 Subject: add tools --- usr.bin/mandoc/tbl_opts.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 usr.bin/mandoc/tbl_opts.c (limited to 'usr.bin/mandoc/tbl_opts.c') diff --git a/usr.bin/mandoc/tbl_opts.c b/usr.bin/mandoc/tbl_opts.c new file mode 100644 index 0000000..8f1e77c --- /dev/null +++ b/usr.bin/mandoc/tbl_opts.c @@ -0,0 +1,171 @@ +/* $OpenBSD: tbl_opts.c,v 1.16 2018/12/14 05:17:45 schwarze Exp $ */ +/* + * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2015 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include + +#include +#include +#include +#include + +#include "mandoc.h" +#include "tbl.h" +#include "libmandoc.h" +#include "tbl_int.h" + +#define KEY_DPOINT 0 +#define KEY_DELIM 1 +#define KEY_LINESIZE 2 +#define KEY_TAB 3 + +struct tbl_phrase { + const char *name; + int key; +}; + +static const struct tbl_phrase keys[] = { + {"decimalpoint", 0}, + {"delim", 0}, + {"linesize", 0}, + {"tab", 0}, + {"allbox", TBL_OPT_ALLBOX | TBL_OPT_BOX}, + {"box", TBL_OPT_BOX}, + {"frame", TBL_OPT_BOX}, + {"center", TBL_OPT_CENTRE}, + {"centre", TBL_OPT_CENTRE}, + {"doublebox", TBL_OPT_DBOX}, + {"doubleframe", TBL_OPT_DBOX}, + {"expand", TBL_OPT_EXPAND}, + {"nokeep", TBL_OPT_NOKEEP}, + {"nospaces", TBL_OPT_NOSPACE}, + {"nowarn", TBL_OPT_NOWARN}, +}; + +#define KEY_MAXKEYS ((int)(sizeof(keys)/sizeof(keys[0]))) + +static void arg(struct tbl_node *, int, const char *, int *, int); + + +static void +arg(struct tbl_node *tbl, int ln, const char *p, int *pos, int key) +{ + int len, want; + + while (p[*pos] == ' ' || p[*pos] == '\t') + (*pos)++; + + /* Arguments are enclosed in parentheses. */ + + len = 0; + if (p[*pos] == '(') { + (*pos)++; + while (p[*pos + len] != ')') + len++; + } + + switch (key) { + case KEY_DELIM: + mandoc_msg(MANDOCERR_TBLOPT_EQN, + ln, *pos, "%.*s", len, p + *pos); + want = 2; + break; + case KEY_TAB: + want = 1; + if (len == want) + tbl->opts.tab = p[*pos]; + break; + case KEY_LINESIZE: + want = 0; + break; + case KEY_DPOINT: + want = 1; + if (len == want) + tbl->opts.decimal = p[*pos]; + break; + default: + abort(); + } + + if (len == 0) + mandoc_msg(MANDOCERR_TBLOPT_NOARG, ln, *pos, + "%s", keys[key].name); + else if (want && len != want) + mandoc_msg(MANDOCERR_TBLOPT_ARGSZ, ln, *pos, + "%s want %d have %d", keys[key].name, want, len); + + *pos += len; + if (p[*pos] == ')') + (*pos)++; +} + +/* + * Parse one line of options up to the semicolon. + * Each option can be preceded by blanks and/or commas, + * and some options are followed by arguments. + */ +void +tbl_option(struct tbl_node *tbl, int ln, const char *p, int *offs) +{ + int i, pos, len; + + pos = *offs; + for (;;) { + while (p[pos] == ' ' || p[pos] == '\t' || p[pos] == ',') + pos++; + + if (p[pos] == ';') { + *offs = pos + 1; + return; + } + + /* Parse one option name. */ + + len = 0; + while (isalpha((unsigned char)p[pos + len])) + len++; + + if (len == 0) { + mandoc_msg(MANDOCERR_TBLOPT_ALPHA, + ln, pos, "%c", p[pos]); + pos++; + continue; + } + + /* Look up the option name. */ + + i = 0; + while (i < KEY_MAXKEYS && + (strncasecmp(p + pos, keys[i].name, len) || + keys[i].name[len] != '\0')) + i++; + + if (i == KEY_MAXKEYS) { + mandoc_msg(MANDOCERR_TBLOPT_BAD, + ln, pos, "%.*s", len, p + pos); + pos += len; + continue; + } + + /* Handle the option. */ + + pos += len; + if (keys[i].key) + tbl->opts.opts |= keys[i].key; + else + arg(tbl, ln, p, &pos, i); + } +} -- cgit v1.2.3