aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-07-08 09:28:33 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-07-08 09:28:33 +0000
commit0731e739450b07bc6fa8a6f731af719b832df6f6 (patch)
treea86779a5281fc8b9effdcb1ec6d1d7fbd87c10da /roff.c
parent234bdeea7ecb7af55757791d9dcd02e1980d5e00 (diff)
downloadmandoc-0731e739450b07bc6fa8a6f731af719b832df6f6.tar.gz
mandoc-0731e739450b07bc6fa8a6f731af719b832df6f6.tar.zst
mandoc-0731e739450b07bc6fa8a6f731af719b832df6f6.zip
Fix two issues: the first, where a `.\}' wasn't being interpreted as a
proper macro in some conditions, resulting in strange parse errors. The second, where `\}' was being re-written as `\&'. Instead, we re-write this as two spaces OR nothing at all, if at the end of line. This isn't exactly what groff does (who knows...) but is a much safer and better way than how I was doing it before.
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/roff.c b/roff.c
index 8f74edf0..79d0897e 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.143 2011/06/30 08:05:13 kristaps Exp $ */
+/* $Id: roff.c,v 1.144 2011/07/08 09:28:33 kristaps Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -596,11 +596,18 @@ roff_parse(struct roff *r, const char *buf, int *pos)
size_t maclen;
enum rofft t;
- if ('\0' == buf[*pos] || '"' == buf[*pos])
+ if ('\0' == buf[*pos] || '"' == buf[*pos] ||
+ '\t' == buf[*pos] || ' ' == buf[*pos])
return(ROFF_MAX);
+ /*
+ * We stop the macro parse at an escape, tab, space, or nil.
+ * However, `\}' is also a valid macro, so make sure we don't
+ * clobber it by seeing the `\' as the end of token.
+ */
+
mac = buf + *pos;
- maclen = strcspn(mac, " \\\t\0");
+ maclen = strcspn(mac + 1, " \\\t\0") + 1;
t = (r->current_string = roff_getstrn(r, mac, maclen))
? ROFF_USERDEF : roff_hash_find(mac, maclen);
@@ -882,7 +889,22 @@ roff_cond_sub(ROFF_ARGS)
ep++;
if ('}' != *ep)
continue;
- *ep = '&';
+
+ /*
+ * Make the \} go away.
+ * This is a little haphazard, as it's not quite
+ * clear how nroff does this.
+ * If we're at the end of line, then just chop
+ * off the \} and resize the buffer.
+ * If we aren't, then conver it to spaces.
+ */
+
+ if ('\0' == *(ep + 1)) {
+ *--ep = '\0';
+ *szp -= 2;
+ } else
+ *(ep - 1) = *ep = ' ';
+
roff_ccond(r, ROFF_ccond, bufp, szp,
ln, pos, pos + 2, offs);
break;