summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2010-09-13 22:04:02 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2010-09-13 22:04:02 +0000
commit69daa2237de0bcc6b4d1ec395ef5fedeca9df9ad (patch)
tree3d1a67bbcc427bdd0668bdd4388dc5fe4c27dffd /usr.bin/mandoc
parentadbda52fbb890551925233cce5dda0908c890d5c (diff)
Parse and ignore the \k, \o, \w, and \z roff escapes, and recursively
ignore embedded escapes and mathematical roff subexpressions. In roff copy mode, resolve "\\" to '\'. Allow ".xx\}" where xx is a macro to close roff conditional scope. Mandoc now handles the special character definitions in the pod2man(1) preamble, so remove the explicit redefinitions in chars.c/chars.in. From kristaps@. I have checked that this causes no relevant change to the Perl manuals. The only change introduced is that some non-ASCII characters rendered incorrectly before are now rendered incorrectly in a different way. For example, e accent aigu was "e", now is "e'" and c cedille was "c", now is "c,".
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r--usr.bin/mandoc/chars.c4
-rw-r--r--usr.bin/mandoc/chars.in13
-rw-r--r--usr.bin/mandoc/mandoc.c46
-rw-r--r--usr.bin/mandoc/out.c43
-rw-r--r--usr.bin/mandoc/roff.c37
5 files changed, 117 insertions, 26 deletions
diff --git a/usr.bin/mandoc/chars.c b/usr.bin/mandoc/chars.c
index 4b5f93c07f8..120a66140b0 100644
--- a/usr.bin/mandoc/chars.c
+++ b/usr.bin/mandoc/chars.c
@@ -1,4 +1,4 @@
-/* $Id: chars.c,v 1.12 2010/08/20 00:53:35 schwarze Exp $ */
+/* $Id: chars.c,v 1.13 2010/09/13 22:04:01 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -36,7 +36,7 @@ struct ln {
#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
};
-#define LINES_MAX 369
+#define LINES_MAX 362
#define CHAR(in, ch, code) \
{ NULL, (in), (ch), (code), CHARS_CHAR },
diff --git a/usr.bin/mandoc/chars.in b/usr.bin/mandoc/chars.in
index 7df6cbd6dde..4c48e3d3209 100644
--- a/usr.bin/mandoc/chars.in
+++ b/usr.bin/mandoc/chars.in
@@ -1,4 +1,4 @@
-/* $Id: chars.in,v 1.11 2010/08/18 02:46:37 schwarze Exp $ */
+/* $Id: chars.in,v 1.12 2010/09/13 22:04:01 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -322,8 +322,8 @@ CHAR("fi", "fi", 64257)
CHAR("fl", "fl", 64258)
CHAR("Fi", "ffi", 64259)
CHAR("Fl", "ffl", 64260)
-BOTH("AE", "AE", 198)
-BOTH("ae", "ae", 230)
+CHAR("AE", "AE", 198)
+CHAR("ae", "ae", 230)
CHAR("OE", "OE", 338)
CHAR("oe", "oe", 339)
CHAR("ss", "ss", 223)
@@ -360,13 +360,6 @@ STRING("^", "^", 94)
STRING(",", ",", 44)
STRING("~", "~", 126)
STRING("/", "/", 47)
-STRING(":", "\"", 776)
-STRING("8", "B", 946)
-STRING("o", "o", 176)
-STRING("D-", "D", 208)
-STRING("d-", "o", 240)
-STRING("Th", "b", 222)
-STRING("th", "b", 254)
/* Old style. */
STRING("Am", "&", 38)
diff --git a/usr.bin/mandoc/mandoc.c b/usr.bin/mandoc/mandoc.c
index 9abaced9a54..8d0421f11bd 100644
--- a/usr.bin/mandoc/mandoc.c
+++ b/usr.bin/mandoc/mandoc.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc.c,v 1.18 2010/08/20 00:53:35 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.19 2010/09/13 22:04:01 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -51,14 +51,10 @@ mandoc_special(char *p)
/* FALLTHROUGH */
case ('x'):
/* FALLTHROUGH */
- case ('w'):
- /* FALLTHROUGH */
case ('S'):
/* FALLTHROUGH */
case ('R'):
/* FALLTHROUGH */
- case ('o'):
- /* FALLTHROUGH */
case ('N'):
/* FALLTHROUGH */
case ('l'):
@@ -126,6 +122,27 @@ mandoc_special(char *p)
p++;
}
+ /* Handle embedded numerical subexp or escape. */
+
+ if ('(' == *p) {
+ while (*p && ')' != *p)
+ if ('\\' == *p++) {
+ i = mandoc_special(--p);
+ if (0 == i)
+ return(0);
+ p += i;
+ }
+
+ if (')' == *p++)
+ break;
+
+ return(0);
+ } else if ('\\' == *p) {
+ if (0 == (i = mandoc_special(p)))
+ return(0);
+ p += i;
+ }
+
break;
#if 0
case ('Y'):
@@ -136,9 +153,9 @@ mandoc_special(char *p)
/* FALLTHROUGH */
case ('n'):
/* FALLTHROUGH */
+#endif
case ('k'):
/* FALLTHROUGH */
-#endif
case ('M'):
/* FALLTHROUGH */
case ('m'):
@@ -167,6 +184,23 @@ mandoc_special(char *p)
case ('['):
term = ']';
break;
+ case ('z'):
+ len = 1;
+ if ('\\' == *p) {
+ if (0 == (i = mandoc_special(p)))
+ return(0);
+ p += i;
+ return(*p ? (int)(p - sv) : 0);
+ }
+ break;
+ case ('o'):
+ /* FALLTHROUGH */
+ case ('w'):
+ if ('\'' == *p++) {
+ term = '\'';
+ break;
+ }
+ /* FALLTHROUGH */
default:
len = 1;
p--;
diff --git a/usr.bin/mandoc/out.c b/usr.bin/mandoc/out.c
index 4da5bb43634..6e1f812fa29 100644
--- a/usr.bin/mandoc/out.c
+++ b/usr.bin/mandoc/out.c
@@ -1,4 +1,4 @@
-/* $Id: out.c,v 1.7 2010/08/18 02:38:40 schwarze Exp $ */
+/* $Id: out.c,v 1.8 2010/09/13 22:04:01 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -168,6 +168,7 @@ a2roffdeco(enum roffdeco *d, const char **word, size_t *sz)
int i, j, lim;
char term, c;
const char *wp;
+ enum roffdeco dd;
*d = DECO_NONE;
lim = i = 0;
@@ -215,6 +216,8 @@ a2roffdeco(enum roffdeco *d, const char **word, size_t *sz)
break;
}
break;
+ case ('k'):
+ /* FALLTHROUGH */
case ('M'):
/* FALLTHROUGH */
case ('m'):
@@ -271,7 +274,27 @@ a2roffdeco(enum roffdeco *d, const char **word, size_t *sz)
return(i);
i++;
}
-
+
+ /* Handle embedded numerical subexp or escape. */
+
+ if ('(' == wp[i]) {
+ while (wp[i] && ')' != wp[i])
+ if ('\\' == wp[i++]) {
+ /* Handle embedded escape. */
+ *word = &wp[i];
+ i += a2roffdeco(&dd, word, sz);
+ }
+
+ if (')' == wp[i++])
+ break;
+
+ *d = DECO_NONE;
+ return(i - 1);
+ } else if ('\\' == wp[i]) {
+ *word = &wp[++i];
+ i += a2roffdeco(&dd, word, sz);
+ }
+
break;
case ('['):
*d = DECO_SPECIAL;
@@ -280,6 +303,22 @@ a2roffdeco(enum roffdeco *d, const char **word, size_t *sz)
case ('c'):
*d = DECO_NOSPACE;
return(i);
+ case ('z'):
+ *d = DECO_NONE;
+ if ('\\' == wp[i]) {
+ *word = &wp[++i];
+ return(i + a2roffdeco(&dd, word, sz));
+ } else
+ lim = 1;
+ break;
+ case ('o'):
+ /* FALLTHROUGH */
+ case ('w'):
+ if ('\'' == wp[i++]) {
+ term = '\'';
+ break;
+ }
+ /* FALLTHROUGH */
default:
*d = DECO_SSPECIAL;
i--;
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index f2a84ddf13f..af5eb60ce5f 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.11 2010/08/20 00:53:35 schwarze Exp $ */
+/* $Id: roff.c,v 1.12 2010/09/13 22:04:01 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -128,6 +128,7 @@ static int roff_res(struct roff *,
char **, size_t *, int);
static void roff_setstr(struct roff *,
const char *, const char *);
+static char *roff_strdup(const char *);
/* See roff_hash_find() */
@@ -744,11 +745,13 @@ roff_cond_sub(ROFF_ARGS)
l = r->last;
roffnode_cleanscope(r);
- if (l != r->last)
- return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
-
- if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
+ if (ROFF_MAX == (t = roff_parse(*bufp, &pos))) {
+ if ('\\' == (*bufp)[pos] && '}' == (*bufp)[pos + 1])
+ return(roff_ccond
+ (r, ROFF_ccond, bufp, szp,
+ ln, pos, pos + 2, offs));
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
+ }
/*
* A denied conditional must evaluate its children if and only
@@ -1005,6 +1008,27 @@ roff_nr(ROFF_ARGS)
}
+static char *
+roff_strdup(const char *name)
+{
+ char *namecopy, *sv;
+
+ /*
+ * This isn't a nice simple mandoc_strdup() because we must
+ * handle roff's stupid double-escape rule.
+ */
+ sv = namecopy = mandoc_malloc(strlen(name) + 1);
+ while (*name) {
+ if ('\\' == *name && '\\' == *(name + 1))
+ name++;
+ *namecopy++ = *name++;
+ }
+
+ *namecopy = '\0';
+ return(sv);
+}
+
+
static void
roff_setstr(struct roff *r, const char *name, const char *string)
{
@@ -1024,7 +1048,8 @@ roff_setstr(struct roff *r, const char *name, const char *string)
} else
free(n->string);
- n->string = string ? strdup(string) : NULL;
+ /* Don't use mandoc_strdup: clean out double-escapes. */
+ n->string = string ? roff_strdup(string) : NULL;
}