aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-07-01 09:47:30 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-07-01 09:47:30 +0000
commitc93f1e0f2d3891330860de19b5ec3e274971a300 (patch)
tree6aa6244559b5608dfb842dda23dbc7377e0ee1ba
parent3aad1243de81f4fa87d3d67a5c4c6f0385bd0ac7 (diff)
downloadmandoc-c93f1e0f2d3891330860de19b5ec3e274971a300.tar.gz
mandoc-c93f1e0f2d3891330860de19b5ec3e274971a300.tar.zst
mandoc-c93f1e0f2d3891330860de19b5ec3e274971a300.zip
Basic reporting of .Xrs to manual pages that don't exist
in the base system, inspired by mdoclint(1). We are able to do this because (1) the -mdoc parser, the -Tlint validator, and the man(1) manual page lookup code are all in the same program and (2) the mandoc.db(5) database format allows fast lookup. Feedback from, previous versions tested by, and OK jmc@. A few features will be added to this in the tree, step by step.
-rw-r--r--Makefile5
-rw-r--r--Makefile.depend24
-rwxr-xr-xconfigure4
-rw-r--r--configure.local.example7
-rw-r--r--main.c35
-rw-r--r--manconf.h5
-rw-r--r--mandoc.112
-rw-r--r--mandoc.h3
-rw-r--r--mandoc_headers.312
-rw-r--r--mandoc_xr.c112
-rw-r--r--mandoc_xr.h30
-rw-r--r--manpath.c9
-rw-r--r--mansearch.c12
-rw-r--r--mdoc_validate.c8
-rw-r--r--read.c3
15 files changed, 253 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index 59df2fcf..2fa997cb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.513 2017/06/12 19:05:47 schwarze Exp $
+# $Id: Makefile,v 1.514 2017/07/01 09:47:30 schwarze Exp $
#
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
# Copyright (c) 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -94,6 +94,7 @@ SRCS = att.c \
mandoc.c \
mandoc_aux.c \
mandoc_ohash.c \
+ mandoc_xr.c \
mandocd.c \
mandocdb.c \
manpath.c \
@@ -180,6 +181,7 @@ DISTFILES = INSTALL \
mandoc_html.3 \
mandoc_malloc.3 \
mandoc_ohash.h \
+ mandoc_xr.h \
mandocd.8 \
mansearch.3 \
mansearch.h \
@@ -229,6 +231,7 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
mandoc.o \
mandoc_aux.o \
mandoc_ohash.o \
+ mandoc_xr.o \
msec.o \
preconv.o \
read.o
diff --git a/Makefile.depend b/Makefile.depend
index 61d967af..c3d85adb 100644
--- a/Makefile.depend
+++ b/Makefile.depend
@@ -1,4 +1,4 @@
-att.o: att.c config.h roff.h mdoc.h libmdoc.h
+att.o: att.c config.h mandoc.h roff.h mdoc.h libmdoc.h
catman.o: catman.c config.h compat_fts.h
cgi.o: cgi.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h main.h manconf.h mansearch.h cgi.h
chars.o: chars.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h libmandoc.h
@@ -11,6 +11,7 @@ compat_mkdtemp.o: compat_mkdtemp.c config.h
compat_ohash.o: compat_ohash.c config.h compat_ohash.h
compat_progname.o: compat_progname.c config.h
compat_reallocarray.o: compat_reallocarray.c config.h
+compat_recallocarray.o: compat_recallocarray.c config.h
compat_strcasestr.o: compat_strcasestr.c config.h
compat_stringlist.o: compat_stringlist.c config.h compat_stringlist.h
compat_strlcat.o: compat_strlcat.c config.h
@@ -24,44 +25,45 @@ dba_read.o: dba_read.c mandoc_aux.h mansearch.h dba_array.h dba.h dbm.h
dba_write.o: dba_write.c config.h dba_write.h
dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h
dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h
-demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.h
+demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
html.o: html.c config.h mandoc_aux.h mandoc.h roff.h out.h html.h manconf.h main.h
-lib.o: lib.c config.h roff.h mdoc.h libmdoc.h lib.in
-main.o: main.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
+lib.o: lib.c config.h mandoc.h roff.h mdoc.h libmdoc.h lib.in
+main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
-man_html.o: man_html.c config.h mandoc_aux.h roff.h man.h out.h html.h main.h
+man_html.o: man_html.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h html.h main.h
man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h main.h
man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
-mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h
+mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h
+mandoc_xr.o: mandoc_xr.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.h
mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h main.h manconf.h
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h dba_array.h dba.h
manpath.o: manpath.c config.h mandoc_aux.h manconf.h
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
-mdoc_html.o: mdoc_html.c config.h mandoc_aux.h roff.h mdoc.h out.h html.h main.h
+mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h html.h main.h
mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h
mdoc_markdown.o: mdoc_markdown.c mandoc_aux.h mandoc.h roff.h mdoc.h main.h
mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h term.h tag.h main.h
-mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
+mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
preconv.o: preconv.c config.h mandoc.h libmandoc.h
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h roff_int.h
roff.o: roff.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h libmandoc.h roff_int.h libroff.h predefs.in
-roff_html.o: roff_html.c roff.h out.h html.h
-roff_term.o: roff_term.c roff.h out.h term.h
+roff_html.o: roff_html.c mandoc.h roff.h out.h html.h
+roff_term.o: roff_term.c mandoc.h roff.h out.h term.h
roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h
soelim.o: soelim.c config.h compat_stringlist.h
-st.o: st.c config.h roff.h mdoc.h libmdoc.h st.in
+st.o: st.c config.h mandoc.h roff.h mdoc.h libmdoc.h st.in
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
tbl_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
diff --git a/configure b/configure
index 346fd28b..f9416ce7 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# $Id: configure,v 1.63 2017/06/12 19:05:47 schwarze Exp $
+# $Id: configure,v 1.64 2017/07/01 09:47:30 schwarze Exp $
#
# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
#
@@ -35,6 +35,7 @@ echo "config.log: writing..."
SOURCEDIR=`dirname "$0"`
+MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
OSNAME=
UTF8_LOCALE=
@@ -359,6 +360,7 @@ __HEREDOC__
echo
echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\""
+echo "#define MANPATH_BASE \"${MANPATH_BASE}\""
echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\""
diff --git a/configure.local.example b/configure.local.example
index 4c0d77b0..d6110a22 100644
--- a/configure.local.example
+++ b/configure.local.example
@@ -1,4 +1,4 @@
-# $Id: configure.local.example,v 1.31 2017/06/12 19:05:47 schwarze Exp $
+# $Id: configure.local.example,v 1.32 2017/07/01 09:47:30 schwarze Exp $
#
# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
#
@@ -62,6 +62,11 @@ UTF8_LOCALE=en_US.UTF-8
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
+# Validation of cross references with mandoc -Tlint only looks
+# for manual pages in the following directories:
+
+MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
+
# In manual pages written in the mdoc(7) language, the operating system
# version is displayed in the page footer line. If an operating system
# is specified as an argument to the .Os macro, that is always used.
diff --git a/main.c b/main.c
index 03092ef6..b8400ff8 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.293 2017/06/24 14:38:32 schwarze Exp $ */
+/* $Id: main.c,v 1.294 2017/07/01 09:47:30 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -43,6 +43,7 @@
#include "mandoc_aux.h"
#include "mandoc.h"
+#include "mandoc_xr.h"
#include "roff.h"
#include "mdoc.h"
#include "man.h"
@@ -86,6 +87,7 @@ struct curparse {
int mandocdb(int, char *[]);
+static void check_xr(const char *);
static int fs_lookup(const struct manpaths *,
size_t ipath, const char *,
const char *, const char *,
@@ -517,6 +519,7 @@ main(int argc, char *argv[])
break;
}
}
+ mandoc_xr_free();
mparse_free(curp.mp);
mchars_free();
@@ -747,6 +750,8 @@ parse(struct curparse *curp, int fd, const char *file)
if (man == NULL)
return;
+ if (curp->mmin < MANDOCERR_STYLE)
+ mandoc_xr_reset();
if (man->macroset == MACROSET_MDOC) {
if (curp->outtype != OUTT_TREE || !curp->outopts->noval)
mdoc_validate(man);
@@ -798,10 +803,38 @@ parse(struct curparse *curp, int fd, const char *file)
break;
}
}
+ check_xr(file);
mparse_updaterc(curp->mp, &rc);
}
static void
+check_xr(const char *file)
+{
+ static struct manpaths paths;
+ struct mansearch search;
+ struct mandoc_xr *xr;
+ char *cp;
+ size_t sz;
+
+ if (paths.sz == 0)
+ manpath_base(&paths);
+
+ for (xr = mandoc_xr_get(); xr != NULL; xr = xr->next) {
+ search.arch = NULL;
+ search.sec = xr->sec;
+ search.outkey = NULL;
+ search.argmode = ARG_NAME;
+ search.firstmatch = 1;
+ if (mansearch(&search, &paths, 1, &xr->name, NULL, &sz))
+ continue;
+ mandoc_asprintf(&cp, "Xr %s %s", xr->name, xr->sec);
+ mmsg(MANDOCERR_XR_BAD, MANDOCLEVEL_STYLE,
+ file, xr->line, xr->pos + 1, cp);
+ free(cp);
+ }
+}
+
+static void
outdata_alloc(struct curparse *curp)
{
switch (curp->outtype) {
diff --git a/manconf.h b/manconf.h
index f5c678e8..b4cd3164 100644
--- a/manconf.h
+++ b/manconf.h
@@ -1,6 +1,6 @@
-/* $OpenBSD$ */
+/* $Id: manconf.h,v 1.5 2017/07/01 09:47:30 schwarze Exp $ */
/*
- * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -47,3 +47,4 @@ struct manconf {
void manconf_parse(struct manconf *, const char *, char *, char *);
int manconf_output(struct manoutput *, const char *, int);
void manconf_free(struct manconf *);
+void manpath_base(struct manpaths *);
diff --git a/mandoc.1 b/mandoc.1
index 5d59ba4f..ff2046e1 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.1,v 1.209 2017/06/29 15:22:17 schwarze Exp $
+.\" $Id: mandoc.1,v 1.210 2017/07/01 09:47:30 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 29 2017 $
+.Dd $Mdocdate: July 1 2017 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -836,6 +836,14 @@ generated by CVS
or
.Ic NetBSD
keyword substitution as conventionally used in these operating systems.
+.It Sy "referenced manual not found"
+.Pq mdoc
+An
+.Ic \&Xr
+macro references a manual page that is not found in the base system.
+The path to look for base system manuals is configurable at compile
+time and defaults to
+.Pa /usr/share/man : /usr/X11R6/man .
.El
.Ss Style suggestions
.Bl -ohang
diff --git a/mandoc.h b/mandoc.h
index 94a5f2fb..cb263002 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.237 2017/06/29 15:22:17 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.238 2017/07/01 09:47:30 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -51,6 +51,7 @@ enum mandocerr {
MANDOCERR_ARCH_BAD, /* unknown architecture: Dt ... arch */
MANDOCERR_OS_ARG, /* operating system explicitly specified: Os ... */
MANDOCERR_RCS_MISSING, /* RCS id missing */
+ MANDOCERR_XR_BAD, /* referenced manual not found: Xr name sec */
MANDOCERR_STYLE, /* ===== start of style suggestions ===== */
diff --git a/mandoc_headers.3 b/mandoc_headers.3
index ecc98e2e..e964aece 100644
--- a/mandoc_headers.3
+++ b/mandoc_headers.3
@@ -123,6 +123,15 @@ Uses the type
from
.Pa roff.h
as an opaque type for function prototypes.
+.It Qq Pa mandoc_xr.h
+Provides
+.Vt struct mandoc_xr
+and the functions
+.Fn mandoc_xr_reset ,
+.Fn mandoc_xr_add ,
+.Fn mandoc_xr_get ,
+and
+.Fn mandoc_xr_free .
.It Qq Pa roff.h
Requires
.Qq Pa mandoc_ohash.h
@@ -540,8 +549,9 @@ Provides
and the functions
.Fn manconf_parse ,
.Fn manconf_output ,
+.Fn manconf_free ,
and
-.Fn manconf_free .
+.Fn manpath_base .
.It Qq Pa mansearch.h
Requires
.In sys/types.h
diff --git a/mandoc_xr.c b/mandoc_xr.c
new file mode 100644
index 00000000..22853616
--- /dev/null
+++ b/mandoc_xr.c
@@ -0,0 +1,112 @@
+/* $Id: mandoc_xr.c,v 1.1 2017/07/01 09:47:30 schwarze Exp $ */
+/*
+ * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/types.h>
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mandoc_aux.h"
+#include "mandoc_ohash.h"
+#include "mandoc_xr.h"
+
+static struct ohash *xr_hash = NULL;
+static struct mandoc_xr *xr_first = NULL;
+static struct mandoc_xr *xr_last = NULL;
+
+static void mandoc_xr_clear(void);
+
+
+static void
+mandoc_xr_clear(void)
+{
+ struct mandoc_xr *xr;
+ unsigned int slot;
+
+ if (xr_hash == NULL)
+ return;
+ for (xr = ohash_first(xr_hash, &slot); xr != NULL;
+ xr = ohash_next(xr_hash, &slot))
+ free(xr);
+ ohash_delete(xr_hash);
+}
+
+void
+mandoc_xr_reset(void)
+{
+ if (xr_hash == NULL)
+ xr_hash = mandoc_malloc(sizeof(*xr_hash));
+ else
+ mandoc_xr_clear();
+ mandoc_ohash_init(xr_hash, 5,
+ offsetof(struct mandoc_xr, hashkey));
+ xr_first = xr_last = NULL;
+}
+
+void
+mandoc_xr_add(const char *sec, const char *name, int line, int pos)
+{
+ struct mandoc_xr *xr;
+ const char *pend;
+ size_t ssz, nsz, tsz;
+ unsigned int slot;
+ uint32_t hv;
+
+ if (xr_hash == NULL)
+ return;
+
+ ssz = strlen(sec) + 1;
+ nsz = strlen(name) + 1;
+ tsz = ssz + nsz;
+ xr = mandoc_malloc(sizeof(*xr) + tsz);
+ xr->next = NULL;
+ xr->sec = xr->hashkey;
+ xr->name = xr->hashkey + ssz;
+ xr->line = line;
+ xr->pos = pos;
+ memcpy(xr->sec, sec, ssz);
+ memcpy(xr->name, name, nsz);
+
+ pend = xr->hashkey + tsz;
+ hv = ohash_interval(xr->hashkey, &pend);
+ slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
+ if (ohash_find(xr_hash, slot) == NULL) {
+ ohash_insert(xr_hash, slot, xr);
+ if (xr_first == NULL)
+ xr_first = xr;
+ else
+ xr_last->next = xr;
+ xr_last = xr;
+ } else
+ free(xr);
+}
+
+struct mandoc_xr *
+mandoc_xr_get(void)
+{
+ return xr_first;
+}
+
+void
+mandoc_xr_free(void)
+{
+ mandoc_xr_clear();
+ free(xr_hash);
+ xr_hash = NULL;
+}
diff --git a/mandoc_xr.h b/mandoc_xr.h
new file mode 100644
index 00000000..3fe2f56d
--- /dev/null
+++ b/mandoc_xr.h
@@ -0,0 +1,30 @@
+/* $Id: mandoc_xr.h,v 1.1 2017/07/01 09:47:30 schwarze Exp $ */
+/*
+ * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct mandoc_xr {
+ struct mandoc_xr *next;
+ char *sec;
+ char *name;
+ int line;
+ int pos;
+ char hashkey[];
+};
+
+void mandoc_xr_reset(void);
+void mandoc_xr_add(const char *, const char *, int, int);
+struct mandoc_xr *mandoc_xr_get(void);
+void mandoc_xr_free(void);
diff --git a/manpath.c b/manpath.c
index 80ac9712..54f7a6b1 100644
--- a/manpath.c
+++ b/manpath.c
@@ -1,4 +1,4 @@
-/* $Id: manpath.c,v 1.34 2017/06/13 15:06:56 schwarze Exp $ */
+/* $Id: manpath.c,v 1.35 2017/07/01 09:47:30 schwarze Exp $ */
/*
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -91,6 +91,13 @@ manconf_parse(struct manconf *conf, const char *file,
manpath_parseline(&conf->manpath, defp, 0);
}
+void
+manpath_base(struct manpaths *dirs)
+{
+ char path_base[] = MANPATH_BASE;
+ manpath_parseline(dirs, path_base, 0);
+}
+
/*
* Parse a FULL pathname from a colon-separated list of arrays.
*/
diff --git a/mansearch.c b/mansearch.c
index 26a7c23f..ddfe2f5d 100644
--- a/mansearch.c
+++ b/mansearch.c
@@ -104,7 +104,8 @@ mansearch(const struct mansearch *search,
}
cur = maxres = 0;
- *res = NULL;
+ if (res != NULL)
+ *res = NULL;
outkey = KEY_Nd;
if (search->outkey != NULL)
@@ -173,6 +174,10 @@ mansearch(const struct mansearch *search,
lstmatch(search->arch, page->arch) == 0)
continue;
+ if (res == NULL) {
+ cur = 1;
+ break;
+ }
if (cur + 1 > maxres) {
maxres += 1024;
*res = mandoc_reallocarray(*res,
@@ -204,12 +209,13 @@ mansearch(const struct mansearch *search,
if (cur && search->firstmatch)
break;
}
- qsort(*res, cur, sizeof(struct manpage), manpage_compare);
+ if (res != NULL)
+ qsort(*res, cur, sizeof(struct manpage), manpage_compare);
if (chdir_status && getcwd_status && chdir(buf) == -1)
warn("%s", buf);
exprfree(e);
*sz = cur;
- return 1;
+ return res != NULL || cur;
}
/*
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 73493155..6561976c 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.345 2017/06/29 15:22:17 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.346 2017/07/01 09:47:30 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -33,6 +33,7 @@
#include "mandoc_aux.h"
#include "mandoc.h"
+#include "mandoc_xr.h"
#include "roff.h"
#include "mdoc.h"
#include "libmandoc.h"
@@ -2336,8 +2337,11 @@ post_xr(POST_ARGS)
if (nch->next == NULL) {
mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse,
n->line, n->pos, "Xr %s", nch->string);
- } else
+ } else {
assert(nch->next == n->last);
+ mandoc_xr_add(nch->next->string, nch->string,
+ nch->line, nch->pos);
+ }
post_delim(mdoc);
}
diff --git a/read.c b/read.c
index ab390334..4e741edb 100644
--- a/read.c
+++ b/read.c
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.183 2017/06/29 15:22:17 schwarze Exp $ */
+/* $Id: read.c,v 1.184 2017/07/01 09:47:30 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -93,6 +93,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"unknown architecture",
"operating system explicitly specified",
"RCS id missing",
+ "referenced manual not found",
"generic style suggestion",