aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2013-06-20 22:39:30 +0000
committerIngo Schwarze <schwarze@openbsd.org>2013-06-20 22:39:30 +0000
commit114032c297cb0cb196cf5356723060c257a60f4d (patch)
treeef6ff1e80068da91a2f84a6c1e432d3280f5d31a
parentb663981f57d1f458daecf7adb34612c2aa90985c (diff)
downloadmandoc-114032c297cb0cb196cf5356723060c257a60f4d.tar.gz
mandoc-114032c297cb0cb196cf5356723060c257a60f4d.tar.zst
mandoc-114032c297cb0cb196cf5356723060c257a60f4d.zip
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.
-rw-r--r--chars.c4
-rw-r--r--chars.in3
-rw-r--r--mandoc.c30
3 files changed, 28 insertions, 9 deletions
diff --git a/chars.c b/chars.c
index 8b4f6b64..3ad1f574 100644
--- a/chars.c
+++ b/chars.c
@@ -1,4 +1,4 @@
-/* $Id: chars.c,v 1.53 2013/05/18 16:40:15 schwarze Exp $ */
+/* $Id: chars.c,v 1.54 2013/06/20 22:39:30 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -37,7 +37,7 @@ struct ln {
int unicode;
};
-#define LINES_MAX 328
+#define LINES_MAX 329
#define CHAR(in, ch, code) \
{ NULL, (in), (ch), (code) },
diff --git a/chars.in b/chars.in
index a4c45b3c..cc6549e7 100644
--- a/chars.in
+++ b/chars.in
@@ -1,4 +1,4 @@
-/* $Id: chars.in,v 1.42 2011/10/02 10:02:26 kristaps Exp $ */
+/* $Id: chars.in,v 1.43 2013/06/20 22:39:30 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -42,6 +42,7 @@ CHAR("&", "", 0)
CHAR("^", "", 0)
CHAR("|", "", 0)
CHAR("}", "", 0)
+CHAR("t", "", 0)
/* Accents. */
CHAR("a\"", "\"", 779)
diff --git a/mandoc.c b/mandoc.c
index 420e8aa5..274b7163 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc.c,v 1.66 2012/06/12 20:21:04 kristaps Exp $ */
+/* $Id: mandoc.c,v 1.67 2013/06/20 22:39:30 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
@@ -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. */