Import mdocml CVS snapshot 20160116
This commit is contained in:
parent
3481e0a06e
commit
877b18fd0c
16
INSTALL
16
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
|
||||
----------------------------------
|
||||
|
17
LICENSE
17
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>
|
||||
|
91
Makefile
91
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 $< > $@
|
||||
|
@ -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
|
||||
|
4
NEWS
4
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.
|
||||
|
110
TODO
110
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
|
||||
@ -474,10 +523,32 @@ are mere guesses, and some may be wrong.
|
||||
in dig(1).
|
||||
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.
|
||||
|
||||
|
19
apropos.1
19
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 ,
|
||||
|
5
att.c
5
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;
|
||||
}
|
||||
|
204
cgi.c
204
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 @@ http_parse(struct req *req, const char *qs)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -364,6 +317,20 @@ resp_begin_http(int code, const char *msg)
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
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, "&");
|
||||
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);
|
||||
|
@ -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
|
||||
|
485
chars.c
485
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
|
||||
/* Special break control characters. */
|
||||
static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
|
||||
static const char ascii_break[2] = { ASCII_BREAK, '\0' };
|
||||
|
||||
#define CHAR(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code) },
|
||||
static struct ln lines[] = {
|
||||
|
||||
#define CHAR_TBL_START static struct ln lines[LINES_MAX] = {
|
||||
#define CHAR_TBL_END };
|
||||
/* 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 },
|
||||
|
||||
#include "chars.in"
|
||||
/* Lines. */
|
||||
{ "ba", "|", 0x007c },
|
||||
{ "br", "|", 0x2502 },
|
||||
{ "ul", "_", 0x005f },
|
||||
{ "rn", "-", 0x203e },
|
||||
{ "bb", "|", 0x00a6 },
|
||||
{ "sl", "/", 0x002f },
|
||||
{ "rs", "\\", 0x005c },
|
||||
|
||||
struct mchars {
|
||||
struct ln **htab;
|
||||
/* 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;
|
||||
size_t i;
|
||||
unsigned int slot;
|
||||
|
||||
/*
|
||||
* 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];
|
||||
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 "<?>";
|
||||
}
|
||||
|
404
chars.in
404
chars.in
@ -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
|
112
compat_err.c
Normal file
112
compat_err.c
Normal file
@ -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
|
@ -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
|
181
compat_fts.c
181
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;
|
||||
|
||||
@ -431,32 +369,6 @@ fts_build(FTS *sp)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
@ -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
|
||||
|
@ -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_ */
|
||||
|
68
compat_getline.c
Normal file
68
compat_getline.c
Normal file
@ -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
|
33
compat_isblank.c
Normal file
33
compat_isblank.c
Normal file
@ -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
|
61
compat_mkdtemp.c
Normal file
61
compat_mkdtemp.c
Normal file
@ -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
|
@ -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
|
||||
|
42
compat_progname.c
Normal file
42
compat_progname.c
Normal file
@ -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
|
@ -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
|
||||
|
119
compat_stringlist.c
Normal file
119
compat_stringlist.c
Normal file
@ -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
|
45
compat_stringlist.h
Normal file
45
compat_stringlist.h
Normal file
@ -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 *);
|
56
compat_vasprintf.c
Normal file
56
compat_vasprintf.c
Normal file
@ -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
|
53
config.h
Normal file
53
config.h
Normal file
@ -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 */
|
210
config.log
Normal file
210
config.log
Normal file
@ -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
|
116
configure
vendored
116
configure
vendored
@ -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_MAN="man"
|
||||
BINM_WHATIS="whatis"
|
||||
BINM_MAKEWHATIS="makewhatis"
|
||||
BINM_MAN="man"
|
||||
BINM_SOELIM="soelim"
|
||||
BINM_WHATIS="whatis"
|
||||
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_MAN "${BINM_MAN}"
|
||||
#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
|
||||
#define BINM_MAN "${BINM_MAN}"
|
||||
#define BINM_SOELIM "${BINM_SOELIM}"
|
||||
#define BINM_WHATIS "${BINM_WHATIS}"
|
||||
|
||||
__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_MAN = ${BINM_MAN}
|
||||
BINM_WHATIS = ${BINM_WHATIS}
|
||||
BINM_MAKEWHATIS = ${BINM_MAKEWHATIS}
|
||||
BINM_MAN = ${BINM_MAN}
|
||||
BINM_SOELIM = ${BINM_SOELIM}
|
||||
BINM_WHATIS = ${BINM_WHATIS}
|
||||
MANM_MAN = ${MANM_MAN}
|
||||
MANM_MANCONF = ${MANM_MANCONF}
|
||||
MANM_MDOC = ${MANM_MDOC}
|
||||
MANM_ROFF = ${MANM_ROFF}
|
||||
MANM_EQN = ${MANM_EQN}
|
||||
|
@ -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:
|
||||
|
47
demandoc.c
47
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);
|
||||
|
10
eqn.7
10
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.
|
||||
|
45
eqn.c
45
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 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
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 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
q = 0;
|
||||
|
||||
if ('\0' == *start)
|
||||
return(NULL);
|
||||
return NULL;
|
||||
|
||||
if (quote == *start) {
|
||||
ep->cur++;
|
||||
@ -432,7 +432,7 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
/* 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 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
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 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent)
|
||||
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 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent)
|
||||
* 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
|
||||
|
@ -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; }
|
3
gmdiff
3
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
|
||||
|
77
html.c
77
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(""");
|
||||
break;
|
||||
case ASCII_NBRSP:
|
||||
putchar('-');
|
||||
printf(" ");
|
||||
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);
|
||||
}
|
||||
|
6
html.h
6
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
|
||||
|
5
lib.c
5
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;
|
||||
}
|
||||
|
63
libman.h
63
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 *);
|
||||
|
44
libmandoc.h
44
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
|
||||
|
89
libmdoc.h
89
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
|
||||
|
@ -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
|
||||
|
600
main.c
600
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 (search.argmode == ARG_FILE && ! moptions(&options, auxpaths))
|
||||
return((int)MANDOCLEVEL_BADARG);
|
||||
#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
|
||||
|
||||
curp.mchars = mchars_alloc();
|
||||
curp.mp = mparse_alloc(options, curp.wlevel, mmsg,
|
||||
curp.mchars, defos);
|
||||
if (search.argmode == ARG_FILE && ! moptions(&options, auxpaths))
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
|
||||
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 (resp == NULL)
|
||||
parse(&curp, fd, *argv, &rc);
|
||||
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;
|
||||
if (use_pager) {
|
||||
tag_files = tag_init();
|
||||
use_pager = 0;
|
||||
}
|
||||
|
||||
rctmp = mparse_wait(curp.mp);
|
||||
if (rc < rctmp)
|
||||
rc = rctmp;
|
||||
if (resp == NULL)
|
||||
parse(&curp, fd, *argv);
|
||||
else if (resp->form & FORM_SRC) {
|
||||
/* For .so only; ignore failure. */
|
||||
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 @@ main(int argc, char *argv[])
|
||||
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 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (curp->outtype) {
|
||||
case OUTT_HTML:
|
||||
curp->outman = html_man;
|
||||
curp->outmdoc = html_mdoc;
|
||||
break;
|
||||
case OUTT_TREE:
|
||||
curp->outman = tree_man;
|
||||
curp->outmdoc = tree_mdoc;
|
||||
break;
|
||||
case OUTT_MAN:
|
||||
curp->outmdoc = man_mdoc;
|
||||
curp->outman = man_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;
|
||||
curp->outdata = ps_alloc(curp->outopts);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mparse_result(curp->mp, &mdoc, &man, NULL);
|
||||
mparse_result(curp->mp, &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;
|
||||
if (man == NULL)
|
||||
return;
|
||||
if (man->macroset == MACROSET_MDOC) {
|
||||
mdoc_validate(man);
|
||||
switch (curp->outtype) {
|
||||
case OUTT_HTML:
|
||||
html_mdoc(curp->outdata, man);
|
||||
break;
|
||||
case OUTT_TREE:
|
||||
tree_mdoc(curp->outdata, man);
|
||||
break;
|
||||
case OUTT_MAN:
|
||||
man_mdoc(curp->outdata, man);
|
||||
break;
|
||||
case OUTT_PDF:
|
||||
case OUTT_ASCII:
|
||||
case OUTT_UTF8:
|
||||
case OUTT_LOCALE:
|
||||
case OUTT_PS:
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
45
main.h
45
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 *);
|
||||
|
13
man-cgi.css
13
man-cgi.css
@ -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; }
|
32
man.1
32
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
|
||||
|
503
man.c
503
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);
|
||||
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);
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
man->last->flags |= MAN_VALID;
|
||||
}
|
||||
|
||||
void
|
||||
man_validate(struct roff_man *man)
|
||||
{
|
||||
|
||||
man->last = man->first;
|
||||
man_node_validate(man);
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
}
|
||||
|
30
man.cgi.8
30
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
|
||||
|
131
man.conf.5
Normal file
131
man.conf.5
Normal file
@ -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
|
144
man.h
144
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;
|
||||
struct roff_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 *);
|
||||
|
||||
__END_DECLS
|
||||
const struct mparse *man_mparse(const struct roff_man *);
|
||||
void man_validate(struct roff_man *);
|
||||
|
29
man_hash.c
29
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;
|
||||
}
|
||||
|
164
man_html.c
164
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;
|
||||
}
|
||||
|
298
man_macro.c
298
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)
|
||||
/* Preserve empty paragraphs before RS. */
|
||||
|
||||
n = man->last;
|
||||
if (tok == MAN_RS && n->child == NULL &&
|
||||
(n->tok == MAN_P || n->tok == MAN_PP || n->tok == MAN_LP))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
if (n->type == ROFFT_ROOT)
|
||||
return;
|
||||
if (REW_REWIND == c)
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind until the current point. Warn if we're a roff
|
||||
* instruction that's mowing over explicit scopes.
|
||||
*/
|
||||
|
||||
man_unscope(man, n);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
291
man_term.c
291
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);
|
||||
|
||||
|
163
man_validate.c
163
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;
|
||||
|
48
manconf.h
Normal file
48
manconf.h
Normal file
@ -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 *);
|
177
mandoc.1
177
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 .
|
||||
|
80
mandoc.3
80
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
|
||||
|
133
mandoc.c
133
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;
|
||||
}
|
||||
|
@ -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. */
|
35
mandoc.h
35
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
|
||||
|
56
mandoc_aux.c
56
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
114
mandoc_char.7
114
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
|
||||
|
121
mandoc_headers.3
121
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
|
||||
|
63
mandoc_ohash.c
Normal file
63
mandoc_ohash.c
Normal file
@ -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);
|
||||
}
|
23
mandoc_ohash.h
Normal file
23
mandoc_ohash.h
Normal file
@ -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);
|
568
mandocdb.c
568
mandocdb.c
File diff suppressed because it is too large
Load Diff
41
manpage.c
41
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 @@ main(int argc, char *argv[])
|
||||
"[-s section] "
|
||||
"expr ...\n",
|
||||
progname);
|
||||
return(EXIT_FAILURE);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
219
manpath.c
219
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);
|
||||
}
|
||||
|
||||
#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 *line, *cp, *ep;
|
||||
size_t linesz, tok, toklen;
|
||||
ssize_t linelen;
|
||||
|
||||
if ((stream = fopen(file, "r")) == NULL)
|
||||
goto out;
|
||||
|
||||
line = NULL;
|
||||
linesz = 0;
|
||||
|
||||
while ((linelen = getline(&line, &linesz, stream)) != -1) {
|
||||
cp = line;
|
||||
ep = cp + linelen;
|
||||
if (ep[-1] != '\n')
|
||||
break;
|
||||
*--ep = '\0';
|
||||
while (isspace((unsigned char)*cp))
|
||||
cp++;
|
||||
if (*cp == '#')
|
||||
continue;
|
||||
|
||||
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
|
||||
manpath_manconf(struct manpaths *dirs, const char *file)
|
||||
manconf_output(struct manoutput *conf, const char *cp)
|
||||
{
|
||||
FILE *stream;
|
||||
char *p, *q;
|
||||
size_t len, keysz;
|
||||
const char *const toks[] = {
|
||||
"includes", "man", "paper", "style",
|
||||
"indent", "width", "fragment", "mdoc"
|
||||
};
|
||||
|
||||
keysz = strlen(MAN_CONF_KEY);
|
||||
assert(keysz > 0);
|
||||
size_t len, tok;
|
||||
|
||||
if (NULL == (stream = fopen(file, "r")))
|
||||
return;
|
||||
|
||||
while (NULL != (p = fgetln(stream, &len))) {
|
||||
if (0 == len || '\n' != p[--len])
|
||||
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;
|
||||
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)
|
||||
continue;
|
||||
if (NULL == (q = strrchr(p, '/')))
|
||||
continue;
|
||||
*q = '\0';
|
||||
manpath_add(dirs, p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(stream);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
198
mansearch.c
198
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
27
mdoc.7
27
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
|
||||
|
592
mdoc.c
592
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);
|
||||
static int mdoc_ptext(struct roff_man *, int, char *, int);
|
||||
static int mdoc_pmacro(struct roff_man *, 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;
|
||||
}
|
||||
|
||||
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);
|
||||
assert(tok > TOKEN_NONE && 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
roff_node_append(mdoc, p);
|
||||
mdoc->next = ROFF_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;
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_word_append(struct mdoc *mdoc, const char *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)
|
||||
mdoc_node_relink(struct roff_man *mdoc, struct roff_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);
|
||||
}
|
||||
|
371
mdoc.h
371
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 *);
|
||||
|
208
mdoc_argv.c
208
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;
|
||||
if (fl == ARGSFL_TABSEP) {
|
||||
if ((p = strchr(*v, '\t')) != 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;
|
||||
}
|
||||
/*
|
||||
* Words right before and right after
|
||||
* tab characters are not parsed,
|
||||
* unless there is a blank in between.
|
||||
*/
|
||||
|
||||
/* By default, assume a phrase. */
|
||||
rc = ARGS_PHRASE;
|
||||
if (p[-1] != ' ')
|
||||
mdoc->flags |= MDOC_PHRASEQL;
|
||||
if (p[1] != ' ')
|
||||
mdoc->flags |= MDOC_PHRASEQN;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
/*
|
||||
* 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);
|
||||
/* Skip any trailing blank characters. */
|
||||
while (p > *v && p[-1] == ' ' &&
|
||||
(p - 1 == *v || p[-2] != '\\'))
|
||||
p--;
|
||||
*p = '\0';
|
||||
|
||||
*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;
|
||||
|
||||
/* 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;
|
||||
|
25
mdoc_hash.c
25
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;
|
||||
}
|
||||
|
466
mdoc_html.c
466
mdoc_html.c
File diff suppressed because it is too large
Load Diff
489
mdoc_macro.c
489
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. */
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
310
mdoc_man.c
310
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;
|
||||
}
|
||||
|
292
mdoc_state.c
Normal file
292
mdoc_state.c
Normal file
@ -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;
|
||||
}
|
540
mdoc_term.c
540
mdoc_term.c
File diff suppressed because it is too large
Load Diff
1141
mdoc_validate.c
1141
mdoc_validate.c
File diff suppressed because it is too large
Load Diff
4
msec.c
4
msec.c
@ -1,4 +1,4 @@
|
||||
/* $Id: msec.c,v 1.14 2014/12/21 14:14:35 schwarze Exp $ */
|
||||
/* $Id: msec.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -32,5 +32,5 @@ mandoc_a2msec(const char *p)
|
||||
|
||||
#include "msec.in"
|
||||
|
||||
return(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
13
out.c
13
out.c
@ -1,4 +1,4 @@
|
||||
/* $Id: out.c,v 1.59 2015/01/30 04:11:50 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.62 2015/10/12 00:08:16 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -51,7 +51,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
dst->unit = def == SCALE_MAX ? SCALE_BU : def;
|
||||
dst->scale = strtod(src, &endptr);
|
||||
if (endptr == src)
|
||||
return(0);
|
||||
return 0;
|
||||
|
||||
switch (*endptr++) {
|
||||
case 'c':
|
||||
@ -89,12 +89,12 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (SCALE_MAX == def)
|
||||
return(0);
|
||||
return 0;
|
||||
dst->unit = def;
|
||||
break;
|
||||
}
|
||||
|
||||
return(*endptr == '\0' ? 2 : 1);
|
||||
return *endptr == '\0' ? 2 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,18 +240,14 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
|
||||
switch (dp->layout->pos) {
|
||||
case TBL_CELL_HORIZ:
|
||||
/* FALLTHROUGH */
|
||||
case TBL_CELL_DHORIZ:
|
||||
sz = (*tbl->len)(1, tbl->arg);
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
break;
|
||||
case TBL_CELL_LONG:
|
||||
/* FALLTHROUGH */
|
||||
case TBL_CELL_CENTRE:
|
||||
/* FALLTHROUGH */
|
||||
case TBL_CELL_LEFT:
|
||||
/* FALLTHROUGH */
|
||||
case TBL_CELL_RIGHT:
|
||||
tblcalc_literal(tbl, col, dp);
|
||||
break;
|
||||
@ -262,7 +258,6 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
|
5
out.h
5
out.h
@ -1,4 +1,4 @@
|
||||
/* $Id: out.h,v 1.26 2014/12/01 08:05:52 schwarze Exp $ */
|
||||
/* $Id: out.h,v 1.27 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -60,12 +60,9 @@ struct rofftbl {
|
||||
(p)->scale = (v); } \
|
||||
while (/* CONSTCOND */ 0)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct tbl_span;
|
||||
|
||||
int a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
void tblcalc(struct rofftbl *tbl,
|
||||
const struct tbl_span *, size_t);
|
||||
|
||||
__END_DECLS
|
||||
|
20
preconv.c
20
preconv.c
@ -1,4 +1,4 @@
|
||||
/* $Id: preconv.c,v 1.14 2015/03/06 09:24:59 kristaps Exp $ */
|
||||
/* $Id: preconv.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -92,17 +92,17 @@ preconv_encode(struct buf *ib, size_t *ii, struct buf *ob, size_t *oi,
|
||||
*oi += snprintf(ob->buf + *oi, 11, "\\[u%.4X]", accum);
|
||||
*ii = (char *)cu - ib->buf;
|
||||
*filenc &= ~MPARSE_LATIN1;
|
||||
return(1);
|
||||
return 1;
|
||||
|
||||
latin:
|
||||
if ( ! (*filenc & MPARSE_LATIN1))
|
||||
return(0);
|
||||
return 0;
|
||||
|
||||
*oi += snprintf(ob->buf + *oi, 11,
|
||||
"\\[u%.4X]", (unsigned char)ib->buf[(*ii)++]);
|
||||
|
||||
*filenc &= ~MPARSE_UTF8;
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -123,7 +123,7 @@ preconv_cue(const struct buf *b, size_t offset)
|
||||
|
||||
if ((sz = (size_t)(eoln - ln)) < 10 ||
|
||||
memcmp(ln, ".\\\" -*-", 7) || memcmp(eoln - 3, "-*-", 3))
|
||||
return(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||
return MPARSE_UTF8 | MPARSE_LATIN1;
|
||||
|
||||
/* Move after the header and adjust for the trailer. */
|
||||
|
||||
@ -162,15 +162,15 @@ preconv_cue(const struct buf *b, size_t offset)
|
||||
sz--;
|
||||
}
|
||||
if (0 == sz)
|
||||
return(0);
|
||||
return 0;
|
||||
|
||||
/* Check us against known encodings. */
|
||||
|
||||
if (phsz > 4 && !strncasecmp(ln, "utf-8", 5))
|
||||
return(MPARSE_UTF8);
|
||||
return MPARSE_UTF8;
|
||||
if (phsz > 10 && !strncasecmp(ln, "iso-latin-1", 11))
|
||||
return(MPARSE_LATIN1);
|
||||
return(0);
|
||||
return MPARSE_LATIN1;
|
||||
return 0;
|
||||
}
|
||||
return(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||
return MPARSE_UTF8 | MPARSE_LATIN1;
|
||||
}
|
||||
|
300
read.c
300
read.c
@ -1,16 +1,16 @@
|
||||
/* $Id: read.c,v 1.131 2015/03/11 13:05:20 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.148 2016/01/08 02:53:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012 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
|
||||
@ -23,10 +23,12 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
@ -35,22 +37,21 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_aux.h"
|
||||
#include "libmandoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
|
||||
#define REPARSE_LIMIT 1000
|
||||
|
||||
struct mparse {
|
||||
struct man *pman; /* persistent man parser */
|
||||
struct mdoc *pmdoc; /* persistent mdoc parser */
|
||||
struct man *man; /* man parser */
|
||||
struct mdoc *mdoc; /* mdoc parser */
|
||||
struct roff_man *man; /* man parser */
|
||||
struct roff *roff; /* roff parser (!NULL) */
|
||||
const struct mchars *mchars; /* character table */
|
||||
char *sodest; /* filename pointed to by .so */
|
||||
const char *file; /* filename of current input file */
|
||||
struct buf *primary; /* buffer currently being parsed */
|
||||
@ -60,10 +61,10 @@ struct mparse {
|
||||
enum mandoclevel file_status; /* status of current parse */
|
||||
enum mandoclevel wlevel; /* ignore messages below this */
|
||||
int options; /* parser options */
|
||||
int gzip; /* current input file is gzipped */
|
||||
int filenc; /* encoding of the current file */
|
||||
int reparse_count; /* finite interp. stack */
|
||||
int line; /* line number in the file */
|
||||
pid_t child; /* the gunzip(1) process */
|
||||
};
|
||||
|
||||
static void choose_parser(struct mparse *);
|
||||
@ -130,7 +131,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"blocks badly nested",
|
||||
"nested displays are not portable",
|
||||
"moving content out of list",
|
||||
".Vt block has child macro",
|
||||
"fill mode already enabled, skipping",
|
||||
"fill mode already disabled, skipping",
|
||||
"line scope broken",
|
||||
@ -217,6 +217,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
/* related to request and macro arguments */
|
||||
"escaped character not allowed in a name",
|
||||
"NOT IMPLEMENTED: Bd -file",
|
||||
"skipping display without arguments",
|
||||
"missing list type, using -item",
|
||||
"missing manual name, using \"\"",
|
||||
"uname(3) system call failed, using UNKNOWN",
|
||||
@ -290,24 +291,22 @@ choose_parser(struct mparse *curp)
|
||||
}
|
||||
}
|
||||
|
||||
if (format == MPARSE_MDOC) {
|
||||
if (NULL == curp->pmdoc)
|
||||
curp->pmdoc = mdoc_alloc(
|
||||
curp->roff, curp, curp->defos,
|
||||
MPARSE_QUICK & curp->options ? 1 : 0);
|
||||
assert(curp->pmdoc);
|
||||
curp->mdoc = curp->pmdoc;
|
||||
return;
|
||||
if (curp->man == NULL) {
|
||||
curp->man = roff_man_alloc(curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
curp->man->macroset = MACROSET_MAN;
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
}
|
||||
|
||||
/* Fall back to man(7) as a last resort. */
|
||||
|
||||
if (NULL == curp->pman)
|
||||
curp->pman = man_alloc(
|
||||
curp->roff, curp, curp->defos,
|
||||
MPARSE_QUICK & curp->options ? 1 : 0);
|
||||
assert(curp->pman);
|
||||
curp->man = curp->pman;
|
||||
if (format == MPARSE_MDOC) {
|
||||
mdoc_hash_init();
|
||||
curp->man->macroset = MACROSET_MDOC;
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
} else {
|
||||
man_hash_init();
|
||||
curp->man->macroset = MACROSET_MAN;
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -329,7 +328,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
int of;
|
||||
int lnn; /* line number in the real file */
|
||||
int fd;
|
||||
pid_t save_child;
|
||||
unsigned char c;
|
||||
|
||||
memset(&ln, 0, sizeof(ln));
|
||||
@ -541,10 +539,9 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
if (curp->secondary)
|
||||
curp->secondary->sz -= pos + 1;
|
||||
save_file = curp->file;
|
||||
save_child = curp->child;
|
||||
if (mparse_open(curp, &fd, ln.buf + of) ==
|
||||
MANDOCLEVEL_OK) {
|
||||
if ((fd = mparse_open(curp, ln.buf + of)) != -1) {
|
||||
mparse_readfd(curp, fd, ln.buf + of);
|
||||
close(fd);
|
||||
curp->file = save_file;
|
||||
} else {
|
||||
curp->file = save_file;
|
||||
@ -559,7 +556,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
of = 0;
|
||||
mparse_buf_r(curp, ln, of, 0);
|
||||
}
|
||||
curp->child = save_child;
|
||||
pos = 0;
|
||||
continue;
|
||||
default:
|
||||
@ -573,7 +569,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
* parsers with each one.
|
||||
*/
|
||||
|
||||
if ( ! (curp->man || curp->mdoc))
|
||||
if (curp->man == NULL ||
|
||||
curp->man->macroset == MACROSET_NONE)
|
||||
choose_parser(curp);
|
||||
|
||||
/*
|
||||
@ -585,19 +582,13 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
* Do the same for ROFF_EQN.
|
||||
*/
|
||||
|
||||
if (rr == ROFF_TBL) {
|
||||
if (rr == ROFF_TBL)
|
||||
while ((span = roff_span(curp->roff)) != NULL)
|
||||
if (curp->man == NULL)
|
||||
mdoc_addspan(curp->mdoc, span);
|
||||
else
|
||||
man_addspan(curp->man, span);
|
||||
} else if (rr == ROFF_EQN) {
|
||||
if (curp->man == NULL)
|
||||
mdoc_addeqn(curp->mdoc, roff_eqn(curp->roff));
|
||||
else
|
||||
man_addeqn(curp->man, roff_eqn(curp->roff));
|
||||
} else if ((curp->man == NULL ?
|
||||
mdoc_parseln(curp->mdoc, curp->line, ln.buf, of) :
|
||||
roff_addtbl(curp->man, span);
|
||||
else if (rr == ROFF_EQN)
|
||||
roff_addeqn(curp->man, roff_eqn(curp->roff));
|
||||
else if ((curp->man->macroset == MACROSET_MDOC ?
|
||||
mdoc_parseln(curp->man, curp->line, ln.buf, of) :
|
||||
man_parseln(curp->man, curp->line, ln.buf, of)) == 2)
|
||||
break;
|
||||
|
||||
@ -618,15 +609,15 @@ static int
|
||||
read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
struct buf *fb, int *with_mmap)
|
||||
{
|
||||
gzFile gz;
|
||||
size_t off;
|
||||
ssize_t ssz;
|
||||
|
||||
#if HAVE_MMAP
|
||||
struct stat st;
|
||||
if (-1 == fstat(fd, &st)) {
|
||||
perror(file);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", file);
|
||||
|
||||
/*
|
||||
* If we're a regular file, try just reading in the whole entry
|
||||
@ -635,19 +626,25 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
* concerned that this is going to tank any machines.
|
||||
*/
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (curp->gzip == 0 && S_ISREG(st.st_mode)) {
|
||||
if (st.st_size > 0x7fffffff) {
|
||||
mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL);
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
*with_mmap = 1;
|
||||
fb->sz = (size_t)st.st_size;
|
||||
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (fb->buf != MAP_FAILED)
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (curp->gzip) {
|
||||
if ((gz = gzdopen(fd, "rb")) == NULL)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", file);
|
||||
} else
|
||||
gz = NULL;
|
||||
|
||||
/*
|
||||
* If this isn't a regular file (like, say, stdin), then we must
|
||||
* go the old way and just read things in bit by bit.
|
||||
@ -666,43 +663,35 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
}
|
||||
resize_buf(fb, 65536);
|
||||
}
|
||||
ssz = read(fd, fb->buf + (int)off, fb->sz - off);
|
||||
ssz = curp->gzip ?
|
||||
gzread(gz, fb->buf + (int)off, fb->sz - off) :
|
||||
read(fd, fb->buf + (int)off, fb->sz - off);
|
||||
if (ssz == 0) {
|
||||
fb->sz = off;
|
||||
return(1);
|
||||
}
|
||||
if (ssz == -1) {
|
||||
perror(file);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
return 1;
|
||||
}
|
||||
if (ssz == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", file);
|
||||
off += (size_t)ssz;
|
||||
}
|
||||
|
||||
free(fb->buf);
|
||||
fb->buf = NULL;
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mparse_end(struct mparse *curp)
|
||||
{
|
||||
|
||||
if (curp->mdoc == NULL &&
|
||||
curp->man == NULL &&
|
||||
curp->sodest == NULL) {
|
||||
if (curp->options & MPARSE_MDOC)
|
||||
curp->mdoc = curp->pmdoc;
|
||||
else {
|
||||
if (curp->pman == NULL)
|
||||
curp->pman = man_alloc(
|
||||
curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
curp->man = curp->pman;
|
||||
}
|
||||
}
|
||||
if (curp->mdoc)
|
||||
mdoc_endparse(curp->mdoc);
|
||||
if (curp->man)
|
||||
if (curp->man == NULL && curp->sodest == NULL)
|
||||
curp->man = roff_man_alloc(curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
if (curp->man->macroset == MACROSET_NONE)
|
||||
curp->man->macroset = MACROSET_MAN;
|
||||
if (curp->man->macroset == MACROSET_MDOC)
|
||||
mdoc_endparse(curp->man);
|
||||
else
|
||||
man_endparse(curp->man);
|
||||
roff_endparse(curp->roff);
|
||||
}
|
||||
@ -757,7 +746,7 @@ mparse_readmem(struct mparse *curp, void *buf, size_t len,
|
||||
blk.sz = len;
|
||||
|
||||
mparse_parse_buffer(curp, blk, file);
|
||||
return(curp->file_status);
|
||||
return curp->file_status;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -784,107 +773,48 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
|
||||
#endif
|
||||
free(blk.buf);
|
||||
}
|
||||
|
||||
if (fd != STDIN_FILENO && close(fd) == -1)
|
||||
perror(file);
|
||||
|
||||
mparse_wait(curp);
|
||||
return(curp->file_status);
|
||||
return curp->file_status;
|
||||
}
|
||||
|
||||
enum mandoclevel
|
||||
mparse_open(struct mparse *curp, int *fd, const char *file)
|
||||
int
|
||||
mparse_open(struct mparse *curp, const char *file)
|
||||
{
|
||||
int pfd[2];
|
||||
int save_errno;
|
||||
char *cp;
|
||||
int fd;
|
||||
|
||||
curp->file = file;
|
||||
cp = strrchr(file, '.');
|
||||
curp->gzip = (cp != NULL && ! strcmp(cp + 1, "gz"));
|
||||
|
||||
/* Unless zipped, try to just open the file. */
|
||||
/* First try to use the filename as it is. */
|
||||
|
||||
if ((cp = strrchr(file, '.')) == NULL ||
|
||||
strcmp(cp + 1, "gz")) {
|
||||
curp->child = 0;
|
||||
if ((*fd = open(file, O_RDONLY)) != -1)
|
||||
return(MANDOCLEVEL_OK);
|
||||
if ((fd = open(file, O_RDONLY)) != -1)
|
||||
return fd;
|
||||
|
||||
/* Open failed; try to append ".gz". */
|
||||
/*
|
||||
* If that doesn't work and the filename doesn't
|
||||
* already end in .gz, try appending .gz.
|
||||
*/
|
||||
|
||||
if ( ! curp->gzip) {
|
||||
mandoc_asprintf(&cp, "%s.gz", file);
|
||||
file = cp;
|
||||
} else
|
||||
cp = NULL;
|
||||
|
||||
/* Before forking, make sure the file can be read. */
|
||||
|
||||
save_errno = errno;
|
||||
if (access(file, R_OK) == -1) {
|
||||
if (cp != NULL)
|
||||
errno = save_errno;
|
||||
fd = open(file, O_RDONLY);
|
||||
free(cp);
|
||||
*fd = -1;
|
||||
curp->child = 0;
|
||||
mandoc_msg(MANDOCERR_FILE, curp, 0, 0, strerror(errno));
|
||||
return(MANDOCLEVEL_ERROR);
|
||||
}
|
||||
|
||||
/* Run gunzip(1). */
|
||||
|
||||
if (pipe(pfd) == -1) {
|
||||
perror("pipe");
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
switch (curp->child = fork()) {
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
case 0:
|
||||
close(pfd[0]);
|
||||
if (dup2(pfd[1], STDOUT_FILENO) == -1) {
|
||||
perror("dup");
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
if (fd != -1) {
|
||||
curp->gzip = 1;
|
||||
return fd;
|
||||
}
|
||||
execlp("gunzip", "gunzip", "-c", file, NULL);
|
||||
perror("exec");
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
default:
|
||||
close(pfd[1]);
|
||||
*fd = pfd[0];
|
||||
return(MANDOCLEVEL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
enum mandoclevel
|
||||
mparse_wait(struct mparse *curp)
|
||||
{
|
||||
int status;
|
||||
/* Neither worked, give up. */
|
||||
|
||||
if (curp->child == 0)
|
||||
return(MANDOCLEVEL_OK);
|
||||
|
||||
if (waitpid(curp->child, &status, 0) == -1) {
|
||||
perror("wait");
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
curp->child = 0;
|
||||
if (WIFSIGNALED(status)) {
|
||||
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
|
||||
"gunzip died from signal %d", WTERMSIG(status));
|
||||
return(MANDOCLEVEL_ERROR);
|
||||
}
|
||||
if (WEXITSTATUS(status)) {
|
||||
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
|
||||
"gunzip failed with code %d", WEXITSTATUS(status));
|
||||
return(MANDOCLEVEL_ERROR);
|
||||
}
|
||||
return(MANDOCLEVEL_OK);
|
||||
mandoc_msg(MANDOCERR_FILE, curp, 0, 0, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct mparse *
|
||||
mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||
const struct mchars *mchars, const char *defos)
|
||||
const char *defos)
|
||||
{
|
||||
struct mparse *curp;
|
||||
|
||||
@ -895,18 +825,18 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||
curp->mmsg = mmsg;
|
||||
curp->defos = defos;
|
||||
|
||||
curp->mchars = mchars;
|
||||
curp->roff = roff_alloc(curp, curp->mchars, options);
|
||||
if (curp->options & MPARSE_MDOC)
|
||||
curp->pmdoc = mdoc_alloc(
|
||||
curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
if (curp->options & MPARSE_MAN)
|
||||
curp->pman = man_alloc(
|
||||
curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
|
||||
return(curp);
|
||||
curp->roff = roff_alloc(curp, options);
|
||||
curp->man = roff_man_alloc( curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
if (curp->options & MPARSE_MDOC) {
|
||||
mdoc_hash_init();
|
||||
curp->man->macroset = MACROSET_MDOC;
|
||||
} else if (curp->options & MPARSE_MAN) {
|
||||
man_hash_init();
|
||||
curp->man->macroset = MACROSET_MAN;
|
||||
}
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
return curp;
|
||||
}
|
||||
|
||||
void
|
||||
@ -915,16 +845,12 @@ mparse_reset(struct mparse *curp)
|
||||
|
||||
roff_reset(curp->roff);
|
||||
|
||||
if (curp->mdoc)
|
||||
mdoc_reset(curp->mdoc);
|
||||
if (curp->man)
|
||||
man_reset(curp->man);
|
||||
if (curp->man != NULL)
|
||||
roff_man_reset(curp->man);
|
||||
if (curp->secondary)
|
||||
curp->secondary->sz = 0;
|
||||
|
||||
curp->file_status = MANDOCLEVEL_OK;
|
||||
curp->mdoc = NULL;
|
||||
curp->man = NULL;
|
||||
|
||||
free(curp->sodest);
|
||||
curp->sodest = NULL;
|
||||
@ -934,10 +860,7 @@ void
|
||||
mparse_free(struct mparse *curp)
|
||||
{
|
||||
|
||||
if (curp->pmdoc)
|
||||
mdoc_free(curp->pmdoc);
|
||||
if (curp->pman)
|
||||
man_free(curp->pman);
|
||||
roff_man_free(curp->man);
|
||||
if (curp->roff)
|
||||
roff_free(curp->roff);
|
||||
if (curp->secondary)
|
||||
@ -949,17 +872,14 @@ mparse_free(struct mparse *curp)
|
||||
}
|
||||
|
||||
void
|
||||
mparse_result(struct mparse *curp,
|
||||
struct mdoc **mdoc, struct man **man, char **sodest)
|
||||
mparse_result(struct mparse *curp, struct roff_man **man,
|
||||
char **sodest)
|
||||
{
|
||||
|
||||
if (sodest && NULL != (*sodest = curp->sodest)) {
|
||||
*mdoc = NULL;
|
||||
*man = NULL;
|
||||
return;
|
||||
}
|
||||
if (mdoc)
|
||||
*mdoc = curp->mdoc;
|
||||
if (man)
|
||||
*man = curp->man;
|
||||
}
|
||||
@ -1002,13 +922,13 @@ const char *
|
||||
mparse_strerror(enum mandocerr er)
|
||||
{
|
||||
|
||||
return(mandocerrs[er]);
|
||||
return mandocerrs[er];
|
||||
}
|
||||
|
||||
const char *
|
||||
mparse_strlevel(enum mandoclevel lvl)
|
||||
{
|
||||
return(mandoclevels[lvl]);
|
||||
return mandoclevels[lvl];
|
||||
}
|
||||
|
||||
void
|
||||
@ -1024,5 +944,5 @@ mparse_getkeep(const struct mparse *p)
|
||||
{
|
||||
|
||||
assert(p->secondary);
|
||||
return(p->secondary->sz ? p->secondary->buf : NULL);
|
||||
return p->secondary->sz ? p->secondary->buf : NULL;
|
||||
}
|
||||
|
34
roff.7
34
roff.7
@ -1,7 +1,7 @@
|
||||
.\" $Id: roff.7,v 1.70 2015/02/17 17:16:52 schwarze Exp $
|
||||
.\" $Id: roff.7,v 1.75 2015/09/24 18:41:22 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 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
|
||||
@ -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 17 2015 $
|
||||
.Dd $Mdocdate: September 24 2015 $
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -665,6 +665,8 @@ produces
|
||||
.D1 \efI\e^XtFree\e^\efP.
|
||||
.Pp
|
||||
in the input stream, and thus in the output: \fI\^XtFree\^\fP.
|
||||
Each occurrence of \e\e$* is replaced with all the arguments,
|
||||
joined together with single blank characters.
|
||||
.Pp
|
||||
Since macros and user-defined strings share a common string table,
|
||||
defining a macro
|
||||
@ -1057,8 +1059,6 @@ If the first character of COND is
|
||||
.Pq string defined ,
|
||||
.Sq e
|
||||
.Pq even page ,
|
||||
.Sq r
|
||||
.Pq register accessed ,
|
||||
.Sq t
|
||||
.Pq troff mode ,
|
||||
or
|
||||
@ -1066,6 +1066,11 @@ or
|
||||
.Pq vroff mode ,
|
||||
COND evaluates to false.
|
||||
.It
|
||||
If the first character of COND is
|
||||
.Sq r ,
|
||||
it evaluates to true if the rest of COND is the name of an existing
|
||||
number register; otherwise, it evaluates to false.
|
||||
.It
|
||||
If COND starts with a parenthesis or with an optionally signed
|
||||
integer number, it is evaluated according to the rules of
|
||||
.Sx Numerical expressions
|
||||
@ -1337,7 +1342,7 @@ Currently unsupported.
|
||||
Temporarily turn off line numbering.
|
||||
Currently unsupported.
|
||||
.Ss \&nop
|
||||
Exexute the rest of the input line as a request or macro line.
|
||||
Execute the rest of the input line as a request or macro line.
|
||||
Currently unsupported.
|
||||
.Ss \&nr
|
||||
Define or change a register.
|
||||
@ -1579,7 +1584,7 @@ Set tab stops.
|
||||
Takes an arbitrary number of arguments.
|
||||
Currently unsupported.
|
||||
.Ss \&tc
|
||||
Change tab repetion character.
|
||||
Change tab repetition character.
|
||||
Currently unsupported.
|
||||
.Ss \&TE
|
||||
End a table context.
|
||||
@ -1679,7 +1684,7 @@ Notify on change of string or macro.
|
||||
This is a Heirloom extension and currently ignored.
|
||||
.Ss \&watchlength
|
||||
On change, report the contents of macros and strings
|
||||
up to the sepcified length.
|
||||
up to the specified length.
|
||||
This is a Heirloom extension and currently ignored.
|
||||
.Ss \&watchn
|
||||
Notify on change of register.
|
||||
@ -1774,7 +1779,7 @@ minimum (not available in C)
|
||||
maximum (not available in C)
|
||||
.El
|
||||
.Pp
|
||||
There is no concept of precendence; evaluation proceeds from left to right,
|
||||
There is no concept of precedence; evaluation proceeds from left to right,
|
||||
except when subexpressions are enclosed in parantheses.
|
||||
Inside parentheses, whitespace is ignored.
|
||||
.Sh ESCAPE SEQUENCE REFERENCE
|
||||
@ -1834,9 +1839,15 @@ For short names, there are variants
|
||||
.No \e* Ns Ar c
|
||||
and
|
||||
.No \e*( Ns Ar cc .
|
||||
.Ss \e,
|
||||
Left italic correction (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \e-
|
||||
Special character
|
||||
.Dq mathematical minus sign .
|
||||
.Ss \e/
|
||||
Right italic correction (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \e[ Ns Ar name ]
|
||||
.Sx Special Characters
|
||||
with names of arbitrary length, see
|
||||
@ -2028,10 +2039,7 @@ Print
|
||||
with zero width and height; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ez
|
||||
Output the next character without advancing the cursor position;
|
||||
approximated in
|
||||
.Xr mandoc 1
|
||||
by simply skipping the next character.
|
||||
Output the next character without advancing the cursor position.
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Xr mandoc 1
|
||||
|
164
roff.h
Normal file
164
roff.h
Normal file
@ -0,0 +1,164 @@
|
||||
/* $OpenBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
struct mdoc_arg;
|
||||
union mdoc_data;
|
||||
|
||||
enum roff_macroset {
|
||||
MACROSET_NONE = 0,
|
||||
MACROSET_MDOC,
|
||||
MACROSET_MAN
|
||||
};
|
||||
|
||||
enum roff_sec {
|
||||
SEC_NONE = 0,
|
||||
SEC_NAME,
|
||||
SEC_LIBRARY,
|
||||
SEC_SYNOPSIS,
|
||||
SEC_DESCRIPTION,
|
||||
SEC_CONTEXT,
|
||||
SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */
|
||||
SEC_RETURN_VALUES,
|
||||
SEC_ENVIRONMENT,
|
||||
SEC_FILES,
|
||||
SEC_EXIT_STATUS,
|
||||
SEC_EXAMPLES,
|
||||
SEC_DIAGNOSTICS,
|
||||
SEC_COMPATIBILITY,
|
||||
SEC_ERRORS,
|
||||
SEC_SEE_ALSO,
|
||||
SEC_STANDARDS,
|
||||
SEC_HISTORY,
|
||||
SEC_AUTHORS,
|
||||
SEC_CAVEATS,
|
||||
SEC_BUGS,
|
||||
SEC_SECURITY,
|
||||
SEC_CUSTOM,
|
||||
SEC__MAX
|
||||
};
|
||||
|
||||
enum roff_type {
|
||||
ROFFT_ROOT,
|
||||
ROFFT_BLOCK,
|
||||
ROFFT_HEAD,
|
||||
ROFFT_BODY,
|
||||
ROFFT_TAIL,
|
||||
ROFFT_ELEM,
|
||||
ROFFT_TEXT,
|
||||
ROFFT_TBL,
|
||||
ROFFT_EQN
|
||||
};
|
||||
|
||||
enum roff_next {
|
||||
ROFF_NEXT_SIBLING = 0,
|
||||
ROFF_NEXT_CHILD
|
||||
};
|
||||
|
||||
/*
|
||||
* Indicates that a BODY's formatting has ended, but
|
||||
* the scope is still open. Used for badly nested blocks.
|
||||
*/
|
||||
enum mdoc_endbody {
|
||||
ENDBODY_NOT = 0,
|
||||
ENDBODY_SPACE, /* Is broken: append a space. */
|
||||
ENDBODY_NOSPACE /* Is broken: don't append a space. */
|
||||
};
|
||||
|
||||
struct roff_node {
|
||||
struct roff_node *parent; /* Parent AST node. */
|
||||
struct roff_node *child; /* First child AST node. */
|
||||
struct roff_node *last; /* Last child AST node. */
|
||||
struct roff_node *next; /* Sibling AST node. */
|
||||
struct roff_node *prev; /* Prior sibling AST node. */
|
||||
struct roff_node *head; /* BLOCK */
|
||||
struct roff_node *body; /* BLOCK/ENDBODY */
|
||||
struct roff_node *tail; /* BLOCK */
|
||||
struct mdoc_arg *args; /* BLOCK/ELEM */
|
||||
union mdoc_data *norm; /* Normalized arguments. */
|
||||
char *string; /* TEXT */
|
||||
const struct tbl_span *span; /* TBL */
|
||||
const struct eqn *eqn; /* EQN */
|
||||
int line; /* Input file line number. */
|
||||
int pos; /* Input file column number. */
|
||||
int tok; /* Request or macro ID. */
|
||||
#define TOKEN_NONE (-1) /* No request or macro. */
|
||||
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)
|
||||
#define MAN_VALID MDOC_VALID
|
||||
#define MAN_EOS MDOC_EOS
|
||||
#define MAN_LINE MDOC_LINE
|
||||
int prev_font; /* Before entering this node. */
|
||||
int aux; /* Decoded node data, type-dependent. */
|
||||
enum roff_type type; /* AST node type. */
|
||||
enum roff_sec sec; /* Current named section. */
|
||||
enum mdoc_endbody end; /* BODY */
|
||||
};
|
||||
|
||||
struct roff_meta {
|
||||
char *msec; /* Manual section, usually a digit. */
|
||||
char *vol; /* Manual volume title. */
|
||||
char *os; /* Operating system. */
|
||||
char *arch; /* Machine architecture. */
|
||||
char *title; /* Manual title, usually CAPS. */
|
||||
char *name; /* Leading manual name. */
|
||||
char *date; /* Normalized date. */
|
||||
int hasbody; /* Document is not empty. */
|
||||
};
|
||||
|
||||
struct roff_man {
|
||||
struct roff_meta meta; /* Document meta-data. */
|
||||
struct mparse *parse; /* Parse pointer. */
|
||||
struct roff *roff; /* Roff parser state data. */
|
||||
const char *defos; /* Default operating system. */
|
||||
struct roff_node *first; /* The first node parsed. */
|
||||
struct roff_node *last; /* The last node parsed. */
|
||||
struct roff_node *last_es; /* The most recent Es node. */
|
||||
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_PHRASE (1 << 4) /* In a Bl -column phrase. */
|
||||
#define MDOC_PHRASELIT (1 << 5) /* Literal within a 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. */
|
||||
#define MAN_ELINE (1 << 11) /* Next-line element scope. */
|
||||
#define MAN_BLINE (1 << 12) /* Next-line block scope. */
|
||||
#define MDOC_PHRASEQF (1 << 13) /* Quote first word encountered. */
|
||||
#define MDOC_PHRASEQL (1 << 14) /* Quote last word of this phrase. */
|
||||
#define MDOC_PHRASEQN (1 << 15) /* Quote first word of the next phrase. */
|
||||
#define MAN_LITERAL MDOC_LITERAL
|
||||
#define MAN_NEWLINE MDOC_NEWLINE
|
||||
enum roff_macroset macroset; /* Kind of high-level macros used. */
|
||||
enum roff_sec lastsec; /* Last section seen. */
|
||||
enum roff_sec lastnamed; /* Last standard section seen. */
|
||||
enum roff_next next; /* Where to put the next node. */
|
||||
};
|
||||
|
||||
|
||||
void deroff(char **, const struct roff_node *);
|
41
roff_int.h
Normal file
41
roff_int.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* $Id: roff_int.h,v 1.7 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
struct roff_node *roff_node_alloc(struct roff_man *, int, int,
|
||||
enum roff_type, int);
|
||||
void roff_node_append(struct roff_man *, struct roff_node *);
|
||||
void roff_word_alloc(struct roff_man *, int, int, const char *);
|
||||
void roff_word_append(struct roff_man *, const char *);
|
||||
void roff_elem_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *roff_block_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *roff_head_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *roff_body_alloc(struct roff_man *, int, int, int);
|
||||
void roff_addeqn(struct roff_man *, const struct eqn *);
|
||||
void roff_addtbl(struct roff_man *, const struct tbl_span *);
|
||||
void roff_node_unlink(struct roff_man *, struct roff_node *);
|
||||
void roff_node_free(struct roff_node *);
|
||||
void roff_node_delete(struct roff_man *, struct roff_node *);
|
||||
|
||||
/*
|
||||
* Functions called from roff.c need to be declared here,
|
||||
* not in libmdoc.h or libman.h, even if they are specific
|
||||
* to either the mdoc(7) or the man(7) parser.
|
||||
*/
|
||||
|
||||
void man_breakscope(struct roff_man *, int);
|
||||
void mdoc_argv_free(struct mdoc_arg *);
|
86
soelim.1
Normal file
86
soelim.1
Normal file
@ -0,0 +1,86 @@
|
||||
.\" $Id: soelim.1,v 1.3 2015/05/20 22:59:12 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.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 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 AUTHOR 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.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 20 2015 $
|
||||
.Dt SOELIM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm soelim
|
||||
.Nd interpret .so requests in manpages
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Crtv
|
||||
.Op Fl I Ar dir
|
||||
.Op Ar files ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
reads
|
||||
.Ar files
|
||||
lines by lines.
|
||||
.Pp
|
||||
If a line starts by:
|
||||
.Dq .so anotherfile
|
||||
it replace the line by processing
|
||||
.Dq anotherfile .
|
||||
Otherwise the line is printed to stdout.
|
||||
.Bl -tag -width "-I dir"
|
||||
.It Fl C
|
||||
Recognise
|
||||
.Em .so
|
||||
when not followed by a space character.
|
||||
.It Fl r
|
||||
Compatibility with GNU groff's
|
||||
.Xr soelim 1
|
||||
(does nothing).
|
||||
.It Fl t
|
||||
Compatibility with GNU groff's
|
||||
.Xr soelim 1
|
||||
(does nothing).
|
||||
.It Fl v
|
||||
Compatibility with GNU groff's
|
||||
.Xr soelim 1
|
||||
(does nothing).
|
||||
.It Fl I Ar dir
|
||||
This option specify directories where
|
||||
.Nm
|
||||
searches for files (both those on the command line and those named in
|
||||
.Dq .so
|
||||
directive.)
|
||||
This options may be specified multiple times. The directories will be searched
|
||||
in the order specified.
|
||||
.El
|
||||
.Pp
|
||||
The files are always searched first in the current directory.
|
||||
.Pp
|
||||
A file specified with an absolute path will be opened directly without
|
||||
performing a search.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1
|
||||
.Sh AUTHORS
|
||||
This version of the
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Baptiste Daroussin Aq Mt bapt@freebsd.org .
|
182
soelim.c
Normal file
182
soelim.c
Normal file
@ -0,0 +1,182 @@
|
||||
/* $Id: soelim.c,v 1.5 2015/11/07 14:22:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.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
|
||||
* in this position and unchanged.
|
||||
* 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(S) ``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(S) 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 "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if HAVE_STRINGLIST
|
||||
#include <stringlist.h>
|
||||
#else
|
||||
#include "compat_stringlist.h"
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
#define C_OPTION 0x1
|
||||
|
||||
static StringList *includes;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static FILE *
|
||||
soelim_fopen(const char *name)
|
||||
{
|
||||
FILE *f;
|
||||
char path[PATH_MAX];
|
||||
size_t i;
|
||||
|
||||
if (strcmp(name, "-") == 0)
|
||||
return (stdin);
|
||||
|
||||
if ((f = fopen(name, "r")) != NULL)
|
||||
return (f);
|
||||
|
||||
if (*name == '/') {
|
||||
warn("can't open '%s'", name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < includes->sl_cur; i++) {
|
||||
snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i],
|
||||
name);
|
||||
if ((f = fopen(path, "r")) != NULL)
|
||||
return (f);
|
||||
}
|
||||
|
||||
warn("can't open '%s'", name);
|
||||
|
||||
return (f);
|
||||
}
|
||||
|
||||
static int
|
||||
soelim_file(FILE *f, int flag)
|
||||
{
|
||||
char *line = NULL;
|
||||
char *walk, *cp;
|
||||
size_t linecap = 0;
|
||||
ssize_t linelen;
|
||||
|
||||
if (f == NULL)
|
||||
return (1);
|
||||
|
||||
while ((linelen = getline(&line, &linecap, f)) > 0) {
|
||||
if (strncmp(line, ".so", 3) != 0) {
|
||||
printf("%s", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
walk = line + 3;
|
||||
if (!isspace(*walk) && ((flag & C_OPTION) == 0)) {
|
||||
printf("%s", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (isspace(*walk))
|
||||
walk++;
|
||||
|
||||
cp = walk;
|
||||
while (*cp != '\0' && !isspace(*cp))
|
||||
cp++;
|
||||
*cp = 0;
|
||||
if (cp < line + linelen)
|
||||
cp++;
|
||||
|
||||
if (*walk == '\0') {
|
||||
printf("%s", line);
|
||||
continue;
|
||||
}
|
||||
if (soelim_file(soelim_fopen(walk), flag) == 1) {
|
||||
free(line);
|
||||
return (1);
|
||||
}
|
||||
if (*cp != '\0')
|
||||
printf("%s", cp);
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, i;
|
||||
int ret = 0;
|
||||
int flags = 0;
|
||||
|
||||
includes = sl_init();
|
||||
if (includes == NULL)
|
||||
err(EXIT_FAILURE, "sl_init()");
|
||||
|
||||
while ((ch = getopt(argc, argv, "CrtvI:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'C':
|
||||
flags |= C_OPTION;
|
||||
break;
|
||||
case 'r':
|
||||
case 'v':
|
||||
case 't':
|
||||
/* stub compatibility with groff's soelim */
|
||||
break;
|
||||
case 'I':
|
||||
sl_add(includes, optarg);
|
||||
break;
|
||||
default:
|
||||
sl_free(includes, 0);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
ret = soelim_file(stdin, flags);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
ret = soelim_file(soelim_fopen(argv[i]), flags);
|
||||
|
||||
sl_free(includes, 0);
|
||||
|
||||
return (ret);
|
||||
}
|
5
st.c
5
st.c
@ -1,4 +1,4 @@
|
||||
/* $Id: st.c,v 1.11 2014/08/10 23:54:41 schwarze Exp $ */
|
||||
/* $Id: st.c,v 1.13 2015/10/06 18:32:20 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_a2st(const char *p)
|
||||
|
||||
#include "st.in"
|
||||
|
||||
return(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
192
tag.c
Normal file
192
tag.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* $Id: tag.c,v 1.11 2015/11/20 21:59:54 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 "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "tag.h"
|
||||
|
||||
struct tag_entry {
|
||||
size_t line;
|
||||
int prio;
|
||||
char s[];
|
||||
};
|
||||
|
||||
static void tag_signal(int);
|
||||
|
||||
static struct ohash tag_data;
|
||||
static struct tag_files tag_files;
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for using a pager.
|
||||
* Not all pagers are capable of using a tag file,
|
||||
* but for simplicity, create it anyway.
|
||||
*/
|
||||
struct tag_files *
|
||||
tag_init(void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
int ofd;
|
||||
|
||||
ofd = -1;
|
||||
tag_files.tfd = -1;
|
||||
tag_files.tcpgid = -1;
|
||||
|
||||
/* Save the original standard output for use by the pager. */
|
||||
|
||||
if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1)
|
||||
goto fail;
|
||||
|
||||
/* Create both temporary output files. */
|
||||
|
||||
(void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX",
|
||||
sizeof(tag_files.ofn));
|
||||
(void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
|
||||
sizeof(tag_files.tfn));
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigfillset(&sa.sa_mask);
|
||||
sa.sa_handler = tag_signal;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
if ((ofd = mkstemp(tag_files.ofn)) == -1)
|
||||
goto fail;
|
||||
if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1)
|
||||
goto fail;
|
||||
if (dup2(ofd, STDOUT_FILENO) == -1)
|
||||
goto fail;
|
||||
close(ofd);
|
||||
|
||||
/*
|
||||
* Set up the ohash table to collect output line numbers
|
||||
* where various marked-up terms are documented.
|
||||
*/
|
||||
|
||||
mandoc_ohash_init(&tag_data, 4, offsetof(struct tag_entry, s));
|
||||
return &tag_files;
|
||||
|
||||
fail:
|
||||
tag_unlink();
|
||||
if (ofd != -1)
|
||||
close(ofd);
|
||||
if (tag_files.ofd != -1)
|
||||
close(tag_files.ofd);
|
||||
if (tag_files.tfd != -1)
|
||||
close(tag_files.tfd);
|
||||
*tag_files.ofn = '\0';
|
||||
*tag_files.tfn = '\0';
|
||||
tag_files.ofd = -1;
|
||||
tag_files.tfd = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the line number where a term is defined,
|
||||
* unless it is already defined at a higher priority.
|
||||
*/
|
||||
void
|
||||
tag_put(const char *s, int prio, size_t line)
|
||||
{
|
||||
struct tag_entry *entry;
|
||||
size_t len;
|
||||
unsigned int slot;
|
||||
|
||||
if (tag_files.tfd <= 0 || strchr(s, ' ') != NULL)
|
||||
return;
|
||||
slot = ohash_qlookup(&tag_data, s);
|
||||
entry = ohash_find(&tag_data, slot);
|
||||
if (entry == NULL) {
|
||||
len = strlen(s) + 1;
|
||||
entry = mandoc_malloc(sizeof(*entry) + len);
|
||||
memcpy(entry->s, s, len);
|
||||
ohash_insert(&tag_data, slot, entry);
|
||||
} else if (entry->prio <= prio)
|
||||
return;
|
||||
entry->line = line;
|
||||
entry->prio = prio;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the tags file using the previously collected
|
||||
* information and clear the ohash table while going along.
|
||||
*/
|
||||
void
|
||||
tag_write(void)
|
||||
{
|
||||
FILE *stream;
|
||||
struct tag_entry *entry;
|
||||
unsigned int slot;
|
||||
|
||||
if (tag_files.tfd <= 0)
|
||||
return;
|
||||
stream = fdopen(tag_files.tfd, "w");
|
||||
entry = ohash_first(&tag_data, &slot);
|
||||
while (entry != NULL) {
|
||||
if (stream != NULL)
|
||||
fprintf(stream, "%s %s %zu\n",
|
||||
entry->s, tag_files.ofn, entry->line);
|
||||
free(entry);
|
||||
entry = ohash_next(&tag_data, &slot);
|
||||
}
|
||||
ohash_delete(&tag_data);
|
||||
if (stream != NULL)
|
||||
fclose(stream);
|
||||
}
|
||||
|
||||
void
|
||||
tag_unlink(void)
|
||||
{
|
||||
pid_t tc_pgid;
|
||||
|
||||
if (tag_files.tcpgid != -1) {
|
||||
tc_pgid = tcgetpgrp(STDIN_FILENO);
|
||||
if (tc_pgid == tag_files.pager_pid ||
|
||||
tc_pgid == getpgid(0) ||
|
||||
getpgid(tc_pgid) == -1)
|
||||
(void)tcsetpgrp(STDIN_FILENO, tag_files.tcpgid);
|
||||
}
|
||||
if (*tag_files.ofn != '\0')
|
||||
unlink(tag_files.ofn);
|
||||
if (*tag_files.tfn != '\0')
|
||||
unlink(tag_files.tfn);
|
||||
}
|
||||
|
||||
static void
|
||||
tag_signal(int signum)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
tag_unlink();
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction(signum, &sa, NULL);
|
||||
kill(getpid(), signum);
|
||||
/* NOTREACHED */
|
||||
_exit(1);
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
/* $Id: manpath.h,v 1.7 2014/12/01 04:05:32 schwarze Exp $ */
|
||||
/* $Id: tag.h,v 1.7 2015/11/20 21:59:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 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
|
||||
@ -16,19 +15,17 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unsorted list of unique, absolute paths to be searched for manual
|
||||
* databases.
|
||||
*/
|
||||
struct manpaths {
|
||||
size_t sz;
|
||||
char **paths;
|
||||
struct tag_files {
|
||||
char ofn[20];
|
||||
char tfn[20];
|
||||
int ofd;
|
||||
int tfd;
|
||||
pid_t tcpgid;
|
||||
pid_t pager_pid;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void manpath_manconf(struct manpaths *, const char *);
|
||||
void manpath_parse(struct manpaths *, const char *, char *, char *);
|
||||
void manpath_free(struct manpaths *);
|
||||
|
||||
__END_DECLS
|
||||
struct tag_files *tag_init(void);
|
||||
void tag_put(const char *, int, size_t);
|
||||
void tag_write(void);
|
||||
void tag_unlink(void);
|
18
tbl.c
18
tbl.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl.c,v 1.39 2015/01/30 17:32:16 schwarze Exp $ */
|
||||
/* $Id: tbl.c,v 1.40 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -66,7 +66,7 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
if (*cp == ';') {
|
||||
tbl_option(tbl, ln, p, &pos);
|
||||
if (p[pos] == '\0')
|
||||
return(ROFF_IGN);
|
||||
return ROFF_IGN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,15 +75,15 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
switch (tbl->part) {
|
||||
case TBL_PART_LAYOUT:
|
||||
tbl_layout(tbl, ln, p, pos);
|
||||
return(ROFF_IGN);
|
||||
return ROFF_IGN;
|
||||
case TBL_PART_CDATA:
|
||||
return(tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN);
|
||||
return tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tbl_data(tbl, ln, p, pos);
|
||||
return(ROFF_TBL);
|
||||
return ROFF_TBL;
|
||||
}
|
||||
|
||||
struct tbl_node *
|
||||
@ -98,7 +98,7 @@ tbl_alloc(int pos, int line, struct mparse *parse)
|
||||
tbl->part = TBL_PART_OPTS;
|
||||
tbl->opts.tab = '\t';
|
||||
tbl->opts.decimal = '.';
|
||||
return(tbl);
|
||||
return tbl;
|
||||
}
|
||||
|
||||
void
|
||||
@ -155,7 +155,7 @@ tbl_span(struct tbl_node *tbl)
|
||||
: tbl->first_span;
|
||||
if (span)
|
||||
tbl->current_span = span;
|
||||
return(span);
|
||||
return span;
|
||||
}
|
||||
|
||||
int
|
||||
@ -177,7 +177,7 @@ tbl_end(struct tbl_node **tblp)
|
||||
if (sp == NULL) {
|
||||
mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->parse,
|
||||
tbl->line, tbl->pos, NULL);
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
|
13
tbl_data.c
13
tbl_data.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_data.c,v 1.39 2015/01/30 17:32:16 schwarze Exp $ */
|
||||
/* $Id: tbl_data.c,v 1.41 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -132,11 +132,12 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
if (p[pos] == tbl->opts.tab) {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
pos++;
|
||||
getdata(tbl, tbl->last_span, ln, p, &pos);
|
||||
return(1);
|
||||
while (p[pos] != '\0')
|
||||
getdata(tbl, tbl->last_span, ln, p, &pos);
|
||||
return 1;
|
||||
} else if (p[pos] == '\0') {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Fallthrough: T} is part of a word. */
|
||||
@ -156,7 +157,7 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
mandoc_msg(MANDOCERR_TBLDATA_SPAN, tbl->parse,
|
||||
ln, pos, dat->string);
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct tbl_span *
|
||||
@ -177,7 +178,7 @@ newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
|
||||
dp->prev->next = dp;
|
||||
tbl->last_span = dp;
|
||||
|
||||
return(dp);
|
||||
return dp;
|
||||
}
|
||||
|
||||
void
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user