summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2017-04-29 12:43:56 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2017-04-29 12:43:56 +0000
commite4a03762c83065142a21c681f115e3405fd81a31 (patch)
tree12ddc0987a0fb73157710f647ae20b6981ab0fc6 /usr.bin/mandoc
parent11ddd3024c30f04c99558f38519a4e5ff9b09661 (diff)
Parser unification: use nice ohashes for all three request and macro tables;
no functional change, minus two source files, minus 200 lines of code.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r--usr.bin/mandoc/Makefile10
-rw-r--r--usr.bin/mandoc/libman.h3
-rw-r--r--usr.bin/mandoc/libmandoc.h4
-rw-r--r--usr.bin/mandoc/libmdoc.h3
-rw-r--r--usr.bin/mandoc/man.c29
-rw-r--r--usr.bin/mandoc/man_hash.c99
-rw-r--r--usr.bin/mandoc/mdoc.c27
-rw-r--r--usr.bin/mandoc/mdoc_hash.c93
-rw-r--r--usr.bin/mandoc/mdoc_macro.c4
-rw-r--r--usr.bin/mandoc/mdoc_validate.c16
-rw-r--r--usr.bin/mandoc/read.c19
-rw-r--r--usr.bin/mandoc/roff.c602
-rw-r--r--usr.bin/mandoc/roff.h9
13 files changed, 357 insertions, 561 deletions
diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile
index 05d3fa5b791..d5943c1e69f 100644
--- a/usr.bin/mandoc/Makefile
+++ b/usr.bin/mandoc/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.105 2017/03/03 14:21:41 schwarze Exp $
+# $OpenBSD: Makefile,v 1.106 2017/04/29 12:43:55 schwarze Exp $
.include <bsd.own.mk>
@@ -8,9 +8,9 @@ LDADD += -lutil -lz
SRCS= mandoc.c mandoc_aux.c mandoc_ohash.c preconv.c read.c \
roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c eqn.c
-SRCS+= mdoc_macro.c mdoc.c mdoc_hash.c \
+SRCS+= mdoc_macro.c mdoc.c \
mdoc_argv.c mdoc_state.c mdoc_validate.c att.c msec.c st.c
-SRCS+= man_macro.c man.c man_hash.c man_validate.c
+SRCS+= man_macro.c man.c man_validate.c
SRCS+= main.c mdoc_term.c tag.c chars.c term.c tree.c man_term.c eqn_term.c
SRCS+= mdoc_man.c
SRCS+= html.c mdoc_html.c man_html.c out.c eqn_html.c
@@ -42,9 +42,9 @@ CLEANFILES += man.cgi cgi.o
# To install, run: sudo make installcgi
# After that, read: man man.cgi.8
-LIBMDOC_OBJS = mdoc_argv.o mdoc_hash.o mdoc_macro.o mdoc_state.o \
+LIBMDOC_OBJS = mdoc_argv.o mdoc_macro.o mdoc_state.o \
mdoc_validate.o mdoc.o att.o st.o
-LIBMAN_OBJS = man.o man_hash.o man_macro.o man_validate.o
+LIBMAN_OBJS = man.o man_macro.o man_validate.o
LIBROFF_OBJS = roff.o eqn.o tbl.o tbl_data.o tbl_layout.o tbl_opts.o
LIBMANDOC_OBJS = ${LIBMDOC_OBJS} ${LIBMAN_OBJS} ${LIBROFF_OBJS} \
mandoc.o mandoc_aux.o mandoc_ohash.o \
diff --git a/usr.bin/mandoc/libman.h b/usr.bin/mandoc/libman.h
index be75f979980..f3ad8d898b3 100644
--- a/usr.bin/mandoc/libman.h
+++ b/usr.bin/mandoc/libman.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libman.h,v 1.55 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: libman.h,v 1.56 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -35,7 +35,6 @@ struct man_macro {
extern const struct man_macro *const man_macros;
-enum roff_tok man_hash_find(const char *);
void man_node_validate(struct roff_man *);
void man_state(struct roff_man *, struct roff_node *);
void man_unscope(struct roff_man *, const struct roff_node *);
diff --git a/usr.bin/mandoc/libmandoc.h b/usr.bin/mandoc/libmandoc.h
index 4f82e71a6fd..41d31723c88 100644
--- a/usr.bin/mandoc/libmandoc.h
+++ b/usr.bin/mandoc/libmandoc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libmandoc.h,v 1.51 2017/02/18 13:43:34 schwarze Exp $ */
+/* $OpenBSD: libmandoc.h,v 1.52 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -50,11 +50,9 @@ int mandoc_eos(const char *, size_t);
int mandoc_strntoi(const char *, size_t, int);
const char *mandoc_a2msec(const char*);
-void mdoc_hash_init(void);
int mdoc_parseln(struct roff_man *, int, char *, int);
void mdoc_endparse(struct roff_man *);
-void man_hash_init(void);
int man_parseln(struct roff_man *, int, char *, int);
void man_endparse(struct roff_man *);
diff --git a/usr.bin/mandoc/libmdoc.h b/usr.bin/mandoc/libmdoc.h
index 8d267bf144b..708f3a15263 100644
--- a/usr.bin/mandoc/libmdoc.h
+++ b/usr.bin/mandoc/libmdoc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libmdoc.h,v 1.81 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: libmdoc.h,v 1.82 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -76,7 +76,6 @@ void mdoc_node_relink(struct roff_man *, struct roff_node *);
void mdoc_node_validate(struct roff_man *);
void mdoc_state(struct roff_man *, struct roff_node *);
void mdoc_state_reset(struct roff_man *);
-enum roff_tok mdoc_hash_find(const char *);
const char *mdoc_a2arch(const char *);
const char *mdoc_a2att(const char *);
enum roff_sec mdoc_a2sec(const char *);
diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c
index 8246784d40e..1db9e879202 100644
--- a/usr.bin/mandoc/man.c
+++ b/usr.bin/mandoc/man.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: man.c,v 1.117 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: man.c,v 1.118 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -143,26 +143,19 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
{
struct roff_node *n;
const char *cp;
- int tok;
- int i, ppos;
+ size_t sz;
+ enum roff_tok tok;
+ int ppos;
int bline;
- char mac[5];
- ppos = offs;
-
- /*
- * Copy the first word into a nil-terminated buffer.
- * Stop when a space, tab, escape, or eoln is encountered.
- */
-
- i = 0;
- while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
- mac[i++] = buf[offs++];
-
- mac[i] = '\0';
-
- tok = (i > 0 && i < 4) ? man_hash_find(mac) : TOKEN_NONE;
+ /* Determine the line macro. */
+ ppos = offs;
+ tok = TOKEN_NONE;
+ for (sz = 0; sz < 4 && strchr(" \t\\", buf[offs]) == NULL; sz++)
+ offs++;
+ if (sz > 0 && sz < 4)
+ tok = roffhash_find(man->manmac, buf + ppos, sz);
if (tok == TOKEN_NONE) {
mandoc_msg(MANDOCERR_MACRO, man->parse,
ln, ppos, buf + ppos - 1);
diff --git a/usr.bin/mandoc/man_hash.c b/usr.bin/mandoc/man_hash.c
deleted file mode 100644
index 8b592f03de3..00000000000
--- a/usr.bin/mandoc/man_hash.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* $OpenBSD: man_hash.c,v 1.26 2017/04/24 23:06:09 schwarze Exp $ */
-/*
- * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
- *
- * 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 <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <limits.h>
-#include <string.h>
-
-#include "mandoc.h"
-#include "roff.h"
-#include "man.h"
-#include "libmandoc.h"
-#include "libman.h"
-
-#define HASH_DEPTH 6
-
-#define HASH_ROW(x) do { \
- if (isupper((unsigned char)(x))) \
- (x) -= 65; \
- else \
- (x) -= 97; \
- (x) *= HASH_DEPTH; \
- } while (/* CONSTCOND */ 0)
-
-/*
- * Lookup table is indexed first by lower-case first letter (plus one
- * for the period, which is stored in the last row), then by lower or
- * uppercase second letter. Buckets correspond to the index of the
- * macro (the integer value of the enum stored as a char to save a bit
- * of space).
- */
-static unsigned char table[26 * HASH_DEPTH];
-
-
-void
-man_hash_init(void)
-{
- int i, j, x;
-
- if (*table != '\0')
- return;
-
- memset(table, UCHAR_MAX, sizeof(table));
-
- for (i = 0; i < (int)(MAN_MAX - MAN_TH); i++) {
- x = *roff_name[MAN_TH + i];
-
- assert(isalpha((unsigned char)x));
-
- HASH_ROW(x);
-
- for (j = 0; j < HASH_DEPTH; j++)
- if (UCHAR_MAX == table[x + j]) {
- table[x + j] = (unsigned char)i;
- break;
- }
-
- assert(j < HASH_DEPTH);
- }
-}
-
-enum roff_tok
-man_hash_find(const char *tmp)
-{
- int x, y, i;
-
- if ('\0' == (x = tmp[0]))
- return TOKEN_NONE;
- if ( ! (isalpha((unsigned char)x)))
- return TOKEN_NONE;
-
- HASH_ROW(x);
-
- for (i = 0; i < HASH_DEPTH; i++) {
- if (UCHAR_MAX == (y = table[x + i]))
- return TOKEN_NONE;
-
- if (strcmp(tmp, roff_name[MAN_TH + y]) == 0)
- return MAN_TH + y;
- }
-
- return TOKEN_NONE;
-}
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index e3e4d89ea4a..7ab4487d7d9 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc.c,v 1.151 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: mdoc.c,v 1.152 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -300,25 +300,18 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
{
struct roff_node *n;
const char *cp;
+ size_t sz;
enum roff_tok tok;
- int i, sv;
- char mac[5];
+ int sv;
- sv = offs;
-
- /*
- * Copy the first word into a nil-terminated buffer.
- * Stop when a space, tab, escape, or eoln is encountered.
- */
-
- i = 0;
- while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
- mac[i++] = buf[offs++];
-
- mac[i] = '\0';
-
- tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : TOKEN_NONE;
+ /* Determine the line macro. */
+ sv = offs;
+ tok = TOKEN_NONE;
+ for (sz = 0; sz < 4 && strchr(" \t\\", buf[offs]) == NULL; sz++)
+ offs++;
+ if (sz == 2 || sz == 3)
+ tok = roffhash_find(mdoc->mdocmac, buf + sv, sz);
if (tok == TOKEN_NONE) {
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
ln, sv, buf + sv - 1);
diff --git a/usr.bin/mandoc/mdoc_hash.c b/usr.bin/mandoc/mdoc_hash.c
deleted file mode 100644
index 375cd45cb93..00000000000
--- a/usr.bin/mandoc/mdoc_hash.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* $OpenBSD: mdoc_hash.c,v 1.23 2017/04/24 23:06:09 schwarze Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
- *
- * 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 <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "mandoc.h"
-#include "roff.h"
-#include "mdoc.h"
-#include "libmandoc.h"
-#include "libmdoc.h"
-
-static unsigned char table[27 * 12];
-
-
-void
-mdoc_hash_init(void)
-{
- int i, j, major;
- const char *p;
-
- if (*table != '\0')
- return;
-
- memset(table, UCHAR_MAX, sizeof(table));
-
- for (i = 0; i < (int)(MDOC_MAX - MDOC_Dd); i++) {
- p = roff_name[MDOC_Dd + i];
-
- if (isalpha((unsigned char)p[1]))
- major = 12 * (tolower((unsigned char)p[1]) - 97);
- else
- major = 12 * 26;
-
- for (j = 0; j < 12; j++)
- if (UCHAR_MAX == table[major + j]) {
- table[major + j] = (unsigned char)i;
- break;
- }
-
- assert(j < 12);
- }
-}
-
-enum roff_tok
-mdoc_hash_find(const char *p)
-{
- int major, i, j;
-
- if (0 == p[0])
- return TOKEN_NONE;
- if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
- return TOKEN_NONE;
-
- if (isalpha((unsigned char)p[1]))
- major = 12 * (tolower((unsigned char)p[1]) - 97);
- else if ('1' == p[1])
- major = 12 * 26;
- else
- return TOKEN_NONE;
-
- if (p[2] && p[3])
- return TOKEN_NONE;
-
- for (j = 0; j < 12; j++) {
- if (UCHAR_MAX == (i = table[major + j]))
- break;
- if (strcmp(p, roff_name[MDOC_Dd + i]) == 0)
- return MDOC_Dd + i;
- }
-
- return TOKEN_NONE;
-}
diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c
index 5af20a7de66..9a9c777f53a 100644
--- a/usr.bin/mandoc/mdoc_macro.c
+++ b/usr.bin/mandoc/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc_macro.c,v 1.176 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: mdoc_macro.c,v 1.177 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -245,7 +245,7 @@ lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p)
return TOKEN_NONE;
}
if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) {
- res = mdoc_hash_find(p);
+ res = roffhash_find(mdoc->mdocmac, p, 0);
if (res != TOKEN_NONE) {
if (mdoc_macros[res].flags & MDOC_CALLABLE)
return res;
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index c6994926dd5..2450bfb10be 100644
--- a/usr.bin/mandoc/mdoc_validate.c
+++ b/usr.bin/mandoc/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mdoc_validate.c,v 1.237 2017/04/28 16:23:30 schwarze Exp $ */
+/* $OpenBSD: mdoc_validate.c,v 1.238 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -56,7 +56,7 @@ static void check_argv(struct roff_man *,
static void check_args(struct roff_man *, struct roff_node *);
static int child_an(const struct roff_node *);
static size_t macro2len(enum roff_tok);
-static void rewrite_macro2len(char **);
+static void rewrite_macro2len(struct roff_man *, char **);
static void post_an(POST_ARGS);
static void post_an_norm(POST_ARGS);
@@ -449,7 +449,7 @@ post_bl_norm(POST_ARGS)
mdoc->parse, argv->line,
argv->pos, "Bl -width %s",
argv->value[0]);
- rewrite_macro2len(argv->value);
+ rewrite_macro2len(mdoc, argv->value);
n->norm->Bl.width = argv->value[0];
break;
case MDOC_Offset:
@@ -464,7 +464,7 @@ post_bl_norm(POST_ARGS)
mdoc->parse, argv->line,
argv->pos, "Bl -offset %s",
argv->value[0]);
- rewrite_macro2len(argv->value);
+ rewrite_macro2len(mdoc, argv->value);
n->norm->Bl.offs = argv->value[0];
break;
default:
@@ -591,7 +591,7 @@ post_bd(POST_ARGS)
mdoc->parse, argv->line,
argv->pos, "Bd -offset %s",
argv->value[0]);
- rewrite_macro2len(argv->value);
+ rewrite_macro2len(mdoc, argv->value);
n->norm->Bd.offs = argv->value[0];
break;
case MDOC_Compact:
@@ -1326,8 +1326,8 @@ post_bl_block(POST_ARGS)
* If the argument of -offset or -width is a macro,
* replace it with the associated default width.
*/
-void
-rewrite_macro2len(char **arg)
+static void
+rewrite_macro2len(struct roff_man *mdoc, char **arg)
{
size_t width;
enum roff_tok tok;
@@ -1336,7 +1336,7 @@ rewrite_macro2len(char **arg)
return;
else if ( ! strcmp(*arg, "Ds"))
width = 6;
- else if ((tok = mdoc_hash_find(*arg)) == TOKEN_NONE)
+ else if ((tok = roffhash_find(mdoc->mdocmac, *arg, 0)) == TOKEN_NONE)
return;
else
width = macro2len(tok);
diff --git a/usr.bin/mandoc/read.c b/usr.bin/mandoc/read.c
index f316ba3a0b9..fe2aad9e198 100644
--- a/usr.bin/mandoc/read.c
+++ b/usr.bin/mandoc/read.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: read.c,v 1.135 2017/03/07 20:00:02 schwarze Exp $ */
+/* $OpenBSD: read.c,v 1.136 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -289,14 +289,15 @@ choose_parser(struct mparse *curp)
}
if (format == MPARSE_MDOC) {
- mdoc_hash_init();
curp->man->macroset = MACROSET_MDOC;
- curp->man->first->tok = TOKEN_NONE;
+ if (curp->man->mdocmac == NULL)
+ curp->man->mdocmac = roffhash_alloc(MDOC_Dd, MDOC_MAX);
} else {
- man_hash_init();
curp->man->macroset = MACROSET_MAN;
- curp->man->first->tok = TOKEN_NONE;
+ if (curp->man->manmac == NULL)
+ curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX);
}
+ curp->man->first->tok = TOKEN_NONE;
}
/*
@@ -801,11 +802,13 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
curp->man = roff_man_alloc( curp->roff, curp, curp->defos,
curp->options & MPARSE_QUICK ? 1 : 0);
if (curp->options & MPARSE_MDOC) {
- mdoc_hash_init();
curp->man->macroset = MACROSET_MDOC;
+ if (curp->man->mdocmac == NULL)
+ curp->man->mdocmac = roffhash_alloc(MDOC_Dd, MDOC_MAX);
} else if (curp->options & MPARSE_MAN) {
- man_hash_init();
curp->man->macroset = MACROSET_MAN;
+ if (curp->man->manmac == NULL)
+ curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX);
}
curp->man->first->tok = TOKEN_NONE;
return curp;
@@ -831,6 +834,8 @@ void
mparse_free(struct mparse *curp)
{
+ roffhash_free(curp->man->mdocmac);
+ roffhash_free(curp->man->manmac);
roff_man_free(curp->man);
roff_free(curp->roff);
if (curp->secondary)
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index be902c3b649..5ca2cbf9e28 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.166 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.167 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -20,12 +20,15 @@
#include <assert.h>
#include <ctype.h>
#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mandoc.h"
#include "mandoc_aux.h"
+#include "mandoc_ohash.h"
#include "roff.h"
#include "libmandoc.h"
#include "roff_int.h"
@@ -62,10 +65,19 @@ struct roffreg {
struct roffreg *next;
};
+/*
+ * Association of request and macro names with token IDs.
+ */
+struct roffreq {
+ enum roff_tok tok;
+ char name[];
+};
+
struct roff {
struct mparse *parse; /* parse point */
struct roffnode *last; /* leaf of stack */
int *rstack; /* stack of inverted `ie' values */
+ struct ohash *reqtab; /* request lookup table */
struct roffreg *regtab; /* number registers */
struct roffkv *strtab; /* user-defined strings & macros */
struct roffkv *xmbtab; /* multi-byte trans table (`tr') */
@@ -108,13 +120,11 @@ struct roffnode {
typedef enum rofferr (*roffproc)(ROFF_ARGS);
struct roffmac {
- const char *name; /* macro name */
roffproc proc; /* process new macro */
roffproc text; /* process as child text of macro */
roffproc sub; /* process as child of macro */
int flags;
#define ROFFMAC_STRUCT (1 << 0) /* always interpret */
- struct roffmac *next;
};
struct predef {
@@ -127,8 +137,6 @@ struct predef {
/* --- function prototypes ------------------------------------------------ */
-static enum roff_tok roffhash_find(const char *, size_t);
-static void roffhash_init(void);
static void roffnode_cleanscope(struct roff *);
static void roffnode_pop(struct roff *);
static void roffnode_push(struct roff *, enum roff_tok,
@@ -195,12 +203,6 @@ static enum rofferr roff_userdef(ROFF_ARGS);
/* --- constant data ------------------------------------------------------ */
-/* See roffhash_find() */
-
-#define ASCII_HI 126
-#define ASCII_LO 33
-#define HASHWIDTH (ASCII_HI - ASCII_LO + 1)
-
#define ROFFNUM_SCALE (1 << 0) /* Honour scaling in roff_getnum(). */
#define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */
@@ -309,245 +311,243 @@ const char *__roff_name[MAN_MAX + 1] = {
};
const char *const *roff_name = __roff_name;
-static struct roffmac *hash[HASHWIDTH];
-
static struct roffmac roffs[TOKEN_NONE] = {
- { "ab", roff_unsupp, NULL, NULL, 0, NULL },
- { "ad", roff_line_ignore, NULL, NULL, 0, NULL },
- { "af", roff_line_ignore, NULL, NULL, 0, NULL },
- { "aln", roff_unsupp, NULL, NULL, 0, NULL },
- { "als", roff_unsupp, NULL, NULL, 0, NULL },
- { "am", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "am1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "ami", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "ami1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "as", roff_ds, NULL, NULL, 0, NULL },
- { "as1", roff_ds, NULL, NULL, 0, NULL },
- { "asciify", roff_unsupp, NULL, NULL, 0, NULL },
- { "backtrace", roff_line_ignore, NULL, NULL, 0, NULL },
- { "bd", roff_line_ignore, NULL, NULL, 0, NULL },
- { "bleedat", roff_line_ignore, NULL, NULL, 0, NULL },
- { "blm", roff_unsupp, NULL, NULL, 0, NULL },
- { "box", roff_unsupp, NULL, NULL, 0, NULL },
- { "boxa", roff_unsupp, NULL, NULL, 0, NULL },
- { "bp", roff_line_ignore, NULL, NULL, 0, NULL },
- { "BP", roff_unsupp, NULL, NULL, 0, NULL },
- { "break", roff_unsupp, NULL, NULL, 0, NULL },
- { "breakchar", roff_line_ignore, NULL, NULL, 0, NULL },
- { "brnl", roff_line_ignore, NULL, NULL, 0, NULL },
- { "brp", roff_brp, NULL, NULL, 0, NULL },
- { "brpnl", roff_line_ignore, NULL, NULL, 0, NULL },
- { "c2", roff_unsupp, NULL, NULL, 0, NULL },
- { "cc", roff_cc, NULL, NULL, 0, NULL },
- { "ce", roff_line_ignore, NULL, NULL, 0, NULL },
- { "cf", roff_insec, NULL, NULL, 0, NULL },
- { "cflags", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ch", roff_line_ignore, NULL, NULL, 0, NULL },
- { "char", roff_unsupp, NULL, NULL, 0, NULL },
- { "chop", roff_unsupp, NULL, NULL, 0, NULL },
- { "class", roff_line_ignore, NULL, NULL, 0, NULL },
- { "close", roff_insec, NULL, NULL, 0, NULL },
- { "CL", roff_unsupp, NULL, NULL, 0, NULL },
- { "color", roff_line_ignore, NULL, NULL, 0, NULL },
- { "composite", roff_unsupp, NULL, NULL, 0, NULL },
- { "continue", roff_unsupp, NULL, NULL, 0, NULL },
- { "cp", roff_line_ignore, NULL, NULL, 0, NULL },
- { "cropat", roff_line_ignore, NULL, NULL, 0, NULL },
- { "cs", roff_line_ignore, NULL, NULL, 0, NULL },
- { "cu", roff_line_ignore, NULL, NULL, 0, NULL },
- { "da", roff_unsupp, NULL, NULL, 0, NULL },
- { "dch", roff_unsupp, NULL, NULL, 0, NULL },
- { "Dd", roff_Dd, NULL, NULL, 0, NULL },
- { "de", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "defcolor", roff_line_ignore, NULL, NULL, 0, NULL },
- { "dei", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "dei1", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "device", roff_unsupp, NULL, NULL, 0, NULL },
- { "devicem", roff_unsupp, NULL, NULL, 0, NULL },
- { "di", roff_unsupp, NULL, NULL, 0, NULL },
- { "do", roff_unsupp, NULL, NULL, 0, NULL },
- { "ds", roff_ds, NULL, NULL, 0, NULL },
- { "ds1", roff_ds, NULL, NULL, 0, NULL },
- { "dwh", roff_unsupp, NULL, NULL, 0, NULL },
- { "dt", roff_unsupp, NULL, NULL, 0, NULL },
- { "ec", roff_unsupp, NULL, NULL, 0, NULL },
- { "ecr", roff_unsupp, NULL, NULL, 0, NULL },
- { "ecs", roff_unsupp, NULL, NULL, 0, NULL },
- { "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
- { "em", roff_unsupp, NULL, NULL, 0, NULL },
- { "EN", roff_EN, NULL, NULL, 0, NULL },
- { "eo", roff_unsupp, NULL, NULL, 0, NULL },
- { "EP", roff_unsupp, NULL, NULL, 0, NULL },
- { "EQ", roff_EQ, NULL, NULL, 0, NULL },
- { "errprint", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ev", roff_unsupp, NULL, NULL, 0, NULL },
- { "evc", roff_unsupp, NULL, NULL, 0, NULL },
- { "ex", roff_unsupp, NULL, NULL, 0, NULL },
- { "fallback", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fam", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fc", roff_unsupp, NULL, NULL, 0, NULL },
- { "fchar", roff_unsupp, NULL, NULL, 0, NULL },
- { "fcolor", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fdeferlig", roff_line_ignore, NULL, NULL, 0, NULL },
- { "feature", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fkern", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fl", roff_line_ignore, NULL, NULL, 0, NULL },
- { "flig", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fp", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fps", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fschar", roff_unsupp, NULL, NULL, 0, NULL },
- { "fspacewidth", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fspecial", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ftr", roff_line_ignore, NULL, NULL, 0, NULL },
- { "fzoom", roff_line_ignore, NULL, NULL, 0, NULL },
- { "gcolor", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hc", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hcode", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hidechar", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hla", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hlm", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hpf", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hpfa", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hpfcode", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hw", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hy", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hylang", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hylen", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hym", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hypp", roff_line_ignore, NULL, NULL, 0, NULL },
- { "hys", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
- { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
- { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },
- { "index", roff_unsupp, NULL, NULL, 0, NULL },
- { "it", roff_it, NULL, NULL, 0, NULL },
- { "itc", roff_unsupp, NULL, NULL, 0, NULL },
- { "IX", roff_line_ignore, NULL, NULL, 0, NULL },
- { "kern", roff_line_ignore, NULL, NULL, 0, NULL },
- { "kernafter", roff_line_ignore, NULL, NULL, 0, NULL },
- { "kernbefore", roff_line_ignore, NULL, NULL, 0, NULL },
- { "kernpair", roff_line_ignore, NULL, NULL, 0, NULL },
- { "lc", roff_unsupp, NULL, NULL, 0, NULL },
- { "lc_ctype", roff_unsupp, NULL, NULL, 0, NULL },
- { "lds", roff_unsupp, NULL, NULL, 0, NULL },
- { "length", roff_unsupp, NULL, NULL, 0, NULL },
- { "letadj", roff_line_ignore, NULL, NULL, 0, NULL },
- { "lf", roff_insec, NULL, NULL, 0, NULL },
- { "lg", roff_line_ignore, NULL, NULL, 0, NULL },
- { "lhang", roff_line_ignore, NULL, NULL, 0, NULL },
- { "linetabs", roff_unsupp, NULL, NULL, 0, NULL },
- { "lnr", roff_unsupp, NULL, NULL, 0, NULL },
- { "lnrf", roff_unsupp, NULL, NULL, 0, NULL },
- { "lpfx", roff_unsupp, NULL, NULL, 0, NULL },
- { "ls", roff_line_ignore, NULL, NULL, 0, NULL },
- { "lsm", roff_unsupp, NULL, NULL, 0, NULL },
- { "lt", roff_line_ignore, NULL, NULL, 0, NULL },
- { "mc", roff_line_ignore, NULL, NULL, 0, NULL },
- { "mediasize", roff_line_ignore, NULL, NULL, 0, NULL },
- { "minss", roff_line_ignore, NULL, NULL, 0, NULL },
- { "mk", roff_line_ignore, NULL, NULL, 0, NULL },
- { "mso", roff_insec, NULL, NULL, 0, NULL },
- { "na", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ne", roff_line_ignore, NULL, NULL, 0, NULL },
- { "nh", roff_line_ignore, NULL, NULL, 0, NULL },
- { "nhychar", roff_line_ignore, NULL, NULL, 0, NULL },
- { "nm", roff_unsupp, NULL, NULL, 0, NULL },
- { "nn", roff_unsupp, NULL, NULL, 0, NULL },
- { "nop", roff_unsupp, NULL, NULL, 0, NULL },
- { "nr", roff_nr, NULL, NULL, 0, NULL },
- { "nrf", roff_unsupp, NULL, NULL, 0, NULL },
- { "nroff", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ns", roff_line_ignore, NULL, NULL, 0, NULL },
- { "nx", roff_insec, NULL, NULL, 0, NULL },
- { "open", roff_insec, NULL, NULL, 0, NULL },
- { "opena", roff_insec, NULL, NULL, 0, NULL },
- { "os", roff_line_ignore, NULL, NULL, 0, NULL },
- { "output", roff_unsupp, NULL, NULL, 0, NULL },
- { "padj", roff_line_ignore, NULL, NULL, 0, NULL },
- { "papersize", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pc", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pev", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pi", roff_insec, NULL, NULL, 0, NULL },
- { "PI", roff_unsupp, NULL, NULL, 0, NULL },
- { "pl", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pm", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pn", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pnr", roff_line_ignore, NULL, NULL, 0, NULL },
- { "po", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ps", roff_line_ignore, NULL, NULL, 0, NULL },
- { "psbb", roff_unsupp, NULL, NULL, 0, NULL },
- { "pshape", roff_unsupp, NULL, NULL, 0, NULL },
- { "pso", roff_insec, NULL, NULL, 0, NULL },
- { "ptr", roff_line_ignore, NULL, NULL, 0, NULL },
- { "pvs", roff_line_ignore, NULL, NULL, 0, NULL },
- { "rchar", roff_unsupp, NULL, NULL, 0, NULL },
- { "rd", roff_line_ignore, NULL, NULL, 0, NULL },
- { "recursionlimit", roff_line_ignore, NULL, NULL, 0, NULL },
- { "return", roff_unsupp, NULL, NULL, 0, NULL },
- { "rfschar", roff_unsupp, NULL, NULL, 0, NULL },
- { "rhang", roff_line_ignore, NULL, NULL, 0, NULL },
- { "rj", roff_line_ignore, NULL, NULL, 0, NULL },
- { "rm", roff_rm, NULL, NULL, 0, NULL },
- { "rn", roff_unsupp, NULL, NULL, 0, NULL },
- { "rnn", roff_unsupp, NULL, NULL, 0, NULL },
- { "rr", roff_rr, NULL, NULL, 0, NULL },
- { "rs", roff_line_ignore, NULL, NULL, 0, NULL },
- { "rt", roff_line_ignore, NULL, NULL, 0, NULL },
- { "schar", roff_unsupp, NULL, NULL, 0, NULL },
- { "sentchar", roff_line_ignore, NULL, NULL, 0, NULL },
- { "shc", roff_line_ignore, NULL, NULL, 0, NULL },
- { "shift", roff_unsupp, NULL, NULL, 0, NULL },
- { "sizes", roff_line_ignore, NULL, NULL, 0, NULL },
- { "so", roff_so, NULL, NULL, 0, NULL },
- { "spacewidth", roff_line_ignore, NULL, NULL, 0, NULL },
- { "special", roff_line_ignore, NULL, NULL, 0, NULL },
- { "spreadwarn", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ss", roff_line_ignore, NULL, NULL, 0, NULL },
- { "sty", roff_line_ignore, NULL, NULL, 0, NULL },
- { "substring", roff_unsupp, NULL, NULL, 0, NULL },
- { "sv", roff_line_ignore, NULL, NULL, 0, NULL },
- { "sy", roff_insec, NULL, NULL, 0, NULL },
- { "T&", roff_T_, NULL, NULL, 0, NULL },
- { "ta", roff_unsupp, NULL, NULL, 0, NULL },
- { "tc", roff_unsupp, NULL, NULL, 0, NULL },
- { "TE", roff_TE, NULL, NULL, 0, NULL },
- { "TH", roff_TH, NULL, NULL, 0, NULL },
- { "ti", roff_unsupp, NULL, NULL, 0, NULL },
- { "tkf", roff_line_ignore, NULL, NULL, 0, NULL },
- { "tl", roff_unsupp, NULL, NULL, 0, NULL },
- { "tm", roff_line_ignore, NULL, NULL, 0, NULL },
- { "tm1", roff_line_ignore, NULL, NULL, 0, NULL },
- { "tmc", roff_line_ignore, NULL, NULL, 0, NULL },
- { "tr", roff_tr, NULL, NULL, 0, NULL },
- { "track", roff_line_ignore, NULL, NULL, 0, NULL },
- { "transchar", roff_line_ignore, NULL, NULL, 0, NULL },
- { "trf", roff_insec, NULL, NULL, 0, NULL },
- { "trimat", roff_line_ignore, NULL, NULL, 0, NULL },
- { "trin", roff_unsupp, NULL, NULL, 0, NULL },
- { "trnt", roff_unsupp, NULL, NULL, 0, NULL },
- { "troff", roff_line_ignore, NULL, NULL, 0, NULL },
- { "TS", roff_TS, NULL, NULL, 0, NULL },
- { "uf", roff_line_ignore, NULL, NULL, 0, NULL },
- { "ul", roff_line_ignore, NULL, NULL, 0, NULL },
- { "unformat", roff_unsupp, NULL, NULL, 0, NULL },
- { "unwatch", roff_line_ignore, NULL, NULL, 0, NULL },
- { "unwatchn", roff_line_ignore, NULL, NULL, 0, NULL },
- { "vpt", roff_line_ignore, NULL, NULL, 0, NULL },
- { "vs", roff_line_ignore, NULL, NULL, 0, NULL },
- { "warn", roff_line_ignore, NULL, NULL, 0, NULL },
- { "warnscale", roff_line_ignore, NULL, NULL, 0, NULL },
- { "watch", roff_line_ignore, NULL, NULL, 0, NULL },
- { "watchlength", roff_line_ignore, NULL, NULL, 0, NULL },
- { "watchn", roff_line_ignore, NULL, NULL, 0, NULL },
- { "wh", roff_unsupp, NULL, NULL, 0, NULL },
- { "while", roff_unsupp, NULL, NULL, 0, NULL },
- { "write", roff_insec, NULL, NULL, 0, NULL },
- { "writec", roff_insec, NULL, NULL, 0, NULL },
- { "writem", roff_insec, NULL, NULL, 0, NULL },
- { "xflag", roff_line_ignore, NULL, NULL, 0, NULL },
- { ".", roff_cblock, NULL, NULL, 0, NULL },
- { NULL, roff_userdef, NULL, NULL, 0, NULL },
+ { roff_unsupp, NULL, NULL, 0 }, /* ab */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ad */
+ { roff_line_ignore, NULL, NULL, 0 }, /* af */
+ { roff_unsupp, NULL, NULL, 0 }, /* aln */
+ { roff_unsupp, NULL, NULL, 0 }, /* als */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* am */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* am1 */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* ami */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* ami1 */
+ { roff_ds, NULL, NULL, 0 }, /* as */
+ { roff_ds, NULL, NULL, 0 }, /* as1 */
+ { roff_unsupp, NULL, NULL, 0 }, /* asciify */
+ { roff_line_ignore, NULL, NULL, 0 }, /* backtrace */
+ { roff_line_ignore, NULL, NULL, 0 }, /* bd */
+ { roff_line_ignore, NULL, NULL, 0 }, /* bleedat */
+ { roff_unsupp, NULL, NULL, 0 }, /* blm */
+ { roff_unsupp, NULL, NULL, 0 }, /* box */
+ { roff_unsupp, NULL, NULL, 0 }, /* boxa */
+ { roff_line_ignore, NULL, NULL, 0 }, /* bp */
+ { roff_unsupp, NULL, NULL, 0 }, /* BP */
+ { roff_unsupp, NULL, NULL, 0 }, /* break */
+ { roff_line_ignore, NULL, NULL, 0 }, /* breakchar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* brnl */
+ { roff_brp, NULL, NULL, 0 }, /* brp */
+ { roff_line_ignore, NULL, NULL, 0 }, /* brpnl */
+ { roff_unsupp, NULL, NULL, 0 }, /* c2 */
+ { roff_cc, NULL, NULL, 0 }, /* cc */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ce */
+ { roff_insec, NULL, NULL, 0 }, /* cf */
+ { roff_line_ignore, NULL, NULL, 0 }, /* cflags */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ch */
+ { roff_unsupp, NULL, NULL, 0 }, /* char */
+ { roff_unsupp, NULL, NULL, 0 }, /* chop */
+ { roff_line_ignore, NULL, NULL, 0 }, /* class */
+ { roff_insec, NULL, NULL, 0 }, /* close */
+ { roff_unsupp, NULL, NULL, 0 }, /* CL */
+ { roff_line_ignore, NULL, NULL, 0 }, /* color */
+ { roff_unsupp, NULL, NULL, 0 }, /* composite */
+ { roff_unsupp, NULL, NULL, 0 }, /* continue */
+ { roff_line_ignore, NULL, NULL, 0 }, /* cp */
+ { roff_line_ignore, NULL, NULL, 0 }, /* cropat */
+ { roff_line_ignore, NULL, NULL, 0 }, /* cs */
+ { roff_line_ignore, NULL, NULL, 0 }, /* cu */
+ { roff_unsupp, NULL, NULL, 0 }, /* da */
+ { roff_unsupp, NULL, NULL, 0 }, /* dch */
+ { roff_Dd, NULL, NULL, 0 }, /* Dd */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* de */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* de1 */
+ { roff_line_ignore, NULL, NULL, 0 }, /* defcolor */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* dei */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* dei1 */
+ { roff_unsupp, NULL, NULL, 0 }, /* device */
+ { roff_unsupp, NULL, NULL, 0 }, /* devicem */
+ { roff_unsupp, NULL, NULL, 0 }, /* di */
+ { roff_unsupp, NULL, NULL, 0 }, /* do */
+ { roff_ds, NULL, NULL, 0 }, /* ds */
+ { roff_ds, NULL, NULL, 0 }, /* ds1 */
+ { roff_unsupp, NULL, NULL, 0 }, /* dwh */
+ { roff_unsupp, NULL, NULL, 0 }, /* dt */
+ { roff_unsupp, NULL, NULL, 0 }, /* ec */
+ { roff_unsupp, NULL, NULL, 0 }, /* ecr */
+ { roff_unsupp, NULL, NULL, 0 }, /* ecs */
+ { roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT }, /* el */
+ { roff_unsupp, NULL, NULL, 0 }, /* em */
+ { roff_EN, NULL, NULL, 0 }, /* EN */
+ { roff_unsupp, NULL, NULL, 0 }, /* eo */
+ { roff_unsupp, NULL, NULL, 0 }, /* EP */
+ { roff_EQ, NULL, NULL, 0 }, /* EQ */
+ { roff_line_ignore, NULL, NULL, 0 }, /* errprint */
+ { roff_unsupp, NULL, NULL, 0 }, /* ev */
+ { roff_unsupp, NULL, NULL, 0 }, /* evc */
+ { roff_unsupp, NULL, NULL, 0 }, /* ex */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fallback */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fam */
+ { roff_unsupp, NULL, NULL, 0 }, /* fc */
+ { roff_unsupp, NULL, NULL, 0 }, /* fchar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fcolor */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fdeferlig */
+ { roff_line_ignore, NULL, NULL, 0 }, /* feature */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fkern */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fl */
+ { roff_line_ignore, NULL, NULL, 0 }, /* flig */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fp */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fps */
+ { roff_unsupp, NULL, NULL, 0 }, /* fschar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fspacewidth */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fspecial */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ftr */
+ { roff_line_ignore, NULL, NULL, 0 }, /* fzoom */
+ { roff_line_ignore, NULL, NULL, 0 }, /* gcolor */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hc */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hcode */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hidechar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hla */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hlm */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hpf */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hpfa */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hpfcode */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hw */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hy */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hylang */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hylen */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hym */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hypp */
+ { roff_line_ignore, NULL, NULL, 0 }, /* hys */
+ { roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT }, /* ie */
+ { roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT }, /* if */
+ { roff_block, roff_block_text, roff_block_sub, 0 }, /* ig */
+ { roff_unsupp, NULL, NULL, 0 }, /* index */
+ { roff_it, NULL, NULL, 0 }, /* it */
+ { roff_unsupp, NULL, NULL, 0 }, /* itc */
+ { roff_line_ignore, NULL, NULL, 0 }, /* IX */
+ { roff_line_ignore, NULL, NULL, 0 }, /* kern */
+ { roff_line_ignore, NULL, NULL, 0 }, /* kernafter */
+ { roff_line_ignore, NULL, NULL, 0 }, /* kernbefore */
+ { roff_line_ignore, NULL, NULL, 0 }, /* kernpair */
+ { roff_unsupp, NULL, NULL, 0 }, /* lc */
+ { roff_unsupp, NULL, NULL, 0 }, /* lc_ctype */
+ { roff_unsupp, NULL, NULL, 0 }, /* lds */
+ { roff_unsupp, NULL, NULL, 0 }, /* length */
+ { roff_line_ignore, NULL, NULL, 0 }, /* letadj */
+ { roff_insec, NULL, NULL, 0 }, /* lf */
+ { roff_line_ignore, NULL, NULL, 0 }, /* lg */
+ { roff_line_ignore, NULL, NULL, 0 }, /* lhang */
+ { roff_unsupp, NULL, NULL, 0 }, /* linetabs */
+ { roff_unsupp, NULL, NULL, 0 }, /* lnr */
+ { roff_unsupp, NULL, NULL, 0 }, /* lnrf */
+ { roff_unsupp, NULL, NULL, 0 }, /* lpfx */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ls */
+ { roff_unsupp, NULL, NULL, 0 }, /* lsm */
+ { roff_line_ignore, NULL, NULL, 0 }, /* lt */
+ { roff_line_ignore, NULL, NULL, 0 }, /* mc */
+ { roff_line_ignore, NULL, NULL, 0 }, /* mediasize */
+ { roff_line_ignore, NULL, NULL, 0 }, /* minss */
+ { roff_line_ignore, NULL, NULL, 0 }, /* mk */
+ { roff_insec, NULL, NULL, 0 }, /* mso */
+ { roff_line_ignore, NULL, NULL, 0 }, /* na */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ne */
+ { roff_line_ignore, NULL, NULL, 0 }, /* nh */
+ { roff_line_ignore, NULL, NULL, 0 }, /* nhychar */
+ { roff_unsupp, NULL, NULL, 0 }, /* nm */
+ { roff_unsupp, NULL, NULL, 0 }, /* nn */
+ { roff_unsupp, NULL, NULL, 0 }, /* nop */
+ { roff_nr, NULL, NULL, 0 }, /* nr */
+ { roff_unsupp, NULL, NULL, 0 }, /* nrf */
+ { roff_line_ignore, NULL, NULL, 0 }, /* nroff */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ns */
+ { roff_insec, NULL, NULL, 0 }, /* nx */
+ { roff_insec, NULL, NULL, 0 }, /* open */
+ { roff_insec, NULL, NULL, 0 }, /* opena */
+ { roff_line_ignore, NULL, NULL, 0 }, /* os */
+ { roff_unsupp, NULL, NULL, 0 }, /* output */
+ { roff_line_ignore, NULL, NULL, 0 }, /* padj */
+ { roff_line_ignore, NULL, NULL, 0 }, /* papersize */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pc */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pev */
+ { roff_insec, NULL, NULL, 0 }, /* pi */
+ { roff_unsupp, NULL, NULL, 0 }, /* PI */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pl */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pm */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pn */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pnr */
+ { roff_line_ignore, NULL, NULL, 0 }, /* po */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ps */
+ { roff_unsupp, NULL, NULL, 0 }, /* psbb */
+ { roff_unsupp, NULL, NULL, 0 }, /* pshape */
+ { roff_insec, NULL, NULL, 0 }, /* pso */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ptr */
+ { roff_line_ignore, NULL, NULL, 0 }, /* pvs */
+ { roff_unsupp, NULL, NULL, 0 }, /* rchar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* rd */
+ { roff_line_ignore, NULL, NULL, 0 }, /* recursionlimit */
+ { roff_unsupp, NULL, NULL, 0 }, /* return */
+ { roff_unsupp, NULL, NULL, 0 }, /* rfschar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* rhang */
+ { roff_line_ignore, NULL, NULL, 0 }, /* rj */
+ { roff_rm, NULL, NULL, 0 }, /* rm */
+ { roff_unsupp, NULL, NULL, 0 }, /* rn */
+ { roff_unsupp, NULL, NULL, 0 }, /* rnn */
+ { roff_rr, NULL, NULL, 0 }, /* rr */
+ { roff_line_ignore, NULL, NULL, 0 }, /* rs */
+ { roff_line_ignore, NULL, NULL, 0 }, /* rt */
+ { roff_unsupp, NULL, NULL, 0 }, /* schar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* sentchar */
+ { roff_line_ignore, NULL, NULL, 0 }, /* shc */
+ { roff_unsupp, NULL, NULL, 0 }, /* shift */
+ { roff_line_ignore, NULL, NULL, 0 }, /* sizes */
+ { roff_so, NULL, NULL, 0 }, /* so */
+ { roff_line_ignore, NULL, NULL, 0 }, /* spacewidth */
+ { roff_line_ignore, NULL, NULL, 0 }, /* special */
+ { roff_line_ignore, NULL, NULL, 0 }, /* spreadwarn */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ss */
+ { roff_line_ignore, NULL, NULL, 0 }, /* sty */
+ { roff_unsupp, NULL, NULL, 0 }, /* substring */
+ { roff_line_ignore, NULL, NULL, 0 }, /* sv */
+ { roff_insec, NULL, NULL, 0 }, /* sy */
+ { roff_T_, NULL, NULL, 0 }, /* T& */
+ { roff_unsupp, NULL, NULL, 0 }, /* ta */
+ { roff_unsupp, NULL, NULL, 0 }, /* tc */
+ { roff_TE, NULL, NULL, 0 }, /* TE */
+ { roff_TH, NULL, NULL, 0 }, /* TH */
+ { roff_unsupp, NULL, NULL, 0 }, /* ti */
+ { roff_line_ignore, NULL, NULL, 0 }, /* tkf */
+ { roff_unsupp, NULL, NULL, 0 }, /* tl */
+ { roff_line_ignore, NULL, NULL, 0 }, /* tm */
+ { roff_line_ignore, NULL, NULL, 0 }, /* tm1 */
+ { roff_line_ignore, NULL, NULL, 0 }, /* tmc */
+ { roff_tr, NULL, NULL, 0 }, /* tr */
+ { roff_line_ignore, NULL, NULL, 0 }, /* track */
+ { roff_line_ignore, NULL, NULL, 0 }, /* transchar */
+ { roff_insec, NULL, NULL, 0 }, /* trf */
+ { roff_line_ignore, NULL, NULL, 0 }, /* trimat */
+ { roff_unsupp, NULL, NULL, 0 }, /* trin */
+ { roff_unsupp, NULL, NULL, 0 }, /* trnt */
+ { roff_line_ignore, NULL, NULL, 0 }, /* troff */
+ { roff_TS, NULL, NULL, 0 }, /* TS */
+ { roff_line_ignore, NULL, NULL, 0 }, /* uf */
+ { roff_line_ignore, NULL, NULL, 0 }, /* ul */
+ { roff_unsupp, NULL, NULL, 0 }, /* unformat */
+ { roff_line_ignore, NULL, NULL, 0 }, /* unwatch */
+ { roff_line_ignore, NULL, NULL, 0 }, /* unwatchn */
+ { roff_line_ignore, NULL, NULL, 0 }, /* vpt */
+ { roff_line_ignore, NULL, NULL, 0 }, /* vs */
+ { roff_line_ignore, NULL, NULL, 0 }, /* warn */
+ { roff_line_ignore, NULL, NULL, 0 }, /* warnscale */
+ { roff_line_ignore, NULL, NULL, 0 }, /* watch */
+ { roff_line_ignore, NULL, NULL, 0 }, /* watchlength */
+ { roff_line_ignore, NULL, NULL, 0 }, /* watchn */
+ { roff_unsupp, NULL, NULL, 0 }, /* wh */
+ { roff_unsupp, NULL, NULL, 0 }, /* while */
+ { roff_insec, NULL, NULL, 0 }, /* write */
+ { roff_insec, NULL, NULL, 0 }, /* writec */
+ { roff_insec, NULL, NULL, 0 }, /* writem */
+ { roff_line_ignore, NULL, NULL, 0 }, /* xflag */
+ { roff_cblock, NULL, NULL, 0 }, /* . */
+ { roff_userdef, NULL, NULL, 0 }
};
/* not currently implemented: Ds em Eq LP Me PP pp Or Rd Sf SH */
@@ -589,65 +589,62 @@ static const struct predef predefs[PREDEFS_MAX] = {
#include "predefs.in"
};
-/* See roffhash_find() */
-#define ROFF_HASH(p) (p[0] - ASCII_LO)
-
static int roffit_lines; /* number of lines to delay */
static char *roffit_macro; /* nil-terminated macro line */
/* --- request table ------------------------------------------------------ */
-static void
-roffhash_init(void)
+struct ohash *
+roffhash_alloc(enum roff_tok mintok, enum roff_tok maxtok)
{
- struct roffmac *n;
- int buc, i;
-
- for (i = 0; i < (int)ROFF_USERDEF; i++) {
- assert(roffs[i].name[0] >= ASCII_LO);
- assert(roffs[i].name[0] <= ASCII_HI);
+ struct ohash *htab;
+ struct roffreq *req;
+ enum roff_tok tok;
+ size_t sz;
+ unsigned int slot;
- buc = ROFF_HASH(roffs[i].name);
+ htab = mandoc_malloc(sizeof(*htab));
+ mandoc_ohash_init(htab, 8, offsetof(struct roffreq, name));
- if (NULL != (n = hash[buc])) {
- for ( ; n->next; n = n->next)
- /* Do nothing. */ ;
- n->next = &roffs[i];
- } else
- hash[buc] = &roffs[i];
+ for (tok = mintok; tok < maxtok; tok++) {
+ sz = strlen(roff_name[tok]);
+ req = mandoc_malloc(sizeof(*req) + sz + 1);
+ req->tok = tok;
+ memcpy(req->name, roff_name[tok], sz + 1);
+ slot = ohash_qlookup(htab, req->name);
+ ohash_insert(htab, slot, req);
}
+ return htab;
}
-/*
- * Look up a roff token by its name. Returns TOKEN_NONE if no macro by
- * the nil-terminated string name could be found.
- */
-static enum roff_tok
-roffhash_find(const char *p, size_t s)
+void
+roffhash_free(struct ohash *htab)
{
- int buc;
- struct roffmac *n;
-
- /*
- * libroff has an extremely simple hashtable, for the time
- * being, which simply keys on the first character, which must
- * be printable, then walks a chain. It works well enough until
- * optimised.
- */
+ struct roffreq *req;
+ unsigned int slot;
- if (p[0] < ASCII_LO || p[0] > ASCII_HI)
- return TOKEN_NONE;
-
- buc = ROFF_HASH(p);
+ if (htab == NULL)
+ return;
+ for (req = ohash_first(htab, &slot); req != NULL;
+ req = ohash_next(htab, &slot))
+ free(req);
+ ohash_delete(htab);
+ free(htab);
+}
- if (NULL == (n = hash[buc]))
- return TOKEN_NONE;
- for ( ; n; n = n->next)
- if (0 == strncmp(n->name, p, s) && '\0' == n->name[(int)s])
- return (enum roff_tok)(n - roffs);
+enum roff_tok
+roffhash_find(struct ohash *htab, const char *name, size_t sz)
+{
+ struct roffreq *req;
+ const char *end;
- return TOKEN_NONE;
+ if (sz) {
+ end = name + sz;
+ req = ohash_find(htab, ohash_qlookupi(htab, name, &end));
+ } else
+ req = ohash_find(htab, ohash_qlookup(htab, name));
+ return req == NULL ? TOKEN_NONE : req->tok;
}
/* --- stack of request blocks -------------------------------------------- */
@@ -738,7 +735,6 @@ roff_free1(struct roff *r)
void
roff_reset(struct roff *r)
{
-
roff_free1(r);
r->format = r->options & (MPARSE_MDOC | MPARSE_MAN);
r->control = 0;
@@ -747,8 +743,8 @@ roff_reset(struct roff *r)
void
roff_free(struct roff *r)
{
-
roff_free1(r);
+ roffhash_free(r->reqtab);
free(r);
}
@@ -759,12 +755,10 @@ roff_alloc(struct mparse *parse, int options)
r = mandoc_calloc(1, sizeof(struct roff));
r->parse = parse;
+ r->reqtab = roffhash_alloc(0, ROFF_USERDEF);
r->options = options;
r->format = options & (MPARSE_MDOC | MPARSE_MAN);
r->rstackpos = -1;
-
- roffhash_init();
-
return r;
}
@@ -1487,7 +1481,7 @@ roff_endparse(struct roff *r)
if (r->last)
mandoc_msg(MANDOCERR_BLK_NOEND, r->parse,
r->last->line, r->last->col,
- roffs[r->last->tok].name);
+ roff_name[r->last->tok]);
if (r->eqn) {
mandoc_msg(MANDOCERR_BLK_NOEND, r->parse,
@@ -1523,7 +1517,7 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos)
maclen = roff_getname(r, &cp, ln, ppos);
t = (r->current_string = roff_getstrn(r, mac, maclen))
- ? ROFF_USERDEF : roffhash_find(mac, maclen);
+ ? ROFF_USERDEF : roffhash_find(r->reqtab, mac, maclen);
if (t != TOKEN_NONE)
*pos = cp - buf;
@@ -1661,7 +1655,7 @@ roff_block(ROFF_ARGS)
if (namesz == 0 && tok != ROFF_ig) {
mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse,
- ln, ppos, roffs[tok].name);
+ ln, ppos, roff_name[tok]);
return ROFF_IGN;
}
@@ -1702,7 +1696,7 @@ roff_block(ROFF_ARGS)
if (*cp != '\0')
mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse,
- ln, pos, ".%s ... %s", roffs[tok].name, cp);
+ ln, pos, ".%s ... %s", roff_name[tok], cp);
return ROFF_IGN;
}
@@ -2011,7 +2005,7 @@ roff_insec(ROFF_ARGS)
{
mandoc_msg(MANDOCERR_REQ_INSEC, r->parse,
- ln, ppos, roffs[tok].name);
+ ln, ppos, roff_name[tok]);
return ROFF_IGN;
}
@@ -2020,7 +2014,7 @@ roff_unsupp(ROFF_ARGS)
{
mandoc_msg(MANDOCERR_REQ_UNSUPP, r->parse,
- ln, ppos, roffs[tok].name);
+ ln, ppos, roff_name[tok]);
return ROFF_IGN;
}
@@ -2093,7 +2087,7 @@ roff_cond(ROFF_ARGS)
if (buf->buf[pos] == '\0')
mandoc_msg(MANDOCERR_COND_EMPTY, r->parse,
- ln, ppos, roffs[tok].name);
+ ln, ppos, roff_name[tok]);
r->last->endspan = 1;
diff --git a/usr.bin/mandoc/roff.h b/usr.bin/mandoc/roff.h
index 69c28664065..5d560e074d8 100644
--- a/usr.bin/mandoc/roff.h
+++ b/usr.bin/mandoc/roff.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.h,v 1.23 2017/04/24 23:06:09 schwarze Exp $ */
+/* $OpenBSD: roff.h,v 1.24 2017/04/29 12:43:55 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -16,6 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+struct ohash;
struct mdoc_arg;
union mdoc_data;
@@ -538,6 +539,8 @@ struct roff_man {
struct roff_meta meta; /* Document meta-data. */
struct mparse *parse; /* Parse pointer. */
struct roff *roff; /* Roff parser state data. */
+ struct ohash *mdocmac; /* Mdoc macro lookup table. */
+ struct ohash *manmac; /* Man macro lookup table. */
const char *defos; /* Default operating system. */
struct roff_node *first; /* The first node parsed. */
struct roff_node *last; /* The last node parsed. */
@@ -569,4 +572,8 @@ struct roff_man {
extern const char *const *roff_name;
+
void deroff(char **, const struct roff_node *);
+struct ohash *roffhash_alloc(enum roff_tok, enum roff_tok);
+enum roff_tok roffhash_find(struct ohash *, const char *, size_t);
+void roffhash_free(struct ohash *);