From 445b12f7ab17bc0449361eeb2f956d5a1a9bcdd6 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Mon, 26 Jan 2015 00:57:22 +0000 Subject: Improve (or rather, rewrite) tbl(7) option parsing. * Allow the layout to start after the semicolon on the options line. * Ignore leading commas. * Option arguments cannot contain closing parentheses. * Avoid needless UNSUPP messages. * Better ERROR reporting. * Delete unused "linesize" field in struct tbl_opts. * No need for static buffers. * Garbage collect one almost empty wrapper function. Improved functionality, but minus 40 lines of code. --- tbl.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'tbl.c') diff --git a/tbl.c b/tbl.c index b6492524..184b7da4 100644 --- a/tbl.c +++ b/tbl.c @@ -1,7 +1,7 @@ -/* $Id: tbl.c,v 1.32 2015/01/21 00:47:04 schwarze Exp $ */ +/* $Id: tbl.c,v 1.33 2015/01/26 00:57:22 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2011, 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 @@ -34,29 +34,45 @@ enum rofferr tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs) { - int len; const char *cp; - - cp = &p[offs]; - len = (int)strlen(cp); + int active; /* - * If we're in the options section and we don't have a - * terminating semicolon, assume we've moved directly into the - * layout section. No need to report a warning: this is, - * apparently, standard behaviour. + * In the options section, proceed to the layout section + * after a semicolon, or right away if there is no semicolon. + * Ignore semicolons in arguments. */ - if (TBL_PART_OPTS == tbl->part && len) - if (';' != cp[len - 1]) - tbl->part = TBL_PART_LAYOUT; + if (tbl->part == TBL_PART_OPTS) { + tbl->part = TBL_PART_LAYOUT; + active = 1; + for (cp = p; *cp != '\0'; cp++) { + switch (*cp) { + case '(': + active = 0; + continue; + case ')': + active = 1; + continue; + case ';': + if (active) + break; + continue; + default: + continue; + } + break; + } + if (*cp == ';') { + tbl_option(tbl, ln, p); + if (*(p = cp + 1) == '\0') + return(ROFF_IGN); + } + } - /* Now process each logical section of the table. */ + /* Process the other section types. */ switch (tbl->part) { - case TBL_PART_OPTS: - tbl_option(tbl, ln, p); - return(ROFF_IGN); case TBL_PART_LAYOUT: tbl_layout(tbl, ln, p); return(ROFF_IGN); @@ -81,7 +97,6 @@ tbl_alloc(int pos, int line, struct mparse *parse) tbl->parse = parse; tbl->part = TBL_PART_OPTS; tbl->opts.tab = '\t'; - tbl->opts.linesize = 12; tbl->opts.decimal = '.'; return(tbl); } -- cgit v1.2.3