summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2014-06-29 22:12:55 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2014-06-29 22:12:55 +0000
commit26961d2bc53d304d95d0d644f2ff4146623b53fb (patch)
tree9f1220fc4eecd26dd58223141aa077bf161614bc
parentf995e6431e8f77fdb5fe9c822bdba1939078da3e (diff)
Major roff_getname() cleanup.
* Return the name even if it is terminated by an escape sequence, not a blank. * Skip the full escape sequence using mandoc_escape(), not just the first byte. * Make it non-destructive, return the length instead of writing a '\0'. * Let .ds and .as cope with the above changes to the internal interface. * Fix .rm and .rr to accept an escape sequence as the end of a name. * Fix .nr and .rr to not set/delete a register with an empty name.
-rw-r--r--regress/usr.bin/mandoc/roff/ds/Makefile4
-rw-r--r--regress/usr.bin/mandoc/roff/ds/escname.in14
-rw-r--r--regress/usr.bin/mandoc/roff/ds/escname.out_ascii11
-rw-r--r--regress/usr.bin/mandoc/roff/nr/Makefile4
-rw-r--r--regress/usr.bin/mandoc/roff/nr/escname.in15
-rw-r--r--regress/usr.bin/mandoc/roff/nr/escname.out_ascii17
-rw-r--r--usr.bin/mandoc/roff.c88
7 files changed, 113 insertions, 40 deletions
diff --git a/regress/usr.bin/mandoc/roff/ds/Makefile b/regress/usr.bin/mandoc/roff/ds/Makefile
index cbb879f5580..98a93d753fd 100644
--- a/regress/usr.bin/mandoc/roff/ds/Makefile
+++ b/regress/usr.bin/mandoc/roff/ds/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.4 2014/04/07 21:00:00 schwarze Exp $
+# $OpenBSD: Makefile,v 1.5 2014/06/29 22:12:54 schwarze Exp $
-REGRESS_TARGETS = append nested quoting
+REGRESS_TARGETS = append escname nested quoting
.include <bsd.regress.mk>
diff --git a/regress/usr.bin/mandoc/roff/ds/escname.in b/regress/usr.bin/mandoc/roff/ds/escname.in
new file mode 100644
index 00000000000..6394144b552
--- /dev/null
+++ b/regress/usr.bin/mandoc/roff/ds/escname.in
@@ -0,0 +1,14 @@
+.Dd June 29, 2014
+.Dt DS-ESCNAME 1
+.Os OpenBSD
+.Sh NAME
+.Nm ds-escname
+.Nd escape sequences in string names
+.Sh DESCRIPTION
+.ds std\\esc stdval
+Now \e*[std\\esc] is
+.Sq \*[std\\esc] .
+.Pp
+.ds esc\eesc escval
+Now \e*[esc] is
+.Sq \*[esc] .
diff --git a/regress/usr.bin/mandoc/roff/ds/escname.out_ascii b/regress/usr.bin/mandoc/roff/ds/escname.out_ascii
new file mode 100644
index 00000000000..48d6bb51a3d
--- /dev/null
+++ b/regress/usr.bin/mandoc/roff/ds/escname.out_ascii
@@ -0,0 +1,11 @@
+DS-ESCNAME(1) OpenBSD Reference Manual DS-ESCNAME(1)
+
+NNAAMMEE
+ ddss--eessccnnaammee - escape sequences in string names
+
+DDEESSCCRRIIPPTTIIOONN
+ Now \*[std\esc] is `stdval'.
+
+ Now \*[esc] is `'.
+
+OpenBSD June 29, 2014 OpenBSD
diff --git a/regress/usr.bin/mandoc/roff/nr/Makefile b/regress/usr.bin/mandoc/roff/nr/Makefile
index e642dadeb26..a7bc4115a14 100644
--- a/regress/usr.bin/mandoc/roff/nr/Makefile
+++ b/regress/usr.bin/mandoc/roff/nr/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.5 2014/04/07 15:05:12 schwarze Exp $
+# $OpenBSD: Makefile,v 1.6 2014/06/29 22:12:54 schwarze Exp $
-REGRESS_TARGETS = argc eval int predef rr
+REGRESS_TARGETS = argc eval escname int predef rr
.include <bsd.regress.mk>
diff --git a/regress/usr.bin/mandoc/roff/nr/escname.in b/regress/usr.bin/mandoc/roff/nr/escname.in
new file mode 100644
index 00000000000..712b1d78d33
--- /dev/null
+++ b/regress/usr.bin/mandoc/roff/nr/escname.in
@@ -0,0 +1,15 @@
+.TH NR-ESCNAME 1 "June 29, 2014" OpenBSD
+.SH NAME
+nr-escname \- escape sequences in register names
+.SH DESCRIPTION
+.nr first 1
+.nr second 2
+.nr first\\second 3
+.nr first\esecond 4
+\n[first] \n[second] \n[first\\second]
+.PP
+.rr first\esecond
+\n[first] \n[second] \n[first\\second]
+.PP
+.rr first\\second
+\n[first] \n[second] \n[first\\second]
diff --git a/regress/usr.bin/mandoc/roff/nr/escname.out_ascii b/regress/usr.bin/mandoc/roff/nr/escname.out_ascii
new file mode 100644
index 00000000000..facc3fd1fda
--- /dev/null
+++ b/regress/usr.bin/mandoc/roff/nr/escname.out_ascii
@@ -0,0 +1,17 @@
+NR-ESCNAME(1) OpenBSD Reference Manual NR-ESCNAME(1)
+
+
+
+NNAAMMEE
+ nr-escname - escape sequences in register names
+
+DDEESSCCRRIIPPTTIIOONN
+ 1 2 3
+
+ 0 2 3
+
+ 0 2 0
+
+
+
+OpenBSD June 29, 2014 NR-ESCNAME(1)
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 0d2a81b40a5..56155bfdfe8 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.84 2014/06/29 21:19:34 schwarze Exp $ */
+/* $Id: roff.c,v 1.85 2014/06/29 22:12:54 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -183,7 +183,7 @@ static int roff_evalstrcond(const char *, int *);
static void roff_free1(struct roff *);
static void roff_freereg(struct roffreg *);
static void roff_freestr(struct roffkv *);
-static char *roff_getname(struct roff *, char **, int, int);
+static size_t roff_getname(struct roff *, char **, int, int);
static int roff_getnum(const char *, int *, int *);
static int roff_getop(const char *, int *, char *);
static int roff_getregn(const struct roff *,
@@ -1314,29 +1314,31 @@ out:
static enum rofferr
roff_ds(ROFF_ARGS)
{
- char *name, *string;
+ char *string;
+ const char *name;
+ size_t namesz;
/*
- * A symbol is named by the first word following the macro
- * invocation up to a space. Its value is anything after the
- * name's trailing whitespace and optional double-quote. Thus,
- *
- * [.ds foo "bar " ]
- *
- * will have `bar " ' as its value.
+ * The first word is the name of the string.
+ * If it is empty or terminated by an escape sequence,
+ * abort the `ds' request without defining anything.
*/
- string = *bufp + pos;
- name = roff_getname(r, &string, ln, pos);
+ name = string = *bufp + pos;
if ('\0' == *name)
return(ROFF_IGN);
- /* Read past initial double-quote. */
+ namesz = roff_getname(r, &string, ln, pos);
+ if ('\\' == name[namesz])
+ return(ROFF_IGN);
+
+ /* Read past the initial double-quote, if any. */
if ('"' == *string)
string++;
/* The rest is the value. */
- roff_setstr(r, name, string, ROFF_as == tok);
+ roff_setstrn(&r->strtab, name, namesz, string, strlen(string),
+ ROFF_as == tok);
return(ROFF_IGN);
}
@@ -1650,13 +1652,19 @@ roff_freereg(struct roffreg *reg)
static enum rofferr
roff_nr(ROFF_ARGS)
{
- const char *key;
- char *val;
+ char *key, *val;
+ size_t keysz;
int iv;
char sign;
- val = *bufp + pos;
- key = roff_getname(r, &val, ln, pos);
+ key = val = *bufp + pos;
+ if ('\0' == *key)
+ return(ROFF_IGN);
+
+ keysz = roff_getname(r, &val, ln, pos);
+ if ('\\' == key[keysz])
+ return(ROFF_IGN);
+ key[keysz] = '\0';
sign = *val;
if ('+' == sign || '-' == sign)
@@ -1672,11 +1680,14 @@ static enum rofferr
roff_rr(ROFF_ARGS)
{
struct roffreg *reg, **prev;
- const char *name;
- char *cp;
+ char *name, *cp;
+ size_t namesz;
- cp = *bufp + pos;
- name = roff_getname(r, &cp, ln, pos);
+ name = cp = *bufp + pos;
+ if ('\0' == *name)
+ return(ROFF_IGN);
+ namesz = roff_getname(r, &cp, ln, pos);
+ name[namesz] = '\0';
prev = &r->regtab;
while (1) {
@@ -1698,12 +1709,15 @@ roff_rm(ROFF_ARGS)
{
const char *name;
char *cp;
+ size_t namesz;
cp = *bufp + pos;
while ('\0' != *cp) {
- name = roff_getname(r, &cp, ln, (int)(cp - *bufp));
- if ('\0' != *name)
- roff_setstr(r, name, NULL, 0);
+ name = cp;
+ namesz = roff_getname(r, &cp, ln, (int)(cp - *bufp));
+ roff_setstrn(&r->strtab, name, namesz, NULL, 0, 0);
+ if ('\\' == name[namesz])
+ break;
}
return(ROFF_IGN);
}
@@ -2003,37 +2017,39 @@ roff_userdef(ROFF_ARGS)
ROFF_REPARSE : ROFF_APPEND);
}
-static char *
+static size_t
roff_getname(struct roff *r, char **cpp, int ln, int pos)
{
char *name, *cp;
+ size_t namesz;
name = *cpp;
if ('\0' == *name)
- return(name);
+ return(0);
- /* Read until end of name. */
- for (cp = name; '\0' != *cp && ' ' != *cp; cp++) {
+ /* Read until end of name and terminate it with NUL. */
+ for (cp = name; 1; cp++) {
+ if ('\0' == *cp || ' ' == *cp) {
+ namesz = cp - name;
+ break;
+ }
if ('\\' != *cp)
continue;
cp++;
if ('\\' == *cp)
continue;
+ namesz = cp - name - 1;
mandoc_msg(MANDOCERR_NAMESC, r->parse, ln, pos, NULL);
- *cp = '\0';
- name = cp;
+ mandoc_escape((const char **)&cp, NULL, NULL);
+ break;
}
- /* Nil-terminate name. */
- if ('\0' != *cp)
- *(cp++) = '\0';
-
/* Read past spaces. */
while (' ' == *cp)
cp++;
*cpp = cp;
- return(name);
+ return(namesz);
}
/*