aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-08-21 18:15:22 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-08-21 18:15:22 +0000
commit1483cf671448b44a8bf37ea7129c88e24f588abd (patch)
tree491940c1180723f98f3b4e05133b1a62ba0dd3af /roff.c
parent9faad2ae0e7caf95d294df3c2ba845e98e0fff85 (diff)
downloadmandoc-1483cf671448b44a8bf37ea7129c88e24f588abd.tar.gz
mandoc-1483cf671448b44a8bf37ea7129c88e24f588abd.tar.zst
mandoc-1483cf671448b44a8bf37ea7129c88e24f588abd.zip
Implement the \\$@ escape sequence (insert all macro arguments,
quoted) in addition to the already supported \\$* (similar, but unquoted). Then use \\$@ to improve the implementation of the .als request (macro alias). Needed by groff_hdtbl(7). Gosh, it feels like the manual pages of the groff package are exercising every bloody roff(7) feature under the sun. In the manual page source code itself, not merely in the implementation of the used macro packages, that is.
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/roff.c b/roff.c
index 4dd18e3e..bef86e8c 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.337 2018/08/20 17:25:09 schwarze Exp $ */
+/* $Id: roff.c,v 1.338 2018/08/21 18:15:22 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -3156,7 +3156,7 @@ roff_als(ROFF_ARGS)
if (oldsz == 0)
return ROFF_IGN;
- valsz = mandoc_asprintf(&value, ".%.*s \\$*\\\"\n",
+ valsz = mandoc_asprintf(&value, ".%.*s \\$@\\\"\n",
(int)oldsz, oldn);
roff_setstrn(&r->strtab, newn, newsz, value, valsz, 0);
roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0);
@@ -3380,7 +3380,7 @@ roff_userdef(ROFF_ARGS)
{
const char *arg[16], *ap;
char *cp, *n1, *n2;
- int argc, expand_count, i, ib, ie;
+ int argc, expand_count, i, ib, ie, quote_args;
size_t asz, esz, rsz;
/*
@@ -3415,13 +3415,21 @@ roff_userdef(ROFF_ARGS)
continue;
if (*cp++ != '$')
continue;
- if (*cp == '*') { /* \\$* inserts all arguments */
+
+ quote_args = 0;
+ switch (*cp) {
+ case '@': /* \\$@ inserts all arguments, quoted */
+ quote_args = 1;
+ /* FALLTHROUGH */
+ case '*': /* \\$* inserts all arguments, unquoted */
ib = 0;
ie = argc - 1;
- } else { /* \\$1 .. \\$9 insert one argument */
+ break;
+ default: /* \\$1 .. \\$9 insert one argument */
ib = ie = *cp - '1';
if (ib < 0 || ib > 8)
continue;
+ break;
}
cp -= 2;
@@ -3447,6 +3455,8 @@ roff_userdef(ROFF_ARGS)
asz = ie > ib ? ie - ib : 0; /* for blanks */
for (i = ib; i <= ie; i++) {
+ if (quote_args)
+ asz += 2;
for (ap = arg[i]; *ap != '\0'; ap++) {
asz++;
if (*ap == '"')
@@ -3493,6 +3503,8 @@ roff_userdef(ROFF_ARGS)
n2 = cp;
for (i = ib; i <= ie; i++) {
+ if (quote_args)
+ *n2++ = '"';
for (ap = arg[i]; *ap != '\0'; ap++) {
if (*ap == '"') {
memcpy(n2, "\\(dq", 4);
@@ -3500,6 +3512,8 @@ roff_userdef(ROFF_ARGS)
} else
*n2++ = *ap;
}
+ if (quote_args)
+ *n2++ = '"';
if (i < ie)
*n2++ = ' ';
}