diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2013-06-20 22:39:30 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2013-06-20 22:39:30 +0000 |
commit | 7d5d7db4acbef7399cc00837c2424a8b25ccd8e4 (patch) | |
tree | b039cc491c0a240e9307b89b2735ab5313653677 /mandoc.c | |
parent | 02147107a75ec2ff2290c4341da118dda7bab836 (diff) | |
download | mandoc-7d5d7db4acbef7399cc00837c2424a8b25ccd8e4.tar.gz |
Improve handling of the roff(7) "\t" escape sequence:
* Parsing macro arguments has to be done in copy mode,
which implies replacing "\t" by a literal tab character.
* Otherwise, render "\t" as the empty string, not as a 't' character.
This fixes formatting of the distfile example in the oldrdist(1) manual.
This also shows up in the unzip(1) manual as one of several issues
preventing the removal of USE_GROFF from the archivers/unzip port.
Thanks to espie@ for attracting my attention to the unzip(1) manual.
Diffstat (limited to 'mandoc.c')
-rw-r--r-- | mandoc.c | 28 |
1 files changed, 23 insertions, 5 deletions
@@ -432,17 +432,35 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos) pairs = 0; white = 0; for (cp = start; '\0' != *cp; cp++) { - /* Move left after quoted quotes and escaped backslashes. */ + + /* + * Move the following text left + * after quoted quotes and after "\\" and "\t". + */ if (pairs) cp[-pairs] = cp[0]; + if ('\\' == cp[0]) { - if ('\\' == cp[1]) { - /* Poor man's copy mode. */ + /* + * In copy mode, translate double to single + * backslashes and backslash-t to literal tabs. + */ + switch (cp[1]) { + case ('t'): + cp[0] = '\t'; + /* FALLTHROUGH */ + case ('\\'): pairs++; cp++; - } else if (0 == quoted && ' ' == cp[1]) + break; + case (' '): /* Skip escaped blanks. */ - cp++; + if (0 == quoted) + cp++; + break; + default: + break; + } } else if (0 == quoted) { if (' ' == cp[0]) { /* Unescaped blanks end unquoted args. */ |