summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2009-10-19 09:16:59 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2009-10-19 09:16:59 +0000
commit34c62bf577e58494a05bd78594815a1badd57985 (patch)
tree314f64a55063442017d0b088921a51cc8dcf7e57 /usr.bin/mandoc
parent85dd4e6459ee1b701693106667f4a9869ded6571 (diff)
sync to 1.9.5: partial rewrite of special character and predefined string
tables and the supporting infrastructure, mostly in preparation for HTML output support
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r--usr.bin/mandoc/Makefile4
-rw-r--r--usr.bin/mandoc/ascii.c217
-rw-r--r--usr.bin/mandoc/ascii.in299
-rw-r--r--usr.bin/mandoc/chars.c204
-rw-r--r--usr.bin/mandoc/chars.h34
-rw-r--r--usr.bin/mandoc/chars.in300
-rw-r--r--usr.bin/mandoc/term.c19
-rw-r--r--usr.bin/mandoc/term.h11
8 files changed, 552 insertions, 536 deletions
diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile
index 8abe16e931c..711a40fd398 100644
--- a/usr.bin/mandoc/Makefile
+++ b/usr.bin/mandoc/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.18 2009/09/18 22:48:29 schwarze Exp $
+# $OpenBSD: Makefile,v 1.19 2009/10/19 09:16:58 schwarze Exp $
.include <bsd.own.mk>
@@ -14,7 +14,7 @@ SRCS= mandoc.c mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \
arch.c vol.c msec.c st.c
SRCS+= man_macro.c man.c man_hash.c man_validate.c \
man_action.c man_argv.c
-SRCS+= main.c mdoc_term.c ascii.c term.c tree.c man_term.c
+SRCS+= main.c mdoc_term.c chars.c term.c tree.c man_term.c
PROG= mandoc
diff --git a/usr.bin/mandoc/ascii.c b/usr.bin/mandoc/ascii.c
deleted file mode 100644
index 89816232a9d..00000000000
--- a/usr.bin/mandoc/ascii.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* $Id: ascii.c,v 1.3 2009/08/22 17:04:48 schwarze Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <err.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "term.h"
-
-#define ASCII_PRINT_HI 126
-#define ASCII_PRINT_LO 32
-
-struct line {
- const char *code;
- const char *out;
- size_t codesz;
- size_t outsz;
- int type;
-#define ASCII_CHAR (1 << 0)
-#define ASCII_STRING (1 << 1)
-#define ASCII_BOTH (0x03)
-};
-
-struct linep {
- const struct line *line;
- struct linep *next;
-};
-
-#define CHAR(w, x, y, z) \
- { (w), (y), (x), (z), ASCII_CHAR },
-#define STRING(w, x, y, z) \
- { (w), (y), (x), (z), ASCII_STRING },
-#define BOTH(w, x, y, z) \
- { (w), (y), (x), (z), ASCII_BOTH },
-static const struct line lines[] = {
-#include "ascii.in"
-};
-
-struct asciitab {
- struct linep *lines;
- void **htab;
-};
-
-
-static inline int match(const struct line *,
- const char *, size_t, int);
-static const char * lookup(struct asciitab *, const char *,
- size_t, size_t *, int);
-
-
-void
-term_asciifree(void *arg)
-{
- struct asciitab *tab;
-
- tab = (struct asciitab *)arg;
-
- free(tab->lines);
- free(tab->htab);
- free(tab);
-}
-
-
-void *
-term_ascii2htab(void)
-{
- struct asciitab *tab;
- void **htab;
- struct linep *pp, *p;
- int i, len, hash;
-
- /*
- * Constructs a very basic chaining hashtable. The hash routine
- * is simply the integral value of the first character.
- * Subsequent entries are chained in the order they're processed
- * (they're in-line re-ordered during lookup).
- */
-
- if (NULL == (tab = malloc(sizeof(struct asciitab))))
- err(1, "malloc");
-
- len = sizeof(lines) / sizeof(struct line);
-
- if (NULL == (p = calloc((size_t)len, sizeof(struct linep))))
- err(1, "malloc");
-
- htab = calloc(ASCII_PRINT_HI - ASCII_PRINT_LO + 1,
- sizeof(struct linep **));
-
- if (NULL == htab)
- err(1, "malloc");
-
- for (i = 0; i < len; i++) {
- assert(lines[i].codesz > 0);
- assert(lines[i].code);
- assert(lines[i].out);
-
- p[i].line = &lines[i];
-
- hash = (int)lines[i].code[0] - ASCII_PRINT_LO;
-
- if (NULL == (pp = ((struct linep **)htab)[hash])) {
- htab[hash] = &p[i];
- continue;
- }
-
- for ( ; pp->next; pp = pp->next)
- /* Scan ahead. */ ;
-
- pp->next = &p[i];
- }
-
- tab->htab = htab;
- tab->lines = p;
-
- return(tab);
-}
-
-
-const char *
-term_a2ascii(void *arg, const char *p, size_t sz, size_t *rsz)
-{
-
- return(lookup((struct asciitab *)arg, p,
- sz, rsz, ASCII_CHAR));
-}
-
-
-const char *
-term_a2res(void *arg, const char *p, size_t sz, size_t *rsz)
-{
-
- return(lookup((struct asciitab *)arg, p,
- sz, rsz, ASCII_STRING));
-}
-
-
-static const char *
-lookup(struct asciitab *tab, const char *p,
- size_t sz, size_t *rsz, int type)
-{
- struct linep *pp, *prev;
- void **htab;
- int hash;
-
- assert(p);
- assert(sz > 0);
-
- if (p[0] < ASCII_PRINT_LO || p[0] > ASCII_PRINT_HI)
- return(NULL);
-
-
- /*
- * Lookup the symbol in the symbol hash. See ascii2htab for the
- * hashtable specs. This dynamically re-orders the hash chain
- * to optimise for repeat hits.
- */
-
- hash = (int)p[0] - ASCII_PRINT_LO;
- htab = tab->htab;
-
- if (NULL == (pp = ((struct linep **)htab)[hash]))
- return(NULL);
-
- if (NULL == pp->next) {
- if ( ! match(pp->line, p, sz, type))
- return(NULL);
- *rsz = pp->line->outsz;
- return(pp->line->out);
- }
-
- for (prev = NULL; pp; pp = pp->next) {
- if ( ! match(pp->line, p, sz, type)) {
- prev = pp;
- continue;
- }
-
- /* Re-order the hash chain. */
-
- if (prev) {
- prev->next = pp->next;
- pp->next = ((struct linep **)htab)[hash];
- htab[hash] = pp;
- }
-
- *rsz = pp->line->outsz;
- return(pp->line->out);
- }
-
- return(NULL);
-}
-
-
-static inline int
-match(const struct line *line, const char *p, size_t sz, int type)
-{
-
- if ( ! (line->type & type))
- return(0);
- if (line->codesz != sz)
- return(0);
- return(0 == strncmp(line->code, p, sz));
-}
diff --git a/usr.bin/mandoc/ascii.in b/usr.bin/mandoc/ascii.in
deleted file mode 100644
index 56f72d83bf3..00000000000
--- a/usr.bin/mandoc/ascii.in
+++ /dev/null
@@ -1,299 +0,0 @@
-/* $Id: ascii.in,v 1.5 2009/08/22 17:04:48 schwarze Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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.
- */
-
-/*
- * The ASCII translation tables. STRING corresponds to predefined
- * strings (cf. mdoc_samples.7 and tmac/mdoc/doc-nroff). CHAR
- * corresponds to special characters (cf. groff_char.7). BOTH contains
- * sequences that are equivalent in both STRING and CHAR.
- *
- * Either way, the left-hand side corresponds to the input sequence (\x,
- * \(xx, \*(xx and so on) whose length is listed second element. The
- * right-hand side is what's produced by the front-end, with the fourth
- * element being its length.
- *
- * Be sure to C-escape strings!
- */
-
-STRING("Am", 2, "&", 1)
-STRING("Ba", 2, "|", 1)
-STRING("Ge", 2, ">=", 2)
-STRING("Gt", 2, ">", 1)
-STRING("If", 2, "infinity", 8)
-STRING("Le", 2, "<=", 2)
-STRING("Lq", 2, "``", 2)
-STRING("Lt", 2, "<", 1)
-STRING("Na", 2, "NaN", 3)
-STRING("Ne", 2, "!=", 2)
-STRING("Pi", 2, "pi", 2)
-STRING("Pm", 2, "+-", 2)
-STRING("R", 1, "(R)", 3)
-STRING("Rq", 2, "\'\'", 2)
-STRING("Tm", 2, "tm", 2)
-STRING("left-bracket", 12, "[", 1)
-STRING("left-parenthesis", 16, "(", 1)
-STRING("left-singlequote", 16, "`", 1)
-STRING("lp", 2, "(", 1)
-STRING("q", 1, "\"", 1)
-STRING("quote-left", 10, "`", 1)
-STRING("quote-right", 11, "\'", 1)
-STRING("right-bracket", 13, "]", 1)
-STRING("right-parenthesis", 17, ")", 1)
-STRING("right-singlequote", 17, "\'", 1)
-STRING("rp", 2, ")", 1)
-
-BOTH("<=", 2, "<=", 2)
-BOTH(">=", 2, ">=", 2)
-BOTH("aa", 2, "\'", 1)
-BOTH("ga", 2, "`", 1)
-BOTH("lq", 2, "``", 2)
-BOTH("rq", 2, "\'\'", 2)
-BOTH("ua", 2, "^", 1)
-
-CHAR(" ", 1, " ", 1)
-CHAR("!=", 2, "!=", 2)
-CHAR("%", 1, "", 0)
-CHAR("&", 1, "", 0)
-CHAR("(=", 2, "(=", 2)
-CHAR("**", 2, "*", 1)
-CHAR("*A", 2, "A", 1)
-CHAR("*B", 2, "B", 1)
-CHAR("*C", 2, "H", 1)
-CHAR("*D", 2, "/\\", 2)
-CHAR("*E", 2, "E", 1)
-CHAR("*F", 2, "O_", 1)
-CHAR("*G", 2, "|", 1)
-CHAR("*H", 2, "O", 1)
-CHAR("*I", 2, "I", 1)
-CHAR("*K", 2, "K", 1)
-CHAR("*L", 2, "/\\", 2)
-CHAR("*M", 2, "M", 1)
-CHAR("*N", 2, "N", 1)
-CHAR("*O", 2, "O", 1)
-CHAR("*P", 2, "TT", 2)
-CHAR("*Q", 2, "Y", 1)
-CHAR("*R", 2, "P", 1)
-CHAR("*S", 2, ">", 1)
-CHAR("*T", 2, "T", 1)
-CHAR("*U", 2, "Y", 1)
-CHAR("*W", 2, "O", 1)
-CHAR("*X", 2, "X", 1)
-CHAR("*Y", 2, "H", 1)
-CHAR("*Z", 2, "Z", 1)
-CHAR("*a", 2, "a", 1)
-CHAR("*b", 2, "B", 1)
-CHAR("*c", 2, "E", 1)
-CHAR("*d", 2, "d", 1)
-CHAR("*e", 2, "e", 1)
-CHAR("*f", 2, "o", 1)
-CHAR("*g", 2, "y", 1)
-CHAR("*h", 2, "0", 1)
-CHAR("*i", 2, "i", 1)
-CHAR("*k", 2, "k", 1)
-CHAR("*l", 2, "\\", 1)
-CHAR("*m", 2, "u", 1)
-CHAR("*n", 2, "v", 1)
-CHAR("*o", 2, "o", 1)
-CHAR("*p", 2, "n", 1)
-CHAR("*q", 2, "u", 1)
-CHAR("*r", 2, "p", 1)
-CHAR("*s", 2, "o", 1)
-CHAR("*t", 2, "t", 1)
-CHAR("*u", 2, "u", 1)
-CHAR("*w", 2, "w", 1)
-CHAR("*x", 2, "x", 1)
-CHAR("*y", 2, "n", 1)
-CHAR("*z", 2, "C", 1)
-CHAR("+-", 2, "+-", 2)
-CHAR("+f", 2, "o", 1)
-CHAR("+h", 2, "0", 1)
-CHAR("+p", 2, "w", 1)
-CHAR(",C", 2, "C", 1)
-CHAR(",c", 2, "c", 1)
-CHAR("-", 1, "-", 1)
-CHAR("->", 2, "->", 2)
-CHAR("-D", 2, "D", 1)
-CHAR(".", 1, ".", 1)
-CHAR("/L", 2, "L", 1)
-CHAR("/O", 2, "O", 1)
-CHAR("/l", 2, "l", 1)
-CHAR("/o", 2, "o", 1)
-CHAR("0", 1, " ", 1)
-CHAR(":A", 2, "A", 1)
-CHAR(":E", 2, "E", 1)
-CHAR(":I", 2, "I", 1)
-CHAR(":O", 2, "O", 1)
-CHAR(":U", 2, "U", 1)
-CHAR(":a", 2, "a", 1)
-CHAR(":e", 2, "e", 1)
-CHAR(":i", 2, "i", 1)
-CHAR(":o", 2, "o", 1)
-CHAR(":u", 2, "u", 1)
-CHAR(":y", 2, "y", 1)
-CHAR("<-", 2, "<-", 2)
-CHAR("<=", 2, "<=", 2)
-CHAR("<>", 2, "<>", 2)
-CHAR("=)", 2, "=)", 2)
-CHAR("==", 2, "==", 2)
-CHAR("=~", 2, "=~", 2)
-CHAR(">=", 2, ">=", 2)
-CHAR("AE", 2, "AE", 2)
-CHAR("AN", 2, "^", 1)
-CHAR("Ah", 2, "N", 1)
-CHAR("Bq", 2, ",,", 2)
-CHAR("Cs", 2, "x", 1)
-CHAR("Do", 2, "$", 1)
-CHAR("Eu", 2, "EUR", 3)
-CHAR("Fc", 2, ">>", 2)
-CHAR("Fi", 2, "ffi", 3)
-CHAR("Fl", 2, "ffl", 3)
-CHAR("Fn", 2, "f", 1)
-CHAR("Fo", 2, "<<", 2)
-CHAR("Im", 2, "I", 1)
-CHAR("OE", 2, "OE", 2)
-CHAR("OR", 2, "v", 1)
-CHAR("Po", 2, "L", 1)
-CHAR("Re", 2, "R", 1)
-CHAR("Sd", 2, "o", 1)
-CHAR("TP", 2, "b", 1)
-CHAR("Tp", 2, "b", 1)
-CHAR("Ye", 2, "Y", 1)
-CHAR("\'", 1, "\'", 1)
-CHAR("\'A", 2, "A", 1)
-CHAR("\'E", 2, "E", 1)
-CHAR("\'I", 2, "I", 1)
-CHAR("\'O", 2, "O", 1)
-CHAR("\'U", 2, "U", 1)
-CHAR("\'a", 2, "a", 1)
-CHAR("\'e", 2, "e", 1)
-CHAR("\'i", 2, "i", 1)
-CHAR("\'o", 2, "o", 1)
-CHAR("\'u", 2, "u", 1)
-CHAR("\\", 1, "\\", 1)
-CHAR("^", 1, "", 0)
-CHAR("^A", 2, "A", 1)
-CHAR("^E", 2, "E", 1)
-CHAR("^I", 2, "I", 1)
-CHAR("^O", 2, "O", 1)
-CHAR("^U", 2, "U", 1)
-CHAR("^a", 2, "a", 1)
-CHAR("^e", 2, "e", 1)
-CHAR("^i", 2, "i", 1)
-CHAR("^o", 2, "o", 1)
-CHAR("^u", 2, "u", 1)
-CHAR("`", 1, "`", 1)
-CHAR("`A", 2, "A", 1)
-CHAR("`E", 2, "E", 1)
-CHAR("`I", 2, "I", 1)
-CHAR("`O", 2, "O", 1)
-CHAR("`U", 2, "U", 1)
-CHAR("`a", 2, "a", 1)
-CHAR("`e", 2, "e", 1)
-CHAR("`i", 2, "i", 1)
-CHAR("`o", 2, "o", 1)
-CHAR("`u", 2, "u", 1)
-CHAR("a-", 2, "-", 1)
-CHAR("a\"", 2, "\"", 1)
-CHAR("a^", 2, "^", 1)
-CHAR("aa", 2, "\'", 1)
-CHAR("ab", 2, "`", 1)
-CHAR("ac", 2, ",", 1)
-CHAR("ad", 2, "\"", 1)
-CHAR("ae", 2, "ae", 2)
-CHAR("ah", 2, "v", 1)
-CHAR("ao", 2, "o", 1)
-CHAR("ap", 2, "~", 1)
-CHAR("aq", 2, "\'", 1)
-CHAR("a~", 2, "~", 1)
-CHAR("ba", 2, "|", 1)
-CHAR("bb", 2, "|", 1)
-CHAR("bq", 2, ",", 1)
-CHAR("bu", 2, "o", 1)
-CHAR("c", 1, "", 0)
-CHAR("ca", 2, "(^)", 3)
-CHAR("ci", 2, "O", 1)
-CHAR("co", 2, "(C)", 3)
-CHAR("ct", 2, "c", 1)
-CHAR("cu", 2, "U", 1)
-CHAR("dA", 2, "v", 1)
-CHAR("da", 2, "v", 1)
-CHAR("dd", 2, "=", 1)
-CHAR("de", 2, "o", 1)
-CHAR("dg", 2, "-", 1)
-CHAR("di", 2, "-:-", 3)
-CHAR("e", 1, "\\", 1)
-CHAR("em", 2, "--", 2)
-CHAR("en", 2, "-", 1)
-CHAR("eq", 2, "=", 1)
-CHAR("es", 2, "{}", 2)
-CHAR("eu", 2, "EUR", 3)
-CHAR("fa", 2, "V", 1)
-CHAR("fc", 2, ">", 1)
-CHAR("ff", 2, "ff", 2)
-CHAR("fi", 2, "fi", 2)
-CHAR("fl", 2, "fl", 2)
-CHAR("fo", 2, "<", 1)
-CHAR("ga", 2, "`", 1)
-CHAR("gr", 2, "V", 1)
-CHAR("hA", 2, "<=>", 3)
-CHAR("ho", 2, ",", 1)
-CHAR("hy", 2, "-", 1)
-CHAR("if", 2, "oo", 2)
-CHAR("lA", 2, "<=", 2)
-CHAR("lB", 2, "[", 1)
-CHAR("lC", 2, "{", 1)
-CHAR("la", 2, "<", 1)
-CHAR("lh", 2, "<=", 2)
-CHAR("mo", 2, "E", 1)
-CHAR("mu", 2, "x", 1)
-CHAR("na", 2, "NaN", 3)
-CHAR("nm", 2, "E", 1)
-CHAR("no", 2, "~", 1)
-CHAR("oA", 2, "A", 1)
-CHAR("oa", 2, "a", 1)
-CHAR("oe", 2, "oe", 2)
-CHAR("oq", 2, "`", 1)
-CHAR("pd", 2, "a", 1)
-CHAR("pl", 2, "+", 1)
-CHAR("ps", 2, "9|", 2)
-CHAR("r!", 2, "i", 1)
-CHAR("r?", 2, "c", 1)
-CHAR("rA", 2, "=>", 2)
-CHAR("rB", 2, "]", 1)
-CHAR("rC", 2, "}", 1)
-CHAR("ra", 2, ">", 1)
-CHAR("rg", 2, "(R)", 3)
-CHAR("rh", 2, "=>", 2)
-CHAR("sc", 2, "S", 1)
-CHAR("ss", 2, "ss", 2)
-CHAR("st", 2, "-)", 2)
-CHAR("te", 2, "3", 1)
-CHAR("tf", 2, ".:.", 3)
-CHAR("tm", 2, "tm", 2)
-CHAR("ts", 2, "s", 1)
-CHAR("uA", 2, "^", 1)
-CHAR("ua", 2, "^", 1)
-CHAR("|", 1, "", 0)
-CHAR("~", 1, " ", 1)
-CHAR("~=", 2, "~=", 2)
-CHAR("~A", 2, "A", 1)
-CHAR("~N", 2, "N", 1)
-CHAR("~O", 2, "O", 1)
-CHAR("~a", 2, "a", 1)
-CHAR("~n", 2, "n", 1)
-CHAR("~o", 2, "o", 1)
-CHAR("~~", 2, "~~", 2)
diff --git a/usr.bin/mandoc/chars.c b/usr.bin/mandoc/chars.c
new file mode 100644
index 00000000000..587da515789
--- /dev/null
+++ b/usr.bin/mandoc/chars.c
@@ -0,0 +1,204 @@
+/* $Id: chars.c,v 1.1 2009/10/19 09:16:58 schwarze Exp $ */
+/*
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * 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 <assert.h>
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "chars.h"
+
+#define PRINT_HI 126
+#define PRINT_LO 32
+
+struct ln {
+ struct ln *next;
+ const char *code;
+ const char *ascii;
+ const char *html;
+ size_t codesz;
+ size_t asciisz;
+ size_t htmlsz;
+ int type;
+#define CHARS_CHAR (1 << 0)
+#define CHARS_STRING (1 << 1)
+#define CHARS_BOTH (0x03)
+};
+
+#define LINES_MAX 266
+
+#define CHAR(w, x, y, z, a, b) \
+ { NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR },
+#define STRING(w, x, y, z, a, b) \
+ { NULL, (w), (y), (a), (x), (z), (b), CHARS_STRING },
+#define BOTH(w, x, y, z, a, b) \
+ { NULL, (w), (y), (a), (x), (z), (b), CHARS_BOTH },
+
+static struct ln lines[LINES_MAX] = {
+#include "chars.in"
+};
+
+struct tbl {
+ enum chars type;
+ struct ln **htab;
+};
+
+static inline int match(const struct ln *,
+ const char *, size_t, int);
+static const char *find(struct tbl *, const char *,
+ size_t, size_t *, int);
+
+
+void
+chars_free(void *arg)
+{
+ struct tbl *tab;
+
+ tab = (struct tbl *)arg;
+
+ free(tab->htab);
+ free(tab);
+}
+
+
+void *
+chars_init(enum chars type)
+{
+ struct tbl *tab;
+ struct ln **htab;
+ struct ln *pp;
+ int i, hash;
+
+ /*
+ * Constructs a very basic chaining hashtable. The hash routine
+ * is simply the integral value of the first character.
+ * Subsequent entries are chained in the order they're processed
+ * (they're in-line re-ordered during lookup).
+ */
+
+ if (NULL == (tab = malloc(sizeof(struct tbl))))
+ err(1, "malloc");
+ tab->type = type;
+
+ htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
+ if (NULL == htab)
+ err(1, "malloc");
+
+ for (i = 0; i < LINES_MAX; i++) {
+ hash = (int)lines[i].code[0] - PRINT_LO;
+
+ if (NULL == (pp = htab[hash])) {
+ htab[hash] = &lines[i];
+ continue;
+ }
+
+ for ( ; pp->next; pp = pp->next)
+ /* Scan ahead. */ ;
+ pp->next = &lines[i];
+ }
+
+ tab->htab = htab;
+ return(tab);
+}
+
+
+const char *
+chars_a2ascii(void *arg, const char *p, size_t sz, size_t *rsz)
+{
+
+ return(find((struct tbl *)arg, p, sz, rsz, CHARS_CHAR));
+}
+
+
+const char *
+chars_a2res(void *arg, const char *p, size_t sz, size_t *rsz)
+{
+
+ return(find((struct tbl *)arg, p, sz, rsz, CHARS_STRING));
+}
+
+
+static const char *
+find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
+{
+ struct ln *pp, *prev;
+ struct ln **htab;
+ int hash;
+
+ assert(p);
+ assert(sz > 0);
+
+ if (p[0] < PRINT_LO || p[0] > PRINT_HI)
+ return(NULL);
+
+ /*
+ * Lookup the symbol in the symbol hash. See ascii2htab for the
+ * hashtable specs. This dynamically re-orders the hash chain
+ * to optimise for repeat hits.
+ */
+
+ hash = (int)p[0] - PRINT_LO;
+ htab = tab->htab;
+
+ if (NULL == (pp = htab[hash]))
+ return(NULL);
+
+ if (NULL == pp->next) {
+ if ( ! match(pp, p, sz, type))
+ return(NULL);
+
+ if (CHARS_HTML == tab->type) {
+ *rsz = pp->htmlsz;
+ return(pp->html);
+ }
+ *rsz = pp->asciisz;
+ return(pp->ascii);
+ }
+
+ for (prev = NULL; pp; pp = pp->next) {
+ if ( ! match(pp, p, sz, type)) {
+ prev = pp;
+ continue;
+ }
+
+ if (prev) {
+ prev->next = pp->next;
+ pp->next = htab[hash];
+ htab[hash] = pp;
+ }
+
+ if (CHARS_HTML == tab->type) {
+ *rsz = pp->htmlsz;
+ return(pp->html);
+ }
+ *rsz = pp->asciisz;
+ return(pp->ascii);
+ }
+
+ return(NULL);
+}
+
+
+static inline int
+match(const struct ln *ln, const char *p, size_t sz, int type)
+{
+
+ if ( ! (ln->type & type))
+ return(0);
+ if (ln->codesz != sz)
+ return(0);
+ return(0 == strncmp(ln->code, p, sz));
+}
diff --git a/usr.bin/mandoc/chars.h b/usr.bin/mandoc/chars.h
new file mode 100644
index 00000000000..fa1608a3b58
--- /dev/null
+++ b/usr.bin/mandoc/chars.h
@@ -0,0 +1,34 @@
+/* $Id: chars.h,v 1.1 2009/10/19 09:16:58 schwarze Exp $ */
+/*
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * 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.
+ */
+#ifndef CHARS_H
+#define CHARS_H
+
+__BEGIN_DECLS
+
+enum chars {
+ CHARS_ASCII,
+ CHARS_HTML
+};
+
+void *chars_init(enum chars);
+const char *chars_a2ascii(void *, const char *, size_t, size_t *);
+const char *chars_a2res(void *, const char *, size_t, size_t *);
+void chars_free(void *);
+
+__END_DECLS
+
+#endif /*!CHARS_H*/
diff --git a/usr.bin/mandoc/chars.in b/usr.bin/mandoc/chars.in
new file mode 100644
index 00000000000..83ffaf28bfb
--- /dev/null
+++ b/usr.bin/mandoc/chars.in
@@ -0,0 +1,300 @@
+/* $Id: chars.in,v 1.1 2009/10/19 09:16:58 schwarze Exp $ */
+/*
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * 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.
+ */
+
+/*
+ * The ASCII translation tables. STRING corresponds to predefined
+ * strings (cf. mdoc_samples.7 and tmac/mdoc/doc-nroff). CHAR
+ * corresponds to special characters (cf. groff_char.7). BOTH contains
+ * sequences that are equivalent in both STRING and CHAR.
+ *
+ * Either way, the left-hand side corresponds to the input sequence (\x,
+ * \(xx, \*(xx and so on) whose length is listed second element. The
+ * right-hand side is what's produced by the front-end, with the fourth
+ * element being its length.
+ *
+ * XXX - C-escape strings!
+ * XXX - update LINES_MAX if adding more!
+ */
+
+STRING("Am", 2, "&", 1, "&amp;", 5)
+STRING("Ba", 2, "|", 1, "|", 0)
+STRING("Ge", 2, ">=", 2, "&#8805;", 7)
+STRING("Gt", 2, ">", 1, "&gt;", 4)
+STRING("If", 2, "infinity", 8, "infinity", 8)
+STRING("Le", 2, "<=", 2, "&#8804;", 7)
+STRING("Lq", 2, "``", 2, "&#8220;", 7)
+STRING("Lt", 2, "<", 1, "&lt;", 4)
+STRING("Na", 2, "NaN", 3, "NaN", 3)
+STRING("Ne", 2, "!=", 2, "&#8800;", 7)
+STRING("Pi", 2, "pi", 2, "&#960;", 6)
+STRING("Pm", 2, "+-", 2, "&#177;", 6)
+STRING("R", 1, "(R)", 3, "&#174;", 6)
+STRING("Rq", 2, "\'\'", 2, "&#8221;", 7)
+STRING("Tm", 2, "tm", 2, "&#8424;", 7)
+STRING("left-bracket", 12, "[", 1, "[", 1)
+STRING("left-parenthesis", 16, "(", 1, "(", 1)
+STRING("left-singlequote", 16, "`", 1, "&#8216;", 7)
+STRING("lp", 2, "(", 1, "(", 1)
+STRING("q", 1, "\"", 1, "&quot;", 6)
+STRING("quote-left", 10, "`", 1, "&#8216;", 7)
+STRING("quote-right", 11, "\'", 1, "&#8217;", 7)
+STRING("right-bracket", 13, "]", 1, "]", 1)
+STRING("right-parenthesis", 17, ")", 1, ")", 1)
+STRING("right-singlequote", 17, "\'", 1, "&#8217;", 7)
+STRING("rp", 2, ")", 1, ")", 1)
+
+BOTH("<=", 2, "<=", 2, "&#8804;", 7)
+BOTH(">=", 2, ">=", 2, "&#8804;", 7)
+BOTH("aa", 2, "\'", 1, "&#180;", 6)
+BOTH("ga", 2, "`", 1, "`", 1)
+BOTH("lq", 2, "``", 2, "&#8220;", 7)
+BOTH("rq", 2, "\'\'", 2, "&#8221;", 7)
+BOTH("ua", 2, "^", 1, "", 0)
+
+CHAR(" ", 1, " ", 1, " ", 1)
+CHAR("!=", 2, "!=", 2, "", 0)
+CHAR("%", 1, "", 0, "", 0)
+CHAR("&", 1, "", 0, "", 0)
+CHAR("(=", 2, "(=", 2, "", 0)
+CHAR("**", 2, "*", 1, "", 0)
+CHAR("*A", 2, "A", 1, "", 0)
+CHAR("*B", 2, "B", 1, "", 0)
+CHAR("*C", 2, "H", 1, "", 0)
+CHAR("*D", 2, "/\\", 2, "", 0)
+CHAR("*E", 2, "E", 1, "", 0)
+CHAR("*F", 2, "O_", 1, "", 0)
+CHAR("*G", 2, "|", 1, "", 0)
+CHAR("*H", 2, "O", 1, "", 0)
+CHAR("*I", 2, "I", 1, "", 0)
+CHAR("*K", 2, "K", 1, "", 0)
+CHAR("*L", 2, "/\\", 2, "", 0)
+CHAR("*M", 2, "M", 1, "", 0)
+CHAR("*N", 2, "N", 1, "", 0)
+CHAR("*O", 2, "O", 1, "", 0)
+CHAR("*P", 2, "TT", 2, "", 0)
+CHAR("*Q", 2, "Y", 1, "", 0)
+CHAR("*R", 2, "P", 1, "", 0)
+CHAR("*S", 2, ">", 1, "", 0)
+CHAR("*T", 2, "T", 1, "", 0)
+CHAR("*U", 2, "Y", 1, "", 0)
+CHAR("*W", 2, "O", 1, "", 0)
+CHAR("*X", 2, "X", 1, "", 0)
+CHAR("*Y", 2, "H", 1, "", 0)
+CHAR("*Z", 2, "Z", 1, "", 0)
+CHAR("*a", 2, "a", 1, "", 0)
+CHAR("*b", 2, "B", 1, "", 0)
+CHAR("*c", 2, "E", 1, "", 0)
+CHAR("*d", 2, "d", 1, "", 0)
+CHAR("*e", 2, "e", 1, "", 0)
+CHAR("*f", 2, "o", 1, "", 0)
+CHAR("*g", 2, "y", 1, "", 0)
+CHAR("*h", 2, "0", 1, "", 0)
+CHAR("*i", 2, "i", 1, "", 0)
+CHAR("*k", 2, "k", 1, "", 0)
+CHAR("*l", 2, "\\", 1, "", 0)
+CHAR("*m", 2, "u", 1, "", 0)
+CHAR("*n", 2, "v", 1, "", 0)
+CHAR("*o", 2, "o", 1, "", 0)
+CHAR("*p", 2, "n", 1, "", 0)
+CHAR("*q", 2, "u", 1, "", 0)
+CHAR("*r", 2, "p", 1, "", 0)
+CHAR("*s", 2, "o", 1, "", 0)
+CHAR("*t", 2, "t", 1, "", 0)
+CHAR("*u", 2, "u", 1, "", 0)
+CHAR("*w", 2, "w", 1, "", 0)
+CHAR("*x", 2, "x", 1, "", 0)
+CHAR("*y", 2, "n", 1, "", 0)
+CHAR("*z", 2, "C", 1, "", 0)
+CHAR("+-", 2, "+-", 2, "", 0)
+CHAR("+f", 2, "o", 1, "", 0)
+CHAR("+h", 2, "0", 1, "", 0)
+CHAR("+p", 2, "w", 1, "", 0)
+CHAR(",C", 2, "C", 1, "", 0)
+CHAR(",c", 2, "c", 1, "", 0)
+CHAR("-", 1, "-", 1, "-", 1)
+CHAR("->", 2, "->", 2, "", 0)
+CHAR("-D", 2, "D", 1, "", 0)
+CHAR(".", 1, ".", 1, ".", 1)
+CHAR("/L", 2, "L", 1, "", 0)
+CHAR("/O", 2, "O", 1, "", 0)
+CHAR("/l", 2, "l", 1, "", 0)
+CHAR("/o", 2, "o", 1, "", 0)
+CHAR("0", 1, " ", 1, "", 0)
+CHAR(":A", 2, "A", 1, "", 0)
+CHAR(":E", 2, "E", 1, "", 0)
+CHAR(":I", 2, "I", 1, "", 0)
+CHAR(":O", 2, "O", 1, "", 0)
+CHAR(":U", 2, "U", 1, "", 0)
+CHAR(":a", 2, "a", 1, "", 0)
+CHAR(":e", 2, "e", 1, "", 0)
+CHAR(":i", 2, "i", 1, "", 0)
+CHAR(":o", 2, "o", 1, "", 0)
+CHAR(":u", 2, "u", 1, "", 0)
+CHAR(":y", 2, "y", 1, "", 0)
+CHAR("<-", 2, "<-", 2, "", 0)
+CHAR("<=", 2, "<=", 2, "", 0)
+CHAR("<>", 2, "<>", 2, "", 0)
+CHAR("=)", 2, "=)", 2, "", 0)
+CHAR("==", 2, "==", 2, "", 0)
+CHAR("=~", 2, "=~", 2, "", 0)
+CHAR(">=", 2, ">=", 2, "", 0)
+CHAR("AE", 2, "AE", 2, "", 0)
+CHAR("AN", 2, "^", 1, "", 0)
+CHAR("Ah", 2, "N", 1, "", 0)
+CHAR("Bq", 2, ",,", 2, "", 0)
+CHAR("Cs", 2, "x", 1, "", 0)
+CHAR("Do", 2, "$", 1, "", 0)
+CHAR("Eu", 2, "EUR", 3, "", 0)
+CHAR("Fc", 2, ">>", 2, "", 0)
+CHAR("Fi", 2, "ffi", 3, "", 0)
+CHAR("Fl", 2, "ffl", 3, "", 0)
+CHAR("Fn", 2, "f", 1, "", 0)
+CHAR("Fo", 2, "<<", 2, "", 0)
+CHAR("Im", 2, "I", 1, "", 0)
+CHAR("OE", 2, "OE", 2, "", 0)
+CHAR("OR", 2, "v", 1, "", 0)
+CHAR("Po", 2, "L", 1, "", 0)
+CHAR("Re", 2, "R", 1, "", 0)
+CHAR("Sd", 2, "o", 1, "", 0)
+CHAR("TP", 2, "b", 1, "", 0)
+CHAR("Tp", 2, "b", 1, "", 0)
+CHAR("Ye", 2, "Y", 1, "", 0)
+CHAR("\'", 1, "\'", 1, "", 0)
+CHAR("\'A", 2, "A", 1, "", 0)
+CHAR("\'E", 2, "E", 1, "", 0)
+CHAR("\'I", 2, "I", 1, "", 0)
+CHAR("\'O", 2, "O", 1, "", 0)
+CHAR("\'U", 2, "U", 1, "", 0)
+CHAR("\'a", 2, "a", 1, "", 0)
+CHAR("\'e", 2, "e", 1, "", 0)
+CHAR("\'i", 2, "i", 1, "", 0)
+CHAR("\'o", 2, "o", 1, "", 0)
+CHAR("\'u", 2, "u", 1, "", 0)
+CHAR("\\", 1, "\\", 1, "", 0)
+CHAR("^", 1, "", 0, "", 0)
+CHAR("^A", 2, "A", 1, "", 0)
+CHAR("^E", 2, "E", 1, "", 0)
+CHAR("^I", 2, "I", 1, "", 0)
+CHAR("^O", 2, "O", 1, "", 0)
+CHAR("^U", 2, "U", 1, "", 0)
+CHAR("^a", 2, "a", 1, "", 0)
+CHAR("^e", 2, "e", 1, "", 0)
+CHAR("^i", 2, "i", 1, "", 0)
+CHAR("^o", 2, "o", 1, "", 0)
+CHAR("^u", 2, "u", 1, "", 0)
+CHAR("`", 1, "`", 1, "", 0)
+CHAR("`A", 2, "A", 1, "", 0)
+CHAR("`E", 2, "E", 1, "", 0)
+CHAR("`I", 2, "I", 1, "", 0)
+CHAR("`O", 2, "O", 1, "", 0)
+CHAR("`U", 2, "U", 1, "", 0)
+CHAR("`a", 2, "a", 1, "", 0)
+CHAR("`e", 2, "e", 1, "", 0)
+CHAR("`i", 2, "i", 1, "", 0)
+CHAR("`o", 2, "o", 1, "", 0)
+CHAR("`u", 2, "u", 1, "", 0)
+CHAR("a-", 2, "-", 1, "", 0)
+CHAR("a\"", 2, "\"", 1, "", 0)
+CHAR("a^", 2, "^", 1, "", 0)
+CHAR("aa", 2, "\'", 1, "", 0)
+CHAR("ab", 2, "`", 1, "", 0)
+CHAR("ac", 2, ",", 1, "", 0)
+CHAR("ad", 2, "\"", 1, "", 0)
+CHAR("ae", 2, "ae", 2, "", 0)
+CHAR("ah", 2, "v", 1, "", 0)
+CHAR("ao", 2, "o", 1, "", 0)
+CHAR("ap", 2, "~", 1, "", 0)
+CHAR("aq", 2, "\'", 1, "&#8217;", 7)
+CHAR("a~", 2, "~", 1, "", 0)
+CHAR("ba", 2, "|", 1, "", 0)
+CHAR("bb", 2, "|", 1, "", 0)
+CHAR("bq", 2, ",", 1, "", 0)
+CHAR("bu", 2, "o", 1, "&#8226;", 7)
+CHAR("c", 1, "", 0, "", 0)
+CHAR("ca", 2, "(^)", 3, "", 0)
+CHAR("ci", 2, "O", 1, "", 0)
+CHAR("co", 2, "(C)", 3, "", 0)
+CHAR("ct", 2, "c", 1, "", 0)
+CHAR("cu", 2, "U", 1, "", 0)
+CHAR("dA", 2, "v", 1, "", 0)
+CHAR("da", 2, "v", 1, "", 0)
+CHAR("dd", 2, "=", 1, "", 0)
+CHAR("de", 2, "o", 1, "", 0)
+CHAR("dg", 2, "-", 1, "", 0)
+CHAR("di", 2, "-:-", 3, "", 0)
+CHAR("e", 1, "\\", 1, "\\", 1)
+CHAR("em", 2, "--", 2, "&#8212;", 7)
+CHAR("en", 2, "-", 1, "&#8211;", 7)
+CHAR("eq", 2, "=", 1, "", 0)
+CHAR("es", 2, "{}", 2, "", 0)
+CHAR("eu", 2, "EUR", 3, "", 0)
+CHAR("fa", 2, "V", 1, "", 0)
+CHAR("fc", 2, ">", 1, "", 0)
+CHAR("ff", 2, "ff", 2, "", 0)
+CHAR("fi", 2, "fi", 2, "", 0)
+CHAR("fl", 2, "fl", 2, "", 0)
+CHAR("fo", 2, "<", 1, "", 0)
+CHAR("ga", 2, "`", 1, "", 0)
+CHAR("gr", 2, "V", 1, "", 0)
+CHAR("hA", 2, "<=>", 3, "", 0)
+CHAR("ho", 2, ",", 1, "", 0)
+CHAR("hy", 2, "-", 1, "", 0)
+CHAR("if", 2, "oo", 2, "", 0)
+CHAR("lA", 2, "<=", 2, "", 0)
+CHAR("lB", 2, "[", 1, "[", 1)
+CHAR("lC", 2, "{", 1, "", 0)
+CHAR("la", 2, "<", 1, "&lt;", 4)
+CHAR("lh", 2, "<=", 2, "", 0)
+CHAR("mo", 2, "E", 1, "", 0)
+CHAR("mu", 2, "x", 1, "", 0)
+CHAR("na", 2, "NaN", 3, "", 0)
+CHAR("nm", 2, "E", 1, "", 0)
+CHAR("no", 2, "~", 1, "", 0)
+CHAR("oA", 2, "A", 1, "", 0)
+CHAR("oa", 2, "a", 1, "", 0)
+CHAR("oe", 2, "oe", 2, "", 0)
+CHAR("oq", 2, "`", 1, "&#8216;", 7)
+CHAR("pd", 2, "a", 1, "", 0)
+CHAR("pl", 2, "+", 1, "", 0)
+CHAR("ps", 2, "9|", 2, "", 0)
+CHAR("r!", 2, "i", 1, "", 0)
+CHAR("r?", 2, "c", 1, "", 0)
+CHAR("rA", 2, "=>", 2, "", 0)
+CHAR("rB", 2, "]", 1, "]", 1)
+CHAR("rC", 2, "}", 1, "", 0)
+CHAR("ra", 2, ">", 1, "&gt;", 4)
+CHAR("rg", 2, "(R)", 3, "", 0)
+CHAR("rh", 2, "=>", 2, "", 0)
+CHAR("sc", 2, "S", 1, "", 0)
+CHAR("ss", 2, "ss", 2, "", 0)
+CHAR("st", 2, "-)", 2, "", 0)
+CHAR("te", 2, "3", 1, "", 0)
+CHAR("tf", 2, ".:.", 3, "", 0)
+CHAR("tm", 2, "tm", 2, "", 0)
+CHAR("ts", 2, "s", 1, "", 0)
+CHAR("uA", 2, "^", 1, "", 0)
+CHAR("ua", 2, "^", 1, "", 0)
+CHAR("|", 1, "", 0, "", 0)
+CHAR("~", 1, " ", 1, "", 0)
+CHAR("~=", 2, "~=", 2, "", 0)
+CHAR("~A", 2, "A", 1, "", 0)
+CHAR("~N", 2, "N", 1, "", 0)
+CHAR("~O", 2, "O", 1, "", 0)
+CHAR("~a", 2, "a", 1, "", 0)
+CHAR("~n", 2, "n", 1, "", 0)
+CHAR("~o", 2, "o", 1, "", 0)
+CHAR("~~", 2, "~~", 2, "", 0)
diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c
index a6a1c36502d..c61f3ac193b 100644
--- a/usr.bin/mandoc/term.c
+++ b/usr.bin/mandoc/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.14 2009/10/18 21:03:31 schwarze Exp $ */
+/* $Id: term.c,v 1.15 2009/10/19 09:16:58 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
+#include "chars.h"
#include "term.h"
#include "man.h"
#include "mdoc.h"
@@ -56,7 +57,7 @@ terminal_man(void *arg, const struct man *man)
p = (struct termp *)arg;
if (NULL == p->symtab)
- p->symtab = term_ascii2htab();
+ p->symtab = chars_init(CHARS_ASCII);
man_run(p, man);
}
@@ -69,7 +70,7 @@ terminal_mdoc(void *arg, const struct mdoc *mdoc)
p = (struct termp *)arg;
if (NULL == p->symtab)
- p->symtab = term_ascii2htab();
+ p->symtab = chars_init(CHARS_ASCII);
mdoc_run(p, mdoc);
}
@@ -89,8 +90,8 @@ term_free(struct termp *p)
if (p->buf)
free(p->buf);
- if (TERMENC_ASCII == p->enc && p->symtab)
- term_asciifree(p->symtab);
+ if (p->symtab)
+ chars_free(p->symtab);
free(p);
}
@@ -102,7 +103,7 @@ term_alloc(enum termenc enc)
struct termp *p;
if (NULL == (p = malloc(sizeof(struct termp))))
- err(1, "malloc");
+ return(NULL);
bzero(p, sizeof(struct termp));
p->maxrmargin = 78;
p->enc = enc;
@@ -331,7 +332,7 @@ do_special(struct termp *p, const char *word, size_t len)
size_t sz;
int i;
- rhs = term_a2ascii(p->symtab, word, len, &sz);
+ rhs = chars_a2ascii(p->symtab, word, len, &sz);
if (NULL == rhs) {
#if 0
@@ -354,7 +355,7 @@ do_reserved(struct termp *p, const char *word, size_t len)
size_t sz;
int i;
- rhs = term_a2res(p->symtab, word, len, &sz);
+ rhs = chars_a2res(p->symtab, word, len, &sz);
if (NULL == rhs) {
#if 0
@@ -555,7 +556,7 @@ buffer(struct termp *p, char c)
s = p->maxcols * 2;
p->buf = realloc(p->buf, s);
if (NULL == p->buf)
- err(1, "realloc");
+ err(1, "realloc"); /* FIXME: shouldn't be here! */
p->maxcols = s;
}
p->buf[(int)(p->col)++] = c;
diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h
index 618e6eb4818..61e5a5a3876 100644
--- a/usr.bin/mandoc/term.h
+++ b/usr.bin/mandoc/term.h
@@ -1,4 +1,4 @@
-/* $Id: term.h,v 1.10 2009/09/21 20:28:43 schwarze Exp $ */
+/* $Id: term.h,v 1.11 2009/10/19 09:16:58 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -20,9 +20,7 @@
__BEGIN_DECLS
enum termenc {
- TERMENC_ASCII,
- TERMENC_LATIN1, /* Not implemented. */
- TERMENC_UTF8 /* Not implemented. */
+ TERMENC_ASCII
};
struct termp {
@@ -50,11 +48,6 @@ struct termp {
void *symtab; /* Encoded-symbol table. */
};
-void *term_ascii2htab(void);
-const char *term_a2ascii(void *, const char *, size_t, size_t *);
-const char *term_a2res(void *, const char *, size_t, size_t *);
-void term_asciifree(void *);
-
void term_newln(struct termp *);
void term_vspace(struct termp *);
void term_word(struct termp *, const char *);