aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--libmandoc.h4
-rw-r--r--regress/roff/nr/Makefile2
-rw-r--r--regress/roff/nr/undef.in24
-rw-r--r--regress/roff/nr/undef.out_ascii21
-rw-r--r--roff.c44
5 files changed, 68 insertions, 27 deletions
diff --git a/libmandoc.h b/libmandoc.h
index 2cf07628..9cc8cce4 100644
--- a/libmandoc.h
+++ b/libmandoc.h
@@ -1,4 +1,4 @@
-/* $Id: libmandoc.h,v 1.70 2017/07/08 17:52:49 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.71 2018/04/09 22:27:04 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -66,7 +66,7 @@ void roff_man_reset(struct roff_man *);
enum rofferr roff_parseln(struct roff *, int, struct buf *, int *);
void roff_endparse(struct roff *);
void roff_setreg(struct roff *, const char *, int, char sign);
-int roff_getreg(const struct roff *, const char *);
+int roff_getreg(struct roff *, const char *);
char *roff_strdup(const struct roff *, const char *);
int roff_getcontrol(const struct roff *,
const char *, int *);
diff --git a/regress/roff/nr/Makefile b/regress/roff/nr/Makefile
index 8da68878..b3ba8102 100644
--- a/regress/roff/nr/Makefile
+++ b/regress/roff/nr/Makefile
@@ -1,6 +1,6 @@
# $OpenBSD: Makefile,v 1.9 2015/01/23 00:38:43 schwarze Exp $
-REGRESS_TARGETS = argc divzero eval escname int predef rr scale
+REGRESS_TARGETS = argc divzero escname eval int predef rr scale undef
LINT_TARGETS = divzero escname
.include <bsd.regress.mk>
diff --git a/regress/roff/nr/undef.in b/regress/roff/nr/undef.in
new file mode 100644
index 00000000..fd6000cb
--- /dev/null
+++ b/regress/roff/nr/undef.in
@@ -0,0 +1,24 @@
+.\" $OpenBSD: divzero.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $
+.TH NR-UNDEF 1 "April 9, 2018"
+.SH NAME
+nr-undef \- using an undefined number register
+.SH DESCRIPTION
+The myr register is initially
+.ie rmyr defined.
+.el undefined.
+.PP
+Its initial value is \n[myr].
+.PP
+After interpolating it, is is now
+.ie rmyr defined.
+.el undefined.
+.PP
+.nr myr 1
+After defining it to \n[myr], it is of course still
+.ie rmyr defined.
+.el undefined.
+.PP
+.rr myr
+After removing it, it is again
+.ie rmyr defined.
+.el undefined.
diff --git a/regress/roff/nr/undef.out_ascii b/regress/roff/nr/undef.out_ascii
new file mode 100644
index 00000000..e7649eca
--- /dev/null
+++ b/regress/roff/nr/undef.out_ascii
@@ -0,0 +1,21 @@
+NR-UNDEF(1) General Commands Manual NR-UNDEF(1)
+
+
+
+NNAAMMEE
+ nr-undef - using an undefined number register
+
+DDEESSCCRRIIPPTTIIOONN
+ The myr register is initially undefined.
+
+ Its initial value is 0.
+
+ After interpolating it, is is now defined.
+
+ After defining it to 1, it is of course still defined.
+
+ After removing it, it is again undefined.
+
+
+
+OpenBSD April 9, 2018 NR-UNDEF(1)
diff --git a/roff.c b/roff.c
index 2a609eaf..08c0afc5 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.325 2018/04/09 02:31:42 schwarze Exp $ */
+/* $Id: roff.c,v 1.326 2018/04/09 22:27:04 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -182,8 +182,7 @@ static void roff_freestr(struct roffkv *);
static size_t roff_getname(struct roff *, char **, int, int);
static int roff_getnum(const char *, int *, int *, int);
static int roff_getop(const char *, int *, char *);
-static int roff_getregn(const struct roff *,
- const char *, size_t);
+static int roff_getregn(struct roff *, const char *, size_t);
static int roff_getregro(const struct roff *,
const char *name);
static const char *roff_getstrn(struct roff *,
@@ -207,6 +206,8 @@ static enum rofferr roff_res(struct roff *, struct buf *, int, int);
static enum rofferr roff_rm(ROFF_ARGS);
static enum rofferr roff_rn(ROFF_ARGS);
static enum rofferr roff_rr(ROFF_ARGS);
+static void roff_setregn(struct roff *, const char *,
+ size_t, int, char);
static void roff_setstr(struct roff *,
const char *, const char *, int);
static void roff_setstrn(struct roffkv **, const char *,
@@ -2521,19 +2522,27 @@ roff_evalnum(struct roff *r, int ln, const char *v,
void
roff_setreg(struct roff *r, const char *name, int val, char sign)
{
+ roff_setregn(r, name, strlen(name), val, sign);
+}
+
+static void
+roff_setregn(struct roff *r, const char *name, size_t len,
+ int val, char sign)
+{
struct roffreg *reg;
/* Search for an existing register with the same name. */
reg = r->regtab;
- while (reg && strcmp(name, reg->key.p))
+ while (reg != NULL && (reg->key.sz != len ||
+ strncmp(reg->key.p, name, len) != 0))
reg = reg->next;
if (NULL == reg) {
/* Create a new register. */
reg = mandoc_malloc(sizeof(struct roffreg));
- reg->key.p = mandoc_strdup(name);
- reg->key.sz = strlen(name);
+ reg->key.p = mandoc_strndup(name, len);
+ reg->key.sz = len;
reg->val = 0;
reg->next = r->regtab;
r->regtab = reg;
@@ -2578,26 +2587,13 @@ roff_getregro(const struct roff *r, const char *name)
}
int
-roff_getreg(const struct roff *r, const char *name)
+roff_getreg(struct roff *r, const char *name)
{
- struct roffreg *reg;
- int val;
-
- if ('.' == name[0] && '\0' != name[1] && '\0' == name[2]) {
- val = roff_getregro(r, name + 1);
- if (-1 != val)
- return val;
- }
-
- for (reg = r->regtab; reg; reg = reg->next)
- if (0 == strcmp(name, reg->key.p))
- return reg->val;
-
- return 0;
+ return roff_getregn(r, name, strlen(name));
}
static int
-roff_getregn(const struct roff *r, const char *name, size_t len)
+roff_getregn(struct roff *r, const char *name, size_t len)
{
struct roffreg *reg;
int val;
@@ -2613,6 +2609,7 @@ roff_getregn(const struct roff *r, const char *name, size_t len)
0 == strncmp(name, reg->key.p, len))
return reg->val;
+ roff_setregn(r, name, len, 0, '\0');
return 0;
}
@@ -2664,14 +2661,13 @@ roff_nr(ROFF_ARGS)
keysz = roff_getname(r, &val, ln, pos);
if (key[keysz] == '\\')
return ROFF_IGN;
- key[keysz] = '\0';
sign = *val;
if (sign == '+' || sign == '-')
val++;
if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE))
- roff_setreg(r, key, iv, sign);
+ roff_setregn(r, key, keysz, iv, sign);
return ROFF_IGN;
}