aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-04-09 22:27:04 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-04-09 22:27:04 +0000
commit318dcfc920386cbcdf23d6d81d97b72fabb8de35 (patch)
treed604e4c97cd171505a613612fe598dcf14b06e9b
parent5aacba9ce0d0de6d9276777e5f2b193b60604d5f (diff)
downloadmandoc-318dcfc920386cbcdf23d6d81d97b72fabb8de35.tar.gz
mandoc-318dcfc920386cbcdf23d6d81d97b72fabb8de35.tar.zst
mandoc-318dcfc920386cbcdf23d6d81d97b72fabb8de35.zip
When accessing an undefined number register, define it to be zero, like
the previous commit for strings and macros, only technically simpler. Desired behaviour also mentioned by Werner Lemberg in 2011. This diff adds functionality but is -21 +19 LOC. :-)
-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;
}