diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2015-08-29 21:37:20 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2015-08-29 21:37:20 +0000 |
commit | ed5bfd990cd4e6ba2ef4f67f0a93fd3b75795b15 (patch) | |
tree | ef7887daeea3e419323ae7ad4fd8a9b186c4b1f9 /roff.c | |
parent | 3f8c736c787041e63a15602a4b099c5c4270713e (diff) | |
download | mandoc-ed5bfd990cd4e6ba2ef4f67f0a93fd3b75795b15.tar.gz |
Implement the escape sequence \\$*, expanding to all arguments
of the current user-defined macro.
This is another missing feature required for ocserv(8).
Problem reported by Kurt Jaeger <pi at FreeBSD>.
Diffstat (limited to 'roff.c')
-rw-r--r-- | roff.c | 41 |
1 files changed, 26 insertions, 15 deletions
@@ -3080,7 +3080,7 @@ roff_userdef(ROFF_ARGS) { const char *arg[9], *ap; char *cp, *n1, *n2; - int i; + int i, ib, ie; size_t asz, rsz; /* @@ -3114,9 +3114,14 @@ roff_userdef(ROFF_ARGS) continue; if (*cp++ != '$') continue; - i = *cp - '1'; - if (0 > i || 8 < i) - continue; + if (*cp == '*') { /* \\$* inserts all arguments */ + ib = 0; + ie = r->argc - 1; + } else { /* \\$1 .. \\$9 insert one argument */ + ib = ie = *cp - '1'; + if (ib < 0 || ib > 8) + continue; + } cp -= 2; /* @@ -3124,11 +3129,13 @@ roff_userdef(ROFF_ARGS) * taking escaping of quotes into account. */ - asz = 0; - for (ap = arg[i]; *ap != '\0'; ap++) { - asz++; - if (*ap == '"') - asz += 3; + asz = ie > ib ? ie - ib : 0; /* for blanks */ + for (i = ib; i <= ie; i++) { + for (ap = arg[i]; *ap != '\0'; ap++) { + asz++; + if (*ap == '"') + asz += 3; + } } if (asz != 3) { @@ -3169,12 +3176,16 @@ roff_userdef(ROFF_ARGS) /* Copy the expanded argument, escaping quotes. */ n2 = cp; - for (ap = arg[i]; *ap != '\0'; ap++) { - if (*ap == '"') { - memcpy(n2, "\\(dq", 4); - n2 += 4; - } else - *n2++ = *ap; + for (i = ib; i <= ie; i++) { + for (ap = arg[i]; *ap != '\0'; ap++) { + if (*ap == '"') { + memcpy(n2, "\\(dq", 4); + n2 += 4; + } else + *n2++ = *ap; + } + if (i < ie) + *n2++ = ' '; } } |