aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2016-01-15 23:08:59 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2016-01-15 23:08:59 +0000
commitca0834218adf25b9cf44601400c1c4a8600d9f5f (patch)
treed03ac3be5c40f1897b2b6802fb3b1a2b0c4e7cfe
parent0ae9da150d599305f27b737214acfa3dc181d0e8 (diff)
downloadsrc-ca0834218adf25b9cf44601400c1c4a8600d9f5f.tar.gz
src-ca0834218adf25b9cf44601400c1c4a8600d9f5f.zip
Import mdocml CVS snapshot 20160116vendor/mandoc/20160116
Notes
Notes: svn path=/vendor/mdocml/dist/; revision=294109 svn path=/vendor/mdocml/20160116/; revision=294110; tag=vendor/mandoc/20160116
-rw-r--r--INSTALL16
-rw-r--r--LICENSE17
-rw-r--r--Makefile91
-rw-r--r--Makefile.depend90
-rw-r--r--NEWS4
-rw-r--r--TODO110
-rw-r--r--apropos.119
-rw-r--r--att.c5
-rw-r--r--cgi.c204
-rw-r--r--cgi.h.example2
-rw-r--r--chars.c495
-rw-r--r--chars.in404
-rw-r--r--compat_err.c112
-rw-r--r--compat_fgetln.c94
-rw-r--r--compat_fts.c181
-rw-r--r--compat_fts.h9
-rw-r--r--compat_getline.c68
-rw-r--r--compat_isblank.c33
-rw-r--r--compat_mkdtemp.c61
-rw-r--r--compat_ohash.h3
-rw-r--r--compat_progname.c42
-rw-r--r--compat_sqlite3_errstr.c2
-rw-r--r--compat_stringlist.c119
-rw-r--r--compat_stringlist.h45
-rw-r--r--compat_vasprintf.c56
-rw-r--r--config.h53
-rw-r--r--config.log210
-rwxr-xr-xconfigure110
-rw-r--r--configure.local.example26
-rw-r--r--demandoc.c47
-rw-r--r--eqn.710
-rw-r--r--eqn.c45
-rw-r--r--example.style.css114
-rw-r--r--gmdiff3
-rw-r--r--html.c77
-rw-r--r--html.h6
-rw-r--r--lib.c5
-rw-r--r--libman.h63
-rw-r--r--libmandoc.h44
-rw-r--r--libmdoc.h89
-rw-r--r--libroff.h5
-rw-r--r--main.c568
-rw-r--r--main.h45
-rw-r--r--man-cgi.css13
-rw-r--r--man.132
-rw-r--r--man.c499
-rw-r--r--man.cgi.830
-rw-r--r--man.conf.5131
-rw-r--r--man.h144
-rw-r--r--man_hash.c29
-rw-r--r--man_html.c164
-rw-r--r--man_macro.c298
-rw-r--r--man_term.c291
-rw-r--r--man_validate.c163
-rw-r--r--manconf.h48
-rw-r--r--mandoc.1177
-rw-r--r--mandoc.380
-rw-r--r--mandoc.c133
-rw-r--r--mandoc.css (renamed from style.css)15
-rw-r--r--mandoc.h35
-rw-r--r--mandoc_aux.c56
-rw-r--r--mandoc_aux.h6
-rw-r--r--mandoc_char.7114
-rw-r--r--mandoc_headers.3121
-rw-r--r--mandoc_ohash.c63
-rw-r--r--mandoc_ohash.h23
-rw-r--r--mandocdb.c568
-rw-r--r--manpage.c41
-rw-r--r--manpath.c215
-rw-r--r--mansearch.38
-rw-r--r--mansearch.c198
-rw-r--r--mansearch.h5
-rw-r--r--mchars_alloc.331
-rw-r--r--mdoc.727
-rw-r--r--mdoc.c594
-rw-r--r--mdoc.h371
-rw-r--r--mdoc_argv.c214
-rw-r--r--mdoc_hash.c25
-rw-r--r--mdoc_html.c466
-rw-r--r--mdoc_macro.c491
-rw-r--r--mdoc_man.c310
-rw-r--r--mdoc_state.c292
-rw-r--r--mdoc_term.c540
-rw-r--r--mdoc_validate.c1139
-rw-r--r--msec.c4
-rw-r--r--out.c13
-rw-r--r--out.h5
-rw-r--r--preconv.c20
-rw-r--r--read.c300
-rw-r--r--roff.734
-rw-r--r--roff.c785
-rw-r--r--roff.h164
-rw-r--r--roff_int.h41
-rw-r--r--soelim.186
-rw-r--r--soelim.c182
-rw-r--r--st.c5
-rw-r--r--tag.c192
-rw-r--r--tag.h (renamed from manpath.h)29
-rw-r--r--tbl.c18
-rw-r--r--tbl_data.c13
-rw-r--r--tbl_html.c8
-rw-r--r--tbl_layout.c9
-rw-r--r--tbl_opts.c3
-rw-r--r--tbl_term.c12
-rw-r--r--term.c126
-rw-r--r--term.h50
-rw-r--r--term_ascii.c147
-rw-r--r--term_ps.c72
-rw-r--r--test-dirent-namlen.c2
-rw-r--r--test-err.c28
-rw-r--r--test-fts.c10
-rw-r--r--test-getline.c (renamed from test-fgetln.c)6
-rw-r--r--test-getsubopt.c6
-rw-r--r--test-isblank.c7
-rw-r--r--test-mkdtemp.c12
-rw-r--r--test-mmap.c2
-rw-r--r--test-ohash.c4
-rw-r--r--test-pledge.c7
-rw-r--r--test-progname.c10
-rw-r--r--test-reallocarray.c2
-rw-r--r--test-rewb-bsd.c26
-rw-r--r--test-rewb-sysv.c26
-rw-r--r--test-sqlite3.c10
-rw-r--r--test-sqlite3_errstr.c2
-rw-r--r--test-strcasestr.c2
-rw-r--r--test-stringlist.c37
-rw-r--r--test-strlcat.c4
-rw-r--r--test-strlcpy.c4
-rw-r--r--test-strptime.c4
-rw-r--r--test-strsep.c2
-rw-r--r--test-strtonum.c20
-rw-r--r--test-vasprintf.c49
-rw-r--r--test-wchar.c14
-rw-r--r--tree.c128
134 files changed, 7839 insertions, 6905 deletions
diff --git a/INSTALL b/INSTALL
index eb8b5dd2c2b5..085fb3e1c672 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-$Id: INSTALL,v 1.10 2015/03/09 21:00:14 schwarze Exp $
+$Id: INSTALL,v 1.13 2015/11/07 14:01:16 schwarze Exp $
About mdocml, the portable mandoc distribution
----------------------------------------------
@@ -42,6 +42,8 @@ generates. If anything looks wrong or different from what you
wish, read the file "configure.local.example", create and edit
a file "configure.local", and re-run "./configure" until the
result seems right to you.
+On Solaris 10 and earlier, you may have to run "ksh ./configure"
+because the native /bin/sh lacks some POSIX features.
3. Run "make".
Any POSIX-compatible make, in particular both BSD make and GNU make,
@@ -82,9 +84,10 @@ manual page source.
Understanding mandoc dependencies
---------------------------------
-The mandoc(1), man(1), and demandoc(1) utilities have no external
-dependencies, but makewhatis(8) and apropos(1) depend on the
-following software:
+The mandoc(1), man(1), and demandoc(1) utilities only depend
+on the zlib library for decompressing gzipped manual pages,
+but makewhatis(8) and apropos(1) depend on the following
+additional software:
1. The SQLite database system, see <http://sqlite.org/>.
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
@@ -107,6 +110,11 @@ If you run into that problem, set "HAVE_FTS=0" in configure.local.
If your system does not have it, the bundled compatibility version
will be used, so you probably need not worry about it.
+One of the chief design goals of the mandoc toolbox is to make
+sure that nothing related to documentation requires C++.
+Consequently, linking mandoc against any kind of C++ program
+would defeat the purpose and is not supported.
+
Checking autoconfiguration quality
----------------------------------
diff --git a/LICENSE b/LICENSE
index 080c04fa2607..ad3cd4b8086e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-$Id: LICENSE,v 1.7 2015/02/16 14:56:22 schwarze Exp $
+$Id: LICENSE,v 1.11 2015/11/07 17:58:55 schwarze Exp $
With the exceptions noted below, all code and documentation
contained in the mdocml toolkit is protected by the Copyright
@@ -8,10 +8,12 @@ Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
+Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
Copyright (c) 1998, 2004, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
+Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
See the individual source files for information about who contributed
@@ -35,13 +37,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
The following files included from outside sources are protected by
-other people's Copyright and are distributed under a 3-clause BSD
-license; see these individual files for details.
+other people's Copyright and are distributed under various 2-clause
+and 3-clause BSD licenses; see these individual files for details.
-compat_fts.c, compat_fts.h,
+soelim.c, soelim.1:
+Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
+
+compat_err.c, compat_fts.c, compat_fts.h,
compat_getsubopt.c, compat_strcasestr.c, compat_strsep.c,
man.1:
Copyright (c) 1989,1990,1993,1994 The Regents of the University of California
-compat_fgetln.c:
-Copyright (c) 1998 The NetBSD Foundation, Inc.
+compat_stringlist.c, compat_stringlist.h:
+Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
diff --git a/Makefile b/Makefile
index d492ce70a720..9be2bd9c61f5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.457 2015/03/13 12:35:32 schwarze Exp $
+# $Id: Makefile,v 1.480 2015/11/07 21:53:14 schwarze Exp $
#
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
# Copyright (c) 2011, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -20,36 +20,49 @@ VERSION = 1.13.3
# === LIST OF FILES ====================================================
TESTSRCS = test-dirent-namlen.c \
- test-fgetln.c \
+ test-err.c \
test-fts.c \
+ test-getline.c \
test-getsubopt.c \
+ test-isblank.c \
+ test-mkdtemp.c \
test-mmap.c \
test-ohash.c \
+ test-pledge.c \
+ test-progname.c \
test-reallocarray.c \
test-sqlite3.c \
test-sqlite3_errstr.c \
test-strcasestr.c \
+ test-stringlist.c \
test-strlcat.c \
test-strlcpy.c \
test-strptime.c \
test-strsep.c \
test-strtonum.c \
+ test-vasprintf.c \
test-wchar.c
SRCS = att.c \
cgi.c \
chars.c \
- compat_fgetln.c \
+ compat_err.c \
compat_fts.c \
+ compat_getline.c \
compat_getsubopt.c \
+ compat_isblank.c \
+ compat_mkdtemp.c \
compat_ohash.c \
+ compat_progname.c \
compat_reallocarray.c \
compat_sqlite3_errstr.c \
compat_strcasestr.c \
+ compat_stringlist.c \
compat_strlcat.c \
compat_strlcpy.c \
compat_strsep.c \
compat_strtonum.c \
+ compat_vasprintf.c \
demandoc.c \
eqn.c \
eqn_html.c \
@@ -65,6 +78,7 @@ SRCS = att.c \
man_validate.c \
mandoc.c \
mandoc_aux.c \
+ mandoc_ohash.c \
mandocdb.c \
manpage.c \
manpath.c \
@@ -76,6 +90,7 @@ SRCS = att.c \
mdoc_html.c \
mdoc_macro.c \
mdoc_man.c \
+ mdoc_state.c \
mdoc_term.c \
mdoc_validate.c \
msec.c \
@@ -83,7 +98,9 @@ SRCS = att.c \
preconv.c \
read.c \
roff.c \
+ soelim.c \
st.c \
+ tag.c \
tbl.c \
tbl_data.c \
tbl_html.c \
@@ -93,8 +110,7 @@ SRCS = att.c \
term.c \
term_ascii.c \
term_ps.c \
- tree.c \
- $(TESTSRCS)
+ tree.c
DISTFILES = INSTALL \
LICENSE \
@@ -104,14 +120,13 @@ DISTFILES = INSTALL \
TODO \
apropos.1 \
cgi.h.example \
- chars.in \
compat_fts.h \
compat_ohash.h \
+ compat_stringlist.h \
configure \
configure.local.example \
demandoc.1 \
eqn.7 \
- example.style.css \
gmdiff \
html.h \
lib.in \
@@ -121,13 +136,15 @@ DISTFILES = INSTALL \
libroff.h \
main.h \
makewhatis.8 \
- man-cgi.css \
man.1 \
man.7 \
man.cgi.8 \
+ man.conf.5 \
man.h \
+ manconf.h \
mandoc.1 \
mandoc.3 \
+ mandoc.css \
mandoc.db.5 \
mandoc.h \
mandoc_aux.h \
@@ -136,7 +153,7 @@ DISTFILES = INSTALL \
mandoc_headers.3 \
mandoc_html.3 \
mandoc_malloc.3 \
- manpath.h \
+ mandoc_ohash.h \
mansearch.3 \
mansearch.h \
mchars_alloc.3 \
@@ -146,12 +163,15 @@ DISTFILES = INSTALL \
out.h \
predefs.in \
roff.7 \
+ roff.h \
+ soelim.1 \
st.in \
- style.css \
+ tag.h \
tbl.3 \
tbl.7 \
term.h \
- $(SRCS)
+ $(SRCS) \
+ $(TESTSRCS)
LIBMAN_OBJS = man.o \
man_hash.o \
@@ -164,6 +184,7 @@ LIBMDOC_OBJS = att.o \
mdoc_argv.o \
mdoc_hash.o \
mdoc_macro.o \
+ mdoc_state.o \
mdoc_validate.o \
st.o
@@ -180,21 +201,27 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
chars.o \
mandoc.o \
mandoc_aux.o \
+ mandoc_ohash.o \
msec.o \
preconv.o \
read.o
-COMPAT_OBJS = compat_fgetln.o \
+COMPAT_OBJS = compat_err.o \
compat_fts.o \
+ compat_getline.o \
compat_getsubopt.o \
+ compat_isblank.o \
+ compat_mkdtemp.o \
compat_ohash.o \
+ compat_progname.o \
compat_reallocarray.o \
compat_sqlite3_errstr.o \
compat_strcasestr.o \
compat_strlcat.o \
compat_strlcpy.o \
compat_strsep.o \
- compat_strtonum.o
+ compat_strtonum.o \
+ compat_vasprintf.o
MANDOC_HTML_OBJS = eqn_html.o \
html.o \
@@ -218,6 +245,7 @@ BASE_OBJS = $(MANDOC_HTML_OBJS) \
main.o \
manpath.o \
out.o \
+ tag.o \
tree.o
MAIN_OBJS = $(BASE_OBJS)
@@ -236,10 +264,18 @@ MANPAGE_OBJS = manpage.o mansearch.o mansearch_const.o manpath.o
DEMANDOC_OBJS = demandoc.o
+SOELIM_OBJS = soelim.o \
+ compat_err.o \
+ compat_getline.o \
+ compat_progname.o \
+ compat_reallocarray.o \
+ compat_stringlist.o
+
WWW_MANS = apropos.1.html \
demandoc.1.html \
man.1.html \
mandoc.1.html \
+ soelim.1.html \
mandoc.3.html \
mandoc_escape.3.html \
mandoc_headers.3.html \
@@ -248,6 +284,7 @@ WWW_MANS = apropos.1.html \
mansearch.3.html \
mchars_alloc.3.html \
tbl.3.html \
+ man.conf.5.html \
mandoc.db.5.html \
eqn.7.html \
man.7.html \
@@ -258,11 +295,12 @@ WWW_MANS = apropos.1.html \
makewhatis.8.html \
man.cgi.8.html \
man.h.html \
+ manconf.h.html \
mandoc.h.html \
mandoc_aux.h.html \
- manpath.h.html \
mansearch.h.html \
- mdoc.h.html
+ mdoc.h.html \
+ roff.h.html
WWW_OBJS = mdocml.tar.gz \
mdocml.sha256
@@ -275,7 +313,7 @@ include Makefile.local
all: base-build $(BUILD_TARGETS) Makefile.local
-base-build: mandoc demandoc
+base-build: mandoc demandoc soelim
cgi-build: man.cgi
@@ -301,33 +339,36 @@ clean:
rm -f man.cgi $(CGI_OBJS)
rm -f manpage $(MANPAGE_OBJS)
rm -f demandoc $(DEMANDOC_OBJS)
+ rm -f soelim $(SOELIM_OBJS)
rm -f $(WWW_MANS) $(WWW_OBJS)
rm -rf *.dSYM
base-install: base-build
mkdir -p $(DESTDIR)$(BINDIR)
- mkdir -p $(DESTDIR)$(EXAMPLEDIR)
mkdir -p $(DESTDIR)$(LIBDIR)
mkdir -p $(DESTDIR)$(INCLUDEDIR)
mkdir -p $(DESTDIR)$(MANDIR)/man1
mkdir -p $(DESTDIR)$(MANDIR)/man3
+ mkdir -p $(DESTDIR)$(MANDIR)/man5
mkdir -p $(DESTDIR)$(MANDIR)/man7
$(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR)
+ $(INSTALL_PROGRAM) soelim $(DESTDIR)$(BINDIR)/$(BINM_SOELIM)
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN)
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
- $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \
+ $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h roff.h \
$(DESTDIR)$(INCLUDEDIR)
$(INSTALL_MAN) mandoc.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1
+ $(INSTALL_MAN) soelim.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_SOELIM).1
$(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
+ $(INSTALL_MAN) man.conf.5 $(DESTDIR)$(MANDIR)/man5/${MANM_MANCONF}.5
$(INSTALL_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MAN}.7
$(INSTALL_MAN) mdoc.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MDOC}.7
$(INSTALL_MAN) roff.7 $(DESTDIR)$(MANDIR)/man7/${MANM_ROFF}.7
$(INSTALL_MAN) eqn.7 $(DESTDIR)$(MANDIR)/man7/${MANM_EQN}.7
$(INSTALL_MAN) tbl.7 $(DESTDIR)$(MANDIR)/man7/${MANM_TBL}.7
$(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
- $(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR)
db-install: base-build
mkdir -p $(DESTDIR)$(BINDIR)
@@ -354,8 +395,7 @@ cgi-install: cgi-build
mkdir -p $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1
mkdir -p $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8
$(INSTALL_PROGRAM) man.cgi $(DESTDIR)$(CGIBINDIR)
- $(INSTALL_DATA) example.style.css $(DESTDIR)$(HTDOCDIR)/man.css
- $(INSTALL_DATA) man-cgi.css $(DESTDIR)$(HTDOCDIR)
+ $(INSTALL_DATA) mandoc.css $(DESTDIR)$(HTDOCDIR)
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1/
$(INSTALL_MAN) man.cgi.8 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8/
@@ -376,13 +416,16 @@ man.cgi: $(CGI_OBJS) libmandoc.a
$(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB)
demandoc: $(DEMANDOC_OBJS) libmandoc.a
- $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a
+ $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a $(DBLIB)
+
+soelim: $(SOELIM_OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(SOELIM_OBJS)
# --- maintainer targets ---
www-install: www
mkdir -p $(HTDOCDIR)/snapshots
- $(INSTALL_DATA) $(WWW_MANS) style.css $(HTDOCDIR)
+ $(INSTALL_DATA) $(WWW_MANS) mandoc.css $(HTDOCDIR)
$(INSTALL_DATA) $(WWW_OBJS) $(HTDOCDIR)/snapshots
$(INSTALL_DATA) mdocml.tar.gz \
$(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz
@@ -416,4 +459,4 @@ mdocml.tar.gz: $(DISTFILES)
.1.1.html .3.3.html .5.5.html .7.7.html .8.8.html: mandoc
./mandoc -Thtml -Wall,stop \
- -Ostyle=style.css,man=%N.%S.html,includes=%I.html $< > $@
+ -Ostyle=mandoc.css,man=%N.%S.html,includes=%I.html $< > $@
diff --git a/Makefile.depend b/Makefile.depend
index 54af8bce33ec..98a1928b7a98 100644
--- a/Makefile.depend
+++ b/Makefile.depend
@@ -1,51 +1,61 @@
-att.o: att.c config.h mdoc.h libmdoc.h
-cgi.o: cgi.c config.h mandoc.h mandoc_aux.h main.h manpath.h mansearch.h cgi.h
-chars.o: chars.c config.h mandoc.h mandoc_aux.h libmandoc.h chars.in
-compat_fgetln.o: compat_fgetln.c config.h
+att.o: att.c config.h roff.h mdoc.h libmdoc.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
+compat_err.o: compat_err.c config.h
compat_fts.o: compat_fts.c config.h compat_fts.h
+compat_getline.o: compat_getline.c config.h
compat_getsubopt.o: compat_getsubopt.c config.h
+compat_isblank.o: compat_isblank.c config.h
+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_sqlite3_errstr.o: compat_sqlite3_errstr.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
compat_strlcpy.o: compat_strlcpy.c config.h
compat_strsep.o: compat_strsep.c config.h
compat_strtonum.o: compat_strtonum.c config.h
-demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h
+compat_vasprintf.o: compat_vasprintf.c config.h
+demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.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.h mandoc_aux.h out.h html.h main.h
-lib.o: lib.c config.h mdoc.h libmdoc.h lib.in
-main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h manpath.h mansearch.h
-man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
-man_hash.o: man_hash.c config.h man.h libman.h
-man_html.o: man_html.c config.h mandoc_aux.h man.h out.h html.h main.h
-man_macro.o: man_macro.c config.h man.h mandoc.h libmandoc.h libman.h
-man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h
-man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
+html.o: html.c config.h mandoc.h mandoc_aux.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
+man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
+man_hash.o: man_hash.c config.h roff.h man.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_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_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
-mandocdb.o: mandocdb.c config.h compat_fts.h compat_ohash.h mdoc.h man.h mandoc.h mandoc_aux.h manpath.h mansearch.h
-manpage.o: manpage.c config.h manpath.h mansearch.h
-manpath.o: manpath.c config.h mandoc_aux.h manpath.h
-mansearch.o: mansearch.c config.h compat_ohash.h mandoc.h mandoc_aux.h manpath.h mansearch.h
+mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.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
+manpage.o: manpage.c config.h manconf.h mansearch.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
mansearch_const.o: mansearch_const.c config.h mansearch.h
-mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
-mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
-mdoc_hash.o: mdoc_hash.c config.h mdoc.h libmdoc.h
-mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mdoc.h out.h html.h main.h
-mdoc_macro.o: mdoc_macro.c config.h mdoc.h mandoc.h libmdoc.h libmandoc.h
-mdoc_man.o: mdoc_man.c config.h mandoc.h mandoc_aux.h out.h man.h mdoc.h main.h
-mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main.h
-mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.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 libmdoc.h
+mdoc_hash.o: mdoc_hash.c config.h roff.h mdoc.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_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_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
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.h mandoc_aux.h libmandoc.h mdoc.h man.h
-roff.o: roff.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h predefs.in
-st.o: st.c config.h mdoc.h libmdoc.h st.in
+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 roff.h libmandoc.h roff_int.h libroff.h predefs.in
+soelim.o: soelim.c config.h compat_stringlist.h
+st.o: st.c config.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
tbl_html.o: tbl_html.c config.h mandoc.h out.h html.h
@@ -53,22 +63,6 @@ tbl_layout.o: tbl_layout.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
tbl_opts.o: tbl_opts.c config.h mandoc.h libmandoc.h libroff.h
tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h
term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
-term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
-term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h main.h
-tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h
-test-dirent-namlen.o: test-dirent-namlen.c
-test-fgetln.o: test-fgetln.c
-test-fts.o: test-fts.c
-test-getsubopt.o: test-getsubopt.c
-test-mmap.o: test-mmap.c
-test-ohash.o: test-ohash.c
-test-reallocarray.o: test-reallocarray.c
-test-sqlite3.o: test-sqlite3.c
-test-sqlite3_errstr.o: test-sqlite3_errstr.c
-test-strcasestr.o: test-strcasestr.c
-test-strlcat.o: test-strlcat.c
-test-strlcpy.o: test-strlcpy.c
-test-strptime.o: test-strptime.c
-test-strsep.o: test-strsep.c
-test-strtonum.o: test-strtonum.c
-test-wchar.o: test-wchar.c
+term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h manconf.h main.h
+term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h manconf.h main.h
+tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h main.h
diff --git a/NEWS b/NEWS
index ecbd0053946e..985f265d3cdd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-$Id: NEWS,v 1.9 2015/03/13 12:35:32 schwarze Exp $
+$Id: NEWS,v 1.10 2015/11/05 16:58:20 schwarze Exp $
This file lists the most important changes in the mdocml.bsd.lv distribution.
@@ -93,7 +93,7 @@ Changes in version 1.13.3, released on March 13, 2015
* roff(7): Three minor fixes with respect to evaluation of conditionals.
* roff(7): Let .it accept numerical expressions, not just constants.
* mandoc_char(7): Correct some character names and renderings.
- * If earlier files set a non-zero exit status, never reset it to zero.
+ * If earlier files set a non-zero exit status, never reset it to zero.
--- THANKS TO ---
* Jonathan Gray (OpenBSD) for yet more testing with afl (the American
Fuzzy Lop security fuzzer), again resulting in many bug reports.
diff --git a/TODO b/TODO
index 701cd1ddf212..d24c939afa4a 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
-* $Id: TODO,v 1.202 2015/03/11 13:11:22 schwarze Exp $
+* $Id: TODO,v 1.216 2016/01/08 01:37:32 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -66,6 +66,7 @@ are mere guesses, and some may be wrong.
loc * exist * algo * size * imp **
- .ns (no-space mode) occurs in xine-config(1)
+ when implementing this, also let .TH set it
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
loc *** exist *** algo *** size ** imp *
@@ -105,6 +106,19 @@ are mere guesses, and some may be wrong.
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
loc ** exist *** algo *** size * imp ***
+- \\ in high-level macro arguments
+ Currently, \\ is expanded in two situations:
+ 1) macro and string definition (roff.c setstrn())
+ 2) macro argument parsing (mandoc.c mandoc_getarg())
+ For user defined macros, the second happens in time because of ROFF_REPARSE.
+ But for standard high-level macros, it only happens after entering the
+ high level parsers, which is too late because the code doesn't get
+ back to roff.c roff_res() from that point. Because this requires
+ distinguishing requests, user-defined macros and standard macros
+ on the roff_res() level, it is hard to solve without the parser reorg.
+ Found by naddy@ in devel/cutils cobfusc(1) Mon, 16 Feb 2015 19:10:52 +0100
+ loc *** exist *** algo *** size ** imp *
+
- using undefined strings or macros defines them to be empty
wl@ Mon, 14 Nov 2011 14:37:01 +0000
loc * exist * algo * size * imp *
@@ -194,6 +208,26 @@ are mere guesses, and some may be wrong.
--- missing tbl features -----------------------------------------------
+- horizontal lines in the layout still consume data cells
+ and can be mixed with actual data on the same table line
+ synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
+ loc ** exist ** algo ** size ** imp ***
+
+- the "w" layout option is ignored
+ synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
+ loc * exist * algo * size * imp **
+
+- the "s" layout column specifier is used for placement of data
+ into columns, but ignored during column width calculations
+ synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
+ loc * exist ** algo *** size * imp **
+
+- support mdoc(7) and man(7) macros inside tbl(7) code;
+ probably requires the parser reorg and letting tbl(7)
+ use roff_node such that macro sets can mix;
+ informed by bapt@ that FreeBSD needs this.
+ loc *** exist ** algo *** size ** imp ***
+
- look at the POSIX manuals in the books/man-pages-posix port,
they use some unsupported tbl(7) features.
loc * exist ** algo ** size ** imp ***
@@ -203,13 +237,13 @@ are mere guesses, and some may be wrong.
suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600
loc * exist ** algo * size * imp **
-- allow standalone `.' to be interpreted as an end-of-layout
- delimiter instead of being thrown away as a no-op roff line
- reported by Yuri Pankov, Wed 18 May 2011 11:34:59 CEST
- loc ** exist ** algo ** size * imp **
-
--- missing eqn features -----------------------------------------------
+- In a matrix, break the output line after each matrix line.
+ Found in the discussion at CDBUG 2015.
+ Suggested by Avi Weinstock.
+ loc * exist * algo * size * imp **
+
- The "size" keyword is parsed, but ignored by the formatter.
loc * exist * algo * size * imp *
@@ -227,13 +261,9 @@ are mere guesses, and some may be wrong.
Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46
loc ** exist ** algo * size * imp *
-- When makewhatis(8) encounters a FATAL parse error,
- it silently treats the file as formatted, which makes no sense
- at all for paths like man1/foo.1 - and which also contradicts
- what the manual says at the end of the description.
- The end result will be ENOENT for file names returned
- by mansearch() in manpage.file.
- loc * exist * algo * size * imp **
+- change the default PAGER to more -Es and use the pager
+ even for apropos title line output; req by bapt@
+ loc * exist * algo * size * imp ***
- makewhatis(8) for preformatted pages:
parse the section number from the header line
@@ -255,11 +285,13 @@ are mere guesses, and some may be wrong.
- kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET)
loc ** exist ** algo ** size *** imp *
---- compatibility checks -----------------------------------------------
+- Vsevolod Stakhov (FreeBSD) needs either a markdown output formatter
+ for mandoc -mdoc or a markdown to mdoc converter because they
+ have to maintain manuals needed both in markdown and mdoc format.
+ Look at the libsoldout (markdown -> whatever)
+ loc * exist * algo * size ** imp **
-- write a configure check for [[:<:]] support and provide some
- fallback for whatis(1) when it doesn't work;
- Svyatoslav Mishyn Wed, 17 Dec 2014 11:07:10 +0200
+--- compatibility checks -----------------------------------------------
- is .Bk implemented correctly in modern groff?
sobrado@ Tue, 19 Apr 2011 22:12:55 +0200
@@ -293,6 +325,9 @@ are mere guesses, and some may be wrong.
http://swtch.com/plan9port/man/man7/man.html
"Anthony J. Bentley" <anthonyjbentley@gmail.com> 28 Dec 2010 21:58:40 -0700
+- check compatibility with COHERENT troff:
+ http://www.nesssoftware.com/home/mwc/source.php
+
- check compatibility with the man(7) formatter
https://raw.githubusercontent.com/rofl0r/hardcore-utils/master/man.c
@@ -381,6 +416,12 @@ are mere guesses, and some may be wrong.
see also matthew@ Fri, 18 Jul 2014 19:25:12 -0700
loc * exist * algo ** size * imp ***
+- .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal
+ space, see for example random(3). Introduced in
+ http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92
+ reported by deraadt@ Mon, 28 Sep 2015 20:14:13 -0600 (MDT)
+ loc ** exist ** algo ** size * imp *
+
- jsg on icb, Nov 3, 2014:
try to guess Xr in man(7) for hyperlinking
@@ -394,6 +435,10 @@ are mere guesses, and some may be wrong.
- consider whether <var> can be used for Ar Dv Er Ev Fa Va.
from bentley@ Wed, 13 Aug 2014 09:17:55 -0600
+- generate <img> tags in HTML
+ idea from florian@ Tue, 7 Apr 2015 00:26:28 +0000
+ may be possible to implement with .Lk img://something.png alt_text
+
- check https://github.com/trentm/mdocml
************************************************************************
@@ -466,6 +511,10 @@ are mere guesses, and some may be wrong.
found while talking to Chris Bennett
loc * exist * algo * size * imp *
+- Sequences of multiple man(7) paragraphs (.PP, .IP) interspersed
+ with .ps and .nf/.fi produce execessive blank lines, see libJudy
+ and graphics/dcmtk. The parser reorg may help with this.
+
- trailing whitespace must be ignored even when followed by a font escape,
see for example
makes
@@ -475,9 +524,31 @@ are mere guesses, and some may be wrong.
loc ** exist ** algo ** size * imp **
************************************************************************
+* portability
+************************************************************************
+
+- systems having UTF-8 but not en_US.UTF-8
+ call locale(1) from ./configure, select a UTF-8-locale,
+ and use that for test-wchar.c and term_ascii.c
+ to Markus Waldeck Sat, 18 Jul 2015 01:55:37 +0200
+ loc * exist * algo * size * imp *
+
+************************************************************************
* warning issues
************************************************************************
+- provide a way in mandoc(1) to warn about broken .Xr links;
+ probably cannot be on by default in -Tlint because it needs
+ to access the manpath and mandoc.db(3) after parsing.
+ asked for by jmc@ Fri, 4 Dec 2015 22:39:40 +0000
+
+- Report errors in -O suboption parsing.
+ loc * exist * algo * size * imp **
+
+- warn when .Sh or .Ss contain other macros
+ Steffen Nurpmeso, savannah.gnu.org/bugs/index.php?45034
+ loc * exist * algo * size * imp **
+
- check that MANDOCERR_BADTAB is thrown in the right cases,
i.e. when finding a literal tab character in fill mode,
and possibly change the wording of the warning message
@@ -557,11 +628,6 @@ Several areas can be cleaned up to make mandoc even faster. These are
* structural issues
************************************************************************
-- Improve -O suboption parsing. Do it in the main program such that
- errors can be reported. Pay attention to distinguishing the
- mandoc(1) and apropos(1) styles of both options.
- loc ** exist * algo ** size ** imp ***
-
- Use libz directly instead of forking gunzip(1).
Suggested by bapt at FreeBSD among others.
diff --git a/apropos.1 b/apropos.1
index 532e4dd7ff74..10ba3c6a454d 100644
--- a/apropos.1
+++ b/apropos.1
@@ -1,4 +1,4 @@
-.\" $Id: apropos.1,v 1.37 2015/02/16 16:23:54 schwarze Exp $
+.\" $Id: apropos.1,v 1.39 2015/04/03 08:46:17 schwarze Exp $
.\"
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2011, 2012, 2014 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: February 16 2015 $
+.Dd $Mdocdate: April 3 2015 $
.Dt APROPOS 1
.Os
.Sh NAME
@@ -210,7 +210,7 @@ This has syntax
.Sm off
.Oo
.Op Ar key Op , Ar key ...
-.Pq Cm = | ~
+.Pq Cm = | \(ti
.Oc
.Ar val ,
.Sm on
@@ -227,7 +227,7 @@ for a list of available keys.
Operator
.Cm =
evaluates a substring, while
-.Cm ~
+.Cm \(ti
evaluates a regular expression.
.It Fl i Ar term
If
@@ -365,7 +365,8 @@ Specifies the pagination program to use when
.Ev MANPAGER
is not defined.
If neither PAGER nor MANPAGER is defined,
-.Pa /usr/bin/more Fl s
+.Xr more 1
+.Fl s
will be used.
.El
.Sh FILES
@@ -398,7 +399,7 @@ as well:
.Pp
Search in names and descriptions using a regular expression:
.Pp
-.Dl $ apropos '~set.?[ug]id'
+.Dl $ apropos \(aq\(tiset.?[ug]id\(aq
.Pp
Search for manuals in the library section mentioning both the
.Qq optind
@@ -413,15 +414,15 @@ Do exactly the same as calling
with the argument
.Qq ssh :
.Pp
-.Dl $ apropos \-\- \-i 'Nm~[[:<:]]ssh[[:>:]]'
+.Dl $ apropos \-\- \-i \(aqNm\(ti[[:<:]]ssh[[:>:]]\(aq
.Pp
The following two invocations are equivalent:
.Pp
.D1 Li $ apropos -S Ar arch Li -s Ar section expression
.Bd -ragged -offset indent
.Li $ apropos \e( Ar expression Li \e)
-.Li -a arch~^( Ns Ar arch Ns Li |any)$
-.Li -a sec~^ Ns Ar section Ns Li $
+.Li -a arch\(ti^( Ns Ar arch Ns Li |any)$
+.Li -a sec\(ti^ Ns Ar section Ns Li $
.Ed
.Sh SEE ALSO
.Xr man 1 ,
diff --git a/att.c b/att.c
index a1703ebcc662..872f982395d3 100644
--- a/att.c
+++ b/att.c
@@ -1,4 +1,4 @@
-/* $Id: att.c,v 1.13 2014/11/28 18:57:31 schwarze Exp $ */
+/* $Id: att.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <string.h>
+#include "roff.h"
#include "mdoc.h"
#include "libmdoc.h"
@@ -45,5 +46,5 @@ mdoc_a2att(const char *p)
LINE("V.3", "AT&T System\\~V Release\\~3 UNIX");
LINE("V.4", "AT&T System\\~V Release\\~4 UNIX");
- return(NULL);
+ return NULL;
}
diff --git a/cgi.c b/cgi.c
index 05d1b8a0df01..0b01d06602e4 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,15 +1,15 @@
-/* $Id: cgi.c,v 1.104 2015/02/10 08:05:30 schwarze Exp $ */
+/* $Id: cgi.c,v 1.116 2016/01/04 12:36:26 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de>
+ * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@usta.de>
*
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -30,10 +30,13 @@
#include <string.h>
#include <unistd.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
+#include "mandoc.h"
+#include "roff.h"
+#include "mdoc.h"
+#include "man.h"
#include "main.h"
-#include "manpath.h"
+#include "manconf.h"
#include "mansearch.h"
#include "cgi.h"
@@ -60,9 +63,6 @@ static void html_print(const char *);
static void html_putchar(char);
static int http_decode(char *);
static void http_parse(struct req *, const char *);
-static void http_print(const char *);
-static void http_putchar(char);
-static void http_printquery(const struct req *, const char *);
static void pathgen(struct req *);
static void pg_error_badrequest(const char *);
static void pg_error_internal(void);
@@ -74,6 +74,7 @@ static void pg_searchres(const struct req *,
static void pg_show(struct req *, const char *);
static void resp_begin_html(int, const char *);
static void resp_begin_http(int, const char *);
+static void resp_copy(const char *);
static void resp_end_html(void);
static void resp_searchform(const struct req *);
static void resp_show(const struct req *, const char *);
@@ -145,40 +146,6 @@ html_putchar(char c)
}
}
-static void
-http_printquery(const struct req *req, const char *sep)
-{
-
- if (NULL != req->q.query) {
- printf("query=");
- http_print(req->q.query);
- }
- if (0 == req->q.equal)
- printf("%sapropos=1", sep);
- if (NULL != req->q.sec) {
- printf("%ssec=", sep);
- http_print(req->q.sec);
- }
- if (NULL != req->q.arch) {
- printf("%sarch=", sep);
- http_print(req->q.arch);
- }
- if (strcmp(req->q.manpath, req->p[0])) {
- printf("%smanpath=", sep);
- http_print(req->q.manpath);
- }
-}
-
-static void
-http_print(const char *p)
-{
-
- if (NULL == p)
- return;
- while ('\0' != *p)
- http_putchar(*p++);
-}
-
/*
* Call through to html_putchar().
* Accepts NULL strings.
@@ -299,20 +266,6 @@ next:
}
}
-static void
-http_putchar(char c)
-{
-
- if (isalnum((unsigned char)c)) {
- putchar((unsigned char)c);
- return;
- } else if (' ' == c) {
- putchar('+');
- return;
- }
- printf("%%%.2x", c);
-}
-
/*
* HTTP-decode a string. The standard explanation is that this turns
* "%4e+foo" into "n foo" in the regular way. This is done in-place
@@ -331,13 +284,13 @@ http_decode(char *p)
for ( ; '\0' != *p; p++, q++) {
if ('%' == *p) {
if ('\0' == (hex[0] = *(p + 1)))
- return(0);
+ return 0;
if ('\0' == (hex[1] = *(p + 2)))
- return(0);
+ return 0;
if (1 != sscanf(hex, "%x", &c))
- return(0);
+ return 0;
if ('\0' == c)
- return(0);
+ return 0;
*q = (char)c;
p += 2;
@@ -346,7 +299,7 @@ http_decode(char *p)
}
*q = '\0';
- return(1);
+ return 1;
}
static void
@@ -365,6 +318,20 @@ resp_begin_http(int code, const char *msg)
}
static void
+resp_copy(const char *filename)
+{
+ char buf[4096];
+ ssize_t sz;
+ int fd;
+
+ if ((fd = open(filename, O_RDONLY)) != -1) {
+ fflush(stdout);
+ while ((sz = read(fd, buf, sizeof(buf))) > 0)
+ write(STDOUT_FILENO, buf, sz);
+ }
+}
+
+static void
resp_begin_html(int code, const char *msg)
{
@@ -374,21 +341,23 @@ resp_begin_html(int code, const char *msg)
"<HTML>\n"
"<HEAD>\n"
"<META CHARSET=\"UTF-8\" />\n"
- "<LINK REL=\"stylesheet\" HREF=\"%s/man-cgi.css\""
- " TYPE=\"text/css\" media=\"all\">\n"
- "<LINK REL=\"stylesheet\" HREF=\"%s/man.css\""
+ "<LINK REL=\"stylesheet\" HREF=\"%s/mandoc.css\""
" TYPE=\"text/css\" media=\"all\">\n"
"<TITLE>%s</TITLE>\n"
"</HEAD>\n"
"<BODY>\n"
"<!-- Begin page content. //-->\n",
- CSS_DIR, CSS_DIR, CUSTOMIZE_TITLE);
+ CSS_DIR, CUSTOMIZE_TITLE);
+
+ resp_copy(MAN_DIR "/header.html");
}
static void
resp_end_html(void)
{
+ resp_copy(MAN_DIR "/footer.html");
+
puts("</BODY>\n"
"</HTML>");
}
@@ -398,7 +367,6 @@ resp_searchform(const struct req *req)
{
int i;
- puts(CUSTOMIZE_BEGIN);
puts("<!-- Begin search form. //-->");
printf("<DIV ID=\"mancgi\">\n"
"<FORM ACTION=\"%s\" METHOD=\"get\">\n"
@@ -498,10 +466,10 @@ validate_urifrag(const char *frag)
if ( ! (isalnum((unsigned char)*frag) ||
'-' == *frag || '.' == *frag ||
'/' == *frag || '_' == *frag))
- return(0);
+ return 0;
frag++;
}
- return(1);
+ return 1;
}
static int
@@ -510,13 +478,13 @@ validate_manpath(const struct req *req, const char* manpath)
size_t i;
if ( ! strcmp(manpath, "mandoc"))
- return(1);
+ return 1;
for (i = 0; i < req->psz; i++)
if ( ! strcmp(manpath, req->p[i]))
- return(1);
+ return 1;
- return(0);
+ return 0;
}
static int
@@ -526,8 +494,8 @@ validate_filename(const char *file)
if ('.' == file[0] && '/' == file[1])
file += 2;
- return ( ! (strstr(file, "../") || strstr(file, "/..") ||
- (strncmp(file, "man", 3) && strncmp(file, "cat", 3))));
+ return ! (strstr(file, "../") || strstr(file, "/..") ||
+ (strncmp(file, "man", 3) && strncmp(file, "cat", 3)));
}
static void
@@ -604,9 +572,8 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
* without any delay.
*/
printf("Status: 303 See Other\r\n");
- printf("Location: http://%s%s/%s/%s?",
+ printf("Location: http://%s%s/%s/%s",
HTTP_HOST, scriptname, req->q.manpath, r[0].file);
- http_printquery(req, "&");
printf("\r\n"
"Content-Type: text/html; charset=utf-8\r\n"
"\r\n");
@@ -621,9 +588,8 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
for (i = 0; i < sz; i++) {
printf("<TR>\n"
"<TD CLASS=\"title\">\n"
- "<A HREF=\"%s/%s/%s?",
+ "<A HREF=\"%s/%s/%s",
scriptname, req->q.manpath, r[i].file);
- http_printquery(req, "&amp;");
printf("\">");
html_print(r[i].names);
printf("</A>\n"
@@ -685,12 +651,13 @@ static void
catman(const struct req *req, const char *file)
{
FILE *f;
- size_t len;
- int i;
char *p;
+ size_t sz;
+ ssize_t len;
+ int i;
int italic, bold;
- if (NULL == (f = fopen(file, "r"))) {
+ if ((f = fopen(file, "r")) == NULL) {
puts("<P>You specified an invalid manual file.</P>");
return;
}
@@ -698,9 +665,12 @@ catman(const struct req *req, const char *file)
puts("<DIV CLASS=\"catman\">\n"
"<PRE>");
- while (NULL != (p = fgetln(f, &len))) {
+ p = NULL;
+ sz = 0;
+
+ while ((len = getline(&p, &sz, f)) != -1) {
bold = italic = 0;
- for (i = 0; i < (int)len - 1; i++) {
+ for (i = 0; i < len - 1; i++) {
/*
* This means that the catpage is out of state.
* Ignore it and keep going (although the
@@ -725,7 +695,7 @@ catman(const struct req *req, const char *file)
italic = bold = 0;
html_putchar(p[i]);
continue;
- } else if (i + 2 >= (int)len)
+ } else if (i + 2 >= len)
continue;
/* Italic mode. */
@@ -801,11 +771,12 @@ catman(const struct req *req, const char *file)
if (bold)
printf("</B>");
- if (i == (int)len - 1 && '\n' != p[i])
+ if (i == len - 1 && p[i] != '\n')
html_putchar(p[i]);
putchar('\n');
}
+ free(p);
puts("</PRE>\n"
"</DIV>");
@@ -816,12 +787,10 @@ catman(const struct req *req, const char *file)
static void
format(const struct req *req, const char *file)
{
+ struct manoutput conf;
struct mparse *mp;
- struct mchars *mchars;
- struct mdoc *mdoc;
- struct man *man;
+ struct roff_man *man;
void *vp;
- char *opts;
int fd;
int usepath;
@@ -830,42 +799,45 @@ format(const struct req *req, const char *file)
return;
}
- mchars = mchars_alloc();
- mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL,
- mchars, req->q.manpath);
+ mchars_alloc();
+ mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, req->q.manpath);
mparse_readfd(mp, fd, file);
close(fd);
+ memset(&conf, 0, sizeof(conf));
+ conf.fragment = 1;
usepath = strcmp(req->q.manpath, req->p[0]);
- mandoc_asprintf(&opts,
- "fragment,man=%s?query=%%N&sec=%%S%s%s%s%s",
+ mandoc_asprintf(&conf.man, "%s?query=%%N&sec=%%S%s%s%s%s",
scriptname,
req->q.arch ? "&arch=" : "",
req->q.arch ? req->q.arch : "",
usepath ? "&manpath=" : "",
usepath ? req->q.manpath : "");
- mparse_result(mp, &mdoc, &man, NULL);
- if (NULL == man && NULL == mdoc) {
+ mparse_result(mp, &man, NULL);
+ if (man == NULL) {
fprintf(stderr, "fatal mandoc error: %s/%s\n",
req->q.manpath, file);
pg_error_internal();
mparse_free(mp);
- mchars_free(mchars);
+ mchars_free();
return;
}
- vp = html_alloc(mchars, opts);
+ vp = html_alloc(&conf);
- if (NULL != mdoc)
- html_mdoc(vp, mdoc);
- else
+ if (man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
+ html_mdoc(vp, man);
+ } else {
+ man_validate(man);
html_man(vp, man);
+ }
html_free(vp);
mparse_free(mp);
- mchars_free(mchars);
- free(opts);
+ mchars_free();
+ free(conf.man);
}
static void
@@ -1030,7 +1002,7 @@ main(void)
if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) {
fprintf(stderr, "setitimer: %s\n", strerror(errno));
pg_error_internal();
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
/* Scan our run-time environment. */
@@ -1042,7 +1014,7 @@ main(void)
fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n",
scriptname);
pg_error_internal();
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
/*
@@ -1055,7 +1027,7 @@ main(void)
fprintf(stderr, "MAN_DIR: %s: %s\n",
MAN_DIR, strerror(errno));
pg_error_internal();
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
memset(&req, 0, sizeof(struct req));
@@ -1071,13 +1043,13 @@ main(void)
else if ( ! validate_manpath(&req, req.q.manpath)) {
pg_error_badrequest(
"You specified an invalid manpath.");
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
pg_error_badrequest(
"You specified an invalid architecture.");
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
/* Dispatch to the three different pages. */
@@ -1102,7 +1074,7 @@ main(void)
for (i = 0; i < (int)req.psz; i++)
free(req.p[i]);
free(req.p);
- return(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
/*
@@ -1114,6 +1086,7 @@ pathgen(struct req *req)
FILE *fp;
char *dp;
size_t dpsz;
+ ssize_t len;
if (NULL == (fp = fopen("manpath.conf", "r"))) {
fprintf(stderr, "%s/manpath.conf: %s\n",
@@ -1122,12 +1095,14 @@ pathgen(struct req *req)
exit(EXIT_FAILURE);
}
- while (NULL != (dp = fgetln(fp, &dpsz))) {
- if ('\n' == dp[dpsz - 1])
- dpsz--;
+ dp = NULL;
+ dpsz = 0;
+
+ while ((len = getline(&dp, &dpsz, fp)) != -1) {
+ if (dp[len - 1] == '\n')
+ dp[--len] = '\0';
req->p = mandoc_realloc(req->p,
(req->psz + 1) * sizeof(char *));
- dp = mandoc_strndup(dp, dpsz);
if ( ! validate_urifrag(dp)) {
fprintf(stderr, "%s/manpath.conf contains "
"unsafe path \"%s\"\n", MAN_DIR, dp);
@@ -1141,7 +1116,10 @@ pathgen(struct req *req)
exit(EXIT_FAILURE);
}
req->p[req->psz++] = dp;
+ dp = NULL;
+ dpsz = 0;
}
+ free(dp);
if ( req->p == NULL ) {
fprintf(stderr, "%s/manpath.conf is empty\n", MAN_DIR);
diff --git a/cgi.h.example b/cgi.h.example
index f4c783186751..c4878d34a194 100644
--- a/cgi.h.example
+++ b/cgi.h.example
@@ -4,6 +4,4 @@
#define MAN_DIR "/var/www/man"
#define CSS_DIR ""
#define CUSTOMIZE_TITLE "Manual pages with mandoc"
-#define CUSTOMIZE_BEGIN "<H2>\nManual pages with " \
- "<A HREF=\"http://mdocml.bsd.lv/\">mandoc</A>\n</H2>"
#define COMPAT_OLDURI Yes
diff --git a/chars.c b/chars.c
index 6b5eba953728..c2cfaf818444 100644
--- a/chars.c
+++ b/chars.c
@@ -1,7 +1,7 @@
-/* $Id: chars.c,v 1.66 2015/02/17 20:37:16 schwarze Exp $ */
+/* $Id: chars.c,v 1.68 2015/10/13 22:59:54 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2014, 2015 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
@@ -21,90 +21,429 @@
#include <assert.h>
#include <ctype.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "mandoc.h"
#include "mandoc_aux.h"
+#include "mandoc_ohash.h"
#include "libmandoc.h"
-#define PRINT_HI 126
-#define PRINT_LO 32
-
struct ln {
- struct ln *next;
- const char *code;
+ const char roffcode[16];
const char *ascii;
int unicode;
};
-#define LINES_MAX 332
-
-#define CHAR(in, ch, code) \
- { NULL, (in), (ch), (code) },
-
-#define CHAR_TBL_START static struct ln lines[LINES_MAX] = {
-#define CHAR_TBL_END };
-
-#include "chars.in"
-
-struct mchars {
- struct ln **htab;
+/* Special break control characters. */
+static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
+static const char ascii_break[2] = { ASCII_BREAK, '\0' };
+
+static struct ln lines[] = {
+
+ /* Spacing. */
+ { " ", ascii_nbrsp, 0x00a0 },
+ { "~", ascii_nbrsp, 0x00a0 },
+ { "0", " ", 0x2002 },
+ { "|", "", 0 },
+ { "^", "", 0 },
+ { "&", "", 0 },
+ { "%", "", 0 },
+ { ":", ascii_break, 0 },
+ /* XXX The following three do not really belong here. */
+ { "t", "", 0 },
+ { "c", "", 0 },
+ { "}", "", 0 },
+
+ /* Lines. */
+ { "ba", "|", 0x007c },
+ { "br", "|", 0x2502 },
+ { "ul", "_", 0x005f },
+ { "rn", "-", 0x203e },
+ { "bb", "|", 0x00a6 },
+ { "sl", "/", 0x002f },
+ { "rs", "\\", 0x005c },
+
+ /* Text markers. */
+ { "ci", "O", 0x25cb },
+ { "bu", "+\bo", 0x2022 },
+ { "dd", "|\b=", 0x2021 },
+ { "dg", "|\b-", 0x2020 },
+ { "lz", "<>", 0x25ca },
+ { "sq", "[]", 0x25a1 },
+ { "ps", "<par>", 0x00b6 },
+ { "sc", "<sec>", 0x00a7 },
+ { "lh", "<=", 0x261c },
+ { "rh", "=>", 0x261e },
+ { "at", "@", 0x0040 },
+ { "sh", "#", 0x0023 },
+ { "CR", "_|", 0x21b5 },
+ { "OK", "\\/", 0x2713 },
+
+ /* Legal symbols. */
+ { "co", "(C)", 0x00a9 },
+ { "rg", "(R)", 0x00ae },
+ { "tm", "tm", 0x2122 },
+
+ /* Punctuation. */
+ { "em", "--", 0x2014 },
+ { "en", "-", 0x2013 },
+ { "hy", "-", 0x2010 },
+ { "e", "\\", 0x005c },
+ { ".", ".", 0x002e },
+ { "r!", "!", 0x00a1 },
+ { "r?", "?", 0x00bf },
+
+ /* Quotes. */
+ { "Bq", ",,", 0x201e },
+ { "bq", ",", 0x201a },
+ { "lq", "\"", 0x201c },
+ { "rq", "\"", 0x201d },
+ { "Lq", "``", 0x201c },
+ { "Rq", "''", 0x201d },
+ { "oq", "`", 0x2018 },
+ { "cq", "\'", 0x2019 },
+ { "aq", "\'", 0x0027 },
+ { "dq", "\"", 0x0022 },
+ { "Fo", "<<", 0x00ab },
+ { "Fc", ">>", 0x00bb },
+ { "fo", "<", 0x2039 },
+ { "fc", ">", 0x203a },
+
+ /* Brackets. */
+ { "lB", "[", 0x005b },
+ { "rB", "]", 0x005d },
+ { "lC", "{", 0x007b },
+ { "rC", "}", 0x007d },
+ { "la", "<", 0x27e8 },
+ { "ra", ">", 0x27e9 },
+ { "bv", "|", 0x23aa },
+ { "braceex", "|", 0x23aa },
+ { "bracketlefttp", "|", 0x23a1 },
+ { "bracketleftbt", "|", 0x23a3 },
+ { "bracketleftex", "|", 0x23a2 },
+ { "bracketrighttp", "|", 0x23a4 },
+ { "bracketrightbt", "|", 0x23a6 },
+ { "bracketrightex", "|", 0x23a5 },
+ { "lt", ",-", 0x23a7 },
+ { "bracelefttp", ",-", 0x23a7 },
+ { "lk", "{", 0x23a8 },
+ { "braceleftmid", "{", 0x23a8 },
+ { "lb", "`-", 0x23a9 },
+ { "braceleftbt", "`-", 0x23a9 },
+ { "braceleftex", "|", 0x23aa },
+ { "rt", "-.", 0x23ab },
+ { "bracerighttp", "-.", 0x23ab },
+ { "rk", "}", 0x23ac },
+ { "bracerightmid", "}", 0x23ac },
+ { "rb", "-\'", 0x23ad },
+ { "bracerightbt", "-\'", 0x23ad },
+ { "bracerightex", "|", 0x23aa },
+ { "parenlefttp", "/", 0x239b },
+ { "parenleftbt", "\\", 0x239d },
+ { "parenleftex", "|", 0x239c },
+ { "parenrighttp", "\\", 0x239e },
+ { "parenrightbt", "/", 0x23a0 },
+ { "parenrightex", "|", 0x239f },
+
+ /* Arrows and lines. */
+ { "<-", "<-", 0x2190 },
+ { "->", "->", 0x2192 },
+ { "<>", "<->", 0x2194 },
+ { "da", "|\bv", 0x2193 },
+ { "ua", "|\b^", 0x2191 },
+ { "va", "^v", 0x2195 },
+ { "lA", "<=", 0x21d0 },
+ { "rA", "=>", 0x21d2 },
+ { "hA", "<=>", 0x21d4 },
+ { "uA", "=\b^", 0x21d1 },
+ { "dA", "=\bv", 0x21d3 },
+ { "vA", "^=v", 0x21d5 },
+
+ /* Logic. */
+ { "AN", "^", 0x2227 },
+ { "OR", "v", 0x2228 },
+ { "no", "~", 0x00ac },
+ { "tno", "~", 0x00ac },
+ { "te", "3", 0x2203 },
+ { "fa", "-\bV", 0x2200 },
+ { "st", "-)", 0x220b },
+ { "tf", ".:.", 0x2234 },
+ { "3d", ".:.", 0x2234 },
+ { "or", "|", 0x007c },
+
+ /* Mathematicals. */
+ { "pl", "+", 0x002b },
+ { "mi", "-", 0x2212 },
+ { "-", "-", 0x002d },
+ { "-+", "-+", 0x2213 },
+ { "+-", "+-", 0x00b1 },
+ { "t+-", "+-", 0x00b1 },
+ { "pc", ".", 0x00b7 },
+ { "md", ".", 0x22c5 },
+ { "mu", "x", 0x00d7 },
+ { "tmu", "x", 0x00d7 },
+ { "c*", "O\bx", 0x2297 },
+ { "c+", "O\b+", 0x2295 },
+ { "di", "-:-", 0x00f7 },
+ { "tdi", "-:-", 0x00f7 },
+ { "f/", "/", 0x2044 },
+ { "**", "*", 0x2217 },
+ { "<=", "<=", 0x2264 },
+ { ">=", ">=", 0x2265 },
+ { "<<", "<<", 0x226a },
+ { ">>", ">>", 0x226b },
+ { "eq", "=", 0x003d },
+ { "!=", "!=", 0x2260 },
+ { "==", "==", 0x2261 },
+ { "ne", "!==", 0x2262 },
+ { "ap", "~", 0x223c },
+ { "|=", "-~", 0x2243 },
+ { "=~", "=~", 0x2245 },
+ { "~~", "~~", 0x2248 },
+ { "~=", "~=", 0x2248 },
+ { "pt", "oc", 0x221d },
+ { "es", "{}", 0x2205 },
+ { "mo", "E", 0x2208 },
+ { "nm", "!E", 0x2209 },
+ { "sb", "(=", 0x2282 },
+ { "nb", "(!=", 0x2284 },
+ { "sp", "=)", 0x2283 },
+ { "nc", "!=)", 0x2285 },
+ { "ib", "(=\b_", 0x2286 },
+ { "ip", "=\b_)", 0x2287 },
+ { "ca", "(^)", 0x2229 },
+ { "cu", "U", 0x222a },
+ { "/_", "_\b/", 0x2220 },
+ { "pp", "_\b|", 0x22a5 },
+ { "is", "'\b,\bI", 0x222b },
+ { "integral", "'\b,\bI", 0x222b },
+ { "sum", "E", 0x2211 },
+ { "product", "TT", 0x220f },
+ { "coproduct", "U", 0x2210 },
+ { "gr", "V", 0x2207 },
+ { "sr", "\\/", 0x221a },
+ { "sqrt", "\\/", 0x221a },
+ { "lc", "|~", 0x2308 },
+ { "rc", "~|", 0x2309 },
+ { "lf", "|_", 0x230a },
+ { "rf", "_|", 0x230b },
+ { "if", "oo", 0x221e },
+ { "Ah", "N", 0x2135 },
+ { "Im", "I", 0x2111 },
+ { "Re", "R", 0x211c },
+ { "pd", "a", 0x2202 },
+ { "-h", "/h", 0x210f },
+ { "12", "1/2", 0x00bd },
+ { "14", "1/4", 0x00bc },
+ { "34", "3/4", 0x00be },
+
+ /* Ligatures. */
+ { "ff", "ff", 0xfb00 },
+ { "fi", "fi", 0xfb01 },
+ { "fl", "fl", 0xfb02 },
+ { "Fi", "ffi", 0xfb03 },
+ { "Fl", "ffl", 0xfb04 },
+ { "AE", "AE", 0x00c6 },
+ { "ae", "ae", 0x00e6 },
+ { "OE", "OE", 0x0152 },
+ { "oe", "oe", 0x0153 },
+ { "ss", "ss", 0x00df },
+ { "IJ", "IJ", 0x0132 },
+ { "ij", "ij", 0x0133 },
+
+ /* Accents. */
+ { "a\"", "\"", 0x02dd },
+ { "a-", "-", 0x00af },
+ { "a.", ".", 0x02d9 },
+ { "a^", "^", 0x005e },
+ { "aa", "\'", 0x00b4 },
+ { "\'", "\'", 0x00b4 },
+ { "ga", "`", 0x0060 },
+ { "`", "`", 0x0060 },
+ { "ab", "'\b`", 0x02d8 },
+ { "ac", ",", 0x00b8 },
+ { "ad", "\"", 0x00a8 },
+ { "ah", "v", 0x02c7 },
+ { "ao", "o", 0x02da },
+ { "a~", "~", 0x007e },
+ { "ho", ",", 0x02db },
+ { "ha", "^", 0x005e },
+ { "ti", "~", 0x007e },
+
+ /* Accented letters. */
+ { "'A", "'\bA", 0x00c1 },
+ { "'E", "'\bE", 0x00c9 },
+ { "'I", "'\bI", 0x00cd },
+ { "'O", "'\bO", 0x00d3 },
+ { "'U", "'\bU", 0x00da },
+ { "'a", "'\ba", 0x00e1 },
+ { "'e", "'\be", 0x00e9 },
+ { "'i", "'\bi", 0x00ed },
+ { "'o", "'\bo", 0x00f3 },
+ { "'u", "'\bu", 0x00fa },
+ { "`A", "`\bA", 0x00c0 },
+ { "`E", "`\bE", 0x00c8 },
+ { "`I", "`\bI", 0x00cc },
+ { "`O", "`\bO", 0x00d2 },
+ { "`U", "`\bU", 0x00d9 },
+ { "`a", "`\ba", 0x00e0 },
+ { "`e", "`\be", 0x00e8 },
+ { "`i", "`\bi", 0x00ec },
+ { "`o", "`\bo", 0x00f2 },
+ { "`u", "`\bu", 0x00f9 },
+ { "~A", "~\bA", 0x00c3 },
+ { "~N", "~\bN", 0x00d1 },
+ { "~O", "~\bO", 0x00d5 },
+ { "~a", "~\ba", 0x00e3 },
+ { "~n", "~\bn", 0x00f1 },
+ { "~o", "~\bo", 0x00f5 },
+ { ":A", "\"\bA", 0x00c4 },
+ { ":E", "\"\bE", 0x00cb },
+ { ":I", "\"\bI", 0x00cf },
+ { ":O", "\"\bO", 0x00d6 },
+ { ":U", "\"\bU", 0x00dc },
+ { ":a", "\"\ba", 0x00e4 },
+ { ":e", "\"\be", 0x00eb },
+ { ":i", "\"\bi", 0x00ef },
+ { ":o", "\"\bo", 0x00f6 },
+ { ":u", "\"\bu", 0x00fc },
+ { ":y", "\"\by", 0x00ff },
+ { "^A", "^\bA", 0x00c2 },
+ { "^E", "^\bE", 0x00ca },
+ { "^I", "^\bI", 0x00ce },
+ { "^O", "^\bO", 0x00d4 },
+ { "^U", "^\bU", 0x00db },
+ { "^a", "^\ba", 0x00e2 },
+ { "^e", "^\be", 0x00ea },
+ { "^i", "^\bi", 0x00ee },
+ { "^o", "^\bo", 0x00f4 },
+ { "^u", "^\bu", 0x00fb },
+ { ",C", ",\bC", 0x00c7 },
+ { ",c", ",\bc", 0x00e7 },
+ { "/L", "/\bL", 0x0141 },
+ { "/l", "/\bl", 0x0142 },
+ { "/O", "/\bO", 0x00d8 },
+ { "/o", "/\bo", 0x00f8 },
+ { "oA", "o\bA", 0x00c5 },
+ { "oa", "o\ba", 0x00e5 },
+
+ /* Special letters. */
+ { "-D", "-\bD", 0x00d0 },
+ { "Sd", "d", 0x00f0 },
+ { "TP", "Th", 0x00de },
+ { "Tp", "th", 0x00fe },
+ { ".i", "i", 0x0131 },
+ { ".j", "j", 0x0237 },
+
+ /* Currency. */
+ { "Do", "$", 0x0024 },
+ { "ct", "/\bc", 0x00a2 },
+ { "Eu", "EUR", 0x20ac },
+ { "eu", "EUR", 0x20ac },
+ { "Ye", "=\bY", 0x00a5 },
+ { "Po", "GBP", 0x00a3 },
+ { "Cs", "o\bx", 0x00a4 },
+ { "Fn", ",\bf", 0x0192 },
+
+ /* Units. */
+ { "de", "<deg>", 0x00b0 },
+ { "%0", "%o", 0x2030 },
+ { "fm", "\'", 0x2032 },
+ { "sd", "''", 0x2033 },
+ { "mc", ",\bu", 0x00b5 },
+
+ /* Greek characters. */
+ { "*A", "A", 0x0391 },
+ { "*B", "B", 0x0392 },
+ { "*G", "G", 0x0393 },
+ { "*D", "_\b/_\b\\", 0x0394 },
+ { "*E", "E", 0x0395 },
+ { "*Z", "Z", 0x0396 },
+ { "*Y", "H", 0x0397 },
+ { "*H", "-\bO", 0x0398 },
+ { "*I", "I", 0x0399 },
+ { "*K", "K", 0x039a },
+ { "*L", "/\\", 0x039b },
+ { "*M", "M", 0x039c },
+ { "*N", "N", 0x039d },
+ { "*C", "_\bH", 0x039e },
+ { "*O", "O", 0x039f },
+ { "*P", "TT", 0x03a0 },
+ { "*R", "P", 0x03a1 },
+ { "*S", "S", 0x03a3 },
+ { "*T", "T", 0x03a4 },
+ { "*U", "Y", 0x03a5 },
+ { "*F", "I\bO", 0x03a6 },
+ { "*X", "X", 0x03a7 },
+ { "*Q", "I\bY", 0x03a8 },
+ { "*W", "_\bO", 0x03a9 },
+ { "*a", "a", 0x03b1 },
+ { "*b", "B", 0x03b2 },
+ { "*g", "y", 0x03b3 },
+ { "*d", "d", 0x03b4 },
+ { "*e", "e", 0x03b5 },
+ { "*z", ",\bC", 0x03b6 },
+ { "*y", "n", 0x03b7 },
+ { "*h", "-\b0", 0x03b8 },
+ { "*i", "i", 0x03b9 },
+ { "*k", "k", 0x03ba },
+ { "*l", ">\b\\", 0x03bb },
+ { "*m", ",\bu", 0x03bc },
+ { "*n", "v", 0x03bd },
+ { "*c", ",\bE", 0x03be },
+ { "*o", "o", 0x03bf },
+ { "*p", "-\bn", 0x03c0 },
+ { "*r", "p", 0x03c1 },
+ { "*s", "-\bo", 0x03c3 },
+ { "*t", "~\bt", 0x03c4 },
+ { "*u", "u", 0x03c5 },
+ { "*f", "|\bo", 0x03d5 },
+ { "*x", "x", 0x03c7 },
+ { "*q", "|\bu", 0x03c8 },
+ { "*w", "w", 0x03c9 },
+ { "+h", "-\b0", 0x03d1 },
+ { "+f", "|\bo", 0x03c6 },
+ { "+p", "-\bw", 0x03d6 },
+ { "+e", "e", 0x03f5 },
+ { "ts", "s", 0x03c2 },
};
-static const struct ln *find(const struct mchars *,
- const char *, size_t);
+static struct ohash mchars;
void
-mchars_free(struct mchars *arg)
+mchars_free(void)
{
- free(arg->htab);
- free(arg);
+ ohash_delete(&mchars);
}
-struct mchars *
+void
mchars_alloc(void)
{
- struct mchars *tab;
- struct ln **htab;
- struct ln *pp;
- int i, hash;
-
- /*
- * Constructs a very basic chaining hashtable. The hash routine
- * is simply the integral value of the first character.
- * Subsequent entries are chained in the order they're processed.
- */
-
- tab = mandoc_malloc(sizeof(struct mchars));
- htab = mandoc_calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln *));
-
- for (i = 0; i < LINES_MAX; i++) {
- hash = (int)lines[i].code[0] - PRINT_LO;
-
- if (NULL == (pp = htab[hash])) {
- htab[hash] = &lines[i];
- continue;
- }
-
- for ( ; pp->next; pp = pp->next)
- /* Scan ahead. */ ;
- pp->next = &lines[i];
+ size_t i;
+ unsigned int slot;
+
+ mandoc_ohash_init(&mchars, 9, offsetof(struct ln, roffcode));
+ for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++) {
+ slot = ohash_qlookup(&mchars, lines[i].roffcode);
+ assert(ohash_find(&mchars, slot) == NULL);
+ ohash_insert(&mchars, slot, lines + i);
}
-
- tab->htab = htab;
- return(tab);
}
int
-mchars_spec2cp(const struct mchars *arg, const char *p, size_t sz)
+mchars_spec2cp(const char *p, size_t sz)
{
const struct ln *ln;
+ const char *end;
- ln = find(arg, p, sz);
- return(ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1);
+ end = p + sz;
+ ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
+ return ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1;
}
int
@@ -113,7 +452,7 @@ mchars_num2char(const char *p, size_t sz)
int i;
i = mandoc_strntoi(p, sz, 10);
- return(i >= 0 && i < 256 ? i : -1);
+ return i >= 0 && i < 256 ? i : -1;
}
int
@@ -123,53 +462,33 @@ mchars_num2uc(const char *p, size_t sz)
i = mandoc_strntoi(p, sz, 16);
assert(i >= 0 && i <= 0x10FFFF);
- return(i);
+ return i;
}
const char *
-mchars_spec2str(const struct mchars *arg,
- const char *p, size_t sz, size_t *rsz)
+mchars_spec2str(const char *p, size_t sz, size_t *rsz)
{
const struct ln *ln;
+ const char *end;
- ln = find(arg, p, sz);
+ end = p + sz;
+ ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
if (ln == NULL) {
*rsz = 1;
- return(sz == 1 ? p : NULL);
+ return sz == 1 ? p : NULL;
}
*rsz = strlen(ln->ascii);
- return(ln->ascii);
+ return ln->ascii;
}
const char *
mchars_uc2str(int uc)
{
- int i;
+ size_t i;
- for (i = 0; i < LINES_MAX; i++)
+ for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++)
if (uc == lines[i].unicode)
- return(lines[i].ascii);
- return("<?>");
-}
-
-static const struct ln *
-find(const struct mchars *tab, const char *p, size_t sz)
-{
- const struct ln *pp;
- int hash;
-
- assert(p);
-
- if (0 == sz || p[0] < PRINT_LO || p[0] > PRINT_HI)
- return(NULL);
-
- hash = (int)p[0] - PRINT_LO;
-
- for (pp = tab->htab[hash]; pp; pp = pp->next)
- if (0 == strncmp(pp->code, p, sz) &&
- '\0' == pp->code[(int)sz])
- return(pp);
-
- return(NULL);
+ return lines[i].ascii;
+ return "<?>";
}
diff --git a/chars.in b/chars.in
deleted file mode 100644
index ac72aba8588c..000000000000
--- a/chars.in
+++ /dev/null
@@ -1,404 +0,0 @@
-/* $Id: chars.in,v 1.52 2015/02/17 20:37:16 schwarze Exp $ */
-/*
- * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014 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.
- */
-
-/*
- * The ASCII translation tables.
- *
- * The left-hand side corresponds to the input sequence (\x, \(xx, \*(xx
- * and so on) whose length is listed second element. The right-hand
- * side is what's produced by the front-end, with the fourth element
- * being its length.
- *
- * XXX - C-escape strings!
- * XXX - update LINES_MAX if adding more!
- */
-
-/* Special break control characters. */
-static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
-static const char ascii_break[2] = { ASCII_BREAK, '\0' };
-
-CHAR_TBL_START
-
-/* Spacing. */
-CHAR(" ", ascii_nbrsp, 160)
-CHAR("~", ascii_nbrsp, 160)
-CHAR("0", " ", 8194)
-CHAR("|", "", 0)
-CHAR("^", "", 0)
-CHAR("&", "", 0)
-CHAR("%", "", 0)
-CHAR(":", ascii_break, 0)
-/* XXX The following three do not really belong into this file. */
-CHAR("t", "", 0)
-CHAR("c", "", 0)
-CHAR("}", "", 0)
-
-/* Accents. */
-CHAR("a\"", "\"", 733)
-CHAR("a-", "-", 175)
-CHAR("a.", ".", 729)
-CHAR("a^", "^", 94)
-CHAR("\'", "\'", 180)
-CHAR("aa", "\'", 180)
-CHAR("ga", "`", 96)
-CHAR("`", "`", 96)
-CHAR("ab", "'\b`", 728)
-CHAR("ac", ",", 184)
-CHAR("ad", "\"", 168)
-CHAR("ah", "v", 711)
-CHAR("ao", "o", 730)
-CHAR("a~", "~", 126)
-CHAR("ho", ",", 731)
-CHAR("ha", "^", 94)
-CHAR("ti", "~", 126)
-
-/* Quotes. */
-CHAR("Bq", ",,", 8222)
-CHAR("bq", ",", 8218)
-CHAR("lq", "\"", 8220)
-CHAR("rq", "\"", 8221)
-CHAR("Lq", "``", 8220)
-CHAR("Rq", "''", 8221)
-CHAR("oq", "`", 8216)
-CHAR("cq", "\'", 8217)
-CHAR("aq", "\'", 39)
-CHAR("dq", "\"", 34)
-CHAR("Fo", "<<", 171)
-CHAR("Fc", ">>", 187)
-CHAR("fo", "<", 8249)
-CHAR("fc", ">", 8250)
-
-/* Brackets. */
-CHAR("lB", "[", 91)
-CHAR("rB", "]", 93)
-CHAR("lC", "{", 123)
-CHAR("rC", "}", 125)
-CHAR("la", "<", 10216)
-CHAR("ra", ">", 10217)
-CHAR("bv", "|", 9130)
-CHAR("braceex", "|", 9130)
-CHAR("bracketlefttp", "|", 9121)
-CHAR("bracketleftbt", "|", 9123)
-CHAR("bracketleftex", "|", 9122)
-CHAR("bracketrighttp", "|", 9124)
-CHAR("bracketrightbt", "|", 9126)
-CHAR("bracketrightex", "|", 9125)
-CHAR("lt", ",-", 9127)
-CHAR("bracelefttp", ",-", 9127)
-CHAR("lk", "{", 9128)
-CHAR("braceleftmid", "{", 9128)
-CHAR("lb", "`-", 9129)
-CHAR("braceleftbt", "`-", 9129)
-CHAR("braceleftex", "|", 9130)
-CHAR("rt", "-.", 9131)
-CHAR("bracerighttp", "-.", 9131)
-CHAR("rk", "}", 9132)
-CHAR("bracerightmid", "}", 9132)
-CHAR("rb", "-\'", 9133)
-CHAR("bracerightbt", "-\'", 9133)
-CHAR("bracerightex", "|", 9130)
-CHAR("parenlefttp", "/", 9115)
-CHAR("parenleftbt", "\\", 9117)
-CHAR("parenleftex", "|", 9116)
-CHAR("parenrighttp", "\\", 9118)
-CHAR("parenrightbt", "/", 9120)
-CHAR("parenrightex", "|", 9119)
-
-/* Greek characters. */
-CHAR("*A", "A", 913)
-CHAR("*B", "B", 914)
-CHAR("*G", "G", 915)
-CHAR("*D", "_\b/_\b\\", 916)
-CHAR("*E", "E", 917)
-CHAR("*Z", "Z", 918)
-CHAR("*Y", "H", 919)
-CHAR("*H", "-\bO", 920)
-CHAR("*I", "I", 921)
-CHAR("*K", "K", 922)
-CHAR("*L", "/\\", 923)
-CHAR("*M", "M", 924)
-CHAR("*N", "N", 925)
-CHAR("*C", "_\bH", 926)
-CHAR("*O", "O", 927)
-CHAR("*P", "TT", 928)
-CHAR("*R", "P", 929)
-CHAR("*S", "S", 931)
-CHAR("*T", "T", 932)
-CHAR("*U", "Y", 933)
-CHAR("*F", "I\bO", 934)
-CHAR("*X", "X", 935)
-CHAR("*Q", "I\bY", 936)
-CHAR("*W", "_\bO", 937)
-CHAR("*a", "a", 945)
-CHAR("*b", "B", 946)
-CHAR("*g", "y", 947)
-CHAR("*d", "d", 948)
-CHAR("*e", "e", 949)
-CHAR("*z", ",\bC", 950)
-CHAR("*y", "n", 951)
-CHAR("*h", "-\b0", 952)
-CHAR("*i", "i", 953)
-CHAR("*k", "k", 954)
-CHAR("*l", ">\b\\", 955)
-CHAR("*m", ",\bu", 956)
-CHAR("*n", "v", 957)
-CHAR("*c", ",\bE", 958)
-CHAR("*o", "o", 959)
-CHAR("*p", "-\bn", 960)
-CHAR("*r", "p", 961)
-CHAR("*s", "-\bo", 963)
-CHAR("*t", "~\bt", 964)
-CHAR("*u", "u", 965)
-CHAR("*f", "|\bo", 981)
-CHAR("*x", "x", 967)
-CHAR("*q", "|\bu", 968)
-CHAR("*w", "w", 969)
-CHAR("+h", "-\b0", 977)
-CHAR("+f", "|\bo", 966)
-CHAR("+p", "-\bw", 982)
-CHAR("+e", "e", 1013)
-CHAR("ts", "s", 962)
-
-/* Accented letters. */
-CHAR(",C", ",\bC", 199)
-CHAR(",c", ",\bc", 231)
-CHAR("/L", "/\bL", 321)
-CHAR("/O", "/\bO", 216)
-CHAR("/l", "/\bl", 322)
-CHAR("/o", "/\bo", 248)
-CHAR("oA", "o\bA", 197)
-CHAR("oa", "o\ba", 229)
-CHAR(":A", "\"\bA", 196)
-CHAR(":E", "\"\bE", 203)
-CHAR(":I", "\"\bI", 207)
-CHAR(":O", "\"\bO", 214)
-CHAR(":U", "\"\bU", 220)
-CHAR(":a", "\"\ba", 228)
-CHAR(":e", "\"\be", 235)
-CHAR(":i", "\"\bi", 239)
-CHAR(":o", "\"\bo", 246)
-CHAR(":u", "\"\bu", 252)
-CHAR(":y", "\"\by", 255)
-CHAR("'A", "'\bA", 193)
-CHAR("'E", "'\bE", 201)
-CHAR("'I", "'\bI", 205)
-CHAR("'O", "'\bO", 211)
-CHAR("'U", "'\bU", 218)
-CHAR("'a", "'\ba", 225)
-CHAR("'e", "'\be", 233)
-CHAR("'i", "'\bi", 237)
-CHAR("'o", "'\bo", 243)
-CHAR("'u", "'\bu", 250)
-CHAR("^A", "^\bA", 194)
-CHAR("^E", "^\bE", 202)
-CHAR("^I", "^\bI", 206)
-CHAR("^O", "^\bO", 212)
-CHAR("^U", "^\bU", 219)
-CHAR("^a", "^\ba", 226)
-CHAR("^e", "^\be", 234)
-CHAR("^i", "^\bi", 238)
-CHAR("^o", "^\bo", 244)
-CHAR("^u", "^\bu", 251)
-CHAR("`A", "`\bA", 192)
-CHAR("`E", "`\bE", 200)
-CHAR("`I", "`\bI", 204)
-CHAR("`O", "`\bO", 210)
-CHAR("`U", "`\bU", 217)
-CHAR("`a", "`\ba", 224)
-CHAR("`e", "`\be", 232)
-CHAR("`i", "`\bi", 236)
-CHAR("`o", "`\bo", 242)
-CHAR("`u", "`\bu", 249)
-CHAR("~A", "~\bA", 195)
-CHAR("~N", "~\bN", 209)
-CHAR("~O", "~\bO", 213)
-CHAR("~a", "~\ba", 227)
-CHAR("~n", "~\bn", 241)
-CHAR("~o", "~\bo", 245)
-
-/* Arrows and lines. */
-CHAR("<-", "<-", 8592)
-CHAR("->", "->", 8594)
-CHAR("<>", "<->", 8596)
-CHAR("da", "|\bv", 8595)
-CHAR("ua", "|\b^", 8593)
-CHAR("va", "^v", 8597)
-CHAR("lA", "<=", 8656)
-CHAR("rA", "=>", 8658)
-CHAR("hA", "<=>", 8660)
-CHAR("dA", "=\bv", 8659)
-CHAR("uA", "=\b^", 8657)
-CHAR("vA", "^=v", 8661)
-
-/* Logic. */
-CHAR("AN", "^", 8743)
-CHAR("OR", "v", 8744)
-CHAR("no", "~", 172)
-CHAR("tno", "~", 172)
-CHAR("te", "3", 8707)
-CHAR("fa", "-\bV", 8704)
-CHAR("st", "-)", 8715)
-CHAR("tf", ".:.", 8756)
-CHAR("3d", ".:.", 8756)
-CHAR("or", "|", 124)
-
-/* Mathematicals. */
-CHAR("pl", "+", 43)
-CHAR("mi", "-", 8722)
-CHAR("-", "-", 45)
-CHAR("-+", "-+", 8723)
-CHAR("+-", "+-", 177)
-CHAR("t+-", "+-", 177)
-CHAR("pc", ".", 183)
-CHAR("md", ".", 8901)
-CHAR("mu", "x", 215)
-CHAR("tmu", "x", 215)
-CHAR("c*", "O\bx", 8855)
-CHAR("c+", "O\b+", 8853)
-CHAR("di", "-:-", 247)
-CHAR("tdi", "-:-", 247)
-CHAR("f/", "/", 8260)
-CHAR("**", "*", 8727)
-CHAR("<=", "<=", 8804)
-CHAR(">=", ">=", 8805)
-CHAR("<<", "<<", 8810)
-CHAR(">>", ">>", 8811)
-CHAR("eq", "=", 61)
-CHAR("!=", "!=", 8800)
-CHAR("==", "==", 8801)
-CHAR("ne", "!==", 8802)
-CHAR("=~", "=~", 8773)
-CHAR("|=", "-~", 8771)
-CHAR("ap", "~", 8764)
-CHAR("~~", "~~", 8776)
-CHAR("~=", "~=", 8776)
-CHAR("pt", "oc", 8733)
-CHAR("es", "{}", 8709)
-CHAR("mo", "E", 8712)
-CHAR("nm", "!E", 8713)
-CHAR("sb", "(=", 8834)
-CHAR("nb", "(!=", 8836)
-CHAR("sp", "=)", 8835)
-CHAR("nc", "!=)", 8837)
-CHAR("ib", "(=\b_", 8838)
-CHAR("ip", "=\b_)", 8839)
-CHAR("ca", "(^)", 8745)
-CHAR("cu", "U", 8746)
-CHAR("/_", "_\b/", 8736)
-CHAR("pp", "_\b|", 8869)
-CHAR("is", "'\b,\bI", 8747)
-CHAR("integral", "'\b,\bI", 8747)
-CHAR("sum", "E", 8721)
-CHAR("product", "TT", 8719)
-CHAR("coproduct", "U", 8720)
-CHAR("gr", "V", 8711)
-CHAR("sr", "\\/", 8730)
-CHAR("sqrt", "\\/", 8730)
-CHAR("lc", "|~", 8968)
-CHAR("rc", "~|", 8969)
-CHAR("lf", "|_", 8970)
-CHAR("rf", "_|", 8971)
-CHAR("if", "oo", 8734)
-CHAR("Ah", "N", 8501)
-CHAR("Im", "I", 8465)
-CHAR("Re", "R", 8476)
-CHAR("pd", "a", 8706)
-CHAR("-h", "/h", 8463)
-CHAR("12", "1/2", 189)
-CHAR("14", "1/4", 188)
-CHAR("34", "3/4", 190)
-
-/* Ligatures. */
-CHAR("ff", "ff", 64256)
-CHAR("fi", "fi", 64257)
-CHAR("fl", "fl", 64258)
-CHAR("Fi", "ffi", 64259)
-CHAR("Fl", "ffl", 64260)
-CHAR("AE", "AE", 198)
-CHAR("ae", "ae", 230)
-CHAR("OE", "OE", 338)
-CHAR("oe", "oe", 339)
-CHAR("ss", "ss", 223)
-CHAR("IJ", "IJ", 306)
-CHAR("ij", "ij", 307)
-
-/* Special letters. */
-CHAR("-D", "-\bD", 208)
-CHAR("Sd", "d", 240)
-CHAR("TP", "Th", 222)
-CHAR("Tp", "th", 254)
-CHAR(".i", "i", 305)
-CHAR(".j", "j", 567)
-
-/* Currency. */
-CHAR("Do", "$", 36)
-CHAR("ct", "/\bc", 162)
-CHAR("Eu", "EUR", 8364)
-CHAR("eu", "EUR", 8364)
-CHAR("Ye", "=\bY", 165)
-CHAR("Po", "GBP", 163)
-CHAR("Cs", "o\bx", 164)
-CHAR("Fn", ",\bf", 402)
-
-/* Lines. */
-CHAR("ba", "|", 124)
-CHAR("br", "|", 9474)
-CHAR("ul", "_", 95)
-CHAR("rn", "-", 8254)
-CHAR("bb", "|", 166)
-CHAR("sl", "/", 47)
-CHAR("rs", "\\", 92)
-
-/* Text markers. */
-CHAR("ci", "O", 9675)
-CHAR("bu", "+\bo", 8226)
-CHAR("dd", "|\b=", 8225)
-CHAR("dg", "|\b-", 8224)
-CHAR("lz", "<>", 9674)
-CHAR("sq", "[]", 9633)
-CHAR("ps", "<par>", 182)
-CHAR("sc", "<sec>", 167)
-CHAR("lh", "<=", 9756)
-CHAR("rh", "=>", 9758)
-CHAR("at", "@", 64)
-CHAR("sh", "#", 35)
-CHAR("CR", "_|", 8629)
-CHAR("OK", "\\/", 10003)
-
-/* Legal symbols. */
-CHAR("co", "(C)", 169)
-CHAR("rg", "(R)", 174)
-CHAR("tm", "tm", 8482)
-
-/* Punctuation. */
-CHAR(".", ".", 46)
-CHAR("r!", "!", 161)
-CHAR("r?", "?", 191)
-CHAR("em", "--", 8212)
-CHAR("en", "-", 8211)
-CHAR("hy", "-", 8208)
-CHAR("e", "\\", 92)
-
-/* Units. */
-CHAR("de", "<deg>", 176)
-CHAR("%0", "%o", 8240)
-CHAR("fm", "\'", 8242)
-CHAR("sd", "''", 8243)
-CHAR("mc", ",\bu", 181)
-
-CHAR_TBL_END
diff --git a/compat_err.c b/compat_err.c
new file mode 100644
index 000000000000..d8b09cb2a307
--- /dev/null
+++ b/compat_err.c
@@ -0,0 +1,112 @@
+#include "config.h"
+
+#if HAVE_ERR
+
+int dummy;
+
+#else
+
+/* $Id: compat_err.c,v 1.4 2015/11/26 07:42:11 schwarze Exp $ */
+/*
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void vwarni(const char *, va_list);
+static void vwarnxi(const char *, va_list);
+
+static void
+vwarnxi(const char *fmt, va_list ap)
+{
+ fprintf(stderr, "%s: ", getprogname());
+ if (fmt != NULL)
+ vfprintf(stderr, fmt, ap);
+}
+
+static void
+vwarni(const char *fmt, va_list ap)
+{
+ int sverrno;
+
+ sverrno = errno;
+ vwarnxi(fmt, ap);
+ if (fmt != NULL)
+ fputs(": ", stderr);
+ fprintf(stderr, "%s\n", strerror(sverrno));
+}
+
+void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarni(fmt, ap);
+ va_end(ap);
+ exit(eval);
+}
+
+void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarnxi(fmt, ap);
+ va_end(ap);
+ fputc('\n', stderr);
+ exit(eval);
+}
+
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarni(fmt, ap);
+ va_end(ap);
+}
+
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarnxi(fmt, ap);
+ va_end(ap);
+ fputc('\n', stderr);
+}
+
+#endif
diff --git a/compat_fgetln.c b/compat_fgetln.c
deleted file mode 100644
index 3760ab994d11..000000000000
--- a/compat_fgetln.c
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "config.h"
-
-#if HAVE_FGETLN
-
-int dummy;
-
-#else
-
-/* $NetBSD: fgetln.c,v 1.3 2006/09/25 07:18:17 lukem Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Christos Zoulas.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-char *
-fgetln(fp, len)
- FILE *fp;
- size_t *len;
-{
- static char *buf = NULL;
- static size_t bufsiz = 0;
- char *ptr;
-
-
- if (buf == NULL) {
- bufsiz = BUFSIZ;
- if ((buf = malloc(bufsiz)) == NULL)
- return NULL;
- }
-
- if (fgets(buf, bufsiz, fp) == NULL)
- return NULL;
-
- *len = 0;
- while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
- size_t nbufsiz = bufsiz + BUFSIZ;
- char *nbuf = realloc(buf, nbufsiz);
-
- if (nbuf == NULL) {
- int oerrno = errno;
- free(buf);
- errno = oerrno;
- buf = NULL;
- return NULL;
- } else
- buf = nbuf;
-
- *len = bufsiz;
- if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
- return buf;
-
- bufsiz = nbufsiz;
- }
-
- *len = (ptr - buf) + 1;
- return buf;
-}
-
-#endif
diff --git a/compat_fts.c b/compat_fts.c
index 194c56552460..ed95854666a0 100644
--- a/compat_fts.c
+++ b/compat_fts.c
@@ -6,7 +6,7 @@ int dummy;
#else
-/* $Id: compat_fts.c,v 1.8 2015/02/07 07:53:01 schwarze Exp $ */
+/* $Id: compat_fts.c,v 1.9 2015/03/18 19:29:48 schwarze Exp $ */
/* $OpenBSD: fts.c,v 1.50 2015/01/16 16:48:51 deraadt Exp $ */
/*-
@@ -60,7 +60,6 @@ static size_t fts_maxarglen(char * const *);
static void fts_padjust(FTS *, FTSENT *);
static int fts_palloc(FTS *, size_t);
static unsigned short fts_stat(FTS *, FTSENT *);
-static int fts_safe_changedir(FTS *, FTSENT *, int, const char *);
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
#ifndef O_DIRECTORY
@@ -74,8 +73,6 @@ static int fts_safe_changedir(FTS *, FTSENT *, int, const char *);
#define ISSET(opt) (sp->fts_options & (opt))
#define SET(opt) (sp->fts_options |= (opt))
-#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
-
FTS *
fts_open(char * const *argv, int options, void *dummy)
{
@@ -146,17 +143,6 @@ fts_open(char * const *argv, int options, void *dummy)
sp->fts_cur->fts_link = root;
sp->fts_cur->fts_info = FTS_INIT;
- /*
- * If using chdir(2), grab a file descriptor pointing to dot to ensure
- * that we can get back here; this could be avoided for some paths,
- * but almost certainly not worth the effort. Slashes, symbolic links,
- * and ".." are all fairly nasty problems. Note, if we can't get the
- * descriptor we run anyway, just more slowly.
- */
- if (!ISSET(FTS_NOCHDIR) &&
- (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0)
- SET(FTS_NOCHDIR);
-
if (nitems == 0)
free(parent);
@@ -197,7 +183,6 @@ int
fts_close(FTS *sp)
{
FTSENT *freep, *p;
- int rfd, error = 0;
/*
* This still works if we haven't read anything -- the dummy structure
@@ -213,25 +198,13 @@ fts_close(FTS *sp)
free(p);
}
- /* Stash the original directory fd if needed. */
- rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd;
-
/* Free up child linked list, sort array, path buffer, stream ptr.*/
if (sp->fts_child)
fts_lfree(sp->fts_child);
free(sp->fts_path);
free(sp);
- /* Return to original directory, checking for error. */
- if (rfd != -1) {
- int saved_errno;
- error = fchdir(rfd);
- saved_errno = errno;
- (void)close(rfd);
- errno = saved_errno;
- }
-
- return (error);
+ return (0);
}
/*
@@ -274,25 +247,11 @@ fts_read(FTS *sp)
}
/*
- * Cd to the subdirectory.
- *
- * If have already read and now fail to chdir, whack the list
- * to make the names come out right, and set the parent errno
- * so the application will eventually get an error condition.
- * Set the FTS_DONTCHDIR flag so that when we logically change
- * directories back to the parent we don't do a chdir.
- *
* If haven't read do so. If the read fails, fts_build sets
* FTS_STOP or the fts_info field of the node.
*/
if (sp->fts_child) {
- if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
- p->fts_errno = errno;
- p->fts_flags |= FTS_DONTCHDIR;
- for (p = sp->fts_child; p; p = p->fts_link)
- p->fts_accpath =
- p->fts_parent->fts_accpath;
- }
+ /* nothing */
} else if ((sp->fts_child = fts_build(sp)) == NULL) {
if (ISSET(FTS_STOP))
return (NULL);
@@ -313,10 +272,6 @@ next: tmp = p;
* the root of the tree), and load the paths for the next root.
*/
if (p->fts_level == FTS_ROOTLEVEL) {
- if (FCHDIR(sp, sp->fts_rfd)) {
- SET(FTS_STOP);
- return (NULL);
- }
fts_load(sp, p);
return (sp->fts_cur = p);
}
@@ -352,23 +307,6 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
/* NUL terminate the pathname. */
sp->fts_path[p->fts_pathlen] = '\0';
- /*
- * Return to the parent directory. If at a root node or came through
- * a symlink, go back through the file descriptor. Otherwise, cd up
- * one directory.
- */
- if (p->fts_level == FTS_ROOTLEVEL) {
- if (FCHDIR(sp, sp->fts_rfd)) {
- SET(FTS_STOP);
- sp->fts_cur = p;
- return (NULL);
- }
- } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
- fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
- SET(FTS_STOP);
- sp->fts_cur = p;
- return (NULL);
- }
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
return (sp->fts_cur = p);
}
@@ -414,7 +352,7 @@ fts_build(FTS *sp)
DIR *dirp;
void *oldaddr;
size_t dlen, len, maxlen;
- int nitems, cderrno, descend, level, doadjust;
+ int nitems, level, doadjust;
int saved_errno;
char *cp;
@@ -432,32 +370,6 @@ fts_build(FTS *sp)
}
/*
- * If we're going to need to stat anything or we want to descend
- * and stay in the directory, chdir. If this fails we keep going,
- * but set a flag so we don't chdir after the post-order visit.
- * We won't be able to stat anything, but we can still return the
- * names themselves. Note, that since fts_read won't be able to
- * chdir into the directory, it will have to return different path
- * names than before, i.e. "a/b" instead of "b". Since the node
- * has already been visited in pre-order, have to wait until the
- * post-order visit to return the error. There is a special case
- * here, if there was nothing to stat then it's not an error to
- * not be able to stat. This is all fairly nasty. If a program
- * needed sorted entries or stat information, they had better be
- * checking FTS_NS on the returned nodes.
- */
- cderrno = 0;
- if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
- cur->fts_errno = errno;
- cur->fts_flags |= FTS_DONTCHDIR;
- descend = 0;
- cderrno = errno;
- (void)closedir(dirp);
- dirp = NULL;
- } else
- descend = 1;
-
- /*
* Figure out the max file name length that can be stored in the
* current path -- the inner loop allocates more path as necessary.
* We really wouldn't have to do the maxlen calculations here, we
@@ -468,10 +380,8 @@ fts_build(FTS *sp)
* each new name into the path.
*/
len = NAPPEND(cur);
- if (ISSET(FTS_NOCHDIR)) {
- cp = sp->fts_path + len;
- *cp++ = '/';
- }
+ cp = sp->fts_path + len;
+ *cp++ = '/';
len++;
maxlen = sp->fts_pathlen - len;
@@ -518,8 +428,7 @@ mem1: saved_errno = errno;
/* Did realloc() change the pointer? */
if (oldaddr != sp->fts_path) {
doadjust = 1;
- if (ISSET(FTS_NOCHDIR))
- cp = sp->fts_path + len;
+ cp = sp->fts_path + len;
}
maxlen = sp->fts_pathlen - len;
}
@@ -542,20 +451,11 @@ mem1: saved_errno = errno;
return (NULL);
}
- if (cderrno) {
- p->fts_info = FTS_NS;
- p->fts_errno = cderrno;
- p->fts_accpath = cur->fts_accpath;
- } else {
- /* Build a file name for fts_stat to stat. */
- if (ISSET(FTS_NOCHDIR)) {
- p->fts_accpath = p->fts_path;
- memmove(cp, p->fts_name, p->fts_namelen + 1);
- } else
- p->fts_accpath = p->fts_name;
- /* Stat it. */
- p->fts_info = fts_stat(sp, p);
- }
+ /* Build a file name for fts_stat to stat. */
+ p->fts_accpath = p->fts_path;
+ memmove(cp, p->fts_name, p->fts_namelen + 1);
+ /* Stat it. */
+ p->fts_info = fts_stat(sp, p);
/* We walk in directory order so "ls -f" doesn't get upset. */
p->fts_link = NULL;
@@ -581,26 +481,9 @@ mem1: saved_errno = errno;
* If not changing directories, reset the path back to original
* state.
*/
- if (ISSET(FTS_NOCHDIR)) {
- if (len == sp->fts_pathlen || nitems == 0)
- --cp;
- *cp = '\0';
- }
-
- /*
- * If descended after called from fts_children or after called from
- * fts_read and nothing found, get back. At the root level we use
- * the saved fd; if one of fts_open()'s arguments is a relative path
- * to an empty directory, we wind up here with no other way back. If
- * can't get back, we're done.
- */
- if (descend && !nitems &&
- (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) :
- fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
- cur->fts_info = FTS_ERR;
- SET(FTS_STOP);
- return (NULL);
- }
+ if (len == sp->fts_pathlen || nitems == 0)
+ --cp;
+ *cp = '\0';
/* If didn't find anything, return NULL. */
if (!nitems) {
@@ -771,38 +654,4 @@ fts_maxarglen(char * const *argv)
return (max + 1);
}
-/*
- * Change to dir specified by fd or p->fts_accpath without getting
- * tricked by someone changing the world out from underneath us.
- * Assumes p->fts_dev and p->fts_ino are filled in.
- */
-static int
-fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
-{
- int ret, oerrno, newfd;
- struct stat sb;
-
- newfd = fd;
- if (ISSET(FTS_NOCHDIR))
- return (0);
- if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
- return (-1);
- if (fstat(newfd, &sb)) {
- ret = -1;
- goto bail;
- }
- if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
- errno = ENOENT; /* disinformation */
- ret = -1;
- goto bail;
- }
- ret = fchdir(newfd);
-bail:
- oerrno = errno;
- if (fd < 0)
- (void)close(newfd);
- errno = oerrno;
- return (ret);
-}
-
#endif
diff --git a/compat_fts.h b/compat_fts.h
index ce7ee6287055..1eed2ae380fd 100644
--- a/compat_fts.h
+++ b/compat_fts.h
@@ -40,13 +40,12 @@ typedef struct {
struct _ftsent *fts_child; /* linked list of children */
dev_t fts_dev; /* starting device # */
char *fts_path; /* path for this descent */
- int fts_rfd; /* fd for root */
size_t fts_pathlen; /* sizeof(path) */
#define FTS_NOCHDIR 0x0004 /* don't change directories */
#define FTS_PHYSICAL 0x0010 /* physical walk */
#define FTS_XDEV 0x0040 /* don't cross devices */
-#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
+#define FTS_OPTIONMASK 0x0054 /* valid user option mask */
#define FTS_STOP 0x2000 /* (private) unrecoverable error */
int fts_options; /* fts_open options, global flags */
@@ -85,9 +84,6 @@ typedef struct _ftsent {
#define FTS_SL 12 /* symbolic link */
unsigned short fts_info; /* user flags for FTSENT structure */
-#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
- unsigned short fts_flags; /* private flags for FTSENT structure */
-
#define FTS_NOINSTR 3 /* no instructions */
#define FTS_SKIP 4 /* discard node */
unsigned short fts_instr; /* fts_set() instructions */
@@ -96,11 +92,10 @@ typedef struct _ftsent {
char fts_name[1]; /* file name */
} FTSENT;
-__BEGIN_DECLS
+
int fts_close(FTS *);
FTS *fts_open(char * const *, int, void *);
FTSENT *fts_read(FTS *);
int fts_set(FTS *, FTSENT *, int);
-__END_DECLS
#endif /* !_FTS_H_ */
diff --git a/compat_getline.c b/compat_getline.c
new file mode 100644
index 000000000000..aed4754ffdae
--- /dev/null
+++ b/compat_getline.c
@@ -0,0 +1,68 @@
+#include "config.h"
+
+#if HAVE_GETLINE
+
+int dummy;
+
+#else
+
+/* $Id: compat_getline.c,v 1.1 2015/11/07 20:52:52 schwarze Exp $ */
+/*
+ * Copyright (c) 2015 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ssize_t
+getline(char **buf, size_t *bufsz, FILE *fp)
+{
+ char *nbuf;
+ size_t nbufsz, pos;
+ int c;
+
+ if (buf == NULL || bufsz == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*buf == NULL)
+ *bufsz = 0;
+ else
+ **buf = '\0';
+
+ pos = 0;
+ for (;;) {
+ if (pos + 1 >= *bufsz) {
+ nbufsz = *bufsz ? *bufsz * 2 : BUFSIZ;
+ if ((nbuf = realloc(*buf, nbufsz)) == NULL)
+ return -1;
+ *buf = nbuf;
+ *bufsz = nbufsz;
+ }
+ if ((c = fgetc(fp)) == EOF) {
+ (*buf)[pos] = '\0';
+ return pos > 0 && feof(fp) ? (ssize_t)pos : -1;
+ }
+ (*buf)[pos++] = c;
+ (*buf)[pos] = '\0';
+ if (c == '\n')
+ return pos;
+ }
+}
+
+#endif
diff --git a/compat_isblank.c b/compat_isblank.c
new file mode 100644
index 000000000000..9e3c74706c3d
--- /dev/null
+++ b/compat_isblank.c
@@ -0,0 +1,33 @@
+#include "config.h"
+
+#if HAVE_ISBLANK
+
+int dummy;
+
+#else
+
+/* $Id: compat_isblank.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */
+/*
+ * Copyright (c) 2015 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.
+ */
+
+int
+isblank(int c)
+{
+
+ return c == ' ' || c == '\t';
+}
+
+#endif
diff --git a/compat_mkdtemp.c b/compat_mkdtemp.c
new file mode 100644
index 000000000000..1fcb325f4f9a
--- /dev/null
+++ b/compat_mkdtemp.c
@@ -0,0 +1,61 @@
+#include "config.h"
+
+#if HAVE_MKDTEMP
+
+int dummy;
+
+#else
+
+/* $Id: compat_mkdtemp.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */
+/*
+ * Copyright (c) 2015 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.
+ *
+ * The algorithm of this function is inspired by OpenBSD mkdtemp(3)
+ * by Theo de Raadt and Todd Miller, but the code differs.
+ */
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+mkdtemp(char *path)
+{
+ char *start, *cp;
+ unsigned int tries;
+
+ start = strchr(path, '\0');
+ while (start > path && start[-1] == 'X')
+ start--;
+
+ for (tries = INT_MAX; tries; tries--) {
+ if (mktemp(path) == NULL) {
+ errno = EEXIST;
+ return NULL;
+ }
+ if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0)
+ return path;
+ if (errno != EEXIST)
+ return NULL;
+ for (cp = start; *cp != '\0'; cp++)
+ *cp = 'X';
+ }
+ errno = EEXIST;
+ return NULL;
+}
+
+#endif
diff --git a/compat_ohash.h b/compat_ohash.h
index e3124c96b124..58fb220c96c0 100644
--- a/compat_ohash.h
+++ b/compat_ohash.h
@@ -49,7 +49,6 @@ struct ohash {
* a hashing table index (opaque) to be used in find/insert/remove.
* The keys are stored at a known position in the client data.
*/
-__BEGIN_DECLS
void ohash_init(struct ohash *, unsigned, struct ohash_info *);
void ohash_delete(struct ohash *);
@@ -69,5 +68,5 @@ uint32_t ohash_interval(const char *, const char **);
unsigned int ohash_qlookupi(struct ohash *, const char *, const char **);
unsigned int ohash_qlookup(struct ohash *, const char *);
-__END_DECLS
+
#endif
diff --git a/compat_progname.c b/compat_progname.c
new file mode 100644
index 000000000000..9840cc7c6c61
--- /dev/null
+++ b/compat_progname.c
@@ -0,0 +1,42 @@
+#include "config.h"
+
+#if HAVE_PROGNAME
+
+int dummy;
+
+#else
+
+/* $Id: compat_progname.c,v 1.1 2015/11/06 16:30:33 schwarze Exp $ */
+/*
+ * Copyright (c) 2015 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.
+ */
+
+static const char *progname;
+
+void
+setprogname(const char *name)
+{
+
+ progname = name;
+}
+
+const char *
+getprogname(void)
+{
+
+ return progname;
+}
+
+#endif
diff --git a/compat_sqlite3_errstr.c b/compat_sqlite3_errstr.c
index c62384887a68..8a6ace28e8cd 100644
--- a/compat_sqlite3_errstr.c
+++ b/compat_sqlite3_errstr.c
@@ -10,7 +10,7 @@ const char *
sqlite3_errstr(int rc)
{
- return(rc ? "unknown error" : "not an error");
+ return rc ? "unknown error" : "not an error";
}
#endif
diff --git a/compat_stringlist.c b/compat_stringlist.c
new file mode 100644
index 000000000000..17eba7724af5
--- /dev/null
+++ b/compat_stringlist.c
@@ -0,0 +1,119 @@
+#include "config.h"
+
+#if HAVE_STRINGLIST
+
+int dummy;
+
+#else
+
+/* $Id: compat_stringlist.c,v 1.6 2015/11/07 14:22:29 schwarze Exp $ */
+/*
+ * Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if HAVE_ERR
+#include <err.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include "compat_stringlist.h"
+
+#define _SL_CHUNKSIZE 20
+
+/*
+ * sl_init(): Initialize a string list
+ */
+StringList *
+sl_init(void)
+{
+ StringList *sl;
+
+ sl = malloc(sizeof(StringList));
+ if (sl == NULL)
+ err(1, "stringlist");
+
+ sl->sl_cur = 0;
+ sl->sl_max = _SL_CHUNKSIZE;
+ sl->sl_str = reallocarray(NULL, sl->sl_max, sizeof(char *));
+ if (sl->sl_str == NULL)
+ err(1, "stringlist");
+ return sl;
+}
+
+
+/*
+ * sl_add(): Add an item to the string list
+ */
+int
+sl_add(StringList *sl, char *name)
+{
+ if (sl->sl_cur == sl->sl_max - 1) {
+ sl->sl_max += _SL_CHUNKSIZE;
+ sl->sl_str = reallocarray(sl->sl_str,
+ sl->sl_max, sizeof(char *));
+ if (sl->sl_str == NULL)
+ return (-1);
+ }
+ sl->sl_str[sl->sl_cur++] = name;
+ return (0);
+}
+
+
+/*
+ * sl_free(): Free a stringlist
+ */
+void
+sl_free(StringList *sl, int all)
+{
+ size_t i;
+
+ if (sl == NULL)
+ return;
+ if (sl->sl_str) {
+ if (all)
+ for (i = 0; i < sl->sl_cur; i++)
+ free(sl->sl_str[i]);
+ free(sl->sl_str);
+ }
+ free(sl);
+}
+
+
+/*
+ * sl_find(): Find a name in the string list
+ */
+char *
+sl_find(StringList *sl, const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < sl->sl_cur; i++)
+ if (strcmp(sl->sl_str[i], name) == 0)
+ return sl->sl_str[i];
+
+ return NULL;
+}
+
+#endif
diff --git a/compat_stringlist.h b/compat_stringlist.h
new file mode 100644
index 000000000000..f04e8435047d
--- /dev/null
+++ b/compat_stringlist.h
@@ -0,0 +1,45 @@
+/* $Id: compat_stringlist.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */
+/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */
+
+/*
+ * Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+
+/*
+ * Simple string list
+ */
+typedef struct _stringlist {
+ char **sl_str;
+ size_t sl_max;
+ size_t sl_cur;
+} StringList;
+
+
+StringList *sl_init(void);
+int sl_add(StringList *, char *);
+void sl_free(StringList *, int);
+char *sl_find(StringList *, const char *);
diff --git a/compat_vasprintf.c b/compat_vasprintf.c
new file mode 100644
index 000000000000..9040822b0097
--- /dev/null
+++ b/compat_vasprintf.c
@@ -0,0 +1,56 @@
+#include "config.h"
+
+#if HAVE_VASPRINTF
+
+int dummy;
+
+#else
+
+/* $Id: compat_vasprintf.c,v 1.3 2015/10/06 18:32:19 schwarze Exp $ */
+/*
+ * Copyright (c) 2015 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.
+ *
+ * This fallback implementation is not efficient:
+ * It does the formatting twice.
+ * Short of fiddling with the unknown internals of the system's
+ * printf(3) or completely reimplementing printf(3), i can't think
+ * of another portable solution.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+vasprintf(char **ret, const char *format, va_list ap)
+{
+ char buf[2];
+ va_list ap2;
+ int sz;
+
+ va_copy(ap2, ap);
+ sz = vsnprintf(buf, sizeof(buf), format, ap2);
+ va_end(ap2);
+
+ if (sz != -1 && (*ret = malloc(sz + 1)) != NULL) {
+ if (vsnprintf(*ret, sz + 1, format, ap) == sz)
+ return sz;
+ free(*ret);
+ }
+ *ret = NULL;
+ return -1;
+}
+
+#endif
diff --git a/config.h b/config.h
new file mode 100644
index 000000000000..5ab2d5edbd16
--- /dev/null
+++ b/config.h
@@ -0,0 +1,53 @@
+#ifdef __cplusplus
+#error "Do not use C++. See the INSTALL file."
+#endif
+
+#ifndef MANDOC_CONFIG_H
+#define MANDOC_CONFIG_H
+
+#if defined(__linux__) || defined(__MINT__)
+#define _GNU_SOURCE /* See test-*.c what needs this. */
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#define MAN_CONF_FILE "/etc/man.conf"
+#define MANPATH_DEFAULT "/usr/share/man:/usr/X11R6/man:/usr/local/man"
+#define HAVE_DIRENT_NAMLEN 1
+#define HAVE_ERR 1
+#define HAVE_FTS 1
+#define HAVE_GETLINE 0
+#define HAVE_GETSUBOPT 1
+#define HAVE_ISBLANK 1
+#define HAVE_MKDTEMP 1
+#define HAVE_MMAP 1
+#define HAVE_PLEDGE 0
+#define HAVE_PROGNAME 1
+#define HAVE_REALLOCARRAY 1
+#define HAVE_REWB_BSD 0
+#define HAVE_REWB_SYSV 0
+#define HAVE_STRCASESTR 1
+#define HAVE_STRINGLIST 0
+#define HAVE_STRLCAT 1
+#define HAVE_STRLCPY 1
+#define HAVE_STRPTIME 1
+#define HAVE_STRSEP 1
+#define HAVE_STRTONUM 1
+#define HAVE_VASPRINTF 1
+#define HAVE_WCHAR 1
+#define HAVE_SQLITE3 1
+#define HAVE_SQLITE3_ERRSTR 0
+#define HAVE_OHASH 0
+#define HAVE_MANPATH 1
+
+#define BINM_APROPOS "apropos"
+#define BINM_MAKEWHATIS "makewhatis"
+#define BINM_MAN "man"
+#define BINM_SOELIM "soelim"
+#define BINM_WHATIS "whatis"
+
+extern ssize_t getline(char **, size_t *, FILE *);
+extern const char *sqlite3_errstr(int);
+
+#endif /* MANDOC_CONFIG_H */
diff --git a/config.log b/config.log
new file mode 100644
index 000000000000..1f7e11600d30
--- /dev/null
+++ b/config.log
@@ -0,0 +1,210 @@
+configure.local: no (fully automatic configuration)
+
+dirent-namlen: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-dirent-namlen test-dirent-namlen.c
+dirent-namlen: cc succeeded
+dirent-namlen: yes
+
+err: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-err test-err.c
+err: cc succeeded
+test-err: 1. warnx
+test-err: 2. warn: No error: 0
+test-err: 3. err: No error: 0
+err: yes
+
+fts: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-fts test-fts.c
+fts: cc succeeded
+fts: yes
+
+getline: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-getline test-getline.c
+test-getline.c:12:9: error: implicit declaration of function 'getline' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
+ return getline(&line, &linesz, stdin) != -1;
+ ^
+1 error generated.
+getline: cc failed with 1
+
+getsubopt: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-getsubopt test-getsubopt.c
+getsubopt: cc succeeded
+getsubopt: yes
+
+isblank: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-isblank test-isblank.c
+isblank: cc succeeded
+isblank: yes
+
+mkdtemp: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-mkdtemp test-mkdtemp.c
+mkdtemp: cc succeeded
+mkdtemp: yes
+
+mmap: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-mmap test-mmap.c
+mmap: cc succeeded
+mmap: yes
+
+pledge: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-pledge test-pledge.c
+test-pledge.c:6:11: error: implicit declaration of function 'pledge' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
+ return !!pledge("stdio", NULL);
+ ^
+1 error generated.
+pledge: cc failed with 1
+
+progname: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-progname test-progname.c
+progname: cc succeeded
+progname: yes
+
+reallocarray: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-reallocarray test-reallocarray.c
+reallocarray: cc succeeded
+reallocarray: yes
+
+rewb-bsd: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-rewb-bsd test-rewb-bsd.c
+test-rewb-bsd.c:11:42: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "the word is here", 0, NULL, 0))
+ ^
+test-rewb-bsd.c:13:35: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "same word", 0, NULL, 0))
+ ^
+test-rewb-bsd.c:15:36: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "word again", 0, NULL, 0))
+ ^
+test-rewb-bsd.c:17:30: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "word", 0, NULL, 0))
+ ^
+test-rewb-bsd.c:19:31: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH)
+ ^
+test-rewb-bsd.c:21:31: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH)
+ ^
+test-rewb-bsd.c:23:34: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH)
+ ^
+7 errors generated.
+rewb-bsd: cc failed with 1
+
+rewb-sysv: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-rewb-sysv test-rewb-sysv.c
+test-rewb-sysv.c:11:42: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "the word is here", 0, NULL, 0))
+ ^
+test-rewb-sysv.c:13:35: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "same word", 0, NULL, 0))
+ ^
+test-rewb-sysv.c:15:36: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "word again", 0, NULL, 0))
+ ^
+test-rewb-sysv.c:17:30: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "word", 0, NULL, 0))
+ ^
+test-rewb-sysv.c:19:31: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH)
+ ^
+test-rewb-sysv.c:21:31: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH)
+ ^
+test-rewb-sysv.c:23:34: error: use of undeclared identifier 'NULL'
+ if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH)
+ ^
+7 errors generated.
+rewb-sysv: cc failed with 1
+
+strcasestr: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strcasestr test-strcasestr.c
+strcasestr: cc succeeded
+strcasestr: yes
+
+stringlist: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-stringlist test-stringlist.c
+test-stringlist.c:26:26: error: use of undeclared identifier 'NULL'
+ if ((sl = sl_init()) == NULL)
+ ^
+1 error generated.
+stringlist: cc failed with 1
+
+strlcat: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strlcat test-strlcat.c
+strlcat: cc succeeded
+strlcat: yes
+
+strlcpy: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strlcpy test-strlcpy.c
+strlcpy: cc succeeded
+strlcpy: yes
+
+strptime: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strptime test-strptime.c
+strptime: cc succeeded
+strptime: yes
+
+strsep: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strsep test-strsep.c
+strsep: cc succeeded
+strsep: yes
+
+strtonum: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strtonum test-strtonum.c
+strtonum: cc succeeded
+strtonum: yes
+
+vasprintf: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-vasprintf test-vasprintf.c
+vasprintf: cc succeeded
+vasprintf: yes
+
+wchar: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-wchar test-wchar.c
+wchar: cc succeeded
+*wchar: yes
+
+sqlite3: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -lsqlite3 -o test-sqlite3 test-sqlite3.c
+test-sqlite3.c:20:10: fatal error: 'sqlite3.h' file not found
+#include <sqlite3.h>
+ ^
+1 error generated.
+sqlite3: cc failed with 1
+
+sqlite3: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -I/usr/local/include -L/usr/local/lib -lsqlite3 -o test-sqlite3 test-sqlite3.c
+sqlite3: cc succeeded
+sqlite3: yes
+
+sqlite3_errstr: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -L/usr/local/lib -lsqlite3 -o test-sqlite3_errstr test-sqlite3_errstr.c
+test-sqlite3_errstr.c:2:10: fatal error: 'sqlite3.h' file not found
+#include <sqlite3.h>
+ ^
+1 error generated.
+sqlite3_errstr: cc failed with 1
+
+ohash: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-ohash test-ohash.c
+test-ohash.c:4:10: fatal error: 'ohash.h' file not found
+#include <ohash.h>
+ ^
+1 error generated.
+ohash: cc failed with 1
+
+ohash: testing...
+cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -lutil -o test-ohash test-ohash.c
+test-ohash.c:4:10: fatal error: 'ohash.h' file not found
+#include <ohash.h>
+ ^
+1 error generated.
+ohash: cc failed with 1
+
+DBLIB="-L/usr/local/lib -lsqlite3 -lz"
+
+/usr/share/man:/usr/local/man:/usr/share/openssl/man:/usr/local/lib/perl5/site_perl/man:/usr/local/lib/perl5/5.20/perl/man:/usr/local/share/xpdf/man
+manpath: yes
+
+config.h: written
+Makefile.local: written
diff --git a/configure b/configure
index fb2dabc9f5d0..21997fcc2083 100755
--- a/configure
+++ b/configure
@@ -16,8 +16,8 @@
set -e
-[ -e config.log ] && mv config.log config.log.old
-[ -e config.h ] && mv config.h config.h.old
+[ -w config.log ] && mv config.log config.log.old
+[ -w config.h ] && mv config.h config.h.old
# Output file descriptor usage:
# 1 (stdout): config.h, Makefile.local
@@ -31,6 +31,7 @@ echo "config.log: writing..."
# Initialize all variables here,
# such that nothing can leak in from the environment.
+MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
OSNAME=
CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make -f -`
@@ -42,17 +43,26 @@ BUILD_DB=1
BUILD_CGI=0
HAVE_DIRENT_NAMLEN=
-HAVE_FGETLN=
+HAVE_ERR=
HAVE_FTS=
+HAVE_GETLINE=
HAVE_GETSUBOPT=
+HAVE_ISBLANK=
+HAVE_MKDTEMP=
HAVE_MMAP=
+HAVE_PLEDGE=
+HAVE_PROGNAME=
HAVE_REALLOCARRAY=
+HAVE_REWB_BSD=
+HAVE_REWB_SYSV=
HAVE_STRCASESTR=
+HAVE_STRINGLIST=
HAVE_STRLCAT=
HAVE_STRLCPY=
HAVE_STRPTIME=
HAVE_STRSEP=
HAVE_STRTONUM=
+HAVE_VASPRINTF=
HAVE_WCHAR=
HAVE_SQLITE3=
@@ -66,7 +76,6 @@ SBINDIR=
INCLUDEDIR=
LIBDIR=
MANDIR=
-EXAMPLEDIR=
HOMEBREWDIR=
WWWPREFIX="/var/www"
@@ -74,10 +83,12 @@ HTDOCDIR=
CGIBINDIR=
BINM_APROPOS="apropos"
+BINM_MAKEWHATIS="makewhatis"
BINM_MAN="man"
+BINM_SOELIM="soelim"
BINM_WHATIS="whatis"
-BINM_MAKEWHATIS="makewhatis"
MANM_MAN="man"
+MANM_MANCONF="man.conf"
MANM_MDOC="mdoc"
MANM_ROFF="roff"
MANM_EQN="eqn"
@@ -91,7 +102,7 @@ INSTALL_DATA=
# --- manual settings from configure.local -----------------------------
-if [ -e ./configure.local ]; then
+if [ -r ./configure.local ]; then
echo "configure.local: reading..." 1>&2
echo "configure.local: reading..." 1>&3
cat ./configure.local 1>&3
@@ -164,17 +175,26 @@ runtest() {
# --- library functions ---
runtest dirent-namlen DIRENT_NAMLEN || true
-runtest fgetln FGETLN || true
+runtest err ERR || true
runtest fts FTS || true
+runtest getline GETLINE || true
runtest getsubopt GETSUBOPT || true
+runtest isblank ISBLANK || true
+runtest mkdtemp MKDTEMP || true
runtest mmap MMAP || true
+runtest pledge PLEDGE || true
+runtest progname PROGNAME || true
runtest reallocarray REALLOCARRAY || true
+runtest rewb-bsd REWB_BSD || true
+runtest rewb-sysv REWB_SYSV || true
runtest strcasestr STRCASESTR || true
+runtest stringlist STRINGLIST || true
runtest strlcat STRLCAT || true
runtest strlcpy STRLCPY || true
runtest strptime STRPTIME || true
runtest strsep STRSEP || true
runtest strtonum STRTONUM || true
+runtest vasprintf VASPRINTF || true
runtest wchar WCHAR || true
# --- sqlite3 ---
@@ -228,9 +248,9 @@ fi
# --- DBLIB ---
if [ ${BUILD_DB} -eq 0 ]; then
- DBLIB=
+ DBLIB="-lz"
elif [ -z "${DBLIB}" ]; then
- DBLIB="${DETECTLIB}"
+ DBLIB="${DETECTLIB} -lz"
echo "DBLIB=\"${DBLIB}\"" 1>&2
echo "DBLIB=\"${DBLIB}\"" 1>&3
echo 1>&3
@@ -256,6 +276,10 @@ fi
exec > config.h
cat << __HEREDOC__
+#ifdef __cplusplus
+#error "Do not use C++. See the INSTALL file."
+#endif
+
#ifndef MANDOC_CONFIG_H
#define MANDOC_CONFIG_H
@@ -265,28 +289,40 @@ cat << __HEREDOC__
__HEREDOC__
-[ ${HAVE_FGETLN} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \
+[ ${HAVE_GETLINE} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \
${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \
&& echo "#include <sys/types.h>"
-[ ${HAVE_FGETLN} -eq 0 ] && echo "#include <stdio.h>"
+[ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>"
+[ ${HAVE_GETLINE} -eq 0 ] && echo "#include <stdio.h>"
echo
+echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\""
+echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
[ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\""
cat << __HEREDOC__
#define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN}
-#define HAVE_FGETLN ${HAVE_FGETLN}
+#define HAVE_ERR ${HAVE_ERR}
#define HAVE_FTS ${HAVE_FTS}
+#define HAVE_GETLINE ${HAVE_GETLINE}
#define HAVE_GETSUBOPT ${HAVE_GETSUBOPT}
+#define HAVE_ISBLANK ${HAVE_ISBLANK}
+#define HAVE_MKDTEMP ${HAVE_MKDTEMP}
#define HAVE_MMAP ${HAVE_MMAP}
+#define HAVE_PLEDGE ${HAVE_PLEDGE}
+#define HAVE_PROGNAME ${HAVE_PROGNAME}
#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY}
+#define HAVE_REWB_BSD ${HAVE_REWB_BSD}
+#define HAVE_REWB_SYSV ${HAVE_REWB_SYSV}
#define HAVE_STRCASESTR ${HAVE_STRCASESTR}
+#define HAVE_STRINGLIST ${HAVE_STRINGLIST}
#define HAVE_STRLCAT ${HAVE_STRLCAT}
#define HAVE_STRLCPY ${HAVE_STRLCPY}
#define HAVE_STRPTIME ${HAVE_STRPTIME}
#define HAVE_STRSEP ${HAVE_STRSEP}
#define HAVE_STRTONUM ${HAVE_STRTONUM}
+#define HAVE_VASPRINTF ${HAVE_VASPRINTF}
#define HAVE_WCHAR ${HAVE_WCHAR}
#define HAVE_SQLITE3 ${HAVE_SQLITE3}
#define HAVE_SQLITE3_ERRSTR ${HAVE_SQLITE3_ERRSTR}
@@ -294,33 +330,37 @@ cat << __HEREDOC__
#define HAVE_MANPATH ${HAVE_MANPATH}
#define BINM_APROPOS "${BINM_APROPOS}"
+#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}"
#define BINM_MAN "${BINM_MAN}"
+#define BINM_SOELIM "${BINM_SOELIM}"
#define BINM_WHATIS "${BINM_WHATIS}"
-#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}"
-
-#if !defined(__BEGIN_DECLS)
-# ifdef __cplusplus
-# define __BEGIN_DECLS extern "C" {
-# else
-# define __BEGIN_DECLS
-# endif
-#endif
-#if !defined(__END_DECLS)
-# ifdef __cplusplus
-# define __END_DECLS }
-# else
-# define __END_DECLS
-# endif
-#endif
__HEREDOC__
-[ ${HAVE_FGETLN} -eq 0 ] && \
- echo "extern char *fgetln(FILE *, size_t *);"
+if [ ${HAVE_ERR} -eq 0 ]; then
+ echo "extern void err(int, const char *, ...);"
+ echo "extern void errx(int, const char *, ...);"
+ echo "extern void warn(const char *, ...);"
+ echo "extern void warnx(const char *, ...);"
+fi
+
+[ ${HAVE_GETLINE} -eq 0 ] && \
+ echo "extern ssize_t getline(char **, size_t *, FILE *);"
[ ${HAVE_GETSUBOPT} -eq 0 ] && \
echo "extern int getsubopt(char **, char * const *, char **);"
+[ ${HAVE_ISBLANK} -eq 0 ] && \
+ echo "extern int isblank(int);"
+
+[ ${HAVE_MKDTEMP} -eq 0 ] && \
+ echo "extern char *mkdtemp(char *);"
+
+if [ ${HAVE_PROGNAME} -eq 0 ]; then
+ echo "extern const char *getprogname(void);"
+ echo "extern void setprogname(const char *);"
+fi
+
[ ${HAVE_REALLOCARRAY} -eq 0 ] && \
echo "extern void *reallocarray(void *, size_t, size_t);"
@@ -342,6 +382,9 @@ __HEREDOC__
[ ${HAVE_STRTONUM} -eq 0 ] && \
echo "extern long long strtonum(const char *, long long, long long, const char **);"
+[ ${HAVE_VASPRINTF} -eq 0 ] && \
+ echo "extern int vasprintf(char **, const char *, va_list);"
+
echo
echo "#endif /* MANDOC_CONFIG_H */"
@@ -357,7 +400,6 @@ exec > Makefile.local
[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include/mandoc"
[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib/mandoc"
[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"
-[ -z "${EXAMPLEDIR}" ] && EXAMPLEDIR="${PREFIX}/share/examples/mandoc"
[ -z "${HTDOCDIR}" ] && HTDOCDIR="${WWWPREFIX}/htdocs"
[ -z "${CGIBINDIR}" ] && CGIBINDIR="${WWWPREFIX}/cgi-bin"
@@ -382,6 +424,7 @@ INSTALL_TARGETS="base-install"
cat << __HEREDOC__
BUILD_TARGETS = ${BUILD_TARGETS}
INSTALL_TARGETS = ${INSTALL_TARGETS}
+CC = ${CC}
CFLAGS = ${CFLAGS}
DBLIB = ${DBLIB}
STATIC = ${STATIC}
@@ -391,15 +434,16 @@ SBINDIR = ${SBINDIR}
INCLUDEDIR = ${INCLUDEDIR}
LIBDIR = ${LIBDIR}
MANDIR = ${MANDIR}
-EXAMPLEDIR = ${EXAMPLEDIR}
WWWPREFIX = ${WWWPREFIX}
HTDOCDIR = ${HTDOCDIR}
CGIBINDIR = ${CGIBINDIR}
BINM_APROPOS = ${BINM_APROPOS}
+BINM_MAKEWHATIS = ${BINM_MAKEWHATIS}
BINM_MAN = ${BINM_MAN}
+BINM_SOELIM = ${BINM_SOELIM}
BINM_WHATIS = ${BINM_WHATIS}
-BINM_MAKEWHATIS = ${BINM_MAKEWHATIS}
MANM_MAN = ${MANM_MAN}
+MANM_MANCONF = ${MANM_MANCONF}
MANM_MDOC = ${MANM_MDOC}
MANM_ROFF = ${MANM_ROFF}
MANM_EQN = ${MANM_EQN}
diff --git a/configure.local.example b/configure.local.example
index bb391591cf5d..de9f08f1410c 100644
--- a/configure.local.example
+++ b/configure.local.example
@@ -1,4 +1,4 @@
-# $Id: configure.local.example,v 1.6 2015/02/16 14:56:22 schwarze Exp $
+# $Id: configure.local.example,v 1.10 2015/11/07 13:14:21 schwarze Exp $
#
# Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
#
@@ -48,6 +48,13 @@ HAVE_WCHAR=1
HAVE_WCHAR=0
+# When man(1) or apropos(1) is called without -m and -M options,
+# MANPATH is not set in the environment, man.conf(5) is not available
+# and manpath(1) not used, manuals are searched for in the following
+# directory trees by default.
+
+MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/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.
@@ -72,7 +79,6 @@ SBINDIR="${PREFIX}/sbin"
INCLUDEDIR="${PREFIX}/include/mandoc"
LIBDIR="${PREFIX}/lib/mandoc"
MANDIR="${PREFIX}/man"
-EXAMPLEDIR="${PREFIX}/share/examples/mandoc"
# The man(1) utility needs to know where the manuals reside.
# We know of two ways to tell it: via manpath(1) or man.conf(5).
@@ -89,6 +95,11 @@ HAVE_MANPATH=1
# man(1), makewhatis(8), and apropos(1) will not work properly.
HAVE_MANPATH=0
+# Some distributions may want to avoid naming conflicts
+# with the configuration files of other man(1) implementations.
+# This changes the name of the installed section 5 manual page as well.
+MANM_MANCONF="mandoc.conf" # default is "man.conf"
+
# Some distributions may want to avoid naming conflicts among manuals.
# If you want to change the names of installed section 7 manual pages,
# the following alternative names are suggested.
@@ -103,13 +114,14 @@ MANM_EQN="mandoc_eqn" # default is "eqn"
MANM_TBL="mandoc_tbl" # default is "tbl"
# Some distributions may want to avoid naming conflicts
-# with another man(1) utility.
-# If you want to change the name of the binary program,
-# the following alternative name is suggested.
-# Using a different name is possible as well.
-# This changes the name of the installed section 1 manual page as well.
+# with other man(1) and soelim(1) utilities.
+# If you want to change the names of binary programs,
+# the following alternative names are suggested.
+# Using different names is possible as well.
+# This changes the names of the installed section 1 manual pages as well.
BINM_MAN=mman # default is "man"
+BINM_SOELIM=msoelim # default is "soelim"
# It is possible to change the utility program used for installation
# and the modes files are installed with. The defaults are:
diff --git a/demandoc.c b/demandoc.c
index f515931d8b91..13b78903da0e 100644
--- a/demandoc.c
+++ b/demandoc.c
@@ -1,4 +1,4 @@
-/* $Id: demandoc.c,v 1.15 2015/02/10 08:05:30 schwarze Exp $ */
+/* $Id: demandoc.c,v 1.26 2016/01/08 02:53:13 schwarze Exp $ */
/*
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -26,14 +26,15 @@
#include <string.h>
#include <unistd.h>
+#include "roff.h"
#include "man.h"
#include "mdoc.h"
#include "mandoc.h"
static void pline(int, int *, int *, int);
-static void pman(const struct man_node *, int *, int *, int);
+static void pman(const struct roff_node *, int *, int *, int);
static void pmandoc(struct mparse *, int, const char *, int);
-static void pmdoc(const struct mdoc_node *, int *, int *, int);
+static void pmdoc(const struct roff_node *, int *, int *, int);
static void pstring(const char *, int, int *, int);
static void usage(void);
@@ -43,7 +44,6 @@ int
main(int argc, char *argv[])
{
struct mparse *mp;
- struct mchars *mchars;
int ch, fd, i, list;
extern int optind;
@@ -72,14 +72,14 @@ main(int argc, char *argv[])
break;
default:
usage();
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
}
argc -= optind;
argv += optind;
- mchars = mchars_alloc();
- mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, NULL);
+ mchars_alloc();
+ mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, NULL);
assert(mp);
if (argc < 1)
@@ -87,7 +87,7 @@ main(int argc, char *argv[])
for (i = 0; i < argc; i++) {
mparse_reset(mp);
- if (mparse_open(mp, &fd, argv[i]) != MANDOCLEVEL_OK) {
+ if ((fd = mparse_open(mp, argv[i])) == -1) {
perror(argv[i]);
continue;
}
@@ -95,8 +95,8 @@ main(int argc, char *argv[])
}
mparse_free(mp);
- mchars_free(mchars);
- return((int)MANDOCLEVEL_OK);
+ mchars_free();
+ return (int)MANDOCLEVEL_OK;
}
static void
@@ -109,21 +109,24 @@ usage(void)
static void
pmandoc(struct mparse *mp, int fd, const char *fn, int list)
{
- struct mdoc *mdoc;
- struct man *man;
+ struct roff_man *man;
int line, col;
mparse_readfd(mp, fd, fn);
- mparse_result(mp, &mdoc, &man, NULL);
+ close(fd);
+ mparse_result(mp, &man, NULL);
line = 1;
col = 0;
- if (mdoc)
- pmdoc(mdoc_node(mdoc), &line, &col, list);
- else if (man)
- pman(man_node(man), &line, &col, list);
- else
+ if (man == NULL)
return;
+ if (man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
+ pmdoc(man->first->child, &line, &col, list);
+ } else {
+ man_validate(man);
+ pman(man->first->child, &line, &col, list);
+ }
if ( ! list)
putchar('\n');
@@ -233,13 +236,13 @@ pline(int line, int *linep, int *col, int list)
}
static void
-pmdoc(const struct mdoc_node *p, int *line, int *col, int list)
+pmdoc(const struct roff_node *p, int *line, int *col, int list)
{
for ( ; p; p = p->next) {
if (MDOC_LINE & p->flags)
pline(p->line, line, col, list);
- if (MDOC_TEXT == p->type)
+ if (ROFFT_TEXT == p->type)
pstring(p->string, p->pos, col, list);
if (p->child)
pmdoc(p->child, line, col, list);
@@ -247,13 +250,13 @@ pmdoc(const struct mdoc_node *p, int *line, int *col, int list)
}
static void
-pman(const struct man_node *p, int *line, int *col, int list)
+pman(const struct roff_node *p, int *line, int *col, int list)
{
for ( ; p; p = p->next) {
if (MAN_LINE & p->flags)
pline(p->line, line, col, list);
- if (MAN_TEXT == p->type)
+ if (ROFFT_TEXT == p->type)
pstring(p->string, p->pos, col, list);
if (p->child)
pman(p->child, line, col, list);
diff --git a/eqn.7 b/eqn.7
index 73c488550a3f..e3aad72e3a91 100644
--- a/eqn.7
+++ b/eqn.7
@@ -1,4 +1,4 @@
-.\" $Id: eqn.7,v 1.34 2015/03/09 20:17:23 schwarze Exp $
+.\" $Id: eqn.7,v 1.35 2015/03/30 16:06:14 schwarze Exp $
.\"
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2014 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: March 9 2015 $
+.Dd $Mdocdate: March 30 2015 $
.Dt EQN 7
.Os
.Sh NAME
@@ -146,7 +146,7 @@ is used as the delimiter for the value
.Ar val .
This allows for arbitrary enclosure of terms (not just quotes), such as
.Pp
-.D1 Cm define Ar foo 'bar baz'
+.D1 Cm define Ar foo \(aqbar baz\(aq
.D1 Cm define Ar foo cbar bazc
.Pp
It is an error to have an empty
@@ -166,8 +166,8 @@ created.
Definitions can create arbitrary strings, for example, the following is
a legal construction.
.Bd -literal -offset indent
-define foo 'define'
-foo bar 'baz'
+define foo \(aqdefine\(aq
+foo bar \(aqbaz\(aq
.Ed
.Pp
Self-referencing definitions will raise an error.
diff --git a/eqn.c b/eqn.c
index 9da57f06e278..e9fbdec086fe 100644
--- a/eqn.c
+++ b/eqn.c
@@ -1,4 +1,4 @@
-/* $Id: eqn.c,v 1.58 2015/03/04 12:19:49 schwarze Exp $ */
+/* $Id: eqn.c,v 1.61 2016/01/08 00:50:45 schwarze Exp $ */
/*
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -302,10 +302,10 @@ eqn_read(struct eqn_node **epp, int ln,
while (' ' == *p || '\t' == *p)
p++;
if ('\0' == *p)
- return(er);
+ return er;
mandoc_vmsg(MANDOCERR_ARG_SKIP, ep->parse,
ln, pos, "EN %s", p);
- return(er);
+ return er;
}
/*
@@ -324,7 +324,7 @@ eqn_read(struct eqn_node **epp, int ln,
ep->sz += sz;
strlcat(ep->data, p + pos, ep->sz + 1);
strlcat(ep->data, " ", ep->sz + 1);
- return(ROFF_IGN);
+ return ROFF_IGN;
}
struct eqn_node *
@@ -339,7 +339,7 @@ eqn_alloc(int pos, int line, struct mparse *parse)
p->eqn.pos = pos;
p->gsize = EQN_DEFSIZE;
- return(p);
+ return p;
}
/*
@@ -353,9 +353,9 @@ eqn_def_find(struct eqn_node *ep, const char *key, size_t sz)
for (i = 0; i < (int)ep->defsz; i++)
if (ep->defs[i].keysz && STRNEQ(ep->defs[i].key,
ep->defs[i].keysz, key, sz))
- return(&ep->defs[i]);
+ return &ep->defs[i];
- return(NULL);
+ return NULL;
}
/*
@@ -382,7 +382,7 @@ again:
if (lim >= EQN_NEST_MAX) {
mandoc_msg(MANDOCERR_ROFFLOOP, ep->parse,
ep->eqn.ln, ep->eqn.pos, NULL);
- return(NULL);
+ return NULL;
}
ep->cur = ep->rew;
@@ -390,7 +390,7 @@ again:
q = 0;
if ('\0' == *start)
- return(NULL);
+ return NULL;
if (quote == *start) {
ep->cur++;
@@ -432,7 +432,7 @@ again:
/* Quotes aren't expanded for values. */
if (q || ! repl)
- return(start);
+ return start;
if (NULL != (def = eqn_def_find(ep, start, *sz))) {
diff = def->valsz - *sz;
@@ -448,10 +448,11 @@ again:
memmove(start + *sz + diff, start + *sz,
(strlen(start) - *sz) + 1);
memcpy(start, def->val, def->valsz);
+ lim++;
goto again;
}
- return(start);
+ return start;
}
/*
@@ -462,7 +463,7 @@ static const char *
eqn_nexttok(struct eqn_node *ep, size_t *sz)
{
- return(eqn_next(ep, '"', sz, 1));
+ return eqn_next(ep, '"', sz, 1);
}
/*
@@ -472,7 +473,7 @@ static const char *
eqn_nextrawtok(struct eqn_node *ep, size_t *sz)
{
- return(eqn_next(ep, '"', sz, 0));
+ return eqn_next(ep, '"', sz, 0);
}
/*
@@ -498,12 +499,12 @@ eqn_tok_parse(struct eqn_node *ep, char **p)
quoted = ep->data[ep->cur] == '"';
if (NULL == (start = eqn_nexttok(ep, &sz)))
- return(EQN_TOK_EOF);
+ return EQN_TOK_EOF;
if (quoted) {
if (p != NULL)
*p = mandoc_strndup(start, sz);
- return(EQN_TOK__MAX);
+ return EQN_TOK__MAX;
}
for (i = 0; i < EQN_TOK__MAX; i++) {
@@ -516,7 +517,7 @@ eqn_tok_parse(struct eqn_node *ep, char **p)
if (i == EQN_TOK__MAX && NULL != p)
*p = mandoc_strndup(start, sz);
- return(i);
+ return i;
}
static void
@@ -557,7 +558,7 @@ eqn_box_alloc(struct eqn_node *ep, struct eqn_box *parent)
parent->first = bp;
parent->last = bp;
- return(bp);
+ return bp;
}
/*
@@ -587,7 +588,7 @@ eqn_box_makebinary(struct eqn_node *ep,
newb->first = newb->last = b;
newb->first->next = NULL;
b->parent = newb;
- return(newb);
+ return newb;
}
/*
@@ -712,7 +713,7 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent)
*/
if (ep->data == NULL)
- return(ROFF_IGN);
+ return ROFF_IGN;
next_tok:
tok = eqn_tok_parse(ep, &p);
@@ -986,7 +987,7 @@ this_tok:
parent->right = mandoc_strndup(start, sz);
}
parent = parent->parent;
- if (EQN_TOK_BRACE_CLOSE == tok && parent &&
+ if (tok == EQN_TOK_BRACE_CLOSE &&
(parent->type == EQN_PILE ||
parent->type == EQN_MATRIX))
parent = parent->parent;
@@ -1060,7 +1061,7 @@ this_tok:
* End of file!
* TODO: make sure we're not in an open subexpression.
*/
- return(ROFF_EQN);
+ return ROFF_EQN;
default:
assert(tok == EQN_TOK__MAX);
assert(NULL != p);
@@ -1104,7 +1105,7 @@ eqn_end(struct eqn_node **epp)
ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box));
ep->eqn.root->expectargs = UINT_MAX;
- return(eqn_parse(ep, ep->eqn.root));
+ return eqn_parse(ep, ep->eqn.root);
}
void
diff --git a/example.style.css b/example.style.css
deleted file mode 100644
index 90eb4a274f2e..000000000000
--- a/example.style.css
+++ /dev/null
@@ -1,114 +0,0 @@
-/* $Id: example.style.css,v 1.55 2015/02/10 08:05:30 schwarze Exp $ */
-/*
- * This is an example style-sheet provided for mandoc(1) and the -Thtml
- * or -Txhtml output mode.
- * It mimics the appearance of the legacy man.cgi output.
- * See mdoc(7) and man(7) for macro explanations.
- */
-
-div.mandoc { min-width: 102ex;
- width: 102ex;
- font-family: monospace; } /* This is the outer node of all mandoc -T[x]html documents. */
-div.mandoc h1 { margin-bottom: 0ex; font-size: inherit; margin-left: -4ex; } /* Section header (Sh, SH). */
-div.mandoc h2 { margin-bottom: 0ex; font-size: inherit; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
-div.mandoc table { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */
-div.mandoc td { vertical-align: top; } /* All table cells. */
-div.mandoc p { } /* Paragraph: Pp, Lp. */
-div.mandoc blockquote { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1, Dl. */
-div.mandoc div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
-div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */
-div.mandoc table.synopsis { } /* SYNOPSIS section table. */
-div.mandoc table.foot { } /* Document footer. */
-div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */
-div.mandoc td.foot-os { width: 50%;
- text-align: right; } /* Document footer: OS/source. */
-div.mandoc table.head { } /* Document header. */
-div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */
-div.mandoc td.head-vol { width: 80%;
- text-align: center; } /* Document header: volume. */
-div.mandoc td.head-rtitle { width: 10%;
- text-align: right; } /* Document header: right-title. */
-div.mandoc .display { } /* All Bd, D1, Dl. */
-div.mandoc .list { } /* All Bl. */
-div.mandoc i { } /* Italic: BI, IB, I, (implicit). */
-div.mandoc b { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
-div.mandoc small { } /* Small: SB, SM. */
-div.mandoc .emph { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
-div.mandoc .symb { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
-div.mandoc .lit { font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */
-div.mandoc i.addr { font-weight: normal; } /* Address (Ad). */
-div.mandoc i.arg { font-weight: normal; } /* Command argument (Ar). */
-div.mandoc span.author { } /* Author name (An). */
-div.mandoc b.cmd { font-style: normal; } /* Command (Cm). */
-div.mandoc b.config { font-style: normal; } /* Config statement (Cd). */
-div.mandoc span.define { } /* Defines (Dv). */
-div.mandoc span.desc { } /* Nd. After em-dash. */
-div.mandoc b.diag { font-style: normal; } /* Diagnostic (Bl -diag). */
-div.mandoc span.env { } /* Environment variables (Ev). */
-div.mandoc span.errno { } /* Error string (Er). */
-div.mandoc i.farg { font-weight: normal; } /* Function argument (Fa, Fn). */
-div.mandoc i.file { font-weight: normal; } /* File (Pa). */
-div.mandoc b.flag { font-style: normal; } /* Flag (Fl, Cm). */
-div.mandoc b.fname { font-style: normal; } /* Function name (Fa, Fn, Rv). */
-div.mandoc i.ftype { font-weight: normal; } /* Function types (Ft, Fn). */
-div.mandoc b.includes { font-style: normal; } /* Header includes (In). */
-div.mandoc span.lib { } /* Library (Lb). */
-div.mandoc i.link-sec { font-weight: normal; } /* Section links (Sx). */
-div.mandoc b.macro { font-style: normal; } /* Macro-ish thing (Fd). */
-div.mandoc b.name { font-style: normal; } /* Name of utility (Nm). */
-div.mandoc span.opt { } /* Options (Op, Oo/Oc). */
-div.mandoc span.ref { } /* Citations (Rs). */
-div.mandoc span.ref-auth { } /* Reference author (%A). */
-div.mandoc i.ref-book { font-weight: normal; } /* Reference book (%B). */
-div.mandoc span.ref-city { } /* Reference city (%C). */
-div.mandoc span.ref-date { } /* Reference date (%D). */
-div.mandoc i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */
-div.mandoc i.ref-jrnl { font-weight: normal; } /* Reference journal (%J). */
-div.mandoc span.ref-num { } /* Reference number (%N). */
-div.mandoc span.ref-opt { } /* Reference optionals (%O). */
-div.mandoc span.ref-page { } /* Reference page (%P). */
-div.mandoc span.ref-corp { } /* Reference corporate/foreign author (%Q). */
-div.mandoc span.ref-rep { } /* Reference report (%R). */
-div.mandoc span.ref-title { text-decoration: underline; } /* Reference title (%T). */
-div.mandoc span.ref-vol { } /* Reference volume (%V). */
-div.mandoc span.type { font-style: italic; font-weight: normal; } /* Variable types (Vt). */
-div.mandoc span.unix { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
-div.mandoc b.utility { font-style: normal; } /* Name of utility (Ex). */
-div.mandoc b.var { font-style: normal; } /* Variables (Rv). */
-div.mandoc a.link-ext { } /* Off-site link (Lk). */
-div.mandoc a.link-includes { } /* Include-file link (In). */
-div.mandoc a.link-mail { } /* Mailto links (Mt). */
-div.mandoc a.link-man { } /* Manual links (Xr). */
-div.mandoc a.link-ref { } /* Reference section links (%Q). */
-div.mandoc a.link-sec { } /* Section links (Sx). */
-div.mandoc dl.list-diag { } /* Formatting for lists. See mdoc(7). */
-div.mandoc dt.list-diag { }
-div.mandoc dd.list-diag { }
-div.mandoc dl.list-hang { }
-div.mandoc dt.list-hang { }
-div.mandoc dd.list-hang { }
-div.mandoc dl.list-inset { }
-div.mandoc dt.list-inset { }
-div.mandoc dd.list-inset { }
-div.mandoc dl.list-ohang { }
-div.mandoc dt.list-ohang { }
-div.mandoc dd.list-ohang { margin-left: 0ex; }
-div.mandoc dl.list-tag { }
-div.mandoc dt.list-tag { }
-div.mandoc dd.list-tag { }
-div.mandoc table.list-col { }
-div.mandoc tr.list-col { }
-div.mandoc td.list-col { }
-div.mandoc ul.list-bul { list-style-type: disc; padding-left: 1em; }
-div.mandoc li.list-bul { }
-div.mandoc ul.list-dash { list-style-type: none; padding-left: 0em; }
-div.mandoc li.list-dash:before { content: "\2014 "; }
-div.mandoc ul.list-hyph { list-style-type: none; padding-left: 0em; }
-div.mandoc li.list-hyph:before { content: "\2013 "; }
-div.mandoc ul.list-item { list-style-type: none; padding-left: 0em; }
-div.mandoc li.list-item { }
-div.mandoc ol.list-enum { padding-left: 2em; }
-div.mandoc li.list-enum { }
-div.mandoc span.eqn { } /* Equation modes. See eqn(7). */
-div.mandoc table.tbl { } /* Table modes. See tbl(7). */
-div.mandoc div.spacer { margin: 1em 0; }
diff --git a/gmdiff b/gmdiff
index ae27726ee525..8d24fa76cad9 100644
--- a/gmdiff
+++ b/gmdiff
@@ -40,7 +40,8 @@ while [ -n "$1" ]; do
shift
echo " ========== $file ========== "
tbl $file | $EQN | $ROFF -mandoc 2> /tmp/roff.err > /tmp/roff.out
- mandoc -Ios='OpenBSD ports' $MOPT $file 2> /tmp/mandoc.err > /tmp/mandoc.out
+ ${MANDOC:=mandoc} -Ios='OpenBSD ports' $MOPT $file \
+ 2> /tmp/mandoc.err > /tmp/mandoc.out
for i in roff mandoc; do
[[ -s /tmp/$i.err ]] && echo "$i errors:" && cat /tmp/$i.err
done
diff --git a/html.c b/html.c
index 487dacda947f..adff053c1a08 100644
--- a/html.c
+++ b/html.c
@@ -1,4 +1,4 @@
-/* $Id: html.c,v 1.185 2015/01/21 20:33:25 schwarze Exp $ */
+/* $Id: html.c,v 1.192 2016/01/04 12:45:29 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,9 +7,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -32,6 +32,7 @@
#include "mandoc_aux.h"
#include "out.h"
#include "html.h"
+#include "manconf.h"
#include "main.h"
struct htmldata {
@@ -129,42 +130,20 @@ static void print_attr(struct html *, const char *, const char *);
void *
-html_alloc(const struct mchars *mchars, char *outopts)
+html_alloc(const struct manoutput *outopts)
{
struct html *h;
- const char *toks[5];
- char *v;
-
- toks[0] = "style";
- toks[1] = "man";
- toks[2] = "includes";
- toks[3] = "fragment";
- toks[4] = NULL;
h = mandoc_calloc(1, sizeof(struct html));
h->tags.head = NULL;
- h->symtab = mchars;
+ h->style = outopts->style;
+ h->base_man = outopts->man;
+ h->base_includes = outopts->includes;
+ if (outopts->fragment)
+ h->oflags |= HTML_FRAGMENT;
- while (outopts && *outopts)
- switch (getsubopt(&outopts, UNCONST(toks), &v)) {
- case 0:
- h->style = v;
- break;
- case 1:
- h->base_man = v;
- break;
- case 2:
- h->base_includes = v;
- break;
- case 3:
- h->oflags |= HTML_FRAGMENT;
- break;
- default:
- break;
- }
-
- return(h);
+ return h;
}
void
@@ -237,13 +216,11 @@ print_metaf(struct html *h, enum mandoc_esc deco)
font = HTMLFONT_BI;
break;
case ESCAPE_FONT:
- /* FALLTHROUGH */
case ESCAPE_FONTROMAN:
font = HTMLFONT_NONE;
break;
default:
abort();
- /* NOTREACHED */
}
if (h->metaf) {
@@ -301,13 +278,10 @@ html_strlen(const char *cp)
cp++;
switch (mandoc_escape(&cp, NULL, NULL)) {
case ESCAPE_ERROR:
- return(sz);
+ return sz;
case ESCAPE_UNICODE:
- /* FALLTHROUGH */
case ESCAPE_NUMBERED:
- /* FALLTHROUGH */
case ESCAPE_SPECIAL:
- /* FALLTHROUGH */
case ESCAPE_OVERSTRIKE:
if (skip)
skip = 0;
@@ -321,7 +295,7 @@ html_strlen(const char *cp)
break;
}
}
- return(sz);
+ return sz;
}
static int
@@ -342,17 +316,17 @@ print_escape(char c)
printf("&quot;");
break;
case ASCII_NBRSP:
- putchar('-');
+ printf("&nbsp;");
break;
case ASCII_HYPH:
putchar('-');
- /* FALLTHROUGH */
+ break;
case ASCII_BREAK:
break;
default:
- return(0);
+ return 0;
}
- return(1);
+ return 1;
}
static int
@@ -391,15 +365,10 @@ print_encode(struct html *h, const char *p, int norecurse)
switch (esc) {
case ESCAPE_FONT:
- /* FALLTHROUGH */
case ESCAPE_FONTPREV:
- /* FALLTHROUGH */
case ESCAPE_FONTBOLD:
- /* FALLTHROUGH */
case ESCAPE_FONTITALIC:
- /* FALLTHROUGH */
case ESCAPE_FONTBI:
- /* FALLTHROUGH */
case ESCAPE_FONTROMAN:
if (0 == norecurse)
print_metaf(h, esc);
@@ -427,7 +396,7 @@ print_encode(struct html *h, const char *p, int norecurse)
continue;
break;
case ESCAPE_SPECIAL:
- c = mchars_spec2cp(h->symtab, seq, len);
+ c = mchars_spec2cp(seq, len);
if (c <= 0)
continue;
break;
@@ -452,7 +421,7 @@ print_encode(struct html *h, const char *p, int norecurse)
putchar(c);
}
- return(nospace);
+ return nospace;
}
static void
@@ -514,7 +483,7 @@ print_otag(struct html *h, enum htmltag tag,
if ((HTML_AUTOCLOSE | HTML_CLRLINE) & htmltags[tag].flags)
putchar('\n');
- return(t);
+ return t;
}
static void
@@ -751,8 +720,8 @@ void
bufcat_id(struct html *h, const char *src)
{
- /* Cf. <http://www.w3.org/TR/html4/types.html#h-6.2>. */
+ /* Cf. <http://www.w3.org/TR/html5/dom.html#the-id-attribute>. */
- while ('\0' != *src)
- bufcat_fmt(h, "%.2x", *src++);
+ for (; '\0' != *src; src++)
+ bufncat(h, *src == ' ' ? "_" : src, 1);
}
diff --git a/html.h b/html.h
index bbf6183cc5c5..27dc140185da 100644
--- a/html.h
+++ b/html.h
@@ -1,4 +1,4 @@
-/* $Id: html.h,v 1.70 2014/12/02 10:08:06 schwarze Exp $ */
+/* $Id: html.h,v 1.72 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -130,7 +130,6 @@ struct html {
struct tagq tags; /* stack of open tags */
struct rofftbl tbl; /* current table */
struct tag *tblt; /* current open table scope */
- const struct mchars *symtab; /* character table */
char *base_man; /* base for manpage href */
char *base_includes; /* base for include href */
char *style; /* style-sheet URI */
@@ -143,7 +142,6 @@ struct html {
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
};
-__BEGIN_DECLS
struct tbl_span;
struct eqn;
@@ -176,5 +174,3 @@ void buffmt_man(struct html *,
void buffmt_includes(struct html *, const char *);
int html_strlen(const char *);
-
-__END_DECLS
diff --git a/lib.c b/lib.c
index 17ce5296dea4..5295950b09b6 100644
--- a/lib.c
+++ b/lib.c
@@ -1,4 +1,4 @@
-/* $Id: lib.c,v 1.11 2014/08/10 23:54:41 schwarze Exp $ */
+/* $Id: lib.c,v 1.13 2015/10/06 18:32:19 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -20,6 +20,7 @@
#include <string.h>
+#include "roff.h"
#include "mdoc.h"
#include "libmdoc.h"
@@ -32,5 +33,5 @@ mdoc_a2lib(const char *p)
#include "lib.in"
- return(NULL);
+ return NULL;
}
diff --git a/libman.h b/libman.h
index 8d115b3abeda..65849602c27c 100644
--- a/libman.h
+++ b/libman.h
@@ -1,44 +1,23 @@
-/* $Id: libman.h,v 1.67 2014/12/28 14:42:27 schwarze Exp $ */
+/* $Id: libman.h,v 1.79 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2015 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
*/
-enum man_next {
- MAN_NEXT_SIBLING = 0,
- MAN_NEXT_CHILD
-};
-
-struct man {
- struct mparse *parse; /* parse pointer */
- const char *defos; /* default OS argument for .TH */
- int quick; /* abort parse early */
- int flags; /* parse flags */
-#define MAN_ELINE (1 << 1) /* Next-line element scope. */
-#define MAN_BLINE (1 << 2) /* Next-line block scope. */
-#define MAN_LITERAL (1 << 4) /* Literal input. */
-#define MAN_NEWLINE (1 << 6) /* first macro/text in a line */
- enum man_next next; /* where to put the next node */
- struct man_node *last; /* the last parsed node */
- struct man_node *first; /* the first parsed node */
- struct man_meta meta; /* document meta-data */
- struct roff *roff;
-};
-
-#define MACRO_PROT_ARGS struct man *man, \
- enum mant tok, \
+#define MACRO_PROT_ARGS struct roff_man *man, \
+ int tok, \
int line, \
int ppos, \
int *pos, \
@@ -47,30 +26,16 @@ struct man {
struct man_macro {
void (*fp)(MACRO_PROT_ARGS);
int flags;
-#define MAN_SCOPED (1 << 0)
-#define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */
-#define MAN_FSCOPED (1 << 2) /* See blk_imp(). */
-#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */
-#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */
-#define MAN_BSCOPE (1 << 5) /* Break BLINE scope. */
-#define MAN_JOIN (1 << 6) /* Join arguments together. */
+#define MAN_SCOPED (1 << 0) /* Optional next-line scope. */
+#define MAN_NSCOPED (1 << 1) /* Allowed in next-line element scope. */
+#define MAN_BSCOPE (1 << 2) /* Break next-line block scope. */
+#define MAN_JOIN (1 << 3) /* Join arguments together. */
};
extern const struct man_macro *const man_macros;
-__BEGIN_DECLS
-
-void man_word_alloc(struct man *, int, int, const char *);
-void man_word_append(struct man *, const char *);
-void man_block_alloc(struct man *, int, int, enum mant);
-void man_head_alloc(struct man *, int, int, enum mant);
-void man_body_alloc(struct man *, int, int, enum mant);
-void man_elem_alloc(struct man *, int, int, enum mant);
-void man_node_delete(struct man *, struct man_node *);
-void man_hash_init(void);
-enum mant man_hash_find(const char *);
-void man_macroend(struct man *);
-void man_valid_post(struct man *);
-void man_unscope(struct man *, const struct man_node *);
-__END_DECLS
+int man_hash_find(const char *);
+void man_node_validate(struct roff_man *);
+void man_state(struct roff_man *, struct roff_node *);
+void man_unscope(struct roff_man *, const struct roff_node *);
diff --git a/libmandoc.h b/libmandoc.h
index 11feebdc1019..939ec83c574d 100644
--- a/libmandoc.h
+++ b/libmandoc.h
@@ -1,15 +1,15 @@
-/* $Id: libmandoc.h,v 1.55 2015/01/15 04:26:39 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.62 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013, 2014, 2015 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -32,15 +32,13 @@ struct buf {
size_t sz;
};
-__BEGIN_DECLS
struct mparse;
-struct mchars;
struct tbl_span;
struct eqn;
struct roff;
-struct mdoc;
-struct man;
+struct roff_man;
+struct roff_node;
void mandoc_msg(enum mandocerr, struct mparse *,
int, int, const char *);
@@ -55,31 +53,25 @@ int mandoc_eos(const char *, size_t);
int mandoc_strntoi(const char *, size_t, int);
const char *mandoc_a2msec(const char*);
-void mdoc_free(struct mdoc *);
-struct mdoc *mdoc_alloc(struct roff *, struct mparse *,
- const char *, int);
-void mdoc_reset(struct mdoc *);
-int mdoc_parseln(struct mdoc *, int, char *, int);
-void mdoc_endparse(struct mdoc *);
-void mdoc_addspan(struct mdoc *, const struct tbl_span *);
-void mdoc_addeqn(struct mdoc *, const struct eqn *);
+void mdoc_hash_init(void);
+int mdoc_parseln(struct roff_man *, int, char *, int);
+void mdoc_endparse(struct roff_man *);
-void man_free(struct man *);
-struct man *man_alloc(struct roff *, struct mparse *,
- const char *, int);
-void man_reset(struct man *);
-int man_parseln(struct man *, int, char *, int);
-void man_endparse(struct man *);
-void man_addspan(struct man *, const struct tbl_span *);
-void man_addeqn(struct man *, const struct eqn *);
+void man_hash_init(void);
+int man_parseln(struct roff_man *, int, char *, int);
+void man_endparse(struct roff_man *);
int preconv_cue(const struct buf *, size_t);
int preconv_encode(struct buf *, size_t *,
struct buf *, size_t *, int *);
void roff_free(struct roff *);
-struct roff *roff_alloc(struct mparse *, const struct mchars *, int);
+struct roff *roff_alloc(struct mparse *, int);
void roff_reset(struct roff *);
+void roff_man_free(struct roff_man *);
+struct roff_man *roff_man_alloc(struct roff *, struct mparse *,
+ const char *, int);
+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);
@@ -91,5 +83,3 @@ int roff_getformat(const struct roff *);
const struct tbl_span *roff_span(const struct roff *);
const struct eqn *roff_eqn(const struct roff *);
-
-__END_DECLS
diff --git a/libmdoc.h b/libmdoc.h
index 527fe0270375..5a6cc3ed9ba8 100644
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -1,53 +1,23 @@
-/* $Id: libmdoc.h,v 1.97 2015/02/02 04:26:44 schwarze Exp $ */
+/* $Id: libmdoc.h,v 1.108 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013, 2014, 2015 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
*/
-enum mdoc_next {
- MDOC_NEXT_SIBLING = 0,
- MDOC_NEXT_CHILD
-};
-
-struct mdoc {
- struct mparse *parse; /* parse pointer */
- const char *defos; /* default argument for .Os */
- int quick; /* abort parse early */
- int flags; /* parse flags */
-#define MDOC_LITERAL (1 << 1) /* in a literal scope */
-#define MDOC_PBODY (1 << 2) /* in the document body */
-#define MDOC_NEWLINE (1 << 3) /* first macro/text in a line */
-#define MDOC_PHRASELIT (1 << 4) /* literal within a partila phrase */
-#define MDOC_PPHRASE (1 << 5) /* within a partial phrase */
-#define MDOC_FREECOL (1 << 6) /* `It' invocation should close */
-#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */
-#define MDOC_KEEP (1 << 8) /* in a word keep */
-#define MDOC_SMOFF (1 << 9) /* spacing is off */
-#define MDOC_NODELIMC (1 << 10) /* disable closing delimiter handling */
- enum mdoc_next next; /* where to put the next node */
- struct mdoc_node *last; /* the last node parsed */
- struct mdoc_node *first; /* the first node parsed */
- struct mdoc_node *last_es; /* the most recent Es node */
- struct mdoc_meta meta; /* document meta-data */
- enum mdoc_sec lastnamed;
- enum mdoc_sec lastsec;
- struct roff *roff;
-};
-
-#define MACRO_PROT_ARGS struct mdoc *mdoc, \
- enum mdoct tok, \
+#define MACRO_PROT_ARGS struct roff_man *mdoc, \
+ int tok, \
int line, \
int ppos, \
int *pos, \
@@ -70,9 +40,7 @@ enum margserr {
ARGS_WORD, /* normal word */
ARGS_PUNCT, /* series of punctuation */
ARGS_QWORD, /* quoted word */
- ARGS_PHRASE, /* Ta'd phrase (-column) */
- ARGS_PPHRASE, /* tabbed phrase (-column) */
- ARGS_PEND /* last phrase (-column) */
+ ARGS_PHRASE /* Bl -column phrase */
};
/*
@@ -94,36 +62,27 @@ enum mdelim {
extern const struct mdoc_macro *const mdoc_macros;
-__BEGIN_DECLS
void mdoc_macro(MACRO_PROT_ARGS);
-void mdoc_word_alloc(struct mdoc *, int, int, const char *);
-void mdoc_word_append(struct mdoc *, const char *);
-void mdoc_elem_alloc(struct mdoc *, int, int,
- enum mdoct, struct mdoc_arg *);
-struct mdoc_node *mdoc_block_alloc(struct mdoc *, int, int,
- enum mdoct, struct mdoc_arg *);
-struct mdoc_node *mdoc_head_alloc(struct mdoc *, int, int, enum mdoct);
-void mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct);
-struct mdoc_node *mdoc_body_alloc(struct mdoc *, int, int, enum mdoct);
-struct mdoc_node *mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct,
- struct mdoc_node *, enum mdoc_endbody);
-void mdoc_node_delete(struct mdoc *, struct mdoc_node *);
-void mdoc_node_relink(struct mdoc *, struct mdoc_node *);
-void mdoc_hash_init(void);
-enum mdoct mdoc_hash_find(const char *);
+void mdoc_elem_alloc(struct roff_man *, int, int,
+ int, struct mdoc_arg *);
+struct roff_node *mdoc_block_alloc(struct roff_man *, int, int,
+ int, struct mdoc_arg *);
+void mdoc_tail_alloc(struct roff_man *, int, int, int);
+struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int, int,
+ struct roff_node *, enum mdoc_endbody);
+void mdoc_node_relink(struct roff_man *, struct roff_node *);
+void mdoc_node_validate(struct roff_man *);
+void mdoc_state(struct roff_man *, struct roff_node *);
+void mdoc_state_reset(struct roff_man *);
+int mdoc_hash_find(const char *);
+const char *mdoc_a2arch(const char *);
const char *mdoc_a2att(const char *);
const char *mdoc_a2lib(const char *);
+enum roff_sec mdoc_a2sec(const char *);
const char *mdoc_a2st(const char *);
-const char *mdoc_a2arch(const char *);
-void mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
-void mdoc_valid_post(struct mdoc *);
-void mdoc_argv(struct mdoc *, int, enum mdoct,
+void mdoc_argv(struct roff_man *, int, int,
struct mdoc_arg **, int *, char *);
-void mdoc_argv_free(struct mdoc_arg *);
-enum margserr mdoc_args(struct mdoc *, int,
- int *, char *, enum mdoct, char **);
-void mdoc_macroend(struct mdoc *);
+enum margserr mdoc_args(struct roff_man *, int,
+ int *, char *, int, char **);
enum mdelim mdoc_isdelim(const char *);
-
-__END_DECLS
diff --git a/libroff.h b/libroff.h
index 08ed1f7925d2..897a55ae61cb 100644
--- a/libroff.h
+++ b/libroff.h
@@ -1,4 +1,4 @@
-/* $Id: libroff.h,v 1.38 2015/01/30 04:11:50 schwarze Exp $ */
+/* $Id: libroff.h,v 1.39 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -60,7 +60,6 @@ struct eqn_def {
size_t valsz;
};
-__BEGIN_DECLS
struct tbl_node *tbl_alloc(int, int, struct mparse *);
void tbl_restart(int, int, struct tbl_node *);
@@ -78,5 +77,3 @@ enum rofferr eqn_end(struct eqn_node **);
void eqn_free(struct eqn_node *);
enum rofferr eqn_read(struct eqn_node **, int,
const char *, int, int *);
-
-__END_DECLS
diff --git a/main.c b/main.c
index f0cd8ca0ccc6..3c4ff2acc247 100644
--- a/main.c
+++ b/main.c
@@ -1,16 +1,16 @@
-/* $Id: main.c,v 1.225 2015/03/10 13:50:03 schwarze Exp $ */
+/* $Id: main.c,v 1.262 2016/01/08 02:53:13 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2012, 2014-2016 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -24,21 +24,27 @@
#include <assert.h>
#include <ctype.h>
+#if HAVE_ERR
+#include <err.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
+#include <signal.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "main.h"
+#include "mandoc.h"
+#include "roff.h"
#include "mdoc.h"
#include "man.h"
-#include "manpath.h"
+#include "tag.h"
+#include "main.h"
+#include "manconf.h"
#include "mansearch.h"
#if !defined(__GNUC__) || (__GNUC__ < 2)
@@ -56,10 +62,6 @@ enum outmode {
OUTMODE_ONE
};
-typedef void (*out_mdoc)(void *, const struct mdoc *);
-typedef void (*out_man)(void *, const struct man *);
-typedef void (*out_free)(void *);
-
enum outt {
OUTT_ASCII = 0, /* -Tascii */
OUTT_LOCALE, /* -Tlocale */
@@ -74,15 +76,11 @@ enum outt {
struct curparse {
struct mparse *mp;
- struct mchars *mchars; /* character table */
enum mandoclevel wlevel; /* ignore messages below this */
int wstop; /* stop after a file with a warning */
enum outt outtype; /* which output to use */
- out_mdoc outmdoc; /* mdoc output ptr */
- out_man outman; /* man output ptr */
- out_free outfree; /* free output ptr */
void *outdata; /* data for output */
- char outopts[BUFSIZ]; /* buf of output opts */
+ struct manoutput *outopts; /* output options */
};
static int fs_lookup(const struct manpaths *,
@@ -99,10 +97,9 @@ int mandocdb(int, char**);
static int moptions(int *, char *);
static void mmsg(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
-static void parse(struct curparse *, int,
- const char *, enum mandoclevel *);
-static enum mandoclevel passthrough(const char *, int, int);
-static pid_t spawn_pager(void);
+static void parse(struct curparse *, int, const char *);
+static void passthrough(const char *, int, int);
+static pid_t spawn_pager(struct tag_files *);
static int toptions(struct curparse *, char *);
static void usage(enum argmode) __attribute__((noreturn));
static int woptions(struct curparse *, char *);
@@ -110,46 +107,60 @@ static int woptions(struct curparse *, char *);
static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
static char help_arg[] = "help";
static char *help_argv[] = {help_arg, NULL};
-static const char *progname;
+static enum mandoclevel rc;
int
main(int argc, char *argv[])
{
+ struct manconf conf;
struct curparse curp;
struct mansearch search;
- struct manpaths paths;
+ struct tag_files *tag_files;
+ const char *progname;
char *auxpaths;
char *defos;
unsigned char *uc;
struct manpage *res, *resp;
char *conf_file, *defpaths;
size_t isec, i, sz;
- int prio, best_prio, synopsis_only;
+ int prio, best_prio;
char sec;
- enum mandoclevel rc, rctmp;
enum outmode outmode;
int fd;
int show_usage;
int options;
+ int use_pager;
+ int status, signum;
int c;
- pid_t pager_pid; /* 0: don't use; 1: not yet spawned. */
+ pid_t pager_pid, tc_pgid, man_pgid, pid;
+#if HAVE_PROGNAME
+ progname = getprogname();
+#else
if (argc < 1)
- progname = "mandoc";
+ progname = mandoc_strdup("mandoc");
else if ((progname = strrchr(argv[0], '/')) == NULL)
progname = argv[0];
else
++progname;
+ setprogname(progname);
+#endif
#if HAVE_SQLITE3
- if (strcmp(progname, BINM_MAKEWHATIS) == 0)
- return(mandocdb(argc, argv));
+ if (strncmp(progname, "mandocdb", 8) == 0 ||
+ strcmp(progname, BINM_MAKEWHATIS) == 0)
+ return mandocdb(argc, argv);
+#endif
+
+#if HAVE_PLEDGE
+ if (pledge("stdio rpath tmppath tty proc exec flock", NULL) == -1)
+ err((int)MANDOCLEVEL_SYSERR, "pledge");
#endif
/* Search options. */
- memset(&paths, 0, sizeof(struct manpaths));
+ memset(&conf, 0, sizeof(conf));
conf_file = defpaths = NULL;
auxpaths = NULL;
@@ -172,12 +183,13 @@ main(int argc, char *argv[])
memset(&curp, 0, sizeof(struct curparse));
curp.outtype = OUTT_LOCALE;
curp.wlevel = MANDOCLEVEL_BADARG;
+ curp.outopts = &conf.output;
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
defos = NULL;
- pager_pid = 1;
+ use_pager = 1;
+ tag_files = NULL;
show_usage = 0;
- synopsis_only = 0;
outmode = OUTMODE_DEF;
while (-1 != (c = getopt(argc, argv,
@@ -190,29 +202,24 @@ main(int argc, char *argv[])
conf_file = optarg;
break;
case 'c':
- pager_pid = 0;
+ use_pager = 0;
break;
case 'f':
search.argmode = ARG_WORD;
break;
case 'h':
- (void)strlcat(curp.outopts, "synopsis,", BUFSIZ);
- synopsis_only = 1;
- pager_pid = 0;
+ conf.output.synopsisonly = 1;
+ use_pager = 0;
outmode = OUTMODE_ALL;
break;
case 'I':
if (strncmp(optarg, "os=", 3)) {
- fprintf(stderr,
- "%s: -I %s: Bad argument\n",
- progname, optarg);
- return((int)MANDOCLEVEL_BADARG);
+ warnx("-I %s: Bad argument", optarg);
+ return (int)MANDOCLEVEL_BADARG;
}
if (defos) {
- fprintf(stderr,
- "%s: -I %s: Duplicate argument\n",
- progname, optarg);
- return((int)MANDOCLEVEL_BADARG);
+ warnx("-I %s: Duplicate argument", optarg);
+ return (int)MANDOCLEVEL_BADARG;
}
defos = mandoc_strdup(optarg + 3);
break;
@@ -221,7 +228,7 @@ main(int argc, char *argv[])
break;
case 'K':
if ( ! koptions(&options, optarg))
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
break;
case 'k':
search.argmode = ARG_EXPR;
@@ -238,8 +245,9 @@ main(int argc, char *argv[])
break;
case 'O':
search.outkey = optarg;
- (void)strlcat(curp.outopts, optarg, BUFSIZ);
- (void)strlcat(curp.outopts, ",", BUFSIZ);
+ while (optarg != NULL)
+ manconf_output(&conf.output,
+ strsep(&optarg, ","));
break;
case 'S':
search.arch = optarg;
@@ -249,11 +257,11 @@ main(int argc, char *argv[])
break;
case 'T':
if ( ! toptions(&curp, optarg))
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
break;
case 'W':
if ( ! woptions(&curp, optarg))
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
break;
case 'w':
outmode = OUTMODE_FLN;
@@ -273,7 +281,7 @@ main(int argc, char *argv[])
switch (search.argmode) {
case ARG_FILE:
outmode = OUTMODE_ALL;
- pager_pid = 0;
+ use_pager = 0;
break;
case ARG_NAME:
outmode = OUTMODE_ONE;
@@ -284,6 +292,17 @@ main(int argc, char *argv[])
}
}
+ if (outmode == OUTMODE_FLN ||
+ outmode == OUTMODE_LST ||
+ !isatty(STDOUT_FILENO))
+ use_pager = 0;
+
+#if HAVE_PLEDGE
+ if (!use_pager)
+ if (pledge("stdio rpath flock", NULL) == -1)
+ err((int)MANDOCLEVEL_SYSERR, "pledge");
+#endif
+
/* Parse arguments. */
if (argc > 0) {
@@ -334,22 +353,28 @@ main(int argc, char *argv[])
/* Access the mandoc database. */
- manpath_parse(&paths, conf_file, defpaths, auxpaths);
+ manconf_parse(&conf, conf_file, defpaths, auxpaths);
#if HAVE_SQLITE3
mansearch_setup(1);
- if( ! mansearch(&search, &paths, argc, argv, &res, &sz))
+ if ( ! mansearch(&search, &conf.manpath,
+ argc, argv, &res, &sz))
usage(search.argmode);
#else
if (search.argmode != ARG_NAME) {
fputs("mandoc: database support not compiled in\n",
stderr);
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
}
sz = 0;
#endif
- if (sz == 0 && search.argmode == ARG_NAME)
- fs_search(&search, &paths, argc, argv, &res, &sz);
+ if (sz == 0) {
+ if (search.argmode == ARG_NAME)
+ fs_search(&search, &conf.manpath,
+ argc, argv, &res, &sz);
+ else
+ warnx("nothing appropriate");
+ }
if (sz == 0) {
rc = MANDOCLEVEL_BADARG;
@@ -404,12 +429,21 @@ main(int argc, char *argv[])
/* mandoc(1) */
+#if HAVE_PLEDGE
+ if (use_pager) {
+ if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1)
+ err((int)MANDOCLEVEL_SYSERR, "pledge");
+ } else {
+ if (pledge("stdio rpath", NULL) == -1)
+ err((int)MANDOCLEVEL_SYSERR, "pledge");
+ }
+#endif
+
if (search.argmode == ARG_FILE && ! moptions(&options, auxpaths))
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
- curp.mchars = mchars_alloc();
- curp.mp = mparse_alloc(options, curp.wlevel, mmsg,
- curp.mchars, defos);
+ mchars_alloc();
+ curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
/*
* Conditionally start up the lookaside buffer before parsing.
@@ -418,41 +452,33 @@ main(int argc, char *argv[])
mparse_keep(curp.mp);
if (argc < 1) {
- if (pager_pid == 1 && isatty(STDOUT_FILENO))
- pager_pid = spawn_pager();
- parse(&curp, STDIN_FILENO, "<stdin>", &rc);
+ if (use_pager)
+ tag_files = tag_init();
+ parse(&curp, STDIN_FILENO, "<stdin>");
}
while (argc > 0) {
- rctmp = mparse_open(curp.mp, &fd,
- resp != NULL ? resp->file : *argv);
- if (rc < rctmp)
- rc = rctmp;
-
+ fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv);
if (fd != -1) {
- if (pager_pid == 1 && isatty(STDOUT_FILENO))
- pager_pid = spawn_pager();
+ if (use_pager) {
+ tag_files = tag_init();
+ use_pager = 0;
+ }
if (resp == NULL)
- parse(&curp, fd, *argv, &rc);
+ parse(&curp, fd, *argv);
else if (resp->form & FORM_SRC) {
/* For .so only; ignore failure. */
- chdir(paths.paths[resp->ipath]);
- parse(&curp, fd, resp->file, &rc);
- } else {
- rctmp = passthrough(resp->file, fd,
- synopsis_only);
- if (rc < rctmp)
- rc = rctmp;
- }
-
- rctmp = mparse_wait(curp.mp);
- if (rc < rctmp)
- rc = rctmp;
+ chdir(conf.manpath.paths[resp->ipath]);
+ parse(&curp, fd, resp->file);
+ } else
+ passthrough(resp->file, fd,
+ conf.output.synopsisonly);
if (argc > 1 && curp.outtype <= OUTT_UTF8)
ascii_sepline(curp.outdata);
- }
+ } else if (rc < MANDOCLEVEL_ERROR)
+ rc = MANDOCLEVEL_ERROR;
if (MANDOCLEVEL_OK != rc && curp.wstop)
break;
@@ -465,14 +491,30 @@ main(int argc, char *argv[])
mparse_reset(curp.mp);
}
- if (curp.outfree)
- (*curp.outfree)(curp.outdata);
+ if (curp.outdata != NULL) {
+ switch (curp.outtype) {
+ case OUTT_HTML:
+ html_free(curp.outdata);
+ break;
+ case OUTT_UTF8:
+ case OUTT_LOCALE:
+ case OUTT_ASCII:
+ ascii_free(curp.outdata);
+ break;
+ case OUTT_PDF:
+ case OUTT_PS:
+ pspdf_free(curp.outdata);
+ break;
+ default:
+ break;
+ }
+ }
mparse_free(curp.mp);
- mchars_free(curp.mchars);
+ mchars_free();
out:
if (search.argmode != ARG_FILE) {
- manpath_free(&paths);
+ manconf_free(&conf);
#if HAVE_SQLITE3
mansearch_free(res, sz);
mansearch_setup(0);
@@ -482,17 +524,63 @@ out:
free(defos);
/*
- * If a pager is attached, flush the pipe leading to it
- * and signal end of file such that the user can browse
- * to the end. Then wait for the user to close the pager.
+ * When using a pager, finish writing both temporary files,
+ * fork it, wait for the user to close it, and clean up.
*/
- if (pager_pid != 0 && pager_pid != 1) {
+ if (tag_files != NULL) {
fclose(stdout);
- waitpid(pager_pid, NULL, 0);
+ tag_write();
+ man_pgid = getpgid(0);
+ tag_files->tcpgid = man_pgid == getpid() ?
+ getpgid(getppid()) : man_pgid;
+ pager_pid = 0;
+ signum = SIGSTOP;
+ for (;;) {
+
+ /* Stop here until moved to the foreground. */
+
+ tc_pgid = tcgetpgrp(STDIN_FILENO);
+ if (tc_pgid != man_pgid) {
+ if (tc_pgid == pager_pid) {
+ (void)tcsetpgrp(STDIN_FILENO,
+ man_pgid);
+ if (signum == SIGTTIN)
+ continue;
+ } else
+ tag_files->tcpgid = tc_pgid;
+ kill(0, signum);
+ continue;
+ }
+
+ /* Once in the foreground, activate the pager. */
+
+ if (pager_pid) {
+ (void)tcsetpgrp(STDIN_FILENO, pager_pid);
+ kill(pager_pid, SIGCONT);
+ } else
+ pager_pid = spawn_pager(tag_files);
+
+ /* Wait for the pager to stop or exit. */
+
+ while ((pid = waitpid(pager_pid, &status,
+ WUNTRACED)) == -1 && errno == EINTR)
+ continue;
+
+ if (pid == -1) {
+ warn("wait");
+ rc = MANDOCLEVEL_SYSERR;
+ break;
+ }
+ if (!WIFSTOPPED(status))
+ break;
+
+ signum = WSTOPSIG(status);
+ }
+ tag_unlink();
}
- return((int)rc);
+ return (int)rc;
}
static void
@@ -501,9 +589,9 @@ usage(enum argmode argmode)
switch (argmode) {
case ARG_FILE:
- fputs("usage: mandoc [-acfhkl] [-Ios=name] "
- "[-Kencoding] [-mformat] [-Ooption]\n"
- "\t [-Toutput] [-Wlevel] [file ...]\n", stderr);
+ fputs("usage: mandoc [-acfhkl] [-I os=name] "
+ "[-K encoding] [-mformat] [-O option]\n"
+ "\t [-T output] [-W level] [file ...]\n", stderr);
break;
case ARG_NAME:
fputs("usage: man [-acfhklw] [-C file] [-I os=name] "
@@ -559,26 +647,23 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
free(file);
}
- mandoc_asprintf(&file, "%s/man%s/%s.*",
+ mandoc_asprintf(&file, "%s/man%s/%s.[01-9]*",
paths->paths[ipath], sec, name);
globres = glob(file, 0, NULL, &globinfo);
if (globres != 0 && globres != GLOB_NOMATCH)
- fprintf(stderr, "%s: %s: glob: %s\n",
- progname, file, strerror(errno));
+ warn("%s: glob", file);
free(file);
if (globres == 0)
file = mandoc_strdup(*globinfo.gl_pathv);
globfree(&globinfo);
if (globres != 0)
- return(0);
+ return 0;
found:
#if HAVE_SQLITE3
- fprintf(stderr, "%s: outdated mandoc.db lacks %s(%s) entry,\n"
- " consider running # makewhatis %s\n",
- progname, name, sec, paths->paths[ipath]);
+ warnx("outdated mandoc.db lacks %s(%s) entry, run makewhatis %s",
+ name, sec, paths->paths[ipath]);
#endif
-
*res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
page = *res + (*ressz - 1);
page->file = file;
@@ -588,7 +673,7 @@ found:
page->bits = NAME_FILE & NAME_MASK;
page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
page->form = form;
- return(1);
+ return 1;
}
static void
@@ -619,9 +704,7 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
return;
}
if (*ressz == lastsz)
- fprintf(stderr,
- "%s: No entry for %s in the manual.\n",
- progname, *argv);
+ warnx("No entry for %s in the manual.", *argv);
lastsz = *ressz;
argv++;
argc--;
@@ -629,111 +712,112 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
}
static void
-parse(struct curparse *curp, int fd, const char *file,
- enum mandoclevel *level)
+parse(struct curparse *curp, int fd, const char *file)
{
- enum mandoclevel rc;
- struct mdoc *mdoc;
- struct man *man;
+ enum mandoclevel rctmp;
+ struct roff_man *man;
/* Begin by parsing the file itself. */
assert(file);
- assert(fd >= -1);
+ assert(fd > 0);
- rc = mparse_readfd(curp->mp, fd, file);
+ rctmp = mparse_readfd(curp->mp, fd, file);
+ if (fd != STDIN_FILENO)
+ close(fd);
+ if (rc < rctmp)
+ rc = rctmp;
/*
* With -Wstop and warnings or errors of at least the requested
* level, do not produce output.
*/
- if (MANDOCLEVEL_OK != rc && curp->wstop)
- goto cleanup;
+ if (rctmp != MANDOCLEVEL_OK && curp->wstop)
+ return;
/* If unset, allocate output dev now (if applicable). */
- if ( ! (curp->outman && curp->outmdoc)) {
+ if (curp->outdata == NULL) {
switch (curp->outtype) {
case OUTT_HTML:
- curp->outdata = html_alloc(curp->mchars,
- curp->outopts);
- curp->outfree = html_free;
+ curp->outdata = html_alloc(curp->outopts);
break;
case OUTT_UTF8:
- curp->outdata = utf8_alloc(curp->mchars,
- curp->outopts);
- curp->outfree = ascii_free;
+ curp->outdata = utf8_alloc(curp->outopts);
break;
case OUTT_LOCALE:
- curp->outdata = locale_alloc(curp->mchars,
- curp->outopts);
- curp->outfree = ascii_free;
+ curp->outdata = locale_alloc(curp->outopts);
break;
case OUTT_ASCII:
- curp->outdata = ascii_alloc(curp->mchars,
- curp->outopts);
- curp->outfree = ascii_free;
+ curp->outdata = ascii_alloc(curp->outopts);
break;
case OUTT_PDF:
- curp->outdata = pdf_alloc(curp->mchars,
- curp->outopts);
- curp->outfree = pspdf_free;
+ curp->outdata = pdf_alloc(curp->outopts);
break;
case OUTT_PS:
- curp->outdata = ps_alloc(curp->mchars,
- curp->outopts);
- curp->outfree = pspdf_free;
+ curp->outdata = ps_alloc(curp->outopts);
break;
default:
break;
}
+ }
+
+ mparse_result(curp->mp, &man, NULL);
+ /* Execute the out device, if it exists. */
+
+ if (man == NULL)
+ return;
+ if (man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
switch (curp->outtype) {
case OUTT_HTML:
- curp->outman = html_man;
- curp->outmdoc = html_mdoc;
+ html_mdoc(curp->outdata, man);
break;
case OUTT_TREE:
- curp->outman = tree_man;
- curp->outmdoc = tree_mdoc;
+ tree_mdoc(curp->outdata, man);
break;
case OUTT_MAN:
- curp->outmdoc = man_mdoc;
- curp->outman = man_man;
+ man_mdoc(curp->outdata, man);
break;
case OUTT_PDF:
- /* FALLTHROUGH */
case OUTT_ASCII:
- /* FALLTHROUGH */
case OUTT_UTF8:
- /* FALLTHROUGH */
case OUTT_LOCALE:
- /* FALLTHROUGH */
case OUTT_PS:
- curp->outman = terminal_man;
- curp->outmdoc = terminal_mdoc;
+ terminal_mdoc(curp->outdata, man);
+ break;
+ default:
+ break;
+ }
+ }
+ if (man->macroset == MACROSET_MAN) {
+ man_validate(man);
+ switch (curp->outtype) {
+ case OUTT_HTML:
+ html_man(curp->outdata, man);
+ break;
+ case OUTT_TREE:
+ tree_man(curp->outdata, man);
+ break;
+ case OUTT_MAN:
+ man_man(curp->outdata, man);
+ break;
+ case OUTT_PDF:
+ case OUTT_ASCII:
+ case OUTT_UTF8:
+ case OUTT_LOCALE:
+ case OUTT_PS:
+ terminal_man(curp->outdata, man);
break;
default:
break;
}
}
-
- mparse_result(curp->mp, &mdoc, &man, NULL);
-
- /* Execute the out device, if it exists. */
-
- if (man && curp->outman)
- (*curp->outman)(curp->outdata, man);
- if (mdoc && curp->outmdoc)
- (*curp->outmdoc)(curp->outdata, mdoc);
-
-cleanup:
- if (*level < rc)
- *level = rc;
}
-static enum mandoclevel
+static void
passthrough(const char *file, int fd, int synopsis_only)
{
const char synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS";
@@ -741,12 +825,12 @@ passthrough(const char *file, int fd, int synopsis_only)
FILE *stream;
const char *syscall;
- char *line;
- size_t len, off;
- ssize_t nw;
+ char *line, *cp;
+ size_t linesz;
int print;
- fflush(stdout);
+ line = NULL;
+ linesz = 0;
if ((stream = fdopen(fd, "r")) == NULL) {
close(fd);
@@ -755,48 +839,44 @@ passthrough(const char *file, int fd, int synopsis_only)
}
print = 0;
- while ((line = fgetln(stream, &len)) != NULL) {
+ while (getline(&line, &linesz, stream) != -1) {
+ cp = line;
if (synopsis_only) {
if (print) {
- if ( ! isspace((unsigned char)*line))
+ if ( ! isspace((unsigned char)*cp))
goto done;
- while (len &&
- isspace((unsigned char)*line)) {
- line++;
- len--;
- }
+ while (isspace((unsigned char)*cp))
+ cp++;
} else {
- if ((len == sizeof(synb) &&
- ! strncmp(line, synb, len - 1)) ||
- (len == sizeof(synr) &&
- ! strncmp(line, synr, len - 1)))
+ if (strcmp(cp, synb) == 0 ||
+ strcmp(cp, synr) == 0)
print = 1;
continue;
}
}
- for (off = 0; off < len; off += nw)
- if ((nw = write(STDOUT_FILENO, line + off,
- len - off)) == -1 || nw == 0) {
- fclose(stream);
- syscall = "write";
- goto fail;
- }
+ if (fputs(cp, stdout)) {
+ fclose(stream);
+ syscall = "fputs";
+ goto fail;
+ }
}
if (ferror(stream)) {
fclose(stream);
- syscall = "fgetln";
+ syscall = "getline";
goto fail;
}
done:
+ free(line);
fclose(stream);
- return(MANDOCLEVEL_OK);
+ return;
fail:
- fprintf(stderr, "%s: %s: SYSERR: %s: %s",
- progname, file, syscall, strerror(errno));
- return(MANDOCLEVEL_SYSERR);
+ free(line);
+ warn("%s: SYSERR: %s", file, syscall);
+ if (rc < MANDOCLEVEL_SYSERR)
+ rc = MANDOCLEVEL_SYSERR;
}
static int
@@ -812,11 +892,10 @@ koptions(int *options, char *arg)
} else if ( ! strcmp(arg, "us-ascii")) {
*options &= ~(MPARSE_UTF8 | MPARSE_LATIN1);
} else {
- fprintf(stderr, "%s: -K %s: Bad argument\n",
- progname, arg);
- return(0);
+ warnx("-K %s: Bad argument", arg);
+ return 0;
}
- return(1);
+ return 1;
}
static int
@@ -832,12 +911,11 @@ moptions(int *options, char *arg)
else if (0 == strcmp(arg, "an"))
*options |= MPARSE_MAN;
else {
- fprintf(stderr, "%s: -m %s: Bad argument\n",
- progname, arg);
- return(0);
+ warnx("-m %s: Bad argument", arg);
+ return 0;
}
- return(1);
+ return 1;
}
static int
@@ -866,12 +944,11 @@ toptions(struct curparse *curp, char *arg)
else if (0 == strcmp(arg, "pdf"))
curp->outtype = OUTT_PDF;
else {
- fprintf(stderr, "%s: -T %s: Bad argument\n",
- progname, arg);
- return(0);
+ warnx("-T %s: Bad argument", arg);
+ return 0;
}
- return(1);
+ return 1;
}
static int
@@ -895,7 +972,6 @@ woptions(struct curparse *curp, char *arg)
curp->wstop = 1;
break;
case 1:
- /* FALLTHROUGH */
case 2:
curp->wlevel = MANDOCLEVEL_WARNING;
break;
@@ -909,13 +985,12 @@ woptions(struct curparse *curp, char *arg)
curp->wlevel = MANDOCLEVEL_BADARG;
break;
default:
- fprintf(stderr, "%s: -W %s: Bad argument\n",
- progname, o);
- return(0);
+ warnx("-W %s: Bad argument", o);
+ return 0;
}
}
- return(1);
+ return 1;
}
static void
@@ -924,7 +999,7 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
{
const char *mparse_msg;
- fprintf(stderr, "%s: %s:", progname, file);
+ fprintf(stderr, "%s: %s:", getprogname(), file);
if (line)
fprintf(stderr, "%d:%d:", line, col + 1);
@@ -941,55 +1016,21 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
}
static pid_t
-spawn_pager(void)
+spawn_pager(struct tag_files *tag_files)
{
#define MAX_PAGER_ARGS 16
char *argv[MAX_PAGER_ARGS];
const char *pager;
char *cp;
- int fildes[2];
+ size_t cmdlen;
int argc;
pid_t pager_pid;
- if (pipe(fildes) == -1) {
- fprintf(stderr, "%s: pipe: %s\n",
- progname, strerror(errno));
- return(0);
- }
-
- switch (pager_pid = fork()) {
- case -1:
- fprintf(stderr, "%s: fork: %s\n",
- progname, strerror(errno));
- exit((int)MANDOCLEVEL_SYSERR);
- case 0:
- break;
- default:
- close(fildes[0]);
- if (dup2(fildes[1], STDOUT_FILENO) == -1) {
- fprintf(stderr, "%s: dup output: %s\n",
- progname, strerror(errno));
- exit((int)MANDOCLEVEL_SYSERR);
- }
- close(fildes[1]);
- return(pager_pid);
- }
-
- /* The child process becomes the pager. */
-
- close(fildes[1]);
- if (dup2(fildes[0], STDIN_FILENO) == -1) {
- fprintf(stderr, "%s: dup input: %s\n",
- progname, strerror(errno));
- exit((int)MANDOCLEVEL_SYSERR);
- }
- close(fildes[0]);
-
pager = getenv("MANPAGER");
if (pager == NULL || *pager == '\0')
pager = getenv("PAGER");
if (pager == NULL || *pager == '\0')
- pager = "/usr/bin/more -s";
+ pager = "more -s";
cp = mandoc_strdup(pager);
/*
@@ -998,7 +1039,7 @@ spawn_pager(void)
*/
argc = 0;
- while (argc + 1 < MAX_PAGER_ARGS) {
+ while (argc + 4 < MAX_PAGER_ARGS) {
argv[argc++] = cp;
cp = strchr(cp, ' ');
if (cp == NULL)
@@ -1009,12 +1050,43 @@ spawn_pager(void)
if (*cp == '\0')
break;
}
+
+ /* For more(1) and less(1), use the tag file. */
+
+ if ((cmdlen = strlen(argv[0])) >= 4) {
+ cp = argv[0] + cmdlen - 4;
+ if (strcmp(cp, "less") == 0 || strcmp(cp, "more") == 0) {
+ argv[argc++] = mandoc_strdup("-T");
+ argv[argc++] = tag_files->tfn;
+ }
+ }
+ argv[argc++] = tag_files->ofn;
argv[argc] = NULL;
- /* Hand over to the pager. */
+ switch (pager_pid = fork()) {
+ case -1:
+ err((int)MANDOCLEVEL_SYSERR, "fork");
+ case 0:
+ /* Set pgrp in both parent and child to avoid racing exec. */
+ (void)setpgid(0, 0);
+ break;
+ default:
+ (void)setpgid(pager_pid, 0);
+ (void)tcsetpgrp(STDIN_FILENO, pager_pid);
+#if HAVE_PLEDGE
+ if (pledge("stdio rpath tmppath tty proc", NULL) == -1)
+ err((int)MANDOCLEVEL_SYSERR, "pledge");
+#endif
+ tag_files->pager_pid = pager_pid;
+ return pager_pid;
+ }
+
+ /* The child process becomes the pager. */
+ if (dup2(tag_files->ofd, STDOUT_FILENO) == -1)
+ err((int)MANDOCLEVEL_SYSERR, "pager stdout");
+ close(tag_files->ofd);
+ close(tag_files->tfd);
execvp(argv[0], argv);
- fprintf(stderr, "%s: exec: %s\n",
- progname, strerror(errno));
- exit((int)MANDOCLEVEL_SYSERR);
+ err((int)MANDOCLEVEL_SYSERR, "exec %s", argv[0]);
}
diff --git a/main.h b/main.h
index 9b04a7816aec..e9e7e8668677 100644
--- a/main.h
+++ b/main.h
@@ -1,15 +1,15 @@
-/* $Id: main.h,v 1.20 2014/12/31 16:52:40 schwarze Exp $ */
+/* $Id: main.h,v 1.24 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2015 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -18,11 +18,8 @@
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
-__BEGIN_DECLS
-
-struct mchars;
-struct mdoc;
-struct man;
+struct roff_man;
+struct manoutput;
/*
* Definitions for main.c-visible output device functions, e.g., -Thtml
@@ -31,28 +28,26 @@ struct man;
* terminal output routines with different character settings.
*/
-void *html_alloc(const struct mchars *, char *);
-void html_mdoc(void *, const struct mdoc *);
-void html_man(void *, const struct man *);
+void *html_alloc(const struct manoutput *);
+void html_mdoc(void *, const struct roff_man *);
+void html_man(void *, const struct roff_man *);
void html_free(void *);
-void tree_mdoc(void *, const struct mdoc *);
-void tree_man(void *, const struct man *);
+void tree_mdoc(void *, const struct roff_man *);
+void tree_man(void *, const struct roff_man *);
-void man_mdoc(void *, const struct mdoc *);
-void man_man(void *, const struct man *);
+void man_mdoc(void *, const struct roff_man *);
+void man_man(void *, const struct roff_man *);
-void *locale_alloc(const struct mchars *, char *);
-void *utf8_alloc(const struct mchars *, char *);
-void *ascii_alloc(const struct mchars *, char *);
+void *locale_alloc(const struct manoutput *);
+void *utf8_alloc(const struct manoutput *);
+void *ascii_alloc(const struct manoutput *);
void ascii_free(void *);
void ascii_sepline(void *);
-void *pdf_alloc(const struct mchars *, char *);
-void *ps_alloc(const struct mchars *, char *);
+void *pdf_alloc(const struct manoutput *);
+void *ps_alloc(const struct manoutput *);
void pspdf_free(void *);
-void terminal_mdoc(void *, const struct mdoc *);
-void terminal_man(void *, const struct man *);
-
-__END_DECLS
+void terminal_mdoc(void *, const struct roff_man *);
+void terminal_man(void *, const struct roff_man *);
diff --git a/man-cgi.css b/man-cgi.css
deleted file mode 100644
index 256e8c6693ef..000000000000
--- a/man-cgi.css
+++ /dev/null
@@ -1,13 +0,0 @@
-body { font-family: Helvetica, Arial, sans-serif; }
-body > div { padding-left: 2em;
- padding-top: 1em; }
-body > div#mancgi { padding-left: 0em;
- padding-top: 0em; }
-body > div.results { font-size: smaller; }
-#mancgi fieldset { text-align: center;
- border: thin solid silver;
- border-radius: 1em;
- font-size: small; }
-#mancgi input[name=expr] { width: 25%; }
-.results td.title { vertical-align: top;
- padding-right: 1em; }
diff --git a/man.1 b/man.1
index 85802967e627..f29360bd5f06 100644
--- a/man.1
+++ b/man.1
@@ -1,4 +1,4 @@
-.\" $Id: man.1,v 1.13 2015/02/16 16:23:54 schwarze Exp $
+.\" $Id: man.1,v 1.16 2015/09/21 09:59:02 schwarze Exp $
.\"
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -31,7 +31,7 @@
.\"
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
.\"
-.Dd $Mdocdate: February 16 2015 $
+.Dd $Mdocdate: September 21 2015 $
.Dt MAN 1
.Os
.Sh NAME
@@ -173,12 +173,6 @@ must be a colon
separated list of directories.
This search path may also be set using the environment variable
.Ev MANPATH .
-The subdirectories to be searched, and their search order,
-are specified by the
-.Dq _subdir
-line in the
-.Nm
-configuration file.
.It Fl m Ar path
Augment the list of standard directories which
.Nm
@@ -194,12 +188,6 @@ the directories specified using the
option or the
.Ev MANPATH
environment variable.
-The subdirectories to be searched, and their search order,
-are specified by the
-.Dq _subdir
-line in the
-.Nm
-configuration file.
.It Fl O Ar option Ns = Ns Ar value
Comma-separated output options.
For each output format, the available options are described in the
@@ -360,6 +348,13 @@ Any non-empty value of the environment variable
.Ev MANPAGER
will be used instead of the standard pagination program,
.Xr more 1 .
+If
+.Xr less 1
+is used, the interactive
+.Ic :t
+command can be used to go to the definitions of various terms, for
+example command line options, command modifiers, internal commands,
+and environment variables.
.It Ev MANPATH
The standard search path used by
.Nm
@@ -370,18 +365,13 @@ variable.
The format of the path is a colon
.Pq Ql \&:
separated list of directories.
-The subdirectories to be searched, as well as their search order,
-are specified by the
-.Dq _subdir
-line in the
-.Nm
-configuration file.
.It Ev PAGER
Specifies the pagination program to use when
.Ev MANPAGER
is not defined.
If neither PAGER nor MANPAGER is defined,
-.Pa /usr/bin/more Fl s
+.Xr more 1
+.Fl s
will be used.
.El
.Sh FILES
diff --git a/man.c b/man.c
index 4e7a398d9bbe..31c094e8d62c 100644
--- a/man.c
+++ b/man.c
@@ -1,4 +1,4 @@
-/* $Id: man.c,v 1.149 2015/01/30 21:28:46 schwarze Exp $ */
+/* $Id: man.c,v 1.166 2015/10/22 21:54:23 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -8,9 +8,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -27,11 +27,13 @@
#include <stdio.h>
#include <string.h>
-#include "man.h"
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "libman.h"
+#include "mandoc.h"
+#include "roff.h"
+#include "man.h"
#include "libmandoc.h"
+#include "roff_int.h"
+#include "libman.h"
const char *const __man_macronames[MAN_MAX] = {
"br", "TH", "SH", "SS",
@@ -48,306 +50,25 @@ const char *const __man_macronames[MAN_MAX] = {
const char * const *man_macronames = __man_macronames;
-static void man_alloc1(struct man *);
-static void man_breakscope(struct man *, enum mant);
-static void man_descope(struct man *, int, int);
-static void man_free1(struct man *);
-static struct man_node *man_node_alloc(struct man *, int, int,
- enum man_type, enum mant);
-static void man_node_append(struct man *, struct man_node *);
-static void man_node_free(struct man_node *);
-static void man_node_unlink(struct man *,
- struct man_node *);
-static int man_ptext(struct man *, int, char *, int);
-static int man_pmacro(struct man *, int, char *, int);
-
-
-const struct man_node *
-man_node(const struct man *man)
-{
-
- return(man->first);
-}
-
-const struct man_meta *
-man_meta(const struct man *man)
-{
-
- return(&man->meta);
-}
-
-void
-man_reset(struct man *man)
-{
-
- man_free1(man);
- man_alloc1(man);
-}
-
-void
-man_free(struct man *man)
-{
-
- man_free1(man);
- free(man);
-}
-
-struct man *
-man_alloc(struct roff *roff, struct mparse *parse,
- const char *defos, int quick)
-{
- struct man *p;
-
- p = mandoc_calloc(1, sizeof(struct man));
-
- man_hash_init();
- p->parse = parse;
- p->defos = defos;
- p->quick = quick;
- p->roff = roff;
-
- man_alloc1(p);
- return(p);
-}
-
-void
-man_endparse(struct man *man)
-{
+static void man_descope(struct roff_man *, int, int);
+static int man_ptext(struct roff_man *, int, char *, int);
+static int man_pmacro(struct roff_man *, int, char *, int);
- man_macroend(man);
-}
int
-man_parseln(struct man *man, int ln, char *buf, int offs)
+man_parseln(struct roff_man *man, int ln, char *buf, int offs)
{
- if (man->last->type != MAN_EQN || ln > man->last->line)
+ if (man->last->type != ROFFT_EQN || ln > man->last->line)
man->flags |= MAN_NEWLINE;
- return (roff_getcontrol(man->roff, buf, &offs) ?
+ return roff_getcontrol(man->roff, buf, &offs) ?
man_pmacro(man, ln, buf, offs) :
- man_ptext(man, ln, buf, offs));
-}
-
-static void
-man_free1(struct man *man)
-{
-
- if (man->first)
- man_node_delete(man, man->first);
- free(man->meta.title);
- free(man->meta.source);
- free(man->meta.date);
- free(man->meta.vol);
- free(man->meta.msec);
-}
-
-static void
-man_alloc1(struct man *man)
-{
-
- memset(&man->meta, 0, sizeof(struct man_meta));
- man->flags = 0;
- man->last = mandoc_calloc(1, sizeof(struct man_node));
- man->first = man->last;
- man->last->type = MAN_ROOT;
- man->last->tok = MAN_MAX;
- man->next = MAN_NEXT_CHILD;
-}
-
-
-static void
-man_node_append(struct man *man, struct man_node *p)
-{
-
- assert(man->last);
- assert(man->first);
- assert(p->type != MAN_ROOT);
-
- switch (man->next) {
- case MAN_NEXT_SIBLING:
- man->last->next = p;
- p->prev = man->last;
- p->parent = man->last->parent;
- break;
- case MAN_NEXT_CHILD:
- man->last->child = p;
- p->parent = man->last;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- assert(p->parent);
- p->parent->nchild++;
-
- switch (p->type) {
- case MAN_BLOCK:
- if (p->tok == MAN_SH || p->tok == MAN_SS)
- man->flags &= ~MAN_LITERAL;
- break;
- case MAN_HEAD:
- assert(p->parent->type == MAN_BLOCK);
- p->parent->head = p;
- break;
- case MAN_BODY:
- assert(p->parent->type == MAN_BLOCK);
- p->parent->body = p;
- break;
- default:
- break;
- }
-
- man->last = p;
-
- switch (p->type) {
- case MAN_TBL:
- /* FALLTHROUGH */
- case MAN_TEXT:
- man_valid_post(man);
- break;
- default:
- break;
- }
-}
-
-static struct man_node *
-man_node_alloc(struct man *man, int line, int pos,
- enum man_type type, enum mant tok)
-{
- struct man_node *p;
-
- p = mandoc_calloc(1, sizeof(struct man_node));
- p->line = line;
- p->pos = pos;
- p->type = type;
- p->tok = tok;
-
- if (man->flags & MAN_NEWLINE)
- p->flags |= MAN_LINE;
- man->flags &= ~MAN_NEWLINE;
- return(p);
-}
-
-void
-man_elem_alloc(struct man *man, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(man, line, pos, MAN_ELEM, tok);
- man_node_append(man, p);
- man->next = MAN_NEXT_CHILD;
-}
-
-void
-man_head_alloc(struct man *man, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(man, line, pos, MAN_HEAD, tok);
- man_node_append(man, p);
- man->next = MAN_NEXT_CHILD;
-}
-
-void
-man_body_alloc(struct man *man, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(man, line, pos, MAN_BODY, tok);
- man_node_append(man, p);
- man->next = MAN_NEXT_CHILD;
-}
-
-void
-man_block_alloc(struct man *man, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(man, line, pos, MAN_BLOCK, tok);
- man_node_append(man, p);
- man->next = MAN_NEXT_CHILD;
-}
-
-void
-man_word_alloc(struct man *man, int line, int pos, const char *word)
-{
- struct man_node *n;
-
- n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX);
- n->string = roff_strdup(man->roff, word);
- man_node_append(man, n);
- man->next = MAN_NEXT_SIBLING;
-}
-
-void
-man_word_append(struct man *man, const char *word)
-{
- struct man_node *n;
- char *addstr, *newstr;
-
- n = man->last;
- addstr = roff_strdup(man->roff, word);
- mandoc_asprintf(&newstr, "%s %s", n->string, addstr);
- free(addstr);
- free(n->string);
- n->string = newstr;
- man->next = MAN_NEXT_SIBLING;
-}
-
-/*
- * Free all of the resources held by a node. This does NOT unlink a
- * node from its context; for that, see man_node_unlink().
- */
-static void
-man_node_free(struct man_node *p)
-{
-
- free(p->string);
- free(p);
-}
-
-void
-man_node_delete(struct man *man, struct man_node *p)
-{
-
- while (p->child)
- man_node_delete(man, p->child);
-
- man_node_unlink(man, p);
- man_node_free(p);
-}
-
-void
-man_addeqn(struct man *man, const struct eqn *ep)
-{
- struct man_node *n;
-
- n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
- n->eqn = ep;
- if (ep->ln > man->last->line)
- n->flags |= MAN_LINE;
- man_node_append(man, n);
- man->next = MAN_NEXT_SIBLING;
- man_descope(man, ep->ln, ep->pos);
-}
-
-void
-man_addspan(struct man *man, const struct tbl_span *sp)
-{
- struct man_node *n;
-
- man_breakscope(man, MAN_MAX);
- n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX);
- n->span = sp;
- man_node_append(man, n);
- man->next = MAN_NEXT_SIBLING;
- man_descope(man, sp->line, 0);
+ man_ptext(man, ln, buf, offs);
}
static void
-man_descope(struct man *man, int line, int offs)
+man_descope(struct roff_man *man, int line, int offs)
{
/*
* Co-ordinate what happens with having a next-line scope open:
@@ -363,20 +84,20 @@ man_descope(struct man *man, int line, int offs)
return;
man->flags &= ~MAN_BLINE;
man_unscope(man, man->last->parent);
- man_body_alloc(man, line, offs, man->last->tok);
+ roff_body_alloc(man, line, offs, man->last->tok);
}
static int
-man_ptext(struct man *man, int line, char *buf, int offs)
+man_ptext(struct roff_man *man, int line, char *buf, int offs)
{
int i;
/* Literal free-form text whitespace is preserved. */
if (man->flags & MAN_LITERAL) {
- man_word_alloc(man, line, offs, buf + offs);
+ roff_word_alloc(man, line, offs, buf + offs);
man_descope(man, line, offs);
- return(1);
+ return 1;
}
for (i = offs; buf[i] == ' '; i++)
@@ -391,10 +112,10 @@ man_ptext(struct man *man, int line, char *buf, int offs)
/* Allocate a blank entry. */
if (man->last->tok != MAN_SH &&
man->last->tok != MAN_SS) {
- man_elem_alloc(man, line, offs, MAN_sp);
- man->next = MAN_NEXT_SIBLING;
+ roff_elem_alloc(man, line, offs, MAN_sp);
+ man->next = ROFF_NEXT_SIBLING;
}
- return(1);
+ return 1;
}
/*
@@ -418,7 +139,7 @@ man_ptext(struct man *man, int line, char *buf, int offs)
buf[i] = '\0';
}
- man_word_alloc(man, line, offs, buf + offs);
+ roff_word_alloc(man, line, offs, buf + offs);
/*
* End-of-sentence check. If the last character is an unescaped
@@ -431,15 +152,15 @@ man_ptext(struct man *man, int line, char *buf, int offs)
man->last->flags |= MAN_EOS;
man_descope(man, line, offs);
- return(1);
+ return 1;
}
static int
-man_pmacro(struct man *man, int ln, char *buf, int offs)
+man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
{
- struct man_node *n;
+ struct roff_node *n;
const char *cp;
- enum mant tok;
+ int tok;
int i, ppos;
int bline;
char mac[5];
@@ -457,12 +178,12 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
mac[i] = '\0';
- tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
+ tok = (i > 0 && i < 4) ? man_hash_find(mac) : TOKEN_NONE;
- if (tok == MAN_MAX) {
+ if (tok == TOKEN_NONE) {
mandoc_msg(MANDOCERR_MACRO, man->parse,
ln, ppos, buf + ppos - 1);
- return(1);
+ return 1;
}
/* Skip a leading escape sequence or tab. */
@@ -511,9 +232,9 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
if (man->quick && tok == MAN_SH) {
n = man->last;
- if (n->type == MAN_BODY &&
+ if (n->type == ROFFT_BODY &&
strcmp(n->prev->child->string, "NAME"))
- return(2);
+ return 2;
}
/*
@@ -524,20 +245,20 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
if ( ! bline || man->flags & MAN_ELINE ||
man_macros[tok].flags & MAN_NSCOPED)
- return(1);
+ return 1;
assert(man->flags & MAN_BLINE);
man->flags &= ~MAN_BLINE;
man_unscope(man, man->last->parent);
- man_body_alloc(man, ln, ppos, man->last->tok);
- return(1);
+ roff_body_alloc(man, ln, ppos, man->last->tok);
+ return 1;
}
void
-man_breakscope(struct man *man, enum mant tok)
+man_breakscope(struct roff_man *man, int tok)
{
- struct man_node *n;
+ struct roff_node *n;
/*
* An element next line scope is open,
@@ -545,142 +266,104 @@ man_breakscope(struct man *man, enum mant tok)
* Delete the element that is being broken.
*/
- if (man->flags & MAN_ELINE && (tok == MAN_MAX ||
+ if (man->flags & MAN_ELINE && (tok == TOKEN_NONE ||
! (man_macros[tok].flags & MAN_NSCOPED))) {
n = man->last;
- assert(n->type != MAN_TEXT);
+ assert(n->type != ROFFT_TEXT);
if (man_macros[n->tok].flags & MAN_NSCOPED)
n = n->parent;
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
n->line, n->pos, "%s breaks %s",
- tok == MAN_MAX ? "TS" : man_macronames[tok],
+ tok == TOKEN_NONE ? "TS" : man_macronames[tok],
man_macronames[n->tok]);
- man_node_delete(man, n);
+ roff_node_delete(man, n);
man->flags &= ~MAN_ELINE;
}
/*
+ * Weird special case:
+ * Switching fill mode closes section headers.
+ */
+
+ if (man->flags & MAN_BLINE &&
+ (tok == MAN_nf || tok == MAN_fi) &&
+ (man->last->tok == MAN_SH || man->last->tok == MAN_SS)) {
+ n = man->last;
+ man_unscope(man, n);
+ roff_body_alloc(man, n->line, n->pos, n->tok);
+ man->flags &= ~MAN_BLINE;
+ }
+
+ /*
* A block header next line scope is open,
* and the new macro is not allowed inside block headers.
* Delete the block that is being broken.
*/
- if (man->flags & MAN_BLINE && (tok == MAN_MAX ||
+ if (man->flags & MAN_BLINE && (tok == TOKEN_NONE ||
man_macros[tok].flags & MAN_BSCOPE)) {
n = man->last;
- if (n->type == MAN_TEXT)
+ if (n->type == ROFFT_TEXT)
n = n->parent;
if ( ! (man_macros[n->tok].flags & MAN_BSCOPE))
n = n->parent;
- assert(n->type == MAN_HEAD);
+ assert(n->type == ROFFT_HEAD);
n = n->parent;
- assert(n->type == MAN_BLOCK);
+ assert(n->type == ROFFT_BLOCK);
assert(man_macros[n->tok].flags & MAN_SCOPED);
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
n->line, n->pos, "%s breaks %s",
- tok == MAN_MAX ? "TS" : man_macronames[tok],
+ tok == TOKEN_NONE ? "TS" : man_macronames[tok],
man_macronames[n->tok]);
- man_node_delete(man, n);
+ roff_node_delete(man, n);
man->flags &= ~MAN_BLINE;
}
}
-/*
- * Unlink a node from its context. If "man" is provided, the last parse
- * point will also be adjusted accordingly.
- */
-static void
-man_node_unlink(struct man *man, struct man_node *n)
-{
-
- /* Adjust siblings. */
-
- if (n->prev)
- n->prev->next = n->next;
- if (n->next)
- n->next->prev = n->prev;
-
- /* Adjust parent. */
-
- if (n->parent) {
- n->parent->nchild--;
- if (n->parent->child == n)
- n->parent->child = n->prev ? n->prev : n->next;
- }
-
- /* Adjust parse point, if applicable. */
-
- if (man && man->last == n) {
- /*XXX: this can occur when bailing from validation. */
- /*assert(NULL == n->next);*/
- if (n->prev) {
- man->last = n->prev;
- man->next = MAN_NEXT_SIBLING;
- } else {
- man->last = n->parent;
- man->next = MAN_NEXT_CHILD;
- }
- }
-
- if (man && man->first == n)
- man->first = NULL;
-}
-
const struct mparse *
-man_mparse(const struct man *man)
+man_mparse(const struct roff_man *man)
{
assert(man && man->parse);
- return(man->parse);
+ return man->parse;
}
void
-man_deroff(char **dest, const struct man_node *n)
+man_state(struct roff_man *man, struct roff_node *n)
{
- char *cp;
- size_t sz;
-
- if (n->type != MAN_TEXT) {
- for (n = n->child; n; n = n->next)
- man_deroff(dest, n);
- return;
- }
- /* Skip leading whitespace and escape sequences. */
-
- cp = n->string;
- while ('\0' != *cp) {
- if ('\\' == *cp) {
- cp++;
- mandoc_escape((const char **)&cp, NULL, NULL);
- } else if (isspace((unsigned char)*cp))
- cp++;
- else
- break;
+ switch(n->tok) {
+ case MAN_nf:
+ case MAN_EX:
+ if (man->flags & MAN_LITERAL && ! (n->flags & MAN_VALID))
+ mandoc_msg(MANDOCERR_NF_SKIP, man->parse,
+ n->line, n->pos, "nf");
+ man->flags |= MAN_LITERAL;
+ break;
+ case MAN_fi:
+ case MAN_EE:
+ if ( ! (man->flags & MAN_LITERAL) &&
+ ! (n->flags & MAN_VALID))
+ mandoc_msg(MANDOCERR_FI_SKIP, man->parse,
+ n->line, n->pos, "fi");
+ man->flags &= ~MAN_LITERAL;
+ break;
+ default:
+ break;
}
+ man->last->flags |= MAN_VALID;
+}
- /* Skip trailing whitespace. */
-
- for (sz = strlen(cp); sz; sz--)
- if (0 == isspace((unsigned char)cp[sz-1]))
- break;
-
- /* Skip empty strings. */
-
- if (0 == sz)
- return;
-
- if (NULL == *dest) {
- *dest = mandoc_strndup(cp, sz);
- return;
- }
+void
+man_validate(struct roff_man *man)
+{
- mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp);
- free(*dest);
- *dest = cp;
+ man->last = man->first;
+ man_node_validate(man);
+ man->flags &= ~MAN_LITERAL;
}
diff --git a/man.cgi.8 b/man.cgi.8
index 4d3588b01607..2e54dbf4b81f 100644
--- a/man.cgi.8
+++ b/man.cgi.8
@@ -1,4 +1,4 @@
-.\" $Id: man.cgi.8,v 1.11 2014/09/14 19:44:28 schwarze Exp $
+.\" $Id: man.cgi.8,v 1.13 2015/11/05 20:55:41 schwarze Exp $
.\"
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,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: September 14 2014 $
+.Dd $Mdocdate: November 5 2015 $
.Dt MAN.CGI 8
.Os
.Sh NAME
@@ -161,6 +161,9 @@ database inside each manpath.
Configure your web server to execute CGI programs located in
.Pa /cgi-bin .
When using
+.Ox
+.Xr httpd 8
+or
.Xr nginx 8 ,
the
.Xr slowcgi 8
@@ -187,14 +190,8 @@ and to be specified without a trailing slash.
When not specified, the CSS files
are assumed to be in the document root.
This is used in generated HTML code.
-.It Ev CUSTOMIZE_BEGIN
-A HTML string to be inserted right after opening the
-.Aq BODY
-element.
.It Ev CUSTOMIZE_TITLE
-An ASCII string to be used for the HTML
-.Aq TITLE
-element.
+An ASCII string to be used for the HTML <TITLE> element.
.It Ev HTTP_HOST
The FQDN of the (possibly virtual) host the HTTP server is running on.
This is used for
@@ -349,15 +346,10 @@ Can be overridden by
The path to the server document root relative to the server root.
This is part of the web server configuration and not specific to
.Nm .
-.It Pa /htdocs/man-cgi.css
-A style sheet for general
-.Nm
-styling, referenced from each generated HTML page.
-.It Pa /htdocs/man.css
+.It Pa /htdocs/mandoc.css
A style sheet for
.Xr mandoc 1
-HTML styling, referenced from each generated HTML page after
-.Pa man-cgi.css .
+HTML styling, referenced from each generated HTML page.
.It Pa /man
Default
.Nm
@@ -376,6 +368,12 @@ or any character not contained in the
.Sx Restricted character set ,
.Nm
reports an internal server error and exits without doing anything.
+.It Pa /man/header.html
+An optional file containing static HTML code to be inserted right
+after opening the <BODY> element.
+.It Pa /man/footer.html
+An optional file containing static HTML code to be inserted right
+before closing the <BODY> element.
.It Pa /man/OpenBSD-current/man1/mandoc.1
An example
.Xr mdoc 7
diff --git a/man.conf.5 b/man.conf.5
new file mode 100644
index 000000000000..9cfeca761d3b
--- /dev/null
+++ b/man.conf.5
@@ -0,0 +1,131 @@
+.\" $Id: man.conf.5,v 1.3 2015/03/27 21:33:20 schwarze Exp $
+.\"
+.\" Copyright (c) 2015 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.
+.\"
+.Dd $Mdocdate: March 27 2015 $
+.Dt MAN.CONF 5
+.Os
+.Sh NAME
+.Nm man.conf
+.Nd configuration file for man
+.Sh DESCRIPTION
+This is the configuration file
+for the
+.Xr man 1 ,
+.Xr apropos 1 ,
+and
+.Xr makewhatis 8
+utilities.
+Its presence, and all directives, are optional.
+.Pp
+This file is an ASCII text file.
+Leading whitespace on lines, lines starting with
+.Sq # ,
+and blank lines are ignored.
+Words are separated by whitespace.
+The first word on each line is the name of a configuration directive.
+.Pp
+The following directives are supported:
+.Bl -tag -width Ds
+.It Ic manpath Ar path
+Override the default search
+.Ar path
+for
+.Xr man 1 ,
+.Xr apropos 1 ,
+and
+.Xr makewhatis 8 .
+It can be used multiple times to specify multiple paths,
+with the order determining the manual page search order.
+.Pp
+Each path is a tree containing subdirectories
+whose names consist of the strings
+.Sq man
+and/or
+.Sq cat
+followed by the names of sections, usually single digits.
+The former are supposed to contain unformatted manual pages in
+.Xr mdoc 7
+and/or
+.Xr man 7
+format; file names should end with the name of the section
+preceded by a dot.
+The latter should contain preformatted manual pages;
+file names should end with
+.Ql .0 .
+.Pp
+Creating a
+.Xr mandoc.db 5
+database with
+.Xr makewhatis 8
+in each directory configured with
+.Ic manpath
+is recommended and necessary for
+.Xr apropos 1
+to work, but not strictly required for
+.Xr man 1 .
+.It Ic output Ar option Op Ar value
+Configure the default value of an output option.
+These directives are overridden by the
+.Fl O
+command line options of the same names.
+For details, see the
+.Xr mandoc 1
+manual.
+.Pp
+.Bl -column fragment integer "ascii, utf8" -compact
+.It Ar option Ta Ar value Ta used by Fl T Ta purpose
+.It Ta Ta Ta
+.It Ic fragment Ta none Ta Cm html Ta print only body
+.It Ic includes Ta string Ta Cm html Ta path to header files
+.It Ic indent Ta integer Ta Cm ascii , utf8 Ta left margin
+.It Ic man Ta string Ta Cm html Ta path for Xr links
+.It Ic paper Ta string Ta Cm ps , pdf Ta paper size
+.It Ic style Ta string Ta Cm html Ta CSS file
+.It Ic width Ta integer Ta Cm ascii , utf8 Ta right margin
+.El
+.It Ic _whatdb Ar path Ns Cm /whatis.db
+This directive provides the same functionality as
+.Ic manpath ,
+but using a historic and misleading syntax.
+It is kept for backward compatibility for now,
+but will eventually be removed.
+.El
+.Sh FILES
+.Pa /etc/man.conf
+.Sh EXAMPLES
+The following configuration file reproduces the defaults:
+installing it is equivalent to not having a
+.Nm
+file at all.
+.Bd -literal -offset indent
+manpath /usr/share/man
+manpath /usr/X11R6/man
+manpath /usr/local/man
+.Ed
+.Sh SEE ALSO
+.Xr apropos 1 ,
+.Xr man 1 ,
+.Xr makewhatis 8
+.Sh HISTORY
+A relatively complicated
+.Nm
+file format first appeared in
+.Bx 4.3 Reno .
+For
+.Ox 5.8 ,
+it was redesigned from scratch, aiming for simplicity.
+.Sh AUTHORS
+.An Ingo Schwarze Aq Mt schwarze@openbsd.org
diff --git a/man.h b/man.h
index 9e8eb03e5717..8f63f3b99ecd 100644
--- a/man.h
+++ b/man.h
@@ -1,116 +1,66 @@
-/* $Id: man.h,v 1.69 2015/01/24 02:41:49 schwarze Exp $ */
+/* $Id: man.h,v 1.77 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2015 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
*/
-enum mant {
- MAN_br = 0,
- MAN_TH,
- MAN_SH,
- MAN_SS,
- MAN_TP,
- MAN_LP,
- MAN_PP,
- MAN_P,
- MAN_IP,
- MAN_HP,
- MAN_SM,
- MAN_SB,
- MAN_BI,
- MAN_IB,
- MAN_BR,
- MAN_RB,
- MAN_R,
- MAN_B,
- MAN_I,
- MAN_IR,
- MAN_RI,
- MAN_sp,
- MAN_nf,
- MAN_fi,
- MAN_RE,
- MAN_RS,
- MAN_DT,
- MAN_UC,
- MAN_PD,
- MAN_AT,
- MAN_in,
- MAN_ft,
- MAN_OP,
- MAN_EX,
- MAN_EE,
- MAN_UR,
- MAN_UE,
- MAN_ll,
- MAN_MAX
-};
+#define MAN_br 0
+#define MAN_TH 1
+#define MAN_SH 2
+#define MAN_SS 3
+#define MAN_TP 4
+#define MAN_LP 5
+#define MAN_PP 6
+#define MAN_P 7
+#define MAN_IP 8
+#define MAN_HP 9
+#define MAN_SM 10
+#define MAN_SB 11
+#define MAN_BI 12
+#define MAN_IB 13
+#define MAN_BR 14
+#define MAN_RB 15
+#define MAN_R 16
+#define MAN_B 17
+#define MAN_I 18
+#define MAN_IR 19
+#define MAN_RI 20
+#define MAN_sp 21
+#define MAN_nf 22
+#define MAN_fi 23
+#define MAN_RE 24
+#define MAN_RS 25
+#define MAN_DT 26
+#define MAN_UC 27
+#define MAN_PD 28
+#define MAN_AT 29
+#define MAN_in 30
+#define MAN_ft 31
+#define MAN_OP 32
+#define MAN_EX 33
+#define MAN_EE 34
+#define MAN_UR 35
+#define MAN_UE 36
+#define MAN_ll 37
+#define MAN_MAX 38
-enum man_type {
- MAN_TEXT,
- MAN_ELEM,
- MAN_ROOT,
- MAN_BLOCK,
- MAN_HEAD,
- MAN_BODY,
- MAN_TBL,
- MAN_EQN
-};
-
-struct man_meta {
- char *msec; /* `TH' section (1, 3p, etc.) */
- char *date; /* `TH' normalised date */
- char *vol; /* `TH' volume */
- char *title; /* `TH' title (e.g., FOO) */
- char *source; /* `TH' source (e.g., GNU) */
- int hasbody; /* document is not empty */
-};
-
-struct man_node {
- struct man_node *parent; /* parent AST node */
- struct man_node *child; /* first child AST node */
- struct man_node *next; /* sibling AST node */
- struct man_node *prev; /* prior sibling AST node */
- int nchild; /* number children */
- int line;
- int pos;
- enum mant tok; /* tok or MAN__MAX if none */
- int flags;
-#define MAN_VALID (1 << 0) /* has been validated */
-#define MAN_EOS (1 << 2) /* at sentence boundary */
-#define MAN_LINE (1 << 3) /* first macro/text on line */
- enum man_type type; /* AST node type */
- char *string; /* TEXT node argument */
- struct man_node *head; /* BLOCK node HEAD ptr */
- struct man_node *tail; /* BLOCK node TAIL ptr */
- struct man_node *body; /* BLOCK node BODY ptr */
- const struct tbl_span *span; /* TBL */
- const struct eqn *eqn; /* EQN */
- int aux; /* decoded node data, type-dependent */
-};
-
-/* Names of macros. Index is enum mant. */
+/* Names of macros. */
extern const char *const *man_macronames;
-__BEGIN_DECLS
-
-struct man;
-const struct man_node *man_node(const struct man *);
-const struct man_meta *man_meta(const struct man *);
-const struct mparse *man_mparse(const struct man *);
-void man_deroff(char **, const struct man_node *);
+struct roff_man;
-__END_DECLS
+const struct mparse *man_mparse(const struct roff_man *);
+void man_validate(struct roff_man *);
diff --git a/man_hash.c b/man_hash.c
index 1cbfb1b7f8e6..8573994e5d53 100644
--- a/man_hash.c
+++ b/man_hash.c
@@ -1,6 +1,7 @@
-/* $Id: man_hash.c,v 1.29 2014/12/01 08:05:52 schwarze Exp $ */
+/* $Id: man_hash.c,v 1.34 2015/10/06 18:32:19 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2015 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
@@ -23,6 +24,7 @@
#include <limits.h>
#include <string.h>
+#include "roff.h"
#include "man.h"
#include "libman.h"
@@ -46,18 +48,15 @@
static unsigned char table[26 * HASH_DEPTH];
-/*
- * XXX - this hash has global scope, so if intended for use as a library
- * with multiple callers, it will need re-invocation protection.
- */
void
man_hash_init(void)
{
int i, j, x;
- memset(table, UCHAR_MAX, sizeof(table));
+ if (*table != '\0')
+ return;
- assert(MAN_MAX < UCHAR_MAX);
+ memset(table, UCHAR_MAX, sizeof(table));
for (i = 0; i < (int)MAN_MAX; i++) {
x = man_macronames[i][0];
@@ -76,27 +75,27 @@ man_hash_init(void)
}
}
-enum mant
+int
man_hash_find(const char *tmp)
{
int x, y, i;
- enum mant tok;
+ int tok;
if ('\0' == (x = tmp[0]))
- return(MAN_MAX);
+ return TOKEN_NONE;
if ( ! (isalpha((unsigned char)x)))
- return(MAN_MAX);
+ return TOKEN_NONE;
HASH_ROW(x);
for (i = 0; i < HASH_DEPTH; i++) {
if (UCHAR_MAX == (y = table[x + i]))
- return(MAN_MAX);
+ return TOKEN_NONE;
- tok = (enum mant)y;
+ tok = y;
if (0 == strcmp(tmp, man_macronames[tok]))
- return(tok);
+ return tok;
}
- return(MAN_MAX);
+ return TOKEN_NONE;
}
diff --git a/man_html.c b/man_html.c
index 110941502587..d71eb3823798 100644
--- a/man_html.c
+++ b/man_html.c
@@ -1,4 +1,4 @@
-/* $Id: man_html.c,v 1.112 2015/03/03 21:11:34 schwarze Exp $ */
+/* $Id: man_html.c,v 1.120 2016/01/08 17:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,9 +7,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -26,6 +26,7 @@
#include <string.h>
#include "mandoc_aux.h"
+#include "roff.h"
#include "man.h"
#include "out.h"
#include "html.h"
@@ -36,8 +37,8 @@
#define INDENT 5
-#define MAN_ARGS const struct man_meta *man, \
- const struct man_node *n, \
+#define MAN_ARGS const struct roff_meta *man, \
+ const struct roff_node *n, \
struct mhtml *mh, \
struct html *h
@@ -52,12 +53,11 @@ struct htmlman {
};
static void print_bvspace(struct html *,
- const struct man_node *);
-static void print_man(MAN_ARGS);
+ const struct roff_node *);
static void print_man_head(MAN_ARGS);
static void print_man_nodelist(MAN_ARGS);
static void print_man_node(MAN_ARGS);
-static int a2width(const struct man_node *,
+static int a2width(const struct roff_node *,
struct roffsu *);
static int man_B_pre(MAN_ARGS);
static int man_HP_pre(MAN_ARGS);
@@ -129,14 +129,14 @@ static const struct htmlman mans[MAN_MAX] = {
* first, print it.
*/
static void
-print_bvspace(struct html *h, const struct man_node *n)
+print_bvspace(struct html *h, const struct roff_node *n)
{
if (n->body && n->body->child)
- if (MAN_TBL == n->body->child->type)
+ if (n->body->child->type == ROFFT_TBL)
return;
- if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
+ if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
if (NULL == n->prev)
return;
@@ -144,36 +144,31 @@ print_bvspace(struct html *h, const struct man_node *n)
}
void
-html_man(void *arg, const struct man *man)
+html_man(void *arg, const struct roff_man *man)
{
struct mhtml mh;
-
- memset(&mh, 0, sizeof(struct mhtml));
- print_man(man_meta(man), man_node(man), &mh, (struct html *)arg);
- putchar('\n');
-}
-
-static void
-print_man(MAN_ARGS)
-{
- struct tag *t, *tt;
struct htmlpair tag;
+ struct html *h;
+ struct tag *t, *tt;
+ memset(&mh, 0, sizeof(mh));
PAIR_CLASS_INIT(&tag, "mandoc");
+ h = (struct html *)arg;
if ( ! (HTML_FRAGMENT & h->oflags)) {
print_gen_decls(h);
t = print_otag(h, TAG_HTML, 0, NULL);
tt = print_otag(h, TAG_HEAD, 0, NULL);
- print_man_head(man, n, mh, h);
+ print_man_head(&man->meta, man->first, &mh, h);
print_tagq(h, tt);
print_otag(h, TAG_BODY, 0, NULL);
print_otag(h, TAG_DIV, 1, &tag);
} else
t = print_otag(h, TAG_DIV, 1, &tag);
- print_man_nodelist(man, n, mh, h);
+ print_man_nodelist(&man->meta, man->first, &mh, h);
print_tagq(h, t);
+ putchar('\n');
}
static void
@@ -208,10 +203,10 @@ print_man_node(MAN_ARGS)
t = h->tags.head;
switch (n->type) {
- case MAN_ROOT:
+ case ROFFT_ROOT:
man_root_pre(man, n, mh, h);
break;
- case MAN_TEXT:
+ case ROFFT_TEXT:
if ('\0' == *n->string) {
print_paragraph(h);
return;
@@ -222,12 +217,12 @@ print_man_node(MAN_ARGS)
print_otag(h, TAG_BR, 0, NULL);
print_text(h, n->string);
return;
- case MAN_EQN:
+ case ROFFT_EQN:
if (n->flags & MAN_LINE)
putchar('\n');
print_eqn(h, n->eqn);
break;
- case MAN_TBL:
+ case ROFFT_TBL:
/*
* This will take care of initialising all of the table
* state data for the first table, then tearing it down
@@ -266,10 +261,10 @@ print_man_node(MAN_ARGS)
print_stagq(h, t);
switch (n->type) {
- case MAN_ROOT:
+ case ROFFT_ROOT:
man_root_post(man, n, mh, h);
break;
- case MAN_EQN:
+ case ROFFT_EQN:
break;
default:
if (mans[n->tok].post)
@@ -279,15 +274,15 @@ print_man_node(MAN_ARGS)
}
static int
-a2width(const struct man_node *n, struct roffsu *su)
+a2width(const struct roff_node *n, struct roffsu *su)
{
- if (MAN_TEXT != n->type)
- return(0);
+ if (n->type != ROFFT_TEXT)
+ return 0;
if (a2roffsu(n->string, su, SCALE_EN))
- return(1);
+ return 1;
- return(0);
+ return 0;
}
static void
@@ -347,8 +342,8 @@ man_root_post(MAN_ARGS)
PAIR_CLASS_INIT(&tag, "foot-os");
print_otag(h, TAG_TD, 1, &tag);
- if (man->source)
- print_text(h, man->source);
+ if (man->os)
+ print_text(h, man->os);
print_tagq(h, t);
}
@@ -376,7 +371,7 @@ man_br_pre(MAN_ARGS)
/* So the div isn't empty: */
print_text(h, "\\~");
- return(0);
+ return 0;
}
static int
@@ -384,22 +379,22 @@ man_SH_pre(MAN_ARGS)
{
struct htmlpair tag;
- if (MAN_BLOCK == n->type) {
+ if (n->type == ROFFT_BLOCK) {
mh->fl &= ~MANH_LITERAL;
PAIR_CLASS_INIT(&tag, "section");
print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- } else if (MAN_BODY == n->type)
- return(1);
+ return 1;
+ } else if (n->type == ROFFT_BODY)
+ return 1;
print_otag(h, TAG_H1, 0, NULL);
- return(1);
+ return 1;
}
static int
man_alt_pre(MAN_ARGS)
{
- const struct man_node *nn;
+ const struct roff_node *nn;
int i, savelit;
enum htmltag fp;
struct tag *t;
@@ -432,7 +427,6 @@ man_alt_pre(MAN_ARGS)
break;
default:
abort();
- /* NOTREACHED */
}
if (i)
@@ -450,7 +444,7 @@ man_alt_pre(MAN_ARGS)
if (savelit)
mh->fl |= MANH_LITERAL;
- return(0);
+ return 0;
}
static int
@@ -460,7 +454,7 @@ man_SM_pre(MAN_ARGS)
print_otag(h, TAG_SMALL, 0, NULL);
if (MAN_SB == n->tok)
print_otag(h, TAG_B, 0, NULL);
- return(1);
+ return 1;
}
static int
@@ -468,41 +462,41 @@ man_SS_pre(MAN_ARGS)
{
struct htmlpair tag;
- if (MAN_BLOCK == n->type) {
+ if (n->type == ROFFT_BLOCK) {
mh->fl &= ~MANH_LITERAL;
PAIR_CLASS_INIT(&tag, "subsection");
print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- } else if (MAN_BODY == n->type)
- return(1);
+ return 1;
+ } else if (n->type == ROFFT_BODY)
+ return 1;
print_otag(h, TAG_H2, 0, NULL);
- return(1);
+ return 1;
}
static int
man_PP_pre(MAN_ARGS)
{
- if (MAN_HEAD == n->type)
- return(0);
- else if (MAN_BLOCK == n->type)
+ if (n->type == ROFFT_HEAD)
+ return 0;
+ else if (n->type == ROFFT_BLOCK)
print_bvspace(h, n);
- return(1);
+ return 1;
}
static int
man_IP_pre(MAN_ARGS)
{
- const struct man_node *nn;
+ const struct roff_node *nn;
- if (MAN_BODY == n->type) {
+ if (n->type == ROFFT_BODY) {
print_otag(h, TAG_DD, 0, NULL);
- return(1);
- } else if (MAN_HEAD != n->type) {
+ return 1;
+ } else if (n->type != ROFFT_HEAD) {
print_otag(h, TAG_DL, 0, NULL);
- return(1);
+ return 1;
}
/* FIXME: width specification. */
@@ -526,7 +520,7 @@ man_IP_pre(MAN_ARGS)
}
}
- return(0);
+ return 0;
}
static int
@@ -534,12 +528,12 @@ man_HP_pre(MAN_ARGS)
{
struct htmlpair tag[2];
struct roffsu su;
- const struct man_node *np;
+ const struct roff_node *np;
- if (MAN_HEAD == n->type)
- return(0);
- else if (MAN_BLOCK != n->type)
- return(1);
+ if (n->type == ROFFT_HEAD)
+ return 0;
+ else if (n->type != ROFFT_BLOCK)
+ return 1;
np = n->head->child;
@@ -555,7 +549,7 @@ man_HP_pre(MAN_ARGS)
PAIR_STYLE_INIT(&tag[0], h);
PAIR_CLASS_INIT(&tag[1], "spacer");
print_otag(h, TAG_DIV, 2, tag);
- return(1);
+ return 1;
}
static int
@@ -584,7 +578,7 @@ man_OP_pre(MAN_ARGS)
print_stagq(h, tt);
h->flags |= HTML_NOSPACE;
print_text(h, "]");
- return(0);
+ return 0;
}
static int
@@ -592,7 +586,7 @@ man_B_pre(MAN_ARGS)
{
print_otag(h, TAG_B, 0, NULL);
- return(1);
+ return 1;
}
static int
@@ -600,7 +594,7 @@ man_I_pre(MAN_ARGS)
{
print_otag(h, TAG_I, 0, NULL);
- return(1);
+ return 1;
}
static int
@@ -613,7 +607,7 @@ man_literal_pre(MAN_ARGS)
} else
mh->fl |= MANH_LITERAL;
- return(0);
+ return 0;
}
static int
@@ -621,14 +615,14 @@ man_in_pre(MAN_ARGS)
{
print_otag(h, TAG_BR, 0, NULL);
- return(0);
+ return 0;
}
static int
man_ign_pre(MAN_ARGS)
{
- return(0);
+ return 0;
}
static int
@@ -637,10 +631,10 @@ man_RS_pre(MAN_ARGS)
struct htmlpair tag;
struct roffsu su;
- if (MAN_HEAD == n->type)
- return(0);
- else if (MAN_BODY == n->type)
- return(1);
+ if (n->type == ROFFT_HEAD)
+ return 0;
+ else if (n->type == ROFFT_BODY)
+ return 1;
SCALE_HS_INIT(&su, INDENT);
if (n->head->child)
@@ -650,7 +644,7 @@ man_RS_pre(MAN_ARGS)
bufcat_su(h, "margin-left", &su);
PAIR_STYLE_INIT(&tag, h);
print_otag(h, TAG_DIV, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -659,19 +653,19 @@ man_UR_pre(MAN_ARGS)
struct htmlpair tag[2];
n = n->child;
- assert(MAN_HEAD == n->type);
- if (n->nchild) {
- assert(MAN_TEXT == n->child->type);
+ assert(n->type == ROFFT_HEAD);
+ if (n->child != NULL) {
+ assert(n->child->type == ROFFT_TEXT);
PAIR_CLASS_INIT(&tag[0], "link-ext");
PAIR_HREF_INIT(&tag[1], n->child->string);
print_otag(h, TAG_A, 2, tag);
}
- assert(MAN_BODY == n->next->type);
- if (n->next->nchild)
+ assert(n->next->type == ROFFT_BODY);
+ if (n->next->child != NULL)
n = n->next;
print_man_nodelist(man, n->child, mh, h);
- return(0);
+ return 0;
}
diff --git a/man_macro.c b/man_macro.c
index c86ab6f13f01..d15335709eca 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -1,4 +1,4 @@
-/* $Id: man_macro.c,v 1.98 2015/02/06 11:54:36 schwarze Exp $ */
+/* $Id: man_macro.c,v 1.114 2016/01/08 17:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2012, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -8,9 +8,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -25,37 +25,27 @@
#include <stdlib.h>
#include <string.h>
-#include "man.h"
#include "mandoc.h"
+#include "roff.h"
+#include "man.h"
#include "libmandoc.h"
+#include "roff_int.h"
#include "libman.h"
-enum rew {
- REW_REWIND,
- REW_NOHALT,
- REW_HALT
-};
-
static void blk_close(MACRO_PROT_ARGS);
static void blk_exp(MACRO_PROT_ARGS);
static void blk_imp(MACRO_PROT_ARGS);
static void in_line_eoln(MACRO_PROT_ARGS);
-static int man_args(struct man *, int,
+static int man_args(struct roff_man *, int,
int *, char *, char **);
-
-static void rew_scope(enum man_type,
- struct man *, enum mant);
-static enum rew rew_dohalt(enum mant, enum man_type,
- const struct man_node *);
-static enum rew rew_block(enum mant, enum man_type,
- const struct man_node *);
+static void rew_scope(struct roff_man *, int);
const struct man_macro __man_macros[MAN_MAX] = {
{ in_line_eoln, MAN_NSCOPED }, /* br */
{ in_line_eoln, MAN_BSCOPE }, /* TH */
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SH */
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SS */
- { blk_imp, MAN_BSCOPE | MAN_SCOPED | MAN_FSCOPED }, /* TP */
+ { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* TP */
{ blk_imp, MAN_BSCOPE }, /* LP */
{ blk_imp, MAN_BSCOPE }, /* PP */
{ blk_imp, MAN_BSCOPE }, /* P */
@@ -73,20 +63,20 @@ const struct man_macro __man_macros[MAN_MAX] = {
{ in_line_eoln, 0 }, /* IR */
{ in_line_eoln, 0 }, /* RI */
{ in_line_eoln, MAN_NSCOPED }, /* sp */
- { in_line_eoln, MAN_BSCOPE }, /* nf */
- { in_line_eoln, MAN_BSCOPE }, /* fi */
+ { in_line_eoln, MAN_NSCOPED }, /* nf */
+ { in_line_eoln, MAN_NSCOPED }, /* fi */
{ blk_close, MAN_BSCOPE }, /* RE */
- { blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* RS */
+ { blk_exp, MAN_BSCOPE }, /* RS */
{ in_line_eoln, 0 }, /* DT */
{ in_line_eoln, 0 }, /* UC */
- { in_line_eoln, 0 }, /* PD */
+ { in_line_eoln, MAN_NSCOPED }, /* PD */
{ in_line_eoln, 0 }, /* AT */
{ in_line_eoln, 0 }, /* in */
{ in_line_eoln, 0 }, /* ft */
{ in_line_eoln, 0 }, /* OP */
{ in_line_eoln, MAN_BSCOPE }, /* EX */
{ in_line_eoln, MAN_BSCOPE }, /* EE */
- { blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */
+ { blk_exp, MAN_BSCOPE }, /* UR */
{ blk_close, MAN_BSCOPE }, /* UE */
{ in_line_eoln, 0 }, /* ll */
};
@@ -95,9 +85,9 @@ const struct man_macro * const man_macros = __man_macros;
void
-man_unscope(struct man *man, const struct man_node *to)
+man_unscope(struct roff_man *man, const struct roff_node *to)
{
- struct man_node *n;
+ struct roff_node *n;
to = to->parent;
n = man->last;
@@ -115,17 +105,17 @@ man_unscope(struct man *man, const struct man_node *to)
if (man->flags & MAN_ELINE)
man->flags &= ~MAN_ELINE;
else {
- assert(n->type == MAN_HEAD);
+ assert(n->type == ROFFT_HEAD);
n = n->parent;
man->flags &= ~MAN_BLINE;
}
man->last = n;
n = n->parent;
- man_node_delete(man, man->last);
+ roff_node_delete(man, man->last);
continue;
}
- if (n->type == MAN_BLOCK &&
- man_macros[n->tok].flags & MAN_EXPLICIT)
+ if (n->type == ROFFT_BLOCK &&
+ man_macros[n->tok].fp == blk_exp)
mandoc_msg(MANDOCERR_BLK_NOEND,
man->parse, n->line, n->pos,
man_macronames[n->tok]);
@@ -140,7 +130,7 @@ man_unscope(struct man *man, const struct man_node *to)
man->last = n;
n = n->parent;
- man_valid_post(man);
+ man->last->flags |= MAN_VALID;
}
/*
@@ -151,90 +141,7 @@ man_unscope(struct man *man, const struct man_node *to)
*/
man->next = (man->last == to) ?
- MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
-}
-
-static enum rew
-rew_block(enum mant ntok, enum man_type type, const struct man_node *n)
-{
-
- if (type == MAN_BLOCK && ntok == n->parent->tok &&
- n->parent->type == MAN_BODY)
- return(REW_REWIND);
- return(ntok == n->tok ? REW_HALT : REW_NOHALT);
-}
-
-/*
- * There are three scope levels: scoped to the root (all), scoped to the
- * section (all less sections), and scoped to subsections (all less
- * sections and subsections).
- */
-static enum rew
-rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
-{
- enum rew c;
-
- /* We cannot progress beyond the root ever. */
- if (MAN_ROOT == n->type)
- return(REW_HALT);
-
- assert(n->parent);
-
- /* Normal nodes shouldn't go to the level of the root. */
- if (MAN_ROOT == n->parent->type)
- return(REW_REWIND);
-
- /* Already-validated nodes should be closed out. */
- if (MAN_VALID & n->flags)
- return(REW_NOHALT);
-
- /* First: rewind to ourselves. */
- if (type == n->type && tok == n->tok) {
- if (MAN_EXPLICIT & man_macros[n->tok].flags)
- return(REW_HALT);
- else
- return(REW_REWIND);
- }
-
- /*
- * Next follow the implicit scope-smashings as defined by man.7:
- * section, sub-section, etc.
- */
-
- switch (tok) {
- case MAN_SH:
- break;
- case MAN_SS:
- /* Rewind to a section, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
- return(c);
- break;
- case MAN_RS:
- /* Preserve empty paragraphs before RS. */
- if (0 == n->nchild && (MAN_P == n->tok ||
- MAN_PP == n->tok || MAN_LP == n->tok))
- return(REW_HALT);
- /* Rewind to a subsection, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
- return(c);
- /* Rewind to a section, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
- return(c);
- break;
- default:
- /* Rewind to an offsetter, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_RS, type, n)))
- return(c);
- /* Rewind to a subsection, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
- return(c);
- /* Rewind to a section, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
- return(c);
- break;
- }
-
- return(REW_NOHALT);
+ ROFF_NEXT_CHILD : ROFF_NEXT_SIBLING;
}
/*
@@ -243,30 +150,40 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
* scopes. When a scope is closed, it must be validated and actioned.
*/
static void
-rew_scope(enum man_type type, struct man *man, enum mant tok)
+rew_scope(struct roff_man *man, int tok)
{
- struct man_node *n;
- enum rew c;
+ struct roff_node *n;
- for (n = man->last; n; n = n->parent) {
- /*
- * Whether we should stop immediately (REW_HALT), stop
- * and rewind until this point (REW_REWIND), or keep
- * rewinding (REW_NOHALT).
- */
- c = rew_dohalt(tok, type, n);
- if (REW_HALT == c)
- return;
- if (REW_REWIND == c)
- break;
- }
+ /* Preserve empty paragraphs before RS. */
- /*
- * Rewind until the current point. Warn if we're a roff
- * instruction that's mowing over explicit scopes.
- */
+ n = man->last;
+ if (tok == MAN_RS && n->child == NULL &&
+ (n->tok == MAN_P || n->tok == MAN_PP || n->tok == MAN_LP))
+ return;
- man_unscope(man, n);
+ for (;;) {
+ if (n->type == ROFFT_ROOT)
+ return;
+ if (n->flags & MAN_VALID) {
+ n = n->parent;
+ continue;
+ }
+ if (n->type != ROFFT_BLOCK) {
+ if (n->parent->type == ROFFT_ROOT) {
+ man_unscope(man, n);
+ return;
+ } else {
+ n = n->parent;
+ continue;
+ }
+ }
+ if (tok != MAN_SH && (n->tok == MAN_SH ||
+ (tok != MAN_SS && (n->tok == MAN_SS ||
+ man_macros[n->tok].fp == blk_exp))))
+ return;
+ man_unscope(man, n);
+ n = man->last;
+ }
}
@@ -276,8 +193,8 @@ rew_scope(enum man_type type, struct man *man, enum mant tok)
void
blk_close(MACRO_PROT_ARGS)
{
- enum mant ntok;
- const struct man_node *nn;
+ int ntok;
+ const struct roff_node *nn;
char *p;
int nrew, target;
@@ -288,7 +205,7 @@ blk_close(MACRO_PROT_ARGS)
if ( ! man_args(man, line, pos, buf, &p))
break;
for (nn = man->last->parent; nn; nn = nn->parent)
- if (nn->tok == ntok && nn->type == MAN_BLOCK)
+ if (nn->tok == ntok && nn->type == ROFFT_BLOCK)
nrew++;
target = strtol(p, &p, 10);
if (*p != '\0')
@@ -308,17 +225,16 @@ blk_close(MACRO_PROT_ARGS)
break;
default:
abort();
- /* NOTREACHED */
}
for (nn = man->last->parent; nn; nn = nn->parent)
- if (nn->tok == ntok && nn->type == MAN_BLOCK && ! --nrew)
+ if (nn->tok == ntok && nn->type == ROFFT_BLOCK && ! --nrew)
break;
if (nn == NULL) {
mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse,
line, ppos, man_macronames[tok]);
- rew_scope(MAN_BLOCK, man, MAN_PP);
+ rew_scope(man, MAN_PP);
} else {
line = man->last->line;
ppos = man->last->pos;
@@ -337,18 +253,17 @@ blk_close(MACRO_PROT_ARGS)
void
blk_exp(MACRO_PROT_ARGS)
{
- struct man_node *head;
+ struct roff_node *head;
char *p;
int la;
- rew_scope(MAN_BLOCK, man, tok);
- man_block_alloc(man, line, ppos, tok);
- man_head_alloc(man, line, ppos, tok);
- head = man->last;
+ rew_scope(man, tok);
+ roff_block_alloc(man, line, ppos, tok);
+ head = roff_head_alloc(man, line, ppos, tok);
la = *pos;
if (man_args(man, line, pos, buf, &p))
- man_word_alloc(man, line, la, p);
+ roff_word_alloc(man, line, la, p);
if (buf[*pos] != '\0')
mandoc_vmsg(MANDOCERR_ARG_EXCESS,
@@ -356,12 +271,12 @@ blk_exp(MACRO_PROT_ARGS)
man_macronames[tok], buf + *pos);
man_unscope(man, head);
- man_body_alloc(man, line, ppos, tok);
+ roff_body_alloc(man, line, ppos, tok);
}
/*
- * Parse an implicit-block macro. These contain a MAN_HEAD and a
- * MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
+ * Parse an implicit-block macro. These contain a ROFFT_HEAD and a
+ * ROFFT_BODY contained within a ROFFT_BLOCK. Rules for closing out other
* scopes, such as `SH' closing out an `SS', are defined in the rew
* routines.
*/
@@ -370,13 +285,13 @@ blk_imp(MACRO_PROT_ARGS)
{
int la;
char *p;
- struct man_node *n;
+ struct roff_node *n;
- rew_scope(MAN_BODY, man, tok);
- rew_scope(MAN_BLOCK, man, tok);
- man_block_alloc(man, line, ppos, tok);
- man_head_alloc(man, line, ppos, tok);
- n = man->last;
+ rew_scope(man, tok);
+ n = roff_block_alloc(man, line, ppos, tok);
+ if (n->tok == MAN_SH || n->tok == MAN_SS)
+ man->flags &= ~MAN_LITERAL;
+ n = roff_head_alloc(man, line, ppos, tok);
/* Add line arguments. */
@@ -384,23 +299,25 @@ blk_imp(MACRO_PROT_ARGS)
la = *pos;
if ( ! man_args(man, line, pos, buf, &p))
break;
- man_word_alloc(man, line, la, p);
+ roff_word_alloc(man, line, la, p);
}
- /* Close out head and open body (unless MAN_SCOPE). */
+ /*
+ * For macros having optional next-line scope,
+ * keep the head open if there were no arguments.
+ * For `TP', always keep the head open.
+ */
- if (man_macros[tok].flags & MAN_SCOPED) {
- /* If we're forcing scope (`TP'), keep it open. */
- if (man_macros[tok].flags & MAN_FSCOPED) {
- man->flags |= MAN_BLINE;
- return;
- } else if (n == man->last) {
- man->flags |= MAN_BLINE;
- return;
- }
+ if (man_macros[tok].flags & MAN_SCOPED &&
+ (tok == MAN_TP || n == man->last)) {
+ man->flags |= MAN_BLINE;
+ return;
}
- rew_scope(MAN_HEAD, man, tok);
- man_body_alloc(man, line, ppos, tok);
+
+ /* Close out the head and open the body. */
+
+ man_unscope(man, n);
+ roff_body_alloc(man, line, ppos, tok);
}
void
@@ -408,9 +325,9 @@ in_line_eoln(MACRO_PROT_ARGS)
{
int la;
char *p;
- struct man_node *n;
+ struct roff_node *n;
- man_elem_alloc(man, line, ppos, tok);
+ roff_elem_alloc(man, line, ppos, tok);
n = man->last;
for (;;) {
@@ -432,10 +349,10 @@ in_line_eoln(MACRO_PROT_ARGS)
if ( ! man_args(man, line, pos, buf, &p))
break;
if (man_macros[tok].flags & MAN_JOIN &&
- man->last->type == MAN_TEXT)
- man_word_append(man, p);
+ man->last->type == ROFFT_TEXT)
+ roff_word_append(man, p);
else
- man_word_alloc(man, line, la, p);
+ roff_word_alloc(man, line, la, p);
}
/*
@@ -459,43 +376,28 @@ in_line_eoln(MACRO_PROT_ARGS)
return;
}
- assert(man->last->type != MAN_ROOT);
- man->next = MAN_NEXT_SIBLING;
+ assert(man->last->type != ROFFT_ROOT);
+ man->next = ROFF_NEXT_SIBLING;
- /*
- * Rewind our element scope. Note that when TH is pruned, we'll
- * be back at the root, so make sure that we don't clobber as
- * its sibling.
- */
+ /* Rewind our element scope. */
for ( ; man->last; man->last = man->last->parent) {
+ man_state(man, man->last);
if (man->last == n)
break;
- if (man->last->type == MAN_ROOT)
- break;
- man_valid_post(man);
}
-
- assert(man->last);
-
- /*
- * Same here regarding whether we're back at the root.
- */
-
- if (man->last->type != MAN_ROOT)
- man_valid_post(man);
}
-
void
-man_macroend(struct man *man)
+man_endparse(struct roff_man *man)
{
man_unscope(man, man->first);
+ man->flags &= ~MAN_LITERAL;
}
static int
-man_args(struct man *man, int line, int *pos, char *buf, char **v)
+man_args(struct roff_man *man, int line, int *pos, char *buf, char **v)
{
char *start;
@@ -504,8 +406,8 @@ man_args(struct man *man, int line, int *pos, char *buf, char **v)
assert(' ' != *start);
if ('\0' == *start)
- return(0);
+ return 0;
*v = mandoc_getarg(man->parse, v, line, pos);
- return(1);
+ return 1;
}
diff --git a/man_term.c b/man_term.c
index 8be7927a65cd..f45e24afea4a 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,4 +1,4 @@
-/* $Id: man_term.c,v 1.169 2015/03/06 15:48:52 schwarze Exp $ */
+/* $Id: man_term.c,v 1.187 2016/01/08 17:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,9 +7,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -26,10 +26,11 @@
#include <stdlib.h>
#include <string.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "out.h"
+#include "mandoc.h"
+#include "roff.h"
#include "man.h"
+#include "out.h"
#include "term.h"
#include "main.h"
@@ -47,8 +48,8 @@ struct mtermp {
#define DECL_ARGS struct termp *p, \
struct mtermp *mt, \
- struct man_node *n, \
- const struct man_meta *meta
+ struct roff_node *n, \
+ const struct roff_meta *meta
struct termact {
int (*pre)(DECL_ARGS);
@@ -59,10 +60,12 @@ struct termact {
static void print_man_nodelist(DECL_ARGS);
static void print_man_node(DECL_ARGS);
-static void print_man_head(struct termp *, const void *);
-static void print_man_foot(struct termp *, const void *);
+static void print_man_head(struct termp *,
+ const struct roff_meta *);
+static void print_man_foot(struct termp *,
+ const struct roff_meta *);
static void print_bvspace(struct termp *,
- const struct man_node *, int);
+ const struct roff_node *, int);
static int pre_B(DECL_ARGS);
static int pre_HP(DECL_ARGS);
@@ -135,36 +138,32 @@ static const struct termact termacts[MAN_MAX] = {
void
-terminal_man(void *arg, const struct man *man)
+terminal_man(void *arg, const struct roff_man *man)
{
struct termp *p;
- const struct man_meta *meta;
- struct man_node *n;
+ struct roff_node *n;
struct mtermp mt;
p = (struct termp *)arg;
-
p->overstep = 0;
p->rmargin = p->maxrmargin = p->defrmargin;
p->tabwidth = term_len(p, 5);
- n = man_node(man)->child;
- meta = man_meta(man);
-
memset(&mt, 0, sizeof(struct mtermp));
-
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
mt.offset = term_len(p, p->defindent);
mt.pardist = 1;
+ n = man->first->child;
if (p->synopsisonly) {
while (n != NULL) {
if (n->tok == MAN_SH &&
- n->child->child->type == MAN_TEXT &&
+ n->child->child->type == ROFFT_TEXT &&
!strcmp(n->child->child->string, "SYNOPSIS")) {
if (n->child->next->child != NULL)
print_man_nodelist(p, &mt,
- n->child->next->child, meta);
+ n->child->next->child,
+ &man->meta);
term_newln(p);
break;
}
@@ -173,10 +172,10 @@ terminal_man(void *arg, const struct man *man)
} else {
if (p->defindent == 0)
p->defindent = 7;
- term_begin(p, print_man_head, print_man_foot, meta);
+ term_begin(p, print_man_head, print_man_foot, &man->meta);
p->flags |= TERMP_NOSPACE;
if (n != NULL)
- print_man_nodelist(p, &mt, n, meta);
+ print_man_nodelist(p, &mt, n, &man->meta);
term_end(p);
}
}
@@ -190,17 +189,17 @@ terminal_man(void *arg, const struct man *man)
* first, print it.
*/
static void
-print_bvspace(struct termp *p, const struct man_node *n, int pardist)
+print_bvspace(struct termp *p, const struct roff_node *n, int pardist)
{
int i;
term_newln(p);
if (n->body && n->body->child)
- if (MAN_TBL == n->body->child->type)
+ if (n->body->child->type == ROFFT_TBL)
return;
- if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
+ if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
if (NULL == n->prev)
return;
@@ -213,15 +212,15 @@ static int
pre_ign(DECL_ARGS)
{
- return(0);
+ return 0;
}
static int
pre_ll(DECL_ARGS)
{
- term_setwidth(p, n->nchild ? n->child->string : NULL);
- return(0);
+ term_setwidth(p, n->child != NULL ? n->child->string : NULL);
+ return 0;
}
static int
@@ -229,7 +228,7 @@ pre_I(DECL_ARGS)
{
term_fontrepl(p, TERMFONT_UNDER);
- return(1);
+ return 1;
}
static int
@@ -256,7 +255,7 @@ pre_literal(DECL_ARGS)
p->flags |= TERMP_NOSPACE;
}
- return(0);
+ return 0;
}
static int
@@ -267,19 +266,19 @@ pre_PD(DECL_ARGS)
n = n->child;
if (n == NULL) {
mt->pardist = 1;
- return(0);
+ return 0;
}
- assert(MAN_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
if (a2roffsu(n->string, &su, SCALE_VS))
mt->pardist = term_vspan(p, &su);
- return(0);
+ return 0;
}
static int
pre_alternate(DECL_ARGS)
{
enum termfont font[2];
- struct man_node *nn;
+ struct roff_node *nn;
int savelit, i;
switch (n->tok) {
@@ -318,12 +317,15 @@ pre_alternate(DECL_ARGS)
term_fontrepl(p, font[i]);
if (savelit && NULL == nn->next)
mt->fl |= MANT_LITERAL;
- print_man_node(p, mt, nn, meta);
+ assert(nn->type == ROFFT_TEXT);
+ term_word(p, nn->string);
+ if (nn->flags & MAN_EOS)
+ p->flags |= TERMP_SENTENCE;
if (nn->next)
p->flags |= TERMP_NOSPACE;
}
- return(0);
+ return 0;
}
static int
@@ -331,7 +333,7 @@ pre_B(DECL_ARGS)
{
term_fontrepl(p, TERMFONT_BOLD);
- return(1);
+ return 1;
}
static int
@@ -353,7 +355,7 @@ pre_OP(DECL_ARGS)
term_fontrepl(p, TERMFONT_NONE);
p->flags |= TERMP_NOSPACE;
term_word(p, "]");
- return(0);
+ return 0;
}
static int
@@ -363,20 +365,17 @@ pre_ft(DECL_ARGS)
if (NULL == n->child) {
term_fontlast(p);
- return(0);
+ return 0;
}
cp = n->child->string;
switch (*cp) {
case '4':
- /* FALLTHROUGH */
case '3':
- /* FALLTHROUGH */
case 'B':
term_fontrepl(p, TERMFONT_BOLD);
break;
case '2':
- /* FALLTHROUGH */
case 'I':
term_fontrepl(p, TERMFONT_UNDER);
break;
@@ -384,16 +383,14 @@ pre_ft(DECL_ARGS)
term_fontlast(p);
break;
case '1':
- /* FALLTHROUGH */
case 'C':
- /* FALLTHROUGH */
case 'R':
term_fontrepl(p, TERMFONT_NONE);
break;
default:
break;
}
- return(0);
+ return 0;
}
static int
@@ -408,7 +405,7 @@ pre_in(DECL_ARGS)
if (NULL == n->child) {
p->offset = mt->offset;
- return(0);
+ return 0;
}
cp = n->child->string;
@@ -422,9 +419,9 @@ pre_in(DECL_ARGS)
cp--;
if ( ! a2roffsu(++cp, &su, SCALE_EN))
- return(0);
+ return 0;
- v = term_hspan(p, &su);
+ v = (term_hspan(p, &su) + 11) / 24;
if (less < 0)
p->offset -= p->offset > v ? v : p->offset;
@@ -435,7 +432,7 @@ pre_in(DECL_ARGS)
if (p->offset > SHRT_MAX)
p->offset = term_len(p, p->defindent);
- return(0);
+ return 0;
}
static int
@@ -447,16 +444,11 @@ pre_sp(DECL_ARGS)
if ((NULL == n->prev && n->parent)) {
switch (n->parent->tok) {
case MAN_SH:
- /* FALLTHROUGH */
case MAN_SS:
- /* FALLTHROUGH */
case MAN_PP:
- /* FALLTHROUGH */
case MAN_LP:
- /* FALLTHROUGH */
case MAN_P:
- /* FALLTHROUGH */
- return(0);
+ return 0;
default:
break;
}
@@ -480,24 +472,35 @@ pre_sp(DECL_ARGS)
for (i = 0; i < len; i++)
term_vspace(p);
- return(0);
+ /*
+ * Handle an explicit break request in the same way
+ * as an overflowing line.
+ */
+
+ if (p->flags & TERMP_BRIND) {
+ p->offset = p->rmargin;
+ p->rmargin = p->maxrmargin;
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
+ }
+
+ return 0;
}
static int
pre_HP(DECL_ARGS)
{
struct roffsu su;
- const struct man_node *nn;
+ const struct roff_node *nn;
int len;
switch (n->type) {
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
print_bvspace(p, n, mt->pardist);
- return(1);
- case MAN_BODY:
+ return 1;
+ case ROFFT_BODY:
break;
default:
- return(0);
+ return 0;
}
if ( ! (MANT_LITERAL & mt->fl)) {
@@ -509,7 +512,7 @@ pre_HP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su);
+ len = term_hspan(p, &su) / 24;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -520,7 +523,7 @@ pre_HP(DECL_ARGS)
p->offset = mt->offset;
p->rmargin = mt->offset + len;
- return(1);
+ return 1;
}
static void
@@ -528,8 +531,19 @@ post_HP(DECL_ARGS)
{
switch (n->type) {
- case MAN_BODY:
+ case ROFFT_BODY:
term_newln(p);
+
+ /*
+ * Compatibility with a groff bug.
+ * The .HP macro uses the undocumented .tag request
+ * which causes a line break and cancels no-space
+ * mode even if there isn't any output.
+ */
+
+ if (n->child == NULL)
+ term_vspace(p);
+
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
p->trailspace = 0;
p->offset = mt->offset;
@@ -545,7 +559,7 @@ pre_PP(DECL_ARGS)
{
switch (n->type) {
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
print_bvspace(p, n, mt->pardist);
break;
@@ -554,36 +568,36 @@ pre_PP(DECL_ARGS)
break;
}
- return(MAN_HEAD != n->type);
+ return n->type != ROFFT_HEAD;
}
static int
pre_IP(DECL_ARGS)
{
struct roffsu su;
- const struct man_node *nn;
+ const struct roff_node *nn;
int len, savelit;
switch (n->type) {
- case MAN_BODY:
+ case ROFFT_BODY:
p->flags |= TERMP_NOSPACE;
break;
- case MAN_HEAD:
+ case ROFFT_HEAD:
p->flags |= TERMP_NOBREAK;
p->trailspace = 1;
break;
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
print_bvspace(p, n, mt->pardist);
/* FALLTHROUGH */
default:
- return(1);
+ return 1;
}
/* Calculate the offset from the optional second argument. */
if ((nn = n->parent->head->child) != NULL &&
(nn = nn->next) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su);
+ len = term_hspan(p, &su) / 24;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -593,7 +607,7 @@ pre_IP(DECL_ARGS)
len = mt->lmargin[mt->lmargincur];
switch (n->type) {
- case MAN_HEAD:
+ case ROFFT_HEAD:
p->offset = mt->offset;
p->rmargin = mt->offset + len;
@@ -606,8 +620,8 @@ pre_IP(DECL_ARGS)
if (savelit)
mt->fl |= MANT_LITERAL;
- return(0);
- case MAN_BODY:
+ return 0;
+ case ROFFT_BODY:
p->offset = mt->offset + len;
p->rmargin = p->maxrmargin;
break;
@@ -615,7 +629,7 @@ pre_IP(DECL_ARGS)
break;
}
- return(1);
+ return 1;
}
static void
@@ -623,13 +637,13 @@ post_IP(DECL_ARGS)
{
switch (n->type) {
- case MAN_HEAD:
+ case ROFFT_HEAD:
term_flushln(p);
p->flags &= ~TERMP_NOBREAK;
p->trailspace = 0;
p->rmargin = p->maxrmargin;
break;
- case MAN_BODY:
+ case ROFFT_BODY:
term_newln(p);
p->offset = mt->offset;
break;
@@ -642,22 +656,22 @@ static int
pre_TP(DECL_ARGS)
{
struct roffsu su;
- struct man_node *nn;
+ struct roff_node *nn;
int len, savelit;
switch (n->type) {
- case MAN_HEAD:
- p->flags |= TERMP_NOBREAK;
+ case ROFFT_HEAD:
+ p->flags |= TERMP_NOBREAK | TERMP_BRTRSP;
p->trailspace = 1;
break;
- case MAN_BODY:
+ case ROFFT_BODY:
p->flags |= TERMP_NOSPACE;
break;
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
print_bvspace(p, n, mt->pardist);
/* FALLTHROUGH */
default:
- return(1);
+ return 1;
}
/* Calculate offset. */
@@ -665,7 +679,7 @@ pre_TP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
nn->string != NULL && ! (MAN_LINE & nn->flags) &&
a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su);
+ len = term_hspan(p, &su) / 24;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -675,7 +689,7 @@ pre_TP(DECL_ARGS)
len = mt->lmargin[mt->lmargincur];
switch (n->type) {
- case MAN_HEAD:
+ case ROFFT_HEAD:
p->offset = mt->offset;
p->rmargin = mt->offset + len;
@@ -694,18 +708,18 @@ pre_TP(DECL_ARGS)
if (savelit)
mt->fl |= MANT_LITERAL;
- return(0);
- case MAN_BODY:
+ return 0;
+ case ROFFT_BODY:
p->offset = mt->offset + len;
p->rmargin = p->maxrmargin;
p->trailspace = 0;
- p->flags &= ~TERMP_NOBREAK;
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP);
break;
default:
break;
}
- return(1);
+ return 1;
}
static void
@@ -713,10 +727,10 @@ post_TP(DECL_ARGS)
{
switch (n->type) {
- case MAN_HEAD:
+ case ROFFT_HEAD:
term_flushln(p);
break;
- case MAN_BODY:
+ case ROFFT_BODY:
term_newln(p);
p->offset = mt->offset;
break;
@@ -731,7 +745,7 @@ pre_SS(DECL_ARGS)
int i;
switch (n->type) {
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
mt->fl &= ~MANT_LITERAL;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
@@ -743,25 +757,32 @@ pre_SS(DECL_ARGS)
do {
n = n->prev;
- } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT);
+ } while (n != NULL && n->tok != TOKEN_NONE &&
+ termacts[n->tok].flags & MAN_NOTEXT);
if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
break;
for (i = 0; i < mt->pardist; i++)
term_vspace(p);
break;
- case MAN_HEAD:
+ case ROFFT_HEAD:
term_fontrepl(p, TERMFONT_BOLD);
p->offset = term_len(p, 3);
+ p->rmargin = mt->offset;
+ p->trailspace = mt->offset;
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND;
break;
- case MAN_BODY:
+ case ROFFT_BODY:
p->offset = mt->offset;
+ p->rmargin = p->maxrmargin;
+ p->trailspace = 0;
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
break;
default:
break;
}
- return(1);
+ return 1;
}
static void
@@ -769,10 +790,10 @@ post_SS(DECL_ARGS)
{
switch (n->type) {
- case MAN_HEAD:
+ case ROFFT_HEAD:
term_newln(p);
break;
- case MAN_BODY:
+ case ROFFT_BODY:
term_newln(p);
break;
default:
@@ -786,7 +807,7 @@ pre_SH(DECL_ARGS)
int i;
switch (n->type) {
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
mt->fl &= ~MANT_LITERAL;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
@@ -805,18 +826,24 @@ pre_SH(DECL_ARGS)
for (i = 0; i < mt->pardist; i++)
term_vspace(p);
break;
- case MAN_HEAD:
+ case ROFFT_HEAD:
term_fontrepl(p, TERMFONT_BOLD);
p->offset = 0;
+ p->rmargin = mt->offset;
+ p->trailspace = mt->offset;
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND;
break;
- case MAN_BODY:
+ case ROFFT_BODY:
p->offset = mt->offset;
+ p->rmargin = p->maxrmargin;
+ p->trailspace = 0;
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
break;
default:
break;
}
- return(1);
+ return 1;
}
static void
@@ -824,10 +851,10 @@ post_SH(DECL_ARGS)
{
switch (n->type) {
- case MAN_HEAD:
+ case ROFFT_HEAD:
term_newln(p);
break;
- case MAN_BODY:
+ case ROFFT_BODY:
term_newln(p);
break;
default:
@@ -841,19 +868,21 @@ pre_RS(DECL_ARGS)
struct roffsu su;
switch (n->type) {
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
term_newln(p);
- return(1);
- case MAN_HEAD:
- return(0);
+ return 1;
+ case ROFFT_HEAD:
+ return 0;
default:
break;
}
n = n->parent->head;
n->aux = SHRT_MAX + 1;
- if (n->child != NULL && a2roffsu(n->child->string, &su, SCALE_EN))
- n->aux = term_hspan(p, &su);
+ if (n->child == NULL)
+ n->aux = mt->lmargin[mt->lmargincur];
+ else if (a2roffsu(n->child->string, &su, SCALE_EN))
+ n->aux = term_hspan(p, &su) / 24;
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
n->aux = -mt->offset;
else if (n->aux > SHRT_MAX)
@@ -866,8 +895,8 @@ pre_RS(DECL_ARGS)
if (++mt->lmarginsz < MAXMARGINS)
mt->lmargincur = mt->lmarginsz;
- mt->lmargin[mt->lmargincur] = mt->lmargin[mt->lmargincur - 1];
- return(1);
+ mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
+ return 1;
}
static void
@@ -875,9 +904,9 @@ post_RS(DECL_ARGS)
{
switch (n->type) {
- case MAN_BLOCK:
+ case ROFFT_BLOCK:
return;
- case MAN_HEAD:
+ case ROFFT_HEAD:
return;
default:
term_newln(p);
@@ -895,14 +924,14 @@ static int
pre_UR(DECL_ARGS)
{
- return (MAN_HEAD != n->type);
+ return n->type != ROFFT_HEAD;
}
static void
post_UR(DECL_ARGS)
{
- if (MAN_BLOCK != n->type)
+ if (n->type != ROFFT_BLOCK)
return;
term_word(p, "<");
@@ -922,7 +951,7 @@ print_man_node(DECL_ARGS)
int c;
switch (n->type) {
- case MAN_TEXT:
+ case ROFFT_TEXT:
/*
* If we have a blank line, output a vertical space.
* If we have a space as the first character, break
@@ -937,14 +966,14 @@ print_man_node(DECL_ARGS)
term_word(p, n->string);
goto out;
- case MAN_EQN:
+ case ROFFT_EQN:
if ( ! (n->flags & MAN_LINE))
p->flags |= TERMP_NOSPACE;
term_eqn(p, n->eqn);
if (n->next != NULL && ! (n->next->flags & MAN_LINE))
p->flags |= TERMP_NOSPACE;
return;
- case MAN_TBL:
+ case ROFFT_TBL:
if (p->tbl.cols == NULL)
term_vspace(p);
term_tbl(p, n->span);
@@ -1010,13 +1039,11 @@ print_man_nodelist(DECL_ARGS)
}
static void
-print_man_foot(struct termp *p, const void *arg)
+print_man_foot(struct termp *p, const struct roff_meta *meta)
{
- const struct man_meta *meta;
char *title;
size_t datelen, titlen;
- meta = (const struct man_meta *)arg;
assert(meta->title);
assert(meta->msec);
assert(meta->date);
@@ -1028,8 +1055,8 @@ print_man_foot(struct termp *p, const void *arg)
/*
* Temporary, undocumented option to imitate mdoc(7) output.
- * In the bottom right corner, use the source instead of
- * the title.
+ * In the bottom right corner, use the operating system
+ * instead of the title.
*/
if ( ! p->mdocstyle) {
@@ -1039,14 +1066,14 @@ print_man_foot(struct termp *p, const void *arg)
}
mandoc_asprintf(&title, "%s(%s)",
meta->title, meta->msec);
- } else if (meta->source) {
- title = mandoc_strdup(meta->source);
+ } else if (meta->os) {
+ title = mandoc_strdup(meta->os);
} else {
title = mandoc_strdup("");
}
datelen = term_strlen(p, meta->date);
- /* Bottom left corner: manual source. */
+ /* Bottom left corner: operating system. */
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
p->trailspace = 1;
@@ -1054,8 +1081,8 @@ print_man_foot(struct termp *p, const void *arg)
p->rmargin = p->maxrmargin > datelen ?
(p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0;
- if (meta->source)
- term_word(p, meta->source);
+ if (meta->os)
+ term_word(p, meta->os);
term_flushln(p);
/* At the bottom in the middle: manual date. */
@@ -1082,14 +1109,12 @@ print_man_foot(struct termp *p, const void *arg)
}
static void
-print_man_head(struct termp *p, const void *arg)
+print_man_head(struct termp *p, const struct roff_meta *meta)
{
- const struct man_meta *meta;
const char *volume;
char *title;
size_t vollen, titlen;
- meta = (const struct man_meta *)arg;
assert(meta->title);
assert(meta->msec);
diff --git a/man_validate.c b/man_validate.c
index 93ee9b3f208b..16d996355eb7 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -1,15 +1,15 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2016 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -28,13 +28,15 @@
#include <string.h>
#include <time.h>
-#include "man.h"
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "libman.h"
+#include "mandoc.h"
+#include "roff.h"
+#include "man.h"
#include "libmandoc.h"
+#include "roff_int.h"
+#include "libman.h"
-#define CHKARGS struct man *man, struct man_node *n
+#define CHKARGS struct roff_man *man, struct roff_node *n
typedef void (*v_check)(CHKARGS);
@@ -46,9 +48,7 @@ static void check_text(CHKARGS);
static void post_AT(CHKARGS);
static void post_IP(CHKARGS);
static void post_vs(CHKARGS);
-static void post_fi(CHKARGS);
static void post_ft(CHKARGS);
-static void post_nf(CHKARGS);
static void post_OP(CHKARGS);
static void post_TH(CHKARGS);
static void post_UC(CHKARGS);
@@ -77,8 +77,8 @@ static v_check man_valids[MAN_MAX] = {
NULL, /* IR */
NULL, /* RI */
post_vs, /* sp */
- post_nf, /* nf */
- post_fi, /* fi */
+ NULL, /* nf */
+ NULL, /* fi */
NULL, /* RE */
check_part, /* RS */
NULL, /* DT */
@@ -88,8 +88,8 @@ static v_check man_valids[MAN_MAX] = {
NULL, /* in */
post_ft, /* ft */
post_OP, /* OP */
- post_nf, /* EX */
- post_fi, /* EE */
+ NULL, /* EX */
+ NULL, /* EE */
post_UR, /* UR */
NULL, /* UE */
NULL, /* ll */
@@ -97,31 +97,39 @@ static v_check man_valids[MAN_MAX] = {
void
-man_valid_post(struct man *man)
+man_node_validate(struct roff_man *man)
{
- struct man_node *n;
+ struct roff_node *n;
v_check *cp;
n = man->last;
- if (n->flags & MAN_VALID)
- return;
- n->flags |= MAN_VALID;
+ man->last = man->last->child;
+ while (man->last != NULL) {
+ man_node_validate(man);
+ if (man->last == n)
+ man->last = man->last->child;
+ else
+ man->last = man->last->next;
+ }
+ man->last = n;
+ man->next = ROFF_NEXT_SIBLING;
switch (n->type) {
- case MAN_TEXT:
+ case ROFFT_TEXT:
check_text(man, n);
break;
- case MAN_ROOT:
+ case ROFFT_ROOT:
check_root(man, n);
break;
- case MAN_EQN:
- /* FALLTHROUGH */
- case MAN_TBL:
+ case ROFFT_EQN:
+ case ROFFT_TBL:
break;
default:
cp = man_valids + n->tok;
if (*cp)
(*cp)(man, n);
+ if (man->last == n)
+ man_state(man, n);
break;
}
}
@@ -172,10 +180,10 @@ static void
post_OP(CHKARGS)
{
- if (n->nchild == 0)
+ if (n->child == NULL)
mandoc_msg(MANDOCERR_OP_EMPTY, man->parse,
n->line, n->pos, "OP");
- else if (n->nchild > 2) {
+ else if (n->child->next != NULL && n->child->next->next != NULL) {
n = n->child->next->next;
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse,
n->line, n->pos, "OP ... %s", n->string);
@@ -186,7 +194,7 @@ static void
post_UR(CHKARGS)
{
- if (n->type == MAN_HEAD && n->child == NULL)
+ if (n->type == ROFFT_HEAD && n->child == NULL)
mandoc_vmsg(MANDOCERR_UR_NOHEAD, man->parse,
n->line, n->pos, "UR");
check_part(man, n);
@@ -198,24 +206,18 @@ post_ft(CHKARGS)
char *cp;
int ok;
- if (0 == n->nchild)
+ if (n->child == NULL)
return;
ok = 0;
cp = n->child->string;
switch (*cp) {
case '1':
- /* FALLTHROUGH */
case '2':
- /* FALLTHROUGH */
case '3':
- /* FALLTHROUGH */
case '4':
- /* FALLTHROUGH */
case 'I':
- /* FALLTHROUGH */
case 'P':
- /* FALLTHROUGH */
case 'R':
if ('\0' == cp[1])
ok = 1;
@@ -243,7 +245,7 @@ static void
check_part(CHKARGS)
{
- if (n->type == MAN_BODY && n->child == NULL)
+ if (n->type == ROFFT_BODY && n->child == NULL)
mandoc_msg(MANDOCERR_BLK_EMPTY, man->parse,
n->line, n->pos, man_macronames[n->tok]);
}
@@ -253,23 +255,23 @@ check_par(CHKARGS)
{
switch (n->type) {
- case MAN_BLOCK:
- if (0 == n->body->nchild)
- man_node_delete(man, n);
+ case ROFFT_BLOCK:
+ if (n->body->child == NULL)
+ roff_node_delete(man, n);
break;
- case MAN_BODY:
- if (0 == n->nchild)
+ case ROFFT_BODY:
+ if (n->child == NULL)
mandoc_vmsg(MANDOCERR_PAR_SKIP,
man->parse, n->line, n->pos,
"%s empty", man_macronames[n->tok]);
break;
- case MAN_HEAD:
- if (n->nchild)
+ case ROFFT_HEAD:
+ if (n->child != NULL)
mandoc_vmsg(MANDOCERR_ARG_SKIP,
man->parse, n->line, n->pos,
"%s %s%s", man_macronames[n->tok],
n->child->string,
- n->nchild > 1 ? " ..." : "");
+ n->child->next != NULL ? " ..." : "");
break;
default:
break;
@@ -281,12 +283,12 @@ post_IP(CHKARGS)
{
switch (n->type) {
- case MAN_BLOCK:
- if (0 == n->head->nchild && 0 == n->body->nchild)
- man_node_delete(man, n);
+ case ROFFT_BLOCK:
+ if (n->head->child == NULL && n->body->child == NULL)
+ roff_node_delete(man, n);
break;
- case MAN_BODY:
- if (0 == n->parent->head->nchild && 0 == n->nchild)
+ case ROFFT_BODY:
+ if (n->parent->head->child == NULL && n->child == NULL)
mandoc_vmsg(MANDOCERR_PAR_SKIP,
man->parse, n->line, n->pos,
"%s empty", man_macronames[n->tok]);
@@ -299,21 +301,21 @@ post_IP(CHKARGS)
static void
post_TH(CHKARGS)
{
- struct man_node *nb;
+ struct roff_node *nb;
const char *p;
free(man->meta.title);
free(man->meta.vol);
- free(man->meta.source);
+ free(man->meta.os);
free(man->meta.msec);
free(man->meta.date);
man->meta.title = man->meta.vol = man->meta.date =
- man->meta.msec = man->meta.source = NULL;
+ man->meta.msec = man->meta.os = NULL;
nb = n;
- /* ->TITLE<- MSEC DATE SOURCE VOL */
+ /* ->TITLE<- MSEC DATE OS VOL */
n = n->child;
if (n && n->string) {
@@ -335,7 +337,7 @@ post_TH(CHKARGS)
nb->line, nb->pos, "TH");
}
- /* TITLE ->MSEC<- DATE SOURCE VOL */
+ /* TITLE ->MSEC<- DATE OS VOL */
if (n)
n = n->next;
@@ -347,7 +349,7 @@ post_TH(CHKARGS)
nb->line, nb->pos, "TH %s", man->meta.title);
}
- /* TITLE MSEC ->DATE<- SOURCE VOL */
+ /* TITLE MSEC ->DATE<- OS VOL */
if (n)
n = n->next;
@@ -363,14 +365,14 @@ post_TH(CHKARGS)
n ? n->pos : nb->pos, "TH");
}
- /* TITLE MSEC DATE ->SOURCE<- VOL */
+ /* TITLE MSEC DATE ->OS<- VOL */
if (n && (n = n->next))
- man->meta.source = mandoc_strdup(n->string);
+ man->meta.os = mandoc_strdup(n->string);
else if (man->defos != NULL)
- man->meta.source = mandoc_strdup(man->defos);
+ man->meta.os = mandoc_strdup(man->defos);
- /* TITLE MSEC DATE SOURCE ->VOL<- */
+ /* TITLE MSEC DATE OS ->VOL<- */
/* If missing, use the default VOL name for MSEC. */
if (n && (n = n->next))
@@ -387,29 +389,7 @@ post_TH(CHKARGS)
* Remove the `TH' node after we've processed it for our
* meta-data.
*/
- man_node_delete(man, man->last);
-}
-
-static void
-post_nf(CHKARGS)
-{
-
- if (man->flags & MAN_LITERAL)
- mandoc_msg(MANDOCERR_NF_SKIP, man->parse,
- n->line, n->pos, "nf");
-
- man->flags |= MAN_LITERAL;
-}
-
-static void
-post_fi(CHKARGS)
-{
-
- if ( ! (MAN_LITERAL & man->flags))
- mandoc_msg(MANDOCERR_FI_SKIP, man->parse,
- n->line, n->pos, "fi");
-
- man->flags &= ~MAN_LITERAL;
+ roff_node_delete(man, man->last);
}
static void
@@ -427,7 +407,7 @@ post_UC(CHKARGS)
n = n->child;
- if (NULL == n || MAN_TEXT != n->type)
+ if (n == NULL || n->type != ROFFT_TEXT)
p = bsd_versions[0];
else {
s = n->string;
@@ -445,8 +425,8 @@ post_UC(CHKARGS)
p = bsd_versions[0];
}
- free(man->meta.source);
- man->meta.source = mandoc_strdup(p);
+ free(man->meta.os);
+ man->meta.os = mandoc_strdup(p);
}
static void
@@ -459,12 +439,12 @@ post_AT(CHKARGS)
"System V Release 2",
};
+ struct roff_node *nn;
const char *p, *s;
- struct man_node *nn;
n = n->child;
- if (NULL == n || MAN_TEXT != n->type)
+ if (n == NULL || n->type != ROFFT_TEXT)
p = unix_versions[0];
else {
s = n->string;
@@ -474,7 +454,9 @@ post_AT(CHKARGS)
p = unix_versions[1];
else if (0 == strcmp(s, "5")) {
nn = n->next;
- if (nn && MAN_TEXT == nn->type && nn->string[0])
+ if (nn != NULL &&
+ nn->type == ROFFT_TEXT &&
+ nn->string[0] != '\0')
p = unix_versions[3];
else
p = unix_versions[2];
@@ -482,8 +464,8 @@ post_AT(CHKARGS)
p = unix_versions[0];
}
- free(man->meta.source);
- man->meta.source = mandoc_strdup(p);
+ free(man->meta.os);
+ man->meta.os = mandoc_strdup(p);
}
static void
@@ -495,18 +477,17 @@ post_vs(CHKARGS)
switch (n->parent->tok) {
case MAN_SH:
- /* FALLTHROUGH */
case MAN_SS:
mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos,
"%s after %s", man_macronames[n->tok],
man_macronames[n->parent->tok]);
/* FALLTHROUGH */
- case MAN_MAX:
+ case TOKEN_NONE:
/*
* Don't warn about this because it occurs in pod2man
* and would cause considerable (unfixable) warnage.
*/
- man_node_delete(man, n);
+ roff_node_delete(man, n);
break;
default:
break;
diff --git a/manconf.h b/manconf.h
new file mode 100644
index 000000000000..782269e7b33d
--- /dev/null
+++ b/manconf.h
@@ -0,0 +1,48 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ *
+ * 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 AUTHORS DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
+ */
+
+/* List of unique, absolute paths to manual trees. */
+
+struct manpaths {
+ char **paths;
+ size_t sz;
+};
+
+/* Data from -O options and man.conf(5) output directives. */
+
+struct manoutput {
+ char *includes;
+ char *man;
+ char *paper;
+ char *style;
+ size_t indent;
+ size_t width;
+ int fragment;
+ int mdoc;
+ int synopsisonly;
+};
+
+struct manconf {
+ struct manoutput output;
+ struct manpaths manpath;
+};
+
+
+void manconf_parse(struct manconf *, const char *, char *, char *);
+void manconf_output(struct manoutput *, const char *);
+void manconf_free(struct manconf *);
diff --git a/mandoc.1 b/mandoc.1
index e218ed7af89c..f4707aa28b04 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.1,v 1.155 2015/02/23 13:31:03 schwarze Exp $
+.\" $Id: mandoc.1,v 1.164 2015/11/05 17:47:51 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2012, 2014, 2015 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: February 23 2015 $
+.Dd $Mdocdate: November 5 2015 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -24,14 +24,12 @@
.Sh SYNOPSIS
.Nm mandoc
.Op Fl acfhkl
-.Sm off
-.Op Fl I Cm os Li = Ar name
-.Sm on
-.Op Fl K Ns Ar encoding
+.Op Fl I Cm os Ns = Ns Ar name
+.Op Fl K Ar encoding
.Op Fl m Ns Ar format
-.Op Fl O Ns Ar option
-.Op Fl T Ns Ar output
-.Op Fl W Ns Ar level
+.Op Fl O Ar option
+.Op Fl T Ar output
+.Op Fl W Ar level
.Op Ar
.Sh DESCRIPTION
The
@@ -49,7 +47,7 @@ or
text from stdin, implying
.Fl m Ns Cm andoc ,
and produces
-.Fl T Ns Cm locale
+.Fl T Cm locale
output.
.Pp
The options are as follows:
@@ -77,9 +75,7 @@ This overrides any earlier
and
.Fl l
options.
-.Sm off
-.It Fl I Cm os Li = Ar name
-.Sm on
+.It Fl I Cm os Ns = Ns Ar name
Override the default operating system
.Ar name
for the
@@ -93,7 +89,7 @@ macro.
Display only the SYNOPSIS lines.
Implies
.Fl c .
-.It Fl K Ns Ar encoding
+.It Fl K Ar encoding
Specify the input encoding.
The supported
.Ar encoding
@@ -141,16 +137,16 @@ See
for available formats.
Defaults to
.Fl m Ns Cm andoc .
-.It Fl O Ns Ar option
+.It Fl O Ar option
Comma-separated output options.
-.It Fl T Ns Ar output
+.It Fl T Ar output
Output format.
See
.Sx Output Formats
for available formats.
Defaults to
-.Fl T Ns Cm locale .
-.It Fl W Ns Ar level
+.Fl T Cm locale .
+.It Fl W Ar level
Specify the minimum message
.Ar level
to be reported on the standard error output and to affect the exit status.
@@ -174,7 +170,7 @@ and
for details.
.Pp
The special option
-.Fl W Ns Cm stop
+.Fl W Cm stop
tells
.Nm
to exit after parsing a file that causes warnings or errors of at least
@@ -185,7 +181,7 @@ If both a
and
.Cm stop
are requested, they can be joined with a comma, for example
-.Fl W Ns Cm error , Ns Cm stop .
+.Fl W Cm error , Ns Cm stop .
.It Ar file
Read input from zero or more files.
If unspecified, reads from stdin.
@@ -254,54 +250,56 @@ The
utility accepts the following
.Fl T
arguments, which correspond to output modes:
-.Bl -tag -width "-Tlocale"
-.It Fl T Ns Cm ascii
+.Bl -tag -width "-T locale"
+.It Fl T Cm ascii
Produce 7-bit ASCII output.
See
.Sx ASCII Output .
-.It Fl T Ns Cm html
+.It Fl T Cm html
Produce HTML5, CSS1, and MathML output.
See
.Sx HTML Output .
-.It Fl T Ns Cm lint
+.It Fl T Cm lint
Parse only: produce no output.
Implies
-.Fl W Ns Cm warning .
-.It Fl T Ns Cm locale
+.Fl W Cm warning .
+.It Fl T Cm locale
Encode output using the current locale.
This is the default.
See
.Sx Locale Output .
-.It Fl T Ns Cm man
+.It Fl T Cm man
Produce
.Xr man 7
format output.
See
.Sx Man Output .
-.It Fl T Ns Cm pdf
+.It Fl T Cm pdf
Produce PDF output.
See
.Sx PDF Output .
-.It Fl T Ns Cm ps
+.It Fl T Cm ps
Produce PostScript output.
See
.Sx PostScript Output .
-.It Fl T Ns Cm tree
+.It Fl T Cm tree
Produce an indented parse tree.
-.It Fl T Ns Cm utf8
+See
+.Sx Syntax tree output .
+.It Fl T Cm utf8
Encode output in the UTF\-8 multi-byte format.
See
.Sx UTF\-8 Output .
-.It Fl T Ns Cm xhtml
+.It Fl T Cm xhtml
This is a synonym for
-.Fl T Ns Cm html .
+.Fl T Cm html .
.El
.Pp
If multiple input files are specified, these will be processed by the
corresponding filter in-order.
.Ss ASCII Output
Output produced by
-.Fl T Ns Cm ascii
+.Fl T Cm ascii
is rendered in standard 7-bit ASCII documented in
.Xr ascii 7 .
.Pp
@@ -343,7 +341,7 @@ which will normalise to \(>=58.
.El
.Ss HTML Output
Output produced by
-.Fl T Ns Cm html
+.Fl T Cm html
conforms to HTML5 using optional self-closing tags.
Default styles use only CSS1.
Equations rendered from
@@ -351,11 +349,11 @@ Equations rendered from
blocks use MathML.
.Pp
The
-.Pa example.style.css
+.Pa mandoc.css
file documents style-sheet classes available for customising output.
If a style-sheet is not specified with
-.Fl O Ns Ar style ,
-.Fl T Ns Cm html
+.Fl O Cm style ,
+.Fl T Cm html
defaults to simple output (via an embedded style-sheet)
readable in any graphical or text-based web
browser.
@@ -411,13 +409,13 @@ relative URI.
.El
.Ss Locale Output
Locale-depending output encoding is triggered with
-.Fl T Ns Cm locale .
+.Fl T Cm locale .
This is the default.
.Pp
This option is not available on all systems: systems without locale
support, or those whose internal representation is not natively UCS-4,
will fall back to
-.Fl T Ns Cm ascii .
+.Fl T Cm ascii .
See
.Sx ASCII Output
for font style specification and available command-line arguments.
@@ -447,7 +445,7 @@ level controls which
are displayed before copying the input to the output.
.Ss PDF Output
PDF-1.1 output may be generated by
-.Fl T Ns Cm pdf .
+.Fl T Cm pdf .
See
.Sx PostScript Output
for
@@ -457,7 +455,7 @@ arguments and defaults.
PostScript
.Qq Adobe-3.0
Level-2 pages may be generated by
-.Fl T Ns Cm ps .
+.Fl T Cm ps .
Output pages default to letter sized and are rendered in the Times font
family, 11-point.
Margins are calculated as 1/9 the page length and width.
@@ -489,11 +487,50 @@ is used.
.El
.Ss UTF\-8 Output
Use
-.Fl T Ns Cm utf8
+.Fl T Cm utf8
to force a UTF\-8 locale.
See
.Sx Locale Output
for details and options.
+.Ss Syntax tree output
+Use
+.Fl T Cm tree
+to show a human readable representation of the syntax tree.
+It is useful for debugging the source code of manual pages.
+The exact format is subject to change, so don't write parsers for it.
+Each output line shows one syntax tree node.
+Child nodes are indented with respect to their parent node.
+The columns are:
+.Pp
+.Bl -enum -compact
+.It
+For macro nodes, the macro name; for text and
+.Xr tbl 7
+nodes, the content.
+There is a special format for
+.Xr eqn 7
+nodes.
+.It
+Node type (text, elem, block, head, body, body-end, tail, tbl, eqn).
+.It
+Flags:
+.Bl -dash -compact
+.It
+An opening parenthesis if the node is an opening delimiter.
+.It
+An asterisk if the node starts a new input line.
+.It
+The input line number (starting at one).
+.It
+A colon.
+.It
+The input column number (starting at one).
+.It
+A closing parenthesis if the node is a closing delimiter.
+.It
+A full stop if the node ends a sentence.
+.El
+.El
.Sh ENVIRONMENT
.Bl -tag -width MANPAGER
.It Ev MANPAGER
@@ -506,7 +543,8 @@ Specifies the pagination program to use when
.Ev MANPAGER
is not defined.
If neither PAGER nor MANPAGER is defined,
-.Pa /usr/bin/more Fl s
+.Xr more 1
+.Fl s
will be used.
.El
.Sh EXIT STATUS
@@ -525,21 +563,21 @@ they were lower than the requested
.Ar level .
.It 2
At least one warning occurred, but no error, and
-.Fl W Ns Cm warning
+.Fl W Cm warning
was specified.
.It 3
At least one parsing error occurred,
but no unsupported feature was encountered, and
-.Fl W Ns Cm error
+.Fl W Cm error
or
-.Fl W Ns Cm warning
+.Fl W Cm warning
was specified.
.It 4
At least one unsupported feature was encountered, and
-.Fl W Ns Cm unsupp ,
-.Fl W Ns Cm error
+.Fl W Cm unsupp ,
+.Fl W Cm error
or
-.Fl W Ns Cm warning
+.Fl W Cm warning
was specified.
.It 5
Invalid command line arguments were specified.
@@ -553,28 +591,28 @@ to exit at once, possibly in the middle of parsing or formatting a file.
.El
.Pp
Note that selecting
-.Fl T Ns Cm lint
+.Fl T Cm lint
output mode implies
-.Fl W Ns Cm warning .
+.Fl W Cm warning .
.Sh EXAMPLES
To page manuals to the terminal:
.Pp
-.Dl $ mandoc \-Wall,stop mandoc.1 2\*(Gt&1 | less
+.Dl $ mandoc \-W all,stop mandoc.1 2\*(Gt&1 | less
.Dl $ mandoc mandoc.1 mdoc.3 mdoc.7 | less
.Pp
To produce HTML manuals with
-.Ar style.css
+.Pa mandoc.css
as the style-sheet:
.Pp
-.Dl $ mandoc \-Thtml -Ostyle=style.css mdoc.7 \*(Gt mdoc.7.html
+.Dl $ mandoc \-T html -O style=mandoc.css mdoc.7 \*(Gt mdoc.7.html
.Pp
To check over a large set of manuals:
.Pp
-.Dl $ mandoc \-Tlint `find /usr/src -name \e*\e.[1-9]`
+.Dl $ mandoc \-T lint \(gafind /usr/src -name \e*\e.[1-9]\(ga
.Pp
To produce a series of PostScript manuals for A4 paper:
.Pp
-.Dl $ mandoc \-Tps \-Opaper=a4 mdoc.7 man.7 \*(Gt manuals.ps
+.Dl $ mandoc \-T ps \-O paper=a4 mdoc.7 man.7 \*(Gt manuals.ps
.Pp
Convert a modern
.Xr mdoc 7
@@ -584,7 +622,7 @@ format, for use on systems lacking an
.Xr mdoc 7
parser:
.Pp
-.Dl $ mandoc \-Tman foo.mdoc \*(Gt foo.man
+.Dl $ mandoc \-T man foo.mdoc \*(Gt foo.man
.Sh DIAGNOSTICS
Messages displayed by
.Nm
@@ -651,7 +689,7 @@ levels except those about non-existent or unreadable input files
are hidden unless their level, or a lower level, is requested using a
.Fl W
option or
-.Fl T Ns Cm lint
+.Fl T Cm lint
output mode.
.Ss Warnings related to the document prologue
.Bl -ohang
@@ -817,7 +855,7 @@ In the SEE ALSO section, an
macro with a lower section number follows one with a higher number,
or two
.Ic \&Xr
-macros refering to the same section are out of alphabetical order.
+macros referring to the same section are out of alphabetical order.
.It Sy "unusual Xr punctuation"
.Pq mdoc
In the SEE ALSO section, punctuation between two
@@ -937,13 +975,6 @@ list block contains text or macros before the first
.Ic \&It
macro.
The offending children are moved before the beginning of the list.
-.It Sy ".Vt block has child macro"
-.Pq mdoc
-The
-.Ic \&Vt
-macro supports plain text arguments only.
-Formatting may be ugly and semantic searching
-for the affected content might not work.
.It Sy "fill mode already enabled, skipping"
.Pq man
A
@@ -1569,6 +1600,13 @@ By requesting the inclusion of a sensitive file, a malicious document
might otherwise trick a privileged user into inadvertently displaying
the file on the screen, revealing the file content to bystanders.
The argument is ignored including the file name following it.
+.It Sy "skipping display without arguments"
+.Pq mdoc
+A
+.Ic \&Bd
+block macro does not have any arguments.
+The block is discarded, and the block content is displayed in
+whatever mode was active before the block.
.It Sy "missing list type, using -item"
.Pq mdoc
A
@@ -1767,6 +1805,7 @@ as if they were a text line.
.Xr roff 7 ,
.Xr tbl 7
.Sh AUTHORS
+.An -nosplit
The
.Nm
utility was written by
@@ -1775,10 +1814,10 @@ and is maintained by
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
.Sh BUGS
In
-.Fl T Ns Cm html ,
+.Fl T Cm html ,
the maximum size of an element attribute is determined by
.Dv BUFSIZ ,
which is usually 1024 bytes.
Be aware of this when setting long link
formats such as
-.Fl O Ns Cm style Ns = Ns Ar really/long/link .
+.Fl O Cm style Ns = Ns Ar really/long/link .
diff --git a/mandoc.3 b/mandoc.3
index a41e25b934d0..61012edec95e 100644
--- a/mandoc.3
+++ b/mandoc.3
@@ -1,7 +1,7 @@
-.\" $Id: mandoc.3,v 1.31 2015/01/15 04:26:40 schwarze Exp $
+.\" $Id: mandoc.3,v 1.36 2016/01/08 17:48:09 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2010, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2010-2016 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
@@ -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: January 15 2015 $
+.Dd $Mdocdate: January 8 2016 $
.Dt MANDOC 3
.Os
.Sh NAME
@@ -37,7 +37,6 @@
.Nm mparse_result ,
.Nm mparse_strerror ,
.Nm mparse_strlevel
-.Nm mparse_wait ,
.Nd mandoc macro compiler library
.Sh SYNOPSIS
.In sys/types.h
@@ -51,7 +50,6 @@
.Fa "int options"
.Fa "enum mandoclevel wlevel"
.Fa "mandocmsg mmsg"
-.Fa "const struct mchars *mchars"
.Fa "char *defos"
.Fc
.Ft void
@@ -75,10 +73,9 @@
.Fo mparse_keep
.Fa "struct mparse *parse"
.Fc
-.Ft "enum mandoclevel"
+.Ft int
.Fo mparse_open
.Fa "struct mparse *parse"
-.Fa "int *fd"
.Fa "const char *fname"
.Fc
.Ft "enum mandoclevel"
@@ -106,10 +103,6 @@
.Fo mparse_strlevel
.Fa "enum mandoclevel"
.Fc
-.Ft "enum mandoclevel"
-.Fo mparse_wait
-.Fa "struct mparse *parse"
-.Fc
.In sys/types.h
.In mandoc.h
.In mdoc.h
@@ -183,6 +176,9 @@ or
parse it with
.Fn mparse_readfd ;
.It
+close it with
+.Xr close 2 ;
+.It
retrieve the syntax tree with
.Fn mparse_result ;
.It
@@ -215,12 +211,6 @@ An error or warning message during parsing.
A classification of an
.Vt "enum mandocerr"
as regards system operation.
-.It Vt "struct mchars"
-An opaque pointer to a a character table.
-Created with
-.Xr mchars_alloc 3
-and freed with
-.Xr mchars_free 3 .
.It Vt "struct mparse"
An opaque pointer to a running parse sequence.
Created with
@@ -345,9 +335,6 @@ A callback function to handle errors and warnings.
See
.Pa main.c
for an example.
-.It Ar mchars
-An opaque pointer to a a character table obtained from
-.Xr mchars_alloc 3 .
.It Ar defos
A default string for the
.Xr mdoc 7
@@ -392,23 +379,15 @@ Declared in
implemented in
.Pa read.c .
.It Fn mparse_open
-If the
+Open the file for reading.
+If that fails and
.Fa fname
-ends in
-.Pa .gz ,
-open with
-.Xr gunzip 1 ;
-otherwise, with
-.Xr open 2 .
-If
-.Xr open 2
-fails, append
-.Pa .gz
-and try with
-.Xr gunzip 1 .
-Return a file descriptor open for reading in
-.Fa fd ,
-or -1 on failure.
+does not already end in
+.Ql .gz ,
+try again after appending
+.Ql .gz .
+Save the information whether the file is zipped or not.
+Return a file descriptor open for reading or -1 on failure.
It can be passed to
.Fn mparse_readfd
or used directly.
@@ -423,10 +402,9 @@ or
.Fn mparse_open .
Pass the associated filename in
.Va fname .
-Calls
-.Fn mparse_wait
-before returning.
This function may be called multiple times with different parameters; however,
+.Xr close 2
+and
.Fn mparse_reset
should be invoked between parses.
Declared in
@@ -460,28 +438,6 @@ Declared in
.In mandoc.h ,
implemented in
.Pa read.c .
-.It Fn mparse_wait
-Bury a
-.Xr gunzip 1
-child process that was spawned with
-.Fn mparse_open .
-To be called after the parse sequence is complete.
-Not needed after
-.Fn mparse_readfd ,
-but does no harm in that case, either.
-Returns
-.Dv MANDOCLEVEL_OK
-on success and
-.Dv MANDOCLEVEL_SYSERR
-on failure, that is, when
-.Xr wait 2
-fails, or when
-.Xr gunzip 1
-died from a signal or exited with non-zero status.
-Declared in
-.In mandoc.h ,
-implemented in
-.Pa read.c .
.El
.Ss Variables
.Bl -ohang
@@ -601,7 +557,7 @@ and
fields), its position in the tree (the
.Va parent ,
.Va child ,
-.Va nchild ,
+.Va last ,
.Va next
and
.Va prev
diff --git a/mandoc.c b/mandoc.c
index 0619420cb196..d265463b4efe 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc.c,v 1.92 2015/02/20 23:55:10 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.98 2015/11/12 22:44:27 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -32,8 +32,6 @@
#include "mandoc_aux.h"
#include "libmandoc.h"
-#define DATESIZE 32
-
static int a2time(time_t *, const char *, const char *);
static char *time2a(time_t);
@@ -83,7 +81,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
break;
case 'C':
if ('\'' != **start)
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
*start = ++*end;
gly = ESCAPE_SPECIAL;
term = '\'';
@@ -93,9 +91,10 @@ mandoc_escape(const char **end, const char **start, int *sz)
* Escapes taking no arguments at all.
*/
case 'd':
- /* FALLTHROUGH */
case 'u':
- return(ESCAPE_IGNORE);
+ case ',':
+ case '/':
+ return ESCAPE_IGNORE;
/*
* The \z escape is supposed to output the following
@@ -104,26 +103,19 @@ mandoc_escape(const char **end, const char **start, int *sz)
* let us just skip the next character.
*/
case 'z':
- return(ESCAPE_SKIPCHAR);
+ return ESCAPE_SKIPCHAR;
/*
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
* 'X' is the trigger. These have opaque sub-strings.
*/
case 'F':
- /* FALLTHROUGH */
case 'g':
- /* FALLTHROUGH */
case 'k':
- /* FALLTHROUGH */
case 'M':
- /* FALLTHROUGH */
case 'm':
- /* FALLTHROUGH */
case 'n':
- /* FALLTHROUGH */
case 'V':
- /* FALLTHROUGH */
case 'Y':
gly = ESCAPE_IGNORE;
/* FALLTHROUGH */
@@ -151,21 +143,16 @@ mandoc_escape(const char **end, const char **start, int *sz)
* The \B and \w escapes are handled in roff.c, roff_res().
*/
case 'A':
- /* FALLTHROUGH */
case 'b':
- /* FALLTHROUGH */
case 'D':
- /* FALLTHROUGH */
case 'R':
- /* FALLTHROUGH */
case 'X':
- /* FALLTHROUGH */
case 'Z':
gly = ESCAPE_IGNORE;
/* FALLTHROUGH */
case 'o':
if (**start == '\0')
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
if (gly == ESCAPE_ERROR)
gly = ESCAPE_OVERSTRIKE;
term = **start;
@@ -177,22 +164,16 @@ mandoc_escape(const char **end, const char **start, int *sz)
* and 'N' resolves to a numerical expression.
*/
case 'h':
- /* FALLTHROUGH */
case 'H':
- /* FALLTHROUGH */
case 'L':
- /* FALLTHROUGH */
case 'l':
- /* FALLTHROUGH */
case 'S':
- /* FALLTHROUGH */
case 'v':
- /* FALLTHROUGH */
case 'x':
if (strchr(" %&()*+-./0123456789:<=>", **start)) {
if ('\0' != **start)
++*end;
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
}
gly = ESCAPE_IGNORE;
term = **start;
@@ -205,11 +186,11 @@ mandoc_escape(const char **end, const char **start, int *sz)
*/
case 'N':
if ('\0' == **start)
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
(*end)++;
if (isdigit((unsigned char)**start)) {
*sz = 1;
- return(ESCAPE_IGNORE);
+ return ESCAPE_IGNORE;
}
(*start)++;
while (isdigit((unsigned char)**end))
@@ -217,7 +198,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
*sz = *end - *start;
if ('\0' != **end)
(*end)++;
- return(ESCAPE_NUMBERED);
+ return ESCAPE_NUMBERED;
/*
* Sizes get a special category of their own.
@@ -243,9 +224,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
term = '\'';
break;
case '3':
- /* FALLTHROUGH */
case '2':
- /* FALLTHROUGH */
case '1':
*sz = (*end)[-1] == 's' &&
isdigit((unsigned char)(*end)[1]) ? 2 : 1;
@@ -279,12 +258,12 @@ mandoc_escape(const char **end, const char **start, int *sz)
while (**end != term) {
switch (**end) {
case '\0':
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
case '\\':
(*end)++;
if (ESCAPE_ERROR ==
mandoc_escape(end, NULL, NULL))
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
break;
default:
(*end)++;
@@ -295,7 +274,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
} else {
assert(*sz > 0);
if ((size_t)*sz > strlen(*start))
- return(ESCAPE_ERROR);
+ return ESCAPE_ERROR;
*end += *sz;
}
@@ -321,12 +300,10 @@ mandoc_escape(const char **end, const char **start, int *sz)
switch (**start) {
case '3':
- /* FALLTHROUGH */
case 'B':
gly = ESCAPE_FONTBOLD;
break;
case '2':
- /* FALLTHROUGH */
case 'I':
gly = ESCAPE_FONTITALIC;
break;
@@ -334,7 +311,6 @@ mandoc_escape(const char **end, const char **start, int *sz)
gly = ESCAPE_FONTPREV;
break;
case '1':
- /* FALLTHROUGH */
case 'R':
gly = ESCAPE_FONTROMAN;
break;
@@ -355,6 +331,9 @@ mandoc_escape(const char **end, const char **start, int *sz)
break;
if (*sz == 6 && (*start)[1] == '0')
break;
+ if (*sz == 5 && (*start)[1] == 'D' &&
+ strchr("89ABCDEF", (*start)[2]) != NULL)
+ break;
if ((int)strspn(*start + 1, "0123456789ABCDEFabcdef")
+ 1 == *sz)
gly = ESCAPE_UNICODE;
@@ -363,7 +342,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
break;
}
- return(gly);
+ return gly;
}
/*
@@ -458,7 +437,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
if ('\0' == *cp && (white || ' ' == cp[-1]))
mandoc_msg(MANDOCERR_SPACE_EOL, parse, ln, *pos, NULL);
- return(start);
+ return start;
}
static int
@@ -475,10 +454,10 @@ a2time(time_t *t, const char *fmt, const char *p)
#endif
if (NULL != pp && '\0' == *pp) {
*t = mktime(&tm);
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
static char *
@@ -491,7 +470,7 @@ time2a(time_t t)
tm = localtime(&t);
if (tm == NULL)
- return(NULL);
+ return NULL;
/*
* Reserve space:
@@ -499,45 +478,61 @@ time2a(time_t t)
* up to 2 characters for the day + comma + blank
* 4 characters for the year and a terminating '\0'
*/
+
p = buf = mandoc_malloc(10 + 4 + 4 + 1);
- if (0 == (ssz = strftime(p, 10 + 1, "%B ", tm)))
+ if ((ssz = strftime(p, 10 + 1, "%B ", tm)) == 0)
goto fail;
p += (int)ssz;
- if (-1 == (isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)))
+ /*
+ * The output format is just "%d" here, not "%2d" or "%02d".
+ * That's also the reason why we can't just format the
+ * date as a whole with "%B %e, %Y" or "%B %d, %Y".
+ * Besides, the present approach is less prone to buffer
+ * overflows, in case anybody should ever introduce the bug
+ * of looking at LC_TIME.
+ */
+
+ if ((isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)) == -1)
goto fail;
p += isz;
- if (0 == strftime(p, 4 + 1, "%Y", tm))
+ if (strftime(p, 4 + 1, "%Y", tm) == 0)
goto fail;
- return(buf);
+ return buf;
fail:
free(buf);
- return(NULL);
+ return NULL;
}
char *
mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
{
- char *out;
time_t t;
- if (NULL == in || '\0' == *in ||
- 0 == strcmp(in, "$" "Mdocdate$")) {
+ /* No date specified: use today's date. */
+
+ if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0) {
mandoc_msg(MANDOCERR_DATE_MISSING, parse, ln, pos, NULL);
- time(&t);
+ return time2a(time(NULL));
}
- else if (a2time(&t, "%Y-%m-%d", in))
- t = 0;
- else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) &&
- !a2time(&t, "%b %d, %Y", in)) {
+
+ /* Valid mdoc(7) date format. */
+
+ if (a2time(&t, "$" "Mdocdate: %b %d %Y $", in) ||
+ a2time(&t, "%b %d, %Y", in))
+ return time2a(t);
+
+ /* Do not warn about the legacy man(7) format. */
+
+ if ( ! a2time(&t, "%Y-%m-%d", in))
mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, in);
- t = 0;
- }
- out = t ? time2a(t) : NULL;
- return(out ? out : mandoc_strdup(in));
+
+ /* Use any non-mdoc(7) date verbatim. */
+
+ return mandoc_strdup(in);
}
int
@@ -547,7 +542,7 @@ mandoc_eos(const char *p, size_t sz)
int enclosed, found;
if (0 == sz)
- return(0);
+ return 0;
/*
* End-of-sentence recognition must include situations where
@@ -559,28 +554,24 @@ mandoc_eos(const char *p, size_t sz)
for (q = p + (int)sz - 1; q >= p; q--) {
switch (*q) {
case '\"':
- /* FALLTHROUGH */
case '\'':
- /* FALLTHROUGH */
case ']':
- /* FALLTHROUGH */
case ')':
if (0 == found)
enclosed = 1;
break;
case '.':
- /* FALLTHROUGH */
case '!':
- /* FALLTHROUGH */
case '?':
found = 1;
break;
default:
- return(found && (!enclosed || isalnum((unsigned char)*q)));
+ return found &&
+ (!enclosed || isalnum((unsigned char)*q));
}
}
- return(found && !enclosed);
+ return found && !enclosed;
}
/*
@@ -595,7 +586,7 @@ mandoc_strntoi(const char *p, size_t sz, int base)
long v;
if (sz > 31)
- return(-1);
+ return -1;
memcpy(buf, p, sz);
buf[(int)sz] = '\0';
@@ -604,12 +595,12 @@ mandoc_strntoi(const char *p, size_t sz, int base)
v = strtol(buf, &ep, base);
if (buf[0] == '\0' || *ep != '\0')
- return(-1);
+ return -1;
if (v > INT_MAX)
v = INT_MAX;
if (v < INT_MIN)
v = INT_MIN;
- return((int)v);
+ return (int)v;
}
diff --git a/style.css b/mandoc.css
index 1328f4d30b45..38c5c58b1704 100644
--- a/style.css
+++ b/mandoc.css
@@ -1,4 +1,4 @@
-/* $Id: style.css,v 1.31 2015/02/10 08:05:30 schwarze Exp $ */
+/* $Id: mandoc.css,v 1.1 2015/11/05 17:47:51 schwarze Exp $ */
/*
* This is an example style-sheet provided for mandoc(1) and the -Thtml
@@ -11,6 +11,19 @@
html { max-width: 880px; margin-left: 1em; }
body { font-size: smaller; font-family: Helvetica,Arial,sans-serif; }
+body > div { padding-left: 2em;
+ padding-top: 1em; }
+body > div.mandoc,
+body > div#mancgi { padding-left: 0em;
+ padding-top: 0em; }
+body > div.results { font-size: smaller; }
+#mancgi fieldset { text-align: center;
+ border: thin solid silver;
+ border-radius: 1em;
+ font-size: small; }
+#mancgi input[name=expr] { width: 25%; }
+.results td.title { vertical-align: top;
+ padding-right: 1em; }
h1 { margin-bottom: 1ex; font-size: 110%; margin-left: -4ex; } /* Section header (Sh, SH). */
h2 { margin-bottom: 1ex; font-size: 105%; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
table { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */
diff --git a/mandoc.h b/mandoc.h
index eb8a1aa6f298..d63814c6deaa 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,15 +1,15 @@
-/* $Id: mandoc.h,v 1.201 2015/02/23 13:31:04 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.209 2016/01/08 02:53:13 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2016 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -86,7 +86,6 @@ enum mandocerr {
MANDOCERR_BLK_NEST, /* blocks badly nested: macro ... */
MANDOCERR_BD_NEST, /* nested displays are not portable: macro ... */
MANDOCERR_BL_MOVE, /* moving content out of list: macro */
- MANDOCERR_VT_CHILD, /* .Vt block has child macro: macro */
MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */
MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */
MANDOCERR_BLK_LINE, /* line scope broken: macro breaks macro */
@@ -173,6 +172,7 @@ enum mandocerr {
/* related to request and macro arguments */
MANDOCERR_NAMESC, /* escaped character not allowed in a name: name */
MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
+ MANDOCERR_BD_NOARG, /* skipping display without arguments: Bd */
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
@@ -408,37 +408,28 @@ enum mandoc_esc {
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
-__BEGIN_DECLS
struct mparse;
-struct mchars;
-struct mdoc;
-struct man;
+struct roff_man;
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
-struct mchars *mchars_alloc(void);
-void mchars_free(struct mchars *);
+void mchars_alloc(void);
+void mchars_free(void);
int mchars_num2char(const char *, size_t);
const char *mchars_uc2str(int);
int mchars_num2uc(const char *, size_t);
-int mchars_spec2cp(const struct mchars *,
- const char *, size_t);
-const char *mchars_spec2str(const struct mchars *,
- const char *, size_t, size_t *);
-struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg,
- const struct mchars *, const char *);
+int mchars_spec2cp(const char *, size_t);
+const char *mchars_spec2str(const char *, size_t, size_t *);
+struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg, const char *);
void mparse_free(struct mparse *);
void mparse_keep(struct mparse *);
-enum mandoclevel mparse_open(struct mparse *, int *, const char *);
+int mparse_open(struct mparse *, const char *);
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
enum mandoclevel mparse_readmem(struct mparse *, void *, size_t,
const char *);
void mparse_reset(struct mparse *);
void mparse_result(struct mparse *,
- struct mdoc **, struct man **, char **);
+ struct roff_man **, char **);
const char *mparse_getkeep(const struct mparse *);
const char *mparse_strerror(enum mandocerr);
const char *mparse_strlevel(enum mandoclevel);
-enum mandoclevel mparse_wait(struct mparse *);
-
-__END_DECLS
diff --git a/mandoc_aux.c b/mandoc_aux.c
index 2275bbcf36b9..cc74b7e72058 100644
--- a/mandoc_aux.c
+++ b/mandoc_aux.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc_aux.c,v 1.4 2014/08/10 23:54:41 schwarze Exp $ */
+/* $Id: mandoc_aux.c,v 1.9 2015/11/07 14:22:29 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -19,6 +19,9 @@
#include <sys/types.h>
+#if HAVE_ERR
+#include <err.h>
+#endif
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
@@ -27,6 +30,7 @@
#include "mandoc.h"
#include "mandoc_aux.h"
+
int
mandoc_asprintf(char **dest, const char *fmt, ...)
{
@@ -37,11 +41,9 @@ mandoc_asprintf(char **dest, const char *fmt, ...)
ret = vasprintf(dest, fmt, ap);
va_end(ap);
- if (-1 == ret) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
- return(ret);
+ if (ret == -1)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
+ return ret;
}
void *
@@ -50,11 +52,9 @@ mandoc_calloc(size_t num, size_t size)
void *ptr;
ptr = calloc(num, size);
- if (NULL == ptr) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
- return(ptr);
+ if (ptr == NULL)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
+ return ptr;
}
void *
@@ -63,11 +63,9 @@ mandoc_malloc(size_t size)
void *ptr;
ptr = malloc(size);
- if (NULL == ptr) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
- return(ptr);
+ if (ptr == NULL)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
+ return ptr;
}
void *
@@ -75,11 +73,9 @@ mandoc_realloc(void *ptr, size_t size)
{
ptr = realloc(ptr, size);
- if (NULL == ptr) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
- return(ptr);
+ if (ptr == NULL)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
+ return ptr;
}
void *
@@ -87,11 +83,9 @@ mandoc_reallocarray(void *ptr, size_t num, size_t size)
{
ptr = reallocarray(ptr, num, size);
- if (NULL == ptr) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
- return(ptr);
+ if (ptr == NULL)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
+ return ptr;
}
char *
@@ -100,11 +94,9 @@ mandoc_strdup(const char *ptr)
char *p;
p = strdup(ptr);
- if (NULL == p) {
- perror(NULL);
- exit((int)MANDOCLEVEL_SYSERR);
- }
- return(p);
+ if (p == NULL)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
+ return p;
}
char *
@@ -115,5 +107,5 @@ mandoc_strndup(const char *ptr, size_t sz)
p = mandoc_malloc(sz + 1);
memcpy(p, ptr, sz);
p[(int)sz] = '\0';
- return(p);
+ return p;
}
diff --git a/mandoc_aux.h b/mandoc_aux.h
index e72fe4e40eda..2ae3a0cd2def 100644
--- a/mandoc_aux.h
+++ b/mandoc_aux.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc_aux.h,v 1.3 2014/12/01 04:05:32 schwarze Exp $ */
+/* $Id: mandoc_aux.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -16,8 +16,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-__BEGIN_DECLS
-
int mandoc_asprintf(char **, const char *, ...);
void *mandoc_calloc(size_t, size_t);
void *mandoc_malloc(size_t);
@@ -25,5 +23,3 @@ void *mandoc_realloc(void *, size_t);
void *mandoc_reallocarray(void *, size_t, size_t);
char *mandoc_strdup(const char *);
char *mandoc_strndup(const char *, size_t);
-
-__END_DECLS
diff --git a/mandoc_char.7 b/mandoc_char.7
index 806b990f1755..d272080fc1d9 100644
--- a/mandoc_char.7
+++ b/mandoc_char.7
@@ -1,8 +1,8 @@
-.\" $Id: mandoc_char.7,v 1.59 2015/01/20 19:39:34 schwarze Exp $
+.\" $Id: mandoc_char.7,v 1.63 2015/09/02 15:38:35 schwarze Exp $
.\"
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2011, 2013, 2015 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
@@ -16,7 +16,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: January 20 2015 $
+.Dd $Mdocdate: September 2 2015 $
.Dt MANDOC_CHAR 7
.Os
.Sh NAME
@@ -49,7 +49,7 @@ names; instead, provide ASCII transcriptions of the names.
.Ss Dashes and Hyphens
In typography there are different types of dashes of various width:
the hyphen (-),
-the minus sign (\-),
+the minus sign (\(mi),
the en-dash (\(en),
and the em-dash (\(em).
.Pp
@@ -64,10 +64,10 @@ lorry-driver
.Pp
The mathematical minus sign is used for negative numbers or subtraction.
It should be written as
-.Sq \e- :
+.Sq \e(mi :
.Bd -unfilled -offset indent
-a = 3 \e- 1;
-b = \e-2;
+a = 3 \e(mi 1;
+b = \e(mi2;
.Ed
.Pp
The en-dash is used to separate the two elements of a range,
@@ -142,6 +142,28 @@ Note that on text lines, literal double-quote characters can be used
verbatim.
All other quote-like characters can be used verbatim as well,
even on request and macro lines.
+.Ss Accents
+In output modes supporting such special output characters, for example
+.Fl T Cm pdf ,
+some
+.Xr roff 7
+formatters convert the following ASCII input characters to the
+following Unicode special output characters:
+.Bl -column x(ga U+2018 -offset indent
+.It \(ga Ta U+2018 Ta left single quotation mark
+.It \(aq Ta U+2019 Ta right single quotation mark
+.It \(ti Ta U+02DC Ta small tilde
+.El
+.Pp
+In prose, this automatic substitution is often desirable;
+but when these characters have to be displayed as plain ASCII
+characters, for example in source code samples, they require
+escaping to render as follows:
+.Bl -column x(ga U+2018 -offset indent
+.It \e(ga Ta U+0060 Ta grave accent
+.It \e(aq Ta U+0027 Ta apostrophe
+.It \e(ti Ta U+007E Ta tilde
+.El
.Ss Periods
The period
.Pq Sq \&.
@@ -196,7 +218,7 @@ Spacing:
.Bl -column "Input" "Description" -offset indent -compact
.It Em Input Ta Em Description
.It Sq \e\ \& Ta unpaddable non-breaking space
-.It \e~ Ta paddable non-breaking space
+.It \e\(ti Ta paddable non-breaking space
.It \e0 Ta unpaddable, breaking digit-width space
.It \e| Ta one-sixth \e(em narrow space, zero width in nroff mode
.It \e^ Ta one-twelfth \e(em half-narrow space, zero width in nroff
@@ -371,9 +393,9 @@ Mathematical:
.It \e(ne Ta \(ne Ta not equivalent
.It \e(ap Ta \(ap Ta tilde operator
.It \e(|= Ta \(|= Ta asymptotically equal
-.It \e(=~ Ta \(=~ Ta approximately equal
-.It \e(~~ Ta \(~~ Ta almost equal
-.It \e(~= Ta \(~= Ta almost equal
+.It \e(=\(ti Ta \(=~ Ta approximately equal
+.It \e(\(ti\(ti Ta \(~~ Ta almost equal
+.It \e(\(ti= Ta \(~= Ta almost equal
.It \e(pt Ta \(pt Ta proportionate
.It \e(es Ta \(es Ta empty set
.It \e(mo Ta \(mo Ta element
@@ -436,15 +458,15 @@ Accents:
.It \e(a. Ta \(a. Ta dotted
.It \e(a^ Ta \(a^ Ta circumflex
.It \e(aa Ta \(aa Ta acute
-.It \e' Ta \' Ta acute
+.It \e\(aq Ta \' Ta acute
.It \e(ga Ta \(ga Ta grave
-.It \e` Ta \` Ta grave
+.It \e\(ga Ta \` Ta grave
.It \e(ab Ta \(ab Ta breve
.It \e(ac Ta \(ac Ta cedilla
.It \e(ad Ta \(ad Ta dieresis
.It \e(ah Ta \(ah Ta caron
.It \e(ao Ta \(ao Ta ring
-.It \e(a~ Ta \(a~ Ta tilde
+.It \e(a\(ti Ta \(a~ Ta tilde
.It \e(ho Ta \(ho Ta ogonek
.It \e(ha Ta \(ha Ta hat (text)
.It \e(ti Ta \(ti Ta tilde (text)
@@ -453,32 +475,32 @@ Accents:
Accented letters:
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
.It Em Input Ta Em Rendered Ta Em Description
-.It \e('A Ta \('A Ta acute A
-.It \e('E Ta \('E Ta acute E
-.It \e('I Ta \('I Ta acute I
-.It \e('O Ta \('O Ta acute O
-.It \e('U Ta \('U Ta acute U
-.It \e('a Ta \('a Ta acute a
-.It \e('e Ta \('e Ta acute e
-.It \e('i Ta \('i Ta acute i
-.It \e('o Ta \('o Ta acute o
-.It \e('u Ta \('u Ta acute u
-.It \e(`A Ta \(`A Ta grave A
-.It \e(`E Ta \(`E Ta grave E
-.It \e(`I Ta \(`I Ta grave I
-.It \e(`O Ta \(`O Ta grave O
-.It \e(`U Ta \(`U Ta grave U
-.It \e(`a Ta \(`a Ta grave a
-.It \e(`e Ta \(`e Ta grave e
-.It \e(`i Ta \(`i Ta grave i
-.It \e(`o Ta \(`i Ta grave o
-.It \e(`u Ta \(`u Ta grave u
-.It \e(~A Ta \(~A Ta tilde A
-.It \e(~N Ta \(~N Ta tilde N
-.It \e(~O Ta \(~O Ta tilde O
-.It \e(~a Ta \(~a Ta tilde a
-.It \e(~n Ta \(~n Ta tilde n
-.It \e(~o Ta \(~o Ta tilde o
+.It \e(\(aqA Ta \('A Ta acute A
+.It \e(\(aqE Ta \('E Ta acute E
+.It \e(\(aqI Ta \('I Ta acute I
+.It \e(\(aqO Ta \('O Ta acute O
+.It \e(\(aqU Ta \('U Ta acute U
+.It \e(\(aqa Ta \('a Ta acute a
+.It \e(\(aqe Ta \('e Ta acute e
+.It \e(\(aqi Ta \('i Ta acute i
+.It \e(\(aqo Ta \('o Ta acute o
+.It \e(\(aqu Ta \('u Ta acute u
+.It \e(\(gaA Ta \(`A Ta grave A
+.It \e(\(gaE Ta \(`E Ta grave E
+.It \e(\(gaI Ta \(`I Ta grave I
+.It \e(\(gaO Ta \(`O Ta grave O
+.It \e(\(gaU Ta \(`U Ta grave U
+.It \e(\(gaa Ta \(`a Ta grave a
+.It \e(\(gae Ta \(`e Ta grave e
+.It \e(\(gai Ta \(`i Ta grave i
+.It \e(\(gao Ta \(`i Ta grave o
+.It \e(\(gau Ta \(`u Ta grave u
+.It \e(\(tiA Ta \(~A Ta tilde A
+.It \e(\(tiN Ta \(~N Ta tilde N
+.It \e(\(tiO Ta \(~O Ta tilde O
+.It \e(\(tia Ta \(~a Ta tilde a
+.It \e(\(tin Ta \(~n Ta tilde n
+.It \e(\(tio Ta \(~o Ta tilde o
.It \e(:A Ta \(:A Ta dieresis A
.It \e(:E Ta \(:E Ta dieresis E
.It \e(:I Ta \(:I Ta dieresis I
@@ -657,7 +679,7 @@ manual.
.Sh UNICODE CHARACTERS
The escape sequences
.Pp
-.Dl \e[uXXXX] and \eC'uXXXX'
+.Dl \e[uXXXX] and \eC\(aquXXXX\(aq
.Pp
are interpreted as Unicode codepoints.
The codepoint must be in the range above U+0080 and less than U+10FFFF.
@@ -669,10 +691,6 @@ must be given as uppercase characters,
and points must be zero-padded to four characters; if
greater than four characters, no zero padding is allowed.
Unicode surrogates are not allowed.
-.\" .Pp
-.\" Unicode glyphs attenuate to the
-.\" .Sq \&?
-.\" character if invalid or not rendered by current output media.
.Sh NUMBERED CHARACTERS
For backward compatibility with existing manuals,
.Xr mandoc 1
@@ -685,7 +703,7 @@ escape sequence, inserting the character
from the current character set into the output.
Of course, this is inherently non-portable and is already marked
as deprecated in the Heirloom roff manual.
-For example, do not use \eN'34', use \e(dq, or even the plain
+For example, do not use \eN\(aq34\(aq, use \e(dq, or even the plain
.Sq \(dq
character where possible.
.Sh COMPATIBILITY
@@ -702,14 +720,14 @@ In
.Fl T Ns Cm ascii ,
the
\e(ss, \e(nm, \e(nb, \e(nc, \e(ib, \e(ip, \e(pp, \e[sum], \e[product],
-\e[coproduct], \e(gr, \e(\-h, and \e(a. special characters render
+\e[coproduct], \e(gr, \e(-h, and \e(a. special characters render
differently between mandoc and groff.
.It
In
.Fl T Ns Cm html
and
.Fl T Ns Cm xhtml ,
-the \e(~=, \e(nb, and \e(nc special characters render differently
+the \e(\(ti=, \e(nb, and \e(nc special characters render differently
between mandoc and groff.
.It
The
diff --git a/mandoc_headers.3 b/mandoc_headers.3
index 79d90fff58d2..6c30e16491eb 100644
--- a/mandoc_headers.3
+++ b/mandoc_headers.3
@@ -54,7 +54,6 @@ require inclusion of the header where that type is defined.
Each of the following headers can be included without including
any other mandoc header.
These headers should be included before any other mandoc headers.
-Afterwards, any other mandoc headers can be included as needed.
.Bl -tag -width Ds
.It Qq Pa mandoc_aux.h
Requires
@@ -99,14 +98,10 @@ and the functions
described in
.Xr mandoc 3 .
.Pp
-Uses the opaque types
+Uses the opaque type
.Vt struct mparse
from
.Pa read.c
-and
-.Vt struct mchars
-from
-.Pa chars.c
for function prototypes.
Uses the types
.Vt struct mdoc
@@ -117,23 +112,45 @@ and
from
.Pa libman.h
as opaque types for function prototypes.
+.It Qq Pa roff.h
+Provides
+.Vt enum mdoc_endbody ,
+.Vt enum roff_sec ,
+.Vt enum roff_type ,
+.Vt struct roff_meta ,
+and
+.Vt struct roff_node .
+.Pp
+Uses pointers to the types
+.Vt struct mdoc_arg
+and
+.Vt union mdoc_data
+from
+.Qq Pa mdoc.h
+as opaque struct members.
+.El
+.Pp
+The following two require
+.Qq Pa roff.h
+but no other mandoc headers.
+Afterwards, any other mandoc headers can be included as needed.
+.Bl -tag -width Ds
.It Qq Pa mdoc.h
Requires
.In sys/types.h
for
-.Vt size_t .
+.Vt size_t
+and
+.Qq Pa roff.h
+for
+.Vt enum roff_type .
.Pp
Provides
-.Vt enum mdoct ,
.Vt enum mdocargt ,
-.Vt enum mdoc_type ,
-.Vt enum mdoc_sec ,
-.Vt enum mdoc_endbody ,
.Vt enum mdoc_disp ,
.Vt enum mdoc_list ,
.Vt enum mdoc_auth ,
.Vt enum mdoc_font ,
-.Vt struct mdoc_meta ,
.Vt struct mdoc_argv ,
.Vt struct mdoc_arg ,
.Vt struct mdoc_bd ,
@@ -141,7 +158,6 @@ Provides
.Vt struct mdoc_an ,
.Vt struct mdoc_bf ,
.Vt struct mdoc_rs ,
-.Vt struct mdoc_node ,
and the functions
.Fn mdoc_*
described in
@@ -163,12 +179,12 @@ When this header is included, the same file should not include
or
.Pa libroff.h .
.It Qq Pa man.h
-Provides
-.Vt enum mant ,
-.Vt enum man_type ,
-.Vt struct man_meta ,
-.Vt struct man_node ,
-and the functions
+Requires
+.Qq Pa roff.h
+for
+.Vt enum roff_type .
+.Pp
+Provides the functions
.Fn man_*
described in
.Xr mandoc 3 .
@@ -204,11 +220,16 @@ are included, the same file should not include any formatter headers.
Requires
.In sys/types.h
for
-.Vt size_t
-and
+.Vt size_t ,
.Qq Pa mandoc.h
for
-.Vt enum mandocerr .
+.Vt enum mandocerr ,
+and
+.Qq Pa roff.h
+for
+.Vt struct roff_meta
+and
+.Vt struct roff_node .
.Pp
Provides
.Vt enum rofferr ,
@@ -243,8 +264,7 @@ as opaque types for function prototypes.
Requires
.Qq Pa mdoc.h
for
-.Vt enum mdoct ,
-.Vt enum mdoc_* ,
+.Vt enum mdoc_*
and
.Vt struct mdoc_* .
.Pp
@@ -274,11 +294,11 @@ or
.Pa libroff.h .
.It Qq Pa libman.h
Requires
-.Qq Pa man.h
+.Qq Pa roff.h
for
-.Vt enum mant
+.Vt struct roff_meta
and
-.Vt struct man_node.
+.Vt struct roff_node .
.Pp
Provides
.Vt enum man_next ,
@@ -366,8 +386,6 @@ from
as an opaque type for function prototypes.
.Pp
When this header is included, the same file should not include
-.Pa manpath.h
-or
.Pa mansearch.h .
.It Qq Pa term.h
Requires
@@ -389,11 +407,7 @@ Provides
.Vt struct termp ,
and many terminal formatting functions.
.Pp
-Uses the opaque types
-.Vt struct mchars
-from
-.Pa chars.c
-and
+Uses the opaque type
.Vt struct termp_ps
from
.Pa term_ps.c .
@@ -403,11 +417,14 @@ and
.Vt struct eqn
from
.Pa mandoc.h
+and
+.Vt struct roff_meta
+from
+.Qq Pa roff.h
as opaque types for function prototypes.
.Pp
When this header is included, the same file should not include
-.Pa html.h ,
-.Pa manpath.h
+.Pa html.h
or
.Pa mansearch.h .
.It Qq Pa html.h
@@ -435,23 +452,13 @@ Provides
.Vt struct html ,
and many HTML formatting functions.
.Pp
-Uses the opaque type
-.Vt struct mchars
-from
-.Pa chars.c .
-.Pp
When this header is included, the same file should not include
-.Pa term.h ,
-.Pa manpath.h
+.Pa term.h
or
.Pa mansearch.h .
.It Qq Pa main.h
Provides the top level steering functions for all formatters.
.Pp
-Uses the opaque type
-.Vt struct mchars
-from
-.Pa chars.c .
Uses the types
.Vt struct mdoc
from
@@ -461,25 +468,21 @@ and
from
.Pa libman.h
as opaque types for function prototypes.
-.It Qq Pa manpath.h
+.It Qq Pa manconf.h
Requires
.In sys/types.h
for
.Vt size_t .
.Pp
Provides
-.Vt struct manpaths
+.Vt struct manconf ,
+.Vt struct manpaths ,
+.Vt struct manoutput ,
and the functions
-.Fn manpath_manconf ,
-.Fn manpath_parse ,
+.Fn manconf_parse ,
+.Fn manconf_output ,
and
-.Fn manpath_free .
-.Pp
-When this header is included, the same file should not include
-.Pa out.h ,
-.Pa term.h ,
-or
-.Pa html.h .
+.Fn manconf_free .
.It Qq Pa mansearch.h
Requires
.In sys/types.h
@@ -503,7 +506,7 @@ and
Uses
.Vt struct manpaths
from
-.Pa manpath.h
+.Pa manconf.h
as an opaque type for function prototypes.
.Pp
When this header is included, the same file should not include
diff --git a/mandoc_ohash.c b/mandoc_ohash.c
new file mode 100644
index 000000000000..0627b469c60b
--- /dev/null
+++ b/mandoc_ohash.c
@@ -0,0 +1,63 @@
+/* $Id: mandoc_ohash.c,v 1.2 2015/10/19 18:58:47 schwarze Exp $ */
+/*
+ * Copyright (c) 2014, 2015 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 AUTHORS DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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 <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "mandoc_aux.h"
+#include "mandoc_ohash.h"
+
+static void *hash_alloc(size_t, void *);
+static void *hash_calloc(size_t, size_t, void *);
+static void hash_free(void *, void *);
+
+
+void
+mandoc_ohash_init(struct ohash *h, unsigned int sz, ptrdiff_t ko)
+{
+ struct ohash_info info;
+
+ info.alloc = hash_alloc;
+ info.calloc = hash_calloc;
+ info.free = hash_free;
+ info.data = NULL;
+ info.key_offset = ko;
+
+ ohash_init(h, sz, &info);
+}
+
+static void *
+hash_alloc(size_t sz, void *arg)
+{
+
+ return mandoc_malloc(sz);
+}
+
+static void *
+hash_calloc(size_t n, size_t sz, void *arg)
+{
+
+ return mandoc_calloc(n, sz);
+}
+
+static void
+hash_free(void *p, void *arg)
+{
+
+ free(p);
+}
diff --git a/mandoc_ohash.h b/mandoc_ohash.h
new file mode 100644
index 000000000000..571c4cda93c7
--- /dev/null
+++ b/mandoc_ohash.h
@@ -0,0 +1,23 @@
+/* $Id: mandoc_ohash.h,v 1.2 2015/11/07 14:01:16 schwarze Exp $ */
+/*
+ * Copyright (c) 2015 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.
+ */
+#if HAVE_OHASH
+#include <ohash.h>
+#else
+#include "compat_ohash.h"
+#endif
+
+void mandoc_ohash_init(struct ohash *, unsigned int, ptrdiff_t);
diff --git a/mandocdb.c b/mandocdb.c
index fed11e9f33e5..08f89c17e3d4 100644
--- a/mandocdb.c
+++ b/mandocdb.c
@@ -1,15 +1,15 @@
-/* $Id: mandocdb.c,v 1.186 2015/03/13 00:19:41 schwarze Exp $ */
+/* $Id: mandocdb.c,v 1.215 2016/01/08 17:48:09 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2016 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -23,6 +23,9 @@
#include <assert.h>
#include <ctype.h>
+#if HAVE_ERR
+#include <err.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#if HAVE_FTS
@@ -39,18 +42,15 @@
#include <string.h>
#include <unistd.h>
-#if HAVE_OHASH
-#include <ohash.h>
-#else
-#include "compat_ohash.h"
-#endif
#include <sqlite3.h>
+#include "mandoc_aux.h"
+#include "mandoc_ohash.h"
+#include "mandoc.h"
+#include "roff.h"
#include "mdoc.h"
#include "man.h"
-#include "mandoc.h"
-#include "mandoc_aux.h"
-#include "manpath.h"
+#include "manconf.h"
#include "mansearch.h"
extern int mansearch_keymax;
@@ -129,8 +129,8 @@ enum stmt {
STMT__MAX
};
-typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
+typedef int (*mdoc_fp)(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
struct mdoc_handler {
mdoc_fp fp; /* optional handler */
@@ -144,9 +144,6 @@ static void dbadd_mlink_name(const struct mlink *mlink);
static int dbopen(int);
static void dbprune(void);
static void filescan(const char *);
-static void *hash_alloc(size_t, void *);
-static void hash_free(void *, void *);
-static void *hash_calloc(size_t, size_t, void *);
static void mlink_add(struct mlink *, const struct stat *);
static void mlink_check(struct mpage *, struct mlink *);
static void mlink_free(struct mlink *);
@@ -155,33 +152,33 @@ static void mpages_free(void);
static void mpages_merge(struct mparse *);
static void names_check(void);
static void parse_cat(struct mpage *, int);
-static void parse_man(struct mpage *, const struct man_meta *,
- const struct man_node *);
-static void parse_mdoc(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_body(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_head(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_Fd(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static void parse_mdoc_fname(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Fn(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_Fo(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_Nd(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_Nm(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_Sh(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
-static int parse_mdoc_Xr(struct mpage *, const struct mdoc_meta *,
- const struct mdoc_node *);
+static void parse_man(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static void parse_mdoc(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_head(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Fd(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static void parse_mdoc_fname(struct mpage *, const struct roff_node *);
+static int parse_mdoc_Fn(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Fo(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Nd(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Nm(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Sh(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Va(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
+static int parse_mdoc_Xr(struct mpage *, const struct roff_meta *,
+ const struct roff_node *);
static void putkey(const struct mpage *, char *, uint64_t);
static void putkeys(const struct mpage *, char *, size_t, uint64_t);
static void putmdockey(const struct mpage *,
- const struct mdoc_node *, uint64_t);
+ const struct roff_node *, uint64_t);
static int render_string(char **, size_t *);
static void say(const char *, const char *, ...);
static int set_basedir(const char *, int);
@@ -189,7 +186,6 @@ static int treescan(void);
static size_t utf8(unsigned int, char [7]);
static char tempfilename[32];
-static char *progname;
static int nodb; /* no database changes */
static int mparse_options; /* abort the parse early */
static int use_all; /* use all found files */
@@ -199,7 +195,6 @@ static int write_utf8; /* write UTF-8 output; else ASCII */
static int exitcode; /* to be returned by main */
static enum op op; /* operational mode */
static char basedir[PATH_MAX]; /* current base directory */
-static struct mchars *mchars; /* table of named characters */
static struct ohash mpages; /* table of distinct manual pages */
static struct ohash mlinks; /* table of directory entries */
static struct ohash names; /* table of all names */
@@ -247,8 +242,8 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
{ NULL, TYPE_Pa }, /* Pa */
{ NULL, 0 }, /* Rv */
{ NULL, TYPE_St }, /* St */
- { NULL, TYPE_Va }, /* Va */
- { parse_mdoc_body, TYPE_Va }, /* Vt */
+ { parse_mdoc_Va, TYPE_Va }, /* Va */
+ { parse_mdoc_Va, TYPE_Vt }, /* Vt */
{ parse_mdoc_Xr, 0 }, /* Xr */
{ NULL, 0 }, /* %A */
{ NULL, 0 }, /* %B */
@@ -338,29 +333,21 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
int
mandocdb(int argc, char *argv[])
{
- int ch, i;
- size_t j, sz;
- const char *path_arg;
- struct manpaths dirs;
+ struct manconf conf;
struct mparse *mp;
- struct ohash_info mpages_info, mlinks_info;
-
- memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *));
- memset(&dirs, 0, sizeof(struct manpaths));
-
- mpages_info.alloc = mlinks_info.alloc = hash_alloc;
- mpages_info.calloc = mlinks_info.calloc = hash_calloc;
- mpages_info.free = mlinks_info.free = hash_free;
- mpages_info.data = mlinks_info.data = NULL;
+ const char *path_arg, *progname;
+ size_t j, sz;
+ int ch, i;
- mpages_info.key_offset = offsetof(struct mpage, inodev);
- mlinks_info.key_offset = offsetof(struct mlink, file);
+#if HAVE_PLEDGE
+ if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) {
+ warn("pledge");
+ return (int)MANDOCLEVEL_SYSERR;
+ }
+#endif
- progname = strrchr(argv[0], '/');
- if (progname == NULL)
- progname = argv[0];
- else
- ++progname;
+ memset(&conf, 0, sizeof(conf));
+ memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *));
/*
* We accept a few different invocations.
@@ -369,8 +356,7 @@ mandocdb(int argc, char *argv[])
*/
#define CHECKOP(_op, _ch) do \
if (OP_DEFAULT != (_op)) { \
- fprintf(stderr, "%s: -%c: Conflicting option\n", \
- progname, (_ch)); \
+ warnx("-%c: Conflicting option", (_ch)); \
goto usage; \
} while (/*CONSTCOND*/0)
@@ -406,9 +392,8 @@ mandocdb(int argc, char *argv[])
break;
case 'T':
if (strcmp(optarg, "utf8")) {
- fprintf(stderr, "%s: -T%s: "
- "Unsupported output format\n",
- progname, optarg);
+ warnx("-T%s: Unsupported output format",
+ optarg);
goto usage;
}
write_utf8 = 1;
@@ -434,18 +419,25 @@ mandocdb(int argc, char *argv[])
argc -= optind;
argv += optind;
+#if HAVE_PLEDGE
+ if (nodb) {
+ if (pledge("stdio rpath", NULL) == -1) {
+ warn("pledge");
+ return (int)MANDOCLEVEL_SYSERR;
+ }
+ }
+#endif
+
if (OP_CONFFILE == op && argc > 0) {
- fprintf(stderr, "%s: -C: Too many arguments\n",
- progname);
+ warnx("-C: Too many arguments");
goto usage;
}
exitcode = (int)MANDOCLEVEL_OK;
- mchars = mchars_alloc();
- mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL,
- mchars, NULL);
- ohash_init(&mpages, 6, &mpages_info);
- ohash_init(&mlinks, 6, &mlinks_info);
+ mchars_alloc();
+ mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL, NULL);
+ mandoc_ohash_init(&mpages, 6, offsetof(struct mpage, inodev));
+ mandoc_ohash_init(&mlinks, 6, offsetof(struct mlink, file));
if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) {
@@ -461,6 +453,15 @@ mandocdb(int argc, char *argv[])
* The existing database is usable. Process
* all files specified on the command-line.
*/
+#if HAVE_PLEDGE
+ if (!nodb) {
+ if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1) {
+ warn("pledge");
+ exitcode = (int)MANDOCLEVEL_SYSERR;
+ goto out;
+ }
+ }
+#endif
use_all = 1;
for (i = 0; i < argc; i++)
filescan(argv[i]);
@@ -485,18 +486,18 @@ mandocdb(int argc, char *argv[])
/*
* If we have arguments, use them as our manpaths.
* If we don't, grok from manpath(1) or however else
- * manpath_parse() wants to do it.
+ * manconf_parse() wants to do it.
*/
if (argc > 0) {
- dirs.paths = mandoc_reallocarray(NULL,
+ conf.manpath.paths = mandoc_reallocarray(NULL,
argc, sizeof(char *));
- dirs.sz = (size_t)argc;
+ conf.manpath.sz = (size_t)argc;
for (i = 0; i < argc; i++)
- dirs.paths[i] = mandoc_strdup(argv[i]);
+ conf.manpath.paths[i] = mandoc_strdup(argv[i]);
} else
- manpath_parse(&dirs, path_arg, NULL, NULL);
+ manconf_parse(&conf, path_arg, NULL, NULL);
- if (0 == dirs.sz) {
+ if (conf.manpath.sz == 0) {
exitcode = (int)MANDOCLEVEL_BADARG;
say("", "Empty manpath");
}
@@ -507,19 +508,21 @@ mandocdb(int argc, char *argv[])
* Ignore zero-length directories and strip trailing
* slashes.
*/
- for (j = 0; j < dirs.sz; j++) {
- sz = strlen(dirs.paths[j]);
- if (sz && '/' == dirs.paths[j][sz - 1])
- dirs.paths[j][--sz] = '\0';
+ for (j = 0; j < conf.manpath.sz; j++) {
+ sz = strlen(conf.manpath.paths[j]);
+ if (sz && conf.manpath.paths[j][sz - 1] == '/')
+ conf.manpath.paths[j][--sz] = '\0';
if (0 == sz)
continue;
if (j) {
- ohash_init(&mpages, 6, &mpages_info);
- ohash_init(&mlinks, 6, &mlinks_info);
+ mandoc_ohash_init(&mpages, 6,
+ offsetof(struct mpage, inodev));
+ mandoc_ohash_init(&mlinks, 6,
+ offsetof(struct mlink, file));
}
- if (0 == set_basedir(dirs.paths[j], argc > 0))
+ if ( ! set_basedir(conf.manpath.paths[j], argc > 0))
continue;
if (0 == treescan())
continue;
@@ -532,7 +535,7 @@ mandocdb(int argc, char *argv[])
names_check();
dbclose(0);
- if (j + 1 < dirs.sz) {
+ if (j + 1 < conf.manpath.sz) {
mpages_free();
ohash_delete(&mpages);
ohash_delete(&mlinks);
@@ -540,23 +543,23 @@ mandocdb(int argc, char *argv[])
}
}
out:
- manpath_free(&dirs);
+ manconf_free(&conf);
mparse_free(mp);
- mchars_free(mchars);
+ mchars_free();
mpages_free();
ohash_delete(&mpages);
ohash_delete(&mlinks);
- return(exitcode);
+ return exitcode;
usage:
+ progname = getprogname();
fprintf(stderr, "usage: %s [-aDnpQ] [-C file] [-Tutf8]\n"
" %s [-aDnpQ] [-Tutf8] dir ...\n"
" %s [-DnpQ] [-Tutf8] -d dir [file ...]\n"
" %s [-Dnp] -u dir [file ...]\n"
" %s [-Q] -t file ...\n",
- progname, progname, progname,
- progname, progname);
+ progname, progname, progname, progname, progname);
- return((int)MANDOCLEVEL_BADARG);
+ return (int)MANDOCLEVEL_BADARG;
}
/*
@@ -590,16 +593,16 @@ treescan(void)
f = fts_open((char * const *)argv,
FTS_PHYSICAL | FTS_NOCHDIR, NULL);
- if (NULL == f) {
+ if (f == NULL) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say("", "&fts_open");
- return(0);
+ return 0;
}
dsec = arch = NULL;
dform = FORM_NONE;
- while (NULL != (ff = fts_read(f))) {
+ while ((ff = fts_read(f)) != NULL) {
path = ff->fts_path + 2;
switch (ff->fts_info) {
@@ -608,7 +611,7 @@ treescan(void)
* then get handled just like regular files.
*/
case FTS_SL:
- if (NULL == realpath(path, buf)) {
+ if (realpath(path, buf) == NULL) {
if (warnings)
say(path, "&realpath");
continue;
@@ -623,7 +626,7 @@ treescan(void)
continue;
}
/* Use logical inode to avoid mpages dupe. */
- if (-1 == stat(path, ff->fts_statp)) {
+ if (stat(path, ff->fts_statp) == -1) {
if (warnings)
say(path, "&stat");
continue;
@@ -635,7 +638,7 @@ treescan(void)
* stored directory data and handling the filename.
*/
case FTS_F:
- if (0 == strcmp(path, MANDOC_DB))
+ if ( ! strcmp(path, MANDOC_DB))
continue;
if ( ! use_all && ff->fts_level < 2) {
if (warnings)
@@ -644,37 +647,37 @@ treescan(void)
}
gzip = 0;
fsec = NULL;
- while (NULL == fsec) {
+ while (fsec == NULL) {
fsec = strrchr(ff->fts_name, '.');
- if (NULL == fsec || strcmp(fsec+1, "gz"))
+ if (fsec == NULL || strcmp(fsec+1, "gz"))
break;
gzip = 1;
*fsec = '\0';
fsec = NULL;
}
- if (NULL == fsec) {
+ if (fsec == NULL) {
if ( ! use_all) {
if (warnings)
say(path,
"No filename suffix");
continue;
}
- } else if (0 == strcmp(++fsec, "html")) {
+ } else if ( ! strcmp(++fsec, "html")) {
if (warnings)
say(path, "Skip html");
continue;
- } else if (0 == strcmp(fsec, "ps")) {
+ } else if ( ! strcmp(fsec, "ps")) {
if (warnings)
say(path, "Skip ps");
continue;
- } else if (0 == strcmp(fsec, "pdf")) {
+ } else if ( ! strcmp(fsec, "pdf")) {
if (warnings)
say(path, "Skip pdf");
continue;
} else if ( ! use_all &&
- ((FORM_SRC == dform &&
+ ((dform == FORM_SRC &&
strncmp(fsec, dsec, strlen(dsec))) ||
- (FORM_CAT == dform && strcmp(fsec, "0")))) {
+ (dform == FORM_CAT && strcmp(fsec, "0")))) {
if (warnings)
say(path, "Wrong filename suffix");
continue;
@@ -699,7 +702,6 @@ treescan(void)
continue;
case FTS_D:
- /* FALLTHROUGH */
case FTS_DP:
break;
@@ -720,13 +722,16 @@ treescan(void)
* If we're not in use_all, enforce it.
*/
cp = ff->fts_name;
- if (FTS_DP == ff->fts_info)
+ if (ff->fts_info == FTS_DP) {
+ dform = FORM_NONE;
+ dsec = NULL;
break;
+ }
- if (0 == strncmp(cp, "man", 3)) {
+ if ( ! strncmp(cp, "man", 3)) {
dform = FORM_SRC;
dsec = cp + 3;
- } else if (0 == strncmp(cp, "cat", 3)) {
+ } else if ( ! strncmp(cp, "cat", 3)) {
dform = FORM_CAT;
dsec = cp + 3;
} else {
@@ -734,7 +739,7 @@ treescan(void)
dsec = NULL;
}
- if (NULL != dsec || use_all)
+ if (dsec != NULL || use_all)
break;
if (warnings)
@@ -746,13 +751,13 @@ treescan(void)
* Possibly our architecture.
* If we're descending, keep tabs on it.
*/
- if (FTS_DP != ff->fts_info && NULL != dsec)
+ if (ff->fts_info != FTS_DP && dsec != NULL)
arch = ff->fts_name;
else
arch = NULL;
break;
default:
- if (FTS_DP == ff->fts_info || use_all)
+ if (ff->fts_info == FTS_DP || use_all)
break;
if (warnings)
say(path, "Extraneous directory part");
@@ -762,7 +767,7 @@ treescan(void)
}
fts_close(f);
- return(1);
+ return 1;
}
/*
@@ -1103,22 +1108,14 @@ static void
mpages_merge(struct mparse *mp)
{
char any[] = "any";
- struct ohash_info str_info;
struct mpage *mpage, *mpage_dest;
struct mlink *mlink, *mlink_dest;
- struct mdoc *mdoc;
- struct man *man;
+ struct roff_man *man;
char *sodest;
char *cp;
int fd;
unsigned int pslot;
- str_info.alloc = hash_alloc;
- str_info.calloc = hash_calloc;
- str_info.free = hash_free;
- str_info.data = NULL;
- str_info.key_offset = offsetof(struct str, key);
-
if ( ! nodb)
SQL_EXEC("BEGIN TRANSACTION");
@@ -1131,15 +1128,13 @@ mpages_merge(struct mparse *mp)
}
name_mask = NAME_MASK;
- ohash_init(&names, 4, &str_info);
- ohash_init(&strings, 6, &str_info);
+ mandoc_ohash_init(&names, 4, offsetof(struct str, key));
+ mandoc_ohash_init(&strings, 6, offsetof(struct str, key));
mparse_reset(mp);
- mdoc = NULL;
man = NULL;
sodest = NULL;
- mparse_open(mp, &fd, mlink->file);
- if (fd == -1) {
+ if ((fd = mparse_open(mp, mlink->file)) == -1) {
say(mlink->file, "&open");
goto nextpage;
}
@@ -1150,7 +1145,8 @@ mpages_merge(struct mparse *mp)
*/
if (mlink->dform != FORM_CAT || mlink->fform != FORM_CAT) {
mparse_readfd(mp, fd, mlink->file);
- mparse_result(mp, &mdoc, &man, &sodest);
+ close(fd);
+ mparse_result(mp, &man, &sodest);
}
if (sodest != NULL) {
@@ -1194,21 +1190,22 @@ mpages_merge(struct mparse *mp)
mpage->mlinks = NULL;
}
goto nextpage;
- } else if (mdoc != NULL) {
+ } else if (man != NULL && man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
mpage->form = FORM_SRC;
- mpage->sec = mdoc_meta(mdoc)->msec;
+ mpage->sec = man->meta.msec;
mpage->sec = mandoc_strdup(
mpage->sec == NULL ? "" : mpage->sec);
- mpage->arch = mdoc_meta(mdoc)->arch;
+ mpage->arch = man->meta.arch;
mpage->arch = mandoc_strdup(
mpage->arch == NULL ? "" : mpage->arch);
- mpage->title =
- mandoc_strdup(mdoc_meta(mdoc)->title);
- } else if (man != NULL) {
+ mpage->title = mandoc_strdup(man->meta.title);
+ } else if (man != NULL && man->macroset == MACROSET_MAN) {
+ man_validate(man);
mpage->form = FORM_SRC;
- mpage->sec = mandoc_strdup(man_meta(man)->msec);
+ mpage->sec = mandoc_strdup(man->meta.msec);
mpage->arch = mandoc_strdup(mlink->arch);
- mpage->title = mandoc_strdup(man_meta(man)->title);
+ mpage->title = mandoc_strdup(man->meta.title);
} else {
mpage->form = FORM_CAT;
mpage->sec = mandoc_strdup(mlink->dsec);
@@ -1230,10 +1227,10 @@ mpages_merge(struct mparse *mp)
}
assert(mpage->desc == NULL);
- if (mdoc != NULL)
- parse_mdoc(mpage, mdoc_meta(mdoc), mdoc_node(mdoc));
+ if (man != NULL && man->macroset == MACROSET_MDOC)
+ parse_mdoc(mpage, &man->meta, man->first);
else if (man != NULL)
- parse_man(mpage, man_meta(man), man_node(man));
+ parse_man(mpage, &man->meta, man->first);
else
parse_cat(mpage, fd);
if (mpage->desc == NULL)
@@ -1248,10 +1245,6 @@ mpages_merge(struct mparse *mp)
mlink = mpage->mlinks;
nextpage:
- if (mparse_wait(mp) != MANDOCLEVEL_OK) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(mlink->file, "&wait gunzip");
- }
ohash_delete(&strings);
ohash_delete(&names);
mpage = ohash_next(&mpages, &pslot);
@@ -1266,7 +1259,6 @@ names_check(void)
{
sqlite3_stmt *stmt;
const char *name, *sec, *arch, *key;
- int irc;
sqlite3_prepare_v2(db,
"SELECT name, sec, arch, key FROM ("
@@ -1282,10 +1274,10 @@ names_check(void)
") USING (pageid);",
-1, &stmt, NULL);
- if (SQLITE_OK != sqlite3_bind_int64(stmt, 1, NAME_TITLE))
+ if (sqlite3_bind_int64(stmt, 1, NAME_TITLE) != SQLITE_OK)
say("", "%s", sqlite3_errmsg(db));
- while (SQLITE_ROW == (irc = sqlite3_step(stmt))) {
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
name = (const char *)sqlite3_column_text(stmt, 0);
sec = (const char *)sqlite3_column_text(stmt, 1);
arch = (const char *)sqlite3_column_text(stmt, 2);
@@ -1302,7 +1294,9 @@ parse_cat(struct mpage *mpage, int fd)
{
FILE *stream;
char *line, *p, *title;
- size_t len, plen, titlesz;
+ size_t linesz, plen, titlesz;
+ ssize_t len;
+ int offs;
stream = (-1 == fd) ?
fopen(mpage->mlinks->file, "r") :
@@ -1315,10 +1309,13 @@ parse_cat(struct mpage *mpage, int fd)
return;
}
+ line = NULL;
+ linesz = 0;
+
/* Skip to first blank line. */
- while (NULL != (line = fgetln(stream, &len)))
- if ('\n' == *line)
+ while (getline(&line, &linesz, stream) != -1)
+ if (*line == '\n')
break;
/*
@@ -1326,8 +1323,8 @@ parse_cat(struct mpage *mpage, int fd)
* is the first section header. Skip to it.
*/
- while (NULL != (line = fgetln(stream, &len)))
- if ('\n' != *line && ' ' != *line)
+ while (getline(&line, &linesz, stream) != -1)
+ if (*line != '\n' && *line != ' ')
break;
/*
@@ -1340,20 +1337,20 @@ parse_cat(struct mpage *mpage, int fd)
titlesz = 0;
title = NULL;
- while (NULL != (line = fgetln(stream, &len))) {
- if (' ' != *line || '\n' != line[len - 1])
+ while ((len = getline(&line, &linesz, stream)) != -1) {
+ if (*line != ' ')
break;
- while (len > 0 && isspace((unsigned char)*line)) {
- line++;
- len--;
- }
- if (1 == len)
+ offs = 0;
+ while (isspace((unsigned char)line[offs]))
+ offs++;
+ if (line[offs] == '\0')
continue;
- title = mandoc_realloc(title, titlesz + len);
- memcpy(title + titlesz, line, len);
- titlesz += len;
+ title = mandoc_realloc(title, titlesz + len - offs);
+ memcpy(title + titlesz, line + offs, len - offs);
+ titlesz += len - offs;
title[titlesz - 1] = ' ';
}
+ free(line);
/*
* If no page content can be found, or the input line
@@ -1371,8 +1368,7 @@ parse_cat(struct mpage *mpage, int fd)
return;
}
- title = mandoc_realloc(title, titlesz + 1);
- title[titlesz] = '\0';
+ title[titlesz - 1] = '\0';
/*
* Skip to the first dash.
@@ -1430,27 +1426,27 @@ putkey(const struct mpage *mpage, char *value, uint64_t type)
*/
static void
putmdockey(const struct mpage *mpage,
- const struct mdoc_node *n, uint64_t m)
+ const struct roff_node *n, uint64_t m)
{
for ( ; NULL != n; n = n->next) {
if (NULL != n->child)
putmdockey(mpage, n->child, m);
- if (MDOC_TEXT == n->type)
+ if (n->type == ROFFT_TEXT)
putkey(mpage, n->string, m);
}
}
static void
-parse_man(struct mpage *mpage, const struct man_meta *meta,
- const struct man_node *n)
+parse_man(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
- const struct man_node *head, *body;
+ const struct roff_node *head, *body;
char *start, *title;
char byte;
size_t sz;
- if (NULL == n)
+ if (n == NULL)
return;
/*
@@ -1460,15 +1456,14 @@ parse_man(struct mpage *mpage, const struct man_meta *meta,
* the correct section or not.
*/
- if (MAN_BODY == n->type && MAN_SH == n->tok) {
+ if (n->type == ROFFT_BODY && n->tok == MAN_SH) {
body = n;
- assert(body->parent);
- if (NULL != (head = body->parent->head) &&
- 1 == head->nchild &&
- NULL != (head = (head->child)) &&
- MAN_TEXT == head->type &&
- 0 == strcmp(head->string, "NAME") &&
- NULL != body->child) {
+ if ((head = body->parent->head) != NULL &&
+ (head = head->child) != NULL &&
+ head->next == NULL &&
+ head->type == ROFFT_TEXT &&
+ strcmp(head->string, "NAME") == 0 &&
+ body->child != NULL) {
/*
* Suck the entire NAME section into memory.
@@ -1478,7 +1473,7 @@ parse_man(struct mpage *mpage, const struct man_meta *meta,
*/
title = NULL;
- man_deroff(&title, body);
+ deroff(&title, body);
if (NULL == title)
return;
@@ -1568,22 +1563,18 @@ parse_man(struct mpage *mpage, const struct man_meta *meta,
}
static void
-parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
assert(NULL != n);
for (n = n->child; NULL != n; n = n->next) {
switch (n->type) {
- case MDOC_ELEM:
- /* FALLTHROUGH */
- case MDOC_BLOCK:
- /* FALLTHROUGH */
- case MDOC_HEAD:
- /* FALLTHROUGH */
- case MDOC_BODY:
- /* FALLTHROUGH */
- case MDOC_TAIL:
+ case ROFFT_ELEM:
+ case ROFFT_BLOCK:
+ case ROFFT_HEAD:
+ case ROFFT_BODY:
+ case ROFFT_TAIL:
if (NULL != mdocs[n->tok].fp)
if (0 == (*mdocs[n->tok].fp)(mpage, meta, n))
break;
@@ -1592,7 +1583,7 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta,
mdocs[n->tok].mask);
break;
default:
- assert(MDOC_ROOT != n->type);
+ assert(n->type != ROFFT_ROOT);
continue;
}
if (NULL != n->child)
@@ -1601,16 +1592,16 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta,
}
static int
-parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Fd(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
char *start, *end;
size_t sz;
if (SEC_SYNOPSIS != n->sec ||
NULL == (n = n->child) ||
- MDOC_TEXT != n->type)
- return(0);
+ n->type != ROFFT_TEXT)
+ return 0;
/*
* Only consider those `Fd' macro fields that begin with an
@@ -1618,10 +1609,10 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta,
*/
if (strcmp("#include", n->string))
- return(0);
+ return 0;
- if (NULL == (n = n->next) || MDOC_TEXT != n->type)
- return(0);
+ if ((n = n->next) == NULL || n->type != ROFFT_TEXT)
+ return 0;
/*
* Strip away the enclosing angle brackets and make sure we're
@@ -1633,7 +1624,7 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta,
start++;
if (0 == (sz = strlen(start)))
- return(0);
+ return 0;
end = &start[(int)sz - 1];
if ('>' == *end || '"' == *end)
@@ -1641,16 +1632,16 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta,
if (end > start)
putkeys(mpage, start, end - start + 1, TYPE_In);
- return(0);
+ return 0;
}
static void
-parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_fname(struct mpage *mpage, const struct roff_node *n)
{
char *cp;
size_t sz;
- if (n->type != MDOC_TEXT)
+ if (n->type != ROFFT_TEXT)
return;
/* Skip function pointer punctuation. */
@@ -1666,74 +1657,99 @@ parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n)
}
static int
-parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Fn(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
if (n->child == NULL)
- return(0);
+ return 0;
parse_mdoc_fname(mpage, n->child);
for (n = n->child->next; n != NULL; n = n->next)
- if (n->type == MDOC_TEXT)
+ if (n->type == ROFFT_TEXT)
putkey(mpage, n->string, TYPE_Fa);
- return(0);
+ return 0;
}
static int
-parse_mdoc_Fo(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Fo(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
- if (n->type != MDOC_HEAD)
- return(1);
+ if (n->type != ROFFT_HEAD)
+ return 1;
if (n->child != NULL)
parse_mdoc_fname(mpage, n->child);
- return(0);
+ return 0;
}
static int
-parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Va(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
+{
+ char *cp;
+
+ if (n->type != ROFFT_ELEM && n->type != ROFFT_BODY)
+ return 0;
+
+ if (n->child != NULL &&
+ n->child->next == NULL &&
+ n->child->type == ROFFT_TEXT)
+ return 1;
+
+ cp = NULL;
+ deroff(&cp, n);
+ if (cp != NULL) {
+ putkey(mpage, cp, TYPE_Vt | (n->tok == MDOC_Va ||
+ n->type == ROFFT_BODY ? TYPE_Va : 0));
+ free(cp);
+ }
+
+ return 0;
+}
+
+static int
+parse_mdoc_Xr(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
char *cp;
if (NULL == (n = n->child))
- return(0);
+ return 0;
if (NULL == n->next) {
putkey(mpage, n->string, TYPE_Xr);
- return(0);
+ return 0;
}
mandoc_asprintf(&cp, "%s(%s)", n->string, n->next->string);
putkey(mpage, cp, TYPE_Xr);
free(cp);
- return(0);
+ return 0;
}
static int
-parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Nd(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
- if (MDOC_BODY == n->type)
- mdoc_deroff(&mpage->desc, n);
- return(0);
+ if (n->type == ROFFT_BODY)
+ deroff(&mpage->desc, n);
+ return 0;
}
static int
-parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Nm(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
if (SEC_NAME == n->sec)
putmdockey(mpage, n->child, NAME_TITLE);
- else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) {
+ else if (n->sec == SEC_SYNOPSIS && n->type == ROFFT_HEAD) {
if (n->child == NULL)
putkey(mpage, meta->name, NAME_SYN);
else
@@ -1742,34 +1758,26 @@ parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta,
if ( ! (mpage->name_head_done ||
n->child == NULL || n->child->string == NULL ||
strcasecmp(n->child->string, meta->title))) {
- putkey(mpage, n->child->string, NAME_HEAD);
+ putkey(mpage, n->child->string, ROFFT_HEAD);
mpage->name_head_done = 1;
}
- return(0);
-}
-
-static int
-parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
-{
-
- return(SEC_CUSTOM == n->sec && MDOC_HEAD == n->type);
+ return 0;
}
static int
-parse_mdoc_head(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_Sh(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
- return(MDOC_HEAD == n->type);
+ return n->sec == SEC_CUSTOM && n->type == ROFFT_HEAD;
}
static int
-parse_mdoc_body(struct mpage *mpage, const struct mdoc_meta *meta,
- const struct mdoc_node *n)
+parse_mdoc_head(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
{
- return(MDOC_BODY == n->type);
+ return n->type == ROFFT_HEAD;
}
/*
@@ -1874,10 +1882,10 @@ utf8(unsigned int cp, char out[7])
out[4] = (cp >> 6 & 63) | 128;
out[5] = (cp & 63) | 128;
} else
- return(0);
+ return 0;
out[rc] = '\0';
- return(rc);
+ return rc;
}
/*
@@ -1935,7 +1943,6 @@ render_string(char **public, size_t *psz)
case '\\':
break;
case '\t':
- /* FALLTHROUGH */
case ASCII_NBRSP:
dst[dsz++] = ' ';
scp++;
@@ -1966,7 +1973,7 @@ render_string(char **public, size_t *psz)
*/
if (write_utf8) {
- unicode = mchars_spec2cp(mchars, seq, seqlen);
+ unicode = mchars_spec2cp(seq, seqlen);
if (unicode <= 0)
continue;
addsz = utf8(unicode, utfbuf);
@@ -1974,7 +1981,7 @@ render_string(char **public, size_t *psz)
continue;
addcp = utfbuf;
} else {
- addcp = mchars_spec2str(mchars, seq, seqlen, &addsz);
+ addcp = mchars_spec2str(seq, seqlen, &addsz);
if (addcp == NULL)
continue;
if (*addcp == ASCII_NBRSP) {
@@ -2001,9 +2008,9 @@ render_string(char **public, size_t *psz)
--*psz;
if (dst != NULL) {
(*public)[*psz] = '\0';
- return(1);
+ return 1;
} else
- return(0);
+ return 0;
}
static void
@@ -2214,7 +2221,7 @@ dbclose(int real)
return;
case 0:
execlp("cmp", "cmp", "-s",
- tempfilename, MANDOC_DB, NULL);
+ tempfilename, MANDOC_DB, (char *)NULL);
say("", "&exec cmp");
exit(0);
default:
@@ -2239,7 +2246,7 @@ dbclose(int real)
say("", "&fork rm");
return;
case 0:
- execlp("rm", "rm", "-rf", tempfilename, NULL);
+ execlp("rm", "rm", "-rf", tempfilename, (char *)NULL);
say("", "&exec rm");
exit((int)MANDOCLEVEL_SYSERR);
default:
@@ -2270,7 +2277,7 @@ dbopen(int real)
int rc, ofl;
if (nodb)
- return(1);
+ return 1;
*tempfilename = '\0';
ofl = SQLITE_OPEN_READWRITE;
@@ -2281,7 +2288,7 @@ dbopen(int real)
exitcode = (int)MANDOCLEVEL_SYSERR;
if (SQLITE_CANTOPEN != rc)
say(MANDOC_DB, "%s", sqlite3_errstr(rc));
- return(0);
+ return 0;
}
goto prepare_statements;
}
@@ -2295,7 +2302,7 @@ dbopen(int real)
if (MPARSE_QUICK & mparse_options) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say(MANDOC_DB "~", "%s", sqlite3_errstr(rc));
- return(0);
+ return 0;
}
(void)strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX",
@@ -2303,7 +2310,7 @@ dbopen(int real)
if (NULL == mkdtemp(tempfilename)) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say("", "&%s", tempfilename);
- return(0);
+ return 0;
}
(void)strlcat(tempfilename, "/" MANDOC_DB,
sizeof(tempfilename));
@@ -2311,7 +2318,7 @@ dbopen(int real)
if (SQLITE_OK != rc) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say("", "%s: %s", tempfilename, sqlite3_errstr(rc));
- return(0);
+ return 0;
}
create_tables:
@@ -2350,7 +2357,7 @@ create_tables:
exitcode = (int)MANDOCLEVEL_SYSERR;
say(MANDOC_DB, "%s", sqlite3_errmsg(db));
sqlite3_close(db);
- return(0);
+ return 0;
}
prepare_statements:
@@ -2360,7 +2367,7 @@ prepare_statements:
say(MANDOC_DB, "PRAGMA foreign_keys: %s",
sqlite3_errmsg(db));
sqlite3_close(db);
- return(0);
+ return 0;
}
sql = "DELETE FROM mpages WHERE pageid IN "
@@ -2394,32 +2401,11 @@ prepare_statements:
say(MANDOC_DB, "PRAGMA synchronous: %s",
sqlite3_errmsg(db));
sqlite3_close(db);
- return(0);
+ return 0;
}
#endif
- return(1);
-}
-
-static void *
-hash_calloc(size_t n, size_t sz, void *arg)
-{
-
- return(mandoc_calloc(n, sz));
-}
-
-static void *
-hash_alloc(size_t sz, void *arg)
-{
-
- return(mandoc_malloc(sz));
-}
-
-static void
-hash_free(void *p, void *arg)
-{
-
- free(p);
+ return 1;
}
static int
@@ -2461,12 +2447,12 @@ set_basedir(const char *targetdir, int report_baddir)
if (2 == getcwd_status) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say("", "getcwd: %s", startdir);
- return(0);
+ return 0;
}
if (-1 == chdir(startdir)) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say("", "&chdir %s", startdir);
- return(0);
+ return 0;
}
}
@@ -2480,13 +2466,13 @@ set_basedir(const char *targetdir, int report_baddir)
exitcode = (int)MANDOCLEVEL_BADARG;
say("", "&%s: realpath", targetdir);
}
- return(0);
+ return 0;
} else if (-1 == chdir(basedir)) {
if (report_baddir || errno != ENOENT) {
exitcode = (int)MANDOCLEVEL_BADARG;
say("", "&chdir");
}
- return(0);
+ return 0;
}
chdir_status = 1;
cp = strchr(basedir, '\0');
@@ -2494,12 +2480,12 @@ set_basedir(const char *targetdir, int report_baddir)
if (cp - basedir >= PATH_MAX - 1) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say("", "Filename too long");
- return(0);
+ return 0;
}
*cp++ = '/';
*cp = '\0';
}
- return(1);
+ return 1;
}
static void
diff --git a/manpage.c b/manpage.c
index 999f3d324762..45b6e7659bae 100644
--- a/manpage.c
+++ b/manpage.c
@@ -1,4 +1,4 @@
-/* $Id: manpage.c,v 1.10 2015/02/10 08:05:30 schwarze Exp $ */
+/* $Id: manpage.c,v 1.13 2015/11/07 17:58:55 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
@@ -28,7 +28,7 @@
#include <string.h>
#include <unistd.h>
-#include "manpath.h"
+#include "manconf.h"
#include "mansearch.h"
static void show(const char *, const char *);
@@ -37,13 +37,14 @@ int
main(int argc, char *argv[])
{
int ch, term;
- size_t i, sz, len;
+ size_t i, sz, linesz;
+ ssize_t len;
struct mansearch search;
struct manpage *res;
- char *conf_file, *defpaths, *auxpaths, *cp;
+ char *conf_file, *defpaths, *auxpaths, *line;
char buf[PATH_MAX];
const char *cmd;
- struct manpaths paths;
+ struct manconf conf;
char *progname;
extern char *optarg;
extern int optind;
@@ -57,7 +58,7 @@ main(int argc, char *argv[])
++progname;
auxpaths = defpaths = conf_file = NULL;
- memset(&paths, 0, sizeof(struct manpaths));
+ memset(&conf, 0, sizeof(conf));
memset(&search, 0, sizeof(struct mansearch));
while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
@@ -90,21 +91,21 @@ main(int argc, char *argv[])
search.outkey = "Nd";
search.argmode = ARG_EXPR;
- manpath_parse(&paths, conf_file, defpaths, auxpaths);
- ch = mansearch(&search, &paths, argc, argv, &res, &sz);
- manpath_free(&paths);
+ manconf_parse(&conf, conf_file, defpaths, auxpaths);
+ ch = mansearch(&search, &conf.manpath, argc, argv, &res, &sz);
+ manconf_free(&conf);
if (0 == ch)
goto usage;
if (0 == sz) {
free(res);
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
} else if (1 == sz && term) {
i = 1;
goto show;
} else if (NULL == res)
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
for (i = 0; i < sz; i++) {
printf("%6zu %s: %s\n",
@@ -117,25 +118,29 @@ main(int argc, char *argv[])
for (i = 0; i < sz; i++)
free(res[i].file);
free(res);
- return(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
i = 1;
printf("Enter a choice [1]: ");
fflush(stdout);
- if (NULL != (cp = fgetln(stdin, &len)))
- if ('\n' == cp[--len] && len > 0) {
- cp[len] = '\0';
- if ((i = atoi(cp)) < 1 || i > sz)
+ line = NULL;
+ linesz = 0;
+ if ((len = getline(&line, &linesz, stdin)) != -1) {
+ if ('\n' == line[--len] && len > 0) {
+ line[len] = '\0';
+ if ((i = atoi(line)) < 1 || i > sz)
i = 0;
}
+ }
+ free(line);
if (0 == i) {
for (i = 0; i < sz; i++)
free(res[i].file);
free(res);
- return(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
show:
cmd = res[i - 1].form ? "mandoc" : "cat";
@@ -154,7 +159,7 @@ usage:
"[-s section] "
"expr ...\n",
progname);
- return(EXIT_FAILURE);
+ return EXIT_FAILURE;
}
static void
diff --git a/manpath.c b/manpath.c
index e85175e945e8..0627f13d25ad 100644
--- a/manpath.c
+++ b/manpath.c
@@ -1,15 +1,15 @@
-/* $Id: manpath.c,v 1.19 2014/11/27 00:30:40 schwarze Exp $ */
+/* $Id: manpath.c,v 1.29 2015/11/07 17:58:55 schwarze Exp $ */
/*
- * Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -20,24 +20,27 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <assert.h>
#include <ctype.h>
+#if HAVE_ERR
+#include <err.h>
+#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mandoc_aux.h"
-#include "manpath.h"
-
-#define MAN_CONF_FILE "/etc/man.conf"
-#define MAN_CONF_KEY "_whatdb"
+#include "manconf.h"
+#if !HAVE_MANPATH
+static void manconf_file(struct manconf *, const char *);
+#endif
static void manpath_add(struct manpaths *, const char *, int);
static void manpath_parseline(struct manpaths *, char *, int);
+
void
-manpath_parse(struct manpaths *dirs, const char *file,
+manconf_parse(struct manconf *conf, const char *file,
char *defp, char *auxp)
{
#if HAVE_MANPATH
@@ -80,7 +83,7 @@ manpath_parse(struct manpaths *dirs, const char *file,
if ( ! ferror(stream) && feof(stream) &&
bsz && '\n' == buf[bsz - 1]) {
buf[bsz - 1] = '\0';
- manpath_parseline(dirs, buf, 1);
+ manpath_parseline(&conf->manpath, buf, 1);
}
free(buf);
@@ -89,11 +92,11 @@ manpath_parse(struct manpaths *dirs, const char *file,
char *insert;
/* Always prepend -m. */
- manpath_parseline(dirs, auxp, 1);
+ manpath_parseline(&conf->manpath, auxp, 1);
/* If -M is given, it overrides everything else. */
if (NULL != defp) {
- manpath_parseline(dirs, defp, 1);
+ manpath_parseline(&conf->manpath, defp, 1);
return;
}
@@ -104,21 +107,21 @@ manpath_parse(struct manpaths *dirs, const char *file,
/* No MANPATH; use man.conf(5) only. */
if (NULL == defp || '\0' == defp[0]) {
- manpath_manconf(dirs, file);
+ manconf_file(conf, file);
return;
}
/* Prepend man.conf(5) to MANPATH. */
if (':' == defp[0]) {
- manpath_manconf(dirs, file);
- manpath_parseline(dirs, defp, 0);
+ manconf_file(conf, file);
+ manpath_parseline(&conf->manpath, defp, 0);
return;
}
/* Append man.conf(5) to MANPATH. */
if (':' == defp[strlen(defp) - 1]) {
- manpath_parseline(dirs, defp, 0);
- manpath_manconf(dirs, file);
+ manpath_parseline(&conf->manpath, defp, 0);
+ manconf_file(conf, file);
return;
}
@@ -126,14 +129,14 @@ manpath_parse(struct manpaths *dirs, const char *file,
insert = strstr(defp, "::");
if (NULL != insert) {
*insert++ = '\0';
- manpath_parseline(dirs, defp, 0);
- manpath_manconf(dirs, file);
- manpath_parseline(dirs, insert + 1, 0);
+ manpath_parseline(&conf->manpath, defp, 0);
+ manconf_file(conf, file);
+ manpath_parseline(&conf->manpath, insert + 1, 0);
return;
}
/* MANPATH overrides man.conf(5) completely. */
- manpath_parseline(dirs, defp, 0);
+ manpath_parseline(&conf->manpath, defp, 0);
#endif
}
@@ -165,10 +168,8 @@ manpath_add(struct manpaths *dirs, const char *dir, int complain)
size_t i;
if (NULL == (cp = realpath(dir, buf))) {
- if (complain) {
- fputs("manpath: ", stderr);
- perror(dir);
- }
+ if (complain)
+ warn("manpath: %s", dir);
return;
}
@@ -177,10 +178,8 @@ manpath_add(struct manpaths *dirs, const char *dir, int complain)
return;
if (stat(cp, &sb) == -1) {
- if (complain) {
- fputs("manpath: ", stderr);
- perror(dir);
- }
+ if (complain)
+ warn("manpath: %s", dir);
return;
}
@@ -191,47 +190,147 @@ manpath_add(struct manpaths *dirs, const char *dir, int complain)
}
void
-manpath_free(struct manpaths *p)
+manconf_free(struct manconf *conf)
{
size_t i;
- for (i = 0; i < p->sz; i++)
- free(p->paths[i]);
+ for (i = 0; i < conf->manpath.sz; i++)
+ free(conf->manpath.paths[i]);
- free(p->paths);
+ free(conf->manpath.paths);
+ free(conf->output.includes);
+ free(conf->output.man);
+ free(conf->output.paper);
+ free(conf->output.style);
}
-void
-manpath_manconf(struct manpaths *dirs, const char *file)
+#if !HAVE_MANPATH
+static void
+manconf_file(struct manconf *conf, const char *file)
{
+ const char *const toks[] = { "manpath", "output", "_whatdb" };
+ char manpath_default[] = MANPATH_DEFAULT;
+
FILE *stream;
- char *p, *q;
- size_t len, keysz;
+ char *line, *cp, *ep;
+ size_t linesz, tok, toklen;
+ ssize_t linelen;
- keysz = strlen(MAN_CONF_KEY);
- assert(keysz > 0);
+ if ((stream = fopen(file, "r")) == NULL)
+ goto out;
- if (NULL == (stream = fopen(file, "r")))
- return;
+ line = NULL;
+ linesz = 0;
- while (NULL != (p = fgetln(stream, &len))) {
- if (0 == len || '\n' != p[--len])
+ while ((linelen = getline(&line, &linesz, stream)) != -1) {
+ cp = line;
+ ep = cp + linelen;
+ if (ep[-1] != '\n')
break;
- p[len] = '\0';
- while (isspace((unsigned char)*p))
- p++;
- if (strncmp(MAN_CONF_KEY, p, keysz))
- continue;
- p += keysz;
- while (isspace((unsigned char)*p))
- p++;
- if ('\0' == *p)
+ *--ep = '\0';
+ while (isspace((unsigned char)*cp))
+ cp++;
+ if (*cp == '#')
continue;
- if (NULL == (q = strrchr(p, '/')))
- continue;
- *q = '\0';
- manpath_add(dirs, p, 0);
- }
+ for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {
+ toklen = strlen(toks[tok]);
+ if (cp + toklen < ep &&
+ isspace((unsigned char)cp[toklen]) &&
+ strncmp(cp, toks[tok], toklen) == 0) {
+ cp += toklen;
+ while (isspace((unsigned char)*cp))
+ cp++;
+ break;
+ }
+ }
+
+ switch (tok) {
+ case 2: /* _whatdb */
+ while (ep > cp && ep[-1] != '/')
+ ep--;
+ if (ep == cp)
+ continue;
+ *ep = '\0';
+ /* FALLTHROUGH */
+ case 0: /* manpath */
+ manpath_add(&conf->manpath, cp, 0);
+ *manpath_default = '\0';
+ break;
+ case 1: /* output */
+ manconf_output(&conf->output, cp);
+ break;
+ default:
+ break;
+ }
+ }
+ free(line);
fclose(stream);
+
+out:
+ if (*manpath_default != '\0')
+ manpath_parseline(&conf->manpath, manpath_default, 0);
+}
+#endif
+
+void
+manconf_output(struct manoutput *conf, const char *cp)
+{
+ const char *const toks[] = {
+ "includes", "man", "paper", "style",
+ "indent", "width", "fragment", "mdoc"
+ };
+
+ size_t len, tok;
+
+ for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {
+ len = strlen(toks[tok]);
+ if ( ! strncmp(cp, toks[tok], len) &&
+ strchr(" = ", cp[len]) != NULL) {
+ cp += len;
+ if (*cp == '=')
+ cp++;
+ while (isspace((unsigned char)*cp))
+ cp++;
+ break;
+ }
+ }
+
+ if (tok < 6 && *cp == '\0')
+ return;
+
+ switch (tok) {
+ case 0:
+ if (conf->includes == NULL)
+ conf->includes = mandoc_strdup(cp);
+ break;
+ case 1:
+ if (conf->man == NULL)
+ conf->man = mandoc_strdup(cp);
+ break;
+ case 2:
+ if (conf->paper == NULL)
+ conf->paper = mandoc_strdup(cp);
+ break;
+ case 3:
+ if (conf->style == NULL)
+ conf->style = mandoc_strdup(cp);
+ break;
+ case 4:
+ if (conf->indent == 0)
+ conf->indent = strtonum(cp, 0, 1000, NULL);
+ break;
+ case 5:
+ if (conf->width == 0)
+ conf->width = strtonum(cp, 58, 1000, NULL);
+ break;
+ case 6:
+ conf->fragment = 1;
+ break;
+ case 7:
+ conf->mdoc = 1;
+ break;
+ default:
+ break;
+ }
}
diff --git a/mansearch.3 b/mansearch.3
index f41e3617f7e2..051f9aa2a8e1 100644
--- a/mansearch.3
+++ b/mansearch.3
@@ -1,4 +1,4 @@
-.\" $Id: mansearch.3,v 1.3 2014/12/12 21:44:33 schwarze Exp $
+.\" $Id: mansearch.3,v 1.4 2015/03/27 17:37:25 schwarze Exp $
.\"
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,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: December 12 2014 $
+.Dd $Mdocdate: March 27 2015 $
.Dt MANSEARCH 3
.Os
.Sh NAME
@@ -23,7 +23,7 @@
.Nd search manual page databases
.Sh SYNOPSIS
.In stdint.h
-.In manpath.h
+.In manconf.h
.In mansearch.h
.Ft int
.Fo mansearch_setup
@@ -53,7 +53,7 @@ Search options, defined in
.In mansearch.h .
.It Fa "const struct manpaths *paths"
Directories to be searched, defined in
-.In manpath.h .
+.In manconf.h .
.It Fa "int argc" , "char *argv[]"
Search criteria, usually taken from the command line.
.El
diff --git a/mansearch.c b/mansearch.c
index 05e2a0a2b3c6..843326baf103 100644
--- a/mansearch.c
+++ b/mansearch.c
@@ -1,4 +1,4 @@
-/* $Id: mansearch.c,v 1.55 2015/03/11 13:11:22 schwarze Exp $ */
+/* $Id: mansearch.c,v 1.64 2016/01/08 15:02:54 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,9 +7,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -21,6 +21,9 @@
#include <sys/types.h>
#include <assert.h>
+#if HAVE_ERR
+#include <err.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -34,11 +37,6 @@
#include <string.h>
#include <unistd.h>
-#if HAVE_OHASH
-#include <ohash.h>
-#else
-#include "compat_ohash.h"
-#endif
#include <sqlite3.h>
#ifndef SQLITE_DETERMINISTIC
#define SQLITE_DETERMINISTIC 0
@@ -46,7 +44,8 @@
#include "mandoc.h"
#include "mandoc_aux.h"
-#include "manpath.h"
+#include "mandoc_ohash.h"
+#include "manconf.h"
#include "mansearch.h"
extern int mansearch_keymax;
@@ -55,17 +54,17 @@ extern const char *const mansearch_keynames[];
#define SQL_BIND_TEXT(_db, _s, _i, _v) \
do { if (SQLITE_OK != sqlite3_bind_text \
((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \
- fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \
+ errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \
} while (0)
#define SQL_BIND_INT64(_db, _s, _i, _v) \
do { if (SQLITE_OK != sqlite3_bind_int64 \
((_s), (_i)++, (_v))) \
- fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \
+ errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \
} while (0)
#define SQL_BIND_BLOB(_db, _s, _i, _v) \
do { if (SQLITE_OK != sqlite3_bind_blob \
((_s), (_i)++, (&_v), sizeof(_v), SQLITE_STATIC)) \
- fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \
+ errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \
} while (0)
struct expr {
@@ -92,9 +91,6 @@ static void buildnames(const struct mansearch *,
const char *, int form);
static char *buildoutput(sqlite3 *, sqlite3_stmt *,
uint64_t, uint64_t);
-static void *hash_alloc(size_t, void *);
-static void hash_free(void *, void *);
-static void *hash_calloc(size_t, size_t, void *);
static struct expr *exprcomp(const struct mansearch *,
int, char *[]);
static void exprfree(struct expr *);
@@ -120,8 +116,8 @@ mansearch_setup(int start)
if (start) {
if (NULL != pagecache) {
- fprintf(stderr, "pagecache already enabled\n");
- return((int)MANDOCLEVEL_BADARG);
+ warnx("pagecache already enabled");
+ return (int)MANDOCLEVEL_BADARG;
}
pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES,
@@ -129,32 +125,32 @@ mansearch_setup(int start)
MAP_SHARED | MAP_ANON, -1, 0);
if (MAP_FAILED == pagecache) {
- perror("mmap");
+ warn("mmap");
pagecache = NULL;
- return((int)MANDOCLEVEL_SYSERR);
+ return (int)MANDOCLEVEL_SYSERR;
}
c = sqlite3_config(SQLITE_CONFIG_PAGECACHE,
pagecache, PC_PAGESIZE, PC_NUMPAGES);
if (SQLITE_OK == c)
- return((int)MANDOCLEVEL_OK);
+ return (int)MANDOCLEVEL_OK;
- fprintf(stderr, "pagecache: %s\n", sqlite3_errstr(c));
+ warnx("pagecache: %s", sqlite3_errstr(c));
} else if (NULL == pagecache) {
- fprintf(stderr, "pagecache missing\n");
- return((int)MANDOCLEVEL_BADARG);
+ warnx("pagecache missing");
+ return (int)MANDOCLEVEL_BADARG;
}
if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) {
- perror("munmap");
+ warn("munmap");
pagecache = NULL;
- return((int)MANDOCLEVEL_SYSERR);
+ return (int)MANDOCLEVEL_SYSERR;
}
pagecache = NULL;
- return((int)MANDOCLEVEL_OK);
+ return (int)MANDOCLEVEL_OK;
}
int
@@ -163,7 +159,6 @@ mansearch(const struct mansearch *search,
int argc, char *argv[],
struct manpage **res, size_t *sz)
{
- int fd, rc, c, indexbit;
int64_t pageid;
uint64_t outbit, iterbit;
char buf[PATH_MAX];
@@ -173,27 +168,18 @@ mansearch(const struct mansearch *search,
sqlite3 *db;
sqlite3_stmt *s, *s2;
struct match *mp;
- struct ohash_info info;
struct ohash htab;
unsigned int idx;
size_t i, j, cur, maxres;
+ int c, chdir_status, getcwd_status, indexbit;
- info.calloc = hash_calloc;
- info.alloc = hash_alloc;
- info.free = hash_free;
- info.key_offset = offsetof(struct match, pageid);
+ if (argc == 0 || (e = exprcomp(search, argc, argv)) == NULL) {
+ *sz = 0;
+ return 0;
+ }
- *sz = cur = maxres = 0;
- sql = NULL;
+ cur = maxres = 0;
*res = NULL;
- fd = -1;
- e = NULL;
- rc = 0;
-
- if (0 == argc)
- goto out;
- if (NULL == (e = exprcomp(search, argc, argv)))
- goto out;
if (NULL != search->outkey) {
outbit = TYPE_Nd;
@@ -210,19 +196,18 @@ mansearch(const struct mansearch *search,
outbit = 0;
/*
- * Save a descriptor to the current working directory.
- * Since pathnames in the "paths" variable might be relative,
- * and we'll be chdir()ing into them, we need to keep a handle
- * on our current directory from which to start the chdir().
+ * Remember the original working directory, if possible.
+ * This will be needed if the second or a later directory
+ * is given as a relative path.
+ * Do not error out if the current directory is not
+ * searchable: Maybe it won't be needed after all.
*/
- if (NULL == getcwd(buf, PATH_MAX)) {
- perror("getcwd");
- goto out;
- } else if (-1 == (fd = open(buf, O_RDONLY, 0))) {
- perror(buf);
- goto out;
- }
+ if (getcwd(buf, PATH_MAX) == NULL) {
+ getcwd_status = 0;
+ (void)strlcpy(buf, strerror(errno), sizeof(buf));
+ } else
+ getcwd_status = 1;
sql = sql_statement(e);
@@ -234,22 +219,28 @@ mansearch(const struct mansearch *search,
* scan it for our match expression.
*/
+ chdir_status = 0;
for (i = 0; i < paths->sz; i++) {
- if (-1 == fchdir(fd)) {
- perror(buf);
- free(*res);
- break;
- } else if (-1 == chdir(paths->paths[i])) {
- perror(paths->paths[i]);
+ if (chdir_status && paths->paths[i][0] != '/') {
+ if ( ! getcwd_status) {
+ warnx("%s: getcwd: %s", paths->paths[i], buf);
+ continue;
+ } else if (chdir(buf) == -1) {
+ warn("%s", buf);
+ continue;
+ }
+ }
+ if (chdir(paths->paths[i]) == -1) {
+ warn("%s", paths->paths[i]);
continue;
}
+ chdir_status = 1;
c = sqlite3_open_v2(MANDOC_DB, &db,
SQLITE_OPEN_READONLY, NULL);
if (SQLITE_OK != c) {
- fprintf(stderr, "%s/%s: %s\n",
- paths->paths[i], MANDOC_DB, strerror(errno));
+ warn("%s/%s", paths->paths[i], MANDOC_DB);
sqlite3_close(db);
continue;
}
@@ -271,7 +262,8 @@ mansearch(const struct mansearch *search,
j = 1;
c = sqlite3_prepare_v2(db, sql, -1, &s, NULL);
if (SQLITE_OK != c)
- fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+ errx((int)MANDOCLEVEL_SYSERR,
+ "%s", sqlite3_errmsg(db));
for (ep = e; NULL != ep; ep = ep->next) {
if (NULL == ep->substr) {
@@ -282,8 +274,7 @@ mansearch(const struct mansearch *search,
SQL_BIND_INT64(db, s, j, ep->bits);
}
- memset(&htab, 0, sizeof(struct ohash));
- ohash_init(&htab, 4, &info);
+ mandoc_ohash_init(&htab, 4, offsetof(struct match, pageid));
/*
* Hash each entry on its [unique] document identifier.
@@ -313,7 +304,7 @@ mansearch(const struct mansearch *search,
}
if (SQLITE_DONE != c)
- fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+ warnx("%s", sqlite3_errmsg(db));
sqlite3_finalize(s);
@@ -322,14 +313,16 @@ mansearch(const struct mansearch *search,
"WHERE pageid=? ORDER BY sec, arch, name",
-1, &s, NULL);
if (SQLITE_OK != c)
- fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+ errx((int)MANDOCLEVEL_SYSERR,
+ "%s", sqlite3_errmsg(db));
c = sqlite3_prepare_v2(db,
"SELECT bits, key, pageid FROM keys "
"WHERE pageid=? AND bits & ?",
-1, &s2, NULL);
if (SQLITE_OK != c)
- fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+ errx((int)MANDOCLEVEL_SYSERR,
+ "%s", sqlite3_errmsg(db));
for (mp = ohash_first(&htab, &idx);
NULL != mp;
@@ -370,17 +363,12 @@ mansearch(const struct mansearch *search,
break;
}
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
- rc = 1;
-out:
- if (-1 != fd) {
- if (-1 == fchdir(fd))
- perror(buf);
- close(fd);
- }
+ if (chdir_status && getcwd_status && chdir(buf) == -1)
+ warn("%s", buf);
exprfree(e);
free(sql);
*sz = cur;
- return(rc);
+ return 1;
}
void
@@ -404,9 +392,9 @@ manpage_compare(const void *vp1, const void *vp2)
mp1 = vp1;
mp2 = vp2;
- return( (diff = mp2->bits - mp1->bits) ? diff :
- (diff = mp1->sec - mp2->sec) ? diff :
- strcasecmp(mp1->names, mp2->names));
+ return (diff = mp2->bits - mp1->bits) ? diff :
+ (diff = mp1->sec - mp2->sec) ? diff :
+ strcasecmp(mp1->names, mp2->names);
}
static void
@@ -515,7 +503,7 @@ buildnames(const struct mansearch *search, struct manpage *mpage,
globfree(&globinfo);
}
if (c != SQLITE_DONE)
- fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+ warnx("%s", sqlite3_errmsg(db));
sqlite3_reset(s);
/* If none of the files is usable, use the first name. */
@@ -565,9 +553,9 @@ buildoutput(sqlite3 *db, sqlite3_stmt *s, uint64_t pageid, uint64_t outbit)
output = newoutput;
}
if (SQLITE_DONE != c)
- fprintf(stderr, "%s\n", sqlite3_errmsg(db));
+ warnx("%s", sqlite3_errmsg(db));
sqlite3_reset(s);
- return(output);
+ return output;
}
/*
@@ -662,7 +650,7 @@ sql_statement(const struct expr *e)
needop = 1;
}
- return(sql);
+ return sql;
}
/*
@@ -745,12 +733,12 @@ exprcomp(const struct mansearch *search, int argc, char *argv[])
toopen = logic = igncase = 0;
}
if ( ! (toopen || logic || igncase || toclose))
- return(first);
+ return first;
fail:
if (NULL != first)
exprfree(first);
- return(NULL);
+ return NULL;
}
static struct expr *
@@ -763,7 +751,7 @@ exprterm(const struct mansearch *search, char *buf, int cs)
int i, irc;
if ('\0' == *buf)
- return(NULL);
+ return NULL;
e = mandoc_calloc(1, sizeof(struct expr));
@@ -771,7 +759,7 @@ exprterm(const struct mansearch *search, char *buf, int cs)
e->bits = TYPE_Nm;
e->substr = buf;
e->equal = 1;
- return(e);
+ return e;
}
/*
@@ -783,7 +771,14 @@ exprterm(const struct mansearch *search, char *buf, int cs)
if (search->argmode == ARG_WORD) {
e->bits = TYPE_Nm;
e->substr = NULL;
+#if HAVE_REWB_BSD
mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
+#elif HAVE_REWB_SYSV
+ mandoc_asprintf(&val, "\\<%s\\>", buf);
+#else
+ mandoc_asprintf(&val,
+ "(^|[^a-zA-Z01-9_])%s([^a-zA-Z01-9_]|$)", buf);
+#endif
cs = 0;
} else if ((val = strpbrk(buf, "=~")) == NULL) {
e->bits = TYPE_Nm | TYPE_Nd;
@@ -807,14 +802,14 @@ exprterm(const struct mansearch *search, char *buf, int cs)
free(val);
if (irc) {
regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
- fprintf(stderr, "regcomp: %s\n", errbuf);
+ warnx("regcomp: %s", errbuf);
free(e);
- return(NULL);
+ return NULL;
}
}
if (e->bits)
- return(e);
+ return e;
/*
* Parse out all possible fields.
@@ -836,13 +831,13 @@ exprterm(const struct mansearch *search, char *buf, int cs)
if (i == mansearch_keymax) {
if (strcasecmp(key, "any")) {
free(e);
- return(NULL);
+ return NULL;
}
e->bits |= ~0ULL;
}
}
- return(e);
+ return e;
}
static void
@@ -856,24 +851,3 @@ exprfree(struct expr *p)
p = pp;
}
}
-
-static void *
-hash_calloc(size_t nmemb, size_t sz, void *arg)
-{
-
- return(mandoc_calloc(nmemb, sz));
-}
-
-static void *
-hash_alloc(size_t sz, void *arg)
-{
-
- return(mandoc_malloc(sz));
-}
-
-static void
-hash_free(void *p, void *arg)
-{
-
- free(p);
-}
diff --git a/mansearch.h b/mansearch.h
index 14ec8ceacd87..7f68ff676750 100644
--- a/mansearch.h
+++ b/mansearch.h
@@ -1,4 +1,4 @@
-/* $Id: mansearch.h,v 1.23 2014/12/01 08:05:52 schwarze Exp $ */
+/* $Id: mansearch.h,v 1.24 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -95,7 +95,6 @@ struct mansearch {
int firstmatch; /* first matching database only */
};
-__BEGIN_DECLS
struct manpaths;
@@ -107,5 +106,3 @@ int mansearch(const struct mansearch *cfg, /* options */
struct manpage **res, /* results */
size_t *ressz); /* results returned */
void mansearch_free(struct manpage *, size_t);
-
-__END_DECLS
diff --git a/mchars_alloc.3 b/mchars_alloc.3
index eba81b5224ec..2d42a432e5e6 100644
--- a/mchars_alloc.3
+++ b/mchars_alloc.3
@@ -1,4 +1,4 @@
-.\" $Id: mchars_alloc.3,v 1.2 2014/10/26 18:07:28 schwarze Exp $
+.\" $Id: mchars_alloc.3,v 1.3 2015/10/13 22:59:54 schwarze Exp $
.\"
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,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: October 26 2014 $
+.Dd $Mdocdate: October 13 2015 $
.Dt MCHARS_ALLOC 3
.Os
.Sh NAME
@@ -25,17 +25,13 @@
.Nm mchars_spec2cp ,
.Nm mchars_spec2str
.Nd character table for mandoc
-.Sh LIBRARY
-.Lb libmandoc
.Sh SYNOPSIS
.In sys/types.h
.In mandoc.h
-.Ft "struct mchars *"
-.Fn mchars_alloc "void"
.Ft void
-.Fo mchars_free
-.Fa "struct mchars *table"
-.Fc
+.Fn mchars_alloc void
+.Ft void
+.Fn mchars_free void
.Ft char
.Fo mchars_num2char
.Fa "const char *decimal"
@@ -48,13 +44,11 @@
.Fc
.Ft int
.Fo mchars_spec2cp
-.Fa "const struct mchars *table"
.Fa "const char *name"
.Fa "size_t sz"
.Fc
.Ft "const char *"
.Fo mchars_spec2str
-.Fa "const struct mchars *table"
.Fa "const char *name"
.Fa "size_t sz"
.Fa "size_t *rsz"
@@ -135,9 +129,9 @@ escape sequences.
.Pp
The function
.Fn mchars_alloc
-allocates an opaque
-.Vt "struct mchars *"
-table object for subsequent use by the following two lookup functions.
+initializes a static
+.Vt "struct ohash"
+object for subsequent use by the following two lookup functions.
When no longer needed, this object can be destroyed with
.Fn mchars_free .
.Pp
@@ -149,9 +143,7 @@ special character
.Fa name
consisting of
.Fa sz
-characters in the
-.Fa table
-and returns the corresponding Unicode codepoint.
+characters and returns the corresponding Unicode codepoint.
If the
.Ar name
is not recognized, \-1 is returned.
@@ -175,9 +167,7 @@ special character
.Fa name
consisting of
.Fa sz
-characters in the
-.Fa table
-and returns an ASCII string representation.
+characters and returns an ASCII string representation.
The length of the representation is returned in
.Fa rsz .
In many cases, the meaning of such ASCII representations
@@ -215,6 +205,7 @@ These funtions are implemented in the file
.Sh SEE ALSO
.Xr mandoc 1 ,
.Xr mandoc_escape 3 ,
+.Xr ohash_init 3 ,
.Xr mandoc_char 7 ,
.Xr roff 7
.Sh HISTORY
diff --git a/mdoc.7 b/mdoc.7
index d4c8ccd11c4b..198a46a9636f 100644
--- a/mdoc.7
+++ b/mdoc.7
@@ -1,4 +1,4 @@
-.\" $Id: mdoc.7,v 1.252 2015/02/23 13:31:04 schwarze Exp $
+.\" $Id: mdoc.7,v 1.257 2015/11/05 12:06:45 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013 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: February 23 2015 $
+.Dd $Mdocdate: November 5 2015 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -304,6 +304,11 @@ Print verbose information.
\&.El
.Ed
.Pp
+List the options in alphabetical order,
+uppercase before lowercase for each letter and
+with no regard to whether an option takes an argument.
+Put digits in ascending order before all letter options.
+.Pp
Manuals not documenting a command won't include the above fragment.
.Pp
Since the
@@ -1622,7 +1627,7 @@ See also
A function name.
Its syntax is as follows:
.Bd -ragged -offset indent
-.Pf \. Ns Sx \&Fn
+.Pf . Sx \&Fn
.Op Ar functype
.Ar funcname
.Op Oo Ar argtype Oc Ar argname
@@ -2093,7 +2098,7 @@ It is suggested to leave it unspecified, in which case
.Xr mandoc 1
uses its
.Fl Ios
-argument, or, if that isn't specified either,
+argument or, if that isn't specified either,
.Fa sysname
and
.Fa release
@@ -2155,19 +2160,23 @@ See also
Close parenthesised context opened by
.Sx \&Po .
.Ss \&Pf
-Removes the space between its argument
-.Pq Dq prefix
-and the following macro.
+Removes the space between its argument and the following macro.
Its syntax is as follows:
.Pp
.D1 .Pf Ar prefix macro arguments ...
.Pp
This is equivalent to:
.Pp
-.D1 .No Ar prefix No \&Ns Ar macro arguments ...
+.D1 .No \e& Ns Ar prefix No \&Ns Ar macro arguments ...
+.Pp
+The
+.Ar prefix
+argument is not parsed for macro names or delimiters,
+but used verbatim as if it were escaped.
.Pp
Examples:
.Dl ".Pf $ Ar variable_name"
+.Dl ".Pf . Ar macro_name"
.Dl ".Pf 0x Ar hex_digits"
.Pp
See also
@@ -2267,7 +2276,7 @@ Examples:
\&.%A J. D. Ullman
\&.%B Introduction to Automata Theory, Languages, and Computation
\&.%I Addison-Wesley
-\&.%C Reading, Massachusettes
+\&.%C Reading, Massachusetts
\&.%D 1979
\&.Re
.Ed
diff --git a/mdoc.c b/mdoc.c
index 027ecbeb317f..724d45c652cd 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.238 2015/02/12 13:00:52 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.256 2015/10/30 19:04:16 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,9 +7,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -27,13 +27,16 @@
#include <string.h>
#include <time.h>
-#include "mdoc.h"
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "libmdoc.h"
+#include "mandoc.h"
+#include "roff.h"
+#include "mdoc.h"
#include "libmandoc.h"
+#include "roff_int.h"
+#include "libmdoc.h"
const char *const __mdoc_macronames[MDOC_MAX + 1] = {
+ "text",
"Ap", "Dd", "Dt", "Os",
"Sh", "Ss", "Pp", "D1",
"Dl", "Bd", "Ed", "Bl",
@@ -64,8 +67,8 @@ const char *const __mdoc_macronames[MDOC_MAX + 1] = {
"Lk", "Mt", "Brq", "Bro",
"Brc", "%C", "Es", "En",
"Dx", "%Q", "br", "sp",
- "%U", "Ta", "ll", "text",
- };
+ "%U", "Ta", "ll",
+};
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
"split", "nosplit", "ragged",
@@ -79,157 +82,22 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
"symbolic", "nested", "centered"
};
-const char * const *mdoc_macronames = __mdoc_macronames;
+const char * const *mdoc_macronames = __mdoc_macronames + 1;
const char * const *mdoc_argnames = __mdoc_argnames;
-static void mdoc_node_free(struct mdoc_node *);
-static void mdoc_node_unlink(struct mdoc *,
- struct mdoc_node *);
-static void mdoc_free1(struct mdoc *);
-static void mdoc_alloc1(struct mdoc *);
-static struct mdoc_node *node_alloc(struct mdoc *, int, int,
- enum mdoct, enum mdoc_type);
-static void node_append(struct mdoc *, struct mdoc_node *);
-static int mdoc_ptext(struct mdoc *, int, char *, int);
-static int mdoc_pmacro(struct mdoc *, int, char *, int);
-
-
-const struct mdoc_node *
-mdoc_node(const struct mdoc *mdoc)
-{
-
- return(mdoc->first);
-}
-
-const struct mdoc_meta *
-mdoc_meta(const struct mdoc *mdoc)
-{
-
- return(&mdoc->meta);
-}
-
-/*
- * Frees volatile resources (parse tree, meta-data, fields).
- */
-static void
-mdoc_free1(struct mdoc *mdoc)
-{
-
- if (mdoc->first)
- mdoc_node_delete(mdoc, mdoc->first);
- free(mdoc->meta.msec);
- free(mdoc->meta.vol);
- free(mdoc->meta.arch);
- free(mdoc->meta.date);
- free(mdoc->meta.title);
- free(mdoc->meta.os);
- free(mdoc->meta.name);
-}
-
-/*
- * Allocate all volatile resources (parse tree, meta-data, fields).
- */
-static void
-mdoc_alloc1(struct mdoc *mdoc)
-{
-
- memset(&mdoc->meta, 0, sizeof(struct mdoc_meta));
- mdoc->flags = 0;
- mdoc->lastnamed = mdoc->lastsec = SEC_NONE;
- mdoc->last = mandoc_calloc(1, sizeof(struct mdoc_node));
- mdoc->first = mdoc->last;
- mdoc->last->type = MDOC_ROOT;
- mdoc->last->tok = MDOC_MAX;
- mdoc->next = MDOC_NEXT_CHILD;
-}
-
-/*
- * Free up volatile resources (see mdoc_free1()) then re-initialises the
- * data with mdoc_alloc1(). After invocation, parse data has been reset
- * and the parser is ready for re-invocation on a new tree; however,
- * cross-parse non-volatile data is kept intact.
- */
-void
-mdoc_reset(struct mdoc *mdoc)
-{
-
- mdoc_free1(mdoc);
- mdoc_alloc1(mdoc);
-}
-
-/*
- * Completely free up all volatile and non-volatile parse resources.
- * After invocation, the pointer is no longer usable.
- */
-void
-mdoc_free(struct mdoc *mdoc)
-{
-
- mdoc_free1(mdoc);
- free(mdoc);
-}
-
-/*
- * Allocate volatile and non-volatile parse resources.
- */
-struct mdoc *
-mdoc_alloc(struct roff *roff, struct mparse *parse,
- const char *defos, int quick)
-{
- struct mdoc *p;
-
- p = mandoc_calloc(1, sizeof(struct mdoc));
-
- p->parse = parse;
- p->defos = defos;
- p->quick = quick;
- p->roff = roff;
-
- mdoc_hash_init();
- mdoc_alloc1(p);
- return(p);
-}
-
-void
-mdoc_endparse(struct mdoc *mdoc)
-{
-
- mdoc_macroend(mdoc);
-}
-
-void
-mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep)
-{
- struct mdoc_node *n;
-
- n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
- n->eqn = ep;
- if (ep->ln > mdoc->last->line)
- n->flags |= MDOC_LINE;
- node_append(mdoc, n);
- mdoc->next = MDOC_NEXT_SIBLING;
-}
+static int mdoc_ptext(struct roff_man *, int, char *, int);
+static int mdoc_pmacro(struct roff_man *, int, char *, int);
-void
-mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
-{
- struct mdoc_node *n;
-
- n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL);
- n->span = sp;
- node_append(mdoc, n);
- mdoc->next = MDOC_NEXT_SIBLING;
-}
/*
* Main parse routine. Parses a single line -- really just hands off to
* the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
*/
int
-mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
+mdoc_parseln(struct roff_man *mdoc, int ln, char *buf, int offs)
{
- if (mdoc->last->type != MDOC_EQN || ln > mdoc->last->line)
+ if (mdoc->last->type != ROFFT_EQN || ln > mdoc->last->line)
mdoc->flags |= MDOC_NEWLINE;
/*
@@ -243,231 +111,80 @@ mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
else
mdoc->flags &= ~MDOC_SYNOPSIS;
- return(roff_getcontrol(mdoc->roff, buf, &offs) ?
+ return roff_getcontrol(mdoc->roff, buf, &offs) ?
mdoc_pmacro(mdoc, ln, buf, offs) :
- mdoc_ptext(mdoc, ln, buf, offs));
+ mdoc_ptext(mdoc, ln, buf, offs);
}
void
mdoc_macro(MACRO_PROT_ARGS)
{
- assert(tok < MDOC_MAX);
-
- if (mdoc->flags & MDOC_PBODY) {
- if (tok == MDOC_Dt) {
- mandoc_vmsg(MANDOCERR_DT_LATE,
- mdoc->parse, line, ppos,
- "Dt %s", buf + *pos);
- return;
- }
- } else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) {
- if (mdoc->meta.title == NULL) {
- mandoc_vmsg(MANDOCERR_DT_NOTITLE,
- mdoc->parse, line, ppos, "%s %s",
- mdoc_macronames[tok], buf + *pos);
- mdoc->meta.title = mandoc_strdup("UNTITLED");
- }
- if (NULL == mdoc->meta.vol)
- mdoc->meta.vol = mandoc_strdup("LOCAL");
- mdoc->flags |= MDOC_PBODY;
- }
- (*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf);
-}
-
-
-static void
-node_append(struct mdoc *mdoc, struct mdoc_node *p)
-{
-
- assert(mdoc->last);
- assert(mdoc->first);
- assert(MDOC_ROOT != p->type);
-
- switch (mdoc->next) {
- case MDOC_NEXT_SIBLING:
- mdoc->last->next = p;
- p->prev = mdoc->last;
- p->parent = mdoc->last->parent;
- break;
- case MDOC_NEXT_CHILD:
- mdoc->last->child = p;
- p->parent = mdoc->last;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- p->parent->nchild++;
-
- /*
- * Copy over the normalised-data pointer of our parent. Not
- * everybody has one, but copying a null pointer is fine.
- */
-
- switch (p->type) {
- case MDOC_BODY:
- if (ENDBODY_NOT != p->end)
- break;
- /* FALLTHROUGH */
- case MDOC_TAIL:
- /* FALLTHROUGH */
- case MDOC_HEAD:
- p->norm = p->parent->norm;
- break;
- default:
- break;
- }
-
- mdoc_valid_pre(mdoc, p);
+ assert(tok > TOKEN_NONE && tok < MDOC_MAX);
- switch (p->type) {
- case MDOC_HEAD:
- assert(MDOC_BLOCK == p->parent->type);
- p->parent->head = p;
- break;
- case MDOC_TAIL:
- assert(MDOC_BLOCK == p->parent->type);
- p->parent->tail = p;
- break;
- case MDOC_BODY:
- if (p->end)
- break;
- assert(MDOC_BLOCK == p->parent->type);
- p->parent->body = p;
- break;
- default:
- break;
- }
-
- mdoc->last = p;
-
- switch (p->type) {
- case MDOC_TBL:
- /* FALLTHROUGH */
- case MDOC_TEXT:
- mdoc_valid_post(mdoc);
- break;
- default:
- break;
- }
-}
-
-static struct mdoc_node *
-node_alloc(struct mdoc *mdoc, int line, int pos,
- enum mdoct tok, enum mdoc_type type)
-{
- struct mdoc_node *p;
-
- p = mandoc_calloc(1, sizeof(struct mdoc_node));
- p->sec = mdoc->lastsec;
- p->line = line;
- p->pos = pos;
- p->tok = tok;
- p->type = type;
-
- /* Flag analysis. */
-
- if (MDOC_SYNOPSIS & mdoc->flags)
- p->flags |= MDOC_SYNPRETTY;
- else
- p->flags &= ~MDOC_SYNPRETTY;
- if (MDOC_NEWLINE & mdoc->flags)
- p->flags |= MDOC_LINE;
- mdoc->flags &= ~MDOC_NEWLINE;
-
- return(p);
+ (*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf);
}
void
-mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
+mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, int tok)
{
- struct mdoc_node *p;
+ struct roff_node *p;
- p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL);
- node_append(mdoc, p);
- mdoc->next = MDOC_NEXT_CHILD;
+ p = roff_node_alloc(mdoc, line, pos, ROFFT_TAIL, tok);
+ roff_node_append(mdoc, p);
+ mdoc->next = ROFF_NEXT_CHILD;
}
-struct mdoc_node *
-mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
+struct roff_node *
+mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok,
+ struct roff_node *body, enum mdoc_endbody end)
{
- struct mdoc_node *p;
-
- assert(mdoc->first);
- assert(mdoc->last);
- p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD);
- node_append(mdoc, p);
- mdoc->next = MDOC_NEXT_CHILD;
- return(p);
-}
-
-struct mdoc_node *
-mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
-{
- struct mdoc_node *p;
-
- p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
- node_append(mdoc, p);
- mdoc->next = MDOC_NEXT_CHILD;
- return(p);
-}
-
-struct mdoc_node *
-mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
- struct mdoc_node *body, enum mdoc_endbody end)
-{
- struct mdoc_node *p;
+ struct roff_node *p;
body->flags |= MDOC_ENDED;
body->parent->flags |= MDOC_ENDED;
- p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
+ p = roff_node_alloc(mdoc, line, pos, ROFFT_BODY, tok);
p->body = body;
p->norm = body->norm;
p->end = end;
- node_append(mdoc, p);
- mdoc->next = MDOC_NEXT_SIBLING;
- return(p);
+ roff_node_append(mdoc, p);
+ mdoc->next = ROFF_NEXT_SIBLING;
+ return p;
}
-struct mdoc_node *
-mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
- enum mdoct tok, struct mdoc_arg *args)
+struct roff_node *
+mdoc_block_alloc(struct roff_man *mdoc, int line, int pos,
+ int tok, struct mdoc_arg *args)
{
- struct mdoc_node *p;
+ struct roff_node *p;
- p = node_alloc(mdoc, line, pos, tok, MDOC_BLOCK);
+ p = roff_node_alloc(mdoc, line, pos, ROFFT_BLOCK, tok);
p->args = args;
if (p->args)
(args->refcnt)++;
switch (tok) {
case MDOC_Bd:
- /* FALLTHROUGH */
case MDOC_Bf:
- /* FALLTHROUGH */
case MDOC_Bl:
- /* FALLTHROUGH */
case MDOC_En:
- /* FALLTHROUGH */
case MDOC_Rs:
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
break;
default:
break;
}
- node_append(mdoc, p);
- mdoc->next = MDOC_NEXT_CHILD;
- return(p);
+ roff_node_append(mdoc, p);
+ mdoc->next = ROFF_NEXT_CHILD;
+ return p;
}
void
-mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
- enum mdoct tok, struct mdoc_arg *args)
+mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos,
+ int tok, struct mdoc_arg *args)
{
- struct mdoc_node *p;
+ struct roff_node *p;
- p = node_alloc(mdoc, line, pos, tok, MDOC_ELEM);
+ p = roff_node_alloc(mdoc, line, pos, ROFFT_ELEM, tok);
p->args = args;
if (p->args)
(args->refcnt)++;
@@ -479,106 +196,17 @@ mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
default:
break;
}
- node_append(mdoc, p);
- mdoc->next = MDOC_NEXT_CHILD;
-}
-
-void
-mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p)
-{
- struct mdoc_node *n;
-
- n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT);
- n->string = roff_strdup(mdoc->roff, p);
- node_append(mdoc, n);
- mdoc->next = MDOC_NEXT_SIBLING;
+ roff_node_append(mdoc, p);
+ mdoc->next = ROFF_NEXT_CHILD;
}
void
-mdoc_word_append(struct mdoc *mdoc, const char *p)
+mdoc_node_relink(struct roff_man *mdoc, struct roff_node *p)
{
- struct mdoc_node *n;
- char *addstr, *newstr;
- n = mdoc->last;
- addstr = roff_strdup(mdoc->roff, p);
- mandoc_asprintf(&newstr, "%s %s", n->string, addstr);
- free(addstr);
- free(n->string);
- n->string = newstr;
- mdoc->next = MDOC_NEXT_SIBLING;
-}
-
-static void
-mdoc_node_free(struct mdoc_node *p)
-{
-
- if (MDOC_BLOCK == p->type || MDOC_ELEM == p->type)
- free(p->norm);
- if (p->string)
- free(p->string);
- if (p->args)
- mdoc_argv_free(p->args);
- free(p);
-}
-
-static void
-mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n)
-{
-
- /* Adjust siblings. */
-
- if (n->prev)
- n->prev->next = n->next;
- if (n->next)
- n->next->prev = n->prev;
-
- /* Adjust parent. */
-
- if (n->parent) {
- n->parent->nchild--;
- if (n->parent->child == n)
- n->parent->child = n->prev ? n->prev : n->next;
- if (n->parent->last == n)
- n->parent->last = n->prev ? n->prev : NULL;
- }
-
- /* Adjust parse point, if applicable. */
-
- if (mdoc && mdoc->last == n) {
- if (n->prev) {
- mdoc->last = n->prev;
- mdoc->next = MDOC_NEXT_SIBLING;
- } else {
- mdoc->last = n->parent;
- mdoc->next = MDOC_NEXT_CHILD;
- }
- }
-
- if (mdoc && mdoc->first == n)
- mdoc->first = NULL;
-}
-
-void
-mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p)
-{
-
- while (p->child) {
- assert(p->nchild);
- mdoc_node_delete(mdoc, p->child);
- }
- assert(0 == p->nchild);
-
- mdoc_node_unlink(mdoc, p);
- mdoc_node_free(p);
-}
-
-void
-mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p)
-{
-
- mdoc_node_unlink(mdoc, p);
- node_append(mdoc, p);
+ roff_node_unlink(mdoc, p);
+ p->prev = p->next = NULL;
+ roff_node_append(mdoc, p);
}
/*
@@ -586,37 +214,37 @@ mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p)
* control character.
*/
static int
-mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
+mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
{
+ struct roff_node *n;
char *c, *ws, *end;
- struct mdoc_node *n;
assert(mdoc->last);
n = mdoc->last;
/*
* Divert directly to list processing if we're encountering a
- * columnar MDOC_BLOCK with or without a prior MDOC_BLOCK entry
- * (a MDOC_BODY means it's already open, in which case we should
+ * columnar ROFFT_BLOCK with or without a prior ROFFT_BLOCK entry
+ * (a ROFFT_BODY means it's already open, in which case we should
* process within its context in the normal way).
*/
- if (n->tok == MDOC_Bl && n->type == MDOC_BODY &&
+ if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
/* `Bl' is open without any children. */
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
- return(1);
+ return 1;
}
- if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
+ if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
NULL != n->parent &&
MDOC_Bl == n->parent->tok &&
LIST_column == n->parent->norm->Bl.type) {
/* `Bl' has block-level `It' children. */
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
- return(1);
+ return 1;
}
/*
@@ -673,16 +301,16 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
* blank lines aren't allowed, but enough manuals assume this
* behaviour that we want to work around it.
*/
- mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL);
- mdoc->next = MDOC_NEXT_SIBLING;
- mdoc_valid_post(mdoc);
- return(1);
+ roff_elem_alloc(mdoc, line, offs, MDOC_sp);
+ mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+ mdoc->next = ROFF_NEXT_SIBLING;
+ return 1;
}
- mdoc_word_alloc(mdoc, line, offs, buf+offs);
+ roff_word_alloc(mdoc, line, offs, buf+offs);
if (mdoc->flags & MDOC_LITERAL)
- return(1);
+ return 1;
/*
* End-of-sentence check. If the last character is an unescaped
@@ -694,7 +322,7 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
mdoc->last->flags |= MDOC_EOS;
- return(1);
+ return 1;
}
/*
@@ -702,11 +330,11 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
* character.
*/
static int
-mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
+mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
{
- struct mdoc_node *n;
+ struct roff_node *n;
const char *cp;
- enum mdoct tok;
+ int tok;
int i, sv;
char mac[5];
@@ -723,12 +351,12 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
mac[i] = '\0';
- tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
+ tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : TOKEN_NONE;
- if (tok == MDOC_MAX) {
+ if (tok == TOKEN_NONE) {
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
ln, sv, buf + sv - 1);
- return(1);
+ return 1;
}
/* Skip a leading escape sequence or tab. */
@@ -767,7 +395,7 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
- return(1);
+ return 1;
}
n = mdoc->last;
@@ -778,11 +406,11 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
* context around the parsed macro.
*/
- if (n->tok == MDOC_Bl && n->type == MDOC_BODY &&
+ if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
- return(1);
+ return 1;
}
/*
@@ -791,13 +419,13 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
* then open an `It' block context around the parsed macro.
*/
- if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
+ if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
NULL != n->parent &&
MDOC_Bl == n->parent->tok &&
LIST_column == n->parent->norm->Bl.type) {
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
- return(1);
+ return 1;
}
/* Normal processing of a macro. */
@@ -808,9 +436,9 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
if (mdoc->quick && MDOC_Sh == tok &&
SEC_NAME != mdoc->last->sec)
- return(2);
+ return 2;
- return(1);
+ return 1;
}
enum mdelim
@@ -818,82 +446,44 @@ mdoc_isdelim(const char *p)
{
if ('\0' == p[0])
- return(DELIM_NONE);
+ return DELIM_NONE;
if ('\0' == p[1])
switch (p[0]) {
case '(':
- /* FALLTHROUGH */
case '[':
- return(DELIM_OPEN);
+ return DELIM_OPEN;
case '|':
- return(DELIM_MIDDLE);
+ return DELIM_MIDDLE;
case '.':
- /* FALLTHROUGH */
case ',':
- /* FALLTHROUGH */
case ';':
- /* FALLTHROUGH */
case ':':
- /* FALLTHROUGH */
case '?':
- /* FALLTHROUGH */
case '!':
- /* FALLTHROUGH */
case ')':
- /* FALLTHROUGH */
case ']':
- return(DELIM_CLOSE);
+ return DELIM_CLOSE;
default:
- return(DELIM_NONE);
+ return DELIM_NONE;
}
if ('\\' != p[0])
- return(DELIM_NONE);
+ return DELIM_NONE;
if (0 == strcmp(p + 1, "."))
- return(DELIM_CLOSE);
+ return DELIM_CLOSE;
if (0 == strcmp(p + 1, "fR|\\fP"))
- return(DELIM_MIDDLE);
+ return DELIM_MIDDLE;
- return(DELIM_NONE);
+ return DELIM_NONE;
}
void
-mdoc_deroff(char **dest, const struct mdoc_node *n)
+mdoc_validate(struct roff_man *mdoc)
{
- char *cp;
- size_t sz;
-
- if (MDOC_TEXT != n->type) {
- for (n = n->child; n; n = n->next)
- mdoc_deroff(dest, n);
- return;
- }
-
- /* Skip leading whitespace. */
-
- for (cp = n->string; '\0' != *cp; cp++)
- if (0 == isspace((unsigned char)*cp))
- break;
-
- /* Skip trailing whitespace. */
-
- for (sz = strlen(cp); sz; sz--)
- if (0 == isspace((unsigned char)cp[sz-1]))
- break;
-
- /* Skip empty strings. */
-
- if (0 == sz)
- return;
-
- if (NULL == *dest) {
- *dest = mandoc_strndup(cp, sz);
- return;
- }
- mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp);
- free(*dest);
- *dest = cp;
+ mdoc->last = mdoc->first;
+ mdoc_node_validate(mdoc);
+ mdoc_state_reset(mdoc);
}
diff --git a/mdoc.h b/mdoc.h
index e45786d4aa6a..ebe4391ef610 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -1,4 +1,4 @@
-/* $Id: mdoc.h,v 1.136 2015/02/12 12:24:33 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.144 2015/11/07 14:01:16 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,141 +7,139 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
*/
-enum mdoct {
- MDOC_Ap = 0,
- MDOC_Dd,
- MDOC_Dt,
- MDOC_Os,
- MDOC_Sh,
- MDOC_Ss,
- MDOC_Pp,
- MDOC_D1,
- MDOC_Dl,
- MDOC_Bd,
- MDOC_Ed,
- MDOC_Bl,
- MDOC_El,
- MDOC_It,
- MDOC_Ad,
- MDOC_An,
- MDOC_Ar,
- MDOC_Cd,
- MDOC_Cm,
- MDOC_Dv,
- MDOC_Er,
- MDOC_Ev,
- MDOC_Ex,
- MDOC_Fa,
- MDOC_Fd,
- MDOC_Fl,
- MDOC_Fn,
- MDOC_Ft,
- MDOC_Ic,
- MDOC_In,
- MDOC_Li,
- MDOC_Nd,
- MDOC_Nm,
- MDOC_Op,
- MDOC_Ot,
- MDOC_Pa,
- MDOC_Rv,
- MDOC_St,
- MDOC_Va,
- MDOC_Vt,
- MDOC_Xr,
- MDOC__A,
- MDOC__B,
- MDOC__D,
- MDOC__I,
- MDOC__J,
- MDOC__N,
- MDOC__O,
- MDOC__P,
- MDOC__R,
- MDOC__T,
- MDOC__V,
- MDOC_Ac,
- MDOC_Ao,
- MDOC_Aq,
- MDOC_At,
- MDOC_Bc,
- MDOC_Bf,
- MDOC_Bo,
- MDOC_Bq,
- MDOC_Bsx,
- MDOC_Bx,
- MDOC_Db,
- MDOC_Dc,
- MDOC_Do,
- MDOC_Dq,
- MDOC_Ec,
- MDOC_Ef,
- MDOC_Em,
- MDOC_Eo,
- MDOC_Fx,
- MDOC_Ms,
- MDOC_No,
- MDOC_Ns,
- MDOC_Nx,
- MDOC_Ox,
- MDOC_Pc,
- MDOC_Pf,
- MDOC_Po,
- MDOC_Pq,
- MDOC_Qc,
- MDOC_Ql,
- MDOC_Qo,
- MDOC_Qq,
- MDOC_Re,
- MDOC_Rs,
- MDOC_Sc,
- MDOC_So,
- MDOC_Sq,
- MDOC_Sm,
- MDOC_Sx,
- MDOC_Sy,
- MDOC_Tn,
- MDOC_Ux,
- MDOC_Xc,
- MDOC_Xo,
- MDOC_Fo,
- MDOC_Fc,
- MDOC_Oo,
- MDOC_Oc,
- MDOC_Bk,
- MDOC_Ek,
- MDOC_Bt,
- MDOC_Hf,
- MDOC_Fr,
- MDOC_Ud,
- MDOC_Lb,
- MDOC_Lp,
- MDOC_Lk,
- MDOC_Mt,
- MDOC_Brq,
- MDOC_Bro,
- MDOC_Brc,
- MDOC__C,
- MDOC_Es,
- MDOC_En,
- MDOC_Dx,
- MDOC__Q,
- MDOC_br,
- MDOC_sp,
- MDOC__U,
- MDOC_Ta,
- MDOC_ll,
- MDOC_MAX
-};
+#define MDOC_Ap 0
+#define MDOC_Dd 1
+#define MDOC_Dt 2
+#define MDOC_Os 3
+#define MDOC_Sh 4
+#define MDOC_Ss 5
+#define MDOC_Pp 6
+#define MDOC_D1 7
+#define MDOC_Dl 8
+#define MDOC_Bd 9
+#define MDOC_Ed 10
+#define MDOC_Bl 11
+#define MDOC_El 12
+#define MDOC_It 13
+#define MDOC_Ad 14
+#define MDOC_An 15
+#define MDOC_Ar 16
+#define MDOC_Cd 17
+#define MDOC_Cm 18
+#define MDOC_Dv 19
+#define MDOC_Er 20
+#define MDOC_Ev 21
+#define MDOC_Ex 22
+#define MDOC_Fa 23
+#define MDOC_Fd 24
+#define MDOC_Fl 25
+#define MDOC_Fn 26
+#define MDOC_Ft 27
+#define MDOC_Ic 28
+#define MDOC_In 29
+#define MDOC_Li 30
+#define MDOC_Nd 31
+#define MDOC_Nm 32
+#define MDOC_Op 33
+#define MDOC_Ot 34
+#define MDOC_Pa 35
+#define MDOC_Rv 36
+#define MDOC_St 37
+#define MDOC_Va 38
+#define MDOC_Vt 39
+#define MDOC_Xr 40
+#define MDOC__A 41
+#define MDOC__B 42
+#define MDOC__D 43
+#define MDOC__I 44
+#define MDOC__J 45
+#define MDOC__N 46
+#define MDOC__O 47
+#define MDOC__P 48
+#define MDOC__R 49
+#define MDOC__T 50
+#define MDOC__V 51
+#define MDOC_Ac 52
+#define MDOC_Ao 53
+#define MDOC_Aq 54
+#define MDOC_At 55
+#define MDOC_Bc 56
+#define MDOC_Bf 57
+#define MDOC_Bo 58
+#define MDOC_Bq 59
+#define MDOC_Bsx 60
+#define MDOC_Bx 61
+#define MDOC_Db 62
+#define MDOC_Dc 63
+#define MDOC_Do 64
+#define MDOC_Dq 65
+#define MDOC_Ec 66
+#define MDOC_Ef 67
+#define MDOC_Em 68
+#define MDOC_Eo 69
+#define MDOC_Fx 70
+#define MDOC_Ms 71
+#define MDOC_No 72
+#define MDOC_Ns 73
+#define MDOC_Nx 74
+#define MDOC_Ox 75
+#define MDOC_Pc 76
+#define MDOC_Pf 77
+#define MDOC_Po 78
+#define MDOC_Pq 79
+#define MDOC_Qc 80
+#define MDOC_Ql 81
+#define MDOC_Qo 82
+#define MDOC_Qq 83
+#define MDOC_Re 84
+#define MDOC_Rs 85
+#define MDOC_Sc 86
+#define MDOC_So 87
+#define MDOC_Sq 88
+#define MDOC_Sm 89
+#define MDOC_Sx 90
+#define MDOC_Sy 91
+#define MDOC_Tn 92
+#define MDOC_Ux 93
+#define MDOC_Xc 94
+#define MDOC_Xo 95
+#define MDOC_Fo 96
+#define MDOC_Fc 97
+#define MDOC_Oo 98
+#define MDOC_Oc 99
+#define MDOC_Bk 100
+#define MDOC_Ek 101
+#define MDOC_Bt 102
+#define MDOC_Hf 103
+#define MDOC_Fr 104
+#define MDOC_Ud 105
+#define MDOC_Lb 106
+#define MDOC_Lp 107
+#define MDOC_Lk 108
+#define MDOC_Mt 109
+#define MDOC_Brq 110
+#define MDOC_Bro 111
+#define MDOC_Brc 112
+#define MDOC__C 113
+#define MDOC_Es 114
+#define MDOC_En 115
+#define MDOC_Dx 116
+#define MDOC__Q 117
+#define MDOC_br 118
+#define MDOC_sp 119
+#define MDOC__U 120
+#define MDOC_Ta 121
+#define MDOC_ll 122
+#define MDOC_MAX 123
enum mdocargt {
MDOC_Split, /* -split */
@@ -174,61 +172,6 @@ enum mdocargt {
MDOC_ARG_MAX
};
-enum mdoc_type {
- MDOC_TEXT,
- MDOC_ELEM,
- MDOC_HEAD,
- MDOC_TAIL,
- MDOC_BODY,
- MDOC_BLOCK,
- MDOC_TBL,
- MDOC_EQN,
- MDOC_ROOT
-};
-
-/*
- * Section (named/unnamed) of `Sh'. Note that these appear in the
- * conventional order imposed by mdoc.7. In the case of SEC_NONE, no
- * section has been invoked (this shouldn't happen). SEC_CUSTOM refers
- * to other sections.
- */
-enum mdoc_sec {
- SEC_NONE = 0,
- SEC_NAME, /* NAME */
- SEC_LIBRARY, /* LIBRARY */
- SEC_SYNOPSIS, /* SYNOPSIS */
- SEC_DESCRIPTION, /* DESCRIPTION */
- SEC_CONTEXT, /* CONTEXT */
- SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */
- SEC_RETURN_VALUES, /* RETURN VALUES */
- SEC_ENVIRONMENT, /* ENVIRONMENT */
- SEC_FILES, /* FILES */
- SEC_EXIT_STATUS, /* EXIT STATUS */
- SEC_EXAMPLES, /* EXAMPLES */
- SEC_DIAGNOSTICS, /* DIAGNOSTICS */
- SEC_COMPATIBILITY, /* COMPATIBILITY */
- SEC_ERRORS, /* ERRORS */
- SEC_SEE_ALSO, /* SEE ALSO */
- SEC_STANDARDS, /* STANDARDS */
- SEC_HISTORY, /* HISTORY */
- SEC_AUTHORS, /* AUTHORS */
- SEC_CAVEATS, /* CAVEATS */
- SEC_BUGS, /* BUGS */
- SEC_SECURITY, /* SECURITY */
- SEC_CUSTOM,
- SEC__MAX
-};
-
-struct mdoc_meta {
- char *msec; /* `Dt' section (1, 3p, etc.) */
- char *vol; /* `Dt' volume (implied) */
- char *arch; /* `Dt' arch (i386, etc.) */
- char *date; /* `Dd' normalised date */
- char *title; /* `Dt' title (FOO, etc.) */
- char *os; /* `Os' system (OpenBSD, etc.) */
- char *name; /* leading `Nm' name */
-};
-
/*
* An argument to a macro (multiple values = `-column xxx yyy').
*/
@@ -251,16 +194,6 @@ struct mdoc_arg {
unsigned int refcnt;
};
-/*
- * Indicates that a BODY's formatting has ended, but the scope is still
- * open. Used for syntax-broken blocks.
- */
-enum mdoc_endbody {
- ENDBODY_NOT = 0,
- ENDBODY_SPACE, /* is broken: append a space */
- ENDBODY_NOSPACE /* is broken: don't append a space */
-};
-
enum mdoc_list {
LIST__NONE = 0,
LIST_bullet, /* -bullet */
@@ -337,59 +270,15 @@ union mdoc_data {
struct mdoc_bd Bd;
struct mdoc_bf Bf;
struct mdoc_bl Bl;
- struct mdoc_node *Es;
+ struct roff_node *Es;
struct mdoc_rs Rs;
};
-/*
- * Single node in tree-linked AST.
- */
-struct mdoc_node {
- struct mdoc_node *parent; /* parent AST node */
- struct mdoc_node *child; /* first child AST node */
- struct mdoc_node *last; /* last child AST node */
- struct mdoc_node *next; /* sibling AST node */
- struct mdoc_node *prev; /* prior sibling AST node */
- int nchild; /* number children */
- int line; /* parse line */
- int pos; /* parse column */
- enum mdoct tok; /* tok or MDOC__MAX if none */
- int flags;
-#define MDOC_VALID (1 << 0) /* has been validated */
-#define MDOC_ENDED (1 << 1) /* gone past body end mark */
-#define MDOC_EOS (1 << 2) /* at sentence boundary */
-#define MDOC_LINE (1 << 3) /* first macro/text on line */
-#define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting */
-#define MDOC_BROKEN (1 << 5) /* must validate parent when ending */
-#define MDOC_DELIMO (1 << 6)
-#define MDOC_DELIMC (1 << 7)
- enum mdoc_type type; /* AST node type */
- enum mdoc_sec sec; /* current named section */
- union mdoc_data *norm; /* normalised args */
- int prev_font; /* before entering this node */
- /* FIXME: these can be union'd to shave a few bytes. */
- struct mdoc_arg *args; /* BLOCK/ELEM */
- struct mdoc_node *head; /* BLOCK */
- struct mdoc_node *body; /* BLOCK/ENDBODY */
- struct mdoc_node *tail; /* BLOCK */
- char *string; /* TEXT */
- const struct tbl_span *span; /* TBL */
- const struct eqn *eqn; /* EQN */
- enum mdoc_endbody end; /* BODY */
-};
-
-/* Names of macros. Index is enum mdoct. */
+/* Names of macros. */
extern const char *const *mdoc_macronames;
/* Names of macro args. Index is enum mdocargt. */
extern const char *const *mdoc_argnames;
-__BEGIN_DECLS
-
-struct mdoc;
-
-const struct mdoc_node *mdoc_node(const struct mdoc *);
-const struct mdoc_meta *mdoc_meta(const struct mdoc *);
-void mdoc_deroff(char **, const struct mdoc_node *);
-__END_DECLS
+void mdoc_validate(struct roff_man *);
diff --git a/mdoc_argv.c b/mdoc_argv.c
index a53389bf99cc..8675bdb2db56 100644
--- a/mdoc_argv.c
+++ b/mdoc_argv.c
@@ -1,15 +1,15 @@
-/* $Id: mdoc_argv.c,v 1.100 2015/02/04 18:59:45 schwarze Exp $ */
+/* $Id: mdoc_argv.c,v 1.107 2015/10/17 00:21:07 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012, 2014, 2015 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -24,11 +24,12 @@
#include <stdio.h>
#include <string.h>
-#include "mdoc.h"
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "libmdoc.h"
+#include "mandoc.h"
+#include "roff.h"
+#include "mdoc.h"
#include "libmandoc.h"
+#include "libmdoc.h"
#define MULTI_STEP 5 /* pre-allocate argument values */
#define DELIMSZ 6 /* max possible size of a delimiter */
@@ -51,12 +52,12 @@ struct mdocarg {
};
static void argn_free(struct mdoc_arg *, int);
-static enum margserr args(struct mdoc *, int, int *,
+static enum margserr args(struct roff_man *, int, int *,
char *, enum argsflag, char **);
static int args_checkpunct(const char *, int);
-static void argv_multi(struct mdoc *, int,
+static void argv_multi(struct roff_man *, int,
struct mdoc_argv *, int *, char *);
-static void argv_single(struct mdoc *, int,
+static void argv_single(struct roff_man *, int,
struct mdoc_argv *, int *, char *);
static const enum argvflag argvflags[MDOC_ARG_MAX] = {
@@ -275,7 +276,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
* Some flags take no argument, some one, some multiple.
*/
void
-mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
+mdoc_argv(struct roff_man *mdoc, int line, int tok,
struct mdoc_arg **reta, int *pos, char *buf)
{
struct mdoc_argv tmpv;
@@ -412,18 +413,18 @@ argn_free(struct mdoc_arg *p, int iarg)
}
enum margserr
-mdoc_args(struct mdoc *mdoc, int line, int *pos,
- char *buf, enum mdoct tok, char **v)
+mdoc_args(struct roff_man *mdoc, int line, int *pos,
+ char *buf, int tok, char **v)
{
- struct mdoc_node *n;
+ struct roff_node *n;
char *v_local;
enum argsflag fl;
if (v == NULL)
v = &v_local;
- fl = tok == MDOC_MAX ? ARGSFL_NONE : mdocargs[tok].flags;
+ fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok].flags;
if (tok != MDOC_It)
- return(args(mdoc, line, pos, buf, fl, v));
+ return args(mdoc, line, pos, buf, fl, v);
/*
* We know that we're in an `It', so it's reasonable to expect
@@ -439,105 +440,82 @@ mdoc_args(struct mdoc *mdoc, int line, int *pos,
break;
}
- return(args(mdoc, line, pos, buf, fl, v));
+ return args(mdoc, line, pos, buf, fl, v);
}
static enum margserr
-args(struct mdoc *mdoc, int line, int *pos,
+args(struct roff_man *mdoc, int line, int *pos,
char *buf, enum argsflag fl, char **v)
{
- char *p, *pp;
+ char *p;
int pairs;
- enum margserr rc;
- if ('\0' == buf[*pos]) {
- if (MDOC_PPHRASE & mdoc->flags)
- return(ARGS_EOLN);
- /*
- * If we're not in a partial phrase and the flag for
- * being a phrase literal is still set, the punctuation
- * is unterminated.
- */
- if (MDOC_PHRASELIT & mdoc->flags)
+ if (buf[*pos] == '\0') {
+ if (mdoc->flags & MDOC_PHRASELIT &&
+ ! (mdoc->flags & MDOC_PHRASE)) {
mandoc_msg(MANDOCERR_ARG_QUOTE,
mdoc->parse, line, *pos, NULL);
-
- mdoc->flags &= ~MDOC_PHRASELIT;
- return(ARGS_EOLN);
+ mdoc->flags &= ~MDOC_PHRASELIT;
+ }
+ return ARGS_EOLN;
}
- *v = &buf[*pos];
+ *v = buf + *pos;
- if (ARGSFL_DELIM == fl)
- if (args_checkpunct(buf, *pos))
- return(ARGS_PUNCT);
+ if (fl == ARGSFL_DELIM && args_checkpunct(buf, *pos))
+ return ARGS_PUNCT;
/*
- * First handle TABSEP items, restricted to `Bl -column'. This
- * ignores conventional token parsing and instead uses tabs or
- * `Ta' macros to separate phrases. Phrases are parsed again
- * for arguments at a later phase.
+ * Tabs in `It' lines in `Bl -column' can't be escaped.
+ * Phrases are reparsed for `Ta' and other macros later.
*/
- if (ARGSFL_TABSEP == fl) {
- /* Scan ahead to tab (can't be escaped). */
- p = strchr(*v, '\t');
- pp = NULL;
-
- /* Scan ahead to unescaped `Ta'. */
- if ( ! (MDOC_PHRASELIT & mdoc->flags))
- for (pp = *v; ; pp++) {
- if (NULL == (pp = strstr(pp, "Ta")))
- break;
- if (pp > *v && ' ' != *(pp - 1))
- continue;
- if (' ' == *(pp + 2) || '\0' == *(pp + 2))
- break;
- }
-
- /* By default, assume a phrase. */
- rc = ARGS_PHRASE;
-
- /*
- * Adjust new-buffer position to be beyond delimiter
- * mark (e.g., Ta -> end + 2).
- */
- if (p && pp) {
- *pos += pp < p ? 2 : 1;
- rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE;
- p = pp < p ? pp : p;
- } else if (p && ! pp) {
- rc = ARGS_PPHRASE;
- *pos += 1;
- } else if (pp && ! p) {
- p = pp;
- *pos += 2;
+ if (fl == ARGSFL_TABSEP) {
+ if ((p = strchr(*v, '\t')) != NULL) {
+
+ /*
+ * Words right before and right after
+ * tab characters are not parsed,
+ * unless there is a blank in between.
+ */
+
+ if (p[-1] != ' ')
+ mdoc->flags |= MDOC_PHRASEQL;
+ if (p[1] != ' ')
+ mdoc->flags |= MDOC_PHRASEQN;
+
+ /*
+ * One or more blanks after a tab cause
+ * one leading blank in the next column.
+ * So skip all but one of them.
+ */
+
+ *pos += (int)(p - *v) + 1;
+ while (buf[*pos] == ' ' && buf[*pos + 1] == ' ')
+ (*pos)++;
+
+ /*
+ * A tab at the end of an input line
+ * switches to the next column.
+ */
+
+ if (buf[*pos] == '\0' || buf[*pos + 1] == '\0')
+ mdoc->flags |= MDOC_PHRASEQN;
} else {
- rc = ARGS_PEND;
- p = strchr(*v, 0);
+ p = strchr(*v, '\0');
+ if (p[-1] == ' ')
+ mandoc_msg(MANDOCERR_SPACE_EOL,
+ mdoc->parse, line, *pos, NULL);
+ *pos += (int)(p - *v);
}
- /* Whitespace check for eoln case... */
- if ('\0' == *p && ' ' == *(p - 1))
- mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
- line, *pos, NULL);
-
- *pos += (int)(p - *v);
-
- /* Strip delimiter's preceding whitespace. */
- pp = p - 1;
- while (pp > *v && ' ' == *pp) {
- if (pp > *v && '\\' == *(pp - 1))
- break;
- pp--;
- }
- *(pp + 1) = 0;
+ /* Skip any trailing blank characters. */
+ while (p > *v && p[-1] == ' ' &&
+ (p - 1 == *v || p[-2] != '\\'))
+ p--;
+ *p = '\0';
- /* Strip delimiter's proceeding whitespace. */
- for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++)
- /* Skip ahead. */ ;
-
- return(rc);
+ return ARGS_PHRASE;
}
/*
@@ -548,11 +526,11 @@ args(struct mdoc *mdoc, int line, int *pos,
* Whitespace is NOT involved in literal termination.
*/
- if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) {
- if ( ! (MDOC_PHRASELIT & mdoc->flags))
+ if (mdoc->flags & MDOC_PHRASELIT || buf[*pos] == '\"') {
+ if ( ! (mdoc->flags & MDOC_PHRASELIT))
*v = &buf[++(*pos)];
- if (MDOC_PPHRASE & mdoc->flags)
+ if (mdoc->flags & MDOC_PHRASE)
mdoc->flags |= MDOC_PHRASELIT;
pairs = 0;
@@ -572,19 +550,18 @@ args(struct mdoc *mdoc, int line, int *pos,
if (pairs)
buf[*pos - pairs] = '\0';
- if ('\0' == buf[*pos]) {
- if (MDOC_PPHRASE & mdoc->flags)
- return(ARGS_QWORD);
- mandoc_msg(MANDOCERR_ARG_QUOTE,
- mdoc->parse, line, *pos, NULL);
- return(ARGS_QWORD);
+ if (buf[*pos] == '\0') {
+ if ( ! (mdoc->flags & MDOC_PHRASE))
+ mandoc_msg(MANDOCERR_ARG_QUOTE,
+ mdoc->parse, line, *pos, NULL);
+ return ARGS_QWORD;
}
mdoc->flags &= ~MDOC_PHRASELIT;
buf[(*pos)++] = '\0';
if ('\0' == buf[*pos])
- return(ARGS_QWORD);
+ return ARGS_QWORD;
while (' ' == buf[*pos])
(*pos)++;
@@ -593,13 +570,22 @@ args(struct mdoc *mdoc, int line, int *pos,
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
line, *pos, NULL);
- return(ARGS_QWORD);
+ return ARGS_QWORD;
}
p = &buf[*pos];
*v = mandoc_getarg(mdoc->parse, &p, line, pos);
- return(ARGS_WORD);
+ /*
+ * After parsing the last word in this phrase,
+ * tell lookup() whether or not to interpret it.
+ */
+
+ if (*p == '\0' && mdoc->flags & MDOC_PHRASEQL) {
+ mdoc->flags &= ~MDOC_PHRASEQL;
+ mdoc->flags |= MDOC_PHRASEQF;
+ }
+ return ARGS_WORD;
}
/*
@@ -621,11 +607,11 @@ args_checkpunct(const char *buf, int i)
dbuf[j] = buf[i];
if (DELIMSZ == j)
- return(0);
+ return 0;
dbuf[j] = '\0';
if (DELIM_CLOSE != mdoc_isdelim(dbuf))
- return(0);
+ return 0;
while (' ' == buf[i])
i++;
@@ -638,22 +624,22 @@ args_checkpunct(const char *buf, int i)
dbuf[j++] = buf[i++];
if (DELIMSZ == j)
- return(0);
+ return 0;
dbuf[j] = '\0';
d = mdoc_isdelim(dbuf);
if (DELIM_NONE == d || DELIM_OPEN == d)
- return(0);
+ return 0;
while (' ' == buf[i])
i++;
}
- return('\0' == buf[i]);
+ return '\0' == buf[i];
}
static void
-argv_multi(struct mdoc *mdoc, int line,
+argv_multi(struct roff_man *mdoc, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
enum margserr ac;
@@ -675,7 +661,7 @@ argv_multi(struct mdoc *mdoc, int line,
}
static void
-argv_single(struct mdoc *mdoc, int line,
+argv_single(struct roff_man *mdoc, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
enum margserr ac;
diff --git a/mdoc_hash.c b/mdoc_hash.c
index 5e34fe8f58be..476116d792ab 100644
--- a/mdoc_hash.c
+++ b/mdoc_hash.c
@@ -1,6 +1,7 @@
-/* $Id: mdoc_hash.c,v 1.21 2014/08/10 23:54:41 schwarze Exp $ */
+/* $Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2015 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
@@ -25,22 +26,22 @@
#include <stdio.h>
#include <string.h>
+#include "roff.h"
#include "mdoc.h"
#include "libmdoc.h"
static unsigned char table[27 * 12];
-/*
- * XXX - this hash has global scope, so if intended for use as a library
- * with multiple callers, it will need re-invocation protection.
- */
void
mdoc_hash_init(void)
{
int i, j, major;
const char *p;
+ if (*table != '\0')
+ return;
+
memset(table, UCHAR_MAX, sizeof(table));
for (i = 0; i < (int)MDOC_MAX; i++) {
@@ -61,32 +62,32 @@ mdoc_hash_init(void)
}
}
-enum mdoct
+int
mdoc_hash_find(const char *p)
{
int major, i, j;
if (0 == p[0])
- return(MDOC_MAX);
+ return TOKEN_NONE;
if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
- return(MDOC_MAX);
+ return TOKEN_NONE;
if (isalpha((unsigned char)p[1]))
major = 12 * (tolower((unsigned char)p[1]) - 97);
else if ('1' == p[1])
major = 12 * 26;
else
- return(MDOC_MAX);
+ return TOKEN_NONE;
if (p[2] && p[3])
- return(MDOC_MAX);
+ return TOKEN_NONE;
for (j = 0; j < 12; j++) {
if (UCHAR_MAX == (i = table[major + j]))
break;
if (0 == strcmp(p, mdoc_macronames[i]))
- return((enum mdoct)i);
+ return i;
}
- return(MDOC_MAX);
+ return TOKEN_NONE;
}
diff --git a/mdoc_html.c b/mdoc_html.c
index fba7fb6fa4ab..8e21bc79630d 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -1,15 +1,15 @@
-/* $Id: mdoc_html.c,v 1.226 2015/03/03 21:11:34 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.240 2016/01/08 17:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2015, 2016 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -27,6 +27,7 @@
#include <unistd.h>
#include "mandoc_aux.h"
+#include "roff.h"
#include "mdoc.h"
#include "out.h"
#include "html.h"
@@ -34,8 +35,8 @@
#define INDENT 5
-#define MDOC_ARGS const struct mdoc_meta *meta, \
- struct mdoc_node *n, \
+#define MDOC_ARGS const struct roff_meta *meta, \
+ struct roff_node *n, \
struct html *h
#ifndef MIN
@@ -47,12 +48,11 @@ struct htmlmdoc {
void (*post)(MDOC_ARGS);
};
-static void print_mdoc(MDOC_ARGS);
static void print_mdoc_head(MDOC_ARGS);
static void print_mdoc_node(MDOC_ARGS);
static void print_mdoc_nodelist(MDOC_ARGS);
static void synopsis_pre(struct html *,
- const struct mdoc_node *);
+ const struct roff_node *);
static void a2width(const char *, struct roffsu *);
@@ -263,15 +263,6 @@ static const char * const lists[LIST_MAX] = {
};
-void
-html_mdoc(void *arg, const struct mdoc *mdoc)
-{
-
- print_mdoc(mdoc_meta(mdoc), mdoc_node(mdoc)->child,
- (struct html *)arg);
- putchar('\n');
-}
-
/*
* Calculate the scaling unit passed in a `-width' argument. This uses
* either a native scaling unit (e.g., 1i, 2m) or the string length of
@@ -292,7 +283,7 @@ a2width(const char *p, struct roffsu *su)
* See the same function in mdoc_term.c for documentation.
*/
static void
-synopsis_pre(struct html *h, const struct mdoc_node *n)
+synopsis_pre(struct html *h, const struct roff_node *n)
{
if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
@@ -308,13 +299,9 @@ synopsis_pre(struct html *h, const struct mdoc_node *n)
switch (n->prev->tok) {
case MDOC_Fd:
- /* FALLTHROUGH */
case MDOC_Fn:
- /* FALLTHROUGH */
case MDOC_Fo:
- /* FALLTHROUGH */
case MDOC_In:
- /* FALLTHROUGH */
case MDOC_Vt:
print_paragraph(h);
break;
@@ -330,27 +317,32 @@ synopsis_pre(struct html *h, const struct mdoc_node *n)
}
}
-static void
-print_mdoc(MDOC_ARGS)
+void
+html_mdoc(void *arg, const struct roff_man *mdoc)
{
- struct tag *t, *tt;
struct htmlpair tag;
+ struct html *h;
+ struct tag *t, *tt;
PAIR_CLASS_INIT(&tag, "mandoc");
+ h = (struct html *)arg;
if ( ! (HTML_FRAGMENT & h->oflags)) {
print_gen_decls(h);
t = print_otag(h, TAG_HTML, 0, NULL);
tt = print_otag(h, TAG_HEAD, 0, NULL);
- print_mdoc_head(meta, n, h);
+ print_mdoc_head(&mdoc->meta, mdoc->first->child, h);
print_tagq(h, tt);
print_otag(h, TAG_BODY, 0, NULL);
print_otag(h, TAG_DIV, 1, &tag);
} else
t = print_otag(h, TAG_DIV, 1, &tag);
- print_mdoc_nodelist(meta, n, h);
+ mdoc_root_pre(&mdoc->meta, mdoc->first->child, h);
+ print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h);
+ mdoc_root_post(&mdoc->meta, mdoc->first->child, h);
print_tagq(h, t);
+ putchar('\n');
}
static void
@@ -390,10 +382,7 @@ print_mdoc_node(MDOC_ARGS)
n->flags &= ~MDOC_ENDED;
switch (n->type) {
- case MDOC_ROOT:
- child = mdoc_root_pre(meta, n, h);
- break;
- case MDOC_TEXT:
+ case ROFFT_TEXT:
/* No tables in this mode... */
assert(NULL == h->tblt);
@@ -410,12 +399,12 @@ print_mdoc_node(MDOC_ARGS)
if (MDOC_DELIMO & n->flags)
h->flags |= HTML_NOSPACE;
return;
- case MDOC_EQN:
+ case ROFFT_EQN:
if (n->flags & MDOC_LINE)
putchar('\n');
print_eqn(h, n->eqn);
break;
- case MDOC_TBL:
+ case ROFFT_TBL:
/*
* This will take care of initialising all of the table
* state data for the first table, then tearing it down
@@ -450,10 +439,7 @@ print_mdoc_node(MDOC_ARGS)
print_stagq(h, t);
switch (n->type) {
- case MDOC_ROOT:
- mdoc_root_post(meta, n, h);
- break;
- case MDOC_EQN:
+ case ROFFT_EQN:
break;
default:
if ( ! mdocs[n->tok].post || n->flags & MDOC_ENDED)
@@ -534,7 +520,7 @@ mdoc_root_pre(MDOC_ARGS)
free(title);
free(volume);
- return(1);
+ return 1;
}
static int
@@ -543,22 +529,21 @@ mdoc_sh_pre(MDOC_ARGS)
struct htmlpair tag;
switch (n->type) {
- case MDOC_BLOCK:
+ case ROFFT_BLOCK:
PAIR_CLASS_INIT(&tag, "section");
print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- case MDOC_BODY:
+ return 1;
+ case ROFFT_BODY:
if (n->sec == SEC_AUTHORS)
h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT);
- return(1);
+ return 1;
default:
break;
}
bufinit(h);
- bufcat(h, "x");
- for (n = n->child; n && MDOC_TEXT == n->type; ) {
+ for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) {
bufcat_id(h, n->string);
if (NULL != (n = n->next))
bufcat_id(h, " ");
@@ -570,7 +555,7 @@ mdoc_sh_pre(MDOC_ARGS)
} else
print_otag(h, TAG_H1, 0, NULL);
- return(1);
+ return 1;
}
static int
@@ -578,17 +563,16 @@ mdoc_ss_pre(MDOC_ARGS)
{
struct htmlpair tag;
- if (MDOC_BLOCK == n->type) {
+ if (n->type == ROFFT_BLOCK) {
PAIR_CLASS_INIT(&tag, "subsection");
print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- } else if (MDOC_BODY == n->type)
- return(1);
+ return 1;
+ } else if (n->type == ROFFT_BODY)
+ return 1;
bufinit(h);
- bufcat(h, "x");
- for (n = n->child; n && MDOC_TEXT == n->type; ) {
+ for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) {
bufcat_id(h, n->string);
if (NULL != (n = n->next))
bufcat_id(h, " ");
@@ -600,7 +584,7 @@ mdoc_ss_pre(MDOC_ARGS)
} else
print_otag(h, TAG_H2, 0, NULL);
- return(1);
+ return 1;
}
static int
@@ -614,17 +598,17 @@ mdoc_fl_pre(MDOC_ARGS)
/* `Cm' has no leading hyphen. */
if (MDOC_Cm == n->tok)
- return(1);
+ return 1;
print_text(h, "\\-");
- if ( ! (n->nchild == 0 &&
+ if (!(n->child == NULL &&
(n->next == NULL ||
- n->next->type == MDOC_TEXT ||
+ n->next->type == ROFFT_TEXT ||
n->next->flags & MDOC_LINE)))
h->flags |= HTML_NOSPACE;
- return(1);
+ return 1;
}
static int
@@ -632,15 +616,15 @@ mdoc_nd_pre(MDOC_ARGS)
{
struct htmlpair tag;
- if (MDOC_BODY != n->type)
- return(1);
+ if (n->type != ROFFT_BODY)
+ return 1;
/* XXX: this tag in theory can contain block elements. */
print_text(h, "\\(em");
PAIR_CLASS_INIT(&tag, "desc");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -651,21 +635,18 @@ mdoc_nm_pre(MDOC_ARGS)
int len;
switch (n->type) {
- case MDOC_ELEM:
- synopsis_pre(h, n);
+ case ROFFT_HEAD:
+ print_otag(h, TAG_TD, 0, NULL);
+ /* FALLTHROUGH */
+ case ROFFT_ELEM:
PAIR_CLASS_INIT(&tag, "name");
print_otag(h, TAG_B, 1, &tag);
- if (NULL == n->child && meta->name)
- print_text(h, meta->name);
- return(1);
- case MDOC_HEAD:
- print_otag(h, TAG_TD, 0, NULL);
- if (NULL == n->child && meta->name)
+ if (n->child == NULL && meta->name != NULL)
print_text(h, meta->name);
- return(1);
- case MDOC_BODY:
+ return 1;
+ case ROFFT_BODY:
print_otag(h, TAG_TD, 0, NULL);
- return(1);
+ return 1;
default:
break;
}
@@ -674,11 +655,11 @@ mdoc_nm_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "synopsis");
print_otag(h, TAG_TABLE, 1, &tag);
- for (len = 0, n = n->child; n; n = n->next)
- if (MDOC_TEXT == n->type)
+ for (len = 0, n = n->head->child; n; n = n->next)
+ if (n->type == ROFFT_TEXT)
len += html_strlen(n->string);
- if (0 == len && meta->name)
+ if (len == 0 && meta->name != NULL)
len = html_strlen(meta->name);
SCALE_HS_INIT(&su, len);
@@ -689,7 +670,7 @@ mdoc_nm_pre(MDOC_ARGS)
print_otag(h, TAG_COL, 0, NULL);
print_otag(h, TAG_TBODY, 0, NULL);
print_otag(h, TAG_TR, 0, NULL);
- return(1);
+ return 1;
}
static int
@@ -698,7 +679,7 @@ mdoc_xr_pre(MDOC_ARGS)
struct htmlpair tag[2];
if (NULL == n->child)
- return(0);
+ return 0;
PAIR_CLASS_INIT(&tag[0], "link-man");
@@ -715,7 +696,7 @@ mdoc_xr_pre(MDOC_ARGS)
print_text(h, n->string);
if (NULL == (n = n->next))
- return(0);
+ return 0;
h->flags |= HTML_NOSPACE;
print_text(h, "(");
@@ -723,7 +704,7 @@ mdoc_xr_pre(MDOC_ARGS)
print_text(h, n->string);
h->flags |= HTML_NOSPACE;
print_text(h, ")");
- return(0);
+ return 0;
}
static int
@@ -732,7 +713,7 @@ mdoc_ns_pre(MDOC_ARGS)
if ( ! (MDOC_LINE & n->flags))
h->flags |= HTML_NOSPACE;
- return(1);
+ return 1;
}
static int
@@ -742,7 +723,7 @@ mdoc_ar_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "arg");
print_otag(h, TAG_I, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -772,7 +753,7 @@ mdoc_xx_pre(MDOC_ARGS)
pp = "UNIX";
break;
default:
- return(1);
+ return 1;
}
PAIR_CLASS_INIT(&tag, "unix");
@@ -785,7 +766,7 @@ mdoc_xx_pre(MDOC_ARGS)
print_text(h, n->child->string);
h->flags = flags;
}
- return(0);
+ return 0;
}
static int
@@ -802,7 +783,7 @@ mdoc_bx_pre(MDOC_ARGS)
print_text(h, "BSD");
} else {
print_text(h, "BSD");
- return(0);
+ return 0;
}
if (NULL != (n = n->next)) {
@@ -812,7 +793,7 @@ mdoc_bx_pre(MDOC_ARGS)
print_text(h, n->string);
}
- return(0);
+ return 0;
}
static int
@@ -821,7 +802,7 @@ mdoc_it_pre(MDOC_ARGS)
struct roffsu su;
enum mdoc_list type;
struct htmlpair tag[2];
- const struct mdoc_node *bl;
+ const struct roff_node *bl;
bl = n->parent;
while (bl && MDOC_Bl != bl->tok)
@@ -836,26 +817,18 @@ mdoc_it_pre(MDOC_ARGS)
bufinit(h);
- if (MDOC_HEAD == n->type) {
+ if (n->type == ROFFT_HEAD) {
switch (type) {
case LIST_bullet:
- /* FALLTHROUGH */
case LIST_dash:
- /* FALLTHROUGH */
case LIST_item:
- /* FALLTHROUGH */
case LIST_hyphen:
- /* FALLTHROUGH */
case LIST_enum:
- return(0);
+ return 0;
case LIST_diag:
- /* FALLTHROUGH */
case LIST_hang:
- /* FALLTHROUGH */
case LIST_inset:
- /* FALLTHROUGH */
case LIST_ohang:
- /* FALLTHROUGH */
case LIST_tag:
SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
bufcat_su(h, "margin-top", &su);
@@ -871,16 +844,12 @@ mdoc_it_pre(MDOC_ARGS)
default:
break;
}
- } else if (MDOC_BODY == n->type) {
+ } else if (n->type == ROFFT_BODY) {
switch (type) {
case LIST_bullet:
- /* FALLTHROUGH */
case LIST_hyphen:
- /* FALLTHROUGH */
case LIST_dash:
- /* FALLTHROUGH */
case LIST_enum:
- /* FALLTHROUGH */
case LIST_item:
SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
bufcat_su(h, "margin-top", &su);
@@ -888,13 +857,9 @@ mdoc_it_pre(MDOC_ARGS)
print_otag(h, TAG_LI, 2, tag);
break;
case LIST_diag:
- /* FALLTHROUGH */
case LIST_hang:
- /* FALLTHROUGH */
case LIST_inset:
- /* FALLTHROUGH */
case LIST_ohang:
- /* FALLTHROUGH */
case LIST_tag:
if (NULL == bl->norm->Bl.width) {
print_otag(h, TAG_DD, 1, tag);
@@ -924,7 +889,7 @@ mdoc_it_pre(MDOC_ARGS)
}
}
- return(1);
+ return 1;
}
static int
@@ -935,15 +900,15 @@ mdoc_bl_pre(MDOC_ARGS)
struct roffsu su;
char buf[BUFSIZ];
- if (MDOC_BODY == n->type) {
+ if (n->type == ROFFT_BODY) {
if (LIST_column == n->norm->Bl.type)
print_otag(h, TAG_TBODY, 0, NULL);
- return(1);
+ return 1;
}
- if (MDOC_HEAD == n->type) {
+ if (n->type == ROFFT_HEAD) {
if (LIST_column != n->norm->Bl.type)
- return(0);
+ return 0;
/*
* For each column, print out the <COL> tag with our
@@ -963,7 +928,7 @@ mdoc_bl_pre(MDOC_ARGS)
print_otag(h, TAG_COL, 1, tag);
}
- return(0);
+ return 0;
}
SCALE_VS_INIT(&su, 0);
@@ -986,11 +951,8 @@ mdoc_bl_pre(MDOC_ARGS)
switch (n->norm->Bl.type) {
case LIST_bullet:
- /* FALLTHROUGH */
case LIST_dash:
- /* FALLTHROUGH */
case LIST_hyphen:
- /* FALLTHROUGH */
case LIST_item:
print_otag(h, TAG_UL, 2, tag);
break;
@@ -998,13 +960,9 @@ mdoc_bl_pre(MDOC_ARGS)
print_otag(h, TAG_OL, 2, tag);
break;
case LIST_diag:
- /* FALLTHROUGH */
case LIST_hang:
- /* FALLTHROUGH */
case LIST_inset:
- /* FALLTHROUGH */
case LIST_ohang:
- /* FALLTHROUGH */
case LIST_tag:
print_otag(h, TAG_DL, 2, tag);
break;
@@ -1013,18 +971,17 @@ mdoc_bl_pre(MDOC_ARGS)
break;
default:
abort();
- /* NOTREACHED */
}
- return(1);
+ return 1;
}
static int
mdoc_ex_pre(MDOC_ARGS)
{
- struct tag *t;
- struct htmlpair tag;
- int nchild;
+ struct htmlpair tag;
+ struct tag *t;
+ struct roff_node *nch;
if (n->prev)
print_otag(h, TAG_BR, 0, NULL);
@@ -1033,30 +990,32 @@ mdoc_ex_pre(MDOC_ARGS)
print_text(h, "The");
- nchild = n->nchild;
- for (n = n->child; n; n = n->next) {
- assert(MDOC_TEXT == n->type);
+ for (nch = n->child; nch != NULL; nch = nch->next) {
+ assert(nch->type == ROFFT_TEXT);
t = print_otag(h, TAG_B, 1, &tag);
- print_text(h, n->string);
+ print_text(h, nch->string);
print_tagq(h, t);
- if (nchild > 2 && n->next) {
+ if (nch->next == NULL)
+ continue;
+
+ if (nch->prev != NULL || nch->next->next != NULL) {
h->flags |= HTML_NOSPACE;
print_text(h, ",");
}
- if (n->next && NULL == n->next->next)
+ if (nch->next->next == NULL)
print_text(h, "and");
}
- if (nchild > 1)
+ if (n->child != NULL && n->child->next != NULL)
print_text(h, "utilities exit\\~0");
else
print_text(h, "utility exits\\~0");
print_text(h, "on success, and\\~>0 if an error occurs.");
- return(0);
+ return 0;
}
static int
@@ -1066,7 +1025,7 @@ mdoc_em_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "emph");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1075,8 +1034,8 @@ mdoc_d1_pre(MDOC_ARGS)
struct htmlpair tag[2];
struct roffsu su;
- if (MDOC_BLOCK != n->type)
- return(1);
+ if (n->type != ROFFT_BLOCK)
+ return 1;
SCALE_VS_INIT(&su, 0);
bufinit(h);
@@ -1095,7 +1054,7 @@ mdoc_d1_pre(MDOC_ARGS)
print_otag(h, TAG_CODE, 1, tag);
}
- return(1);
+ return 1;
}
static int
@@ -1104,7 +1063,7 @@ mdoc_sx_pre(MDOC_ARGS)
struct htmlpair tag[2];
bufinit(h);
- bufcat(h, "#x");
+ bufcat(h, "#");
for (n = n->child; n; ) {
bufcat_id(h, n->string);
@@ -1117,7 +1076,7 @@ mdoc_sx_pre(MDOC_ARGS)
print_otag(h, TAG_I, 1, tag);
print_otag(h, TAG_A, 2, tag);
- return(1);
+ return 1;
}
static int
@@ -1125,16 +1084,16 @@ mdoc_bd_pre(MDOC_ARGS)
{
struct htmlpair tag[2];
int comp, sv;
- struct mdoc_node *nn;
+ struct roff_node *nn;
struct roffsu su;
- if (MDOC_HEAD == n->type)
- return(0);
+ if (n->type == ROFFT_HEAD)
+ return 0;
- if (MDOC_BLOCK == n->type) {
+ if (n->type == ROFFT_BLOCK) {
comp = n->norm->Bd.comp;
for (nn = n; nn && ! comp; nn = nn->parent) {
- if (MDOC_BLOCK != nn->type)
+ if (nn->type != ROFFT_BLOCK)
continue;
if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok)
comp = 1;
@@ -1143,7 +1102,7 @@ mdoc_bd_pre(MDOC_ARGS)
}
if ( ! comp)
print_paragraph(h);
- return(1);
+ return 1;
}
/* Handle the -offset argument. */
@@ -1166,7 +1125,7 @@ mdoc_bd_pre(MDOC_ARGS)
DISP_literal != n->norm->Bd.type) {
PAIR_CLASS_INIT(&tag[1], "display");
print_otag(h, TAG_DIV, 2, tag);
- return(1);
+ return 1;
}
PAIR_CLASS_INIT(&tag[1], "lit display");
@@ -1187,19 +1146,12 @@ mdoc_bd_pre(MDOC_ARGS)
*/
switch (nn->tok) {
case MDOC_Sm:
- /* FALLTHROUGH */
case MDOC_br:
- /* FALLTHROUGH */
case MDOC_sp:
- /* FALLTHROUGH */
case MDOC_Bl:
- /* FALLTHROUGH */
case MDOC_D1:
- /* FALLTHROUGH */
case MDOC_Dl:
- /* FALLTHROUGH */
case MDOC_Lp:
- /* FALLTHROUGH */
case MDOC_Pp:
continue;
default:
@@ -1217,7 +1169,7 @@ mdoc_bd_pre(MDOC_ARGS)
if (0 == sv)
h->flags &= ~HTML_LITERAL;
- return(0);
+ return 0;
}
static int
@@ -1227,7 +1179,7 @@ mdoc_pa_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "file");
print_otag(h, TAG_I, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1237,7 +1189,7 @@ mdoc_ad_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "addr");
print_otag(h, TAG_I, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1248,12 +1200,12 @@ mdoc_an_pre(MDOC_ARGS)
if (n->norm->An.auth == AUTH_split) {
h->flags &= ~HTML_NOSPLIT;
h->flags |= HTML_SPLIT;
- return(0);
+ return 0;
}
if (n->norm->An.auth == AUTH_nosplit) {
h->flags &= ~HTML_SPLIT;
h->flags |= HTML_NOSPLIT;
- return(0);
+ return 0;
}
if (h->flags & HTML_SPLIT)
@@ -1264,7 +1216,7 @@ mdoc_an_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "author");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1275,7 +1227,7 @@ mdoc_cd_pre(MDOC_ARGS)
synopsis_pre(h, n);
PAIR_CLASS_INIT(&tag, "config");
print_otag(h, TAG_B, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1285,7 +1237,7 @@ mdoc_dv_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "define");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1295,7 +1247,7 @@ mdoc_ev_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "env");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1305,20 +1257,20 @@ mdoc_er_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "errno");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
mdoc_fa_pre(MDOC_ARGS)
{
- const struct mdoc_node *nn;
+ const struct roff_node *nn;
struct htmlpair tag;
struct tag *t;
PAIR_CLASS_INIT(&tag, "farg");
if (n->parent->tok != MDOC_Fo) {
print_otag(h, TAG_I, 1, &tag);
- return(1);
+ return 1;
}
for (nn = n->child; nn; nn = nn->next) {
@@ -1336,7 +1288,7 @@ mdoc_fa_pre(MDOC_ARGS)
print_text(h, ",");
}
- return(0);
+ return 0;
}
static int
@@ -1351,14 +1303,14 @@ mdoc_fd_pre(MDOC_ARGS)
synopsis_pre(h, n);
if (NULL == (n = n->child))
- return(0);
+ return 0;
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
if (strcmp(n->string, "#include")) {
PAIR_CLASS_INIT(&tag[0], "macro");
print_otag(h, TAG_B, 1, tag);
- return(1);
+ return 1;
}
PAIR_CLASS_INIT(&tag[0], "includes");
@@ -1366,7 +1318,7 @@ mdoc_fd_pre(MDOC_ARGS)
print_text(h, n->string);
if (NULL != (n = n->next)) {
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
/*
* XXX This is broken and not easy to fix.
@@ -1400,11 +1352,11 @@ mdoc_fd_pre(MDOC_ARGS)
}
for ( ; n; n = n->next) {
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
print_text(h, n->string);
}
- return(0);
+ return 0;
}
static int
@@ -1412,17 +1364,17 @@ mdoc_vt_pre(MDOC_ARGS)
{
struct htmlpair tag;
- if (MDOC_BLOCK == n->type) {
+ if (n->type == ROFFT_BLOCK) {
synopsis_pre(h, n);
- return(1);
- } else if (MDOC_ELEM == n->type) {
+ return 1;
+ } else if (n->type == ROFFT_ELEM) {
synopsis_pre(h, n);
- } else if (MDOC_HEAD == n->type)
- return(0);
+ } else if (n->type == ROFFT_HEAD)
+ return 0;
PAIR_CLASS_INIT(&tag, "type");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1433,7 +1385,7 @@ mdoc_ft_pre(MDOC_ARGS)
synopsis_pre(h, n);
PAIR_CLASS_INIT(&tag, "ftype");
print_otag(h, TAG_I, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1523,7 +1475,7 @@ mdoc_fn_pre(MDOC_ARGS)
print_text(h, ";");
}
- return(0);
+ return 0;
}
static int
@@ -1540,14 +1492,14 @@ mdoc_sm_pre(MDOC_ARGS)
if ( ! (HTML_NONOSPACE & h->flags))
h->flags &= ~HTML_NOSPACE;
- return(0);
+ return 0;
}
static int
mdoc_skip_pre(MDOC_ARGS)
{
- return(0);
+ return 0;
}
static int
@@ -1555,7 +1507,7 @@ mdoc_pp_pre(MDOC_ARGS)
{
print_paragraph(h);
- return(0);
+ return 0;
}
static int
@@ -1584,7 +1536,7 @@ mdoc_sp_pre(MDOC_ARGS)
/* So the div isn't empty: */
print_text(h, "\\~");
- return(0);
+ return 0;
}
@@ -1594,9 +1546,9 @@ mdoc_lk_pre(MDOC_ARGS)
struct htmlpair tag[2];
if (NULL == (n = n->child))
- return(0);
+ return 0;
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
PAIR_CLASS_INIT(&tag[0], "link-ext");
PAIR_HREF_INIT(&tag[1], n->string);
@@ -1609,7 +1561,7 @@ mdoc_lk_pre(MDOC_ARGS)
for (n = n->next; n; n = n->next)
print_text(h, n->string);
- return(0);
+ return 0;
}
static int
@@ -1621,7 +1573,7 @@ mdoc_mt_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag[0], "link-mail");
for (n = n->child; n; n = n->next) {
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
bufinit(h);
bufcat(h, "mailto:");
@@ -1633,7 +1585,7 @@ mdoc_mt_pre(MDOC_ARGS)
print_tagq(h, t);
}
- return(0);
+ return 0;
}
static int
@@ -1642,33 +1594,32 @@ mdoc_fo_pre(MDOC_ARGS)
struct htmlpair tag;
struct tag *t;
- if (MDOC_BODY == n->type) {
+ if (n->type == ROFFT_BODY) {
h->flags |= HTML_NOSPACE;
print_text(h, "(");
h->flags |= HTML_NOSPACE;
- return(1);
- } else if (MDOC_BLOCK == n->type) {
+ return 1;
+ } else if (n->type == ROFFT_BLOCK) {
synopsis_pre(h, n);
- return(1);
+ return 1;
}
- /* XXX: we drop non-initial arguments as per groff. */
+ if (n->child == NULL)
+ return 0;
- assert(n->child);
assert(n->child->string);
-
PAIR_CLASS_INIT(&tag, "fname");
t = print_otag(h, TAG_B, 1, &tag);
print_text(h, n->child->string);
print_tagq(h, t);
- return(0);
+ return 0;
}
static void
mdoc_fo_post(MDOC_ARGS)
{
- if (MDOC_BODY != n->type)
+ if (n->type != ROFFT_BODY)
return;
h->flags |= HTML_NOSPACE;
print_text(h, ")");
@@ -1702,7 +1653,7 @@ mdoc_in_pre(MDOC_ARGS)
h->flags |= HTML_NOSPACE;
if (NULL != (n = n->child)) {
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
PAIR_CLASS_INIT(&tag[0], "link-includes");
@@ -1724,11 +1675,11 @@ mdoc_in_pre(MDOC_ARGS)
print_text(h, ">");
for ( ; n; n = n->next) {
- assert(MDOC_TEXT == n->type);
+ assert(n->type == ROFFT_TEXT);
print_text(h, n->string);
}
- return(0);
+ return 0;
}
static int
@@ -1738,7 +1689,7 @@ mdoc_ic_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "cmd");
print_otag(h, TAG_B, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1746,37 +1697,36 @@ mdoc_rv_pre(MDOC_ARGS)
{
struct htmlpair tag;
struct tag *t;
- int nchild;
+ struct roff_node *nch;
if (n->prev)
print_otag(h, TAG_BR, 0, NULL);
PAIR_CLASS_INIT(&tag, "fname");
- nchild = n->nchild;
- if (nchild > 0) {
+ if (n->child != NULL) {
print_text(h, "The");
- for (n = n->child; n; n = n->next) {
+ for (nch = n->child; nch != NULL; nch = nch->next) {
t = print_otag(h, TAG_B, 1, &tag);
- print_text(h, n->string);
+ print_text(h, nch->string);
print_tagq(h, t);
h->flags |= HTML_NOSPACE;
print_text(h, "()");
- if (n->next == NULL)
+ if (nch->next == NULL)
continue;
- if (nchild > 2) {
+ if (nch->prev != NULL || nch->next->next != NULL) {
h->flags |= HTML_NOSPACE;
print_text(h, ",");
}
- if (n->next->next == NULL)
+ if (nch->next->next == NULL)
print_text(h, "and");
}
- if (nchild > 1)
+ if (n->child != NULL && n->child->next != NULL)
print_text(h, "functions return");
else
print_text(h, "function returns");
@@ -1794,7 +1744,7 @@ mdoc_rv_pre(MDOC_ARGS)
print_text(h, "errno");
print_tagq(h, t);
print_text(h, "is set to indicate the error.");
- return(0);
+ return 0;
}
static int
@@ -1804,7 +1754,7 @@ mdoc_va_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "var");
print_otag(h, TAG_B, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1814,7 +1764,7 @@ mdoc_ap_pre(MDOC_ARGS)
h->flags |= HTML_NOSPACE;
print_text(h, "\\(aq");
h->flags |= HTML_NOSPACE;
- return(1);
+ return 1;
}
static int
@@ -1823,10 +1773,10 @@ mdoc_bf_pre(MDOC_ARGS)
struct htmlpair tag[2];
struct roffsu su;
- if (MDOC_HEAD == n->type)
- return(0);
- else if (MDOC_BODY != n->type)
- return(1);
+ if (n->type == ROFFT_HEAD)
+ return 0;
+ else if (n->type != ROFFT_BODY)
+ return 1;
if (FONT_Em == n->norm->Bf.font)
PAIR_CLASS_INIT(&tag[0], "emph");
@@ -1848,7 +1798,7 @@ mdoc_bf_pre(MDOC_ARGS)
bufcat_su(h, "margin-left", &su);
PAIR_STYLE_INIT(&tag[1], h);
print_otag(h, TAG_DIV, 2, tag);
- return(1);
+ return 1;
}
static int
@@ -1858,7 +1808,7 @@ mdoc_ms_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "symb");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1866,7 +1816,7 @@ mdoc_igndelim_pre(MDOC_ARGS)
{
h->flags |= HTML_IGNDELIM;
- return(1);
+ return 1;
}
static void
@@ -1882,15 +1832,15 @@ mdoc_rs_pre(MDOC_ARGS)
{
struct htmlpair tag;
- if (MDOC_BLOCK != n->type)
- return(1);
+ if (n->type != ROFFT_BLOCK)
+ return 1;
if (n->prev && SEC_SEE_ALSO == n->sec)
print_paragraph(h);
PAIR_CLASS_INIT(&tag, "ref");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1900,7 +1850,7 @@ mdoc_no_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "none");
print_otag(h, TAG_CODE, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1910,7 +1860,7 @@ mdoc_li_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "lit");
print_otag(h, TAG_CODE, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1920,7 +1870,7 @@ mdoc_sy_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "symb");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -1928,7 +1878,7 @@ mdoc_bt_pre(MDOC_ARGS)
{
print_text(h, "is currently in beta test.");
- return(0);
+ return 0;
}
static int
@@ -1936,7 +1886,7 @@ mdoc_ud_pre(MDOC_ARGS)
{
print_text(h, "currently under development.");
- return(0);
+ return 0;
}
static int
@@ -1949,7 +1899,7 @@ mdoc_lb_pre(MDOC_ARGS)
PAIR_CLASS_INIT(&tag, "lib");
print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
+ return 1;
}
static int
@@ -2011,18 +1961,17 @@ mdoc__x_pre(MDOC_ARGS)
break;
default:
abort();
- /* NOTREACHED */
}
if (MDOC__U != n->tok) {
print_otag(h, t, 1, tag);
- return(1);
+ return 1;
}
PAIR_HREF_INIT(&tag[1], n->child->string);
print_otag(h, TAG_A, 2, tag);
- return(1);
+ return 1;
}
static void
@@ -2048,27 +1997,26 @@ mdoc_bk_pre(MDOC_ARGS)
{
switch (n->type) {
- case MDOC_BLOCK:
+ case ROFFT_BLOCK:
break;
- case MDOC_HEAD:
- return(0);
- case MDOC_BODY:
- if (n->parent->args || 0 == n->prev->nchild)
+ case ROFFT_HEAD:
+ return 0;
+ case ROFFT_BODY:
+ if (n->parent->args != NULL || n->prev->child == NULL)
h->flags |= HTML_PREKEEP;
break;
default:
abort();
- /* NOTREACHED */
}
- return(1);
+ return 1;
}
static void
mdoc_bk_post(MDOC_ARGS)
{
- if (MDOC_BODY == n->type)
+ if (n->type == ROFFT_BODY)
h->flags &= ~(HTML_KEEP | HTML_PREKEEP);
}
@@ -2077,28 +2025,24 @@ mdoc_quote_pre(MDOC_ARGS)
{
struct htmlpair tag;
- if (MDOC_BODY != n->type)
- return(1);
+ if (n->type != ROFFT_BODY)
+ return 1;
switch (n->tok) {
case MDOC_Ao:
- /* FALLTHROUGH */
case MDOC_Aq:
- print_text(h, n->nchild == 1 &&
+ print_text(h, n->child != NULL && n->child->next == NULL &&
n->child->tok == MDOC_Mt ? "<" : "\\(la");
break;
case MDOC_Bro:
- /* FALLTHROUGH */
case MDOC_Brq:
print_text(h, "\\(lC");
break;
case MDOC_Bo:
- /* FALLTHROUGH */
case MDOC_Bq:
print_text(h, "\\(lB");
break;
case MDOC_Oo:
- /* FALLTHROUGH */
case MDOC_Op:
print_text(h, "\\(lB");
h->flags |= HTML_NOSPACE;
@@ -2108,20 +2052,16 @@ mdoc_quote_pre(MDOC_ARGS)
case MDOC_En:
if (NULL == n->norm->Es ||
NULL == n->norm->Es->child)
- return(1);
+ return 1;
print_text(h, n->norm->Es->child->string);
break;
case MDOC_Do:
- /* FALLTHROUGH */
case MDOC_Dq:
- /* FALLTHROUGH */
case MDOC_Qo:
- /* FALLTHROUGH */
case MDOC_Qq:
print_text(h, "\\(lq");
break;
case MDOC_Po:
- /* FALLTHROUGH */
case MDOC_Pq:
print_text(h, "(");
break;
@@ -2132,46 +2072,39 @@ mdoc_quote_pre(MDOC_ARGS)
print_otag(h, TAG_CODE, 1, &tag);
break;
case MDOC_So:
- /* FALLTHROUGH */
case MDOC_Sq:
print_text(h, "\\(oq");
break;
default:
abort();
- /* NOTREACHED */
}
h->flags |= HTML_NOSPACE;
- return(1);
+ return 1;
}
static void
mdoc_quote_post(MDOC_ARGS)
{
- if (n->type != MDOC_BODY && n->type != MDOC_ELEM)
+ if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM)
return;
h->flags |= HTML_NOSPACE;
switch (n->tok) {
case MDOC_Ao:
- /* FALLTHROUGH */
case MDOC_Aq:
- print_text(h, n->nchild == 1 &&
+ print_text(h, n->child != NULL && n->child->next == NULL &&
n->child->tok == MDOC_Mt ? ">" : "\\(ra");
break;
case MDOC_Bro:
- /* FALLTHROUGH */
case MDOC_Brq:
print_text(h, "\\(rC");
break;
case MDOC_Oo:
- /* FALLTHROUGH */
case MDOC_Op:
- /* FALLTHROUGH */
case MDOC_Bo:
- /* FALLTHROUGH */
case MDOC_Bq:
print_text(h, "\\(rB");
break;
@@ -2184,29 +2117,22 @@ mdoc_quote_post(MDOC_ARGS)
print_text(h, n->norm->Es->child->next->string);
break;
case MDOC_Qo:
- /* FALLTHROUGH */
case MDOC_Qq:
- /* FALLTHROUGH */
case MDOC_Do:
- /* FALLTHROUGH */
case MDOC_Dq:
print_text(h, "\\(rq");
break;
case MDOC_Po:
- /* FALLTHROUGH */
case MDOC_Pq:
print_text(h, ")");
break;
case MDOC_Ql:
- /* FALLTHROUGH */
case MDOC_So:
- /* FALLTHROUGH */
case MDOC_Sq:
print_text(h, "\\(cq");
break;
default:
abort();
- /* NOTREACHED */
}
}
@@ -2214,8 +2140,8 @@ static int
mdoc_eo_pre(MDOC_ARGS)
{
- if (n->type != MDOC_BODY)
- return(1);
+ if (n->type != ROFFT_BODY)
+ return 1;
if (n->end == ENDBODY_NOT &&
n->parent->head->child == NULL &&
@@ -2226,7 +2152,7 @@ mdoc_eo_pre(MDOC_ARGS)
n->parent->head->child != NULL && (n->child != NULL ||
(n->parent->tail != NULL && n->parent->tail->child != NULL)))
h->flags |= HTML_NOSPACE;
- return(1);
+ return 1;
}
static void
@@ -2234,7 +2160,7 @@ mdoc_eo_post(MDOC_ARGS)
{
int body, tail;
- if (n->type != MDOC_BODY)
+ if (n->type != ROFFT_BODY)
return;
if (n->end != ENDBODY_NOT) {
diff --git a/mdoc_macro.c b/mdoc_macro.c
index efb48d023f83..ca959589acd6 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.183 2015/02/12 12:24:33 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.206 2015/10/20 02:01:32 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -7,9 +7,9 @@
* 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
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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
@@ -26,10 +26,12 @@
#include <string.h>
#include <time.h>
-#include "mdoc.h"
#include "mandoc.h"
-#include "libmdoc.h"
+#include "roff.h"
+#include "mdoc.h"
#include "libmandoc.h"
+#include "roff_int.h"
+#include "libmdoc.h"
static void blk_full(MACRO_PROT_ARGS);
static void blk_exp_close(MACRO_PROT_ARGS);
@@ -41,18 +43,19 @@ static void in_line_argn(MACRO_PROT_ARGS);
static void in_line(MACRO_PROT_ARGS);
static void phrase_ta(MACRO_PROT_ARGS);
-static void dword(struct mdoc *, int, int, const char *,
- enum mdelim, int);
-static void append_delims(struct mdoc *, int, int *, char *);
-static enum mdoct lookup(struct mdoc *, enum mdoct,
- int, int, const char *);
+static void append_delims(struct roff_man *, int, int *, char *);
+static void dword(struct roff_man *, int, int, const char *,
+ enum mdelim, int);
+static int find_pending(struct roff_man *, int, int, int,
+ struct roff_node *);
+static int lookup(struct roff_man *, int, int, int, const char *);
static int macro_or_word(MACRO_PROT_ARGS, int);
-static int parse_rest(struct mdoc *, enum mdoct,
- int, int *, char *);
-static enum mdoct rew_alt(enum mdoct);
-static void rew_elem(struct mdoc *, enum mdoct);
-static void rew_last(struct mdoc *, const struct mdoc_node *);
-static void rew_pending(struct mdoc *, const struct mdoc_node *);
+static int parse_rest(struct roff_man *, int, int, int *, char *);
+static int rew_alt(int);
+static void rew_elem(struct roff_man *, int);
+static void rew_last(struct roff_man *, const struct roff_node *);
+static void rew_pending(struct roff_man *,
+ const struct roff_node *);
const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ap */
@@ -207,9 +210,9 @@ const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
* are errors.
*/
void
-mdoc_macroend(struct mdoc *mdoc)
+mdoc_endparse(struct roff_man *mdoc)
{
- struct mdoc_node *n;
+ struct roff_node *n;
/* Scan for open explicit scopes. */
@@ -217,7 +220,7 @@ mdoc_macroend(struct mdoc *mdoc)
mdoc->last->parent : mdoc->last;
for ( ; n; n = n->parent)
- if (n->type == MDOC_BLOCK &&
+ if (n->type == ROFFT_BLOCK &&
mdoc_macros[n->tok].flags & MDOC_EXPLICIT)
mandoc_msg(MANDOCERR_BLK_NOEND, mdoc->parse,
n->line, n->pos, mdoc_macronames[n->tok]);
@@ -225,86 +228,87 @@ mdoc_macroend(struct mdoc *mdoc)
/* Rewind to the first. */
rew_last(mdoc, mdoc->first);
+ mdoc_state_reset(mdoc);
}
/*
* Look up the macro at *p called by "from",
- * or as a line macro if from == MDOC_MAX.
+ * or as a line macro if from == TOKEN_NONE.
*/
-static enum mdoct
-lookup(struct mdoc *mdoc, enum mdoct from, int line, int ppos, const char *p)
+static int
+lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p)
{
- enum mdoct res;
+ int res;
- if (from == MDOC_MAX || mdoc_macros[from].flags & MDOC_PARSED) {
+ if (mdoc->flags & MDOC_PHRASEQF) {
+ mdoc->flags &= ~MDOC_PHRASEQF;
+ return TOKEN_NONE;
+ }
+ if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) {
res = mdoc_hash_find(p);
- if (res != MDOC_MAX) {
+ if (res != TOKEN_NONE) {
if (mdoc_macros[res].flags & MDOC_CALLABLE)
- return(res);
+ return res;
if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
mandoc_msg(MANDOCERR_MACRO_CALL,
mdoc->parse, line, ppos, p);
}
}
- return(MDOC_MAX);
+ return TOKEN_NONE;
}
/*
* Rewind up to and including a specific node.
*/
static void
-rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
+rew_last(struct roff_man *mdoc, const struct roff_node *to)
{
- struct mdoc_node *n, *np;
- assert(to);
- mdoc->next = MDOC_NEXT_SIBLING;
+ if (to->flags & MDOC_VALID)
+ return;
+
while (mdoc->last != to) {
- /*
- * Save the parent here, because we may delete the
- * mdoc->last node in the post-validation phase and reset
- * it to mdoc->last->parent, causing a step in the closing
- * out to be lost.
- */
- np = mdoc->last->parent;
- mdoc_valid_post(mdoc);
- n = mdoc->last;
- mdoc->last = np;
- assert(mdoc->last);
- mdoc->last->last = n;
+ mdoc_state(mdoc, mdoc->last);
+ mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+ mdoc->last = mdoc->last->parent;
}
- mdoc_valid_post(mdoc);
+ mdoc_state(mdoc, mdoc->last);
+ mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+ mdoc->next = ROFF_NEXT_SIBLING;
}
/*
* Rewind up to a specific block, including all blocks that broke it.
*/
static void
-rew_pending(struct mdoc *mdoc, const struct mdoc_node *n)
+rew_pending(struct roff_man *mdoc, const struct roff_node *n)
{
for (;;) {
rew_last(mdoc, n);
- switch (n->type) {
- case MDOC_HEAD:
- mdoc_body_alloc(mdoc, n->line, n->pos, n->tok);
- return;
- case MDOC_BLOCK:
- break;
- default:
- return;
- }
-
- if ( ! (n->flags & MDOC_BROKEN))
- return;
+ if (mdoc->last == n) {
+ switch (n->type) {
+ case ROFFT_HEAD:
+ roff_body_alloc(mdoc, n->line, n->pos,
+ n->tok);
+ return;
+ case ROFFT_BLOCK:
+ break;
+ default:
+ return;
+ }
+ if ( ! (n->flags & MDOC_BROKEN))
+ return;
+ } else
+ n = mdoc->last;
for (;;) {
if ((n = n->parent) == NULL)
return;
- if (n->type == MDOC_BLOCK ||
- n->type == MDOC_HEAD) {
+ if (n->type == ROFFT_BLOCK ||
+ n->type == ROFFT_HEAD) {
if (n->flags & MDOC_ENDED)
break;
else
@@ -318,67 +322,104 @@ rew_pending(struct mdoc *mdoc, const struct mdoc_node *n)
* For a block closing macro, return the corresponding opening one.
* Otherwise, return the macro itself.
*/
-static enum mdoct
-rew_alt(enum mdoct tok)
+static int
+rew_alt(int tok)
{
switch (tok) {
case MDOC_Ac:
- return(MDOC_Ao);
+ return MDOC_Ao;
case MDOC_Bc:
- return(MDOC_Bo);
+ return MDOC_Bo;
case MDOC_Brc:
- return(MDOC_Bro);
+ return MDOC_Bro;
case MDOC_Dc:
- return(MDOC_Do);
+ return MDOC_Do;
case MDOC_Ec:
- return(MDOC_Eo);
+ return MDOC_Eo;
case MDOC_Ed:
- return(MDOC_Bd);
+ return MDOC_Bd;
case MDOC_Ef:
- return(MDOC_Bf);
+ return MDOC_Bf;
case MDOC_Ek:
- return(MDOC_Bk);
+ return MDOC_Bk;
case MDOC_El:
- return(MDOC_Bl);
+ return MDOC_Bl;
case MDOC_Fc:
- return(MDOC_Fo);
+ return MDOC_Fo;
case MDOC_Oc:
- return(MDOC_Oo);
+ return MDOC_Oo;
case MDOC_Pc:
- return(MDOC_Po);
+ return MDOC_Po;
case MDOC_Qc:
- return(MDOC_Qo);
+ return MDOC_Qo;
case MDOC_Re:
- return(MDOC_Rs);
+ return MDOC_Rs;
case MDOC_Sc:
- return(MDOC_So);
+ return MDOC_So;
case MDOC_Xc:
- return(MDOC_Xo);
+ return MDOC_Xo;
default:
- return(tok);
+ return tok;
}
- /* NOTREACHED */
}
static void
-rew_elem(struct mdoc *mdoc, enum mdoct tok)
+rew_elem(struct roff_man *mdoc, int tok)
{
- struct mdoc_node *n;
+ struct roff_node *n;
n = mdoc->last;
- if (MDOC_ELEM != n->type)
+ if (n->type != ROFFT_ELEM)
n = n->parent;
- assert(MDOC_ELEM == n->type);
+ assert(n->type == ROFFT_ELEM);
assert(tok == n->tok);
rew_last(mdoc, n);
}
/*
+ * If there is an open sub-block of the target requiring
+ * explicit close-out, postpone closing out the target until
+ * the rew_pending() call closing out the sub-block.
+ */
+static int
+find_pending(struct roff_man *mdoc, int tok, int line, int ppos,
+ struct roff_node *target)
+{
+ struct roff_node *n;
+ int irc;
+
+ irc = 0;
+ for (n = mdoc->last; n != NULL && n != target; n = n->parent) {
+ if (n->flags & MDOC_ENDED) {
+ if ( ! (n->flags & MDOC_VALID))
+ n->flags |= MDOC_BROKEN;
+ continue;
+ }
+ if (n->type == ROFFT_BLOCK &&
+ mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
+ irc = 1;
+ n->flags = MDOC_BROKEN;
+ if (target->type == ROFFT_HEAD)
+ target->flags = MDOC_ENDED;
+ else if ( ! (target->flags & MDOC_ENDED)) {
+ mandoc_vmsg(MANDOCERR_BLK_NEST,
+ mdoc->parse, line, ppos,
+ "%s breaks %s", mdoc_macronames[tok],
+ mdoc_macronames[n->tok]);
+ mdoc_endbody_alloc(mdoc, line, ppos,
+ tok, target, ENDBODY_NOSPACE);
+ }
+ }
+ }
+ return irc;
+}
+
+/*
* Allocate a word and check whether it's punctuation or not.
* Punctuation consists of those tokens found in mdoc_isdelim().
*/
static void
-dword(struct mdoc *mdoc, int line, int col, const char *p,
+dword(struct roff_man *mdoc, int line, int col, const char *p,
enum mdelim d, int may_append)
{
@@ -387,13 +428,13 @@ dword(struct mdoc *mdoc, int line, int col, const char *p,
if (may_append &&
! (mdoc->flags & (MDOC_SYNOPSIS | MDOC_KEEP | MDOC_SMOFF)) &&
- d == DELIM_NONE && mdoc->last->type == MDOC_TEXT &&
+ d == DELIM_NONE && mdoc->last->type == ROFFT_TEXT &&
mdoc_isdelim(mdoc->last->string) == DELIM_NONE) {
- mdoc_word_append(mdoc, p);
+ roff_word_append(mdoc, p);
return;
}
- mdoc_word_alloc(mdoc, line, col, p);
+ roff_word_alloc(mdoc, line, col, p);
/*
* If the word consists of a bare delimiter,
@@ -412,7 +453,7 @@ dword(struct mdoc *mdoc, int line, int col, const char *p,
}
static void
-append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
+append_delims(struct roff_man *mdoc, int line, int *pos, char *buf)
{
char *p;
int la;
@@ -422,7 +463,8 @@ append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
for (;;) {
la = *pos;
- if (mdoc_args(mdoc, line, pos, buf, MDOC_MAX, &p) == ARGS_EOLN)
+ if (mdoc_args(mdoc, line, pos, buf, TOKEN_NONE, &p) ==
+ ARGS_EOLN)
break;
dword(mdoc, line, la, p, DELIM_MAX, 1);
@@ -452,26 +494,26 @@ static int
macro_or_word(MACRO_PROT_ARGS, int parsed)
{
char *p;
- enum mdoct ntok;
+ int ntok;
p = buf + ppos;
- ntok = MDOC_MAX;
+ ntok = TOKEN_NONE;
if (*p == '"')
p++;
else if (parsed && ! (mdoc->flags & MDOC_PHRASELIT))
ntok = lookup(mdoc, tok, line, ppos, p);
- if (ntok == MDOC_MAX) {
- dword(mdoc, line, ppos, p, DELIM_MAX, tok == MDOC_MAX ||
+ if (ntok == TOKEN_NONE) {
+ dword(mdoc, line, ppos, p, DELIM_MAX, tok == TOKEN_NONE ||
mdoc_macros[tok].flags & MDOC_JOIN);
- return(0);
+ return 0;
} else {
if (mdoc_macros[tok].fp == in_line_eoln)
rew_elem(mdoc, tok);
mdoc_macro(mdoc, ntok, line, ppos, pos, buf);
- if (tok == MDOC_MAX)
+ if (tok == TOKEN_NONE)
append_delims(mdoc, line, pos, buf);
- return(1);
+ return 1;
}
}
@@ -481,15 +523,16 @@ macro_or_word(MACRO_PROT_ARGS, int parsed)
static void
blk_exp_close(MACRO_PROT_ARGS)
{
- struct mdoc_node *body; /* Our own body. */
- struct mdoc_node *endbody; /* Our own end marker. */
- struct mdoc_node *itblk; /* An It block starting later. */
- struct mdoc_node *later; /* A sub-block starting later. */
- struct mdoc_node *n; /* Search back to our block. */
-
- int j, lastarg, maxargs, nl;
+ struct roff_node *body; /* Our own body. */
+ struct roff_node *endbody; /* Our own end marker. */
+ struct roff_node *itblk; /* An It block starting later. */
+ struct roff_node *later; /* A sub-block starting later. */
+ struct roff_node *n; /* Search back to our block. */
+ struct roff_node *target; /* For find_pending(). */
+
+ int j, lastarg, maxargs, nl, pending;
enum margserr ac;
- enum mdoct atok, ntok;
+ int atok, ntok;
char *p;
nl = MDOC_NEWLINE & mdoc->flags;
@@ -522,13 +565,13 @@ blk_exp_close(MACRO_PROT_ARGS)
/* Remember the start of our own body. */
- if (n->type == MDOC_BODY && atok == n->tok) {
+ if (n->type == ROFFT_BODY && atok == n->tok) {
if (n->end == ENDBODY_NOT)
body = n;
continue;
}
- if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm)
+ if (n->type != ROFFT_BLOCK || n->tok == MDOC_Nm)
continue;
if (n->tok == MDOC_It) {
@@ -575,7 +618,7 @@ blk_exp_close(MACRO_PROT_ARGS)
*/
if (maxargs)
- mdoc->next = MDOC_NEXT_CHILD;
+ mdoc->next = ROFF_NEXT_CHILD;
break;
}
@@ -596,12 +639,14 @@ blk_exp_close(MACRO_PROT_ARGS)
if (body == NULL) {
mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse,
line, ppos, mdoc_macronames[tok]);
+ if (later != NULL)
+ later->flags &= ~MDOC_BROKEN;
if (maxargs && endbody == NULL) {
/*
* Stray .Ec without previous .Eo:
* Break the output line, keep the arguments.
*/
- mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
+ roff_elem_alloc(mdoc, line, ppos, MDOC_br);
rew_elem(mdoc, MDOC_br);
}
} else if (endbody == NULL) {
@@ -623,38 +668,47 @@ blk_exp_close(MACRO_PROT_ARGS)
if (endbody != NULL)
n = endbody;
+
+ ntok = TOKEN_NONE;
for (j = 0; ; j++) {
lastarg = *pos;
- if (j == maxargs && n != NULL) {
- rew_pending(mdoc, n);
- n = NULL;
- }
+ if (j == maxargs && n != NULL)
+ rew_last(mdoc, n);
ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
break;
- ntok = ac == ARGS_QWORD ? MDOC_MAX :
+ ntok = ac == ARGS_QWORD ? TOKEN_NONE :
lookup(mdoc, tok, line, lastarg, p);
- if (ntok == MDOC_MAX) {
+ if (ntok == TOKEN_NONE) {
dword(mdoc, line, lastarg, p, DELIM_MAX,
MDOC_JOIN & mdoc_macros[tok].flags);
continue;
}
- if (n != NULL) {
- rew_pending(mdoc, n);
- n = NULL;
- }
+ if (n != NULL)
+ rew_last(mdoc, n);
mdoc->flags &= ~MDOC_NEWLINE;
mdoc_macro(mdoc, ntok, line, lastarg, pos, buf);
break;
}
- if (n != NULL)
- rew_pending(mdoc, n);
+ if (n != NULL) {
+ if (ntok != TOKEN_NONE && n->flags & MDOC_BROKEN) {
+ target = n;
+ do
+ target = target->parent;
+ while ( ! (target->flags & MDOC_ENDED));
+ pending = find_pending(mdoc, ntok, line, ppos,
+ target);
+ } else
+ pending = 0;
+ if ( ! pending)
+ rew_pending(mdoc, n);
+ }
if (nl)
append_delims(mdoc, line, pos, buf);
}
@@ -663,7 +717,7 @@ static void
in_line(MACRO_PROT_ARGS)
{
int la, scope, cnt, firstarg, mayopen, nc, nl;
- enum mdoct ntok;
+ int ntok;
enum margserr ac;
enum mdelim d;
struct mdoc_arg *arg;
@@ -678,15 +732,10 @@ in_line(MACRO_PROT_ARGS)
switch (tok) {
case MDOC_An:
- /* FALLTHROUGH */
case MDOC_Ar:
- /* FALLTHROUGH */
case MDOC_Fl:
- /* FALLTHROUGH */
case MDOC_Mt:
- /* FALLTHROUGH */
case MDOC_Nm:
- /* FALLTHROUGH */
case MDOC_Pa:
nc = 1;
break;
@@ -730,7 +779,7 @@ in_line(MACRO_PROT_ARGS)
}
ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ?
- MDOC_MAX : lookup(mdoc, tok, line, la, p);
+ TOKEN_NONE : lookup(mdoc, tok, line, la, p);
/*
* In this case, we've located a submacro and must
@@ -739,7 +788,7 @@ in_line(MACRO_PROT_ARGS)
* or raise a warning.
*/
- if (ntok != MDOC_MAX) {
+ if (ntok != TOKEN_NONE) {
if (scope)
rew_elem(mdoc, tok);
if (nc && ! cnt) {
@@ -847,10 +896,10 @@ blk_full(MACRO_PROT_ARGS)
{
int la, nl, parsed;
struct mdoc_arg *arg;
- struct mdoc_node *blk; /* Our own or a broken block. */
- struct mdoc_node *head; /* Our own head. */
- struct mdoc_node *body; /* Our own body. */
- struct mdoc_node *n;
+ struct roff_node *blk; /* Our own or a broken block. */
+ struct roff_node *head; /* Our own head. */
+ struct roff_node *body; /* Our own body. */
+ struct roff_node *n;
enum margserr ac, lac;
char *p;
@@ -873,7 +922,7 @@ blk_full(MACRO_PROT_ARGS)
n->flags |= MDOC_BROKEN;
continue;
}
- if (n->type != MDOC_BLOCK)
+ if (n->type != ROFFT_BLOCK)
continue;
if (tok == MDOC_It && n->tok == MDOC_Bl) {
@@ -890,7 +939,6 @@ blk_full(MACRO_PROT_ARGS)
if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
switch (tok) {
case MDOC_Sh:
- /* FALLTHROUGH */
case MDOC_Ss:
mandoc_vmsg(MANDOCERR_BLK_BROKEN,
mdoc->parse, line, ppos,
@@ -938,7 +986,7 @@ blk_full(MACRO_PROT_ARGS)
if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
line, ppos, "It %s", buf + *pos);
- mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
+ roff_elem_alloc(mdoc, line, ppos, MDOC_br);
rew_elem(mdoc, MDOC_br);
return;
}
@@ -972,34 +1020,47 @@ blk_full(MACRO_PROT_ARGS)
*/
if (tok == MDOC_Nd) {
- head = mdoc_head_alloc(mdoc, line, ppos, tok);
+ head = roff_head_alloc(mdoc, line, ppos, tok);
rew_last(mdoc, head);
- body = mdoc_body_alloc(mdoc, line, ppos, tok);
+ body = roff_body_alloc(mdoc, line, ppos, tok);
}
if (tok == MDOC_Bk)
mdoc->flags |= MDOC_KEEP;
- ac = ARGS_PEND;
+ ac = ARGS_EOLN;
for (;;) {
+
+ /*
+ * If we are right after a tab character,
+ * do not parse the first word for macros.
+ */
+
+ if (mdoc->flags & MDOC_PHRASEQN) {
+ mdoc->flags &= ~MDOC_PHRASEQN;
+ mdoc->flags |= MDOC_PHRASEQF;
+ }
+
la = *pos;
lac = ac;
ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
if (ac == ARGS_EOLN) {
- if (lac != ARGS_PPHRASE && lac != ARGS_PHRASE)
+ if (lac != ARGS_PHRASE ||
+ ! (mdoc->flags & MDOC_PHRASEQF))
break;
+
/*
- * This is necessary: if the last token on a
- * line is a `Ta' or tab, then we'll get
- * ARGS_EOLN, so we must be smart enough to
- * reopen our scope if the last parse was a
- * phrase or partial phrase.
+ * This line ends in a tab; start the next
+ * column now, with a leading blank.
*/
+
if (body != NULL)
rew_last(mdoc, body);
- body = mdoc_body_alloc(mdoc, line, ppos, tok);
+ body = roff_body_alloc(mdoc, line, ppos, tok);
+ roff_word_alloc(mdoc, line, ppos, "\\&");
break;
}
+
if (tok == MDOC_Bd || tok == MDOC_Bk) {
mandoc_vmsg(MANDOCERR_ARG_EXCESS,
mdoc->parse, line, la, "%s ... %s",
@@ -1016,13 +1077,11 @@ blk_full(MACRO_PROT_ARGS)
/*
* Emit leading punctuation (i.e., punctuation before
- * the MDOC_HEAD) for non-phrase types.
+ * the ROFFT_HEAD) for non-phrase types.
*/
if (head == NULL &&
- ac != ARGS_PEND &&
ac != ARGS_PHRASE &&
- ac != ARGS_PPHRASE &&
ac != ARGS_QWORD &&
mdoc_isdelim(p) == DELIM_OPEN) {
dword(mdoc, line, la, p, DELIM_OPEN, 0);
@@ -1032,11 +1091,9 @@ blk_full(MACRO_PROT_ARGS)
/* Open a head if one hasn't been opened. */
if (head == NULL)
- head = mdoc_head_alloc(mdoc, line, ppos, tok);
+ head = roff_head_alloc(mdoc, line, ppos, tok);
- if (ac == ARGS_PHRASE ||
- ac == ARGS_PEND ||
- ac == ARGS_PPHRASE) {
+ if (ac == ARGS_PHRASE) {
/*
* If we haven't opened a body yet, rewind the
@@ -1044,20 +1101,18 @@ blk_full(MACRO_PROT_ARGS)
*/
rew_last(mdoc, body == NULL ? head : body);
- body = mdoc_body_alloc(mdoc, line, ppos, tok);
+ body = roff_body_alloc(mdoc, line, ppos, tok);
- /*
- * Process phrases: set whether we're in a
- * partial-phrase (this effects line handling)
- * then call down into the phrase parser.
- */
+ /* Process to the tab or to the end of the line. */
- if (ac == ARGS_PPHRASE)
- mdoc->flags |= MDOC_PPHRASE;
- if (ac == ARGS_PEND && lac == ARGS_PPHRASE)
- mdoc->flags |= MDOC_PPHRASE;
- parse_rest(mdoc, MDOC_MAX, line, &la, buf);
- mdoc->flags &= ~MDOC_PPHRASE;
+ mdoc->flags |= MDOC_PHRASE;
+ parse_rest(mdoc, TOKEN_NONE, line, &la, buf);
+ mdoc->flags &= ~MDOC_PHRASE;
+
+ /* There may have been `Ta' macros. */
+
+ while (body->next != NULL)
+ body = body->next;
continue;
}
@@ -1068,37 +1123,18 @@ blk_full(MACRO_PROT_ARGS)
if (blk->flags & MDOC_VALID)
return;
if (head == NULL)
- head = mdoc_head_alloc(mdoc, line, ppos, tok);
+ head = roff_head_alloc(mdoc, line, ppos, tok);
if (nl && tok != MDOC_Bd && tok != MDOC_Bl && tok != MDOC_Rs)
append_delims(mdoc, line, pos, buf);
if (body != NULL)
goto out;
-
- /*
- * If there is an open (i.e., unvalidated) sub-block requiring
- * explicit close-out, postpone switching the current block from
- * head to body until the rew_pending() call closing out that
- * sub-block.
- */
- for (n = mdoc->last; n && n != head; n = n->parent) {
- if (n->flags & MDOC_ENDED) {
- if ( ! (n->flags & MDOC_VALID))
- n->flags |= MDOC_BROKEN;
- continue;
- }
- if (n->type == MDOC_BLOCK &&
- mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
- n->flags = MDOC_BROKEN;
- head->flags = MDOC_ENDED;
- }
- }
- if (head->flags & MDOC_ENDED)
+ if (find_pending(mdoc, tok, line, ppos, head))
return;
/* Close out scopes to remain in a consistent state. */
rew_last(mdoc, head);
- body = mdoc_body_alloc(mdoc, line, ppos, tok);
+ body = roff_body_alloc(mdoc, line, ppos, tok);
out:
if (mdoc->flags & MDOC_FREECOL) {
rew_last(mdoc, body);
@@ -1113,9 +1149,9 @@ blk_part_imp(MACRO_PROT_ARGS)
int la, nl;
enum margserr ac;
char *p;
- struct mdoc_node *blk; /* saved block context */
- struct mdoc_node *body; /* saved body context */
- struct mdoc_node *n;
+ struct roff_node *blk; /* saved block context */
+ struct roff_node *body; /* saved body context */
+ struct roff_node *n;
nl = MDOC_NEWLINE & mdoc->flags;
@@ -1129,7 +1165,7 @@ blk_part_imp(MACRO_PROT_ARGS)
*/
blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL);
- rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok));
+ rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok));
/*
* Open the body scope "on-demand", that is, after we've
@@ -1150,42 +1186,15 @@ blk_part_imp(MACRO_PROT_ARGS)
}
if (body == NULL)
- body = mdoc_body_alloc(mdoc, line, ppos, tok);
+ body = roff_body_alloc(mdoc, line, ppos, tok);
if (macro_or_word(mdoc, tok, line, la, pos, buf, 1))
break;
}
if (body == NULL)
- body = mdoc_body_alloc(mdoc, line, ppos, tok);
+ body = roff_body_alloc(mdoc, line, ppos, tok);
- /*
- * If there is an open sub-block requiring explicit close-out,
- * postpone closing out the current block until the
- * rew_pending() call closing out the sub-block.
- */
-
- for (n = mdoc->last; n && n != body && n != blk->parent;
- n = n->parent) {
- if (n->flags & MDOC_ENDED) {
- if ( ! (n->flags & MDOC_VALID))
- n->flags |= MDOC_BROKEN;
- continue;
- }
- if (n->type == MDOC_BLOCK &&
- mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
- n->flags |= MDOC_BROKEN;
- if ( ! (body->flags & MDOC_ENDED)) {
- mandoc_vmsg(MANDOCERR_BLK_NEST,
- mdoc->parse, line, ppos,
- "%s breaks %s", mdoc_macronames[tok],
- mdoc_macronames[n->tok]);
- mdoc_endbody_alloc(mdoc, line, ppos,
- tok, body, ENDBODY_NOSPACE);
- }
- }
- }
- assert(n == body);
- if (body->flags & MDOC_ENDED)
+ if (find_pending(mdoc, tok, line, ppos, body))
return;
rew_last(mdoc, body);
@@ -1206,7 +1215,7 @@ blk_part_exp(MACRO_PROT_ARGS)
{
int la, nl;
enum margserr ac;
- struct mdoc_node *head; /* keep track of head */
+ struct roff_node *head; /* keep track of head */
char *p;
nl = MDOC_NEWLINE & mdoc->flags;
@@ -1217,7 +1226,7 @@ blk_part_exp(MACRO_PROT_ARGS)
* case of `Eo'); and a body that may be empty.
*/
- mdoc_block_alloc(mdoc, line, ppos, tok, NULL);
+ roff_block_alloc(mdoc, line, ppos, tok);
head = NULL;
for (;;) {
la = *pos;
@@ -1234,11 +1243,11 @@ blk_part_exp(MACRO_PROT_ARGS)
}
if (head == NULL) {
- head = mdoc_head_alloc(mdoc, line, ppos, tok);
+ head = roff_head_alloc(mdoc, line, ppos, tok);
if (tok == MDOC_Eo) /* Not parsed. */
dword(mdoc, line, la, p, DELIM_MAX, 0);
rew_last(mdoc, head);
- mdoc_body_alloc(mdoc, line, ppos, tok);
+ roff_body_alloc(mdoc, line, ppos, tok);
if (tok == MDOC_Eo)
continue;
}
@@ -1250,8 +1259,8 @@ blk_part_exp(MACRO_PROT_ARGS)
/* Clean-up to leave in a consistent state. */
if (head == NULL) {
- rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok));
- mdoc_body_alloc(mdoc, line, ppos, tok);
+ rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok));
+ roff_body_alloc(mdoc, line, ppos, tok);
}
if (nl)
append_delims(mdoc, line, pos, buf);
@@ -1263,7 +1272,7 @@ in_line_argn(MACRO_PROT_ARGS)
struct mdoc_arg *arg;
char *p;
enum margserr ac;
- enum mdoct ntok;
+ int ntok;
int state; /* arg#; -1: not yet open; -2: closed */
int la, maxargs, nl;
@@ -1279,16 +1288,12 @@ in_line_argn(MACRO_PROT_ARGS)
switch (tok) {
case MDOC_Ap:
- /* FALLTHROUGH */
case MDOC_Ns:
- /* FALLTHROUGH */
case MDOC_Ux:
maxargs = 0;
break;
case MDOC_Bx:
- /* FALLTHROUGH */
case MDOC_Es:
- /* FALLTHROUGH */
case MDOC_Xr:
maxargs = 2;
break;
@@ -1332,9 +1337,9 @@ in_line_argn(MACRO_PROT_ARGS)
}
ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && state == 0)) ?
- MDOC_MAX : lookup(mdoc, tok, line, la, p);
+ TOKEN_NONE : lookup(mdoc, tok, line, la, p);
- if (ntok != MDOC_MAX) {
+ if (ntok != TOKEN_NONE) {
if (state >= 0) {
rew_elem(mdoc, tok);
state = -2;
@@ -1377,16 +1382,16 @@ in_line_argn(MACRO_PROT_ARGS)
static void
in_line_eoln(MACRO_PROT_ARGS)
{
- struct mdoc_node *n;
+ struct roff_node *n;
struct mdoc_arg *arg;
if ((tok == MDOC_Pp || tok == MDOC_Lp) &&
! (mdoc->flags & MDOC_SYNOPSIS)) {
n = mdoc->last;
- if (mdoc->next == MDOC_NEXT_SIBLING)
+ if (mdoc->next == ROFF_NEXT_SIBLING)
n = n->parent;
if (n->tok == MDOC_Nm)
- rew_last(mdoc, mdoc->last->parent);
+ rew_last(mdoc, n->parent);
}
if (buf[*pos] == '\0' &&
@@ -1409,16 +1414,16 @@ in_line_eoln(MACRO_PROT_ARGS)
* or until the next macro, call that macro, and return 1.
*/
static int
-parse_rest(struct mdoc *mdoc, enum mdoct tok, int line, int *pos, char *buf)
+parse_rest(struct roff_man *mdoc, int tok, int line, int *pos, char *buf)
{
int la;
for (;;) {
la = *pos;
if (mdoc_args(mdoc, line, pos, buf, tok, NULL) == ARGS_EOLN)
- return(0);
+ return 0;
if (macro_or_word(mdoc, tok, line, la, pos, buf, 1))
- return(1);
+ return 1;
}
}
@@ -1444,7 +1449,7 @@ ctx_synopsis(MACRO_PROT_ARGS)
static void
phrase_ta(MACRO_PROT_ARGS)
{
- struct mdoc_node *body, *n;
+ struct roff_node *body, *n;
/* Make sure we are in a column list or ignore this macro. */
@@ -1452,7 +1457,7 @@ phrase_ta(MACRO_PROT_ARGS)
for (n = mdoc->last; n != NULL; n = n->parent) {
if (n->flags & MDOC_ENDED)
continue;
- if (n->tok == MDOC_It && n->type == MDOC_BODY)
+ if (n->tok == MDOC_It && n->type == ROFFT_BODY)
body = n;
if (n->tok == MDOC_Bl)
break;
@@ -1467,6 +1472,6 @@ phrase_ta(MACRO_PROT_ARGS)
/* Advance to the next column. */
rew_last(mdoc, body);
- mdoc_body_alloc(mdoc, line, ppos, MDOC_It);
- parse_rest(mdoc, MDOC_MAX, line, pos, buf);
+ roff_body_alloc(mdoc, line, ppos, MDOC_It);
+ parse_rest(mdoc, TOKEN_NONE, line, pos, buf);
}
diff --git a/mdoc_man.c b/mdoc_man.c
index 9c086a576c4e..ab245313492a 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_man.c,v 1.88 2015/02/17 20:37:17 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.96 2016/01/08 17:48:09 schwarze Exp $ */
/*
- * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2016 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
@@ -22,14 +22,15 @@
#include <stdio.h>
#include <string.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
-#include "out.h"
-#include "man.h"
+#include "mandoc.h"
+#include "roff.h"
#include "mdoc.h"
+#include "man.h"
+#include "out.h"
#include "main.h"
-#define DECL_ARGS const struct mdoc_meta *meta, struct mdoc_node *n
+#define DECL_ARGS const struct roff_meta *meta, struct roff_node *n
struct manact {
int (*cond)(DECL_ARGS); /* DON'T run actions */
@@ -107,7 +108,7 @@ static int pre_sm(DECL_ARGS);
static int pre_sp(DECL_ARGS);
static int pre_sect(DECL_ARGS);
static int pre_sy(DECL_ARGS);
-static void pre_syn(const struct mdoc_node *);
+static void pre_syn(const struct roff_node *);
static int pre_vt(DECL_ARGS);
static int pre_ux(DECL_ARGS);
static int pre_xr(DECL_ARGS);
@@ -116,7 +117,7 @@ static void print_line(const char *, int);
static void print_block(const char *, int);
static void print_offs(const char *, int);
static void print_width(const struct mdoc_bl *,
- const struct mdoc_node *);
+ const struct roff_node *);
static void print_count(int *);
static void print_node(DECL_ARGS);
@@ -467,7 +468,7 @@ print_offs(const char *v, int keywords)
* Set up the indentation for a list item; used from pre_it().
*/
static void
-print_width(const struct mdoc_bl *bl, const struct mdoc_node *child)
+print_width(const struct mdoc_bl *bl, const struct roff_node *child)
{
char buf[24];
struct roffsu su;
@@ -492,7 +493,7 @@ print_width(const struct mdoc_bl *bl, const struct mdoc_node *child)
/* XXX Rough estimation, might have multiple parts. */
if (bl->type == LIST_enum)
chsz = (bl->count > 8) + 1;
- else if (child != NULL && child->type == MDOC_TEXT)
+ else if (child != NULL && child->type == ROFFT_TEXT)
chsz = strlen(child->string);
else
chsz = 0;
@@ -531,7 +532,7 @@ print_count(int *count)
}
void
-man_man(void *arg, const struct man *man)
+man_man(void *arg, const struct roff_man *man)
{
/*
@@ -544,18 +545,14 @@ man_man(void *arg, const struct man *man)
}
void
-man_mdoc(void *arg, const struct mdoc *mdoc)
+man_mdoc(void *arg, const struct roff_man *mdoc)
{
- const struct mdoc_meta *meta;
- struct mdoc_node *n;
-
- meta = mdoc_meta(mdoc);
- n = mdoc_node(mdoc)->child;
+ struct roff_node *n;
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
- meta->title,
- (meta->msec == NULL ? "" : meta->msec),
- meta->date, meta->os, meta->vol);
+ mdoc->meta.title,
+ (mdoc->meta.msec == NULL ? "" : mdoc->meta.msec),
+ mdoc->meta.date, mdoc->meta.os, mdoc->meta.vol);
/* Disable hyphenation and if nroff, disable justification. */
printf(".nh\n.if n .ad l");
@@ -566,10 +563,8 @@ man_mdoc(void *arg, const struct mdoc *mdoc)
fontqueue.head = fontqueue.tail = mandoc_malloc(8);
*fontqueue.tail = 'R';
}
- while (n != NULL) {
- print_node(meta, n);
- n = n->next;
- }
+ for (n = mdoc->first->child; n != NULL; n = n->next)
+ print_node(&mdoc->meta, n);
putchar('\n');
}
@@ -577,7 +572,7 @@ static void
print_node(DECL_ARGS)
{
const struct manact *act;
- struct mdoc_node *sub;
+ struct roff_node *sub;
int cond, do_sub;
/*
@@ -592,7 +587,7 @@ print_node(DECL_ARGS)
do_sub = 1;
n->flags &= ~MDOC_ENDED;
- if (MDOC_TEXT == n->type) {
+ if (n->type == ROFFT_TEXT) {
/*
* Make sure that we don't happen to start with a
* control character at the start of a line.
@@ -615,7 +610,8 @@ print_node(DECL_ARGS)
*/
act = manacts + n->tok;
cond = act->cond == NULL || (*act->cond)(meta, n);
- if (cond && act->pre && (n->end == ENDBODY_NOT || n->nchild))
+ if (cond && act->pre != NULL &&
+ (n->end == ENDBODY_NOT || n->child != NULL))
do_sub = (*act->pre)(meta, n);
}
@@ -648,14 +644,14 @@ static int
cond_head(DECL_ARGS)
{
- return(MDOC_HEAD == n->type);
+ return n->type == ROFFT_HEAD;
}
static int
cond_body(DECL_ARGS)
{
- return(MDOC_BODY == n->type);
+ return n->type == ROFFT_BODY;
}
static int
@@ -665,10 +661,10 @@ pre_enc(DECL_ARGS)
prefix = manacts[n->tok].prefix;
if (NULL == prefix)
- return(1);
+ return 1;
print_word(prefix);
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
}
static void
@@ -686,37 +682,36 @@ post_enc(DECL_ARGS)
static int
pre_ex(DECL_ARGS)
{
- int nchild;
+ struct roff_node *nch;
outflags |= MMAN_br | MMAN_nl;
print_word("The");
- nchild = n->nchild;
- for (n = n->child; n; n = n->next) {
+ for (nch = n->child; nch != NULL; nch = nch->next) {
font_push('B');
- print_word(n->string);
+ print_word(nch->string);
font_pop();
- if (n->next == NULL)
+ if (nch->next == NULL)
continue;
- if (nchild > 2) {
+ if (nch->prev != NULL || nch->next->next != NULL) {
outflags &= ~MMAN_spc;
print_word(",");
}
- if (n->next->next == NULL)
+ if (nch->next->next == NULL)
print_word("and");
}
- if (nchild > 1)
+ if (n->child != NULL && n->child->next != NULL)
print_word("utilities exit\\~0");
else
print_word("utility exits\\~0");
print_word("on success, and\\~>0 if an error occurs.");
outflags |= MMAN_nl;
- return(0);
+ return 0;
}
static void
@@ -754,7 +749,7 @@ pre__t(DECL_ARGS)
outflags &= ~MMAN_spc;
} else
font_push('I');
- return(1);
+ return 1;
}
static void
@@ -778,14 +773,14 @@ static int
pre_sect(DECL_ARGS)
{
- if (MDOC_HEAD == n->type) {
+ if (n->type == ROFFT_HEAD) {
outflags |= MMAN_sp;
print_block(manacts[n->tok].prefix, 0);
print_word("");
putchar('\"');
outflags &= ~MMAN_spc;
}
- return(1);
+ return 1;
}
/*
@@ -795,7 +790,7 @@ static void
post_sect(DECL_ARGS)
{
- if (MDOC_HEAD != n->type)
+ if (n->type != ROFFT_HEAD)
return;
outflags &= ~MMAN_spc;
print_word("");
@@ -807,7 +802,7 @@ post_sect(DECL_ARGS)
/* See mdoc_term.c, synopsis_pre() for comments. */
static void
-pre_syn(const struct mdoc_node *n)
+pre_syn(const struct roff_node *n)
{
if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
@@ -823,13 +818,9 @@ pre_syn(const struct mdoc_node *n)
switch (n->prev->tok) {
case MDOC_Fd:
- /* FALLTHROUGH */
case MDOC_Fn:
- /* FALLTHROUGH */
case MDOC_Fo:
- /* FALLTHROUGH */
case MDOC_In:
- /* FALLTHROUGH */
case MDOC_Vt:
outflags |= MMAN_sp;
break;
@@ -853,18 +844,18 @@ pre_an(DECL_ARGS)
case AUTH_split:
outflags &= ~MMAN_An_nosplit;
outflags |= MMAN_An_split;
- return(0);
+ return 0;
case AUTH_nosplit:
outflags &= ~MMAN_An_split;
outflags |= MMAN_An_nosplit;
- return(0);
+ return 0;
default:
if (MMAN_An_split & outflags)
outflags |= MMAN_br;
else if (SEC_AUTHORS == n->sec &&
! (MMAN_An_nosplit & outflags))
outflags |= MMAN_An_split;
- return(1);
+ return 1;
}
}
@@ -875,17 +866,17 @@ pre_ap(DECL_ARGS)
outflags &= ~MMAN_spc;
print_word("'");
outflags &= ~MMAN_spc;
- return(0);
+ return 0;
}
static int
pre_aq(DECL_ARGS)
{
- print_word(n->nchild == 1 &&
+ print_word(n->child != NULL && n->child->next == NULL &&
n->child->tok == MDOC_Mt ? "<" : "\\(la");
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
}
static void
@@ -893,7 +884,7 @@ post_aq(DECL_ARGS)
{
outflags &= ~(MMAN_spc | MMAN_nl);
- print_word(n->nchild == 1 &&
+ print_word(n->child != NULL && n->child->next == NULL &&
n->child->tok == MDOC_Mt ? ">" : "\\(ra");
}
@@ -909,7 +900,7 @@ pre_bd(DECL_ARGS)
if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
outflags |= MMAN_sp;
print_offs(n->norm->Bd.offs, 1);
- return(1);
+ return 1;
}
static void
@@ -932,12 +923,12 @@ pre_bf(DECL_ARGS)
{
switch (n->type) {
- case MDOC_BLOCK:
- return(1);
- case MDOC_BODY:
+ case ROFFT_BLOCK:
+ return 1;
+ case ROFFT_BODY:
break;
default:
- return(0);
+ return 0;
}
switch (n->norm->Bf.font) {
case FONT_Em:
@@ -950,14 +941,14 @@ pre_bf(DECL_ARGS)
font_push('R');
break;
}
- return(1);
+ return 1;
}
static void
post_bf(DECL_ARGS)
{
- if (MDOC_BODY == n->type)
+ if (n->type == ROFFT_BODY)
font_pop();
}
@@ -966,13 +957,13 @@ pre_bk(DECL_ARGS)
{
switch (n->type) {
- case MDOC_BLOCK:
- return(1);
- case MDOC_BODY:
+ case ROFFT_BLOCK:
+ return 1;
+ case ROFFT_BODY:
outflags |= MMAN_Bk;
- return(1);
+ return 1;
default:
- return(0);
+ return 0;
}
}
@@ -980,7 +971,7 @@ static void
post_bk(DECL_ARGS)
{
- if (MDOC_BODY == n->type)
+ if (n->type == ROFFT_BODY)
outflags &= ~MMAN_Bk;
}
@@ -1002,21 +993,21 @@ pre_bl(DECL_ARGS)
switch (n->norm->Bl.type) {
case LIST_enum:
n->norm->Bl.count = 0;
- return(1);
+ return 1;
case LIST_column:
break;
default:
- return(1);
+ return 1;
}
- if (n->nchild) {
+ if (n->child != NULL) {
print_line(".TS", MMAN_nl);
for (icol = 0; icol < n->norm->Bl.ncols; icol++)
print_word("l");
print_word(".");
}
outflags |= MMAN_nl;
- return(1);
+ return 1;
}
static void
@@ -1025,7 +1016,7 @@ post_bl(DECL_ARGS)
switch (n->norm->Bl.type) {
case LIST_column:
- if (n->nchild)
+ if (n->child != NULL)
print_line(".TE", 0);
break;
case LIST_enum:
@@ -1056,7 +1047,7 @@ pre_br(DECL_ARGS)
{
outflags |= MMAN_br;
- return(0);
+ return 0;
}
static int
@@ -1071,12 +1062,12 @@ pre_bx(DECL_ARGS)
}
print_word("BSD");
if (NULL == n)
- return(0);
+ return 0;
outflags &= ~MMAN_spc;
print_word("-");
outflags &= ~MMAN_spc;
print_word(n->string);
- return(0);
+ return 0;
}
static int
@@ -1084,7 +1075,7 @@ pre_dl(DECL_ARGS)
{
print_offs("6n", 0);
- return(1);
+ return 1;
}
static void
@@ -1103,7 +1094,7 @@ pre_em(DECL_ARGS)
{
font_push('I');
- return(1);
+ return 1;
}
static int
@@ -1112,11 +1103,11 @@ pre_en(DECL_ARGS)
if (NULL == n->norm->Es ||
NULL == n->norm->Es->child)
- return(1);
+ return 1;
print_word(n->norm->Es->child->string);
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
}
static void
@@ -1146,7 +1137,7 @@ pre_eo(DECL_ARGS)
n->parent->head->child != NULL && (n->child != NULL ||
(n->parent->tail != NULL && n->parent->tail->child != NULL)))
outflags &= ~(MMAN_spc | MMAN_nl);
- return(1);
+ return 1;
}
static void
@@ -1189,7 +1180,7 @@ pre_fa(DECL_ARGS)
if (NULL != (n = n->next))
print_word(",");
}
- return(0);
+ return 0;
}
static void
@@ -1206,7 +1197,7 @@ pre_fd(DECL_ARGS)
pre_syn(n);
font_push('B');
- return(1);
+ return 1;
}
static void
@@ -1223,9 +1214,9 @@ pre_fl(DECL_ARGS)
font_push('B');
print_word("\\-");
- if (n->nchild)
+ if (n->child != NULL)
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
}
static void
@@ -1233,9 +1224,9 @@ post_fl(DECL_ARGS)
{
font_pop();
- if ( ! (n->nchild ||
+ if (!(n->child != NULL ||
n->next == NULL ||
- n->next->type == MDOC_TEXT ||
+ n->next->type == ROFFT_TEXT ||
n->next->flags & MDOC_LINE))
outflags &= ~MMAN_spc;
}
@@ -1248,7 +1239,7 @@ pre_fn(DECL_ARGS)
n = n->child;
if (NULL == n)
- return(0);
+ return 0;
if (MDOC_SYNPRETTY & n->flags)
print_block(".HP 4n", MMAN_nl);
@@ -1263,7 +1254,7 @@ pre_fn(DECL_ARGS)
n = n->next;
if (NULL != n)
pre_fa(meta, n);
- return(0);
+ return 0;
}
static void
@@ -1282,17 +1273,17 @@ pre_fo(DECL_ARGS)
{
switch (n->type) {
- case MDOC_BLOCK:
+ case ROFFT_BLOCK:
pre_syn(n);
break;
- case MDOC_HEAD:
+ case ROFFT_HEAD:
if (n->child == NULL)
- return(0);
+ return 0;
if (MDOC_SYNPRETTY & n->flags)
print_block(".HP 4n", MMAN_nl);
font_push('B');
break;
- case MDOC_BODY:
+ case ROFFT_BODY:
outflags &= ~(MMAN_spc | MMAN_nl);
print_word("(");
outflags &= ~MMAN_spc;
@@ -1300,7 +1291,7 @@ pre_fo(DECL_ARGS)
default:
break;
}
- return(1);
+ return 1;
}
static void
@@ -1308,11 +1299,11 @@ post_fo(DECL_ARGS)
{
switch (n->type) {
- case MDOC_HEAD:
+ case ROFFT_HEAD:
if (n->child != NULL)
font_pop();
break;
- case MDOC_BODY:
+ case ROFFT_BODY:
post_fn(meta, n);
break;
default:
@@ -1326,7 +1317,7 @@ pre_ft(DECL_ARGS)
pre_syn(n);
font_push('I');
- return(1);
+ return 1;
}
static int
@@ -1343,7 +1334,7 @@ pre_in(DECL_ARGS)
outflags &= ~MMAN_spc;
font_push('I');
}
- return(1);
+ return 1;
}
static void
@@ -1365,10 +1356,10 @@ post_in(DECL_ARGS)
static int
pre_it(DECL_ARGS)
{
- const struct mdoc_node *bln;
+ const struct roff_node *bln;
switch (n->type) {
- case MDOC_HEAD:
+ case ROFFT_HEAD:
outflags |= MMAN_PP | MMAN_nl;
bln = n->parent->parent;
if (0 == bln->norm->Bl.comp ||
@@ -1378,22 +1369,18 @@ pre_it(DECL_ARGS)
outflags &= ~MMAN_br;
switch (bln->norm->Bl.type) {
case LIST_item:
- return(0);
+ return 0;
case LIST_inset:
- /* FALLTHROUGH */
case LIST_diag:
- /* FALLTHROUGH */
case LIST_ohang:
if (bln->norm->Bl.type == LIST_diag)
print_line(".B \"", 0);
else
print_line(".R \"", 0);
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
case LIST_bullet:
- /* FALLTHROUGH */
case LIST_dash:
- /* FALLTHROUGH */
case LIST_hyphen:
print_width(&bln->norm->Bl, NULL);
TPremain = 0;
@@ -1405,31 +1392,31 @@ pre_it(DECL_ARGS)
print_word("-");
font_pop();
outflags |= MMAN_nl;
- return(0);
+ return 0;
case LIST_enum:
print_width(&bln->norm->Bl, NULL);
TPremain = 0;
outflags |= MMAN_nl;
print_count(&bln->norm->Bl.count);
outflags |= MMAN_nl;
- return(0);
+ return 0;
case LIST_hang:
print_width(&bln->norm->Bl, n->child);
TPremain = 0;
outflags |= MMAN_nl;
- return(1);
+ return 1;
case LIST_tag:
print_width(&bln->norm->Bl, n->child);
putchar('\n');
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
default:
- return(1);
+ return 1;
}
default:
break;
}
- return(1);
+ return 1;
}
/*
@@ -1462,12 +1449,12 @@ mid_it(void)
static void
post_it(DECL_ARGS)
{
- const struct mdoc_node *bln;
+ const struct roff_node *bln;
bln = n->parent->parent;
switch (n->type) {
- case MDOC_HEAD:
+ case ROFFT_HEAD:
switch (bln->norm->Bl.type) {
case LIST_diag:
outflags &= ~MMAN_spc;
@@ -1480,18 +1467,13 @@ post_it(DECL_ARGS)
break;
}
break;
- case MDOC_BODY:
+ case ROFFT_BODY:
switch (bln->norm->Bl.type) {
case LIST_bullet:
- /* FALLTHROUGH */
case LIST_dash:
- /* FALLTHROUGH */
case LIST_hyphen:
- /* FALLTHROUGH */
case LIST_enum:
- /* FALLTHROUGH */
case LIST_hang:
- /* FALLTHROUGH */
case LIST_tag:
assert(Bl_stack_len);
Bl_stack[--Bl_stack_len] = 0;
@@ -1532,10 +1514,10 @@ post_lb(DECL_ARGS)
static int
pre_lk(DECL_ARGS)
{
- const struct mdoc_node *link, *descr;
+ const struct roff_node *link, *descr;
if (NULL == (link = n->child))
- return(0);
+ return 0;
if (NULL != (descr = link->next)) {
font_push('I');
@@ -1550,7 +1532,7 @@ pre_lk(DECL_ARGS)
font_push('B');
print_word(link->string);
font_pop();
- return(0);
+ return 0;
}
static int
@@ -1558,7 +1540,7 @@ pre_ll(DECL_ARGS)
{
print_line(".ll", 0);
- return(1);
+ return 1;
}
static int
@@ -1566,7 +1548,7 @@ pre_li(DECL_ARGS)
{
font_push('R');
- return(1);
+ return 1;
}
static int
@@ -1574,16 +1556,16 @@ pre_nm(DECL_ARGS)
{
char *name;
- if (MDOC_BLOCK == n->type) {
+ if (n->type == ROFFT_BLOCK) {
outflags |= MMAN_Bk;
pre_syn(n);
}
- if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
- return(1);
+ if (n->type != ROFFT_ELEM && n->type != ROFFT_HEAD)
+ return 1;
name = n->child ? n->child->string : meta->name;
if (NULL == name)
- return(0);
- if (MDOC_HEAD == n->type) {
+ return 0;
+ if (n->type == ROFFT_HEAD) {
if (NULL == n->parent->prev)
outflags |= MMAN_sp;
print_block(".HP", 0);
@@ -1593,7 +1575,7 @@ pre_nm(DECL_ARGS)
font_push('B');
if (NULL == n->child)
print_word(meta->name);
- return(1);
+ return 1;
}
static void
@@ -1601,12 +1583,11 @@ post_nm(DECL_ARGS)
{
switch (n->type) {
- case MDOC_BLOCK:
+ case ROFFT_BLOCK:
outflags &= ~MMAN_Bk;
break;
- case MDOC_HEAD:
- /* FALLTHROUGH */
- case MDOC_ELEM:
+ case ROFFT_HEAD:
+ case ROFFT_ELEM:
if (n->child != NULL || meta->name != NULL)
font_pop();
break;
@@ -1620,7 +1601,7 @@ pre_no(DECL_ARGS)
{
outflags |= MMAN_spc_force;
- return(1);
+ return 1;
}
static int
@@ -1628,7 +1609,7 @@ pre_ns(DECL_ARGS)
{
outflags &= ~MMAN_spc;
- return(0);
+ return 0;
}
static void
@@ -1647,7 +1628,7 @@ pre_pp(DECL_ARGS)
outflags |= MMAN_PP;
outflags |= MMAN_sp | MMAN_nl;
outflags &= ~MMAN_br;
- return(0);
+ return 0;
}
static int
@@ -1658,40 +1639,39 @@ pre_rs(DECL_ARGS)
outflags |= MMAN_PP | MMAN_sp | MMAN_nl;
outflags &= ~MMAN_br;
}
- return(1);
+ return 1;
}
static int
pre_rv(DECL_ARGS)
{
- int nchild;
+ struct roff_node *nch;
outflags |= MMAN_br | MMAN_nl;
- nchild = n->nchild;
- if (nchild > 0) {
+ if (n->child != NULL) {
print_word("The");
- for (n = n->child; n; n = n->next) {
+ for (nch = n->child; nch != NULL; nch = nch->next) {
font_push('B');
- print_word(n->string);
+ print_word(nch->string);
font_pop();
outflags &= ~MMAN_spc;
print_word("()");
- if (n->next == NULL)
+ if (nch->next == NULL)
continue;
- if (nchild > 2) {
+ if (nch->prev != NULL || nch->next->next != NULL) {
outflags &= ~MMAN_spc;
print_word(",");
}
- if (n->next->next == NULL)
+ if (nch->next->next == NULL)
print_word("and");
}
- if (nchild > 1)
+ if (n->child != NULL && n->child->next != NULL)
print_word("functions return");
else
print_word("function returns");
@@ -1710,14 +1690,14 @@ pre_rv(DECL_ARGS)
print_word("is set to indicate the error.");
outflags |= MMAN_nl;
- return(0);
+ return 0;
}
static int
pre_skip(DECL_ARGS)
{
- return(0);
+ return 0;
}
static int
@@ -1734,7 +1714,7 @@ pre_sm(DECL_ARGS)
if (MMAN_Sm & outflags)
outflags |= MMAN_spc;
- return(0);
+ return 0;
}
static int
@@ -1746,7 +1726,7 @@ pre_sp(DECL_ARGS)
print_line(".PP", 0);
} else
print_line(".sp", 0);
- return(1);
+ return 1;
}
static void
@@ -1761,7 +1741,7 @@ pre_sy(DECL_ARGS)
{
font_push('B');
- return(1);
+ return 1;
}
static int
@@ -1770,24 +1750,24 @@ pre_vt(DECL_ARGS)
if (MDOC_SYNPRETTY & n->flags) {
switch (n->type) {
- case MDOC_BLOCK:
+ case ROFFT_BLOCK:
pre_syn(n);
- return(1);
- case MDOC_BODY:
+ return 1;
+ case ROFFT_BODY:
break;
default:
- return(0);
+ return 0;
}
}
font_push('I');
- return(1);
+ return 1;
}
static void
post_vt(DECL_ARGS)
{
- if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type)
+ if (n->flags & MDOC_SYNPRETTY && n->type != ROFFT_BODY)
return;
font_pop();
}
@@ -1798,16 +1778,16 @@ pre_xr(DECL_ARGS)
n = n->child;
if (NULL == n)
- return(0);
+ return 0;
print_node(meta, n);
n = n->next;
if (NULL == n)
- return(0);
+ return 0;
outflags &= ~MMAN_spc;
print_word("(");
print_node(meta, n);
print_word(")");
- return(0);
+ return 0;
}
static int
@@ -1816,9 +1796,9 @@ pre_ux(DECL_ARGS)
print_word(manacts[n->tok].prefix);
if (NULL == n->child)
- return(0);
+ return 0;
outflags &= ~MMAN_spc;
print_word("\\ ");
outflags &= ~MMAN_spc;
- return(1);
+ return 1;
}
diff --git a/mdoc_state.c b/mdoc_state.c
new file mode 100644
index 000000000000..cbd7376309e8
--- /dev/null
+++ b/mdoc_state.c
@@ -0,0 +1,292 @@
+/* $Id: mdoc_state.c,v 1.3 2015/10/30 18:53:54 schwarze Exp $ */
+/*
+ * Copyright (c) 2014, 2015 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 <stdlib.h>
+#include <string.h>
+
+#include "mandoc.h"
+#include "roff.h"
+#include "mdoc.h"
+#include "libmandoc.h"
+#include "libmdoc.h"
+
+#define STATE_ARGS struct roff_man *mdoc, struct roff_node *n
+
+typedef void (*state_handler)(STATE_ARGS);
+
+static void state_bd(STATE_ARGS);
+static void state_bl(STATE_ARGS);
+static void state_dl(STATE_ARGS);
+static void state_sh(STATE_ARGS);
+static void state_sm(STATE_ARGS);
+
+static const state_handler state_handlers[MDOC_MAX] = {
+ NULL, /* Ap */
+ NULL, /* Dd */
+ NULL, /* Dt */
+ NULL, /* Os */
+ state_sh, /* Sh */
+ NULL, /* Ss */
+ NULL, /* Pp */
+ NULL, /* D1 */
+ state_dl, /* Dl */
+ state_bd, /* Bd */
+ NULL, /* Ed */
+ state_bl, /* Bl */
+ NULL, /* El */
+ NULL, /* It */
+ NULL, /* Ad */
+ NULL, /* An */
+ NULL, /* Ar */
+ NULL, /* Cd */
+ NULL, /* Cm */
+ NULL, /* Dv */
+ NULL, /* Er */
+ NULL, /* Ev */
+ NULL, /* Ex */
+ NULL, /* Fa */
+ NULL, /* Fd */
+ NULL, /* Fl */
+ NULL, /* Fn */
+ NULL, /* Ft */
+ NULL, /* Ic */
+ NULL, /* In */
+ NULL, /* Li */
+ NULL, /* Nd */
+ NULL, /* Nm */
+ NULL, /* Op */
+ NULL, /* Ot */
+ NULL, /* Pa */
+ NULL, /* Rv */
+ NULL, /* St */
+ NULL, /* Va */
+ NULL, /* Vt */
+ NULL, /* Xr */
+ NULL, /* %A */
+ NULL, /* %B */
+ NULL, /* %D */
+ NULL, /* %I */
+ NULL, /* %J */
+ NULL, /* %N */
+ NULL, /* %O */
+ NULL, /* %P */
+ NULL, /* %R */
+ NULL, /* %T */
+ NULL, /* %V */
+ NULL, /* Ac */
+ NULL, /* Ao */
+ NULL, /* Aq */
+ NULL, /* At */
+ NULL, /* Bc */
+ NULL, /* Bf */
+ NULL, /* Bo */
+ NULL, /* Bq */
+ NULL, /* Bsx */
+ NULL, /* Bx */
+ NULL, /* Db */
+ NULL, /* Dc */
+ NULL, /* Do */
+ NULL, /* Dq */
+ NULL, /* Ec */
+ NULL, /* Ef */
+ NULL, /* Em */
+ NULL, /* Eo */
+ NULL, /* Fx */
+ NULL, /* Ms */
+ NULL, /* No */
+ NULL, /* Ns */
+ NULL, /* Nx */
+ NULL, /* Ox */
+ NULL, /* Pc */
+ NULL, /* Pf */
+ NULL, /* Po */
+ NULL, /* Pq */
+ NULL, /* Qc */
+ NULL, /* Ql */
+ NULL, /* Qo */
+ NULL, /* Qq */
+ NULL, /* Re */
+ NULL, /* Rs */
+ NULL, /* Sc */
+ NULL, /* So */
+ NULL, /* Sq */
+ state_sm, /* Sm */
+ NULL, /* Sx */
+ NULL, /* Sy */
+ NULL, /* Tn */
+ NULL, /* Ux */
+ NULL, /* Xc */
+ NULL, /* Xo */
+ NULL, /* Fo */
+ NULL, /* Fc */
+ NULL, /* Oo */
+ NULL, /* Oc */
+ NULL, /* Bk */
+ NULL, /* Ek */
+ NULL, /* Bt */
+ NULL, /* Hf */
+ NULL, /* Fr */
+ NULL, /* Ud */
+ NULL, /* Lb */
+ NULL, /* Lp */
+ NULL, /* Lk */
+ NULL, /* Mt */
+ NULL, /* Brq */
+ NULL, /* Bro */
+ NULL, /* Brc */
+ NULL, /* %C */
+ NULL, /* Es */
+ NULL, /* En */
+ NULL, /* Dx */
+ NULL, /* %Q */
+ NULL, /* br */
+ NULL, /* sp */
+ NULL, /* %U */
+ NULL, /* Ta */
+ NULL, /* ll */
+};
+
+
+void
+mdoc_state(struct roff_man *mdoc, struct roff_node *n)
+{
+ state_handler handler;
+
+ if (n->tok == TOKEN_NONE)
+ return;
+
+ if ( ! (mdoc_macros[n->tok].flags & MDOC_PROLOGUE))
+ mdoc->flags |= MDOC_PBODY;
+
+ handler = state_handlers[n->tok];
+ if (*handler)
+ (*handler)(mdoc, n);
+}
+
+void
+mdoc_state_reset(struct roff_man *mdoc)
+{
+
+ roff_setreg(mdoc->roff, "nS", 0, '=');
+ mdoc->flags = 0;
+}
+
+static void
+state_bd(STATE_ARGS)
+{
+ enum mdocargt arg;
+
+ if (n->type != ROFFT_HEAD &&
+ (n->type != ROFFT_BODY || n->end != ENDBODY_NOT))
+ return;
+
+ if (n->parent->args == NULL)
+ return;
+
+ arg = n->parent->args->argv[0].arg;
+ if (arg != MDOC_Literal && arg != MDOC_Unfilled)
+ return;
+
+ state_dl(mdoc, n);
+}
+
+static void
+state_bl(STATE_ARGS)
+{
+
+ if (n->type != ROFFT_HEAD || n->parent->args == NULL)
+ return;
+
+ switch(n->parent->args->argv[0].arg) {
+ case MDOC_Diag:
+ n->norm->Bl.type = LIST_diag;
+ break;
+ case MDOC_Column:
+ n->norm->Bl.type = LIST_column;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+state_dl(STATE_ARGS)
+{
+
+ switch (n->type) {
+ case ROFFT_HEAD:
+ mdoc->flags |= MDOC_LITERAL;
+ break;
+ case ROFFT_BODY:
+ mdoc->flags &= ~MDOC_LITERAL;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+state_sh(STATE_ARGS)
+{
+ struct roff_node *nch;
+ char *secname;
+
+ if (n->type != ROFFT_HEAD)
+ return;
+
+ if ( ! (n->flags & MDOC_VALID)) {
+ secname = NULL;
+ deroff(&secname, n);
+
+ /*
+ * Set the section attribute for the BLOCK, HEAD,
+ * and HEAD children; the latter can only be TEXT
+ * nodes, so no recursion is needed. For other
+ * nodes, including the .Sh BODY, this is done
+ * when allocating the node data structures, but
+ * for .Sh BLOCK and HEAD, the section is still
+ * unknown at that time.
+ */
+
+ n->sec = n->parent->sec = secname == NULL ?
+ SEC_CUSTOM : mdoc_a2sec(secname);
+ for (nch = n->child; nch != NULL; nch = nch->next)
+ nch->sec = n->sec;
+ free(secname);
+ }
+
+ if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
+ roff_setreg(mdoc->roff, "nS", 1, '=');
+ mdoc->flags |= MDOC_SYNOPSIS;
+ } else {
+ roff_setreg(mdoc->roff, "nS", 0, '=');
+ mdoc->flags &= ~MDOC_SYNOPSIS;
+ }
+}
+
+static void
+state_sm(STATE_ARGS)
+{
+
+ if (n->child == NULL)
+ mdoc->flags ^= MDOC_SMOFF;
+ else if ( ! strcmp(n->child->string, "on"))
+ mdoc->flags &= ~MDOC_SMOFF;
+ else if ( ! strcmp(n->child->string, "off"))
+ mdoc->flags |= MDOC_SMOFF;
+}
diff --git a/mdoc_term.c b/mdoc_term.c
index 20c47d666893..e846436273da 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -1,16 +1,16 @@
-/* $Id: mdoc_term.c,v 1.313 2015/03/06 15:48:52 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.331 2016/01/08 17:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>