diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-09-13 22:04:02 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-09-13 22:04:02 +0000 |
commit | 69daa2237de0bcc6b4d1ec395ef5fedeca9df9ad (patch) | |
tree | 3d1a67bbcc427bdd0668bdd4388dc5fe4c27dffd /usr.bin/mandoc | |
parent | adbda52fbb890551925233cce5dda0908c890d5c (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.c | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/chars.in | 13 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.c | 46 | ||||
-rw-r--r-- | usr.bin/mandoc/out.c | 43 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 37 |
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; } |