mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-27 00:33:30 +00:00
Import mandoc cvs snapshot 20170121 (pre 1.14)
This commit is contained in:
parent
05798824d2
commit
ef7476572c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/mdocml/dist/; revision=312591 svn path=/vendor/mdocml/20170121/; revision=312592; tag=vendor/mandoc/20170121
40
INSTALL
40
INSTALL
@ -1,4 +1,4 @@
|
||||
$Id: INSTALL,v 1.15 2016/07/14 11:09:06 schwarze Exp $
|
||||
$Id: INSTALL,v 1.17 2016/07/19 22:40:33 schwarze Exp $
|
||||
|
||||
About mdocml, the portable mandoc distribution
|
||||
----------------------------------------------
|
||||
@ -35,7 +35,11 @@ To install mandoc manually, the following steps are needed:
|
||||
command "echo BUILD_CGI=1 > configure.local". Then run "cp
|
||||
cgi.h.examples cgi.h" and edit cgi.h as desired.
|
||||
|
||||
2. Run "./configure".
|
||||
2. Define MANPATH_DEFAULT in configure.local
|
||||
if /usr/share/man:/usr/X11R6/man:/usr/local/man is not appropriate
|
||||
for your operating system.
|
||||
|
||||
3. Run "./configure".
|
||||
This script attempts autoconfiguration of mandoc for your system.
|
||||
Read both its standard output and the file "Makefile.local" it
|
||||
generates. If anything looks wrong or different from what you
|
||||
@ -45,28 +49,21 @@ 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".
|
||||
4. Run "make".
|
||||
Any POSIX-compatible make, in particular both BSD make and GNU make,
|
||||
should work. If the build fails, look at "configure.local.example"
|
||||
and go back to step 2.
|
||||
|
||||
4. Run "make -n install" and check whether everything will be
|
||||
5. Run "make -n install" and check whether everything will be
|
||||
installed to the intended places. Otherwise, put some *DIR or *NM*
|
||||
variables into "configure.local" and go back to step 2.
|
||||
variables into "configure.local" and go back to step 3.
|
||||
|
||||
5. Run "sudo make install". If you intend to build a binary
|
||||
6. Run "sudo make install". If you intend to build a binary
|
||||
package using some kind of fake root mechanism, you may need a
|
||||
command like "make DESTDIR=... install". Read the *-install targets
|
||||
in the "Makefile" to understand how DESTDIR is used.
|
||||
|
||||
6. If you want to use the integrated man(1) and your system uses
|
||||
manpath(1), make sure it is configured correctly, in particular,
|
||||
it returns all directory trees where manual pages are installed.
|
||||
Otherwise, if your system uses man.conf(5), make sure it contains
|
||||
a "manpath" line for each directory tree, and the order of these
|
||||
lines meets your wishes.
|
||||
|
||||
7. If you compiled with database support, run the command "sudo
|
||||
7. Run the command "sudo
|
||||
makewhatis" to build mandoc.db(5) databases in all the directory
|
||||
trees configured in step 6. Whenever installing new manual pages,
|
||||
re-run makewhatis(8) to update the databases, or apropos(1) will
|
||||
@ -84,20 +81,9 @@ manual page source.
|
||||
|
||||
Understanding mandoc dependencies
|
||||
---------------------------------
|
||||
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:
|
||||
The following libraries are required:
|
||||
|
||||
1. The SQLite database system, see <http://sqlite.org/>.
|
||||
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
|
||||
toolset is known to work with version 3.7.5 or newer. Versions
|
||||
older than 3.8.3 may not achieve full performance due to the
|
||||
missing SQLITE_DETERMINISTIC optimization flag. Versions older
|
||||
than 3.8.0 may not show full error information if opening a database
|
||||
fails due to the missing sqlite3_errstr() API. Both are very minor
|
||||
problems, apropos(1) is fully usable with SQLite 3.7.5. Versions
|
||||
older than 3.7.5 may or may not work, they have not been tested.
|
||||
1. zlib for decompressing gzipped manual pages.
|
||||
|
||||
2. The fts(3) directory traversion functions.
|
||||
If your system does not have them, the bundled compatibility version
|
||||
|
7
LICENSE
7
LICENSE
@ -1,4 +1,4 @@
|
||||
$Id: LICENSE,v 1.12 2016/07/07 23:46:36 schwarze Exp $
|
||||
$Id: LICENSE,v 1.13 2016/10/18 14:15:33 schwarze Exp $
|
||||
|
||||
With the exceptions noted below, all code and documentation
|
||||
contained in the mdocml toolkit is protected by the Copyright
|
||||
@ -8,7 +8,8 @@ Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
Copyright (c) 2010-2016 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) 2014 Baptiste Daroussin <bapt@freebsd.org>
|
||||
Copyright (c) 2016 Ed Maste <emaste@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>
|
||||
@ -41,7 +42,7 @@ other people's Copyright and are distributed under various 2-clause
|
||||
and 3-clause BSD licenses; see these individual files for details.
|
||||
|
||||
soelim.c, soelim.1:
|
||||
Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
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,
|
||||
|
104
Makefile
104
Makefile
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.488 2016/07/12 05:18:38 kristaps Exp $
|
||||
# $Id: Makefile,v 1.493 2016/11/19 15:24:51 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
# Copyright (c) 2011, 2013-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,27 +15,29 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
VERSION = 1.13.4
|
||||
VERSION = 1.14.0
|
||||
|
||||
# === LIST OF FILES ====================================================
|
||||
|
||||
TESTSRCS = test-dirent-namlen.c \
|
||||
TESTSRCS = test-be32toh.c \
|
||||
test-dirent-namlen.c \
|
||||
test-EFTYPE.c \
|
||||
test-err.c \
|
||||
test-fts.c \
|
||||
test-getline.c \
|
||||
test-getsubopt.c \
|
||||
test-isblank.c \
|
||||
test-mkdtemp.c \
|
||||
test-mmap.c \
|
||||
test-nanosleep.c \
|
||||
test-ntohl.c \
|
||||
test-ohash.c \
|
||||
test-PATH_MAX.c \
|
||||
test-pledge.c \
|
||||
test-progname.c \
|
||||
test-reallocarray.c \
|
||||
test-rewb-bsd.c \
|
||||
test-rewb-sysv.c \
|
||||
test-sandbox_init.c \
|
||||
test-sqlite3.c \
|
||||
test-sqlite3_errstr.c \
|
||||
test-strcasestr.c \
|
||||
test-stringlist.c \
|
||||
test-strlcat.c \
|
||||
@ -58,7 +60,6 @@ SRCS = att.c \
|
||||
compat_ohash.c \
|
||||
compat_progname.c \
|
||||
compat_reallocarray.c \
|
||||
compat_sqlite3_errstr.c \
|
||||
compat_strcasestr.c \
|
||||
compat_stringlist.c \
|
||||
compat_strlcat.c \
|
||||
@ -66,6 +67,12 @@ SRCS = att.c \
|
||||
compat_strsep.c \
|
||||
compat_strtonum.c \
|
||||
compat_vasprintf.c \
|
||||
dba.c \
|
||||
dba_array.c \
|
||||
dba_read.c \
|
||||
dba_write.c \
|
||||
dbm.c \
|
||||
dbm_map.c \
|
||||
demandoc.c \
|
||||
eqn.c \
|
||||
eqn_html.c \
|
||||
@ -86,7 +93,6 @@ SRCS = att.c \
|
||||
manpage.c \
|
||||
manpath.c \
|
||||
mansearch.c \
|
||||
mansearch_const.c \
|
||||
mdoc.c \
|
||||
mdoc_argv.c \
|
||||
mdoc_hash.c \
|
||||
@ -128,6 +134,11 @@ DISTFILES = INSTALL \
|
||||
compat_stringlist.h \
|
||||
configure \
|
||||
configure.local.example \
|
||||
dba.h \
|
||||
dba_array.h \
|
||||
dba_write.h \
|
||||
dbm.h \
|
||||
dbm_map.h \
|
||||
demandoc.1 \
|
||||
eqn.7 \
|
||||
gmdiff \
|
||||
@ -220,7 +231,6 @@ COMPAT_OBJS = compat_err.o \
|
||||
compat_ohash.o \
|
||||
compat_progname.o \
|
||||
compat_reallocarray.o \
|
||||
compat_sqlite3_errstr.o \
|
||||
compat_strcasestr.o \
|
||||
compat_strlcat.o \
|
||||
compat_strlcpy.o \
|
||||
@ -244,28 +254,35 @@ MANDOC_TERM_OBJS = eqn_term.o \
|
||||
term_ps.o \
|
||||
tbl_term.o
|
||||
|
||||
BASE_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
DBM_OBJS = dbm.o \
|
||||
dbm_map.o \
|
||||
mansearch.o
|
||||
|
||||
DBA_OBJS = dba.o \
|
||||
dba_array.o \
|
||||
dba_read.o \
|
||||
dba_write.o \
|
||||
mandocdb.o
|
||||
|
||||
MAIN_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
$(MANDOC_MAN_OBJS) \
|
||||
$(MANDOC_TERM_OBJS) \
|
||||
$(DBM_OBJS) \
|
||||
$(DBA_OBJS) \
|
||||
main.o \
|
||||
manpath.o \
|
||||
out.o \
|
||||
tag.o \
|
||||
tree.o
|
||||
|
||||
MAIN_OBJS = $(BASE_OBJS)
|
||||
|
||||
DB_OBJS = mandocdb.o \
|
||||
mansearch.o \
|
||||
mansearch_const.o
|
||||
|
||||
CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
$(DBM_OBJS) \
|
||||
cgi.o \
|
||||
mansearch.o \
|
||||
mansearch_const.o \
|
||||
out.o
|
||||
|
||||
MANPAGE_OBJS = manpage.o mansearch.o mansearch_const.o manpath.o
|
||||
MANPAGE_OBJS = $(DBM_OBJS) \
|
||||
manpage.o \
|
||||
manpath.o
|
||||
|
||||
DEMANDOC_OBJS = demandoc.o
|
||||
|
||||
@ -329,7 +346,7 @@ www: $(WWW_OBJS) $(WWW_MANS)
|
||||
|
||||
$(WWW_MANS): mandoc
|
||||
|
||||
.PHONY: base-install cgi-install db-install install www-install
|
||||
.PHONY: base-install cgi-install install www-install
|
||||
.PHONY: clean distclean depend
|
||||
|
||||
include Makefile.depend
|
||||
@ -341,7 +358,7 @@ distclean: clean
|
||||
|
||||
clean:
|
||||
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS)
|
||||
rm -f mandoc $(BASE_OBJS) $(DB_OBJS)
|
||||
rm -f mandoc $(MAIN_OBJS)
|
||||
rm -f man.cgi $(CGI_OBJS)
|
||||
rm -f manpage $(MANPAGE_OBJS)
|
||||
rm -f demandoc $(DEMANDOC_OBJS)
|
||||
@ -351,50 +368,45 @@ clean:
|
||||
|
||||
base-install: base-build
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(LIBDIR)
|
||||
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man7
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
$(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 roff.h \
|
||||
$(DESTDIR)$(INCLUDEDIR)
|
||||
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS)
|
||||
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS)
|
||||
ln -f $(DESTDIR)$(BINDIR)/mandoc \
|
||||
$(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS)
|
||||
$(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) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1
|
||||
ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \
|
||||
$(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1
|
||||
$(INSTALL_MAN) man.conf.5 $(DESTDIR)$(MANDIR)/man5/${MANM_MANCONF}.5
|
||||
$(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5
|
||||
$(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
|
||||
|
||||
db-install: base-build
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS)
|
||||
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS)
|
||||
ln -f $(DESTDIR)$(BINDIR)/mandoc \
|
||||
$(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS)
|
||||
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1
|
||||
ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \
|
||||
$(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1
|
||||
$(INSTALL_MAN) mansearch.3 $(DESTDIR)$(MANDIR)/man3
|
||||
$(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5
|
||||
$(INSTALL_MAN) makewhatis.8 \
|
||||
$(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8
|
||||
|
||||
lib-install: base-build
|
||||
mkdir -p $(DESTDIR)$(LIBDIR)
|
||||
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h roff.h \
|
||||
$(DESTDIR)$(INCLUDEDIR)
|
||||
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
|
||||
mansearch.3 mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
|
||||
|
||||
cgi-install: cgi-build
|
||||
mkdir -p $(DESTDIR)$(CGIBINDIR)
|
||||
mkdir -p $(DESTDIR)$(HTDOCDIR)
|
||||
|
@ -10,7 +10,6 @@ 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
|
||||
@ -18,6 +17,12 @@ compat_strlcpy.o: compat_strlcpy.c config.h
|
||||
compat_strsep.o: compat_strsep.c config.h
|
||||
compat_strtonum.o: compat_strtonum.c config.h
|
||||
compat_vasprintf.o: compat_vasprintf.c config.h
|
||||
dba.o: dba.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mansearch.h dba_write.h dba_array.h dba.h
|
||||
dba_array.o: dba_array.c mandoc_aux.h dba_write.h dba_array.h
|
||||
dba_read.o: dba_read.c mandoc_aux.h mansearch.h dba_array.h dba.h dbm.h
|
||||
dba_write.o: dba_write.c config.h dba_write.h
|
||||
dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h
|
||||
dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h
|
||||
demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.h
|
||||
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
|
||||
@ -26,7 +31,7 @@ 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_hash.o: man_hash.c config.h mandoc.h roff.h man.h libmandoc.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
|
||||
@ -34,14 +39,13 @@ man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libma
|
||||
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
|
||||
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
|
||||
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h dba_array.h dba.h
|
||||
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
|
||||
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
|
||||
mdoc_hash.o: mdoc_hash.c config.h roff.h mdoc.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_hash.o: mdoc_hash.c config.h mandoc.h roff.h mdoc.h libmandoc.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
|
||||
|
41
TODO
41
TODO
@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.218 2016/06/05 21:06:04 schwarze Exp $
|
||||
* $Id: TODO,v 1.223 2017/01/17 15:32:43 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@ -32,15 +32,6 @@ Many issues are annotated for difficulty as follows:
|
||||
Obviously, as the issues have not been solved yet, these annotations
|
||||
are mere guesses, and some may be wrong.
|
||||
|
||||
************************************************************************
|
||||
* crashes
|
||||
************************************************************************
|
||||
|
||||
- The abort() in bufcat(), html.c, can be triggered via buffmt_includes()
|
||||
by running -Thtml -Oincludes on a file containing a long .In argument.
|
||||
Fixing this will probably require reworking the whole bufcat() concept.
|
||||
loc ** exist * algo * size ** imp **
|
||||
|
||||
************************************************************************
|
||||
* missing features
|
||||
************************************************************************
|
||||
@ -213,6 +204,13 @@ are mere guesses, and some may be wrong.
|
||||
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
|
||||
loc ** exist ** algo ** size ** imp ***
|
||||
|
||||
- break long text into lines inside cells
|
||||
net/lftp(1) from jirib via bentley@ Sep 13, 2016
|
||||
|
||||
- layout l1 for a column of max text width 3 reduces the following
|
||||
inter-column spacing for groff, but not for mandoc
|
||||
net/lftp(1) from jirib via bentley@ Sep 13, 2016
|
||||
|
||||
- the "w" layout option is ignored
|
||||
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
|
||||
loc * exist * algo * size * imp **
|
||||
@ -528,16 +526,6 @@ 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
|
||||
************************************************************************
|
||||
@ -612,7 +600,6 @@ are mere guesses, and some may be wrong.
|
||||
************************************************************************
|
||||
|
||||
- Why are we using MAP_SHARED, not MAP_PRIVATE for mmap(2)?
|
||||
How does SQLITE_CONFIG_PAGECACHE actually work? Document it!
|
||||
from kristaps@ Sat, 09 Aug 2014 13:51:36 +0200
|
||||
|
||||
Several areas can be cleaned up to make mandoc even faster. These are
|
||||
@ -631,6 +618,13 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
||||
* structural issues
|
||||
************************************************************************
|
||||
|
||||
- POSIX says in the documentation of sysconf(3) that PATH_MAX
|
||||
is allowed to be so large that it is a bad idea to use it
|
||||
for sizing static buffers. So use dynamic buffers throughout.
|
||||
See the file test-PATH_MAX.c for details.
|
||||
Found by Aaron M. Ucko in the GNU Hurd via Bdale Garbee,
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=829624
|
||||
|
||||
- We use the input line number at several places to distinguish
|
||||
same-line from different-line input. That plainly doesn't work
|
||||
with user-defined macros, leading to random breakage.
|
||||
@ -646,11 +640,6 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
||||
- struct mparse refactoring
|
||||
Steffen Nurpmeso Thu, 04 Sep 2014 12:50:00 +0200
|
||||
|
||||
- Consider creating some views that will make the database more
|
||||
readable from the sqlite3 shell. Consider using them to
|
||||
abstract from the database structure, too.
|
||||
suggested by espie@ Sat, 19 Apr 2014 14:52:57 +0200
|
||||
|
||||
************************************************************************
|
||||
* CGI issues
|
||||
************************************************************************
|
||||
|
107
cgi.c
107
cgi.c
@ -1,7 +1,7 @@
|
||||
/* $Id: cgi.c,v 1.135 2016/07/11 22:48:37 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.144 2017/01/21 01:20:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@usta.de>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 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
|
||||
@ -113,17 +113,18 @@ static const char *const sec_names[] = {
|
||||
static const int sec_MAX = sizeof(sec_names) / sizeof(char *);
|
||||
|
||||
static const char *const arch_names[] = {
|
||||
"amd64", "alpha", "armish", "armv7",
|
||||
"hppa", "hppa64", "i386", "landisk",
|
||||
"amd64", "alpha", "armv7",
|
||||
"hppa", "i386", "landisk",
|
||||
"loongson", "luna88k", "macppc", "mips64",
|
||||
"octeon", "sgi", "socppc", "sparc",
|
||||
"sparc64", "zaurus",
|
||||
"amiga", "arc", "arm32", "atari",
|
||||
"aviion", "beagle", "cats", "hp300",
|
||||
"octeon", "sgi", "socppc", "sparc64",
|
||||
"amiga", "arc", "armish", "arm32",
|
||||
"atari", "aviion", "beagle", "cats",
|
||||
"hppa64", "hp300",
|
||||
"ia64", "mac68k", "mvme68k", "mvme88k",
|
||||
"mvmeppc", "palm", "pc532", "pegasos",
|
||||
"pmax", "powerpc", "solbourne", "sun3",
|
||||
"vax", "wgrisc", "x68k"
|
||||
"pmax", "powerpc", "solbourne", "sparc",
|
||||
"sun3", "vax", "wgrisc", "x68k",
|
||||
"zaurus"
|
||||
};
|
||||
static const int arch_MAX = sizeof(arch_names) / sizeof(char *);
|
||||
|
||||
@ -137,7 +138,7 @@ html_putchar(char c)
|
||||
|
||||
switch (c) {
|
||||
case ('"'):
|
||||
printf(""e;");
|
||||
printf(""");
|
||||
break;
|
||||
case ('&'):
|
||||
printf("&");
|
||||
@ -337,6 +338,7 @@ resp_copy(const char *filename)
|
||||
fflush(stdout);
|
||||
while ((sz = read(fd, buf, sizeof(buf))) > 0)
|
||||
write(STDOUT_FILENO, buf, sz);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,13 +351,12 @@ resp_begin_html(int code, const char *msg)
|
||||
printf("<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<meta charset=\"UTF-8\"/>\n"
|
||||
"<link rel=\"stylesheet\" href=\"%s/mandoc.css\""
|
||||
" <meta charset=\"UTF-8\"/>\n"
|
||||
" <link rel=\"stylesheet\" href=\"%s/mandoc.css\""
|
||||
" type=\"text/css\" media=\"all\">\n"
|
||||
"<title>%s</title>\n"
|
||||
" <title>%s</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<!-- Begin page content. //-->\n",
|
||||
"<body>\n",
|
||||
CSS_DIR, CUSTOMIZE_TITLE);
|
||||
|
||||
resp_copy(MAN_DIR "/header.html");
|
||||
@ -376,16 +377,14 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
{
|
||||
int i;
|
||||
|
||||
puts("<!-- Begin search form. //-->");
|
||||
printf("<div id=\"mancgi\">\n"
|
||||
"<form action=\"/%s\" method=\"get\">\n"
|
||||
"<fieldset>\n"
|
||||
"<legend>Manual Page Search Parameters</legend>\n",
|
||||
printf("<form action=\"/%s\" method=\"get\">\n"
|
||||
" <fieldset>\n"
|
||||
" <legend>Manual Page Search Parameters</legend>\n",
|
||||
scriptname);
|
||||
|
||||
/* Write query input box. */
|
||||
|
||||
printf("<input type=\"text\" name=\"query\" value=\"");
|
||||
printf(" <input type=\"text\" name=\"query\" value=\"");
|
||||
if (req->q.query != NULL)
|
||||
html_print(req->q.query);
|
||||
printf( "\" size=\"40\"");
|
||||
@ -395,45 +394,46 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
|
||||
/* Write submission buttons. */
|
||||
|
||||
printf( "<button type=\"submit\" name=\"apropos\" value=\"0\">"
|
||||
printf( " <button type=\"submit\" name=\"apropos\" value=\"0\">"
|
||||
"man</button>\n"
|
||||
"<button type=\"submit\" name=\"apropos\" value=\"1\">"
|
||||
"apropos</button>\n<br/>\n");
|
||||
" <button type=\"submit\" name=\"apropos\" value=\"1\">"
|
||||
"apropos</button>\n"
|
||||
" <br/>\n");
|
||||
|
||||
/* Write section selector. */
|
||||
|
||||
puts("<select name=\"sec\">");
|
||||
puts(" <select name=\"sec\">");
|
||||
for (i = 0; i < sec_MAX; i++) {
|
||||
printf("<option value=\"%s\"", sec_numbers[i]);
|
||||
printf(" <option value=\"%s\"", sec_numbers[i]);
|
||||
if (NULL != req->q.sec &&
|
||||
0 == strcmp(sec_numbers[i], req->q.sec))
|
||||
printf(" selected=\"selected\"");
|
||||
printf(">%s</option>\n", sec_names[i]);
|
||||
}
|
||||
puts("</select>");
|
||||
puts(" </select>");
|
||||
|
||||
/* Write architecture selector. */
|
||||
|
||||
printf( "<select name=\"arch\">\n"
|
||||
"<option value=\"default\"");
|
||||
printf( " <select name=\"arch\">\n"
|
||||
" <option value=\"default\"");
|
||||
if (NULL == req->q.arch)
|
||||
printf(" selected=\"selected\"");
|
||||
puts(">All Architectures</option>");
|
||||
for (i = 0; i < arch_MAX; i++) {
|
||||
printf("<option value=\"%s\"", arch_names[i]);
|
||||
printf(" <option value=\"%s\"", arch_names[i]);
|
||||
if (NULL != req->q.arch &&
|
||||
0 == strcmp(arch_names[i], req->q.arch))
|
||||
printf(" selected=\"selected\"");
|
||||
printf(">%s</option>\n", arch_names[i]);
|
||||
}
|
||||
puts("</select>");
|
||||
puts(" </select>");
|
||||
|
||||
/* Write manpath selector. */
|
||||
|
||||
if (req->psz > 1) {
|
||||
puts("<select name=\"manpath\">");
|
||||
puts(" <select name=\"manpath\">");
|
||||
for (i = 0; i < (int)req->psz; i++) {
|
||||
printf("<option ");
|
||||
printf(" <option ");
|
||||
if (strcmp(req->q.manpath, req->p[i]) == 0)
|
||||
printf("selected=\"selected\" ");
|
||||
printf("value=\"");
|
||||
@ -442,13 +442,11 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
html_print(req->p[i]);
|
||||
puts("</option>");
|
||||
}
|
||||
puts("</select>");
|
||||
puts(" </select>");
|
||||
}
|
||||
|
||||
puts("</fieldset>\n"
|
||||
"</form>\n"
|
||||
"</div>");
|
||||
puts("<!-- End search form. //-->");
|
||||
puts(" </fieldset>\n"
|
||||
"</form>");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -496,9 +494,9 @@ pg_index(const struct req *req)
|
||||
resp_searchform(req, FOCUS_QUERY);
|
||||
printf("<p>\n"
|
||||
"This web interface is documented in the\n"
|
||||
"<a href=\"/%s%sman.cgi.8\">man.cgi(8)</a>\n"
|
||||
"<a class=\"Xr\" href=\"/%s%sman.cgi.8\">man.cgi(8)</a>\n"
|
||||
"manual, and the\n"
|
||||
"<a href=\"/%s%sapropos.1\">apropos(1)</a>\n"
|
||||
"<a class=\"Xr\" href=\"/%s%sapropos.1\">apropos(1)</a>\n"
|
||||
"manual explains the query syntax.\n"
|
||||
"</p>\n",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
@ -578,27 +576,21 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
req->q.equal || sz == 1 ? FOCUS_NONE : FOCUS_QUERY);
|
||||
|
||||
if (sz > 1) {
|
||||
puts("<div class=\"results\">");
|
||||
puts("<table>");
|
||||
|
||||
puts("<table class=\"results\">");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf("<tr>\n"
|
||||
"<td class=\"title\">\n"
|
||||
"<a href=\"/%s%s%s/%s",
|
||||
printf(" <tr>\n"
|
||||
" <td>"
|
||||
"<a class=\"Xr\" href=\"/%s%s%s/%s\">",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
req->q.manpath, r[i].file);
|
||||
printf("\">");
|
||||
html_print(r[i].names);
|
||||
printf("</a>\n"
|
||||
"</td>\n"
|
||||
"<td class=\"desc\">");
|
||||
printf("</a></td>\n"
|
||||
" <td><span class=\"Nd\">");
|
||||
html_print(r[i].output);
|
||||
puts("</td>\n"
|
||||
"</tr>");
|
||||
puts("</span></td>\n"
|
||||
" </tr>");
|
||||
}
|
||||
|
||||
puts("</table>\n"
|
||||
"</div>");
|
||||
puts("</table>");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -800,7 +792,8 @@ resp_format(const struct req *req, const char *file)
|
||||
}
|
||||
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, req->q.manpath);
|
||||
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1,
|
||||
MANDOCLEVEL_BADARG, NULL, req->q.manpath);
|
||||
mparse_readfd(mp, fd, file);
|
||||
close(fd);
|
||||
|
||||
|
99
compat_fts.c
99
compat_fts.c
@ -6,8 +6,8 @@ int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $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 $ */
|
||||
/* $Id: compat_fts.c,v 1.12 2016/10/18 23:58:12 schwarze Exp $ */
|
||||
/* $OpenBSD: fts.c,v 1.56 2016/09/21 04:38:56 guenther Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
@ -59,6 +59,7 @@ static void fts_load(FTS *, FTSENT *);
|
||||
static size_t fts_maxarglen(char * const *);
|
||||
static void fts_padjust(FTS *, FTSENT *);
|
||||
static int fts_palloc(FTS *, size_t);
|
||||
static FTSENT *fts_sort(FTS *, FTSENT *, int);
|
||||
static unsigned short fts_stat(FTS *, FTSENT *);
|
||||
|
||||
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
|
||||
@ -68,19 +69,22 @@ static unsigned short fts_stat(FTS *, FTSENT *);
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#define CLR(opt) (sp->fts_options &= ~(opt))
|
||||
#define ISSET(opt) (sp->fts_options & (opt))
|
||||
#define SET(opt) (sp->fts_options |= (opt))
|
||||
|
||||
FTS *
|
||||
fts_open(char * const *argv, int options, void *dummy)
|
||||
fts_open(char * const *argv, int options,
|
||||
int (*compar)(const FTSENT **, const FTSENT **))
|
||||
{
|
||||
FTS *sp;
|
||||
FTSENT *p, *root;
|
||||
int nitems;
|
||||
FTSENT *parent, *tmp;
|
||||
size_t len;
|
||||
|
||||
/* Options check. */
|
||||
if (options & ~FTS_OPTIONMASK) {
|
||||
@ -88,9 +92,16 @@ fts_open(char * const *argv, int options, void *dummy)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* At least one path must be specified. */
|
||||
if (*argv == NULL) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Allocate/initialize the stream */
|
||||
if ((sp = calloc(1, sizeof(FTS))) == NULL)
|
||||
return (NULL);
|
||||
sp->fts_compar = compar;
|
||||
sp->fts_options = options;
|
||||
|
||||
/*
|
||||
@ -107,13 +118,7 @@ fts_open(char * const *argv, int options, void *dummy)
|
||||
|
||||
/* Allocate/initialize root(s). */
|
||||
for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
|
||||
/* Don't allow zero-length paths. */
|
||||
if ((len = strlen(*argv)) == 0) {
|
||||
errno = ENOENT;
|
||||
goto mem3;
|
||||
}
|
||||
|
||||
if ((p = fts_alloc(sp, *argv, len)) == NULL)
|
||||
if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL)
|
||||
goto mem3;
|
||||
p->fts_level = FTS_ROOTLEVEL;
|
||||
p->fts_parent = parent;
|
||||
@ -124,14 +129,25 @@ fts_open(char * const *argv, int options, void *dummy)
|
||||
if (p->fts_info == FTS_DOT)
|
||||
p->fts_info = FTS_D;
|
||||
|
||||
p->fts_link = NULL;
|
||||
if (root == NULL)
|
||||
tmp = root = p;
|
||||
else {
|
||||
tmp->fts_link = p;
|
||||
tmp = p;
|
||||
/*
|
||||
* If comparison routine supplied, traverse in sorted
|
||||
* order; otherwise traverse in the order specified.
|
||||
*/
|
||||
if (compar) {
|
||||
p->fts_link = root;
|
||||
root = p;
|
||||
} else {
|
||||
p->fts_link = NULL;
|
||||
if (root == NULL)
|
||||
tmp = root = p;
|
||||
else {
|
||||
tmp->fts_link = p;
|
||||
tmp = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compar && nitems > 1)
|
||||
root = fts_sort(sp, root, nitems);
|
||||
|
||||
/*
|
||||
* Allocate a dummy pointer and make fts_read think that we've just
|
||||
@ -201,6 +217,7 @@ fts_close(FTS *sp)
|
||||
/* Free up child linked list, sort array, path buffer, stream ptr.*/
|
||||
if (sp->fts_child)
|
||||
fts_lfree(sp->fts_child);
|
||||
free(sp->fts_array);
|
||||
free(sp->fts_path);
|
||||
free(sp);
|
||||
|
||||
@ -317,7 +334,6 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
|
||||
* semantics to fts using fts_set. An error return is allowed for similar
|
||||
* reasons.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
fts_set(FTS *sp, FTSENT *p, int instr)
|
||||
{
|
||||
@ -416,8 +432,7 @@ fts_build(FTS *sp)
|
||||
* structures already allocated.
|
||||
*/
|
||||
mem1: saved_errno = errno;
|
||||
if (p)
|
||||
free(p);
|
||||
free(p);
|
||||
fts_lfree(head);
|
||||
(void)closedir(dirp);
|
||||
cur->fts_info = FTS_ERR;
|
||||
@ -490,6 +505,10 @@ mem1: saved_errno = errno;
|
||||
cur->fts_info = FTS_DP;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Sort the entries. */
|
||||
if (sp->fts_compar && nitems > 1)
|
||||
head = fts_sort(sp, head, nitems);
|
||||
return (head);
|
||||
}
|
||||
|
||||
@ -546,6 +565,40 @@ fts_stat(FTS *sp, FTSENT *p)
|
||||
return (FTS_DEFAULT);
|
||||
}
|
||||
|
||||
static FTSENT *
|
||||
fts_sort(FTS *sp, FTSENT *head, int nitems)
|
||||
{
|
||||
FTSENT **ap, *p;
|
||||
|
||||
/*
|
||||
* Construct an array of pointers to the structures and call qsort(3).
|
||||
* Reassemble the array in the order returned by qsort. If unable to
|
||||
* sort for memory reasons, return the directory entries in their
|
||||
* current order. Allocate enough space for the current needs plus
|
||||
* 40 so don't realloc one entry at a time.
|
||||
*/
|
||||
if (nitems > sp->fts_nitems) {
|
||||
struct _ftsent **a;
|
||||
|
||||
sp->fts_nitems = nitems + 40;
|
||||
if ((a = reallocarray(sp->fts_array,
|
||||
sp->fts_nitems, sizeof(FTSENT *))) == NULL) {
|
||||
free(sp->fts_array);
|
||||
sp->fts_array = NULL;
|
||||
sp->fts_nitems = 0;
|
||||
return (head);
|
||||
}
|
||||
sp->fts_array = a;
|
||||
}
|
||||
for (ap = sp->fts_array, p = head; p; p = p->fts_link)
|
||||
*ap++ = p;
|
||||
qsort(sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
|
||||
for (head = *(ap = sp->fts_array); --nitems; ++ap)
|
||||
ap[0]->fts_link = ap[1];
|
||||
ap[0]->fts_link = NULL;
|
||||
return (head);
|
||||
}
|
||||
|
||||
static FTSENT *
|
||||
fts_alloc(FTS *sp, const char *name, size_t namelen)
|
||||
{
|
||||
@ -597,8 +650,7 @@ fts_palloc(FTS *sp, size_t more)
|
||||
*/
|
||||
more += 256;
|
||||
if (sp->fts_pathlen + more < sp->fts_pathlen) {
|
||||
if (sp->fts_path)
|
||||
free(sp->fts_path);
|
||||
free(sp->fts_path);
|
||||
sp->fts_path = NULL;
|
||||
errno = ENAMETOOLONG;
|
||||
return (1);
|
||||
@ -606,8 +658,7 @@ fts_palloc(FTS *sp, size_t more)
|
||||
sp->fts_pathlen += more;
|
||||
p = realloc(sp->fts_path, sp->fts_pathlen);
|
||||
if (p == NULL) {
|
||||
if (sp->fts_path)
|
||||
free(sp->fts_path);
|
||||
free(sp->fts_path);
|
||||
sp->fts_path = NULL;
|
||||
return (1);
|
||||
}
|
||||
|
@ -38,9 +38,12 @@
|
||||
typedef struct {
|
||||
struct _ftsent *fts_cur; /* current node */
|
||||
struct _ftsent *fts_child; /* linked list of children */
|
||||
struct _ftsent **fts_array; /* sort array */
|
||||
dev_t fts_dev; /* starting device # */
|
||||
char *fts_path; /* path for this descent */
|
||||
size_t fts_pathlen; /* sizeof(path) */
|
||||
int fts_nitems; /* elements in the sort array */
|
||||
int (*fts_compar)(); /* compare function */
|
||||
|
||||
#define FTS_NOCHDIR 0x0004 /* don't change directories */
|
||||
#define FTS_PHYSICAL 0x0010 /* physical walk */
|
||||
@ -94,7 +97,8 @@ typedef struct _ftsent {
|
||||
|
||||
|
||||
int fts_close(FTS *);
|
||||
FTS *fts_open(char * const *, int, void *);
|
||||
FTS *fts_open(char * const *, int,
|
||||
int (*)(const FTSENT **, const FTSENT **));
|
||||
FTSENT *fts_read(FTS *);
|
||||
int fts_set(FTS *, FTSENT *, int);
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_SQLITE3_ERRSTR
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
const char *
|
||||
sqlite3_errstr(int rc)
|
||||
{
|
||||
|
||||
return rc ? "unknown error" : "not an error";
|
||||
}
|
||||
|
||||
#endif
|
210
config.log
210
config.log
@ -1,210 +0,0 @@
|
||||
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
|
206
configure
vendored
206
configure
vendored
@ -1,5 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.55 2017/01/12 15:45:05 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
@ -33,26 +35,34 @@ echo "config.log: writing..."
|
||||
|
||||
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
OSNAME=
|
||||
UTF8_LOCALE=
|
||||
|
||||
CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make -f -`
|
||||
CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings"
|
||||
CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | env -i make -sf -`
|
||||
CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings"
|
||||
CFLAGS="${CFLAGS} -Wno-unused-parameter"
|
||||
LDADD=
|
||||
LDFLAGS=
|
||||
LD_NANOSLEEP=
|
||||
LD_OHASH=
|
||||
LD_SQLITE3=
|
||||
STATIC="-static"
|
||||
|
||||
BUILD_DB=1
|
||||
BUILD_CGI=0
|
||||
INSTALL_LIBMANDOC=0
|
||||
|
||||
HAVE_DIRENT_NAMLEN=
|
||||
HAVE_EFTYPE=
|
||||
HAVE_ENDIAN=
|
||||
HAVE_ERR=
|
||||
HAVE_FTS=
|
||||
HAVE_FTS_COMPARE_CONST=
|
||||
HAVE_GETLINE=
|
||||
HAVE_GETSUBOPT=
|
||||
HAVE_ISBLANK=
|
||||
HAVE_MKDTEMP=
|
||||
HAVE_MMAP=
|
||||
HAVE_NANOSLEEP=
|
||||
HAVE_NTOHL=
|
||||
HAVE_OHASH=
|
||||
HAVE_PATH_MAX=
|
||||
HAVE_PLEDGE=
|
||||
HAVE_PROGNAME=
|
||||
HAVE_REALLOCARRAY=
|
||||
@ -66,14 +76,10 @@ HAVE_STRLCPY=
|
||||
HAVE_STRPTIME=
|
||||
HAVE_STRSEP=
|
||||
HAVE_STRTONUM=
|
||||
HAVE_SYS_ENDIAN=
|
||||
HAVE_VASPRINTF=
|
||||
HAVE_WCHAR=
|
||||
|
||||
HAVE_SQLITE3=
|
||||
HAVE_SQLITE3_ERRSTR=
|
||||
HAVE_OHASH=
|
||||
HAVE_MANPATH=
|
||||
|
||||
PREFIX="/usr/local"
|
||||
BINDIR=
|
||||
SBINDIR=
|
||||
@ -125,9 +131,9 @@ COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
|
||||
# If yes, use the override, if no, do not decide anything yet.
|
||||
# Arguments: lower-case test name, manual value
|
||||
ismanual() {
|
||||
[ -z "${2}" ] && return 1
|
||||
echo "${1}: manual (${2})" 1>&2
|
||||
echo "${1}: manual (${2})" 1>&3
|
||||
[ -z "${3}" ] && return 1
|
||||
echo "${1}: manual (HAVE_${2}=${3})" 1>&2
|
||||
echo "${1}: manual (HAVE_${2}=${3})" 1>&3
|
||||
echo 1>&3
|
||||
return 0
|
||||
}
|
||||
@ -138,27 +144,27 @@ ismanual() {
|
||||
# Arguments: lower-case test name, upper-case test name, additional CFLAGS
|
||||
singletest() {
|
||||
cat 1>&3 << __HEREDOC__
|
||||
${1}: testing...
|
||||
${COMP} ${3} -o test-${1} test-${1}.c
|
||||
${1}${3}: testing...
|
||||
${COMP} -o test-${1} test-${1}.c ${3}
|
||||
__HEREDOC__
|
||||
|
||||
if ${COMP} ${3} -o "test-${1}" "test-${1}.c" 1>&3 2>&3; then
|
||||
echo "${1}: ${CC} succeeded" 1>&3
|
||||
if ${COMP} -o "test-${1}" "test-${1}.c" ${3} 1>&3 2>&3; then
|
||||
echo "${1}${3}: ${CC} succeeded" 1>&3
|
||||
else
|
||||
echo "${1}: ${CC} failed with $?" 1>&3
|
||||
echo "${1}${3}: ${CC} failed with $?" 1>&3
|
||||
echo 1>&3
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ./test-${1} 1>&3 2>&3; then
|
||||
echo "${1}: yes" 1>&2
|
||||
echo "${1}: yes" 1>&3
|
||||
echo "${1}${3}: yes" 1>&2
|
||||
echo "${1}${3}: yes" 1>&3
|
||||
echo 1>&3
|
||||
eval HAVE_${2}=1
|
||||
rm "test-${1}"
|
||||
return 0
|
||||
else
|
||||
echo "${1}: execution failed with $?" 1>&3
|
||||
echo "${1}${3}: execution failed with $?" 1>&3
|
||||
echo 1>&3
|
||||
rm "test-${1}"
|
||||
return 1
|
||||
@ -170,22 +176,42 @@ __HEREDOC__
|
||||
# Arguments: lower case name, upper case name, additional CFLAGS
|
||||
runtest() {
|
||||
eval _manual=\${HAVE_${2}}
|
||||
ismanual "${1}" "${_manual}" && return 0
|
||||
ismanual "${1}" "${2}" "${_manual}" && return 0
|
||||
singletest "${1}" "${2}" "${3}" && return 0
|
||||
echo "${1}: no" 1>&2
|
||||
echo "${1}${3}: no" 1>&2
|
||||
eval HAVE_${2}=0
|
||||
return 1
|
||||
}
|
||||
|
||||
# Select a UTF-8 locale.
|
||||
get_locale() {
|
||||
[ -n "${HAVE_WCHAR}" ] && [ "${HAVE_WCHAR}" -eq 0 ] && return 0
|
||||
ismanual UTF8_LOCALE UTF8_LOCALE "$UTF8_LOCALE" && return 0
|
||||
echo "UTF8_LOCALE: testing..." 1>&3
|
||||
UTF8_LOCALE=`locale -a | grep -i '^en_US\.UTF-*8$' | head -n 1`
|
||||
if [ -z "${UTF8_LOCALE}" ]; then
|
||||
UTF8_LOCALE=`locale -a | grep -i '\.UTF-*8' | head -n 1`
|
||||
[ -n "${UTF8_LOCALE}" ] || return 1
|
||||
fi
|
||||
echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&2
|
||||
echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&3
|
||||
echo 1>&3
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
# --- library functions ---
|
||||
runtest dirent-namlen DIRENT_NAMLEN || true
|
||||
runtest be32toh ENDIAN || true
|
||||
runtest be32toh SYS_ENDIAN -DSYS_ENDIAN || true
|
||||
runtest EFTYPE EFTYPE || 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 ntohl NTOHL || true
|
||||
runtest PATH_MAX PATH_MAX || true
|
||||
runtest pledge PLEDGE || true
|
||||
runtest sandbox_init SANDBOX_INIT || true
|
||||
runtest progname PROGNAME || true
|
||||
@ -200,48 +226,48 @@ runtest strptime STRPTIME || true
|
||||
runtest strsep STRSEP || true
|
||||
runtest strtonum STRTONUM || true
|
||||
runtest vasprintf VASPRINTF || true
|
||||
runtest wchar WCHAR || true
|
||||
|
||||
# --- sqlite3 ---
|
||||
if [ ${BUILD_DB} -eq 0 ]; then
|
||||
echo "BUILD_DB=0 (manual)" 1>&2
|
||||
echo "BUILD_DB=0 (manual)" 1>&3
|
||||
echo 1>&3
|
||||
HAVE_SQLITE3=0
|
||||
elif ismanual sqlite3 "${HAVE_SQLITE3}"; then
|
||||
if [ -z "${LD_SQLITE3}" ]; then
|
||||
LD_SQLITE3="-lsqlite3"
|
||||
fi
|
||||
elif [ -n "${LD_SQLITE3}" ]; then
|
||||
runtest sqlite3 SQLITE3 "${LD_SQLITE3}" || true
|
||||
elif singletest sqlite3 SQLITE3 "-lsqlite3"; then
|
||||
LD_SQLITE3="-lsqlite3"
|
||||
elif runtest sqlite3 SQLITE3 \
|
||||
"-I/usr/local/include -L/usr/local/lib -lsqlite3"; then
|
||||
LD_SQLITE3="-L/usr/local/lib -lsqlite3"
|
||||
CFLAGS="${CFLAGS} -I/usr/local/include"
|
||||
fi
|
||||
if [ ${HAVE_SQLITE3} -eq 0 ]; then
|
||||
LD_SQLITE3=
|
||||
if [ ${BUILD_DB} -gt 0 ]; then
|
||||
echo "BUILD_DB=0 (no sqlite3)" 1>&2
|
||||
echo "BUILD_DB=0 (no sqlite3)" 1>&3
|
||||
echo 1>&3
|
||||
BUILD_DB=0
|
||||
fi
|
||||
if [ ${HAVE_ENDIAN} -eq 0 -a \
|
||||
${HAVE_SYS_ENDIAN} -eq 0 -a \
|
||||
${HAVE_NTOHL} -eq 0 ]; then
|
||||
echo "FATAL: no endian conversion functions found" 1>&2
|
||||
echo "FATAL: no endian conversion functions found" 1>&3
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- sqlite3_errstr ---
|
||||
if [ ${BUILD_DB} -eq 0 ]; then
|
||||
HAVE_SQLITE3_ERRSTR=1
|
||||
elif ismanual sqlite3_errstr "${HAVE_SQLITE3_ERRSTR}"; then
|
||||
:
|
||||
if ismanual fts FTS ${HAVE_FTS}; then
|
||||
HAVE_FTS_COMPARE_CONST=0
|
||||
elif runtest fts FTS_COMPARE_CONST -DFTS_COMPARE_CONST; then
|
||||
HAVE_FTS=1
|
||||
else
|
||||
runtest sqlite3_errstr SQLITE3_ERRSTR "${LD_SQLITE3}" || true
|
||||
runtest fts FTS || true
|
||||
fi
|
||||
|
||||
# --- wide character and locale support ---
|
||||
if get_locale; then
|
||||
runtest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true
|
||||
else
|
||||
HAVE_WCHAR=0
|
||||
echo "wchar: no (no UTF8_LOCALE)" 1>&2
|
||||
echo "wchar: no (no UTF8_LOCALE)" 1>&3
|
||||
fi
|
||||
|
||||
# --- nanosleep ---
|
||||
if [ -n "${LD_NANOSLEEP}" ]; then
|
||||
runtest nanosleep NANOSLEEP "${LD_NANOSLEEP}" || true
|
||||
elif singletest nanosleep NANOSLEEP; then
|
||||
:
|
||||
elif runtest nanosleep NANOSLEEP "-lrt"; then
|
||||
LD_NANOSLEEP="-lrt"
|
||||
fi
|
||||
if [ "${HAVE_NANOSLEEP}" -eq 0 ]; then
|
||||
echo "FATAL: nanosleep: no" 1>&2
|
||||
echo "FATAL: nanosleep: no" 1>&3
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- ohash ---
|
||||
if ismanual ohash "${HAVE_OHASH}"; then
|
||||
if ismanual ohash OHASH "${HAVE_OHASH}"; then
|
||||
:
|
||||
elif [ -n "${LD_OHASH}" ]; then
|
||||
runtest ohash OHASH "${LD_OHASH}" || true
|
||||
@ -255,26 +281,11 @@ if [ "${HAVE_OHASH}" -eq 0 ]; then
|
||||
fi
|
||||
|
||||
# --- LDADD ---
|
||||
LDADD="${LDADD} ${LD_SQLITE3} ${LD_OHASH} -lz"
|
||||
LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_OHASH} -lz"
|
||||
echo "LDADD=\"${LDADD}\"" 1>&2
|
||||
echo "LDADD=\"${LDADD}\"" 1>&3
|
||||
echo 1>&3
|
||||
|
||||
# --- manpath ---
|
||||
if ismanual manpath "${HAVE_MANPATH}"; then
|
||||
:
|
||||
elif manpath 1>&3 2>&3; then
|
||||
echo "manpath: yes" 1>&2
|
||||
echo "manpath: yes" 1>&3
|
||||
echo 1>&3
|
||||
HAVE_MANPATH=1
|
||||
else
|
||||
echo "manpath: no" 1>&2
|
||||
echo "manpath: no" 1>&3
|
||||
echo 1>&3
|
||||
HAVE_MANPATH=0
|
||||
fi
|
||||
|
||||
# --- write config.h ---
|
||||
|
||||
exec > config.h
|
||||
@ -284,8 +295,9 @@ cat << __HEREDOC__
|
||||
#error "Do not use C++. See the INSTALL file."
|
||||
#endif
|
||||
|
||||
#ifndef MANDOC_CONFIG_H
|
||||
#define MANDOC_CONFIG_H
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 4)
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__MINT__)
|
||||
#define _GNU_SOURCE /* See test-*.c what needs this. */
|
||||
@ -303,17 +315,26 @@ echo
|
||||
echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\""
|
||||
echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
|
||||
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
|
||||
[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\""
|
||||
[ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\""
|
||||
[ ${HAVE_EFTYPE} -eq 0 ] && echo "#define EFTYPE EINVAL"
|
||||
[ ${HAVE_PATH_MAX} -eq 0 ] && echo "#define PATH_MAX 4096"
|
||||
if [ ${HAVE_ENDIAN} -eq 0 -a ${HAVE_SYS_ENDIAN} -eq 0 ]; then
|
||||
echo "#define be32toh ntohl"
|
||||
echo "#define htobe32 htonl"
|
||||
fi
|
||||
|
||||
cat << __HEREDOC__
|
||||
#define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN}
|
||||
#define HAVE_ENDIAN ${HAVE_ENDIAN}
|
||||
#define HAVE_ERR ${HAVE_ERR}
|
||||
#define HAVE_FTS ${HAVE_FTS}
|
||||
#define HAVE_FTS_COMPARE_CONST ${HAVE_FTS_COMPARE_CONST}
|
||||
#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_NTOHL ${HAVE_NTOHL}
|
||||
#define HAVE_PLEDGE ${HAVE_PLEDGE}
|
||||
#define HAVE_PROGNAME ${HAVE_PROGNAME}
|
||||
#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY}
|
||||
@ -327,12 +348,10 @@ cat << __HEREDOC__
|
||||
#define HAVE_STRPTIME ${HAVE_STRPTIME}
|
||||
#define HAVE_STRSEP ${HAVE_STRSEP}
|
||||
#define HAVE_STRTONUM ${HAVE_STRTONUM}
|
||||
#define HAVE_SYS_ENDIAN ${HAVE_SYS_ENDIAN}
|
||||
#define HAVE_VASPRINTF ${HAVE_VASPRINTF}
|
||||
#define HAVE_WCHAR ${HAVE_WCHAR}
|
||||
#define HAVE_SQLITE3 ${HAVE_SQLITE3}
|
||||
#define HAVE_SQLITE3_ERRSTR ${HAVE_SQLITE3_ERRSTR}
|
||||
#define HAVE_OHASH ${HAVE_OHASH}
|
||||
#define HAVE_MANPATH ${HAVE_MANPATH}
|
||||
|
||||
#define BINM_APROPOS "${BINM_APROPOS}"
|
||||
#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}"
|
||||
@ -369,9 +388,6 @@ fi
|
||||
[ ${HAVE_REALLOCARRAY} -eq 0 ] && \
|
||||
echo "extern void *reallocarray(void *, size_t, size_t);"
|
||||
|
||||
[ ${BUILD_DB} -gt 0 -a ${HAVE_SQLITE3_ERRSTR} -eq 0 ] &&
|
||||
echo "extern const char *sqlite3_errstr(int);"
|
||||
|
||||
[ ${HAVE_STRCASESTR} -eq 0 ] && \
|
||||
echo "extern char *strcasestr(const char *, const char *);"
|
||||
|
||||
@ -390,9 +406,6 @@ fi
|
||||
[ ${HAVE_VASPRINTF} -eq 0 ] && \
|
||||
echo "extern int vasprintf(char **, const char *, va_list);"
|
||||
|
||||
echo
|
||||
echo "#endif /* MANDOC_CONFIG_H */"
|
||||
|
||||
echo "config.h: written" 1>&2
|
||||
echo "config.h: written" 1>&3
|
||||
|
||||
@ -414,16 +427,10 @@ exec > Makefile.local
|
||||
[ -z "${INSTALL_MAN}" ] && INSTALL_MAN="${INSTALL} -m 0444"
|
||||
[ -z "${INSTALL_DATA}" ] && INSTALL_DATA="${INSTALL} -m 0444"
|
||||
|
||||
if [ ${BUILD_DB} -eq 0 -a ${BUILD_CGI} -gt 0 ]; then
|
||||
echo "BUILD_CGI=0 (no BUILD_DB)" 1>&2
|
||||
echo "BUILD_CGI=0 (no BUILD_DB)" 1>&3
|
||||
BUILD_CGI=0
|
||||
fi
|
||||
|
||||
BUILD_TARGETS="base-build"
|
||||
[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} cgi-build"
|
||||
INSTALL_TARGETS="base-install"
|
||||
[ ${BUILD_DB} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} db-install"
|
||||
BUILD_TARGETS=
|
||||
[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="cgi-build"
|
||||
INSTALL_TARGETS=
|
||||
[ ${INSTALL_LIBMANDOC} -gt 0 ] && INSTALL_TARGETS="lib-install"
|
||||
[ ${BUILD_CGI} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} cgi-install"
|
||||
|
||||
cat << __HEREDOC__
|
||||
@ -461,9 +468,6 @@ INSTALL_MAN = ${INSTALL_MAN}
|
||||
INSTALL_DATA = ${INSTALL_DATA}
|
||||
__HEREDOC__
|
||||
|
||||
[ ${BUILD_DB} -gt 0 ] && \
|
||||
echo "MAIN_OBJS = \$(BASE_OBJS) \$(DB_OBJS)"
|
||||
|
||||
echo "Makefile.local: written" 1>&2
|
||||
echo "Makefile.local: written" 1>&3
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: configure.local.example,v 1.13 2016/07/14 11:09:06 schwarze Exp $
|
||||
# $Id: configure.local.example,v 1.22 2016/11/19 15:24:51 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
@ -48,10 +48,17 @@ HAVE_WCHAR=1
|
||||
|
||||
HAVE_WCHAR=0
|
||||
|
||||
# For -Tutf8 mode, mandoc needs to set an arbitrary locale having
|
||||
# a UTF-8 character set. If autodetection of a suitable locale
|
||||
# fails or selects an undesirable locale, you can manually choose
|
||||
# the locale for -Tutf8 mode:
|
||||
|
||||
UTF8_LOCALE=en_US.UTF-8
|
||||
|
||||
# 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 is not set in the environment, and man.conf(5) is not
|
||||
# available, manuals are searched for in the following directory
|
||||
# trees by default.
|
||||
|
||||
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
|
||||
@ -65,7 +72,7 @@ MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
# If you do not want uname(3) to be called but instead want a fixed
|
||||
# string to be used, use the following line:
|
||||
|
||||
OSNAME="OpenBSD 5.9"
|
||||
OSNAME="OpenBSD 6.0"
|
||||
|
||||
# The following installation directories are used.
|
||||
# It is possible to set only one or a few of these variables,
|
||||
@ -76,25 +83,8 @@ OSNAME="OpenBSD 5.9"
|
||||
PREFIX="/usr/local"
|
||||
BINDIR="${PREFIX}/bin"
|
||||
SBINDIR="${PREFIX}/sbin"
|
||||
INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||
LIBDIR="${PREFIX}/lib/mandoc"
|
||||
MANDIR="${PREFIX}/man"
|
||||
|
||||
# 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).
|
||||
# The latter is used by OpenBSD and NetBSD, the former by most
|
||||
# other systems.
|
||||
|
||||
# Force usage of manpath(1).
|
||||
# If it is not installed or not operational,
|
||||
# man(1), makewhatis(8), and apropos(1) will not work properly.
|
||||
HAVE_MANPATH=1
|
||||
|
||||
# Force usage of man.conf(5).
|
||||
# If it does not exist or contains no valid configuration,
|
||||
# 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.
|
||||
@ -113,14 +103,20 @@ MANM_ROFF="mandoc_roff" # default is "roff"
|
||||
MANM_EQN="mandoc_eqn" # default is "eqn"
|
||||
MANM_TBL="mandoc_tbl" # default is "tbl"
|
||||
|
||||
# Some distributions may want to avoid naming conflicts
|
||||
# with other man(1) and soelim(1) utilities.
|
||||
# Some distributions may want to avoid naming conflicts with
|
||||
# other man(1), apropos(1), makewhatis(8), or 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.
|
||||
# This changes the names of the installed section 1 and section 8
|
||||
# manual pages as well.
|
||||
# It is possible to set only one or two of these variables,
|
||||
# there is no need to copy the whole block.
|
||||
|
||||
BINM_MAN=mman # default is "man"
|
||||
BINM_APROPOS=mapropos # default is "apropos"
|
||||
BINM_WHATIS=mwhatis # default is "whatis"
|
||||
BINM_MAKEWHATIS=mandocdb # default is "makewhatis"
|
||||
BINM_SOELIM=msoelim # default is "soelim"
|
||||
|
||||
# Before falling back to the bundled version of the ohash(3) hashing
|
||||
@ -131,11 +127,24 @@ BINM_SOELIM=msoelim # default is "soelim"
|
||||
|
||||
LD_OHASH="-lutil"
|
||||
|
||||
# Some platforms may need additional linker flags to link against libmandoc
|
||||
# that are not autodetected.
|
||||
# For example, Solaris 9 and 10 need -lrt for nanosleep(2).
|
||||
# When library autodetection decides to use -L/usr/local/lib,
|
||||
# -I/usr/local/include is automatically added to CFLAGS.
|
||||
# If you manually set LD_OHASH to something including -L/usr/local/lib,
|
||||
# chances are you will also need the following line:
|
||||
|
||||
LDADD="-lrt"
|
||||
CFLAGS="${CFLAGS} -I/usr/local/include"
|
||||
|
||||
# Some platforms may need an additional linker flag for nanosleep(2).
|
||||
# If none is needed or it is -lrt, it is autodetected.
|
||||
# Otherwise, set the following variable.
|
||||
|
||||
LD_NANOSLEEP="-lrt"
|
||||
|
||||
# Some platforms might need additional linker flags to link against
|
||||
# libmandoc that are not autodetected, though no such cases are
|
||||
# currently known.
|
||||
|
||||
LDADD="-lm"
|
||||
|
||||
# Some systems may want to set additional linker flags for all the
|
||||
# binaries, not only for those using libmandoc, for example for
|
||||
@ -152,43 +161,6 @@ INSTALL_LIB="${INSTALL} -m 0444"
|
||||
INSTALL_MAN="${INSTALL} -m 0444"
|
||||
INSTALL_DATA="${INSTALL} -m 0444"
|
||||
|
||||
# --- user settings related to database support ------------------------
|
||||
|
||||
# By default, building makewhatis(8) and apropos(1) is enabled.
|
||||
# To disable it, for example to avoid the dependency on SQLite3,
|
||||
# use the following line. It that case, the remaining settings
|
||||
# in this section are irrelevant.
|
||||
|
||||
BUILD_DB=0
|
||||
|
||||
# Autoconfiguration tries the following linker flags to find the
|
||||
# SQLite3 library installed on your system. If none of these work,
|
||||
# set the following variable to specify the required linker flags.
|
||||
|
||||
LD_SQLITE3="-lsqlite3"
|
||||
LD_SQLITE3="-L/usr/local/lib -lsqlite3"
|
||||
|
||||
# When library autodetection decides to use -L/usr/local/lib,
|
||||
# -I/usr/local/include is automatically added to CFLAGS.
|
||||
# If you manually set LD_SQLITE3 to something including -L/usr/local/lib,
|
||||
# chances are you will also need the following line:
|
||||
|
||||
CFLAGS="${CFLAGS} -I/usr/local/include"
|
||||
|
||||
# Some distributions may want to avoid naming conflicts
|
||||
# with another implementation of apropos(1) and makewhatis(8).
|
||||
# If you want to change the names of the binary programs,
|
||||
# the following alternative names are suggested.
|
||||
# Using other names is possible as well.
|
||||
# This changes the names of the installed section 1 and section 8
|
||||
# manual pages as well.
|
||||
# It is possible to set only one or two of these variables,
|
||||
# there is no need to copy the whole block.
|
||||
|
||||
BINM_APROPOS=mapropos # default is "apropos"
|
||||
BINM_WHATIS=mwhatis # default is "whatis"
|
||||
BINM_MAKEWHATIS=mandocdb # default is "makewhatis"
|
||||
|
||||
# When using the "homebrew" package manager on Mac OS X, the actual
|
||||
# manuals are located in a so-called "cellar" and only symlinked
|
||||
# into the manual trees. To allow mandoc to follow such symlinks,
|
||||
@ -198,11 +170,25 @@ BINM_MAKEWHATIS=mandocdb # default is "makewhatis"
|
||||
PREFIX="/usr/local"
|
||||
HOMEBREWDIR="${PREFIX}/Cellar"
|
||||
|
||||
# --- user settings related man.cgi ------------------------------------
|
||||
# --- user settings for the mandoc(3) library --------------------------
|
||||
|
||||
# By default, libmandoc.a is not installed. It is almost never needed
|
||||
# because there is almost no non-mandoc software out there using this
|
||||
# library. The one notable exception is NetBSD apropos(1).
|
||||
# So, when building for the NetBSD base system - but not for NetBSD
|
||||
# ports nor for pkgsrc! - you may want the following:
|
||||
|
||||
INSTALL_LIBMANDOC=1
|
||||
|
||||
# The following settings are only used when INSTALL_LIBMANDOC is set.
|
||||
|
||||
INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||
LIBDIR="${PREFIX}/lib/mandoc"
|
||||
|
||||
# --- user settings related to man.cgi ---------------------------------
|
||||
|
||||
# By default, building man.cgi(8) is disabled. To enable it, copy
|
||||
# cgi.h.example to cgi.h, edit it, and use the following line.
|
||||
# Obviously, this requires that BUILD_DB is enabled, too.
|
||||
|
||||
BUILD_CGI=1
|
||||
|
||||
@ -254,13 +240,18 @@ CFLAGS="-g"
|
||||
# be regarded as successful).
|
||||
|
||||
HAVE_DIRENT_NAMLEN=0
|
||||
HAVE_ENDIAN=0
|
||||
HAVE_EFTYPE=0
|
||||
HAVE_ERR=0
|
||||
HAVE_FTS=0
|
||||
HAVE_FTS=0 # Setting this implies HAVE_FTS_COMPARE_CONST=0.
|
||||
HAVE_FTS_COMPARE_CONST=0 # Setting this implies HAVE_FTS=1.
|
||||
HAVE_GETLINE=0
|
||||
HAVE_GETSUBOPT=0
|
||||
HAVE_ISBLANK=0
|
||||
HAVE_MKDTEMP=0
|
||||
HAVE_MMAP=0
|
||||
HAVE_NTOHL=0
|
||||
HAVE_OHASH=0
|
||||
HAVE_PATH_MAX=0
|
||||
HAVE_PLEDGE=0
|
||||
HAVE_PROGNAME=0
|
||||
HAVE_REALLOCARRAY=0
|
||||
@ -273,9 +264,6 @@ HAVE_STRLCPY=0
|
||||
HAVE_STRPTIME=0
|
||||
HAVE_STRSEP=0
|
||||
HAVE_STRTONUM=0
|
||||
HAVE_SYS_ENDIAN=0
|
||||
HAVE_VASPRINTF=0
|
||||
HAVE_WCHAR=0
|
||||
|
||||
HAVE_SQLITE3=0
|
||||
HAVE_SQLITE3_ERRSTR=0
|
||||
HAVE_OHASH=0
|
||||
|
508
dba.c
Normal file
508
dba.c
Normal file
@ -0,0 +1,508 @@
|
||||
/* $Id: dba.c,v 1.9 2017/01/15 15:28:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Allocation-based version of the mandoc database, for read-write access.
|
||||
* The interface is defined in "dba.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#if HAVE_ENDIAN
|
||||
#include <endian.h>
|
||||
#elif HAVE_SYS_ENDIAN
|
||||
#include <sys/endian.h>
|
||||
#elif HAVE_NTOHL
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "mansearch.h"
|
||||
#include "dba_write.h"
|
||||
#include "dba_array.h"
|
||||
#include "dba.h"
|
||||
|
||||
struct macro_entry {
|
||||
struct dba_array *pages;
|
||||
char value[];
|
||||
};
|
||||
|
||||
static void *prepend(const char *, char);
|
||||
static void dba_pages_write(struct dba_array *);
|
||||
static int compare_names(const void *, const void *);
|
||||
static int compare_strings(const void *, const void *);
|
||||
|
||||
static struct macro_entry
|
||||
*get_macro_entry(struct ohash *, const char *, int32_t);
|
||||
static void dba_macros_write(struct dba_array *);
|
||||
static void dba_macro_write(struct ohash *);
|
||||
static int compare_entries(const void *, const void *);
|
||||
|
||||
|
||||
/*** top-level functions **********************************************/
|
||||
|
||||
struct dba *
|
||||
dba_new(int32_t npages)
|
||||
{
|
||||
struct dba *dba;
|
||||
struct ohash *macro;
|
||||
int32_t im;
|
||||
|
||||
dba = mandoc_malloc(sizeof(*dba));
|
||||
dba->pages = dba_array_new(npages, DBA_GROW);
|
||||
dba->macros = dba_array_new(MACRO_MAX, 0);
|
||||
for (im = 0; im < MACRO_MAX; im++) {
|
||||
macro = mandoc_malloc(sizeof(*macro));
|
||||
mandoc_ohash_init(macro, 4,
|
||||
offsetof(struct macro_entry, value));
|
||||
dba_array_set(dba->macros, im, macro);
|
||||
}
|
||||
return dba;
|
||||
}
|
||||
|
||||
void
|
||||
dba_free(struct dba *dba)
|
||||
{
|
||||
struct dba_array *page;
|
||||
struct ohash *macro;
|
||||
struct macro_entry *entry;
|
||||
unsigned int slot;
|
||||
|
||||
dba_array_FOREACH(dba->macros, macro) {
|
||||
for (entry = ohash_first(macro, &slot); entry != NULL;
|
||||
entry = ohash_next(macro, &slot)) {
|
||||
dba_array_free(entry->pages);
|
||||
free(entry);
|
||||
}
|
||||
ohash_delete(macro);
|
||||
free(macro);
|
||||
}
|
||||
dba_array_free(dba->macros);
|
||||
|
||||
dba_array_undel(dba->pages);
|
||||
dba_array_FOREACH(dba->pages, page) {
|
||||
dba_array_free(dba_array_get(page, DBP_NAME));
|
||||
dba_array_free(dba_array_get(page, DBP_SECT));
|
||||
dba_array_free(dba_array_get(page, DBP_ARCH));
|
||||
free(dba_array_get(page, DBP_DESC));
|
||||
dba_array_free(dba_array_get(page, DBP_FILE));
|
||||
dba_array_free(page);
|
||||
}
|
||||
dba_array_free(dba->pages);
|
||||
|
||||
free(dba);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the complete mandoc database to disk; the format is:
|
||||
* - One integer each for magic and version.
|
||||
* - One pointer each to the macros table and to the final magic.
|
||||
* - The pages table.
|
||||
* - The macros table.
|
||||
* - And at the very end, the magic integer again.
|
||||
*/
|
||||
int
|
||||
dba_write(const char *fname, struct dba *dba)
|
||||
{
|
||||
int save_errno;
|
||||
int32_t pos_end, pos_macros, pos_macros_ptr;
|
||||
|
||||
if (dba_open(fname) == -1)
|
||||
return -1;
|
||||
dba_int_write(MANDOCDB_MAGIC);
|
||||
dba_int_write(MANDOCDB_VERSION);
|
||||
pos_macros_ptr = dba_skip(1, 2);
|
||||
dba_pages_write(dba->pages);
|
||||
pos_macros = dba_tell();
|
||||
dba_macros_write(dba->macros);
|
||||
pos_end = dba_tell();
|
||||
dba_int_write(MANDOCDB_MAGIC);
|
||||
dba_seek(pos_macros_ptr);
|
||||
dba_int_write(pos_macros);
|
||||
dba_int_write(pos_end);
|
||||
if (dba_close() == -1) {
|
||||
save_errno = errno;
|
||||
unlink(fname);
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*** functions for handling pages *************************************/
|
||||
|
||||
/*
|
||||
* Create a new page and append it to the pages table.
|
||||
*/
|
||||
struct dba_array *
|
||||
dba_page_new(struct dba_array *pages, const char *arch,
|
||||
const char *desc, const char *file, enum form form)
|
||||
{
|
||||
struct dba_array *page, *entry;
|
||||
|
||||
page = dba_array_new(DBP_MAX, 0);
|
||||
entry = dba_array_new(1, DBA_STR | DBA_GROW);
|
||||
dba_array_add(page, entry);
|
||||
entry = dba_array_new(1, DBA_STR | DBA_GROW);
|
||||
dba_array_add(page, entry);
|
||||
if (arch != NULL && *arch != '\0') {
|
||||
entry = dba_array_new(1, DBA_STR | DBA_GROW);
|
||||
dba_array_add(entry, (void *)arch);
|
||||
} else
|
||||
entry = NULL;
|
||||
dba_array_add(page, entry);
|
||||
dba_array_add(page, mandoc_strdup(desc));
|
||||
entry = dba_array_new(1, DBA_STR | DBA_GROW);
|
||||
dba_array_add(entry, prepend(file, form));
|
||||
dba_array_add(page, entry);
|
||||
dba_array_add(pages, page);
|
||||
return page;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a section, architecture, or file name to an existing page.
|
||||
* Passing the NULL pointer for the architecture makes the page MI.
|
||||
* In that case, any earlier or later architectures are ignored.
|
||||
*/
|
||||
void
|
||||
dba_page_add(struct dba_array *page, int32_t ie, const char *str)
|
||||
{
|
||||
struct dba_array *entries;
|
||||
char *entry;
|
||||
|
||||
entries = dba_array_get(page, ie);
|
||||
if (ie == DBP_ARCH) {
|
||||
if (entries == NULL)
|
||||
return;
|
||||
if (str == NULL || *str == '\0') {
|
||||
dba_array_free(entries);
|
||||
dba_array_set(page, DBP_ARCH, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (*str == '\0')
|
||||
return;
|
||||
dba_array_FOREACH(entries, entry) {
|
||||
if (ie == DBP_FILE && *entry < ' ')
|
||||
entry++;
|
||||
if (strcmp(entry, str) == 0)
|
||||
return;
|
||||
}
|
||||
dba_array_add(entries, (void *)str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an additional name to an existing page.
|
||||
*/
|
||||
void
|
||||
dba_page_alias(struct dba_array *page, const char *name, uint64_t mask)
|
||||
{
|
||||
struct dba_array *entries;
|
||||
char *entry;
|
||||
char maskbyte;
|
||||
|
||||
if (*name == '\0')
|
||||
return;
|
||||
maskbyte = mask & NAME_MASK;
|
||||
entries = dba_array_get(page, DBP_NAME);
|
||||
dba_array_FOREACH(entries, entry) {
|
||||
if (strcmp(entry + 1, name) == 0) {
|
||||
*entry |= maskbyte;
|
||||
return;
|
||||
}
|
||||
}
|
||||
dba_array_add(entries, prepend(name, maskbyte));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to a temporary copy of instr with inbyte prepended.
|
||||
*/
|
||||
static void *
|
||||
prepend(const char *instr, char inbyte)
|
||||
{
|
||||
static char *outstr = NULL;
|
||||
static size_t outlen = 0;
|
||||
size_t newlen;
|
||||
|
||||
newlen = strlen(instr) + 1;
|
||||
if (newlen > outlen) {
|
||||
outstr = mandoc_realloc(outstr, newlen + 1);
|
||||
outlen = newlen;
|
||||
}
|
||||
*outstr = inbyte;
|
||||
memcpy(outstr + 1, instr, newlen);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the pages table to disk; the format is:
|
||||
* - One integer containing the number of pages.
|
||||
* - For each page, five pointers to the names, sections,
|
||||
* architectures, description, and file names of the page.
|
||||
* MI pages write 0 instead of the architecture pointer.
|
||||
* - One list each for names, sections, architectures, descriptions and
|
||||
* file names. The description for each page ends with a NUL byte.
|
||||
* For all the other lists, each string ends with a NUL byte,
|
||||
* and the last string for a page ends with two NUL bytes.
|
||||
* - To assure alignment of following integers,
|
||||
* the end is padded with NUL bytes up to a multiple of four bytes.
|
||||
*/
|
||||
static void
|
||||
dba_pages_write(struct dba_array *pages)
|
||||
{
|
||||
struct dba_array *page, *entry;
|
||||
int32_t pos_pages, pos_end;
|
||||
|
||||
pos_pages = dba_array_writelen(pages, 5);
|
||||
dba_array_FOREACH(pages, page) {
|
||||
dba_array_setpos(page, DBP_NAME, dba_tell());
|
||||
entry = dba_array_get(page, DBP_NAME);
|
||||
dba_array_sort(entry, compare_names);
|
||||
dba_array_writelst(entry);
|
||||
}
|
||||
dba_array_FOREACH(pages, page) {
|
||||
dba_array_setpos(page, DBP_SECT, dba_tell());
|
||||
entry = dba_array_get(page, DBP_SECT);
|
||||
dba_array_sort(entry, compare_strings);
|
||||
dba_array_writelst(entry);
|
||||
}
|
||||
dba_array_FOREACH(pages, page) {
|
||||
if ((entry = dba_array_get(page, DBP_ARCH)) != NULL) {
|
||||
dba_array_setpos(page, DBP_ARCH, dba_tell());
|
||||
dba_array_sort(entry, compare_strings);
|
||||
dba_array_writelst(entry);
|
||||
} else
|
||||
dba_array_setpos(page, DBP_ARCH, 0);
|
||||
}
|
||||
dba_array_FOREACH(pages, page) {
|
||||
dba_array_setpos(page, DBP_DESC, dba_tell());
|
||||
dba_str_write(dba_array_get(page, DBP_DESC));
|
||||
}
|
||||
dba_array_FOREACH(pages, page) {
|
||||
dba_array_setpos(page, DBP_FILE, dba_tell());
|
||||
dba_array_writelst(dba_array_get(page, DBP_FILE));
|
||||
}
|
||||
pos_end = dba_align();
|
||||
dba_seek(pos_pages);
|
||||
dba_array_FOREACH(pages, page)
|
||||
dba_array_writepos(page);
|
||||
dba_seek(pos_end);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_names(const void *vp1, const void *vp2)
|
||||
{
|
||||
const char *cp1, *cp2;
|
||||
int diff;
|
||||
|
||||
cp1 = *(char **)vp1;
|
||||
cp2 = *(char **)vp2;
|
||||
return (diff = *cp2 - *cp1) ? diff :
|
||||
strcasecmp(cp1 + 1, cp2 + 1);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_strings(const void *vp1, const void *vp2)
|
||||
{
|
||||
const char *cp1, *cp2;
|
||||
|
||||
cp1 = *(char **)vp1;
|
||||
cp2 = *(char **)vp2;
|
||||
return strcmp(cp1, cp2);
|
||||
}
|
||||
|
||||
/*** functions for handling macros ************************************/
|
||||
|
||||
/*
|
||||
* In the hash table for a single macro, look up an entry by
|
||||
* the macro value or add an empty one if it doesn't exist yet.
|
||||
*/
|
||||
static struct macro_entry *
|
||||
get_macro_entry(struct ohash *macro, const char *value, int32_t np)
|
||||
{
|
||||
struct macro_entry *entry;
|
||||
size_t len;
|
||||
unsigned int slot;
|
||||
|
||||
slot = ohash_qlookup(macro, value);
|
||||
if ((entry = ohash_find(macro, slot)) == NULL) {
|
||||
len = strlen(value) + 1;
|
||||
entry = mandoc_malloc(sizeof(*entry) + len);
|
||||
memcpy(&entry->value, value, len);
|
||||
entry->pages = dba_array_new(np, DBA_GROW);
|
||||
ohash_insert(macro, slot, entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* In addition to get_macro_entry(), add multiple page references,
|
||||
* converting them from the on-disk format (byte offsets in the file)
|
||||
* to page pointers in memory.
|
||||
*/
|
||||
void
|
||||
dba_macro_new(struct dba *dba, int32_t im, const char *value,
|
||||
const int32_t *pp)
|
||||
{
|
||||
struct macro_entry *entry;
|
||||
const int32_t *ip;
|
||||
int32_t np;
|
||||
|
||||
np = 0;
|
||||
for (ip = pp; *ip; ip++)
|
||||
np++;
|
||||
|
||||
entry = get_macro_entry(dba_array_get(dba->macros, im), value, np);
|
||||
for (ip = pp; *ip; ip++)
|
||||
dba_array_add(entry->pages, dba_array_get(dba->pages,
|
||||
be32toh(*ip) / 5 / sizeof(*ip) - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* In addition to get_macro_entry(), add one page reference,
|
||||
* directly taking the in-memory page pointer as an argument.
|
||||
*/
|
||||
void
|
||||
dba_macro_add(struct dba_array *macros, int32_t im, const char *value,
|
||||
struct dba_array *page)
|
||||
{
|
||||
struct macro_entry *entry;
|
||||
|
||||
if (*value == '\0')
|
||||
return;
|
||||
entry = get_macro_entry(dba_array_get(macros, im), value, 1);
|
||||
dba_array_add(entry->pages, page);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the macros table to disk; the format is:
|
||||
* - The number of macro tables (actually, MACRO_MAX).
|
||||
* - That number of pointers to the individual macro tables.
|
||||
* - The individual macro tables.
|
||||
*/
|
||||
static void
|
||||
dba_macros_write(struct dba_array *macros)
|
||||
{
|
||||
struct ohash *macro;
|
||||
int32_t im, pos_macros, pos_end;
|
||||
|
||||
pos_macros = dba_array_writelen(macros, 1);
|
||||
im = 0;
|
||||
dba_array_FOREACH(macros, macro) {
|
||||
dba_array_setpos(macros, im++, dba_tell());
|
||||
dba_macro_write(macro);
|
||||
}
|
||||
pos_end = dba_tell();
|
||||
dba_seek(pos_macros);
|
||||
dba_array_writepos(macros);
|
||||
dba_seek(pos_end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one individual macro table to disk; the format is:
|
||||
* - The number of entries in the table.
|
||||
* - For each entry, two pointers, the first one to the value
|
||||
* and the second one to the list of pages.
|
||||
* - A list of values, each ending in a NUL byte.
|
||||
* - To assure alignment of following integers,
|
||||
* padding with NUL bytes up to a multiple of four bytes.
|
||||
* - A list of pointers to pages, each list ending in a 0 integer.
|
||||
*/
|
||||
static void
|
||||
dba_macro_write(struct ohash *macro)
|
||||
{
|
||||
struct macro_entry **entries, *entry;
|
||||
struct dba_array *page;
|
||||
int32_t *kpos, *dpos;
|
||||
unsigned int ie, ne, slot;
|
||||
int use;
|
||||
int32_t addr, pos_macro, pos_end;
|
||||
|
||||
/* Temporary storage for filtering and sorting. */
|
||||
|
||||
ne = ohash_entries(macro);
|
||||
entries = mandoc_reallocarray(NULL, ne, sizeof(*entries));
|
||||
kpos = mandoc_reallocarray(NULL, ne, sizeof(*kpos));
|
||||
dpos = mandoc_reallocarray(NULL, ne, sizeof(*dpos));
|
||||
|
||||
/* Build a list of non-empty entries and sort it. */
|
||||
|
||||
ne = 0;
|
||||
for (entry = ohash_first(macro, &slot); entry != NULL;
|
||||
entry = ohash_next(macro, &slot)) {
|
||||
use = 0;
|
||||
dba_array_FOREACH(entry->pages, page)
|
||||
if (dba_array_getpos(page))
|
||||
use = 1;
|
||||
if (use)
|
||||
entries[ne++] = entry;
|
||||
}
|
||||
qsort(entries, ne, sizeof(*entries), compare_entries);
|
||||
|
||||
/* Number of entries, and space for the pointer pairs. */
|
||||
|
||||
dba_int_write(ne);
|
||||
pos_macro = dba_skip(2, ne);
|
||||
|
||||
/* String table. */
|
||||
|
||||
for (ie = 0; ie < ne; ie++) {
|
||||
kpos[ie] = dba_tell();
|
||||
dba_str_write(entries[ie]->value);
|
||||
}
|
||||
dba_align();
|
||||
|
||||
/* Pages table. */
|
||||
|
||||
for (ie = 0; ie < ne; ie++) {
|
||||
dpos[ie] = dba_tell();
|
||||
dba_array_FOREACH(entries[ie]->pages, page)
|
||||
if ((addr = dba_array_getpos(page)))
|
||||
dba_int_write(addr);
|
||||
dba_int_write(0);
|
||||
}
|
||||
pos_end = dba_tell();
|
||||
|
||||
/* Fill in the pointer pairs. */
|
||||
|
||||
dba_seek(pos_macro);
|
||||
for (ie = 0; ie < ne; ie++) {
|
||||
dba_int_write(kpos[ie]);
|
||||
dba_int_write(dpos[ie]);
|
||||
}
|
||||
dba_seek(pos_end);
|
||||
|
||||
free(entries);
|
||||
free(kpos);
|
||||
free(dpos);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_entries(const void *vp1, const void *vp2)
|
||||
{
|
||||
const struct macro_entry *ep1, *ep2;
|
||||
|
||||
ep1 = *(struct macro_entry **)vp1;
|
||||
ep2 = *(struct macro_entry **)vp2;
|
||||
return strcmp(ep1->value, ep2->value);
|
||||
}
|
50
dba.h
Normal file
50
dba.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* $Id: dba.h,v 1.2 2016/08/17 20:46:56 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Public interface of the allocation-based version
|
||||
* of the mandoc database, for read-write access.
|
||||
* To be used by dba.c, dba_read.c, and makewhatis(8).
|
||||
*/
|
||||
|
||||
#define DBP_NAME 0
|
||||
#define DBP_SECT 1
|
||||
#define DBP_ARCH 2
|
||||
#define DBP_DESC 3
|
||||
#define DBP_FILE 4
|
||||
#define DBP_MAX 5
|
||||
|
||||
struct dba_array;
|
||||
|
||||
struct dba {
|
||||
struct dba_array *pages;
|
||||
struct dba_array *macros;
|
||||
};
|
||||
|
||||
|
||||
struct dba *dba_new(int32_t);
|
||||
void dba_free(struct dba *);
|
||||
struct dba *dba_read(const char *);
|
||||
int dba_write(const char *, struct dba *);
|
||||
|
||||
struct dba_array *dba_page_new(struct dba_array *, const char *,
|
||||
const char *, const char *, enum form);
|
||||
void dba_page_add(struct dba_array *, int32_t, const char *);
|
||||
void dba_page_alias(struct dba_array *, const char *, uint64_t);
|
||||
|
||||
void dba_macro_new(struct dba *, int32_t,
|
||||
const char *, const int32_t *);
|
||||
void dba_macro_add(struct dba_array *, int32_t,
|
||||
const char *, struct dba_array *);
|
188
dba_array.c
Normal file
188
dba_array.c
Normal file
@ -0,0 +1,188 @@
|
||||
/* $Id: dba_array.c,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Allocation-based arrays for the mandoc database, for read-write access.
|
||||
* The interface is defined in "dba_array.h".
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "dba_write.h"
|
||||
#include "dba_array.h"
|
||||
|
||||
struct dba_array {
|
||||
void **ep; /* Array of entries. */
|
||||
int32_t *em; /* Array of map positions. */
|
||||
int flags;
|
||||
int32_t ea; /* Entries allocated. */
|
||||
int32_t eu; /* Entries used (including deleted). */
|
||||
int32_t ed; /* Entries deleted. */
|
||||
int32_t ec; /* Currently active entry. */
|
||||
int32_t pos; /* Map position of this array. */
|
||||
};
|
||||
|
||||
|
||||
struct dba_array *
|
||||
dba_array_new(int32_t ea, int flags)
|
||||
{
|
||||
struct dba_array *array;
|
||||
|
||||
assert(ea > 0);
|
||||
array = mandoc_malloc(sizeof(*array));
|
||||
array->ep = mandoc_reallocarray(NULL, ea, sizeof(*array->ep));
|
||||
array->em = mandoc_reallocarray(NULL, ea, sizeof(*array->em));
|
||||
array->ea = ea;
|
||||
array->eu = 0;
|
||||
array->ed = 0;
|
||||
array->ec = 0;
|
||||
array->flags = flags;
|
||||
array->pos = 0;
|
||||
return array;
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_free(struct dba_array *array)
|
||||
{
|
||||
int32_t ie;
|
||||
|
||||
if (array == NULL)
|
||||
return;
|
||||
if (array->flags & DBA_STR)
|
||||
for (ie = 0; ie < array->eu; ie++)
|
||||
free(array->ep[ie]);
|
||||
free(array->ep);
|
||||
free(array->em);
|
||||
free(array);
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_set(struct dba_array *array, int32_t ie, void *entry)
|
||||
{
|
||||
assert(ie >= 0);
|
||||
assert(ie < array->ea);
|
||||
assert(ie <= array->eu);
|
||||
if (ie == array->eu)
|
||||
array->eu++;
|
||||
if (array->flags & DBA_STR)
|
||||
entry = mandoc_strdup(entry);
|
||||
array->ep[ie] = entry;
|
||||
array->em[ie] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_add(struct dba_array *array, void *entry)
|
||||
{
|
||||
if (array->eu == array->ea) {
|
||||
assert(array->flags & DBA_GROW);
|
||||
array->ep = mandoc_reallocarray(array->ep,
|
||||
2, sizeof(*array->ep) * array->ea);
|
||||
array->em = mandoc_reallocarray(array->em,
|
||||
2, sizeof(*array->em) * array->ea);
|
||||
array->ea *= 2;
|
||||
}
|
||||
dba_array_set(array, array->eu, entry);
|
||||
}
|
||||
|
||||
void *
|
||||
dba_array_get(struct dba_array *array, int32_t ie)
|
||||
{
|
||||
if (ie < 0 || ie >= array->eu || array->em[ie] == -1)
|
||||
return NULL;
|
||||
return array->ep[ie];
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_start(struct dba_array *array)
|
||||
{
|
||||
array->ec = array->eu;
|
||||
}
|
||||
|
||||
void *
|
||||
dba_array_next(struct dba_array *array)
|
||||
{
|
||||
if (array->ec < array->eu)
|
||||
array->ec++;
|
||||
else
|
||||
array->ec = 0;
|
||||
while (array->ec < array->eu && array->em[array->ec] == -1)
|
||||
array->ec++;
|
||||
return array->ec < array->eu ? array->ep[array->ec] : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_del(struct dba_array *array)
|
||||
{
|
||||
if (array->ec < array->eu && array->em[array->ec] != -1) {
|
||||
array->em[array->ec] = -1;
|
||||
array->ed++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_undel(struct dba_array *array)
|
||||
{
|
||||
memset(array->em, 0, sizeof(*array->em) * array->eu);
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_setpos(struct dba_array *array, int32_t ie, int32_t pos)
|
||||
{
|
||||
array->em[ie] = pos;
|
||||
}
|
||||
|
||||
int32_t
|
||||
dba_array_getpos(struct dba_array *array)
|
||||
{
|
||||
return array->pos;
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_sort(struct dba_array *array, dba_compare_func func)
|
||||
{
|
||||
assert(array->ed == 0);
|
||||
qsort(array->ep, array->eu, sizeof(*array->ep), func);
|
||||
}
|
||||
|
||||
int32_t
|
||||
dba_array_writelen(struct dba_array *array, int32_t nmemb)
|
||||
{
|
||||
dba_int_write(array->eu - array->ed);
|
||||
return dba_skip(nmemb, array->eu - array->ed);
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_writepos(struct dba_array *array)
|
||||
{
|
||||
int32_t ie;
|
||||
|
||||
array->pos = dba_tell();
|
||||
for (ie = 0; ie < array->eu; ie++)
|
||||
if (array->em[ie] != -1)
|
||||
dba_int_write(array->em[ie]);
|
||||
}
|
||||
|
||||
void
|
||||
dba_array_writelst(struct dba_array *array)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
dba_array_FOREACH(array, str)
|
||||
dba_str_write(str);
|
||||
dba_char_write('\0');
|
||||
}
|
47
dba_array.h
Normal file
47
dba_array.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* $Id: dba_array.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Public interface for allocation-based arrays
|
||||
* for the mandoc database, for read-write access.
|
||||
* To be used by dba*.c and by makewhatis(8).
|
||||
*/
|
||||
|
||||
struct dba_array;
|
||||
|
||||
#define DBA_STR 0x01 /* Map contains strings, not pointers. */
|
||||
#define DBA_GROW 0x02 /* Allow the array to grow. */
|
||||
|
||||
#define dba_array_FOREACH(a, e) \
|
||||
dba_array_start(a); \
|
||||
while (((e) = dba_array_next(a)) != NULL)
|
||||
|
||||
typedef int dba_compare_func(const void *, const void *);
|
||||
|
||||
struct dba_array *dba_array_new(int32_t, int);
|
||||
void dba_array_free(struct dba_array *);
|
||||
void dba_array_set(struct dba_array *, int32_t, void *);
|
||||
void dba_array_add(struct dba_array *, void *);
|
||||
void *dba_array_get(struct dba_array *, int32_t);
|
||||
void dba_array_start(struct dba_array *);
|
||||
void *dba_array_next(struct dba_array *);
|
||||
void dba_array_del(struct dba_array *);
|
||||
void dba_array_undel(struct dba_array *);
|
||||
void dba_array_setpos(struct dba_array *, int32_t, int32_t);
|
||||
int32_t dba_array_getpos(struct dba_array *);
|
||||
void dba_array_sort(struct dba_array *, dba_compare_func);
|
||||
int32_t dba_array_writelen(struct dba_array *, int32_t);
|
||||
void dba_array_writepos(struct dba_array *);
|
||||
void dba_array_writelst(struct dba_array *);
|
72
dba_read.c
Normal file
72
dba_read.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* $Id: dba_read.c,v 1.4 2016/08/17 20:46:56 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Function to read the mandoc database from disk into RAM,
|
||||
* such that data can be added or removed.
|
||||
* The interface is defined in "dba.h".
|
||||
* This file is seperate from dba.c because this also uses "dbm.h".
|
||||
*/
|
||||
#include <regex.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mansearch.h"
|
||||
#include "dba_array.h"
|
||||
#include "dba.h"
|
||||
#include "dbm.h"
|
||||
|
||||
|
||||
struct dba *
|
||||
dba_read(const char *fname)
|
||||
{
|
||||
struct dba *dba;
|
||||
struct dba_array *page;
|
||||
struct dbm_page *pdata;
|
||||
struct dbm_macro *mdata;
|
||||
const char *cp;
|
||||
int32_t im, ip, iv, npages;
|
||||
|
||||
if (dbm_open(fname) == -1)
|
||||
return NULL;
|
||||
npages = dbm_page_count();
|
||||
dba = dba_new(npages < 128 ? 128 : npages);
|
||||
for (ip = 0; ip < npages; ip++) {
|
||||
pdata = dbm_page_get(ip);
|
||||
page = dba_page_new(dba->pages, pdata->arch,
|
||||
pdata->desc, pdata->file + 1, *pdata->file);
|
||||
for (cp = pdata->name; *cp != '\0'; cp = strchr(cp, '\0') + 1)
|
||||
dba_page_add(page, DBP_NAME, cp);
|
||||
for (cp = pdata->sect; *cp != '\0'; cp = strchr(cp, '\0') + 1)
|
||||
dba_page_add(page, DBP_SECT, cp);
|
||||
if ((cp = pdata->arch) != NULL)
|
||||
while (*(cp = strchr(cp, '\0') + 1) != '\0')
|
||||
dba_page_add(page, DBP_ARCH, cp);
|
||||
cp = pdata->file;
|
||||
while (*(cp = strchr(cp, '\0') + 1) != '\0')
|
||||
dba_page_add(page, DBP_FILE, cp);
|
||||
}
|
||||
for (im = 0; im < MACRO_MAX; im++) {
|
||||
for (iv = 0; iv < dbm_macro_count(im); iv++) {
|
||||
mdata = dbm_macro_get(im, iv);
|
||||
dba_macro_new(dba, im, mdata->value, mdata->pp);
|
||||
}
|
||||
}
|
||||
dbm_close();
|
||||
return dba;
|
||||
}
|
127
dba_write.c
Normal file
127
dba_write.c
Normal file
@ -0,0 +1,127 @@
|
||||
/* $Id: dba_write.c,v 1.3 2016/08/05 23:15:08 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Low-level functions for serializing allocation-based data to disk.
|
||||
* The interface is defined in "dba_write.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#if HAVE_ENDIAN
|
||||
#include <endian.h>
|
||||
#elif HAVE_SYS_ENDIAN
|
||||
#include <sys/endian.h>
|
||||
#elif HAVE_NTOHL
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dba_write.h"
|
||||
|
||||
static FILE *ofp;
|
||||
|
||||
|
||||
int
|
||||
dba_open(const char *fname)
|
||||
{
|
||||
ofp = fopen(fname, "w");
|
||||
return ofp == NULL ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
dba_close(void)
|
||||
{
|
||||
return fclose(ofp) == EOF ? -1 : 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
dba_tell(void)
|
||||
{
|
||||
long pos;
|
||||
|
||||
if ((pos = ftell(ofp)) == -1)
|
||||
err(1, "ftell");
|
||||
if (pos >= INT32_MAX) {
|
||||
errno = EOVERFLOW;
|
||||
err(1, "ftell = %ld", pos);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
void
|
||||
dba_seek(int32_t pos)
|
||||
{
|
||||
if (fseek(ofp, pos, SEEK_SET) == -1)
|
||||
err(1, "fseek(%d)", pos);
|
||||
}
|
||||
|
||||
int32_t
|
||||
dba_align(void)
|
||||
{
|
||||
int32_t pos;
|
||||
|
||||
pos = dba_tell();
|
||||
while (pos & 3) {
|
||||
dba_char_write('\0');
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
int32_t
|
||||
dba_skip(int32_t nmemb, int32_t sz)
|
||||
{
|
||||
const int32_t out[5] = {0, 0, 0, 0, 0};
|
||||
int32_t i, pos;
|
||||
|
||||
assert(sz >= 0);
|
||||
assert(nmemb > 0);
|
||||
assert(nmemb <= 5);
|
||||
pos = dba_tell();
|
||||
for (i = 0; i < sz; i++)
|
||||
if (nmemb - fwrite(&out, sizeof(out[0]), nmemb, ofp))
|
||||
err(1, "fwrite");
|
||||
return pos;
|
||||
}
|
||||
|
||||
void
|
||||
dba_char_write(int c)
|
||||
{
|
||||
if (putc(c, ofp) == EOF)
|
||||
err(1, "fputc");
|
||||
}
|
||||
|
||||
void
|
||||
dba_str_write(const char *str)
|
||||
{
|
||||
if (fputs(str, ofp) == EOF)
|
||||
err(1, "fputs");
|
||||
dba_char_write('\0');
|
||||
}
|
||||
|
||||
void
|
||||
dba_int_write(int32_t i)
|
||||
{
|
||||
i = htobe32(i);
|
||||
if (fwrite(&i, sizeof(i), 1, ofp) != 1)
|
||||
err(1, "fwrite");
|
||||
}
|
30
dba_write.h
Normal file
30
dba_write.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* $Id: dba_write.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Internal interface to low-level functions
|
||||
* for serializing allocation-based data to disk.
|
||||
* For use by dba_array.c and dba.c only.
|
||||
*/
|
||||
|
||||
int dba_open(const char *);
|
||||
int dba_close(void);
|
||||
int32_t dba_tell(void);
|
||||
void dba_seek(int32_t);
|
||||
int32_t dba_align(void);
|
||||
int32_t dba_skip(int32_t, int32_t);
|
||||
void dba_char_write(int);
|
||||
void dba_str_write(const char *);
|
||||
void dba_int_write(int32_t);
|
480
dbm.c
Normal file
480
dbm.c
Normal file
@ -0,0 +1,480 @@
|
||||
/* $Id: dbm.c,v 1.5 2016/10/18 22:27:25 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Map-based version of the mandoc database, for read-only access.
|
||||
* The interface is defined in "dbm.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#if HAVE_ENDIAN
|
||||
#include <endian.h>
|
||||
#elif HAVE_SYS_ENDIAN
|
||||
#include <sys/endian.h>
|
||||
#elif HAVE_NTOHL
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mansearch.h"
|
||||
#include "dbm_map.h"
|
||||
#include "dbm.h"
|
||||
|
||||
struct macro {
|
||||
int32_t value;
|
||||
int32_t pages;
|
||||
};
|
||||
|
||||
struct page {
|
||||
int32_t name;
|
||||
int32_t sect;
|
||||
int32_t arch;
|
||||
int32_t desc;
|
||||
int32_t file;
|
||||
};
|
||||
|
||||
enum iter {
|
||||
ITER_NONE = 0,
|
||||
ITER_NAME,
|
||||
ITER_SECT,
|
||||
ITER_ARCH,
|
||||
ITER_DESC,
|
||||
ITER_MACRO
|
||||
};
|
||||
|
||||
static struct macro *macros[MACRO_MAX];
|
||||
static int32_t nvals[MACRO_MAX];
|
||||
static struct page *pages;
|
||||
static int32_t npages;
|
||||
static enum iter iteration;
|
||||
|
||||
static struct dbm_res page_bytitle(enum iter, const struct dbm_match *);
|
||||
static struct dbm_res page_byarch(const struct dbm_match *);
|
||||
static struct dbm_res page_bymacro(int32_t, const struct dbm_match *);
|
||||
static char *macro_bypage(int32_t, int32_t);
|
||||
|
||||
|
||||
/*** top level functions **********************************************/
|
||||
|
||||
/*
|
||||
* Open a disk-based mandoc database for read-only access.
|
||||
* Map the pages and macros[] arrays.
|
||||
* Return 0 on success. Return -1 and set errno on failure.
|
||||
*/
|
||||
int
|
||||
dbm_open(const char *fname)
|
||||
{
|
||||
const int32_t *mp, *ep;
|
||||
int32_t im;
|
||||
|
||||
if (dbm_map(fname) == -1)
|
||||
return -1;
|
||||
|
||||
if ((npages = be32toh(*dbm_getint(4))) < 0) {
|
||||
warnx("dbm_open(%s): Invalid number of pages: %d",
|
||||
fname, npages);
|
||||
goto fail;
|
||||
}
|
||||
pages = (struct page *)dbm_getint(5);
|
||||
|
||||
if ((mp = dbm_get(*dbm_getint(2))) == NULL) {
|
||||
warnx("dbm_open(%s): Invalid offset of macros array", fname);
|
||||
goto fail;
|
||||
}
|
||||
if (be32toh(*mp) != MACRO_MAX) {
|
||||
warnx("dbm_open(%s): Invalid number of macros: %d",
|
||||
fname, be32toh(*mp));
|
||||
goto fail;
|
||||
}
|
||||
for (im = 0; im < MACRO_MAX; im++) {
|
||||
if ((ep = dbm_get(*++mp)) == NULL) {
|
||||
warnx("dbm_open(%s): Invalid offset of macro %d",
|
||||
fname, im);
|
||||
goto fail;
|
||||
}
|
||||
nvals[im] = be32toh(*ep);
|
||||
macros[im] = (struct macro *)++ep;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dbm_unmap();
|
||||
errno = EFTYPE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
dbm_close(void)
|
||||
{
|
||||
dbm_unmap();
|
||||
}
|
||||
|
||||
|
||||
/*** functions for handling pages *************************************/
|
||||
|
||||
int32_t
|
||||
dbm_page_count(void)
|
||||
{
|
||||
return npages;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give the caller pointers to the data for one manual page.
|
||||
*/
|
||||
struct dbm_page *
|
||||
dbm_page_get(int32_t ip)
|
||||
{
|
||||
static struct dbm_page res;
|
||||
|
||||
assert(ip >= 0);
|
||||
assert(ip < npages);
|
||||
res.name = dbm_get(pages[ip].name);
|
||||
if (res.name == NULL)
|
||||
res.name = "(NULL)";
|
||||
res.sect = dbm_get(pages[ip].sect);
|
||||
if (res.sect == NULL)
|
||||
res.sect = "(NULL)";
|
||||
res.arch = pages[ip].arch ? dbm_get(pages[ip].arch) : NULL;
|
||||
res.desc = dbm_get(pages[ip].desc);
|
||||
if (res.desc == NULL)
|
||||
res.desc = "(NULL)";
|
||||
res.file = dbm_get(pages[ip].file);
|
||||
if (res.file == NULL)
|
||||
res.file = " (NULL)";
|
||||
res.addr = dbm_addr(pages + ip);
|
||||
return &res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to start filtered iterations over manual pages.
|
||||
*/
|
||||
void
|
||||
dbm_page_byname(const struct dbm_match *match)
|
||||
{
|
||||
assert(match != NULL);
|
||||
page_bytitle(ITER_NAME, match);
|
||||
}
|
||||
|
||||
void
|
||||
dbm_page_bysect(const struct dbm_match *match)
|
||||
{
|
||||
assert(match != NULL);
|
||||
page_bytitle(ITER_SECT, match);
|
||||
}
|
||||
|
||||
void
|
||||
dbm_page_byarch(const struct dbm_match *match)
|
||||
{
|
||||
assert(match != NULL);
|
||||
page_byarch(match);
|
||||
}
|
||||
|
||||
void
|
||||
dbm_page_bydesc(const struct dbm_match *match)
|
||||
{
|
||||
assert(match != NULL);
|
||||
page_bytitle(ITER_DESC, match);
|
||||
}
|
||||
|
||||
void
|
||||
dbm_page_bymacro(int32_t im, const struct dbm_match *match)
|
||||
{
|
||||
assert(im >= 0);
|
||||
assert(im < MACRO_MAX);
|
||||
assert(match != NULL);
|
||||
page_bymacro(im, match);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of the next manual page in the current iteration.
|
||||
*/
|
||||
struct dbm_res
|
||||
dbm_page_next(void)
|
||||
{
|
||||
struct dbm_res res = {-1, 0};
|
||||
|
||||
switch(iteration) {
|
||||
case ITER_NONE:
|
||||
return res;
|
||||
case ITER_ARCH:
|
||||
return page_byarch(NULL);
|
||||
case ITER_MACRO:
|
||||
return page_bymacro(0, NULL);
|
||||
default:
|
||||
return page_bytitle(iteration, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions implementing the iteration over manual pages.
|
||||
*/
|
||||
static struct dbm_res
|
||||
page_bytitle(enum iter arg_iter, const struct dbm_match *arg_match)
|
||||
{
|
||||
static const struct dbm_match *match;
|
||||
static const char *cp;
|
||||
static int32_t ip;
|
||||
struct dbm_res res = {-1, 0};
|
||||
|
||||
assert(arg_iter == ITER_NAME || arg_iter == ITER_DESC ||
|
||||
arg_iter == ITER_SECT);
|
||||
|
||||
/* Initialize for a new iteration. */
|
||||
|
||||
if (arg_match != NULL) {
|
||||
iteration = arg_iter;
|
||||
match = arg_match;
|
||||
switch (iteration) {
|
||||
case ITER_NAME:
|
||||
cp = dbm_get(pages[0].name);
|
||||
break;
|
||||
case ITER_SECT:
|
||||
cp = dbm_get(pages[0].sect);
|
||||
break;
|
||||
case ITER_DESC:
|
||||
cp = dbm_get(pages[0].desc);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
if (cp == NULL) {
|
||||
iteration = ITER_NONE;
|
||||
match = NULL;
|
||||
cp = NULL;
|
||||
ip = npages;
|
||||
} else
|
||||
ip = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Search for a name. */
|
||||
|
||||
while (ip < npages) {
|
||||
if (iteration == ITER_NAME)
|
||||
cp++;
|
||||
if (dbm_match(match, cp))
|
||||
break;
|
||||
cp = strchr(cp, '\0') + 1;
|
||||
if (iteration == ITER_DESC)
|
||||
ip++;
|
||||
else if (*cp == '\0') {
|
||||
cp++;
|
||||
ip++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reached the end without a match. */
|
||||
|
||||
if (ip == npages) {
|
||||
iteration = ITER_NONE;
|
||||
match = NULL;
|
||||
cp = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Found a match; save the quality for later retrieval. */
|
||||
|
||||
res.page = ip;
|
||||
res.bits = iteration == ITER_NAME ? cp[-1] : 0;
|
||||
|
||||
/* Skip the remaining names of this page. */
|
||||
|
||||
if (++ip < npages) {
|
||||
do {
|
||||
cp++;
|
||||
} while (cp[-1] != '\0' ||
|
||||
(iteration != ITER_DESC && cp[-2] != '\0'));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct dbm_res
|
||||
page_byarch(const struct dbm_match *arg_match)
|
||||
{
|
||||
static const struct dbm_match *match;
|
||||
struct dbm_res res = {-1, 0};
|
||||
static int32_t ip;
|
||||
const char *cp;
|
||||
|
||||
/* Initialize for a new iteration. */
|
||||
|
||||
if (arg_match != NULL) {
|
||||
iteration = ITER_ARCH;
|
||||
match = arg_match;
|
||||
ip = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Search for an architecture. */
|
||||
|
||||
for ( ; ip < npages; ip++)
|
||||
if (pages[ip].arch)
|
||||
for (cp = dbm_get(pages[ip].arch);
|
||||
*cp != '\0';
|
||||
cp = strchr(cp, '\0') + 1)
|
||||
if (dbm_match(match, cp)) {
|
||||
res.page = ip++;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Reached the end without a match. */
|
||||
|
||||
iteration = ITER_NONE;
|
||||
match = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct dbm_res
|
||||
page_bymacro(int32_t arg_im, const struct dbm_match *arg_match)
|
||||
{
|
||||
static const struct dbm_match *match;
|
||||
static const int32_t *pp;
|
||||
static const char *cp;
|
||||
static int32_t im, iv;
|
||||
struct dbm_res res = {-1, 0};
|
||||
|
||||
assert(im >= 0);
|
||||
assert(im < MACRO_MAX);
|
||||
|
||||
/* Initialize for a new iteration. */
|
||||
|
||||
if (arg_match != NULL) {
|
||||
iteration = ITER_MACRO;
|
||||
match = arg_match;
|
||||
im = arg_im;
|
||||
cp = nvals[im] ? dbm_get(macros[im]->value) : NULL;
|
||||
pp = NULL;
|
||||
iv = -1;
|
||||
return res;
|
||||
}
|
||||
if (iteration != ITER_MACRO)
|
||||
return res;
|
||||
|
||||
/* Find the next matching macro value. */
|
||||
|
||||
while (pp == NULL || *pp == 0) {
|
||||
if (++iv == nvals[im]) {
|
||||
iteration = ITER_NONE;
|
||||
return res;
|
||||
}
|
||||
if (iv)
|
||||
cp = strchr(cp, '\0') + 1;
|
||||
if (dbm_match(match, cp))
|
||||
pp = dbm_get(macros[im][iv].pages);
|
||||
}
|
||||
|
||||
/* Found a matching page. */
|
||||
|
||||
res.page = (struct page *)dbm_get(*pp++) - pages;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*** functions for handling macros ************************************/
|
||||
|
||||
int32_t
|
||||
dbm_macro_count(int32_t im)
|
||||
{
|
||||
assert(im >= 0);
|
||||
assert(im < MACRO_MAX);
|
||||
return nvals[im];
|
||||
}
|
||||
|
||||
struct dbm_macro *
|
||||
dbm_macro_get(int32_t im, int32_t iv)
|
||||
{
|
||||
static struct dbm_macro macro;
|
||||
|
||||
assert(im >= 0);
|
||||
assert(im < MACRO_MAX);
|
||||
assert(iv >= 0);
|
||||
assert(iv < nvals[im]);
|
||||
macro.value = dbm_get(macros[im][iv].value);
|
||||
macro.pp = dbm_get(macros[im][iv].pages);
|
||||
return ¯o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Filtered iteration over macro entries.
|
||||
*/
|
||||
void
|
||||
dbm_macro_bypage(int32_t im, int32_t ip)
|
||||
{
|
||||
assert(im >= 0);
|
||||
assert(im < MACRO_MAX);
|
||||
assert(ip != 0);
|
||||
macro_bypage(im, ip);
|
||||
}
|
||||
|
||||
char *
|
||||
dbm_macro_next(void)
|
||||
{
|
||||
return macro_bypage(MACRO_MAX, 0);
|
||||
}
|
||||
|
||||
static char *
|
||||
macro_bypage(int32_t arg_im, int32_t arg_ip)
|
||||
{
|
||||
static const int32_t *pp;
|
||||
static int32_t im, ip, iv;
|
||||
|
||||
/* Initialize for a new iteration. */
|
||||
|
||||
if (arg_im < MACRO_MAX && arg_ip != 0) {
|
||||
im = arg_im;
|
||||
ip = arg_ip;
|
||||
pp = dbm_get(macros[im]->pages);
|
||||
iv = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (im >= MACRO_MAX)
|
||||
return NULL;
|
||||
|
||||
/* Search for the next value. */
|
||||
|
||||
while (iv < nvals[im]) {
|
||||
if (*pp == ip)
|
||||
break;
|
||||
if (*pp == 0)
|
||||
iv++;
|
||||
pp++;
|
||||
}
|
||||
|
||||
/* Reached the end without a match. */
|
||||
|
||||
if (iv == nvals[im]) {
|
||||
im = MACRO_MAX;
|
||||
ip = 0;
|
||||
pp = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Found a match; skip the remaining pages of this entry. */
|
||||
|
||||
if (++iv < nvals[im])
|
||||
while (*pp++ != 0)
|
||||
continue;
|
||||
|
||||
return dbm_get(macros[im][iv - 1].value);
|
||||
}
|
68
dbm.h
Normal file
68
dbm.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* $Id: dbm.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Public interface for the map-based version
|
||||
* of the mandoc database, for read-only access.
|
||||
* To be used by dbm*.c, dba_read.c, and man(1) and apropos(1).
|
||||
*/
|
||||
|
||||
enum dbm_mtype {
|
||||
DBM_EXACT = 0,
|
||||
DBM_SUB,
|
||||
DBM_REGEX
|
||||
};
|
||||
|
||||
struct dbm_match {
|
||||
regex_t *re;
|
||||
const char *str;
|
||||
enum dbm_mtype type;
|
||||
};
|
||||
|
||||
struct dbm_res {
|
||||
int32_t page;
|
||||
int32_t bits;
|
||||
};
|
||||
|
||||
struct dbm_page {
|
||||
const char *name;
|
||||
const char *sect;
|
||||
const char *arch;
|
||||
const char *desc;
|
||||
const char *file;
|
||||
int32_t addr;
|
||||
};
|
||||
|
||||
struct dbm_macro {
|
||||
const char *value;
|
||||
const int32_t *pp;
|
||||
};
|
||||
|
||||
int dbm_open(const char *);
|
||||
void dbm_close(void);
|
||||
|
||||
int32_t dbm_page_count(void);
|
||||
struct dbm_page *dbm_page_get(int32_t);
|
||||
void dbm_page_byname(const struct dbm_match *);
|
||||
void dbm_page_bysect(const struct dbm_match *);
|
||||
void dbm_page_byarch(const struct dbm_match *);
|
||||
void dbm_page_bydesc(const struct dbm_match *);
|
||||
void dbm_page_bymacro(int32_t, const struct dbm_match *);
|
||||
struct dbm_res dbm_page_next(void);
|
||||
|
||||
int32_t dbm_macro_count(int32_t);
|
||||
struct dbm_macro *dbm_macro_get(int32_t, int32_t);
|
||||
void dbm_macro_bypage(int32_t, int32_t);
|
||||
char *dbm_macro_next(void);
|
194
dbm_map.c
Normal file
194
dbm_map.c
Normal file
@ -0,0 +1,194 @@
|
||||
/* $Id: dbm_map.c,v 1.7 2016/10/22 10:09:27 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.
|
||||
*
|
||||
* Low-level routines for the map-based version
|
||||
* of the mandoc database, for read-only access.
|
||||
* The interface is defined in "dbm_map.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if HAVE_ENDIAN
|
||||
#include <endian.h>
|
||||
#elif HAVE_SYS_ENDIAN
|
||||
#include <sys/endian.h>
|
||||
#elif HAVE_NTOHL
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <regex.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mansearch.h"
|
||||
#include "dbm_map.h"
|
||||
#include "dbm.h"
|
||||
|
||||
static struct stat st;
|
||||
static char *dbm_base;
|
||||
static int ifd;
|
||||
static int32_t max_offset;
|
||||
|
||||
/*
|
||||
* Open a disk-based database for read-only access.
|
||||
* Validate the file format as far as it is not mandoc-specific.
|
||||
* Return 0 on success. Return -1 and set errno on failure.
|
||||
*/
|
||||
int
|
||||
dbm_map(const char *fname)
|
||||
{
|
||||
int save_errno;
|
||||
const int32_t *magic;
|
||||
|
||||
if ((ifd = open(fname, O_RDONLY)) == -1)
|
||||
return -1;
|
||||
if (fstat(ifd, &st) == -1)
|
||||
goto fail;
|
||||
if (st.st_size < 5) {
|
||||
warnx("dbm_map(%s): File too short", fname);
|
||||
errno = EFTYPE;
|
||||
goto fail;
|
||||
}
|
||||
if (st.st_size > INT32_MAX) {
|
||||
errno = EFBIG;
|
||||
goto fail;
|
||||
}
|
||||
if ((dbm_base = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED,
|
||||
ifd, 0)) == MAP_FAILED)
|
||||
goto fail;
|
||||
magic = dbm_getint(0);
|
||||
if (be32toh(*magic) != MANDOCDB_MAGIC) {
|
||||
if (strncmp(dbm_base, "SQLite format 3", 15))
|
||||
warnx("dbm_map(%s): "
|
||||
"Bad initial magic %x (expected %x)",
|
||||
fname, be32toh(*magic), MANDOCDB_MAGIC);
|
||||
else
|
||||
warnx("dbm_map(%s): "
|
||||
"Obsolete format based on SQLite 3",
|
||||
fname);
|
||||
errno = EFTYPE;
|
||||
goto fail;
|
||||
}
|
||||
magic = dbm_getint(1);
|
||||
if (be32toh(*magic) != MANDOCDB_VERSION) {
|
||||
warnx("dbm_map(%s): Bad version number %d (expected %d)",
|
||||
fname, be32toh(*magic), MANDOCDB_VERSION);
|
||||
errno = EFTYPE;
|
||||
goto fail;
|
||||
}
|
||||
max_offset = be32toh(*dbm_getint(3)) + sizeof(int32_t);
|
||||
if (st.st_size != max_offset) {
|
||||
warnx("dbm_map(%s): Inconsistent file size %lld (expected %d)",
|
||||
fname, (long long)st.st_size, max_offset);
|
||||
errno = EFTYPE;
|
||||
goto fail;
|
||||
}
|
||||
if ((magic = dbm_get(*dbm_getint(3))) == NULL) {
|
||||
errno = EFTYPE;
|
||||
goto fail;
|
||||
}
|
||||
if (be32toh(*magic) != MANDOCDB_MAGIC) {
|
||||
warnx("dbm_map(%s): Bad final magic %x (expected %x)",
|
||||
fname, be32toh(*magic), MANDOCDB_MAGIC);
|
||||
errno = EFTYPE;
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
save_errno = errno;
|
||||
close(ifd);
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
dbm_unmap(void)
|
||||
{
|
||||
if (munmap(dbm_base, st.st_size) == -1)
|
||||
warn("dbm_unmap: munmap");
|
||||
if (close(ifd) == -1)
|
||||
warn("dbm_unmap: close");
|
||||
dbm_base = (char *)-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Take a raw integer as it was read from the database.
|
||||
* Interpret it as an offset into the database file
|
||||
* and return a pointer to that place in the file.
|
||||
*/
|
||||
void *
|
||||
dbm_get(int32_t offset)
|
||||
{
|
||||
offset = be32toh(offset);
|
||||
if (offset < 0) {
|
||||
warnx("dbm_get: Database corrupt: offset %d", offset);
|
||||
return NULL;
|
||||
}
|
||||
if (offset >= max_offset) {
|
||||
warnx("dbm_get: Database corrupt: offset %d > %d",
|
||||
offset, max_offset);
|
||||
return NULL;
|
||||
}
|
||||
return dbm_base + offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume the database starts with some integers.
|
||||
* Assume they are numbered starting from 0, increasing.
|
||||
* Get a pointer to one with the number "offset".
|
||||
*/
|
||||
int32_t *
|
||||
dbm_getint(int32_t offset)
|
||||
{
|
||||
return (int32_t *)dbm_base + offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* The reverse of dbm_get().
|
||||
* Take pointer into the database file
|
||||
* and convert it to the raw integer
|
||||
* that would be used to refer to that place in the file.
|
||||
*/
|
||||
int32_t
|
||||
dbm_addr(const void *p)
|
||||
{
|
||||
return htobe32((char *)p - dbm_base);
|
||||
}
|
||||
|
||||
int
|
||||
dbm_match(const struct dbm_match *match, const char *str)
|
||||
{
|
||||
switch (match->type) {
|
||||
case DBM_EXACT:
|
||||
return strcmp(str, match->str) == 0;
|
||||
case DBM_SUB:
|
||||
return strcasestr(str, match->str) != NULL;
|
||||
case DBM_REGEX:
|
||||
return regexec(match->re, str, 0, NULL, 0) == 0;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/* $Id: mansearch_const.c,v 1.7 2014/12/01 08:05:52 schwarze Exp $ */
|
||||
/* $Id: dbm_map.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 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
|
||||
@ -13,21 +13,17 @@
|
||||
* 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.
|
||||
*
|
||||
* Private interface for low-level routines for the map-based version
|
||||
* of the mandoc database, for read-only access.
|
||||
* To be used by dbm*.c only.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
struct dbm_match;
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mansearch.h"
|
||||
|
||||
const int mansearch_keymax = 40;
|
||||
|
||||
const char *const mansearch_keynames[40] = {
|
||||
"arch", "sec", "Xr", "Ar", "Fa", "Fl", "Dv", "Fn",
|
||||
"Ic", "Pa", "Cm", "Li", "Em", "Cd", "Va", "Ft",
|
||||
"Tn", "Er", "Ev", "Sy", "Sh", "In", "Ss", "Ox",
|
||||
"An", "Mt", "St", "Bx", "At", "Nx", "Fx", "Lk",
|
||||
"Ms", "Bsx", "Dx", "Rs", "Vt", "Lb", "Nm", "Nd"
|
||||
};
|
||||
int dbm_map(const char *);
|
||||
void dbm_unmap(void);
|
||||
void *dbm_get(int32_t);
|
||||
int32_t *dbm_getint(int32_t);
|
||||
int32_t dbm_addr(const void *);
|
||||
int dbm_match(const struct dbm_match *, const char *);
|
@ -1,4 +1,4 @@
|
||||
/* $Id: demandoc.c,v 1.27 2016/07/09 15:24:19 schwarze Exp $ */
|
||||
/* $Id: demandoc.c,v 1.28 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -239,7 +239,7 @@ pmdoc(const struct roff_node *p, int *line, int *col, int list)
|
||||
{
|
||||
|
||||
for ( ; p; p = p->next) {
|
||||
if (MDOC_LINE & p->flags)
|
||||
if (NODE_LINE & p->flags)
|
||||
pline(p->line, line, col, list);
|
||||
if (ROFFT_TEXT == p->type)
|
||||
pstring(p->string, p->pos, col, list);
|
||||
@ -253,7 +253,7 @@ pman(const struct roff_node *p, int *line, int *col, int list)
|
||||
{
|
||||
|
||||
for ( ; p; p = p->next) {
|
||||
if (MAN_LINE & p->flags)
|
||||
if (NODE_LINE & p->flags)
|
||||
pline(p->line, line, col, list);
|
||||
if (ROFFT_TEXT == p->type)
|
||||
pstring(p->string, p->pos, col, list);
|
||||
|
64
eqn_html.c
64
eqn_html.c
@ -1,6 +1,7 @@
|
||||
/* $Id: eqn_html.c,v 1.10 2014/10/12 19:31:41 schwarze Exp $ */
|
||||
/* $Id: eqn_html.c,v 1.11 2017/01/17 01:47:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -31,7 +32,6 @@ static void
|
||||
eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
{
|
||||
struct tag *post, *row, *cell, *t;
|
||||
struct htmlpair tag[2];
|
||||
const struct eqn_box *child, *parent;
|
||||
size_t i, j, rows;
|
||||
|
||||
@ -59,10 +59,10 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
for (rows = 0; NULL != child; rows++)
|
||||
child = child->next;
|
||||
/* Print row-by-row. */
|
||||
post = print_otag(p, TAG_MTABLE, 0, NULL);
|
||||
post = print_otag(p, TAG_MTABLE, "");
|
||||
for (i = 0; i < rows; i++) {
|
||||
parent = bp->first->first;
|
||||
row = print_otag(p, TAG_MTR, 0, NULL);
|
||||
row = print_otag(p, TAG_MTR, "");
|
||||
while (NULL != parent) {
|
||||
child = parent->first;
|
||||
for (j = 0; j < i; j++) {
|
||||
@ -70,8 +70,7 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
break;
|
||||
child = child->next;
|
||||
}
|
||||
cell = print_otag
|
||||
(p, TAG_MTD, 0, NULL);
|
||||
cell = print_otag(p, TAG_MTD, "");
|
||||
/*
|
||||
* If we have no data for this
|
||||
* particular cell, then print a
|
||||
@ -89,28 +88,28 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
|
||||
switch (bp->pos) {
|
||||
case (EQNPOS_TO):
|
||||
post = print_otag(p, TAG_MOVER, 0, NULL);
|
||||
post = print_otag(p, TAG_MOVER, "");
|
||||
break;
|
||||
case (EQNPOS_SUP):
|
||||
post = print_otag(p, TAG_MSUP, 0, NULL);
|
||||
post = print_otag(p, TAG_MSUP, "");
|
||||
break;
|
||||
case (EQNPOS_FROM):
|
||||
post = print_otag(p, TAG_MUNDER, 0, NULL);
|
||||
post = print_otag(p, TAG_MUNDER, "");
|
||||
break;
|
||||
case (EQNPOS_SUB):
|
||||
post = print_otag(p, TAG_MSUB, 0, NULL);
|
||||
post = print_otag(p, TAG_MSUB, "");
|
||||
break;
|
||||
case (EQNPOS_OVER):
|
||||
post = print_otag(p, TAG_MFRAC, 0, NULL);
|
||||
post = print_otag(p, TAG_MFRAC, "");
|
||||
break;
|
||||
case (EQNPOS_FROMTO):
|
||||
post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
|
||||
post = print_otag(p, TAG_MUNDEROVER, "");
|
||||
break;
|
||||
case (EQNPOS_SUBSUP):
|
||||
post = print_otag(p, TAG_MSUBSUP, 0, NULL);
|
||||
post = print_otag(p, TAG_MSUBSUP, "");
|
||||
break;
|
||||
case (EQNPOS_SQRT):
|
||||
post = print_otag(p, TAG_MSQRT, 0, NULL);
|
||||
post = print_otag(p, TAG_MSQRT, "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -119,52 +118,49 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
if (bp->top || bp->bottom) {
|
||||
assert(NULL == post);
|
||||
if (bp->top && NULL == bp->bottom)
|
||||
post = print_otag(p, TAG_MOVER, 0, NULL);
|
||||
post = print_otag(p, TAG_MOVER, "");
|
||||
else if (bp->top && bp->bottom)
|
||||
post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
|
||||
post = print_otag(p, TAG_MUNDEROVER, "");
|
||||
else if (bp->bottom)
|
||||
post = print_otag(p, TAG_MUNDER, 0, NULL);
|
||||
post = print_otag(p, TAG_MUNDER, "");
|
||||
}
|
||||
|
||||
if (EQN_PILE == bp->type) {
|
||||
assert(NULL == post);
|
||||
if (bp->first != NULL && bp->first->type == EQN_LIST)
|
||||
post = print_otag(p, TAG_MTABLE, 0, NULL);
|
||||
post = print_otag(p, TAG_MTABLE, "");
|
||||
} else if (bp->type == EQN_LIST &&
|
||||
bp->parent && bp->parent->type == EQN_PILE) {
|
||||
assert(NULL == post);
|
||||
post = print_otag(p, TAG_MTR, 0, NULL);
|
||||
print_otag(p, TAG_MTD, 0, NULL);
|
||||
post = print_otag(p, TAG_MTR, "");
|
||||
print_otag(p, TAG_MTD, "");
|
||||
}
|
||||
|
||||
if (NULL != bp->text) {
|
||||
assert(NULL == post);
|
||||
post = print_otag(p, TAG_MI, 0, NULL);
|
||||
post = print_otag(p, TAG_MI, "");
|
||||
print_text(p, bp->text);
|
||||
} else if (NULL == post) {
|
||||
if (NULL != bp->left || NULL != bp->right) {
|
||||
PAIR_INIT(&tag[0], ATTR_OPEN,
|
||||
NULL == bp->left ? "" : bp->left);
|
||||
PAIR_INIT(&tag[1], ATTR_CLOSE,
|
||||
NULL == bp->right ? "" : bp->right);
|
||||
post = print_otag(p, TAG_MFENCED, 2, tag);
|
||||
}
|
||||
if (NULL != bp->left || NULL != bp->right)
|
||||
post = print_otag(p, TAG_MFENCED, "??",
|
||||
"open", bp->left == NULL ? "" : bp->left,
|
||||
"close", bp->right == NULL ? "" : bp->right);
|
||||
if (NULL == post)
|
||||
post = print_otag(p, TAG_MROW, 0, NULL);
|
||||
post = print_otag(p, TAG_MROW, "");
|
||||
else
|
||||
print_otag(p, TAG_MROW, 0, NULL);
|
||||
print_otag(p, TAG_MROW, "");
|
||||
}
|
||||
|
||||
eqn_box(p, bp->first);
|
||||
|
||||
out:
|
||||
if (NULL != bp->bottom) {
|
||||
t = print_otag(p, TAG_MO, 0, NULL);
|
||||
t = print_otag(p, TAG_MO, "");
|
||||
print_text(p, bp->bottom);
|
||||
print_tagq(p, t);
|
||||
}
|
||||
if (NULL != bp->top) {
|
||||
t = print_otag(p, TAG_MO, 0, NULL);
|
||||
t = print_otag(p, TAG_MO, "");
|
||||
print_text(p, bp->top);
|
||||
print_tagq(p, t);
|
||||
}
|
||||
@ -178,11 +174,9 @@ out:
|
||||
void
|
||||
print_eqn(struct html *p, const struct eqn *ep)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct tag *t;
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "eqn");
|
||||
t = print_otag(p, TAG_MATH, 1, &tag);
|
||||
t = print_otag(p, TAG_MATH, "c", "eqn");
|
||||
|
||||
p->flags |= HTML_NONOSPACE;
|
||||
eqn_box(p, ep->root);
|
||||
|
717
html.c
717
html.c
@ -1,7 +1,7 @@
|
||||
/* $Id: html.c,v 1.192 2016/01/04 12:45:29 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.200 2017/01/21 02:29:57 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -38,74 +38,65 @@
|
||||
struct htmldata {
|
||||
const char *name;
|
||||
int flags;
|
||||
#define HTML_CLRLINE (1 << 0)
|
||||
#define HTML_NOSTACK (1 << 1)
|
||||
#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */
|
||||
#define HTML_NOSTACK (1 << 0)
|
||||
#define HTML_AUTOCLOSE (1 << 1)
|
||||
#define HTML_NLBEFORE (1 << 2)
|
||||
#define HTML_NLBEGIN (1 << 3)
|
||||
#define HTML_NLEND (1 << 4)
|
||||
#define HTML_NLAFTER (1 << 5)
|
||||
#define HTML_NLAROUND (HTML_NLBEFORE | HTML_NLAFTER)
|
||||
#define HTML_NLINSIDE (HTML_NLBEGIN | HTML_NLEND)
|
||||
#define HTML_NLALL (HTML_NLAROUND | HTML_NLINSIDE)
|
||||
#define HTML_INDENT (1 << 6)
|
||||
#define HTML_NOINDENT (1 << 7)
|
||||
};
|
||||
|
||||
static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"html", HTML_CLRLINE}, /* TAG_HTML */
|
||||
{"head", HTML_CLRLINE}, /* TAG_HEAD */
|
||||
{"body", HTML_CLRLINE}, /* TAG_BODY */
|
||||
{"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */
|
||||
{"title", HTML_CLRLINE}, /* TAG_TITLE */
|
||||
{"div", HTML_CLRLINE}, /* TAG_DIV */
|
||||
{"h1", 0}, /* TAG_H1 */
|
||||
{"h2", 0}, /* TAG_H2 */
|
||||
{"span", 0}, /* TAG_SPAN */
|
||||
{"link", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_LINK */
|
||||
{"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */
|
||||
{"a", 0}, /* TAG_A */
|
||||
{"table", HTML_CLRLINE}, /* TAG_TABLE */
|
||||
{"tbody", HTML_CLRLINE}, /* TAG_TBODY */
|
||||
{"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */
|
||||
{"tr", HTML_CLRLINE}, /* TAG_TR */
|
||||
{"td", HTML_CLRLINE}, /* TAG_TD */
|
||||
{"li", HTML_CLRLINE}, /* TAG_LI */
|
||||
{"ul", HTML_CLRLINE}, /* TAG_UL */
|
||||
{"ol", HTML_CLRLINE}, /* TAG_OL */
|
||||
{"dl", HTML_CLRLINE}, /* TAG_DL */
|
||||
{"dt", HTML_CLRLINE}, /* TAG_DT */
|
||||
{"dd", HTML_CLRLINE}, /* TAG_DD */
|
||||
{"blockquote", HTML_CLRLINE}, /* TAG_BLOCKQUOTE */
|
||||
{"pre", HTML_CLRLINE }, /* TAG_PRE */
|
||||
{"b", 0 }, /* TAG_B */
|
||||
{"i", 0 }, /* TAG_I */
|
||||
{"code", 0 }, /* TAG_CODE */
|
||||
{"small", 0 }, /* TAG_SMALL */
|
||||
{"style", HTML_CLRLINE}, /* TAG_STYLE */
|
||||
{"math", HTML_CLRLINE}, /* TAG_MATH */
|
||||
{"mrow", 0}, /* TAG_MROW */
|
||||
{"mi", 0}, /* TAG_MI */
|
||||
{"mo", 0}, /* TAG_MO */
|
||||
{"msup", 0}, /* TAG_MSUP */
|
||||
{"msub", 0}, /* TAG_MSUB */
|
||||
{"msubsup", 0}, /* TAG_MSUBSUP */
|
||||
{"mfrac", 0}, /* TAG_MFRAC */
|
||||
{"msqrt", 0}, /* TAG_MSQRT */
|
||||
{"mfenced", 0}, /* TAG_MFENCED */
|
||||
{"mtable", 0}, /* TAG_MTABLE */
|
||||
{"mtr", 0}, /* TAG_MTR */
|
||||
{"mtd", 0}, /* TAG_MTD */
|
||||
{"munderover", 0}, /* TAG_MUNDEROVER */
|
||||
{"munder", 0}, /* TAG_MUNDER*/
|
||||
{"mover", 0}, /* TAG_MOVER*/
|
||||
};
|
||||
|
||||
static const char *const htmlattrs[ATTR_MAX] = {
|
||||
"name", /* ATTR_NAME */
|
||||
"rel", /* ATTR_REL */
|
||||
"href", /* ATTR_HREF */
|
||||
"type", /* ATTR_TYPE */
|
||||
"media", /* ATTR_MEDIA */
|
||||
"class", /* ATTR_CLASS */
|
||||
"style", /* ATTR_STYLE */
|
||||
"id", /* ATTR_ID */
|
||||
"colspan", /* ATTR_COLSPAN */
|
||||
"charset", /* ATTR_CHARSET */
|
||||
"open", /* ATTR_OPEN */
|
||||
"close", /* ATTR_CLOSE */
|
||||
"mathvariant", /* ATTR_MATHVARIANT */
|
||||
{"html", HTML_NLALL},
|
||||
{"head", HTML_NLALL | HTML_INDENT},
|
||||
{"body", HTML_NLALL},
|
||||
{"meta", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"title", HTML_NLAROUND},
|
||||
{"div", HTML_NLAROUND},
|
||||
{"h1", HTML_NLAROUND},
|
||||
{"h2", HTML_NLAROUND},
|
||||
{"span", 0},
|
||||
{"link", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"br", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"a", 0},
|
||||
{"table", HTML_NLALL | HTML_INDENT},
|
||||
{"tbody", HTML_NLALL | HTML_INDENT},
|
||||
{"col", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"tr", HTML_NLALL | HTML_INDENT},
|
||||
{"td", HTML_NLAROUND},
|
||||
{"li", HTML_NLAROUND | HTML_INDENT},
|
||||
{"ul", HTML_NLALL | HTML_INDENT},
|
||||
{"ol", HTML_NLALL | HTML_INDENT},
|
||||
{"dl", HTML_NLALL | HTML_INDENT},
|
||||
{"dt", HTML_NLAROUND},
|
||||
{"dd", HTML_NLAROUND | HTML_INDENT},
|
||||
{"pre", HTML_NLALL | HTML_NOINDENT},
|
||||
{"b", 0},
|
||||
{"i", 0},
|
||||
{"code", 0},
|
||||
{"small", 0},
|
||||
{"style", HTML_NLALL | HTML_INDENT},
|
||||
{"math", HTML_NLALL | HTML_INDENT},
|
||||
{"mrow", 0},
|
||||
{"mi", 0},
|
||||
{"mo", 0},
|
||||
{"msup", 0},
|
||||
{"msub", 0},
|
||||
{"msubsup", 0},
|
||||
{"mfrac", 0},
|
||||
{"msqrt", 0},
|
||||
{"mfenced", 0},
|
||||
{"mtable", 0},
|
||||
{"mtr", 0},
|
||||
{"mtd", 0},
|
||||
{"munderover", 0},
|
||||
{"munder", 0},
|
||||
{"mover", 0},
|
||||
};
|
||||
|
||||
static const char *const roffscales[SCALE_MAX] = {
|
||||
@ -121,12 +112,18 @@ static const char *const roffscales[SCALE_MAX] = {
|
||||
"ex", /* SCALE_FS */
|
||||
};
|
||||
|
||||
static void bufncat(struct html *, const char *, size_t);
|
||||
static void a2width(const char *, struct roffsu *);
|
||||
static void print_byte(struct html *, char);
|
||||
static void print_endline(struct html *);
|
||||
static void print_endword(struct html *);
|
||||
static void print_indent(struct html *);
|
||||
static void print_word(struct html *, const char *);
|
||||
|
||||
static void print_ctag(struct html *, struct tag *);
|
||||
static int print_escape(char);
|
||||
static int print_encode(struct html *, const char *, int);
|
||||
static int print_escape(struct html *, char);
|
||||
static int print_encode(struct html *, const char *, const char *, int);
|
||||
static void print_href(struct html *, const char *, const char *, int);
|
||||
static void print_metaf(struct html *, enum mandoc_esc);
|
||||
static void print_attr(struct html *, const char *, const char *);
|
||||
|
||||
|
||||
void *
|
||||
@ -165,36 +162,27 @@ html_free(void *p)
|
||||
void
|
||||
print_gen_head(struct html *h)
|
||||
{
|
||||
struct htmlpair tag[4];
|
||||
struct tag *t;
|
||||
|
||||
tag[0].key = ATTR_CHARSET;
|
||||
tag[0].val = "utf-8";
|
||||
print_otag(h, TAG_META, 1, tag);
|
||||
print_otag(h, TAG_META, "?", "charset", "utf-8");
|
||||
|
||||
/*
|
||||
* Print a default style-sheet.
|
||||
*/
|
||||
t = print_otag(h, TAG_STYLE, 0, NULL);
|
||||
print_text(h, "table.head, table.foot { width: 100%; }\n"
|
||||
"td.head-rtitle, td.foot-os { text-align: right; }\n"
|
||||
"td.head-vol { text-align: center; }\n"
|
||||
"table.foot td { width: 50%; }\n"
|
||||
"table.head td { width: 33%; }\n"
|
||||
"div.spacer { margin: 1em 0; }\n");
|
||||
|
||||
t = print_otag(h, TAG_STYLE, "");
|
||||
print_text(h, "table.head, table.foot { width: 100%; }");
|
||||
print_endline(h);
|
||||
print_text(h, "td.head-rtitle, td.foot-os { text-align: right; }");
|
||||
print_endline(h);
|
||||
print_text(h, "td.head-vol { text-align: center; }");
|
||||
print_endline(h);
|
||||
print_text(h, "div.Pp { margin: 1ex 0ex; }");
|
||||
print_tagq(h, t);
|
||||
|
||||
if (h->style) {
|
||||
tag[0].key = ATTR_REL;
|
||||
tag[0].val = "stylesheet";
|
||||
tag[1].key = ATTR_HREF;
|
||||
tag[1].val = h->style;
|
||||
tag[2].key = ATTR_TYPE;
|
||||
tag[2].val = "text/css";
|
||||
tag[3].key = ATTR_MEDIA;
|
||||
tag[3].val = "all";
|
||||
print_otag(h, TAG_LINK, 4, tag);
|
||||
}
|
||||
if (h->style)
|
||||
print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet",
|
||||
h->style, "type", "text/css", "media", "all");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -233,14 +221,14 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
|
||||
switch (font) {
|
||||
case HTMLFONT_ITALIC:
|
||||
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
||||
h->metaf = print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_BOLD:
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
break;
|
||||
case HTMLFONT_BI:
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -299,27 +287,27 @@ html_strlen(const char *cp)
|
||||
}
|
||||
|
||||
static int
|
||||
print_escape(char c)
|
||||
print_escape(struct html *h, char c)
|
||||
{
|
||||
|
||||
switch (c) {
|
||||
case '<':
|
||||
printf("<");
|
||||
print_word(h, "<");
|
||||
break;
|
||||
case '>':
|
||||
printf(">");
|
||||
print_word(h, ">");
|
||||
break;
|
||||
case '&':
|
||||
printf("&");
|
||||
print_word(h, "&");
|
||||
break;
|
||||
case '"':
|
||||
printf(""");
|
||||
print_word(h, """);
|
||||
break;
|
||||
case ASCII_NBRSP:
|
||||
printf(" ");
|
||||
print_word(h, " ");
|
||||
break;
|
||||
case ASCII_HYPH:
|
||||
putchar('-');
|
||||
print_byte(h, '-');
|
||||
break;
|
||||
case ASCII_BREAK:
|
||||
break;
|
||||
@ -330,8 +318,9 @@ print_escape(char c)
|
||||
}
|
||||
|
||||
static int
|
||||
print_encode(struct html *h, const char *p, int norecurse)
|
||||
print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
{
|
||||
char numbuf[16];
|
||||
size_t sz;
|
||||
int c, len, nospace;
|
||||
const char *seq;
|
||||
@ -339,24 +328,28 @@ print_encode(struct html *h, const char *p, int norecurse)
|
||||
static const char rejs[9] = { '\\', '<', '>', '&', '"',
|
||||
ASCII_NBRSP, ASCII_HYPH, ASCII_BREAK, '\0' };
|
||||
|
||||
if (pend == NULL)
|
||||
pend = strchr(p, '\0');
|
||||
|
||||
nospace = 0;
|
||||
|
||||
while ('\0' != *p) {
|
||||
while (p < pend) {
|
||||
if (HTML_SKIPCHAR & h->flags && '\\' != *p) {
|
||||
h->flags &= ~HTML_SKIPCHAR;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
sz = strcspn(p, rejs);
|
||||
for (sz = strcspn(p, rejs); sz-- && p < pend; p++)
|
||||
if (*p == ' ')
|
||||
print_endword(h);
|
||||
else
|
||||
print_byte(h, *p);
|
||||
|
||||
fwrite(p, 1, sz, stdout);
|
||||
p += (int)sz;
|
||||
|
||||
if ('\0' == *p)
|
||||
if (p >= pend)
|
||||
break;
|
||||
|
||||
if (print_escape(*p++))
|
||||
if (print_escape(h, *p++))
|
||||
continue;
|
||||
|
||||
esc = mandoc_escape(&p, &seq, &len);
|
||||
@ -415,33 +408,57 @@ print_encode(struct html *h, const char *p, int norecurse)
|
||||
if ((c < 0x20 && c != 0x09) ||
|
||||
(c > 0x7E && c < 0xA0))
|
||||
c = 0xFFFD;
|
||||
if (c > 0x7E)
|
||||
printf("&#%d;", c);
|
||||
else if ( ! print_escape(c))
|
||||
putchar(c);
|
||||
if (c > 0x7E) {
|
||||
(void)snprintf(numbuf, sizeof(numbuf), "&#%d;", c);
|
||||
print_word(h, numbuf);
|
||||
} else if (print_escape(h, c) == 0)
|
||||
print_byte(h, c);
|
||||
}
|
||||
|
||||
return nospace;
|
||||
}
|
||||
|
||||
static void
|
||||
print_attr(struct html *h, const char *key, const char *val)
|
||||
print_href(struct html *h, const char *name, const char *sec, int man)
|
||||
{
|
||||
printf(" %s=\"", key);
|
||||
(void)print_encode(h, val, 1);
|
||||
putchar('\"');
|
||||
const char *p, *pp;
|
||||
|
||||
pp = man ? h->base_man : h->base_includes;
|
||||
while ((p = strchr(pp, '%')) != NULL) {
|
||||
print_encode(h, pp, p, 1);
|
||||
if (man && p[1] == 'S') {
|
||||
if (sec == NULL)
|
||||
print_byte(h, '1');
|
||||
else
|
||||
print_encode(h, sec, NULL, 1);
|
||||
} else if ((man && p[1] == 'N') ||
|
||||
(man == 0 && p[1] == 'I'))
|
||||
print_encode(h, name, NULL, 1);
|
||||
else
|
||||
print_encode(h, p, p + 2, 1);
|
||||
pp = p + 2;
|
||||
}
|
||||
if (*pp != '\0')
|
||||
print_encode(h, pp, NULL, 1);
|
||||
}
|
||||
|
||||
struct tag *
|
||||
print_otag(struct html *h, enum htmltag tag,
|
||||
int sz, const struct htmlpair *p)
|
||||
print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
{
|
||||
int i;
|
||||
va_list ap;
|
||||
struct roffsu mysu, *su;
|
||||
char numbuf[16];
|
||||
struct tag *t;
|
||||
const char *attr;
|
||||
char *s;
|
||||
double v;
|
||||
int i, have_style, tflags;
|
||||
|
||||
tflags = htmltags[tag].flags;
|
||||
|
||||
/* Push this tags onto the stack of open scopes. */
|
||||
|
||||
if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
|
||||
if ((tflags & HTML_NOSTACK) == 0) {
|
||||
t = mandoc_malloc(sizeof(struct tag));
|
||||
t->tag = tag;
|
||||
t->next = h->tags.head;
|
||||
@ -449,16 +466,19 @@ print_otag(struct html *h, enum htmltag tag,
|
||||
} else
|
||||
t = NULL;
|
||||
|
||||
if ( ! (HTML_NOSPACE & h->flags))
|
||||
if ( ! (HTML_CLRLINE & htmltags[tag].flags)) {
|
||||
/* Manage keeps! */
|
||||
if ( ! (HTML_KEEP & h->flags)) {
|
||||
if (HTML_PREKEEP & h->flags)
|
||||
h->flags |= HTML_KEEP;
|
||||
putchar(' ');
|
||||
} else
|
||||
printf(" ");
|
||||
if (tflags & HTML_NLBEFORE)
|
||||
print_endline(h);
|
||||
if (h->col == 0)
|
||||
print_indent(h);
|
||||
else if ((h->flags & HTML_NOSPACE) == 0) {
|
||||
if (h->flags & HTML_KEEP)
|
||||
print_word(h, " ");
|
||||
else {
|
||||
if (h->flags & HTML_PREKEEP)
|
||||
h->flags |= HTML_KEEP;
|
||||
print_endword(h);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
@ -467,21 +487,164 @@ print_otag(struct html *h, enum htmltag tag,
|
||||
|
||||
/* Print out the tag name and attributes. */
|
||||
|
||||
printf("<%s", htmltags[tag].name);
|
||||
for (i = 0; i < sz; i++)
|
||||
print_attr(h, htmlattrs[p[i].key], p[i].val);
|
||||
print_byte(h, '<');
|
||||
print_word(h, htmltags[tag].name);
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
have_style = 0;
|
||||
while (*fmt != '\0') {
|
||||
if (*fmt == 's') {
|
||||
print_word(h, " style=\"");
|
||||
have_style = 1;
|
||||
fmt++;
|
||||
break;
|
||||
}
|
||||
s = va_arg(ap, char *);
|
||||
switch (*fmt++) {
|
||||
case 'c':
|
||||
attr = "class";
|
||||
break;
|
||||
case 'h':
|
||||
attr = "href";
|
||||
break;
|
||||
case 'i':
|
||||
attr = "id";
|
||||
break;
|
||||
case '?':
|
||||
attr = s;
|
||||
s = va_arg(ap, char *);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
print_byte(h, ' ');
|
||||
print_word(h, attr);
|
||||
print_byte(h, '=');
|
||||
print_byte(h, '"');
|
||||
switch (*fmt) {
|
||||
case 'M':
|
||||
print_href(h, s, va_arg(ap, char *), 1);
|
||||
fmt++;
|
||||
break;
|
||||
case 'I':
|
||||
print_href(h, s, NULL, 0);
|
||||
fmt++;
|
||||
break;
|
||||
case 'R':
|
||||
print_byte(h, '#');
|
||||
fmt++;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
print_encode(h, s, NULL, 1);
|
||||
break;
|
||||
}
|
||||
print_byte(h, '"');
|
||||
}
|
||||
|
||||
/* Print out styles. */
|
||||
|
||||
s = NULL;
|
||||
su = &mysu;
|
||||
while (*fmt != '\0') {
|
||||
|
||||
/* First letter: input argument type. */
|
||||
|
||||
switch (*fmt++) {
|
||||
case 'h':
|
||||
i = va_arg(ap, int);
|
||||
SCALE_HS_INIT(su, i);
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(ap, char *);
|
||||
break;
|
||||
case 'u':
|
||||
su = va_arg(ap, struct roffsu *);
|
||||
break;
|
||||
case 'v':
|
||||
i = va_arg(ap, int);
|
||||
SCALE_VS_INIT(su, i);
|
||||
break;
|
||||
case 'w':
|
||||
s = va_arg(ap, char *);
|
||||
a2width(s, su);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Second letter: style name. */
|
||||
|
||||
switch (*fmt++) {
|
||||
case 'b':
|
||||
attr = "margin-bottom";
|
||||
break;
|
||||
case 'h':
|
||||
attr = "height";
|
||||
break;
|
||||
case 'i':
|
||||
attr = "text-indent";
|
||||
break;
|
||||
case 'l':
|
||||
attr = "margin-left";
|
||||
break;
|
||||
case 't':
|
||||
attr = "margin-top";
|
||||
break;
|
||||
case 'w':
|
||||
attr = "width";
|
||||
break;
|
||||
case 'W':
|
||||
attr = "min-width";
|
||||
break;
|
||||
case '?':
|
||||
print_word(h, s);
|
||||
print_byte(h, ':');
|
||||
print_byte(h, ' ');
|
||||
print_word(h, va_arg(ap, char *));
|
||||
print_byte(h, ';');
|
||||
if (*fmt != '\0')
|
||||
print_byte(h, ' ');
|
||||
continue;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
v = su->scale;
|
||||
if (su->unit == SCALE_MM && (v /= 100.0) == 0.0)
|
||||
v = 1.0;
|
||||
else if (su->unit == SCALE_BU)
|
||||
v /= 24.0;
|
||||
print_word(h, attr);
|
||||
print_byte(h, ':');
|
||||
print_byte(h, ' ');
|
||||
(void)snprintf(numbuf, sizeof(numbuf), "%.2f", v);
|
||||
print_word(h, numbuf);
|
||||
print_word(h, roffscales[su->unit]);
|
||||
print_byte(h, ';');
|
||||
if (*fmt != '\0')
|
||||
print_byte(h, ' ');
|
||||
}
|
||||
if (have_style)
|
||||
print_byte(h, '"');
|
||||
|
||||
va_end(ap);
|
||||
|
||||
/* Accommodate for "well-formed" singleton escaping. */
|
||||
|
||||
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
||||
putchar('/');
|
||||
print_byte(h, '/');
|
||||
|
||||
putchar('>');
|
||||
print_byte(h, '>');
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
if (tflags & HTML_NLBEGIN)
|
||||
print_endline(h);
|
||||
else
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
if ((HTML_AUTOCLOSE | HTML_CLRLINE) & htmltags[tag].flags)
|
||||
putchar('\n');
|
||||
if (tflags & HTML_INDENT)
|
||||
h->indent++;
|
||||
if (tflags & HTML_NOINDENT)
|
||||
h->noindent++;
|
||||
|
||||
return t;
|
||||
}
|
||||
@ -489,6 +652,7 @@ print_otag(struct html *h, enum htmltag tag,
|
||||
static void
|
||||
print_ctag(struct html *h, struct tag *tag)
|
||||
{
|
||||
int tflags;
|
||||
|
||||
/*
|
||||
* Remember to close out and nullify the current
|
||||
@ -499,11 +663,21 @@ print_ctag(struct html *h, struct tag *tag)
|
||||
if (tag == h->tblt)
|
||||
h->tblt = NULL;
|
||||
|
||||
printf("</%s>", htmltags[tag->tag].name);
|
||||
if (HTML_CLRLINE & htmltags[tag->tag].flags) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
putchar('\n');
|
||||
}
|
||||
tflags = htmltags[tag->tag].flags;
|
||||
|
||||
if (tflags & HTML_INDENT)
|
||||
h->indent--;
|
||||
if (tflags & HTML_NOINDENT)
|
||||
h->noindent--;
|
||||
if (tflags & HTML_NLEND)
|
||||
print_endline(h);
|
||||
print_indent(h);
|
||||
print_byte(h, '<');
|
||||
print_byte(h, '/');
|
||||
print_word(h, htmltags[tag->tag].name);
|
||||
print_byte(h, '>');
|
||||
if (tflags & HTML_NLAFTER)
|
||||
print_endline(h);
|
||||
|
||||
h->tags.head = tag->next;
|
||||
free(tag);
|
||||
@ -512,42 +686,41 @@ print_ctag(struct html *h, struct tag *tag)
|
||||
void
|
||||
print_gen_decls(struct html *h)
|
||||
{
|
||||
|
||||
puts("<!DOCTYPE html>");
|
||||
print_word(h, "<!DOCTYPE html>");
|
||||
print_endline(h);
|
||||
}
|
||||
|
||||
void
|
||||
print_text(struct html *h, const char *word)
|
||||
{
|
||||
|
||||
if ( ! (HTML_NOSPACE & h->flags)) {
|
||||
/* Manage keeps! */
|
||||
if (h->col && (h->flags & HTML_NOSPACE) == 0) {
|
||||
if ( ! (HTML_KEEP & h->flags)) {
|
||||
if (HTML_PREKEEP & h->flags)
|
||||
h->flags |= HTML_KEEP;
|
||||
putchar(' ');
|
||||
print_endword(h);
|
||||
} else
|
||||
printf(" ");
|
||||
print_word(h, " ");
|
||||
}
|
||||
|
||||
assert(NULL == h->metaf);
|
||||
switch (h->metac) {
|
||||
case HTMLFONT_ITALIC:
|
||||
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
||||
h->metaf = print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_BOLD:
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
break;
|
||||
case HTMLFONT_BI:
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
default:
|
||||
print_indent(h);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(word);
|
||||
if ( ! print_encode(h, word, 0)) {
|
||||
if ( ! print_encode(h, word, NULL, 0)) {
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
h->flags &= ~HTML_NONEWLINE;
|
||||
@ -590,138 +763,136 @@ void
|
||||
print_paragraph(struct html *h)
|
||||
{
|
||||
struct tag *t;
|
||||
struct htmlpair tag;
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "spacer");
|
||||
t = print_otag(h, TAG_DIV, 1, &tag);
|
||||
t = print_otag(h, TAG_DIV, "c", "Pp");
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufinit(struct html *h)
|
||||
{
|
||||
|
||||
h->buf[0] = '\0';
|
||||
h->buflen = 0;
|
||||
}
|
||||
|
||||
void
|
||||
bufcat_style(struct html *h, const char *key, const char *val)
|
||||
{
|
||||
|
||||
bufcat(h, key);
|
||||
bufcat(h, ":");
|
||||
bufcat(h, val);
|
||||
bufcat(h, ";");
|
||||
}
|
||||
|
||||
void
|
||||
bufcat(struct html *h, const char *p)
|
||||
{
|
||||
|
||||
/*
|
||||
* XXX This is broken and not easy to fix.
|
||||
* When using the -Oincludes option, buffmt_includes()
|
||||
* may pass in strings overrunning BUFSIZ, causing a crash.
|
||||
*/
|
||||
|
||||
h->buflen = strlcat(h->buf, p, BUFSIZ);
|
||||
assert(h->buflen < BUFSIZ);
|
||||
}
|
||||
|
||||
void
|
||||
bufcat_fmt(struct html *h, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)vsnprintf(h->buf + (int)h->buflen,
|
||||
BUFSIZ - h->buflen - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
h->buflen = strlen(h->buf);
|
||||
}
|
||||
/***********************************************************************
|
||||
* Low level output functions.
|
||||
* They implement line breaking using a short static buffer.
|
||||
***********************************************************************/
|
||||
|
||||
/*
|
||||
* Buffer one HTML output byte.
|
||||
* If the buffer is full, flush and deactivate it and start a new line.
|
||||
* If the buffer is inactive, print directly.
|
||||
*/
|
||||
static void
|
||||
bufncat(struct html *h, const char *p, size_t sz)
|
||||
print_byte(struct html *h, char c)
|
||||
{
|
||||
|
||||
assert(h->buflen + sz + 1 < BUFSIZ);
|
||||
strncat(h->buf, p, sz);
|
||||
h->buflen += sz;
|
||||
}
|
||||
|
||||
void
|
||||
buffmt_includes(struct html *h, const char *name)
|
||||
{
|
||||
const char *p, *pp;
|
||||
|
||||
pp = h->base_includes;
|
||||
|
||||
bufinit(h);
|
||||
while (NULL != (p = strchr(pp, '%'))) {
|
||||
bufncat(h, pp, (size_t)(p - pp));
|
||||
switch (*(p + 1)) {
|
||||
case'I':
|
||||
bufcat(h, name);
|
||||
break;
|
||||
default:
|
||||
bufncat(h, p, 2);
|
||||
break;
|
||||
}
|
||||
pp = p + 2;
|
||||
if ((h->flags & HTML_BUFFER) == 0) {
|
||||
putchar(c);
|
||||
h->col++;
|
||||
return;
|
||||
}
|
||||
if (pp)
|
||||
bufcat(h, pp);
|
||||
}
|
||||
|
||||
void
|
||||
buffmt_man(struct html *h, const char *name, const char *sec)
|
||||
{
|
||||
const char *p, *pp;
|
||||
|
||||
pp = h->base_man;
|
||||
|
||||
bufinit(h);
|
||||
while (NULL != (p = strchr(pp, '%'))) {
|
||||
bufncat(h, pp, (size_t)(p - pp));
|
||||
switch (*(p + 1)) {
|
||||
case 'S':
|
||||
bufcat(h, sec ? sec : "1");
|
||||
break;
|
||||
case 'N':
|
||||
bufcat_fmt(h, "%s", name);
|
||||
break;
|
||||
default:
|
||||
bufncat(h, p, 2);
|
||||
break;
|
||||
}
|
||||
pp = p + 2;
|
||||
if (h->col + h->bufcol < sizeof(h->buf)) {
|
||||
h->buf[h->bufcol++] = c;
|
||||
return;
|
||||
}
|
||||
if (pp)
|
||||
bufcat(h, pp);
|
||||
|
||||
putchar('\n');
|
||||
h->col = 0;
|
||||
print_indent(h);
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
fwrite(h->buf, h->bufcol, 1, stdout);
|
||||
putchar(c);
|
||||
h->col = (h->indent + 1) * 2 + h->bufcol + 1;
|
||||
h->bufcol = 0;
|
||||
h->flags &= ~HTML_BUFFER;
|
||||
}
|
||||
|
||||
void
|
||||
bufcat_su(struct html *h, const char *p, const struct roffsu *su)
|
||||
/*
|
||||
* If something was printed on the current output line, end it.
|
||||
* Not to be called right after print_indent().
|
||||
*/
|
||||
static void
|
||||
print_endline(struct html *h)
|
||||
{
|
||||
double v;
|
||||
if (h->col == 0)
|
||||
return;
|
||||
|
||||
v = su->scale;
|
||||
if (SCALE_MM == su->unit && 0.0 == (v /= 100.0))
|
||||
v = 1.0;
|
||||
else if (SCALE_BU == su->unit)
|
||||
v /= 24.0;
|
||||
|
||||
bufcat_fmt(h, "%s: %.2f%s;", p, v, roffscales[su->unit]);
|
||||
if (h->bufcol) {
|
||||
putchar(' ');
|
||||
fwrite(h->buf, h->bufcol, 1, stdout);
|
||||
h->bufcol = 0;
|
||||
}
|
||||
putchar('\n');
|
||||
h->col = 0;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
h->flags &= ~HTML_BUFFER;
|
||||
}
|
||||
|
||||
void
|
||||
bufcat_id(struct html *h, const char *src)
|
||||
/*
|
||||
* Flush the HTML output buffer.
|
||||
* If it is inactive, activate it.
|
||||
*/
|
||||
static void
|
||||
print_endword(struct html *h)
|
||||
{
|
||||
if (h->noindent) {
|
||||
print_byte(h, ' ');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cf. <http://www.w3.org/TR/html5/dom.html#the-id-attribute>. */
|
||||
|
||||
for (; '\0' != *src; src++)
|
||||
bufncat(h, *src == ' ' ? "_" : src, 1);
|
||||
if ((h->flags & HTML_BUFFER) == 0) {
|
||||
h->col++;
|
||||
h->flags |= HTML_BUFFER;
|
||||
} else if (h->bufcol) {
|
||||
putchar(' ');
|
||||
fwrite(h->buf, h->bufcol, 1, stdout);
|
||||
h->col += h->bufcol + 1;
|
||||
}
|
||||
h->bufcol = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If at the beginning of a new output line,
|
||||
* perform indentation and mark the line as containing output.
|
||||
* Make sure to really produce some output right afterwards,
|
||||
* but do not use print_otag() for producing it.
|
||||
*/
|
||||
static void
|
||||
print_indent(struct html *h)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (h->col)
|
||||
return;
|
||||
|
||||
if (h->noindent == 0) {
|
||||
h->col = h->indent * 2;
|
||||
for (i = 0; i < h->col; i++)
|
||||
putchar(' ');
|
||||
}
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print or buffer some characters
|
||||
* depending on the current HTML output buffer state.
|
||||
*/
|
||||
static void
|
||||
print_word(struct html *h, const char *cp)
|
||||
{
|
||||
while (*cp != '\0')
|
||||
print_byte(h, *cp++);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the scaling unit passed in a `-width' argument. This uses
|
||||
* either a native scaling unit (e.g., 1i, 2m) or the string length of
|
||||
* the value.
|
||||
*/
|
||||
static void
|
||||
a2width(const char *p, struct roffsu *su)
|
||||
{
|
||||
if (a2roffsu(p, su, SCALE_MAX) < 2) {
|
||||
su->unit = SCALE_EN;
|
||||
su->scale = html_strlen(p);
|
||||
} else if (su->scale < 0.0)
|
||||
su->scale = 0.0;
|
||||
}
|
||||
|
63
html.h
63
html.h
@ -1,6 +1,7 @@
|
||||
/* $Id: html.h,v 1.72 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.78 2017/01/19 16:59:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -39,7 +40,6 @@ enum htmltag {
|
||||
TAG_DL,
|
||||
TAG_DT,
|
||||
TAG_DD,
|
||||
TAG_BLOCKQUOTE,
|
||||
TAG_PRE,
|
||||
TAG_B,
|
||||
TAG_I,
|
||||
@ -65,23 +65,6 @@ enum htmltag {
|
||||
TAG_MAX
|
||||
};
|
||||
|
||||
enum htmlattr {
|
||||
ATTR_NAME,
|
||||
ATTR_REL,
|
||||
ATTR_HREF,
|
||||
ATTR_TYPE,
|
||||
ATTR_MEDIA,
|
||||
ATTR_CLASS,
|
||||
ATTR_STYLE,
|
||||
ATTR_ID,
|
||||
ATTR_COLSPAN,
|
||||
ATTR_CHARSET,
|
||||
ATTR_OPEN,
|
||||
ATTR_CLOSE,
|
||||
ATTR_MATHVARIANT,
|
||||
ATTR_MAX
|
||||
};
|
||||
|
||||
enum htmlfont {
|
||||
HTMLFONT_NONE = 0,
|
||||
HTMLFONT_BOLD,
|
||||
@ -99,22 +82,6 @@ struct tagq {
|
||||
struct tag *head;
|
||||
};
|
||||
|
||||
struct htmlpair {
|
||||
enum htmlattr key;
|
||||
const char *val;
|
||||
};
|
||||
|
||||
#define PAIR_INIT(p, t, v) \
|
||||
do { \
|
||||
(p)->key = (t); \
|
||||
(p)->val = (v); \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
#define PAIR_ID_INIT(p, v) PAIR_INIT(p, ATTR_ID, v)
|
||||
#define PAIR_CLASS_INIT(p, v) PAIR_INIT(p, ATTR_CLASS, v)
|
||||
#define PAIR_HREF_INIT(p, v) PAIR_INIT(p, ATTR_HREF, v)
|
||||
#define PAIR_STYLE_INIT(p, h) PAIR_INIT(p, ATTR_STYLE, (h)->buf)
|
||||
|
||||
struct html {
|
||||
int flags;
|
||||
#define HTML_NOSPACE (1 << 0) /* suppress next space */
|
||||
@ -127,14 +94,18 @@ struct html {
|
||||
#define HTML_NOSPLIT (1 << 7) /* do not break line before .An */
|
||||
#define HTML_SPLIT (1 << 8) /* break line before .An */
|
||||
#define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */
|
||||
#define HTML_BUFFER (1 << 10) /* Collect a word to see if it fits. */
|
||||
size_t indent; /* current output indentation level */
|
||||
int noindent; /* indent disabled by <pre> */
|
||||
size_t col; /* current output byte position */
|
||||
size_t bufcol; /* current buf byte position */
|
||||
char buf[80]; /* output buffer */
|
||||
struct tagq tags; /* stack of open tags */
|
||||
struct rofftbl tbl; /* current table */
|
||||
struct tag *tblt; /* current open table scope */
|
||||
char *base_man; /* base for manpage href */
|
||||
char *base_includes; /* base for include href */
|
||||
char *style; /* style-sheet URI */
|
||||
char buf[BUFSIZ]; /* see bufcat and friends */
|
||||
size_t buflen;
|
||||
struct tag *metaf; /* current open font scope */
|
||||
enum htmlfont metal; /* last used font */
|
||||
enum htmlfont metac; /* current font mode */
|
||||
@ -148,8 +119,7 @@ struct eqn;
|
||||
|
||||
void print_gen_decls(struct html *);
|
||||
void print_gen_head(struct html *);
|
||||
struct tag *print_otag(struct html *, enum htmltag,
|
||||
int, const struct htmlpair *);
|
||||
struct tag *print_otag(struct html *, enum htmltag, const char *, ...);
|
||||
void print_tagq(struct html *, const struct tag *);
|
||||
void print_stagq(struct html *, const struct tag *);
|
||||
void print_text(struct html *, const char *);
|
||||
@ -158,19 +128,4 @@ void print_tbl(struct html *, const struct tbl_span *);
|
||||
void print_eqn(struct html *, const struct eqn *);
|
||||
void print_paragraph(struct html *);
|
||||
|
||||
#if __GNUC__ - 0 >= 4
|
||||
__attribute__((__format__ (__printf__, 2, 3)))
|
||||
#endif
|
||||
void bufcat_fmt(struct html *, const char *, ...);
|
||||
void bufcat(struct html *, const char *);
|
||||
void bufcat_id(struct html *, const char *);
|
||||
void bufcat_style(struct html *,
|
||||
const char *, const char *);
|
||||
void bufcat_su(struct html *, const char *,
|
||||
const struct roffsu *);
|
||||
void bufinit(struct html *);
|
||||
void buffmt_man(struct html *,
|
||||
const char *, const char *);
|
||||
void buffmt_includes(struct html *, const char *);
|
||||
|
||||
int html_strlen(const char *);
|
||||
|
6
lib.in
6
lib.in
@ -1,4 +1,4 @@
|
||||
/* $Id: lib.in,v 1.18 2014/01/06 00:53:33 schwarze Exp $ */
|
||||
/* $Id: lib.in,v 1.19 2016/11/23 20:22:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
@ -83,6 +83,7 @@ LINE("libnetpgpverify", "Netpgp Verification (libnetpgpverify, \\-lnetpgpverify)
|
||||
LINE("libnpf", "NPF Packet Filter Library (libnpf, \\-lnpf)")
|
||||
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
|
||||
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
|
||||
LINE("libpanel", "Z-order for curses windows (libpanel, \\-lpanel)")
|
||||
LINE("libpcap", "Capture Library (libpcap, \\-lpcap)")
|
||||
LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
|
||||
LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
|
||||
@ -90,8 +91,10 @@ LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
|
||||
LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
|
||||
LINE("libposix1e", "POSIX.1e Security API Library (libposix1e, \\-lposix1e)")
|
||||
LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
|
||||
LINE("libproc", "Process Manipulation Library (libproc, \\-lproc)")
|
||||
LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
|
||||
LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
|
||||
LINE("libpthread_dbg", "POSIX Debug Threads Library (libpthread_dbg, \\-lpthread_dbg)")
|
||||
LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
|
||||
LINE("libquota", "Disk Quota Access and Control Library (libquota, \\-lquota)")
|
||||
LINE("libradius", "RADIUS Client Library (libradius, \\-lradius)")
|
||||
@ -100,6 +103,7 @@ LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
|
||||
LINE("librpcsec_gss", "RPC GSS-API Authentication Library (librpcsec_gss, \\-lrpcsec_gss)")
|
||||
LINE("librpcsvc", "RPC Service Library (librpcsvc, \\-lrpcsvc)")
|
||||
LINE("librt", "POSIX Real\\-time Library (librt, \\-lrt)")
|
||||
LINE("librtld_db", "Debugging interface to the runtime linker Library (librtld_db, \\-lrtld_db)")
|
||||
LINE("librumpclient", "Clientside Stubs for rump Kernel Remote Protocols (librumpclient, \\-lrumpclient)")
|
||||
LINE("libsaslc", "Simple Authentication and Security Layer client library (libsaslc, \\-lsaslc)")
|
||||
LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)")
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: libmandoc.h,v 1.63 2016/07/07 19:19:01 schwarze Exp $ */
|
||||
/* $Id: libmandoc.h,v 1.64 2016/07/19 13:36:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -41,11 +41,9 @@ struct roff_man;
|
||||
|
||||
void mandoc_msg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *);
|
||||
#if __GNUC__ - 0 >= 4
|
||||
__attribute__((__format__ (__printf__, 5, 6)))
|
||||
#endif
|
||||
void mandoc_vmsg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *, ...);
|
||||
int, int, const char *, ...)
|
||||
__attribute__((__format__ (printf, 5, 6)));
|
||||
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
||||
char *mandoc_normdate(struct mparse *, char *, int, int);
|
||||
int mandoc_eos(const char *, size_t);
|
||||
|
136
main.c
136
main.c
@ -1,7 +1,7 @@
|
||||
/* $Id: main.c,v 1.269 2016/07/12 05:18:38 kristaps Exp $ */
|
||||
/* $Id: main.c,v 1.279 2017/01/09 17:49:57 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2012, 2014-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -51,12 +51,6 @@
|
||||
#include "manconf.h"
|
||||
#include "mansearch.h"
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 2)
|
||||
# if !defined(lint)
|
||||
# define __attribute__(x)
|
||||
# endif
|
||||
#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
|
||||
|
||||
enum outmode {
|
||||
OUTMODE_DEF = 0,
|
||||
OUTMODE_FLN,
|
||||
@ -87,6 +81,9 @@ struct curparse {
|
||||
struct manoutput *outopts; /* output options */
|
||||
};
|
||||
|
||||
|
||||
int mandocdb(int, char *[]);
|
||||
|
||||
static int fs_lookup(const struct manpaths *,
|
||||
size_t ipath, const char *,
|
||||
const char *, const char *,
|
||||
@ -95,12 +92,10 @@ static void fs_search(const struct mansearch *,
|
||||
const struct manpaths *, int, char**,
|
||||
struct manpage **, size_t *);
|
||||
static int koptions(int *, char *);
|
||||
#if HAVE_SQLITE3
|
||||
int mandocdb(int, char**);
|
||||
#endif
|
||||
static int moptions(int *, char *);
|
||||
static void mmsg(enum mandocerr, enum mandoclevel,
|
||||
const char *, int, int, const char *);
|
||||
static void outdata_alloc(struct curparse *);
|
||||
static void parse(struct curparse *, int, const char *);
|
||||
static void passthrough(const char *, int, int);
|
||||
static pid_t spawn_pager(struct tag_files *);
|
||||
@ -151,11 +146,9 @@ main(int argc, char *argv[])
|
||||
setprogname(progname);
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLITE3
|
||||
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)
|
||||
@ -353,9 +346,6 @@ main(int argc, char *argv[])
|
||||
/* man(1), whatis(1), apropos(1) */
|
||||
|
||||
if (search.argmode != ARG_FILE) {
|
||||
if (argc == 0)
|
||||
usage(search.argmode);
|
||||
|
||||
if (search.argmode == ARG_NAME &&
|
||||
outmode == OUTMODE_ONE)
|
||||
search.firstmatch = 1;
|
||||
@ -363,19 +353,9 @@ main(int argc, char *argv[])
|
||||
/* Access the mandoc database. */
|
||||
|
||||
manconf_parse(&conf, conf_file, defpaths, auxpaths);
|
||||
#if HAVE_SQLITE3
|
||||
mansearch_setup(1);
|
||||
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;
|
||||
}
|
||||
sz = 0;
|
||||
#endif
|
||||
|
||||
if (sz == 0) {
|
||||
if (search.argmode == ARG_NAME)
|
||||
@ -478,7 +458,7 @@ main(int argc, char *argv[])
|
||||
|
||||
if (resp == NULL)
|
||||
parse(&curp, fd, *argv);
|
||||
else if (resp->form & FORM_SRC) {
|
||||
else if (resp->form == FORM_SRC) {
|
||||
/* For .so only; ignore failure. */
|
||||
chdir(conf.manpath.paths[resp->ipath]);
|
||||
parse(&curp, fd, resp->file);
|
||||
@ -486,8 +466,11 @@ main(int argc, char *argv[])
|
||||
passthrough(resp->file, fd,
|
||||
conf.output.synopsisonly);
|
||||
|
||||
if (argc > 1 && curp.outtype <= OUTT_UTF8)
|
||||
if (argc > 1 && curp.outtype <= OUTT_UTF8) {
|
||||
if (curp.outdata == NULL)
|
||||
outdata_alloc(&curp);
|
||||
terminal_sepline(curp.outdata);
|
||||
}
|
||||
} else if (rc < MANDOCLEVEL_ERROR)
|
||||
rc = MANDOCLEVEL_ERROR;
|
||||
|
||||
@ -526,10 +509,7 @@ main(int argc, char *argv[])
|
||||
out:
|
||||
if (search.argmode != ARG_FILE) {
|
||||
manconf_free(&conf);
|
||||
#if HAVE_SQLITE3
|
||||
mansearch_free(res, sz);
|
||||
mansearch_setup(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
free(defos);
|
||||
@ -551,10 +531,10 @@ out:
|
||||
|
||||
/* Stop here until moved to the foreground. */
|
||||
|
||||
tc_pgid = tcgetpgrp(STDIN_FILENO);
|
||||
tc_pgid = tcgetpgrp(tag_files->ofd);
|
||||
if (tc_pgid != man_pgid) {
|
||||
if (tc_pgid == pager_pid) {
|
||||
(void)tcsetpgrp(STDIN_FILENO,
|
||||
(void)tcsetpgrp(tag_files->ofd,
|
||||
man_pgid);
|
||||
if (signum == SIGTTIN)
|
||||
continue;
|
||||
@ -567,7 +547,7 @@ out:
|
||||
/* Once in the foreground, activate the pager. */
|
||||
|
||||
if (pager_pid) {
|
||||
(void)tcsetpgrp(STDIN_FILENO, pager_pid);
|
||||
(void)tcsetpgrp(tag_files->ofd, pager_pid);
|
||||
kill(pager_pid, SIGCONT);
|
||||
} else
|
||||
pager_pid = spawn_pager(tag_files);
|
||||
@ -633,7 +613,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
glob_t globinfo;
|
||||
struct manpage *page;
|
||||
char *file;
|
||||
int form, globres;
|
||||
int globres;
|
||||
enum form form;
|
||||
|
||||
form = FORM_SRC;
|
||||
mandoc_asprintf(&file, "%s/man%s/%s.%s",
|
||||
@ -671,10 +652,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
return 0;
|
||||
|
||||
found:
|
||||
#if HAVE_SQLITE3
|
||||
warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
|
||||
name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
|
||||
#endif
|
||||
*res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
|
||||
page = *res + (*ressz - 1);
|
||||
page->file = file;
|
||||
@ -747,32 +726,8 @@ parse(struct curparse *curp, int fd, const char *file)
|
||||
if (rctmp != MANDOCLEVEL_OK && curp->wstop)
|
||||
return;
|
||||
|
||||
/* If unset, allocate output dev now (if applicable). */
|
||||
|
||||
if (curp->outdata == NULL) {
|
||||
switch (curp->outtype) {
|
||||
case OUTT_HTML:
|
||||
curp->outdata = html_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_UTF8:
|
||||
curp->outdata = utf8_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_LOCALE:
|
||||
curp->outdata = locale_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_ASCII:
|
||||
curp->outdata = ascii_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_PDF:
|
||||
curp->outdata = pdf_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_PS:
|
||||
curp->outdata = ps_alloc(curp->outopts);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curp->outdata == NULL)
|
||||
outdata_alloc(curp);
|
||||
|
||||
mparse_result(curp->mp, &man, NULL);
|
||||
|
||||
@ -826,6 +781,34 @@ parse(struct curparse *curp, int fd, const char *file)
|
||||
break;
|
||||
}
|
||||
}
|
||||
mparse_updaterc(curp->mp, &rc);
|
||||
}
|
||||
|
||||
static void
|
||||
outdata_alloc(struct curparse *curp)
|
||||
{
|
||||
switch (curp->outtype) {
|
||||
case OUTT_HTML:
|
||||
curp->outdata = html_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_UTF8:
|
||||
curp->outdata = utf8_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_LOCALE:
|
||||
curp->outdata = locale_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_ASCII:
|
||||
curp->outdata = ascii_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_PDF:
|
||||
curp->outdata = pdf_alloc(curp->outopts);
|
||||
break;
|
||||
case OUTT_PS:
|
||||
curp->outdata = ps_alloc(curp->outopts);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -838,11 +821,17 @@ passthrough(const char *file, int fd, int synopsis_only)
|
||||
const char *syscall;
|
||||
char *line, *cp;
|
||||
size_t linesz;
|
||||
ssize_t len, written;
|
||||
int print;
|
||||
|
||||
line = NULL;
|
||||
linesz = 0;
|
||||
|
||||
if (fflush(stdout) == EOF) {
|
||||
syscall = "fflush";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((stream = fdopen(fd, "r")) == NULL) {
|
||||
close(fd);
|
||||
syscall = "fdopen";
|
||||
@ -850,14 +839,16 @@ passthrough(const char *file, int fd, int synopsis_only)
|
||||
}
|
||||
|
||||
print = 0;
|
||||
while (getline(&line, &linesz, stream) != -1) {
|
||||
while ((len = getline(&line, &linesz, stream)) != -1) {
|
||||
cp = line;
|
||||
if (synopsis_only) {
|
||||
if (print) {
|
||||
if ( ! isspace((unsigned char)*cp))
|
||||
goto done;
|
||||
while (isspace((unsigned char)*cp))
|
||||
while (isspace((unsigned char)*cp)) {
|
||||
cp++;
|
||||
len--;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(cp, synb) == 0 ||
|
||||
strcmp(cp, synr) == 0)
|
||||
@ -865,9 +856,11 @@ passthrough(const char *file, int fd, int synopsis_only)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fputs(cp, stdout)) {
|
||||
for (; len > 0; len -= written) {
|
||||
if ((written = write(STDOUT_FILENO, cp, len)) != -1)
|
||||
continue;
|
||||
fclose(stream);
|
||||
syscall = "fputs";
|
||||
syscall = "write";
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@ -978,7 +971,7 @@ woptions(struct curparse *curp, char *arg)
|
||||
|
||||
while (*arg) {
|
||||
o = arg;
|
||||
switch (getsubopt(&arg, UNCONST(toks), &v)) {
|
||||
switch (getsubopt(&arg, (char * const *)toks, &v)) {
|
||||
case 0:
|
||||
curp->wstop = 1;
|
||||
break;
|
||||
@ -1010,7 +1003,8 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
|
||||
{
|
||||
const char *mparse_msg;
|
||||
|
||||
fprintf(stderr, "%s: %s:", getprogname(), file);
|
||||
fprintf(stderr, "%s: %s:", getprogname(),
|
||||
file == NULL ? "<stdin>" : file);
|
||||
|
||||
if (line)
|
||||
fprintf(stderr, "%d:%d:", line, col + 1);
|
||||
@ -1082,7 +1076,7 @@ spawn_pager(struct tag_files *tag_files)
|
||||
break;
|
||||
default:
|
||||
(void)setpgid(pager_pid, 0);
|
||||
(void)tcsetpgrp(STDIN_FILENO, pager_pid);
|
||||
(void)tcsetpgrp(tag_files->ofd, pager_pid);
|
||||
#if HAVE_PLEDGE
|
||||
if (pledge("stdio rpath tmppath tty proc", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
@ -1100,7 +1094,7 @@ spawn_pager(struct tag_files *tag_files)
|
||||
|
||||
/* Do not start the pager before controlling the terminal. */
|
||||
|
||||
while (tcgetpgrp(STDIN_FILENO) != getpid())
|
||||
while (tcgetpgrp(STDOUT_FILENO) != getpid())
|
||||
nanosleep(&timeout, NULL);
|
||||
|
||||
execvp(argv[0], argv);
|
||||
|
4
main.h
4
main.h
@ -1,4 +1,4 @@
|
||||
/* $Id: main.h,v 1.25 2016/07/08 22:29:05 schwarze Exp $ */
|
||||
/* $Id: main.h,v 1.26 2016/07/15 19:33:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,8 +16,6 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
|
||||
|
||||
struct roff_man;
|
||||
struct manoutput;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: makewhatis.8,v 1.3 2014/08/17 21:03:06 schwarze Exp $
|
||||
.\" $Id: makewhatis.8,v 1.4 2016/07/19 22:40:33 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2012 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: August 17 2014 $
|
||||
.Dd $Mdocdate: July 19 2016 $
|
||||
.Dt MAKEWHATIS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -79,8 +79,6 @@ If
|
||||
is not provided,
|
||||
.Nm
|
||||
uses the default paths stipulated by
|
||||
.Xr manpath 1 ,
|
||||
or
|
||||
.Xr man.conf 5 .
|
||||
.Pp
|
||||
The arguments are as follows:
|
||||
|
38
man.1
38
man.1
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.1,v 1.17 2016/07/01 20:24:04 schwarze Exp $
|
||||
.\" $Id: man.1,v 1.20 2017/01/06 01:34:57 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: July 1 2016 $
|
||||
.Dd $Mdocdate: January 6 2017 $
|
||||
.Dt MAN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -69,12 +69,8 @@ machine architecture
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
Display all of the manual pages for a specified
|
||||
.Ar section
|
||||
and
|
||||
.Ar name
|
||||
combination.
|
||||
Normally, only the first manual page found is displayed.
|
||||
Display all matching manual pages.
|
||||
Normally, only the first page found is displayed.
|
||||
.It Fl C Ar file
|
||||
Use the specified
|
||||
.Ar file
|
||||
@ -100,6 +96,12 @@ This overrides any earlier
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl h
|
||||
Display only the SYNOPSIS lines of the requested manual pages.
|
||||
Implies
|
||||
.Fl a
|
||||
and
|
||||
.Fl c .
|
||||
.It Fl I Cm os Ns = Ns Ar name
|
||||
Override the default operating system
|
||||
.Ar name
|
||||
@ -110,12 +112,6 @@ and for the
|
||||
.Xr man 7
|
||||
.Ic \&TH
|
||||
macro.
|
||||
.It Fl h
|
||||
Display only the SYNOPSIS lines of the requested manual pages.
|
||||
Implies
|
||||
.Fl a
|
||||
and
|
||||
.Fl c .
|
||||
.It Fl K Ar encoding
|
||||
Specify the input encoding.
|
||||
The supported
|
||||
@ -330,7 +326,19 @@ 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.
|
||||
environment variables, function names, preprocessor macros,
|
||||
.Xr errno 2
|
||||
values, and some other emphasized words.
|
||||
Some terms may have defining text at more than one place.
|
||||
In that case, the
|
||||
.Xr less 1
|
||||
interactive commands
|
||||
.Ic t
|
||||
and
|
||||
.Ic T
|
||||
can be used to move to the next and to the previous place providing
|
||||
information about the term last searched for with
|
||||
.Ic :t .
|
||||
.It Ev MANPATH
|
||||
The standard search path used by
|
||||
.Nm
|
||||
|
10
man.c
10
man.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man.c,v 1.166 2015/10/22 21:54:23 schwarze Exp $ */
|
||||
/* $Id: man.c,v 1.167 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -149,7 +149,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
|
||||
assert(i);
|
||||
if (mandoc_eos(buf, (size_t)i))
|
||||
man->last->flags |= MAN_EOS;
|
||||
man->last->flags |= NODE_EOS;
|
||||
|
||||
man_descope(man, line, offs);
|
||||
return 1;
|
||||
@ -340,7 +340,7 @@ man_state(struct roff_man *man, struct roff_node *n)
|
||||
switch(n->tok) {
|
||||
case MAN_nf:
|
||||
case MAN_EX:
|
||||
if (man->flags & MAN_LITERAL && ! (n->flags & MAN_VALID))
|
||||
if (man->flags & MAN_LITERAL && ! (n->flags & NODE_VALID))
|
||||
mandoc_msg(MANDOCERR_NF_SKIP, man->parse,
|
||||
n->line, n->pos, "nf");
|
||||
man->flags |= MAN_LITERAL;
|
||||
@ -348,7 +348,7 @@ man_state(struct roff_man *man, struct roff_node *n)
|
||||
case MAN_fi:
|
||||
case MAN_EE:
|
||||
if ( ! (man->flags & MAN_LITERAL) &&
|
||||
! (n->flags & MAN_VALID))
|
||||
! (n->flags & NODE_VALID))
|
||||
mandoc_msg(MANDOCERR_FI_SKIP, man->parse,
|
||||
n->line, n->pos, "fi");
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
@ -356,7 +356,7 @@ man_state(struct roff_man *man, struct roff_node *n)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
man->last->flags |= MAN_VALID;
|
||||
man->last->flags |= NODE_VALID;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.conf.5,v 1.3 2015/03/27 21:33:20 schwarze Exp $
|
||||
.\" $Id: man.conf.5,v 1.4 2016/12/28 22:52:17 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015 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: March 27 2015 $
|
||||
.Dd $Mdocdate: December 28 2016 $
|
||||
.Dt MAN.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -91,7 +91,7 @@ manual.
|
||||
.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 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man_hash.c,v 1.34 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: man_hash.c,v 1.35 2016/07/15 18:03:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -24,8 +24,10 @@
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libman.h"
|
||||
|
||||
#define HASH_DEPTH 6
|
||||
|
169
man_html.c
169
man_html.c
@ -1,7 +1,7 @@
|
||||
/* $Id: man_html.c,v 1.120 2016/01/08 17:48:09 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.129 2017/01/21 01:20:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -147,40 +147,39 @@ void
|
||||
html_man(void *arg, const struct roff_man *man)
|
||||
{
|
||||
struct mhtml mh;
|
||||
struct htmlpair tag;
|
||||
struct html *h;
|
||||
struct tag *t, *tt;
|
||||
struct tag *t;
|
||||
|
||||
memset(&mh, 0, sizeof(mh));
|
||||
PAIR_CLASS_INIT(&tag, "mandoc");
|
||||
h = (struct html *)arg;
|
||||
|
||||
if ( ! (HTML_FRAGMENT & h->oflags)) {
|
||||
if ((h->oflags & HTML_FRAGMENT) == 0) {
|
||||
print_gen_decls(h);
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
tt = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
print_otag(h, TAG_HTML, "");
|
||||
t = print_otag(h, TAG_HEAD, "");
|
||||
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_tagq(h, t);
|
||||
print_otag(h, TAG_BODY, "");
|
||||
}
|
||||
|
||||
print_man_nodelist(&man->meta, man->first, &mh, h);
|
||||
man_root_pre(&man->meta, man->first, &mh, h);
|
||||
t = print_otag(h, TAG_DIV, "c", "manual-text");
|
||||
print_man_nodelist(&man->meta, man->first->child, &mh, h);
|
||||
print_tagq(h, t);
|
||||
putchar('\n');
|
||||
man_root_post(&man->meta, man->first, &mh, h);
|
||||
print_tagq(h, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
print_man_head(MAN_ARGS)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
print_gen_head(h);
|
||||
assert(man->title);
|
||||
assert(man->msec);
|
||||
bufcat_fmt(h, "%s(%s)", man->title, man->msec);
|
||||
print_otag(h, TAG_TITLE, 0, NULL);
|
||||
print_text(h, h->buf);
|
||||
mandoc_asprintf(&cp, "%s(%s)", man->title, man->msec);
|
||||
print_otag(h, TAG_TITLE, "");
|
||||
print_text(h, cp);
|
||||
free(cp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -203,23 +202,18 @@ print_man_node(MAN_ARGS)
|
||||
t = h->tags.head;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_ROOT:
|
||||
man_root_pre(man, n, mh, h);
|
||||
break;
|
||||
case ROFFT_TEXT:
|
||||
if ('\0' == *n->string) {
|
||||
print_paragraph(h);
|
||||
return;
|
||||
}
|
||||
if (n->flags & MAN_LINE && (*n->string == ' ' ||
|
||||
if (n->flags & NODE_LINE && (*n->string == ' ' ||
|
||||
(n->prev != NULL && mh->fl & MANH_LITERAL &&
|
||||
! (h->flags & HTML_NONEWLINE))))
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
print_otag(h, TAG_BR, "");
|
||||
print_text(h, n->string);
|
||||
return;
|
||||
case ROFFT_EQN:
|
||||
if (n->flags & MAN_LINE)
|
||||
putchar('\n');
|
||||
print_eqn(h, n->eqn);
|
||||
break;
|
||||
case ROFFT_TBL:
|
||||
@ -261,9 +255,6 @@ print_man_node(MAN_ARGS)
|
||||
print_stagq(h, t);
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_ROOT:
|
||||
man_root_post(man, n, mh, h);
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
break;
|
||||
default:
|
||||
@ -288,7 +279,6 @@ a2width(const struct roff_node *n, struct roffsu *su)
|
||||
static void
|
||||
man_root_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct tag *t, *tt;
|
||||
char *title;
|
||||
|
||||
@ -296,26 +286,20 @@ man_root_pre(MAN_ARGS)
|
||||
assert(man->msec);
|
||||
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "head");
|
||||
t = print_otag(h, TAG_TABLE, 1, &tag);
|
||||
t = print_otag(h, TAG_TABLE, "c", "head");
|
||||
print_otag(h, TAG_TBODY, "");
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "head-ltitle");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
print_otag(h, TAG_TD, "c", "head-ltitle");
|
||||
print_text(h, title);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "head-vol");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
print_otag(h, TAG_TD, "c", "head-vol");
|
||||
if (NULL != man->vol)
|
||||
print_text(h, man->vol);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "head-rtitle");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
print_otag(h, TAG_TD, "c", "head-rtitle");
|
||||
print_text(h, title);
|
||||
print_tagq(h, t);
|
||||
free(title);
|
||||
@ -324,24 +308,16 @@ man_root_pre(MAN_ARGS)
|
||||
static void
|
||||
man_root_post(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct tag *t, *tt;
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "foot");
|
||||
t = print_otag(h, TAG_TABLE, 1, &tag);
|
||||
t = print_otag(h, TAG_TABLE, "c", "foot");
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "foot-date");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
|
||||
assert(man->date);
|
||||
print_otag(h, TAG_TD, "c", "foot-date");
|
||||
print_text(h, man->date);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "foot-os");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "foot-os");
|
||||
if (man->os)
|
||||
print_text(h, man->os);
|
||||
print_tagq(h, t);
|
||||
@ -352,7 +328,6 @@ static int
|
||||
man_br_pre(MAN_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
struct htmlpair tag;
|
||||
|
||||
SCALE_VS_INIT(&su, 1);
|
||||
|
||||
@ -363,10 +338,7 @@ man_br_pre(MAN_ARGS)
|
||||
} else
|
||||
su.scale = 0.0;
|
||||
|
||||
bufinit(h);
|
||||
bufcat_su(h, "height", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
print_otag(h, TAG_DIV, "suh", &su);
|
||||
|
||||
/* So the div isn't empty: */
|
||||
print_text(h, "\\~");
|
||||
@ -377,17 +349,13 @@ man_br_pre(MAN_ARGS)
|
||||
static int
|
||||
man_SH_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
|
||||
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 (n->type == ROFFT_BODY)
|
||||
return 1;
|
||||
|
||||
print_otag(h, TAG_H1, 0, NULL);
|
||||
print_otag(h, TAG_H1, "c", "Sh");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -400,7 +368,7 @@ man_alt_pre(MAN_ARGS)
|
||||
struct tag *t;
|
||||
|
||||
if ((savelit = mh->fl & MANH_LITERAL))
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
print_otag(h, TAG_BR, "");
|
||||
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
|
||||
@ -433,7 +401,7 @@ man_alt_pre(MAN_ARGS)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
if (TAG_MAX != fp)
|
||||
t = print_otag(h, fp, 0, NULL);
|
||||
t = print_otag(h, fp, "");
|
||||
|
||||
print_man_node(man, nn, mh, h);
|
||||
|
||||
@ -450,27 +418,22 @@ man_alt_pre(MAN_ARGS)
|
||||
static int
|
||||
man_SM_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_SMALL, 0, NULL);
|
||||
print_otag(h, TAG_SMALL, "");
|
||||
if (MAN_SB == n->tok)
|
||||
print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_B, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_SS_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
|
||||
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 (n->type == ROFFT_BODY)
|
||||
return 1;
|
||||
|
||||
print_otag(h, TAG_H2, 0, NULL);
|
||||
print_otag(h, TAG_H2, "c", "Ss");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -492,16 +455,16 @@ man_IP_pre(MAN_ARGS)
|
||||
const struct roff_node *nn;
|
||||
|
||||
if (n->type == ROFFT_BODY) {
|
||||
print_otag(h, TAG_DD, 0, NULL);
|
||||
print_otag(h, TAG_DD, "c", "It-tag");
|
||||
return 1;
|
||||
} else if (n->type != ROFFT_HEAD) {
|
||||
print_otag(h, TAG_DL, 0, NULL);
|
||||
print_otag(h, TAG_DL, "c", "Bl-tag");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* FIXME: width specification. */
|
||||
|
||||
print_otag(h, TAG_DT, 0, NULL);
|
||||
print_otag(h, TAG_DT, "c", "It-tag");
|
||||
|
||||
/* For IP, only print the first header element. */
|
||||
|
||||
@ -512,7 +475,7 @@ man_IP_pre(MAN_ARGS)
|
||||
|
||||
if (MAN_TP == n->tok) {
|
||||
nn = n->child;
|
||||
while (NULL != nn && 0 == (MAN_LINE & nn->flags))
|
||||
while (NULL != nn && 0 == (NODE_LINE & nn->flags))
|
||||
nn = nn->next;
|
||||
while (NULL != nn) {
|
||||
print_man_node(man, nn, mh, h);
|
||||
@ -526,8 +489,7 @@ man_IP_pre(MAN_ARGS)
|
||||
static int
|
||||
man_HP_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag[2];
|
||||
struct roffsu su;
|
||||
struct roffsu sum, sui;
|
||||
const struct roff_node *np;
|
||||
|
||||
if (n->type == ROFFT_HEAD)
|
||||
@ -537,18 +499,14 @@ man_HP_pre(MAN_ARGS)
|
||||
|
||||
np = n->head->child;
|
||||
|
||||
if (NULL == np || ! a2width(np, &su))
|
||||
SCALE_HS_INIT(&su, INDENT);
|
||||
if (np == NULL || !a2width(np, &sum))
|
||||
SCALE_HS_INIT(&sum, INDENT);
|
||||
|
||||
bufinit(h);
|
||||
sui.unit = sum.unit;
|
||||
sui.scale = -sum.scale;
|
||||
|
||||
print_bvspace(h, n);
|
||||
bufcat_su(h, "margin-left", &su);
|
||||
su.scale = -su.scale;
|
||||
bufcat_su(h, "text-indent", &su);
|
||||
PAIR_STYLE_INIT(&tag[0], h);
|
||||
PAIR_CLASS_INIT(&tag[1], "spacer");
|
||||
print_otag(h, TAG_DIV, 2, tag);
|
||||
print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -556,22 +514,20 @@ static int
|
||||
man_OP_pre(MAN_ARGS)
|
||||
{
|
||||
struct tag *tt;
|
||||
struct htmlpair tag;
|
||||
|
||||
print_text(h, "[");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
PAIR_CLASS_INIT(&tag, "opt");
|
||||
tt = print_otag(h, TAG_SPAN, 1, &tag);
|
||||
tt = print_otag(h, TAG_SPAN, "c", "Op");
|
||||
|
||||
if (NULL != (n = n->child)) {
|
||||
print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_B, "");
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
print_stagq(h, tt);
|
||||
|
||||
if (NULL != n && NULL != n->next) {
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
print_otag(h, TAG_I, "");
|
||||
print_text(h, n->next->string);
|
||||
}
|
||||
|
||||
@ -584,16 +540,14 @@ man_OP_pre(MAN_ARGS)
|
||||
static int
|
||||
man_B_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_B, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_I_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
print_otag(h, TAG_I, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -602,7 +556,7 @@ man_literal_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
if (MAN_fi == n->tok || MAN_EE == n->tok) {
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
print_otag(h, TAG_BR, "");
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
} else
|
||||
mh->fl |= MANH_LITERAL;
|
||||
@ -613,8 +567,7 @@ man_literal_pre(MAN_ARGS)
|
||||
static int
|
||||
man_in_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
print_otag(h, TAG_BR, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -628,7 +581,6 @@ man_ign_pre(MAN_ARGS)
|
||||
static int
|
||||
man_RS_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
|
||||
if (n->type == ROFFT_HEAD)
|
||||
@ -640,25 +592,18 @@ man_RS_pre(MAN_ARGS)
|
||||
if (n->head->child)
|
||||
a2width(n->head->child, &su);
|
||||
|
||||
bufinit(h);
|
||||
bufcat_su(h, "margin-left", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
print_otag(h, TAG_DIV, "sul", &su);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_UR_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag[2];
|
||||
|
||||
n = n->child;
|
||||
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);
|
||||
print_otag(h, TAG_A, "ch", "Lk", n->child->string);
|
||||
}
|
||||
|
||||
assert(n->next->type == ROFFT_BODY);
|
||||
|
12
man_macro.c
12
man_macro.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man_macro.c,v 1.114 2016/01/08 17:48:09 schwarze Exp $ */
|
||||
/* $Id: man_macro.c,v 1.115 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -95,7 +95,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
|
||||
/* Reached the end of the document? */
|
||||
|
||||
if (to == NULL && ! (n->flags & MAN_VALID)) {
|
||||
if (to == NULL && ! (n->flags & NODE_VALID)) {
|
||||
if (man->flags & (MAN_BLINE | MAN_ELINE) &&
|
||||
man_macros[n->tok].flags & MAN_SCOPED) {
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE,
|
||||
@ -130,7 +130,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
|
||||
man->last = n;
|
||||
n = n->parent;
|
||||
man->last->flags |= MAN_VALID;
|
||||
man->last->flags |= NODE_VALID;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -164,7 +164,7 @@ rew_scope(struct roff_man *man, int tok)
|
||||
for (;;) {
|
||||
if (n->type == ROFFT_ROOT)
|
||||
return;
|
||||
if (n->flags & MAN_VALID) {
|
||||
if (n->flags & NODE_VALID) {
|
||||
n = n->parent;
|
||||
continue;
|
||||
}
|
||||
@ -356,13 +356,13 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* Append MAN_EOS in case the last snipped argument
|
||||
* Append NODE_EOS in case the last snipped argument
|
||||
* ends with a dot, e.g. `.IR syslog (3).'
|
||||
*/
|
||||
|
||||
if (n != man->last &&
|
||||
mandoc_eos(man->last->string, strlen(man->last->string)))
|
||||
man->last->flags |= MAN_EOS;
|
||||
man->last->flags |= NODE_EOS;
|
||||
|
||||
/*
|
||||
* If no arguments are specified and this is MAN_SCOPED (i.e.,
|
||||
|
18
man_term.c
18
man_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man_term.c,v 1.187 2016/01/08 17:48:09 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.188 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -319,7 +319,7 @@ pre_alternate(DECL_ARGS)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
assert(nn->type == ROFFT_TEXT);
|
||||
term_word(p, nn->string);
|
||||
if (nn->flags & MAN_EOS)
|
||||
if (nn->flags & NODE_EOS)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
if (nn->next)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -677,7 +677,7 @@ pre_TP(DECL_ARGS)
|
||||
/* Calculate offset. */
|
||||
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
nn->string != NULL && ! (MAN_LINE & nn->flags) &&
|
||||
nn->string != NULL && ! (NODE_LINE & nn->flags) &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN)) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
@ -698,7 +698,7 @@ pre_TP(DECL_ARGS)
|
||||
|
||||
/* Don't print same-line elements. */
|
||||
nn = n->child;
|
||||
while (NULL != nn && 0 == (MAN_LINE & nn->flags))
|
||||
while (NULL != nn && 0 == (NODE_LINE & nn->flags))
|
||||
nn = nn->next;
|
||||
|
||||
while (NULL != nn) {
|
||||
@ -960,17 +960,17 @@ print_man_node(DECL_ARGS)
|
||||
if ('\0' == *n->string) {
|
||||
term_vspace(p);
|
||||
return;
|
||||
} else if (' ' == *n->string && MAN_LINE & n->flags)
|
||||
} else if (' ' == *n->string && NODE_LINE & n->flags)
|
||||
term_newln(p);
|
||||
|
||||
term_word(p, n->string);
|
||||
goto out;
|
||||
|
||||
case ROFFT_EQN:
|
||||
if ( ! (n->flags & MAN_LINE))
|
||||
if ( ! (n->flags & NODE_LINE))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_eqn(p, n->eqn);
|
||||
if (n->next != NULL && ! (n->next->flags & MAN_LINE))
|
||||
if (n->next != NULL && ! (n->next->flags & NODE_LINE))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
return;
|
||||
case ROFFT_TBL:
|
||||
@ -1007,7 +1007,7 @@ out:
|
||||
*/
|
||||
if (mt->fl & MANT_LITERAL &&
|
||||
! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
|
||||
(n->next == NULL || n->next->flags & MAN_LINE)) {
|
||||
(n->next == NULL || n->next->flags & NODE_LINE)) {
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
@ -1023,7 +1023,7 @@ out:
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
}
|
||||
if (MAN_EOS & n->flags)
|
||||
if (NODE_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
}
|
||||
|
||||
|
61
mandoc.1
61
mandoc.1
@ -1,7 +1,7 @@
|
||||
.\" $Id: mandoc.1,v 1.164 2015/11/05 17:47:51 schwarze Exp $
|
||||
.\" $Id: mandoc.1,v 1.171 2017/01/21 02:32:39 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -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: November 5 2015 $
|
||||
.Dd $Mdocdate: January 21 2017 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -75,6 +75,10 @@ This overrides any earlier
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl h
|
||||
Display only the SYNOPSIS lines.
|
||||
Implies
|
||||
.Fl c .
|
||||
.It Fl I Cm os Ns = Ns Ar name
|
||||
Override the default operating system
|
||||
.Ar name
|
||||
@ -85,10 +89,6 @@ and for the
|
||||
.Xr man 7
|
||||
.Sq \&TH
|
||||
macro.
|
||||
.It Fl h
|
||||
Display only the SYNOPSIS lines.
|
||||
Implies
|
||||
.Fl c .
|
||||
.It Fl K Ar encoding
|
||||
Specify the input encoding.
|
||||
The supported
|
||||
@ -498,7 +498,15 @@ Use
|
||||
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.
|
||||
.Pp
|
||||
The first paragraph shows meta data found in the
|
||||
.Xr mdoc 7
|
||||
prologue, on the
|
||||
.Xr man 7
|
||||
.Ic \&TH
|
||||
line, or the fallbacks used.
|
||||
.Pp
|
||||
In the tree dump, each output line shows one syntax tree node.
|
||||
Child nodes are indented with respect to their parent node.
|
||||
The columns are:
|
||||
.Pp
|
||||
@ -529,6 +537,12 @@ The input column number (starting at one).
|
||||
A closing parenthesis if the node is a closing delimiter.
|
||||
.It
|
||||
A full stop if the node ends a sentence.
|
||||
.It
|
||||
NOSRC if the node is not in the input file,
|
||||
but automatically generated from macros.
|
||||
.It
|
||||
NOPRT if the node is not supposed to generate output
|
||||
for any output format.
|
||||
.El
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
@ -809,11 +823,13 @@ This may confuse
|
||||
.Xr makewhatis 8
|
||||
and
|
||||
.Xr apropos 1 .
|
||||
.It Sy "NAME section without name"
|
||||
.It Sy "NAME section without Nm before Nd"
|
||||
.Pq mdoc
|
||||
The NAME section does not contain any
|
||||
.Ic \&Nm
|
||||
child macro.
|
||||
child macro before the first
|
||||
.Ic \&Nd
|
||||
macro.
|
||||
.It Sy "NAME section without description"
|
||||
.Pq mdoc
|
||||
The NAME section lacks the mandatory
|
||||
@ -830,6 +846,11 @@ The NAME section contains plain text or macros other than
|
||||
.Ic \&Nm
|
||||
and
|
||||
.Ic \&Nd .
|
||||
.It Sy "missing comma before name"
|
||||
.Pq mdoc
|
||||
The NAME section contains an
|
||||
.Ic \&Nm
|
||||
macro that is neither the first one nor preceded by a comma.
|
||||
.It Sy "missing description line, using \(dq\(dq"
|
||||
.Pq mdoc
|
||||
The
|
||||
@ -1147,6 +1168,13 @@ macro is immediately followed by an
|
||||
.Ic \&Re
|
||||
macro on the next input line.
|
||||
Such an empty block does not produce any output.
|
||||
.It Sy "missing section argument"
|
||||
.Pq mdoc
|
||||
An
|
||||
.Ic \&Xr
|
||||
macro lacks its second, section number argument.
|
||||
The first argument, i.e. the name, is printed, but without subsequent
|
||||
parentheses.
|
||||
.It Sy "missing -std argument, adding it"
|
||||
.Pq mdoc
|
||||
An
|
||||
@ -1615,8 +1643,8 @@ macro fails to specify the list type.
|
||||
.It Sy "missing manual name, using \(dq\(dq"
|
||||
.Pq mdoc
|
||||
The first call to
|
||||
.Ic \&Nm
|
||||
lacks the required argument.
|
||||
.Ic \&Nm ,
|
||||
or any call in the NAME section, lacks the required argument.
|
||||
.It Sy "uname(3) system call failed, using UNKNOWN"
|
||||
.Pq mdoc
|
||||
The
|
||||
@ -1812,12 +1840,3 @@ utility was written by
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
and is maintained by
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
||||
.Sh BUGS
|
||||
In
|
||||
.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 Cm style Ns = Ns Ar really/long/link .
|
||||
|
33
mandoc.3
33
mandoc.3
@ -1,7 +1,7 @@
|
||||
.\" $Id: mandoc.3,v 1.37 2016/07/07 19:19:01 schwarze Exp $
|
||||
.\" $Id: mandoc.3,v 1.38 2017/01/09 01:37:03 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -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: July 7 2016 $
|
||||
.Dd $Mdocdate: January 9 2017 $
|
||||
.Dt MANDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -34,7 +34,8 @@
|
||||
.Nm mparse_reset ,
|
||||
.Nm mparse_result ,
|
||||
.Nm mparse_strerror ,
|
||||
.Nm mparse_strlevel
|
||||
.Nm mparse_strlevel ,
|
||||
.Nm mparse_updaterc
|
||||
.Nd mandoc macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
@ -100,6 +101,11 @@
|
||||
.Fo mparse_strlevel
|
||||
.Fa "enum mandoclevel"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_updaterc
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "enum mandoclevel *rc"
|
||||
.Fc
|
||||
.In roff.h
|
||||
.Ft void
|
||||
.Fo deroff
|
||||
@ -181,6 +187,9 @@ or
|
||||
.Fn man_validate ,
|
||||
respectively;
|
||||
.It
|
||||
if information about the validity of the input is needed, fetch it with
|
||||
.Fn mparse_updaterc ;
|
||||
.It
|
||||
iterate over parse nodes with starting from the
|
||||
.Fa first
|
||||
member of the returned
|
||||
@ -416,6 +425,22 @@ Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_updaterc
|
||||
If the highest warning or error level that occurred during the current
|
||||
.Fa parse
|
||||
is higher than
|
||||
.Pf * Fa rc ,
|
||||
update
|
||||
.Pf * Fa rc
|
||||
accordingly.
|
||||
This is useful after calling
|
||||
.Fn mdoc_validate
|
||||
or
|
||||
.Fn man_validate .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.El
|
||||
.Ss Variables
|
||||
.Bl -ohang
|
||||
|
276
mandoc.css
276
mandoc.css
@ -1,159 +1,173 @@
|
||||
/* $Id: mandoc.css,v 1.2 2016/04/13 10:19:23 schwarze Exp $ */
|
||||
|
||||
/* $Id: mandoc.css,v 1.13 2017/01/21 02:29:57 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 traditional cvsweb output.
|
||||
*
|
||||
* See mdoc(7) and man(7) for macro explanations.
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*/
|
||||
|
||||
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% }
|
||||
div.section > h1 { 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. */
|
||||
td { vertical-align: top; } /* All table cells. */
|
||||
p { } /* Paragraph: Pp, Lp. */
|
||||
blockquote { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1. */
|
||||
div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
|
||||
div.subsection { } /* Sub-sections (Ss, SS). */
|
||||
table.synopsis { } /* SYNOPSIS section table. */
|
||||
div.spacer { margin: 1em 0; }
|
||||
/* Global defaults. */
|
||||
|
||||
/* Preamble structure. */
|
||||
html { max-width: 100ex; }
|
||||
body { font-family: Helvetica,Arial,sans-serif; }
|
||||
table { margin-top: 0em;
|
||||
margin-bottom: 0em; }
|
||||
td { vertical-align: top; }
|
||||
ul, ol, dl { margin-top: 0em;
|
||||
margin-bottom: 0em; }
|
||||
li, dt { margin-top: 1em; }
|
||||
|
||||
table.foot { font-size: smaller; margin-top: 1em; border-top: 1px dotted #dddddd; } /* Document footer. */
|
||||
td.foot-date { width: 50%; } /* Document footer: date. */
|
||||
td.foot-os { width: 50%; } /* Document footer: OS/source. */
|
||||
table.head { font-size: smaller; margin-bottom: 1em; border-bottom: 1px dotted #dddddd; } /* Document header. */
|
||||
td.head-ltitle { width: 10%; } /* Document header: left-title. */
|
||||
td.head-vol { width: 80%; } /* Document header: volume. */
|
||||
td.head-rtitle { width: 10%; } /* Document header: right-title. */
|
||||
/* Search form and search results. */
|
||||
|
||||
/* General font modes. */
|
||||
fieldset { border: thin solid silver;
|
||||
border-radius: 1em;
|
||||
text-align: center; }
|
||||
input[name=expr] {
|
||||
width: 25%; }
|
||||
|
||||
i { } /* Italic: BI, IB, I, (implicit). */
|
||||
.emph { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
|
||||
b { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
|
||||
.symb { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
|
||||
small { } /* Small: SB, SM. */
|
||||
.lit { font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */
|
||||
table.results { margin-top: 1em;
|
||||
margin-left: 2em;
|
||||
font-size: smaller; }
|
||||
|
||||
/* Block modes. */
|
||||
/* Header and footer lines. */
|
||||
|
||||
.display { } /* Top of all Bd, D1, Dl. */
|
||||
.list { } /* Top of all Bl. */
|
||||
table.head { width: 100%;
|
||||
border-bottom: 1px dotted #808080;
|
||||
margin-bottom: 1em;
|
||||
font-size: smaller; }
|
||||
td.head-vol { text-align: center; }
|
||||
td.head-rtitle {
|
||||
text-align: right; }
|
||||
span.Nd { }
|
||||
|
||||
/* Context-specific modes. */
|
||||
table.foot { width: 100%;
|
||||
border-top: 1px dotted #808080;
|
||||
margin-top: 1em;
|
||||
font-size: smaller; }
|
||||
td.foot-os { text-align: right; }
|
||||
|
||||
i.addr { font-weight: normal; } /* Address (Ad). */
|
||||
i.arg { font-weight: normal; } /* Command argument (Ar). */
|
||||
span.author { } /* Author name (An). */
|
||||
b.cmd { font-style: normal; } /* Command (Cm). */
|
||||
b.config { font-style: normal; } /* Config statement (Cd). */
|
||||
span.define { } /* Defines (Dv). */
|
||||
span.desc { } /* Nd. After em-dash. */
|
||||
b.diag { font-style: normal; } /* Diagnostic (Bl -diag). */
|
||||
span.env { } /* Environment variables (Ev). */
|
||||
span.errno { } /* Error string (Er). */
|
||||
i.farg { font-weight: normal; } /* Function argument (Fa, Fn). */
|
||||
i.file { font-weight: normal; } /* File (Pa). */
|
||||
b.flag { font-style: normal; } /* Flag (Fl, Cm). */
|
||||
b.fname { font-style: normal; } /* Function name (Fa, Fn, Rv). */
|
||||
i.ftype { font-weight: normal; } /* Function types (Ft, Fn). */
|
||||
b.includes { font-style: normal; } /* Header includes (In). */
|
||||
span.lib { } /* Library (Lb). */
|
||||
i.link-sec { font-weight: normal; } /* Section links (Sx). */
|
||||
b.macro { font-style: normal; } /* Macro-ish thing (Fd). */
|
||||
b.name { font-style: normal; } /* Name of utility (Nm). */
|
||||
span.opt { } /* Options (Op, Oo/Oc). */
|
||||
span.ref { } /* Citations (Rs). */
|
||||
span.ref-auth { } /* Reference author (%A). */
|
||||
i.ref-book { font-weight: normal; } /* Reference book (%B). */
|
||||
span.ref-city { } /* Reference city (%C). */
|
||||
span.ref-date { } /* Reference date (%D). */
|
||||
i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */
|
||||
i.ref-jrnl { font-weight: normal; } /* Reference journal (%J). */
|
||||
span.ref-num { } /* Reference number (%N). */
|
||||
span.ref-opt { } /* Reference optionals (%O). */
|
||||
span.ref-page { } /* Reference page (%P). */
|
||||
span.ref-corp { } /* Reference corporate/foreign author (%Q). */
|
||||
span.ref-rep { } /* Reference report (%R). */
|
||||
span.ref-title { text-decoration: underline; } /* Reference title (%T). */
|
||||
span.ref-vol { } /* Reference volume (%V). */
|
||||
span.type { font-style: italic; font-weight: normal; } /* Variable types (Vt). */
|
||||
span.unix { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
|
||||
b.utility { font-style: normal; } /* Name of utility (Ex). */
|
||||
b.var { font-style: normal; } /* Variables (Rv). */
|
||||
/* Sections and paragraphs. */
|
||||
|
||||
a.link-ext { } /* Off-site link (Lk). */
|
||||
a.link-includes { } /* Include-file link (In). */
|
||||
a.link-mail { } /* Mailto links (Mt). */
|
||||
a.link-man { } /* Manual links (Xr). */
|
||||
a.link-ref { } /* Reference section links (%Q). */
|
||||
a.link-sec { } /* Section links (Sx). */
|
||||
div.manual-text {
|
||||
margin-left: 5ex; }
|
||||
h1.Sh { margin-top: 2ex;
|
||||
margin-bottom: 1ex;
|
||||
margin-left: -4ex;
|
||||
font-size: 110%; }
|
||||
h2.Ss { margin-top: 2ex;
|
||||
margin-bottom: 1ex;
|
||||
margin-left: -2ex;
|
||||
font-size: 105%; }
|
||||
div.Pp { margin: 1ex 0ex; }
|
||||
a.Sx { }
|
||||
a.Xr { }
|
||||
|
||||
/* Formatting for lists. See mdoc(7). */
|
||||
/* Displays and lists. */
|
||||
|
||||
dl.list-diag { }
|
||||
dt.list-diag { }
|
||||
dd.list-diag { }
|
||||
div.Bd { }
|
||||
div.D1 { margin-left: 5ex; }
|
||||
|
||||
dl.list-hang { }
|
||||
dt.list-hang { }
|
||||
dd.list-hang { }
|
||||
ul.Bl-bullet { list-style-type: disc;
|
||||
padding-left: 1em; }
|
||||
li.It-bullet { }
|
||||
ul.Bl-dash { list-style-type: none;
|
||||
padding-left: 0em; }
|
||||
li.It-dash:before {
|
||||
content: "\2014 "; }
|
||||
ul.Bl-item { list-style-type: none;
|
||||
padding-left: 0em; }
|
||||
li.It-item { }
|
||||
|
||||
dl.list-inset { }
|
||||
dt.list-inset { }
|
||||
dd.list-inset { }
|
||||
ol.Bl-enum { padding-left: 2em; }
|
||||
li.It-enum { }
|
||||
|
||||
dl.list-ohang { }
|
||||
dt.list-ohang { }
|
||||
dd.list-ohang { margin-left: 0ex; }
|
||||
dl.Bl-diag { }
|
||||
dt.It-diag { }
|
||||
dd.It-diag { }
|
||||
b.It-diag { font-style: normal; }
|
||||
dl.Bl-hang { }
|
||||
dt.It-hang { }
|
||||
dd.It-hang { }
|
||||
dl.Bl-inset { }
|
||||
dt.It-inset { }
|
||||
dd.It-inset { }
|
||||
dl.Bl-ohang { }
|
||||
dt.It-ohang { }
|
||||
dd.It-ohang { margin-left: 0ex; }
|
||||
dl.Bl-tag { }
|
||||
dt.It-tag { }
|
||||
dd.It-tag { }
|
||||
|
||||
dl.list-tag { }
|
||||
dt.list-tag { }
|
||||
dd.list-tag { }
|
||||
table.Bl-column { }
|
||||
tr.It-column { }
|
||||
td.It-column { margin-top: 1em; }
|
||||
|
||||
table.list-col { }
|
||||
tr.list-col { }
|
||||
td.list-col { }
|
||||
span.Rs { }
|
||||
span.RsA { }
|
||||
i.RsB { font-weight: normal; }
|
||||
span.RsC { }
|
||||
span.RsD { }
|
||||
i.RsI { font-weight: normal; }
|
||||
i.RsJ { font-weight: normal; }
|
||||
span.RsN { }
|
||||
span.RsO { }
|
||||
span.RsP { }
|
||||
span.RsQ { }
|
||||
span.RsR { }
|
||||
span.RsT { text-decoration: underline; }
|
||||
a.RsU { }
|
||||
span.RsV { }
|
||||
|
||||
ul.list-bul { list-style-type: disc; padding-left: 1em; }
|
||||
li.list-bul { }
|
||||
span.eqn { }
|
||||
table.tbl { }
|
||||
|
||||
ul.list-dash { list-style-type: none; padding-left: 0em; }
|
||||
li.list-dash:before { content: "\2014 "; }
|
||||
/* Semantic markup for command line utilities. */
|
||||
|
||||
ul.list-hyph { list-style-type: none; padding-left: 0em; }
|
||||
li.list-hyph:before { content: "\2013 "; }
|
||||
table.Nm { }
|
||||
b.Nm { font-style: normal; }
|
||||
b.Fl { font-style: normal; }
|
||||
b.Cm { font-style: normal; }
|
||||
i.Ar { font-weight: normal; }
|
||||
span.Op { }
|
||||
b.Ic { font-style: normal; }
|
||||
code.Ev { font-style: normal;
|
||||
font-weight: normal;
|
||||
font-family: monospace; }
|
||||
i.Pa { font-weight: normal; }
|
||||
|
||||
ul.list-item { list-style-type: none; padding-left: 0em; }
|
||||
li.list-item { }
|
||||
/* Semantic markup for function libraries. */
|
||||
|
||||
ol.list-enum { padding-left: 2em; }
|
||||
li.list-enum { }
|
||||
span.Lb { }
|
||||
b.In { font-style: normal; }
|
||||
a.In { }
|
||||
b.Fd { font-style: normal; }
|
||||
i.Ft { font-weight: normal; }
|
||||
b.Fn { font-style: normal; }
|
||||
i.Fa { font-weight: normal; }
|
||||
i.Vt { font-weight: normal; }
|
||||
i.Va { font-weight: normal; }
|
||||
code.Dv { font-style: normal;
|
||||
font-weight: normal;
|
||||
font-family: monospace; }
|
||||
code.Er { font-style: normal;
|
||||
font-weight: normal;
|
||||
font-family: monospace; }
|
||||
|
||||
/* Equation modes. See eqn(7). */
|
||||
/* Various semantic markup. */
|
||||
|
||||
span.eqn { }
|
||||
span.An { }
|
||||
a.Lk { }
|
||||
a.Mt { }
|
||||
b.Cd { font-style: normal; }
|
||||
i.Ad { font-weight: normal; }
|
||||
b.Ms { font-style: normal; }
|
||||
a.Ux { }
|
||||
|
||||
/* Table modes. See tbl(7). */
|
||||
/* Physical markup. */
|
||||
|
||||
table.tbl { }
|
||||
.No { font-style: normal;
|
||||
font-weight: normal; }
|
||||
.Em { font-style: italic;
|
||||
font-weight: normal; }
|
||||
.Sy { font-style: normal;
|
||||
font-weight: bold; }
|
||||
.Li { font-style: normal;
|
||||
font-weight: normal;
|
||||
font-family: monospace; }
|
||||
|
234
mandoc.db.5
234
mandoc.db.5
@ -1,6 +1,6 @@
|
||||
.\" $Id: mandoc.db.5,v 1.4 2016/07/07 14:35:48 schwarze Exp $
|
||||
.\" $Id: mandoc.db.5,v 1.5 2016/08/01 12:27:15 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2014, 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
|
||||
@ -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: July 7 2016 $
|
||||
.Dd $Mdocdate: August 1 2016 $
|
||||
.Dt MANDOC.DB 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -23,7 +23,7 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
SQLite3 file format is used to store information about installed manual
|
||||
file format is used to store information about installed manual
|
||||
pages to facilitate semantic searching for manuals.
|
||||
Each manual page tree contains its own
|
||||
.Nm
|
||||
@ -34,87 +34,156 @@ for examples.
|
||||
Such database files are generated by
|
||||
.Xr makewhatis 8
|
||||
and used by
|
||||
.Xr man 1 ,
|
||||
.Xr apropos 1
|
||||
and
|
||||
.Xr whatis 1 .
|
||||
.Pp
|
||||
One line in the following tables describes:
|
||||
.Bl -tag -width Ds
|
||||
.It Sy mpages
|
||||
One physical manual page file, no matter how many times and under which
|
||||
names it may appear in the file system.
|
||||
.It Sy mlinks
|
||||
One entry in the file system, no matter which content it points to.
|
||||
.It Sy names
|
||||
One manual page name, no matter whether it appears in a page header,
|
||||
in a NAME or SYNOPSIS section, or as a file name.
|
||||
.It Sy keys
|
||||
One chunk of text from some macro invocation.
|
||||
The file format uses three datatypes:
|
||||
.Pp
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
32-bit signed integer numbers in big endian (network) byte ordering
|
||||
.It
|
||||
NUL-terminated strings
|
||||
.It
|
||||
lists of NUL-terminated strings, terminated by a second NUL character
|
||||
.El
|
||||
.Pp
|
||||
Each record in the latter three tables uses its
|
||||
.Va pageid
|
||||
column to point to a record in the
|
||||
.Sy mpages
|
||||
table.
|
||||
Numbers are aligned to four-byte boundaries; where they follow
|
||||
strings or lists of strings, padding with additional NUL characters
|
||||
occurs.
|
||||
Some, but not all, numbers point to positions in the file.
|
||||
These pointers are measured in bytes, and the first byte of the
|
||||
file is considered to be byte 0.
|
||||
.Pp
|
||||
The other columns are as follows; unless stated otherwise, they are
|
||||
of type
|
||||
.Vt TEXT .
|
||||
.Bl -tag -width mpages.desc
|
||||
.It Sy mpages.desc
|
||||
The description line
|
||||
.Pq Sq \&Nd
|
||||
of the page.
|
||||
.It Sy mpages.form
|
||||
An
|
||||
.Vt INTEGER
|
||||
bit field.
|
||||
If bit
|
||||
.Dv FORM_GZ
|
||||
is set, the page is compressed and requires
|
||||
.Xr gunzip 1
|
||||
for display.
|
||||
If bit
|
||||
.Dv FORM_SRC
|
||||
is set, the page is unformatted, that is in
|
||||
Each file consists of:
|
||||
.Pp
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
One magic number, 0x3a7d0cdb.
|
||||
.It
|
||||
One version number, currently 1.
|
||||
.It
|
||||
One pointer to the macros table.
|
||||
.It
|
||||
One pointer to the final magic number.
|
||||
.It
|
||||
The pages table (variable length).
|
||||
.It
|
||||
The macros table (variable length).
|
||||
.It
|
||||
The magic number once again, 0x3a7d0cdb.
|
||||
.El
|
||||
.Pp
|
||||
The pages table contains one entry for each physical manual page
|
||||
file, no matter how many hard and soft links it may have in the
|
||||
file system.
|
||||
The pages table consists of:
|
||||
.Pp
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
The number of pages in the database.
|
||||
.It
|
||||
For each page:
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
One pointer to the list of names.
|
||||
.It
|
||||
One pointer to the list of sections.
|
||||
.It
|
||||
One pointer to the list of architectures
|
||||
or 0 if the page is machine-independent.
|
||||
.It
|
||||
One pointer to the one-line description string.
|
||||
.It
|
||||
One pointer to the list of filenames.
|
||||
.El
|
||||
.It
|
||||
For each page, the list of names.
|
||||
Each name is preceded by a single byte indicating the sources of the name.
|
||||
The meaning of the bits is:
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
0x10: The name appears in a filename.
|
||||
.It
|
||||
0x08: The name appears in a header line, i.e. in a .Dt or .TH macro.
|
||||
.It
|
||||
0x04: The name is the first one in the title line, i.e. it appears
|
||||
in the first .Nm macro in the NAME section.
|
||||
.It
|
||||
0x02: The name appears in any .Nm macro in the NAME section.
|
||||
.It
|
||||
0x01: The name appears in an .Nm block in the SYNOPSIS section.
|
||||
.El
|
||||
.It
|
||||
For each page, the list of sections.
|
||||
Each section is given as a string, not as a number.
|
||||
.It
|
||||
For each architecture-dependent page, the list of architectures.
|
||||
.It
|
||||
For each page, the one-line description string taken from the .Nd macro.
|
||||
.It
|
||||
For each page, the list of filenames relative to the root of the
|
||||
respective manpath.
|
||||
This list includes hard links, soft links, and links simulated
|
||||
with .so
|
||||
.Xr roff 7
|
||||
requests.
|
||||
The first filename is preceded by a single byte
|
||||
having the following significance:
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
.Dv FORM_SRC No = 0x01 :
|
||||
The file format is
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
format, and requires
|
||||
.Xr mandoc 1
|
||||
for display.
|
||||
If bit
|
||||
.Dv FORM_SRC
|
||||
is not set, the page is formatted, i.e. a
|
||||
.Sq cat
|
||||
page.
|
||||
.It Sy mlinks.sec
|
||||
The manual section as found in the subdirectory name.
|
||||
.It Sy mlinks.arch
|
||||
The manual architecture as found in the subdirectory name, or
|
||||
.Qq any .
|
||||
.It Sy mlinks.name
|
||||
The manual name as found in the file name.
|
||||
.It Sy names.bits
|
||||
An
|
||||
.Vt INTEGER
|
||||
bit mask telling whether the name came from a header line, from the
|
||||
NAME or SYNOPSIS section, or from a file name.
|
||||
Bits are defined in
|
||||
.In mansearch.h .
|
||||
.It Sy names.name
|
||||
The name itself.
|
||||
.It Sy keys.bits
|
||||
An
|
||||
.Vt INTEGER
|
||||
bit mask telling which semantic contexts the key was found in;
|
||||
defined in
|
||||
.In mansearch.h ,
|
||||
documented in
|
||||
.Xr man 7 .
|
||||
.It
|
||||
.Dv FORM_CAT No = 0x02 :
|
||||
The manual page is preformatted.
|
||||
.El
|
||||
.It
|
||||
Zero to three NUL bytes for padding.
|
||||
.El
|
||||
.Pp
|
||||
The macros table consists of:
|
||||
.Pp
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
The number of different macro keys, currently 36.
|
||||
The ordering of macros is defined in
|
||||
.In mansearch.h
|
||||
and the significance of the macro keys is documented in
|
||||
.Xr apropos 1 .
|
||||
.It Sy keys.key
|
||||
The string found in those contexts.
|
||||
.It
|
||||
For each macro key, one pointer to the respective macro table.
|
||||
.It
|
||||
For each macro key, the macro table (variable length).
|
||||
.El
|
||||
.Pp
|
||||
Each macro table consists of:
|
||||
.Pp
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
The number of entries in the table.
|
||||
.It
|
||||
For each entry:
|
||||
.Bl -dash -compact -offset 2n -width 1n
|
||||
.It
|
||||
One pointer to the value of the macro key.
|
||||
Each value is a string of text taken from some macro invocation.
|
||||
.It
|
||||
One pointer to the list of pages.
|
||||
.El
|
||||
.It
|
||||
For each entry, the value of the macro key.
|
||||
.It
|
||||
Zero to three NUL bytes for padding.
|
||||
.It
|
||||
For each entry, one or more pointers to pages in the pages table,
|
||||
pointing to the pointer to the list of names,
|
||||
followed by the number 0.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/share/man/mandoc.db -compact
|
||||
@ -128,10 +197,16 @@ Window System.
|
||||
The same for
|
||||
.Xr packages 7 .
|
||||
.El
|
||||
.Pp
|
||||
A program to dump
|
||||
.Nm
|
||||
files in a human-readable format suitable for
|
||||
.Xr diff 1
|
||||
is provided in the directory
|
||||
.Pa /usr/src/regress/usr.bin/mandoc/db/dbm_dump/ .
|
||||
.Sh SEE ALSO
|
||||
.Xr apropos 1 ,
|
||||
.Xr man 1 ,
|
||||
.Xr sqlite3 1 ,
|
||||
.Xr whatis 1 ,
|
||||
.Xr makewhatis 8
|
||||
.Sh HISTORY
|
||||
@ -140,7 +215,7 @@ A manual page database
|
||||
first appeared in
|
||||
.Bx 2 .
|
||||
The present format first appeared in
|
||||
.Ox 5.6 .
|
||||
.Ox 6.1 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The original version of
|
||||
@ -148,9 +223,6 @@ The original version of
|
||||
was written by
|
||||
.An Bill Joy
|
||||
in 1979.
|
||||
An SQLite3 version was first implemented by
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
in 2012.
|
||||
The present database format was designed by
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
||||
in 2014.
|
||||
in 2016.
|
||||
|
11
mandoc.h
11
mandoc.h
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc.h,v 1.209 2016/01/08 02:53:13 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.213 2017/01/09 01:37:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -65,10 +65,11 @@ enum mandocerr {
|
||||
MANDOCERR_DOC_EMPTY, /* no document body */
|
||||
MANDOCERR_SEC_BEFORE, /* content before first section header: macro */
|
||||
MANDOCERR_NAMESEC_FIRST, /* first section is not NAME: Sh title */
|
||||
MANDOCERR_NAMESEC_NONM, /* NAME section without name */
|
||||
MANDOCERR_NAMESEC_NONM, /* NAME section without Nm before Nd */
|
||||
MANDOCERR_NAMESEC_NOND, /* NAME section without description */
|
||||
MANDOCERR_NAMESEC_ND, /* description not at the end of NAME */
|
||||
MANDOCERR_NAMESEC_BAD, /* bad NAME section content: macro */
|
||||
MANDOCERR_NAMESEC_PUNCT, /* missing comma before name: Nm name */
|
||||
MANDOCERR_ND_EMPTY, /* missing description line, using "" */
|
||||
MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
|
||||
MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
|
||||
@ -98,7 +99,7 @@ enum mandocerr {
|
||||
MANDOCERR_ARG_EMPTY, /* empty argument, using 0n: macro arg */
|
||||
MANDOCERR_BD_NOTYPE, /* missing display type, using -ragged: Bd */
|
||||
MANDOCERR_BL_LATETYPE, /* list type is not the first argument: Bl arg */
|
||||
MANDOCERR_BL_NOWIDTH, /* missing -width in -tag list, using 8n */
|
||||
MANDOCERR_BL_NOWIDTH, /* missing -width in -tag list, using 6n */
|
||||
MANDOCERR_EX_NONAME, /* missing utility name, using "": Ex */
|
||||
MANDOCERR_FO_NOHEAD, /* missing function name, using "": Fo */
|
||||
MANDOCERR_IT_NOHEAD, /* empty head in list item: Bl -type It */
|
||||
@ -107,6 +108,7 @@ enum mandocerr {
|
||||
MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */
|
||||
MANDOCERR_PF_SKIP, /* nothing follows prefix: Pf arg */
|
||||
MANDOCERR_RS_EMPTY, /* empty reference block: Rs */
|
||||
MANDOCERR_XR_NOSEC, /* missing section argument: Xr arg */
|
||||
MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
|
||||
MANDOCERR_OP_EMPTY, /* missing option string, using "": OP */
|
||||
MANDOCERR_UR_NOHEAD, /* missing resource identifier, using "": UR */
|
||||
@ -433,3 +435,4 @@ void mparse_result(struct mparse *,
|
||||
const char *mparse_getkeep(const struct mparse *);
|
||||
const char *mparse_strerror(enum mandocerr);
|
||||
const char *mparse_strlevel(enum mandoclevel);
|
||||
void mparse_updaterc(struct mparse *, enum mandoclevel *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc_aux.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: mandoc_aux.h,v 1.5 2016/07/19 13:36:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,7 +16,8 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
int mandoc_asprintf(char **, const char *, ...);
|
||||
int mandoc_asprintf(char **, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)));
|
||||
void *mandoc_calloc(size_t, size_t);
|
||||
void *mandoc_malloc(size_t);
|
||||
void *mandoc_realloc(void *, size_t);
|
||||
|
179
mandoc_html.3
179
mandoc_html.3
@ -1,6 +1,6 @@
|
||||
.\" $Id: mandoc_html.3,v 1.1 2014/07/23 18:13:09 schwarze Exp $
|
||||
.\" $Id: mandoc_html.3,v 1.3 2017/01/17 15:32:44 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -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: July 23 2014 $
|
||||
.Dd $Mdocdate: January 17 2017 $
|
||||
.Dt MANDOC_HTML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -30,8 +30,8 @@
|
||||
.Fo print_otag
|
||||
.Fa "struct html *h"
|
||||
.Fa "enum htmltag tag"
|
||||
.Fa "int sz"
|
||||
.Fa "const struct htmlpair *p"
|
||||
.Fa "const char *fmt"
|
||||
.Fa ...
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo print_tagq
|
||||
@ -84,15 +84,6 @@ These structures are declared in
|
||||
.Bl -tag -width Ds
|
||||
.It Vt struct html
|
||||
Internal state of the HTML formatter.
|
||||
.It Vt struct htmlpair
|
||||
Holds one HTML attribute.
|
||||
Members are
|
||||
.Fa "enum htmlattr key"
|
||||
and
|
||||
.Fa "const char *val" .
|
||||
Helper macros
|
||||
.Fn PAIR_*
|
||||
are provided to support initialization of such structures.
|
||||
.It Vt struct tag
|
||||
One entry for the LIFO stack of HTML elements.
|
||||
Members are
|
||||
@ -134,14 +125,136 @@ The function
|
||||
.Fn print_otag
|
||||
prints the start tag of an HTML element with the name
|
||||
.Fa tag ,
|
||||
including the
|
||||
.Fa sz
|
||||
attributes that can optionally be provided in the
|
||||
.Fa p
|
||||
array.
|
||||
It uses the private function
|
||||
.Fn print_attr
|
||||
which in turn uses the private function
|
||||
optionally including the attributes specified by
|
||||
.Fa fmt .
|
||||
If
|
||||
.Fa fmt
|
||||
is the empty string, no attributes are written.
|
||||
Each letter of
|
||||
.Fa fmt
|
||||
specifies one attribute to write.
|
||||
Most attributes require one
|
||||
.Va char *
|
||||
argument which becomes the value of the attribute.
|
||||
The arguments have to be given in the same order as the attribute letters.
|
||||
.Bl -tag -width 1n -offset indent
|
||||
.It Cm c
|
||||
Print a
|
||||
.Cm class
|
||||
attribute.
|
||||
.It Cm h
|
||||
Print a
|
||||
.Cm href
|
||||
attribute.
|
||||
This attribute letter can optionally be followed by a modifier letter.
|
||||
If followed by
|
||||
.Cm R ,
|
||||
it formats the link as a local one by prefixing a
|
||||
.Sq #
|
||||
character.
|
||||
If followed by
|
||||
.Cm I ,
|
||||
it interpretes the argument as a header file name
|
||||
and generates a link using the
|
||||
.Xr mandoc 1
|
||||
.Fl O Cm includes
|
||||
option.
|
||||
If followed by
|
||||
.Cm M ,
|
||||
it takes two arguments instead of one, a manual page name and
|
||||
section, and formats them as a link to a manual page using the
|
||||
.Xr mandoc 1
|
||||
.Fl O Cm man
|
||||
option.
|
||||
.It Cm i
|
||||
Print an
|
||||
.Cm id
|
||||
attribute.
|
||||
.It Cm \&?
|
||||
Print an arbitrary attribute.
|
||||
This format letter requires two
|
||||
.Vt char *
|
||||
arguments, the attribute name and the value.
|
||||
.It Cm s
|
||||
Print a
|
||||
.Cm style
|
||||
attribute.
|
||||
If present, it must be the last format letter.
|
||||
In contrast to the other format letters, this one does not yet
|
||||
print the value and does not require an argument.
|
||||
Instead, the rest of the format string consists of pairs of
|
||||
argument type letters and style name letters.
|
||||
.El
|
||||
.Pp
|
||||
Argument type letters each require on argument as follows:
|
||||
.Bl -tag -width 1n -offset indent
|
||||
.It Cm h
|
||||
Requires one
|
||||
.Vt int
|
||||
argument, interpreted as a horizontal length in units of
|
||||
.Dv SCALE_EN .
|
||||
.It Cm s
|
||||
Requires one
|
||||
.Vt char *
|
||||
argument, used as a style value.
|
||||
.It Cm u
|
||||
Requires one
|
||||
.Vt struct roffsu *
|
||||
argument, used as a length.
|
||||
.It Cm v
|
||||
Requires one
|
||||
.Vt int
|
||||
argument, interpreted as a vertical length in units of
|
||||
.Dv SCALE_VS .
|
||||
.It Cm w
|
||||
Requires one
|
||||
.Vt char *
|
||||
argument, interpreted as an
|
||||
.Xr mdoc 7 Ns -style
|
||||
width specifier.
|
||||
.El
|
||||
.Pp
|
||||
Style name letters decide what to do with the preceding argument:
|
||||
.Bl -tag -width 1n -offset indent
|
||||
.It Cm b
|
||||
Set
|
||||
.Cm margin-bottom
|
||||
to the given length.
|
||||
.It Cm h
|
||||
Set
|
||||
.Cm height
|
||||
to the given length.
|
||||
.It Cm i
|
||||
Set
|
||||
.Cm text-indent
|
||||
to the given length.
|
||||
.It Cm l
|
||||
Set
|
||||
.Cm margin-left
|
||||
to the given length.
|
||||
.It Cm t
|
||||
Set
|
||||
.Cm margin-top
|
||||
to the given length.
|
||||
.It Cm w
|
||||
Set
|
||||
.Cm width
|
||||
to the given length.
|
||||
.It Cm W
|
||||
Set
|
||||
.Cm min-width
|
||||
to the given length.
|
||||
.It Cm \&?
|
||||
The special pair
|
||||
.Cm s?
|
||||
requires two
|
||||
.Vt char *
|
||||
arguments.
|
||||
The first is the style name, the second its value.
|
||||
.El
|
||||
.Pp
|
||||
.Fn print_otag
|
||||
uses the private function
|
||||
.Fn print_encode
|
||||
to take care of HTML encoding.
|
||||
If required by the element type, it remembers in
|
||||
@ -175,28 +288,6 @@ and
|
||||
functions.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn bufinit ,
|
||||
.Fn bufcat* ,
|
||||
and
|
||||
.Fn buffmt*
|
||||
do not directly produce output but buffer text in the
|
||||
.Fa buf
|
||||
member of
|
||||
.Fa h .
|
||||
They are not used internally by
|
||||
.Pa html.c
|
||||
but intended for use by the language-specific formatters
|
||||
to ease preparation of strings for the
|
||||
.Fa p
|
||||
argument of
|
||||
.Fn print_otag
|
||||
and for the
|
||||
.Fa word
|
||||
argument of
|
||||
.Fn print_text .
|
||||
Consequently, these functions do not do any HTML encoding.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn html_strlen ,
|
||||
.Fn print_eqn ,
|
||||
.Fn print_tbl ,
|
||||
|
822
mandocdb.c
822
mandocdb.c
File diff suppressed because it is too large
Load Diff
53
manpath.c
53
manpath.c
@ -1,4 +1,4 @@
|
||||
/* $Id: manpath.c,v 1.30 2016/05/28 13:44:13 schwarze Exp $ */
|
||||
/* $Id: manpath.c,v 1.31 2016/07/19 22:40:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -32,9 +32,7 @@
|
||||
#include "mandoc_aux.h"
|
||||
#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);
|
||||
|
||||
@ -43,52 +41,6 @@ void
|
||||
manconf_parse(struct manconf *conf, const char *file,
|
||||
char *defp, char *auxp)
|
||||
{
|
||||
#if HAVE_MANPATH
|
||||
char cmd[(PATH_MAX * 3) + 20];
|
||||
FILE *stream;
|
||||
char *buf;
|
||||
size_t sz, bsz;
|
||||
|
||||
strlcpy(cmd, "manpath", sizeof(cmd));
|
||||
if (file) {
|
||||
strlcat(cmd, " -C ", sizeof(cmd));
|
||||
strlcat(cmd, file, sizeof(cmd));
|
||||
}
|
||||
if (auxp) {
|
||||
strlcat(cmd, " -m ", sizeof(cmd));
|
||||
strlcat(cmd, auxp, sizeof(cmd));
|
||||
}
|
||||
if (defp) {
|
||||
strlcat(cmd, " -M ", sizeof(cmd));
|
||||
strlcat(cmd, defp, sizeof(cmd));
|
||||
}
|
||||
|
||||
/* Open manpath(1). Ignore errors. */
|
||||
|
||||
stream = popen(cmd, "r");
|
||||
if (NULL == stream)
|
||||
return;
|
||||
|
||||
buf = NULL;
|
||||
bsz = 0;
|
||||
|
||||
/* Read in as much output as we can. */
|
||||
|
||||
do {
|
||||
buf = mandoc_realloc(buf, bsz + 1024);
|
||||
sz = fread(buf + bsz, 1, 1024, stream);
|
||||
bsz += sz;
|
||||
} while (sz > 0);
|
||||
|
||||
if ( ! ferror(stream) && feof(stream) &&
|
||||
bsz && '\n' == buf[bsz - 1]) {
|
||||
buf[bsz - 1] = '\0';
|
||||
manpath_parseline(&conf->manpath, buf, 1);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
pclose(stream);
|
||||
#else
|
||||
char *insert;
|
||||
|
||||
/* Always prepend -m. */
|
||||
@ -137,7 +89,6 @@ manconf_parse(struct manconf *conf, const char *file,
|
||||
|
||||
/* MANPATH overrides man.conf(5) completely. */
|
||||
manpath_parseline(&conf->manpath, defp, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -204,7 +155,6 @@ manconf_free(struct manconf *conf)
|
||||
free(conf->output.style);
|
||||
}
|
||||
|
||||
#if !HAVE_MANPATH
|
||||
static void
|
||||
manconf_file(struct manconf *conf, const char *file)
|
||||
{
|
||||
@ -270,7 +220,6 @@ out:
|
||||
if (*manpath_default != '\0')
|
||||
manpath_parseline(&conf->manpath, manpath_default, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
manconf_output(struct manoutput *conf, const char *cp)
|
||||
|
1055
mansearch.c
1055
mansearch.c
File diff suppressed because it is too large
Load Diff
21
mansearch.h
21
mansearch.h
@ -1,7 +1,7 @@
|
||||
/* $Id: mansearch.h,v 1.24 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: mansearch.h,v 1.27 2016/08/01 12:31:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 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
|
||||
@ -17,6 +17,12 @@
|
||||
*/
|
||||
|
||||
#define MANDOC_DB "mandoc.db"
|
||||
#define MANDOCDB_MAGIC 0x3a7d0cdb
|
||||
#define MANDOCDB_VERSION 1
|
||||
|
||||
#define MACRO_MAX 36
|
||||
#define KEY_Nd 39
|
||||
#define KEY_MAX 40
|
||||
|
||||
#define TYPE_arch 0x0000000000000001ULL
|
||||
#define TYPE_sec 0x0000000000000002ULL
|
||||
@ -66,9 +72,11 @@
|
||||
#define NAME_FILE 0x0000004000000010ULL
|
||||
#define NAME_MASK 0x000000000000001fULL
|
||||
|
||||
#define FORM_CAT 0 /* manual page is preformatted */
|
||||
#define FORM_SRC 1 /* format is mdoc(7) or man(7) */
|
||||
#define FORM_NONE 4 /* format is unknown */
|
||||
enum form {
|
||||
FORM_SRC = 1, /* Format is mdoc(7) or man(7). */
|
||||
FORM_CAT, /* Manual page is preformatted. */
|
||||
FORM_NONE /* Format is unknown. */
|
||||
};
|
||||
|
||||
enum argmode {
|
||||
ARG_FILE = 0,
|
||||
@ -84,7 +92,7 @@ struct manpage {
|
||||
size_t ipath; /* number of the manpath */
|
||||
uint64_t bits; /* name type mask */
|
||||
int sec; /* section number, 10 means invalid */
|
||||
int form; /* 0 == catpage */
|
||||
enum form form;
|
||||
};
|
||||
|
||||
struct mansearch {
|
||||
@ -98,7 +106,6 @@ struct mansearch {
|
||||
|
||||
struct manpaths;
|
||||
|
||||
int mansearch_setup(int);
|
||||
int mansearch(const struct mansearch *cfg, /* options */
|
||||
const struct manpaths *paths, /* manpaths */
|
||||
int argc, /* size of argv */
|
||||
|
41
mdoc.7
41
mdoc.7
@ -1,7 +1,7 @@
|
||||
.\" $Id: mdoc.7,v 1.257 2015/11/05 12:06:45 schwarze Exp $
|
||||
.\" $Id: mdoc.7,v 1.260 2017/01/09 14:10:53 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -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: November 5 2015 $
|
||||
.Dd $Mdocdate: January 9 2017 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1831,14 +1831,25 @@ The
|
||||
list is the most complicated.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Sx \&It Ar cell Op <TAB> Ar cell ...
|
||||
.D1 Pf \. Sx \&It Ar cell Op Sx \&Ta Ar cell ...
|
||||
.D1 Pf \. Sx \&It Ar cell Op <TAB> Ar cell ...
|
||||
.Pp
|
||||
The arguments consist of one or more lines of text and macros
|
||||
representing a complete table line.
|
||||
Cells within the line are delimited by tabs or by the special
|
||||
Cells within the line are delimited by the special
|
||||
.Sx \&Ta
|
||||
block macro.
|
||||
block macro or by literal tab characters.
|
||||
.Pp
|
||||
Using literal tabs is strongly discouraged because they are very
|
||||
hard to use correctly and
|
||||
.Nm
|
||||
code using them is very hard to read.
|
||||
In particular, a blank character is syntactically significant
|
||||
before and after the literal tab character.
|
||||
If a word precedes or follows the tab without an intervening blank,
|
||||
that word is never interpreted as a macro call, but always output
|
||||
literally.
|
||||
.Pp
|
||||
The tab cell delimiter may only be used within the
|
||||
.Sx \&It
|
||||
line itself; on following lines, only the
|
||||
@ -1853,9 +1864,10 @@ Note that quoted strings may span tab-delimited cells on an
|
||||
line.
|
||||
For example,
|
||||
.Pp
|
||||
.Dl .It \(dqcol1 ; <TAB> col2 ;\(dq \&;
|
||||
.Dl .It \(dqcol1 ,\& <TAB> col2 ,\(dq \&;
|
||||
.Pp
|
||||
will preserve the semicolon whitespace except for the last.
|
||||
will preserve the whitespace before both commas,
|
||||
but not the whitespace before the semicolon.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&Bl .
|
||||
@ -2714,14 +2726,13 @@ Link to another manual
|
||||
.Pq Qq cross-reference .
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Sx \&Xr Ar name Op section
|
||||
.D1 Pf \. Sx \&Xr Ar name section
|
||||
.Pp
|
||||
Cross reference the
|
||||
.Ar name
|
||||
and
|
||||
.Ar section
|
||||
number of another man page;
|
||||
omitting the section number is rarely useful.
|
||||
number of another man page.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Xr mandoc 1
|
||||
@ -3033,7 +3044,7 @@ then the macro accepts an arbitrary number of arguments.
|
||||
.It Sx \&Ux Ta Yes Ta Yes Ta n
|
||||
.It Sx \&Va Ta Yes Ta Yes Ta n
|
||||
.It Sx \&Vt Ta Yes Ta Yes Ta >0
|
||||
.It Sx \&Xr Ta Yes Ta Yes Ta >0
|
||||
.It Sx \&Xr Ta Yes Ta Yes Ta 2
|
||||
.It Sx \&br Ta \&No Ta \&No Ta 0
|
||||
.It Sx \&sp Ta \&No Ta \&No Ta 1
|
||||
.El
|
||||
@ -3217,6 +3228,12 @@ but produces large indentations.
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr roff 7 ,
|
||||
.Xr tbl 7
|
||||
.Pp
|
||||
The web page
|
||||
.Lk http://mdocml.bsd.lv/mdoc/ "extended documentation for the mdoc language"
|
||||
provides a few tutorial-style pages for beginners, an extensive style
|
||||
guide for advanced authors, and an alphabetic index helping to choose
|
||||
the best macros for various kinds of content.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
71
mdoc.c
71
mdoc.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc.c,v 1.256 2015/10/30 19:04:16 schwarze Exp $ */
|
||||
/* $Id: mdoc.c,v 1.258 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* 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
|
||||
@ -140,8 +140,8 @@ mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok,
|
||||
{
|
||||
struct roff_node *p;
|
||||
|
||||
body->flags |= MDOC_ENDED;
|
||||
body->parent->flags |= MDOC_ENDED;
|
||||
body->flags |= NODE_ENDED;
|
||||
body->parent->flags |= NODE_ENDED;
|
||||
p = roff_node_alloc(mdoc, line, pos, ROFFT_BODY, tok);
|
||||
p->body = body;
|
||||
p->norm = body->norm;
|
||||
@ -219,29 +219,19 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
struct roff_node *n;
|
||||
char *c, *ws, *end;
|
||||
|
||||
assert(mdoc->last);
|
||||
n = mdoc->last;
|
||||
|
||||
/*
|
||||
* Divert directly to list processing if we're encountering a
|
||||
* 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 a column list contains plain text, assume an implicit item
|
||||
* macro. This can happen one or more times at the beginning
|
||||
* of such a list, intermixed with non-It mdoc macros and with
|
||||
* nodes generated on the roff level, for example by tbl.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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. */
|
||||
if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
|
||||
n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
|
||||
(n->parent != NULL && n->parent->tok == MDOC_Bl &&
|
||||
n->parent->norm->Bl.type == LIST_column)) {
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
|
||||
return 1;
|
||||
@ -302,7 +292,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
* behaviour that we want to work around it.
|
||||
*/
|
||||
roff_elem_alloc(mdoc, line, offs, MDOC_sp);
|
||||
mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
|
||||
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
return 1;
|
||||
}
|
||||
@ -321,7 +311,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
assert(buf < end);
|
||||
|
||||
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
|
||||
mdoc->last->flags |= MDOC_EOS;
|
||||
mdoc->last->flags |= NODE_EOS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -393,36 +383,23 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
* into macro processing.
|
||||
*/
|
||||
|
||||
if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
|
||||
n = mdoc->last;
|
||||
if (n == NULL || tok == MDOC_It || tok == MDOC_El) {
|
||||
mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = mdoc->last;
|
||||
assert(mdoc->last);
|
||||
|
||||
/*
|
||||
* If the first macro of a `Bl -column', open an `It' block
|
||||
* context around the parsed macro.
|
||||
* If a column list contains a non-It macro, assume an implicit
|
||||
* item macro. This can happen one or more times at the
|
||||
* beginning of such a list, intermixed with text lines and
|
||||
* with nodes generated on the roff level, for example by tbl.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're following a block-level `It' within a `Bl -column'
|
||||
* context (perhaps opened in the above block or in ptext()),
|
||||
* then open an `It' block context around the parsed macro.
|
||||
*/
|
||||
|
||||
if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
|
||||
NULL != n->parent &&
|
||||
MDOC_Bl == n->parent->tok &&
|
||||
LIST_column == n->parent->norm->Bl.type) {
|
||||
if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
|
||||
n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
|
||||
(n->parent != NULL && n->parent->tok == MDOC_Bl &&
|
||||
n->parent->norm->Bl.type == LIST_column)) {
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
|
||||
return 1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_argv.c,v 1.107 2015/10/17 00:21:07 schwarze Exp $ */
|
||||
/* $Id: mdoc_argv.c,v 1.109 2016/08/28 16:15:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -29,6 +29,7 @@
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define MULTI_STEP 5 /* pre-allocate argument values */
|
||||
@ -479,7 +480,7 @@ args(struct roff_man *mdoc, int line, int *pos,
|
||||
* unless there is a blank in between.
|
||||
*/
|
||||
|
||||
if (p[-1] != ' ')
|
||||
if (p > buf && p[-1] != ' ')
|
||||
mdoc->flags |= MDOC_PHRASEQL;
|
||||
if (p[1] != ' ')
|
||||
mdoc->flags |= MDOC_PHRASEQN;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: mdoc_hash.c,v 1.27 2016/07/15 18:03:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -26,8 +26,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
static unsigned char table[27 * 12];
|
||||
|
1089
mdoc_html.c
1089
mdoc_html.c
File diff suppressed because it is too large
Load Diff
99
mdoc_macro.c
99
mdoc_macro.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_macro.c,v 1.206 2015/10/20 02:01:32 schwarze Exp $ */
|
||||
/* $Id: mdoc_macro.c,v 1.210 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 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
|
||||
@ -216,7 +216,7 @@ mdoc_endparse(struct roff_man *mdoc)
|
||||
|
||||
/* Scan for open explicit scopes. */
|
||||
|
||||
n = mdoc->last->flags & MDOC_VALID ?
|
||||
n = mdoc->last->flags & NODE_VALID ?
|
||||
mdoc->last->parent : mdoc->last;
|
||||
|
||||
for ( ; n; n = n->parent)
|
||||
@ -264,16 +264,16 @@ static void
|
||||
rew_last(struct roff_man *mdoc, const struct roff_node *to)
|
||||
{
|
||||
|
||||
if (to->flags & MDOC_VALID)
|
||||
if (to->flags & NODE_VALID)
|
||||
return;
|
||||
|
||||
while (mdoc->last != to) {
|
||||
mdoc_state(mdoc, mdoc->last);
|
||||
mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
|
||||
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
|
||||
mdoc->last = mdoc->last->parent;
|
||||
}
|
||||
mdoc_state(mdoc, mdoc->last);
|
||||
mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
|
||||
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
|
||||
@ -292,13 +292,13 @@ rew_pending(struct roff_man *mdoc, const struct roff_node *n)
|
||||
case ROFFT_HEAD:
|
||||
roff_body_alloc(mdoc, n->line, n->pos,
|
||||
n->tok);
|
||||
return;
|
||||
break;
|
||||
case ROFFT_BLOCK:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if ( ! (n->flags & MDOC_BROKEN))
|
||||
if ( ! (n->flags & NODE_BROKEN))
|
||||
return;
|
||||
} else
|
||||
n = mdoc->last;
|
||||
@ -309,7 +309,7 @@ rew_pending(struct roff_man *mdoc, const struct roff_node *n)
|
||||
|
||||
if (n->type == ROFFT_BLOCK ||
|
||||
n->type == ROFFT_HEAD) {
|
||||
if (n->flags & MDOC_ENDED)
|
||||
if (n->flags & NODE_ENDED)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
@ -390,18 +390,18 @@ find_pending(struct roff_man *mdoc, int tok, int line, int ppos,
|
||||
|
||||
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;
|
||||
if (n->flags & NODE_ENDED) {
|
||||
if ( ! (n->flags & NODE_VALID))
|
||||
n->flags |= NODE_BROKEN;
|
||||
continue;
|
||||
}
|
||||
if (n->type == ROFFT_BLOCK &&
|
||||
mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
|
||||
irc = 1;
|
||||
n->flags = MDOC_BROKEN;
|
||||
n->flags = NODE_BROKEN;
|
||||
if (target->type == ROFFT_HEAD)
|
||||
target->flags = MDOC_ENDED;
|
||||
else if ( ! (target->flags & MDOC_ENDED)) {
|
||||
target->flags = NODE_ENDED;
|
||||
else if ( ! (target->flags & NODE_ENDED)) {
|
||||
mandoc_vmsg(MANDOCERR_BLK_NEST,
|
||||
mdoc->parse, line, ppos,
|
||||
"%s breaks %s", mdoc_macronames[tok],
|
||||
@ -444,11 +444,11 @@ dword(struct roff_man *mdoc, int line, int col, const char *p,
|
||||
*/
|
||||
|
||||
if (d == DELIM_OPEN)
|
||||
mdoc->last->flags |= MDOC_DELIMO;
|
||||
mdoc->last->flags |= NODE_DELIMO;
|
||||
else if (d == DELIM_CLOSE &&
|
||||
! (mdoc->flags & MDOC_NODELIMC) &&
|
||||
mdoc->last->parent->tok != MDOC_Fd)
|
||||
mdoc->last->flags |= MDOC_DELIMC;
|
||||
mdoc->last->flags |= NODE_DELIMC;
|
||||
mdoc->flags &= ~MDOC_NODELIMC;
|
||||
}
|
||||
|
||||
@ -481,7 +481,7 @@ append_delims(struct roff_man *mdoc, int line, int *pos, char *buf)
|
||||
*/
|
||||
|
||||
if (mandoc_eos(p, strlen(p)))
|
||||
mdoc->last->flags |= MDOC_EOS;
|
||||
mdoc->last->flags |= NODE_EOS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,29 +549,40 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Search backwards for the beginning of our own body. */
|
||||
|
||||
atok = rew_alt(tok);
|
||||
body = NULL;
|
||||
for (n = mdoc->last; n; n = n->parent) {
|
||||
if (n->flags & NODE_ENDED || n->tok != atok ||
|
||||
n->type != ROFFT_BODY || n->end != ENDBODY_NOT)
|
||||
continue;
|
||||
body = n;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search backwards for beginnings of blocks,
|
||||
* both of our own and of pending sub-blocks.
|
||||
*/
|
||||
|
||||
atok = rew_alt(tok);
|
||||
body = endbody = itblk = later = NULL;
|
||||
endbody = itblk = later = NULL;
|
||||
for (n = mdoc->last; n; n = n->parent) {
|
||||
if (n->flags & MDOC_ENDED) {
|
||||
if ( ! (n->flags & MDOC_VALID))
|
||||
n->flags |= MDOC_BROKEN;
|
||||
if (n->flags & NODE_ENDED) {
|
||||
if ( ! (n->flags & NODE_VALID))
|
||||
n->flags |= NODE_BROKEN;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Remember the start of our own body. */
|
||||
/*
|
||||
* Mismatching end macros can never break anything,
|
||||
* SYNOPSIS name blocks can never be broken,
|
||||
* and we only care about the breaking of BLOCKs.
|
||||
*/
|
||||
|
||||
if (n->type == ROFFT_BODY && atok == n->tok) {
|
||||
if (n->end == ENDBODY_NOT)
|
||||
body = n;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n->type != ROFFT_BLOCK || n->tok == MDOC_Nm)
|
||||
if (body == NULL ||
|
||||
n->tok == MDOC_Nm ||
|
||||
n->type != ROFFT_BLOCK)
|
||||
continue;
|
||||
|
||||
if (n->tok == MDOC_It) {
|
||||
@ -609,7 +620,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
atok, body, ENDBODY_SPACE);
|
||||
|
||||
if (tok == MDOC_El)
|
||||
itblk->flags |= MDOC_ENDED | MDOC_BROKEN;
|
||||
itblk->flags |= NODE_ENDED | NODE_BROKEN;
|
||||
|
||||
/*
|
||||
* If a block closing macro taking arguments
|
||||
@ -631,7 +642,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
|
||||
/* Breaking an open sub block. */
|
||||
|
||||
n->flags |= MDOC_BROKEN;
|
||||
n->flags |= NODE_BROKEN;
|
||||
if (later == NULL)
|
||||
later = n;
|
||||
}
|
||||
@ -639,8 +650,6 @@ 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:
|
||||
@ -697,11 +706,11 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
}
|
||||
|
||||
if (n != NULL) {
|
||||
if (ntok != TOKEN_NONE && n->flags & MDOC_BROKEN) {
|
||||
if (ntok != TOKEN_NONE && n->flags & NODE_BROKEN) {
|
||||
target = n;
|
||||
do
|
||||
target = target->parent;
|
||||
while ( ! (target->flags & MDOC_ENDED));
|
||||
while ( ! (target->flags & NODE_ENDED));
|
||||
pending = find_pending(mdoc, ntok, line, ppos,
|
||||
target);
|
||||
} else
|
||||
@ -760,7 +769,7 @@ in_line(MACRO_PROT_ARGS)
|
||||
|
||||
if (ac == ARGS_EOLN) {
|
||||
if (d == DELIM_OPEN)
|
||||
mdoc->last->flags &= ~MDOC_DELIMO;
|
||||
mdoc->last->flags &= ~NODE_DELIMO;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -854,7 +863,7 @@ in_line(MACRO_PROT_ARGS)
|
||||
*/
|
||||
|
||||
if (firstarg && d == DELIM_CLOSE && !nc)
|
||||
mdoc->last->flags &= ~MDOC_DELIMC;
|
||||
mdoc->last->flags &= ~NODE_DELIMC;
|
||||
firstarg = 0;
|
||||
|
||||
/*
|
||||
@ -917,9 +926,9 @@ blk_full(MACRO_PROT_ARGS)
|
||||
|
||||
blk = NULL;
|
||||
for (n = mdoc->last; n != NULL; n = n->parent) {
|
||||
if (n->flags & MDOC_ENDED) {
|
||||
if ( ! (n->flags & MDOC_VALID))
|
||||
n->flags |= MDOC_BROKEN;
|
||||
if (n->flags & NODE_ENDED) {
|
||||
if ( ! (n->flags & NODE_VALID))
|
||||
n->flags |= NODE_BROKEN;
|
||||
continue;
|
||||
}
|
||||
if (n->type != ROFFT_BLOCK)
|
||||
@ -1120,7 +1129,7 @@ blk_full(MACRO_PROT_ARGS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (blk->flags & MDOC_VALID)
|
||||
if (blk->flags & NODE_VALID)
|
||||
return;
|
||||
if (head == NULL)
|
||||
head = roff_head_alloc(mdoc, line, ppos, tok);
|
||||
@ -1455,11 +1464,11 @@ phrase_ta(MACRO_PROT_ARGS)
|
||||
|
||||
body = NULL;
|
||||
for (n = mdoc->last; n != NULL; n = n->parent) {
|
||||
if (n->flags & MDOC_ENDED)
|
||||
if (n->flags & NODE_ENDED)
|
||||
continue;
|
||||
if (n->tok == MDOC_It && n->type == ROFFT_BODY)
|
||||
body = n;
|
||||
if (n->tok == MDOC_Bl)
|
||||
if (n->tok == MDOC_Bl && n->end == ENDBODY_NOT)
|
||||
break;
|
||||
}
|
||||
|
||||
|
182
mdoc_man.c
182
mdoc_man.c
@ -1,6 +1,6 @@
|
||||
/* $Id: mdoc_man.c,v 1.96 2016/01/08 17:48:09 schwarze Exp $ */
|
||||
/* $Id: mdoc_man.c,v 1.101 2017/01/11 17:39:53 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -79,7 +79,6 @@ static int pre_bf(DECL_ARGS);
|
||||
static int pre_bk(DECL_ARGS);
|
||||
static int pre_bl(DECL_ARGS);
|
||||
static int pre_br(DECL_ARGS);
|
||||
static int pre_bx(DECL_ARGS);
|
||||
static int pre_dl(DECL_ARGS);
|
||||
static int pre_en(DECL_ARGS);
|
||||
static int pre_enc(DECL_ARGS);
|
||||
@ -103,14 +102,12 @@ static int pre_no(DECL_ARGS);
|
||||
static int pre_ns(DECL_ARGS);
|
||||
static int pre_pp(DECL_ARGS);
|
||||
static int pre_rs(DECL_ARGS);
|
||||
static int pre_rv(DECL_ARGS);
|
||||
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 roff_node *);
|
||||
static int pre_vt(DECL_ARGS);
|
||||
static int pre_ux(DECL_ARGS);
|
||||
static int pre_xr(DECL_ARGS);
|
||||
static void print_word(const char *);
|
||||
static void print_line(const char *, int);
|
||||
@ -158,7 +155,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
|
||||
{ NULL, pre_ft, post_font, NULL, NULL }, /* Ot */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Pa */
|
||||
{ NULL, pre_rv, NULL, NULL, NULL }, /* Rv */
|
||||
{ NULL, pre_ex, NULL, NULL, NULL }, /* Rv */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* St */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Va */
|
||||
{ NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
|
||||
@ -182,8 +179,8 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
|
||||
{ NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
|
||||
{ NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bsx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bx */
|
||||
{ NULL, pre_skip, NULL, NULL, NULL }, /* Db */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
|
||||
{ cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */
|
||||
@ -192,12 +189,12 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
|
||||
{ cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
|
||||
{ NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Fx */
|
||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
|
||||
{ NULL, pre_no, NULL, NULL, NULL }, /* No */
|
||||
{ NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
|
||||
{ NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
|
||||
{ NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Nx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ox */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Pc */
|
||||
{ NULL, NULL, post_pf, NULL, NULL }, /* Pf */
|
||||
{ cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
|
||||
@ -215,7 +212,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Sx */
|
||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Sy */
|
||||
{ NULL, pre_li, post_font, NULL, NULL }, /* Tn */
|
||||
{ NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ux */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Xc */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Xo */
|
||||
{ NULL, pre_fo, post_fo, NULL, NULL }, /* Fo */
|
||||
@ -224,10 +221,10 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Oc */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ek */
|
||||
{ NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bt */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Hf */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Fr */
|
||||
{ NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ud */
|
||||
{ NULL, NULL, post_lb, NULL, NULL }, /* Lb */
|
||||
{ NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
|
||||
{ NULL, pre_lk, NULL, NULL, NULL }, /* Lk */
|
||||
@ -238,7 +235,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %C */
|
||||
{ NULL, pre_skip, NULL, NULL, NULL }, /* Es */
|
||||
{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
|
||||
{ NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dx */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
|
||||
{ NULL, pre_br, NULL, NULL, NULL }, /* br */
|
||||
{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
|
||||
@ -575,17 +572,20 @@ print_node(DECL_ARGS)
|
||||
struct roff_node *sub;
|
||||
int cond, do_sub;
|
||||
|
||||
if (n->flags & NODE_NOPRT)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Break the line if we were parsed subsequent the current node.
|
||||
* This makes the page structure be more consistent.
|
||||
*/
|
||||
if (MMAN_spc & outflags && MDOC_LINE & n->flags)
|
||||
if (MMAN_spc & outflags && NODE_LINE & n->flags)
|
||||
outflags |= MMAN_nl;
|
||||
|
||||
act = NULL;
|
||||
cond = 0;
|
||||
do_sub = 1;
|
||||
n->flags &= ~MDOC_ENDED;
|
||||
n->flags &= ~NODE_ENDED;
|
||||
|
||||
if (n->type == ROFFT_TEXT) {
|
||||
/*
|
||||
@ -598,10 +598,14 @@ print_node(DECL_ARGS)
|
||||
printf("\\&");
|
||||
outflags &= ~MMAN_spc;
|
||||
}
|
||||
if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMC))
|
||||
if (n->flags & NODE_DELIMC)
|
||||
outflags &= ~(MMAN_spc | MMAN_spc_force);
|
||||
else if (outflags & MMAN_Sm)
|
||||
outflags |= MMAN_spc_force;
|
||||
print_word(n->string);
|
||||
if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMO))
|
||||
if (n->flags & NODE_DELIMO)
|
||||
outflags &= ~(MMAN_spc | MMAN_spc_force);
|
||||
else if (outflags & MMAN_Sm)
|
||||
outflags |= MMAN_spc;
|
||||
} else {
|
||||
/*
|
||||
@ -627,14 +631,14 @@ print_node(DECL_ARGS)
|
||||
/*
|
||||
* Lastly, conditionally run the post-node handler.
|
||||
*/
|
||||
if (MDOC_ENDED & n->flags)
|
||||
if (NODE_ENDED & n->flags)
|
||||
return;
|
||||
|
||||
if (cond && act->post)
|
||||
(*act->post)(meta, n);
|
||||
|
||||
if (ENDBODY_NOT != n->end)
|
||||
n->body->flags |= MDOC_ENDED;
|
||||
n->body->flags |= NODE_ENDED;
|
||||
|
||||
if (ENDBODY_NOSPACE == n->end)
|
||||
outflags &= ~(MMAN_spc | MMAN_nl);
|
||||
@ -682,36 +686,8 @@ post_enc(DECL_ARGS)
|
||||
static int
|
||||
pre_ex(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
|
||||
outflags |= MMAN_br | MMAN_nl;
|
||||
|
||||
print_word("The");
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next) {
|
||||
font_push('B');
|
||||
print_word(nch->string);
|
||||
font_pop();
|
||||
|
||||
if (nch->next == NULL)
|
||||
continue;
|
||||
|
||||
if (nch->prev != NULL || nch->next->next != NULL) {
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word(",");
|
||||
}
|
||||
if (nch->next->next == NULL)
|
||||
print_word("and");
|
||||
}
|
||||
|
||||
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 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -805,7 +781,7 @@ static void
|
||||
pre_syn(const struct roff_node *n)
|
||||
{
|
||||
|
||||
if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
|
||||
if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
|
||||
return;
|
||||
|
||||
if (n->prev->tok == n->tok &&
|
||||
@ -1050,26 +1026,6 @@ pre_br(DECL_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_bx(DECL_ARGS)
|
||||
{
|
||||
|
||||
n = n->child;
|
||||
if (n) {
|
||||
print_word(n->string);
|
||||
outflags &= ~MMAN_spc;
|
||||
n = n->next;
|
||||
}
|
||||
print_word("BSD");
|
||||
if (NULL == n)
|
||||
return 0;
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word("-");
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word(n->string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_dl(DECL_ARGS)
|
||||
{
|
||||
@ -1173,7 +1129,7 @@ pre_fa(DECL_ARGS)
|
||||
|
||||
while (NULL != n) {
|
||||
font_push('I');
|
||||
if (am_Fa || MDOC_SYNPRETTY & n->flags)
|
||||
if (am_Fa || NODE_SYNPRETTY & n->flags)
|
||||
outflags |= MMAN_nbrword;
|
||||
print_node(meta, n);
|
||||
font_pop();
|
||||
@ -1227,7 +1183,7 @@ post_fl(DECL_ARGS)
|
||||
if (!(n->child != NULL ||
|
||||
n->next == NULL ||
|
||||
n->next->type == ROFFT_TEXT ||
|
||||
n->next->flags & MDOC_LINE))
|
||||
n->next->flags & NODE_LINE))
|
||||
outflags &= ~MMAN_spc;
|
||||
}
|
||||
|
||||
@ -1241,7 +1197,7 @@ pre_fn(DECL_ARGS)
|
||||
if (NULL == n)
|
||||
return 0;
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
print_block(".HP 4n", MMAN_nl);
|
||||
|
||||
font_push('B');
|
||||
@ -1262,7 +1218,7 @@ post_fn(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_word(")");
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
if (NODE_SYNPRETTY & n->flags) {
|
||||
print_word(";");
|
||||
outflags |= MMAN_PP;
|
||||
}
|
||||
@ -1279,7 +1235,7 @@ pre_fo(DECL_ARGS)
|
||||
case ROFFT_HEAD:
|
||||
if (n->child == NULL)
|
||||
return 0;
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
print_block(".HP 4n", MMAN_nl);
|
||||
font_push('B');
|
||||
break;
|
||||
@ -1324,7 +1280,7 @@ static int
|
||||
pre_in(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
if (NODE_SYNPRETTY & n->flags) {
|
||||
pre_syn(n);
|
||||
font_push('B');
|
||||
print_word("#include <");
|
||||
@ -1341,7 +1297,7 @@ static void
|
||||
post_in(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
if (NODE_SYNPRETTY & n->flags) {
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word(">");
|
||||
font_pop();
|
||||
@ -1616,7 +1572,7 @@ static void
|
||||
post_pf(DECL_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
|
||||
if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
|
||||
outflags &= ~MMAN_spc;
|
||||
}
|
||||
|
||||
@ -1642,57 +1598,6 @@ pre_rs(DECL_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_rv(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
|
||||
outflags |= MMAN_br | MMAN_nl;
|
||||
|
||||
if (n->child != NULL) {
|
||||
print_word("The");
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next) {
|
||||
font_push('B');
|
||||
print_word(nch->string);
|
||||
font_pop();
|
||||
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word("()");
|
||||
|
||||
if (nch->next == NULL)
|
||||
continue;
|
||||
|
||||
if (nch->prev != NULL || nch->next->next != NULL) {
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word(",");
|
||||
}
|
||||
if (nch->next->next == NULL)
|
||||
print_word("and");
|
||||
}
|
||||
|
||||
if (n->child != NULL && n->child->next != NULL)
|
||||
print_word("functions return");
|
||||
else
|
||||
print_word("function returns");
|
||||
|
||||
print_word("the value\\~0 if successful;");
|
||||
} else
|
||||
print_word("Upon successful completion, "
|
||||
"the value\\~0 is returned;");
|
||||
|
||||
print_word("otherwise the value\\~\\-1 is returned"
|
||||
" and the global variable");
|
||||
|
||||
font_push('I');
|
||||
print_word("errno");
|
||||
font_pop();
|
||||
|
||||
print_word("is set to indicate the error.");
|
||||
outflags |= MMAN_nl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_skip(DECL_ARGS)
|
||||
{
|
||||
@ -1748,7 +1653,7 @@ static int
|
||||
pre_vt(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
if (NODE_SYNPRETTY & n->flags) {
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
pre_syn(n);
|
||||
@ -1767,7 +1672,7 @@ static void
|
||||
post_vt(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->flags & MDOC_SYNPRETTY && n->type != ROFFT_BODY)
|
||||
if (n->flags & NODE_SYNPRETTY && n->type != ROFFT_BODY)
|
||||
return;
|
||||
font_pop();
|
||||
}
|
||||
@ -1789,16 +1694,3 @@ pre_xr(DECL_ARGS)
|
||||
print_word(")");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ux(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_word(manacts[n->tok].prefix);
|
||||
if (NULL == n->child)
|
||||
return 0;
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word("\\ ");
|
||||
outflags &= ~MMAN_spc;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_state.c,v 1.3 2015/10/30 18:53:54 schwarze Exp $ */
|
||||
/* $Id: mdoc_state.c,v 1.4 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -249,7 +249,7 @@ state_sh(STATE_ARGS)
|
||||
if (n->type != ROFFT_HEAD)
|
||||
return;
|
||||
|
||||
if ( ! (n->flags & MDOC_VALID)) {
|
||||
if ( ! (n->flags & NODE_VALID)) {
|
||||
secname = NULL;
|
||||
deroff(&secname, n);
|
||||
|
||||
|
290
mdoc_term.c
290
mdoc_term.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_term.c,v 1.331 2016/01/08 17:48:09 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.341 2017/01/11 17:39:53 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -80,6 +80,7 @@ static void termp_pf_post(DECL_ARGS);
|
||||
static void termp_quote_post(DECL_ARGS);
|
||||
static void termp_sh_post(DECL_ARGS);
|
||||
static void termp_ss_post(DECL_ARGS);
|
||||
static void termp_xx_post(DECL_ARGS);
|
||||
|
||||
static int termp__a_pre(DECL_ARGS);
|
||||
static int termp__t_pre(DECL_ARGS);
|
||||
@ -90,11 +91,10 @@ static int termp_bf_pre(DECL_ARGS);
|
||||
static int termp_bk_pre(DECL_ARGS);
|
||||
static int termp_bl_pre(DECL_ARGS);
|
||||
static int termp_bold_pre(DECL_ARGS);
|
||||
static int termp_bt_pre(DECL_ARGS);
|
||||
static int termp_bx_pre(DECL_ARGS);
|
||||
static int termp_cd_pre(DECL_ARGS);
|
||||
static int termp_d1_pre(DECL_ARGS);
|
||||
static int termp_eo_pre(DECL_ARGS);
|
||||
static int termp_em_pre(DECL_ARGS);
|
||||
static int termp_er_pre(DECL_ARGS);
|
||||
static int termp_ex_pre(DECL_ARGS);
|
||||
static int termp_fa_pre(DECL_ARGS);
|
||||
@ -113,15 +113,14 @@ static int termp_nm_pre(DECL_ARGS);
|
||||
static int termp_ns_pre(DECL_ARGS);
|
||||
static int termp_quote_pre(DECL_ARGS);
|
||||
static int termp_rs_pre(DECL_ARGS);
|
||||
static int termp_rv_pre(DECL_ARGS);
|
||||
static int termp_sh_pre(DECL_ARGS);
|
||||
static int termp_skip_pre(DECL_ARGS);
|
||||
static int termp_sm_pre(DECL_ARGS);
|
||||
static int termp_sp_pre(DECL_ARGS);
|
||||
static int termp_ss_pre(DECL_ARGS);
|
||||
static int termp_sy_pre(DECL_ARGS);
|
||||
static int termp_tag_pre(DECL_ARGS);
|
||||
static int termp_under_pre(DECL_ARGS);
|
||||
static int termp_ud_pre(DECL_ARGS);
|
||||
static int termp_vt_pre(DECL_ARGS);
|
||||
static int termp_xr_pre(DECL_ARGS);
|
||||
static int termp_xx_pre(DECL_ARGS);
|
||||
@ -163,7 +162,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_quote_pre, termp_quote_post }, /* Op */
|
||||
{ termp_ft_pre, NULL }, /* Ot */
|
||||
{ termp_under_pre, NULL }, /* Pa */
|
||||
{ termp_rv_pre, NULL }, /* Rv */
|
||||
{ termp_ex_pre, NULL }, /* Rv */
|
||||
{ NULL, NULL }, /* St */
|
||||
{ termp_under_pre, NULL }, /* Va */
|
||||
{ termp_vt_pre, NULL }, /* Vt */
|
||||
@ -187,22 +186,22 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_bf_pre, NULL }, /* Bf */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Bo */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Bq */
|
||||
{ termp_xx_pre, NULL }, /* Bsx */
|
||||
{ termp_bx_pre, NULL }, /* Bx */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Bsx */
|
||||
{ NULL, NULL }, /* Bx */
|
||||
{ termp_skip_pre, NULL }, /* Db */
|
||||
{ NULL, NULL }, /* Dc */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Do */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Dq */
|
||||
{ NULL, NULL }, /* Ec */ /* FIXME: no space */
|
||||
{ NULL, NULL }, /* Ef */
|
||||
{ termp_under_pre, NULL }, /* Em */
|
||||
{ termp_em_pre, NULL }, /* Em */
|
||||
{ termp_eo_pre, termp_eo_post }, /* Eo */
|
||||
{ termp_xx_pre, NULL }, /* Fx */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Fx */
|
||||
{ termp_bold_pre, NULL }, /* Ms */
|
||||
{ termp_li_pre, NULL }, /* No */
|
||||
{ termp_ns_pre, NULL }, /* Ns */
|
||||
{ termp_xx_pre, NULL }, /* Nx */
|
||||
{ termp_xx_pre, NULL }, /* Ox */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Nx */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Ox */
|
||||
{ NULL, NULL }, /* Pc */
|
||||
{ NULL, termp_pf_post }, /* Pf */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Po */
|
||||
@ -218,9 +217,9 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_quote_pre, termp_quote_post }, /* Sq */
|
||||
{ termp_sm_pre, NULL }, /* Sm */
|
||||
{ termp_under_pre, NULL }, /* Sx */
|
||||
{ termp_bold_pre, NULL }, /* Sy */
|
||||
{ termp_sy_pre, NULL }, /* Sy */
|
||||
{ NULL, NULL }, /* Tn */
|
||||
{ termp_xx_pre, NULL }, /* Ux */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Ux */
|
||||
{ NULL, NULL }, /* Xc */
|
||||
{ NULL, NULL }, /* Xo */
|
||||
{ termp_fo_pre, termp_fo_post }, /* Fo */
|
||||
@ -229,10 +228,10 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* Oc */
|
||||
{ termp_bk_pre, termp_bk_post }, /* Bk */
|
||||
{ NULL, NULL }, /* Ek */
|
||||
{ termp_bt_pre, NULL }, /* Bt */
|
||||
{ NULL, NULL }, /* Bt */
|
||||
{ NULL, NULL }, /* Hf */
|
||||
{ termp_under_pre, NULL }, /* Fr */
|
||||
{ termp_ud_pre, NULL }, /* Ud */
|
||||
{ NULL, NULL }, /* Ud */
|
||||
{ NULL, termp_lb_post }, /* Lb */
|
||||
{ termp_sp_pre, NULL }, /* Lp */
|
||||
{ termp_lk_pre, NULL }, /* Lk */
|
||||
@ -243,7 +242,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ NULL, termp____post }, /* %C */
|
||||
{ termp_skip_pre, NULL }, /* Es */
|
||||
{ termp_quote_pre, termp_quote_post }, /* En */
|
||||
{ termp_xx_pre, NULL }, /* Dx */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Dx */
|
||||
{ NULL, termp____post }, /* %Q */
|
||||
{ termp_sp_pre, NULL }, /* br */
|
||||
{ termp_sp_pre, NULL }, /* sp */
|
||||
@ -283,6 +282,8 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc)
|
||||
p->defindent = 5;
|
||||
term_begin(p, print_mdoc_head, print_mdoc_foot,
|
||||
&mdoc->meta);
|
||||
while (n != NULL && n->flags & NODE_NOPRT)
|
||||
n = n->next;
|
||||
if (n != NULL) {
|
||||
if (n->tok != MDOC_Sh)
|
||||
term_vspace(p);
|
||||
@ -309,10 +310,13 @@ print_mdoc_node(DECL_ARGS)
|
||||
struct termpair npair;
|
||||
size_t offset, rmargin;
|
||||
|
||||
if (n->flags & NODE_NOPRT)
|
||||
return;
|
||||
|
||||
chld = 1;
|
||||
offset = p->offset;
|
||||
rmargin = p->rmargin;
|
||||
n->flags &= ~MDOC_ENDED;
|
||||
n->flags &= ~NODE_ENDED;
|
||||
n->prev_font = p->fonti;
|
||||
|
||||
memset(&npair, 0, sizeof(struct termpair));
|
||||
@ -323,7 +327,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
* invoked in a prior line, revert it to PREKEEP.
|
||||
*/
|
||||
|
||||
if (p->flags & TERMP_KEEP && n->flags & MDOC_LINE) {
|
||||
if (p->flags & TERMP_KEEP && n->flags & NODE_LINE) {
|
||||
p->flags &= ~TERMP_KEEP;
|
||||
p->flags |= TERMP_PREKEEP;
|
||||
}
|
||||
@ -335,19 +339,19 @@ print_mdoc_node(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
if (' ' == *n->string && MDOC_LINE & n->flags)
|
||||
if (' ' == *n->string && NODE_LINE & n->flags)
|
||||
term_newln(p);
|
||||
if (MDOC_DELIMC & n->flags)
|
||||
if (NODE_DELIMC & n->flags)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, n->string);
|
||||
if (MDOC_DELIMO & n->flags)
|
||||
if (NODE_DELIMO & n->flags)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
if ( ! (n->flags & MDOC_LINE))
|
||||
if ( ! (n->flags & NODE_LINE))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_eqn(p, n->eqn);
|
||||
if (n->next != NULL && ! (n->next->flags & MDOC_LINE))
|
||||
if (n->next != NULL && ! (n->next->flags & NODE_LINE))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case ROFFT_TBL:
|
||||
@ -377,7 +381,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
case ROFFT_EQN:
|
||||
break;
|
||||
default:
|
||||
if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
|
||||
if ( ! termacts[n->tok].post || NODE_ENDED & n->flags)
|
||||
break;
|
||||
(void)(*termacts[n->tok].post)(p, &npair, meta, n);
|
||||
|
||||
@ -387,7 +391,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
* that it must not call the post handler again.
|
||||
*/
|
||||
if (ENDBODY_NOT != n->end)
|
||||
n->body->flags |= MDOC_ENDED;
|
||||
n->body->flags |= NODE_ENDED;
|
||||
|
||||
/*
|
||||
* End of line terminating an implicit block
|
||||
@ -399,7 +403,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (MDOC_EOS & n->flags)
|
||||
if (NODE_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
||||
if (MDOC_ll != n->tok) {
|
||||
@ -562,6 +566,8 @@ print_bvspace(struct termp *p,
|
||||
/* Do not vspace directly after Ss/Sh. */
|
||||
|
||||
nn = n;
|
||||
while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT)
|
||||
nn = nn->prev;
|
||||
while (nn->prev == NULL) {
|
||||
do {
|
||||
nn = nn->parent;
|
||||
@ -631,10 +637,10 @@ termp_it_pre(DECL_ARGS)
|
||||
width = term_len(p, 2);
|
||||
break;
|
||||
case LIST_hang:
|
||||
case LIST_tag:
|
||||
width = term_len(p, 8);
|
||||
break;
|
||||
case LIST_column:
|
||||
case LIST_tag:
|
||||
width = term_len(p, 10);
|
||||
break;
|
||||
default:
|
||||
@ -1042,7 +1048,7 @@ termp_fl_pre(DECL_ARGS)
|
||||
if (!(n->child == NULL &&
|
||||
(n->next == NULL ||
|
||||
n->next->type == ROFFT_TEXT ||
|
||||
n->next->flags & MDOC_LINE)))
|
||||
n->next->flags & NODE_LINE)))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
return 1;
|
||||
@ -1087,7 +1093,7 @@ static int
|
||||
termp_ns_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (MDOC_LINE & n->flags))
|
||||
if ( ! (NODE_LINE & n->flags))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
return 1;
|
||||
}
|
||||
@ -1103,92 +1109,11 @@ termp_rs_pre(DECL_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_rv_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (n->child != NULL) {
|
||||
term_word(p, "The");
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next) {
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, nch->string);
|
||||
term_fontpop(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "()");
|
||||
|
||||
if (nch->next == NULL)
|
||||
continue;
|
||||
|
||||
if (nch->prev != NULL || nch->next->next != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
if (nch->next->next == NULL)
|
||||
term_word(p, "and");
|
||||
}
|
||||
|
||||
if (n->child != NULL && n->child->next != NULL)
|
||||
term_word(p, "functions return");
|
||||
else
|
||||
term_word(p, "function returns");
|
||||
|
||||
term_word(p, "the value\\~0 if successful;");
|
||||
} else
|
||||
term_word(p, "Upon successful completion,"
|
||||
" the value\\~0 is returned;");
|
||||
|
||||
term_word(p, "otherwise the value\\~\\-1 is returned"
|
||||
" and the global variable");
|
||||
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
term_word(p, "errno");
|
||||
term_fontpop(p);
|
||||
|
||||
term_word(p, "is set to indicate the error.");
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_ex_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
|
||||
term_newln(p);
|
||||
term_word(p, "The");
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next) {
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, nch->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (nch->next == NULL)
|
||||
continue;
|
||||
|
||||
if (nch->prev != NULL || nch->next->next != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
|
||||
if (nch->next->next == NULL)
|
||||
term_word(p, "and");
|
||||
}
|
||||
|
||||
if (n->child != NULL && n->child->next != NULL)
|
||||
term_word(p, "utilities exit\\~0");
|
||||
else
|
||||
term_word(p, "utility exits\\~0");
|
||||
|
||||
term_word(p, "on success, and\\~>0 if an error occurs.");
|
||||
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1253,7 +1178,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n)
|
||||
* Obviously, if we're not in a SYNOPSIS or no prior macros
|
||||
* exist, do nothing.
|
||||
*/
|
||||
if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
|
||||
if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -1389,32 +1314,14 @@ termp_sh_post(DECL_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
termp_bt_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_word(p, "is currently in beta test.");
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
termp_lb_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags)
|
||||
if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags)
|
||||
term_newln(p);
|
||||
}
|
||||
|
||||
static int
|
||||
termp_ud_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_word(p, "currently under development.");
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_d1_pre(DECL_ARGS)
|
||||
{
|
||||
@ -1430,7 +1337,7 @@ static int
|
||||
termp_ft_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
/* NB: MDOC_LINE does not effect this! */
|
||||
/* NB: NODE_LINE does not effect this! */
|
||||
synopsis_pre(p, n);
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
@ -1442,7 +1349,7 @@ termp_fn_pre(DECL_ARGS)
|
||||
size_t rmargin = 0;
|
||||
int pretty;
|
||||
|
||||
pretty = MDOC_SYNPRETTY & n->flags;
|
||||
pretty = NODE_SYNPRETTY & n->flags;
|
||||
|
||||
synopsis_pre(p, n);
|
||||
|
||||
@ -1460,7 +1367,7 @@ termp_fn_pre(DECL_ARGS)
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (n->sec == SEC_DESCRIPTION)
|
||||
if (n->sec == SEC_DESCRIPTION || n->sec == SEC_CUSTOM)
|
||||
tag_put(n->string, ++fn_prio, p->line);
|
||||
|
||||
if (pretty) {
|
||||
@ -1608,7 +1515,7 @@ termp_bd_pre(DECL_ARGS)
|
||||
break;
|
||||
}
|
||||
if (p->flags & TERMP_NONEWLINE ||
|
||||
(nn->next && ! (nn->next->flags & MDOC_LINE)))
|
||||
(nn->next && ! (nn->next->flags & NODE_LINE)))
|
||||
continue;
|
||||
term_flushln(p);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -1642,85 +1549,41 @@ termp_bd_post(DECL_ARGS)
|
||||
p->maxrmargin = rmax;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_bx_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (NULL != (n = n->child)) {
|
||||
term_word(p, n->string);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "BSD");
|
||||
} else {
|
||||
term_word(p, "BSD");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NULL != (n = n->next)) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "-");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, n->string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_xx_pre(DECL_ARGS)
|
||||
{
|
||||
const char *pp;
|
||||
int flags;
|
||||
if ((n->aux = p->flags & TERMP_PREKEEP) == 0)
|
||||
p->flags |= TERMP_PREKEEP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
pp = NULL;
|
||||
switch (n->tok) {
|
||||
case MDOC_Bsx:
|
||||
pp = "BSD/OS";
|
||||
break;
|
||||
case MDOC_Dx:
|
||||
pp = "DragonFly";
|
||||
break;
|
||||
case MDOC_Fx:
|
||||
pp = "FreeBSD";
|
||||
break;
|
||||
case MDOC_Nx:
|
||||
pp = "NetBSD";
|
||||
break;
|
||||
case MDOC_Ox:
|
||||
pp = "OpenBSD";
|
||||
break;
|
||||
case MDOC_Ux:
|
||||
pp = "UNIX";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
term_word(p, pp);
|
||||
if (n->child) {
|
||||
flags = p->flags;
|
||||
p->flags |= TERMP_KEEP;
|
||||
term_word(p, n->child->string);
|
||||
p->flags = flags;
|
||||
}
|
||||
return 0;
|
||||
static void
|
||||
termp_xx_post(DECL_ARGS)
|
||||
{
|
||||
if (n->aux == 0)
|
||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||
}
|
||||
|
||||
static void
|
||||
termp_pf_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
|
||||
if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_ss_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
term_newln(p);
|
||||
if (n->prev)
|
||||
for (nn = n->prev; nn != NULL; nn = nn->prev)
|
||||
if ((nn->flags & NODE_NOPRT) == 0)
|
||||
break;
|
||||
if (nn != NULL)
|
||||
term_vspace(p);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
@ -1760,7 +1623,7 @@ termp_in_pre(DECL_ARGS)
|
||||
|
||||
synopsis_pre(p, n);
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags) {
|
||||
if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags) {
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, "#include");
|
||||
term_word(p, "<");
|
||||
@ -1777,13 +1640,13 @@ static void
|
||||
termp_in_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ">");
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
term_fontpop(p);
|
||||
}
|
||||
|
||||
@ -1990,7 +1853,7 @@ termp_fo_pre(DECL_ARGS)
|
||||
size_t rmargin = 0;
|
||||
int pretty;
|
||||
|
||||
pretty = MDOC_SYNPRETTY & n->flags;
|
||||
pretty = NODE_SYNPRETTY & n->flags;
|
||||
|
||||
if (n->type == ROFFT_BLOCK) {
|
||||
synopsis_pre(p, n);
|
||||
@ -2036,7 +1899,7 @@ termp_fo_post(DECL_ARGS)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ")");
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
if (NODE_SYNPRETTY & n->flags) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ";");
|
||||
term_flushln(p);
|
||||
@ -2120,6 +1983,7 @@ static int
|
||||
termp_li_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
termp_tag_pre(p, pair, meta, n);
|
||||
term_fontpush(p, TERMFONT_NONE);
|
||||
return 1;
|
||||
}
|
||||
@ -2217,6 +2081,26 @@ termp_under_pre(DECL_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_em_pre(DECL_ARGS)
|
||||
{
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT)
|
||||
tag_put(n->child->string, 0, p->line);
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_sy_pre(DECL_ARGS)
|
||||
{
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT)
|
||||
tag_put(n->child->string, 0, p->line);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_er_pre(DECL_ARGS)
|
||||
{
|
||||
@ -2235,7 +2119,9 @@ termp_tag_pre(DECL_ARGS)
|
||||
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT &&
|
||||
n->prev == NULL &&
|
||||
(n->prev == NULL ||
|
||||
(n->prev->type == ROFFT_TEXT &&
|
||||
strcmp(n->prev->string, "|") == 0)) &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Xo &&
|
||||
n->parent->parent->prev == NULL &&
|
||||
|
617
mdoc_validate.c
617
mdoc_validate.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_validate.c,v 1.301 2016/01/08 17:48:09 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.317 2017/01/11 17:39:53 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -51,6 +51,7 @@ enum check_ineq {
|
||||
|
||||
typedef void (*v_post)(POST_ARGS);
|
||||
|
||||
static int build_list(struct roff_man *, int);
|
||||
static void check_text(struct roff_man *, int, int, char *);
|
||||
static void check_argv(struct roff_man *,
|
||||
struct roff_node *, struct mdoc_argv *);
|
||||
@ -67,7 +68,6 @@ static void post_bf(POST_ARGS);
|
||||
static void post_bk(POST_ARGS);
|
||||
static void post_bl(POST_ARGS);
|
||||
static void post_bl_block(POST_ARGS);
|
||||
static void post_bl_block_tag(POST_ARGS);
|
||||
static void post_bl_head(POST_ARGS);
|
||||
static void post_bl_norm(POST_ARGS);
|
||||
static void post_bx(POST_ARGS);
|
||||
@ -96,6 +96,7 @@ static void post_par(POST_ARGS);
|
||||
static void post_prevpar(POST_ARGS);
|
||||
static void post_root(POST_ARGS);
|
||||
static void post_rs(POST_ARGS);
|
||||
static void post_rv(POST_ARGS);
|
||||
static void post_sh(POST_ARGS);
|
||||
static void post_sh_head(POST_ARGS);
|
||||
static void post_sh_name(POST_ARGS);
|
||||
@ -104,6 +105,8 @@ static void post_sh_authors(POST_ARGS);
|
||||
static void post_sm(POST_ARGS);
|
||||
static void post_st(POST_ARGS);
|
||||
static void post_std(POST_ARGS);
|
||||
static void post_xr(POST_ARGS);
|
||||
static void post_xx(POST_ARGS);
|
||||
|
||||
static v_post mdoc_valids[MDOC_MAX] = {
|
||||
NULL, /* Ap */
|
||||
@ -142,11 +145,11 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
NULL, /* Op */
|
||||
post_obsolete, /* Ot */
|
||||
post_defaults, /* Pa */
|
||||
post_std, /* Rv */
|
||||
post_rv, /* Rv */
|
||||
post_st, /* St */
|
||||
NULL, /* Va */
|
||||
NULL, /* Vt */
|
||||
NULL, /* Xr */
|
||||
post_xr, /* Xr */
|
||||
NULL, /* %A */
|
||||
post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */
|
||||
NULL, /* %D */
|
||||
@ -166,7 +169,7 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
post_bf, /* Bf */
|
||||
NULL, /* Bo */
|
||||
NULL, /* Bq */
|
||||
NULL, /* Bsx */
|
||||
post_xx, /* Bsx */
|
||||
post_bx, /* Bx */
|
||||
post_obsolete, /* Db */
|
||||
NULL, /* Dc */
|
||||
@ -176,12 +179,12 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
NULL, /* Ef */
|
||||
NULL, /* Em */
|
||||
NULL, /* Eo */
|
||||
NULL, /* Fx */
|
||||
post_xx, /* Fx */
|
||||
NULL, /* Ms */
|
||||
NULL, /* No */
|
||||
post_ns, /* Ns */
|
||||
NULL, /* Nx */
|
||||
NULL, /* Ox */
|
||||
post_xx, /* Nx */
|
||||
post_xx, /* Ox */
|
||||
NULL, /* Pc */
|
||||
NULL, /* Pf */
|
||||
NULL, /* Po */
|
||||
@ -199,7 +202,7 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
post_hyph, /* Sx */
|
||||
NULL, /* Sy */
|
||||
NULL, /* Tn */
|
||||
NULL, /* Ux */
|
||||
post_xx, /* Ux */
|
||||
NULL, /* Xc */
|
||||
NULL, /* Xo */
|
||||
post_fo, /* Fo */
|
||||
@ -222,7 +225,7 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
NULL, /* %C */
|
||||
post_es, /* Es */
|
||||
post_en, /* En */
|
||||
NULL, /* Dx */
|
||||
post_xx, /* Dx */
|
||||
NULL, /* %Q */
|
||||
post_par, /* br */
|
||||
post_par, /* sp */
|
||||
@ -297,7 +300,8 @@ mdoc_node_validate(struct roff_man *mdoc)
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd)
|
||||
if (n->sec != SEC_SYNOPSIS ||
|
||||
(n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
|
||||
check_text(mdoc, n->line, n->pos, n->string);
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
@ -316,9 +320,9 @@ mdoc_node_validate(struct roff_man *mdoc)
|
||||
*/
|
||||
|
||||
if (n->child != NULL)
|
||||
n->child->flags &= ~MDOC_DELIMC;
|
||||
n->child->flags &= ~NODE_DELIMC;
|
||||
if (n->last != NULL)
|
||||
n->last->flags &= ~MDOC_DELIMO;
|
||||
n->last->flags &= ~NODE_DELIMO;
|
||||
|
||||
/* Call the macro's postprocessor. */
|
||||
|
||||
@ -502,6 +506,7 @@ post_bl_norm(POST_ARGS)
|
||||
mandoc_msg(MANDOCERR_BL_NOTYPE, mdoc->parse,
|
||||
n->line, n->pos, "Bl");
|
||||
n->norm->Bl.type = LIST_item;
|
||||
mdoclt = MDOC_Item;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -618,6 +623,10 @@ post_bd(POST_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Stand-alone line macros.
|
||||
*/
|
||||
|
||||
static void
|
||||
post_an_norm(POST_ARGS)
|
||||
{
|
||||
@ -645,6 +654,158 @@ post_an_norm(POST_ARGS)
|
||||
abort();
|
||||
}
|
||||
|
||||
static void
|
||||
post_eoln(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse,
|
||||
n->line, n->pos, "%s %s",
|
||||
mdoc_macronames[n->tok], n->child->string);
|
||||
|
||||
while (n->child != NULL)
|
||||
roff_node_delete(mdoc, n->child);
|
||||
|
||||
roff_word_alloc(mdoc, n->line, n->pos, n->tok == MDOC_Bt ?
|
||||
"is currently in beta test." : "currently under development.");
|
||||
mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static int
|
||||
build_list(struct roff_man *mdoc, int tok)
|
||||
{
|
||||
struct roff_node *n;
|
||||
int ic;
|
||||
|
||||
n = mdoc->last->next;
|
||||
for (ic = 1;; ic++) {
|
||||
roff_elem_alloc(mdoc, n->line, n->pos, tok);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc_node_relink(mdoc, n);
|
||||
n = mdoc->last = mdoc->last->parent;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
if (n->next == NULL)
|
||||
return ic;
|
||||
if (ic > 1 || n->next->next != NULL) {
|
||||
roff_word_alloc(mdoc, n->line, n->pos, ",");
|
||||
mdoc->last->flags |= NODE_DELIMC | NODE_NOSRC;
|
||||
}
|
||||
n = mdoc->last->next;
|
||||
if (n->next == NULL) {
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "and");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_ex(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
int ic;
|
||||
|
||||
post_std(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "The");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
|
||||
if (mdoc->last->next != NULL)
|
||||
ic = build_list(mdoc, MDOC_Nm);
|
||||
else if (mdoc->meta.name != NULL) {
|
||||
roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Nm);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = mdoc->last->parent;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
ic = 1;
|
||||
} else {
|
||||
mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
|
||||
n->line, n->pos, "Ex");
|
||||
ic = 0;
|
||||
}
|
||||
|
||||
roff_word_alloc(mdoc, n->line, n->pos,
|
||||
ic > 1 ? "utilities exit\\~0" : "utility exits\\~0");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos,
|
||||
"on success, and\\~>0 if an error occurs.");
|
||||
mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static void
|
||||
post_lb(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *p;
|
||||
|
||||
n = mdoc->last;
|
||||
assert(n->child->type == ROFFT_TEXT);
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
|
||||
if ((p = mdoc_a2lib(n->child->string)) != NULL) {
|
||||
n->child->flags |= NODE_NOPRT;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, p);
|
||||
mdoc->last->flags = NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
return;
|
||||
}
|
||||
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "library");
|
||||
mdoc->last->flags = NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq");
|
||||
mdoc->last->flags = NODE_DELIMO | NODE_NOSRC;
|
||||
mdoc->last = mdoc->last->next;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq");
|
||||
mdoc->last->flags = NODE_DELIMC | NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static void
|
||||
post_rv(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
int ic;
|
||||
|
||||
post_std(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
if (n->child != NULL) {
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "The");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
ic = build_list(mdoc, MDOC_Fn);
|
||||
roff_word_alloc(mdoc, n->line, n->pos,
|
||||
ic > 1 ? "functions return" : "function returns");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos,
|
||||
"the value\\~0 if successful;");
|
||||
} else
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "Upon successful "
|
||||
"completion, the value\\~0 is returned;");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "otherwise "
|
||||
"the value\\~\\-1 is returned and the global variable");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Va);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "errno");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = mdoc->last->parent;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_word_alloc(mdoc, n->line, n->pos,
|
||||
"is set to indicate the error.");
|
||||
mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static void
|
||||
post_std(POST_ARGS)
|
||||
{
|
||||
@ -659,6 +820,30 @@ post_std(POST_ARGS)
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
post_st(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n, *nch;
|
||||
const char *p;
|
||||
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
assert(nch->type == ROFFT_TEXT);
|
||||
|
||||
if ((p = mdoc_a2st(nch->string)) == NULL) {
|
||||
mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse,
|
||||
nch->line, nch->pos, "St %s", nch->string);
|
||||
roff_node_delete(mdoc, n);
|
||||
return;
|
||||
}
|
||||
|
||||
nch->flags |= NODE_NOPRT;
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, nch->line, nch->pos, p);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last= n;
|
||||
}
|
||||
|
||||
static void
|
||||
post_obsolete(POST_ARGS)
|
||||
{
|
||||
@ -670,6 +855,10 @@ post_obsolete(POST_ARGS)
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Block macros.
|
||||
*/
|
||||
|
||||
static void
|
||||
post_bf(POST_ARGS)
|
||||
{
|
||||
@ -735,39 +924,6 @@ post_bf(POST_ARGS)
|
||||
"Bf %s", np->child->string);
|
||||
}
|
||||
|
||||
static void
|
||||
post_lb(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *stdlibname;
|
||||
char *libname;
|
||||
|
||||
n = mdoc->last->child;
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
|
||||
if (NULL == (stdlibname = mdoc_a2lib(n->string)))
|
||||
mandoc_asprintf(&libname,
|
||||
"library \\(Lq%s\\(Rq", n->string);
|
||||
else
|
||||
libname = mandoc_strdup(stdlibname);
|
||||
|
||||
free(n->string);
|
||||
n->string = libname;
|
||||
}
|
||||
|
||||
static void
|
||||
post_eoln(POST_ARGS)
|
||||
{
|
||||
const struct roff_node *n;
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"%s %s", mdoc_macronames[n->tok],
|
||||
n->child->string);
|
||||
}
|
||||
|
||||
static void
|
||||
post_fname(POST_ARGS)
|
||||
{
|
||||
@ -850,12 +1006,11 @@ post_nm(POST_ARGS)
|
||||
n->last->tok == MDOC_Lp))
|
||||
mdoc_node_relink(mdoc, n->last);
|
||||
|
||||
if (mdoc->meta.name != NULL)
|
||||
return;
|
||||
|
||||
deroff(&mdoc->meta.name, n);
|
||||
|
||||
if (mdoc->meta.name == NULL)
|
||||
deroff(&mdoc->meta.name, n);
|
||||
|
||||
if (mdoc->meta.name == NULL ||
|
||||
(mdoc->lastsec == SEC_NAME && n->child == NULL))
|
||||
mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,
|
||||
n->line, n->pos, "Nm");
|
||||
}
|
||||
@ -885,9 +1040,11 @@ post_display(POST_ARGS)
|
||||
n = mdoc->last;
|
||||
switch (n->type) {
|
||||
case ROFFT_BODY:
|
||||
if (n->end != ENDBODY_NOT)
|
||||
break;
|
||||
if (n->child == NULL)
|
||||
if (n->end != ENDBODY_NOT) {
|
||||
if (n->tok == MDOC_Bd &&
|
||||
n->body->parent->args == NULL)
|
||||
roff_node_delete(mdoc, n);
|
||||
} else if (n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
else if (n->tok == MDOC_D1)
|
||||
@ -942,12 +1099,15 @@ post_defaults(POST_ARGS)
|
||||
case MDOC_Ar:
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, nn->line, nn->pos, "file");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, nn->line, nn->pos, "...");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
break;
|
||||
case MDOC_Pa:
|
||||
case MDOC_Mt:
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, nn->line, nn->pos, "~");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -958,17 +1118,11 @@ post_defaults(POST_ARGS)
|
||||
static void
|
||||
post_at(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *std_att;
|
||||
char *att;
|
||||
struct roff_node *n, *nch;
|
||||
const char *att;
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->child == NULL) {
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX");
|
||||
mdoc->last = n;
|
||||
return;
|
||||
}
|
||||
nch = n->child;
|
||||
|
||||
/*
|
||||
* If we have a child, look it up in the standard keys. If a
|
||||
@ -976,17 +1130,19 @@ post_at(POST_ARGS)
|
||||
* prefix "AT&T UNIX " to the existing data.
|
||||
*/
|
||||
|
||||
n = n->child;
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
if ((std_att = mdoc_a2att(n->string)) == NULL) {
|
||||
att = NULL;
|
||||
if (nch != NULL && ((att = mdoc_a2att(nch->string)) == NULL))
|
||||
mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse,
|
||||
n->line, n->pos, "At %s", n->string);
|
||||
mandoc_asprintf(&att, "AT&T UNIX %s", n->string);
|
||||
} else
|
||||
att = mandoc_strdup(std_att);
|
||||
nch->line, nch->pos, "At %s", nch->string);
|
||||
|
||||
free(n->string);
|
||||
n->string = att;
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
if (att != NULL) {
|
||||
roff_word_alloc(mdoc, nch->line, nch->pos, att);
|
||||
nch->flags |= NODE_NOPRT;
|
||||
} else
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1024,6 +1180,41 @@ post_es(POST_ARGS)
|
||||
mdoc->last_es = mdoc->last;
|
||||
}
|
||||
|
||||
static void
|
||||
post_xx(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *os;
|
||||
|
||||
n = mdoc->last;
|
||||
switch (n->tok) {
|
||||
case MDOC_Bsx:
|
||||
os = "BSD/OS";
|
||||
break;
|
||||
case MDOC_Dx:
|
||||
os = "DragonFly";
|
||||
break;
|
||||
case MDOC_Fx:
|
||||
os = "FreeBSD";
|
||||
break;
|
||||
case MDOC_Nx:
|
||||
os = "NetBSD";
|
||||
break;
|
||||
case MDOC_Ox:
|
||||
os = "OpenBSD";
|
||||
break;
|
||||
case MDOC_Ux:
|
||||
os = "UNIX";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, os);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static void
|
||||
post_it(POST_ARGS)
|
||||
{
|
||||
@ -1063,10 +1254,11 @@ post_it(POST_ARGS)
|
||||
mdoc_argnames[nbl->args->argv[0].arg]);
|
||||
/* FALLTHROUGH */
|
||||
case LIST_item:
|
||||
if (nit->head->child != NULL)
|
||||
if ((nch = nit->head->child) != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
mdoc->parse, nit->line, nit->pos,
|
||||
"It %s", nit->head->child->string);
|
||||
"It %s", nch->string == NULL ?
|
||||
mdoc_macronames[nch->tok] : nch->string);
|
||||
break;
|
||||
case LIST_column:
|
||||
cols = (int)nbl->norm->Bl.ncols;
|
||||
@ -1095,22 +1287,7 @@ post_bl_block(POST_ARGS)
|
||||
|
||||
post_prevpar(mdoc);
|
||||
|
||||
/*
|
||||
* These are fairly complicated, so we've broken them into two
|
||||
* functions. post_bl_block_tag() is called when a -tag is
|
||||
* specified, but no -width (it must be guessed). The second
|
||||
* when a -width is specified (macro indicators must be
|
||||
* rewritten into real lengths).
|
||||
*/
|
||||
|
||||
n = mdoc->last;
|
||||
|
||||
if (n->norm->Bl.type == LIST_tag &&
|
||||
n->norm->Bl.width == NULL) {
|
||||
post_bl_block_tag(mdoc);
|
||||
assert(n->norm->Bl.width != NULL);
|
||||
}
|
||||
|
||||
for (ni = n->body->child; ni != NULL; ni = ni->next) {
|
||||
if (ni->body == NULL)
|
||||
continue;
|
||||
@ -1167,71 +1344,6 @@ rewrite_macro2len(char **arg)
|
||||
mandoc_asprintf(arg, "%zun", width);
|
||||
}
|
||||
|
||||
static void
|
||||
post_bl_block_tag(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n, *nn;
|
||||
size_t sz, ssz;
|
||||
int i;
|
||||
char buf[24];
|
||||
|
||||
/*
|
||||
* Calculate the -width for a `Bl -tag' list if it hasn't been
|
||||
* provided. Uses the first head macro. NOTE AGAIN: this is
|
||||
* ONLY if the -width argument has NOT been provided. See
|
||||
* rewrite_macro2len() for converting the -width string.
|
||||
*/
|
||||
|
||||
sz = 10;
|
||||
n = mdoc->last;
|
||||
|
||||
for (nn = n->body->child; nn != NULL; nn = nn->next) {
|
||||
if (nn->tok != MDOC_It)
|
||||
continue;
|
||||
|
||||
assert(nn->type == ROFFT_BLOCK);
|
||||
nn = nn->head->child;
|
||||
|
||||
if (nn == NULL)
|
||||
break;
|
||||
|
||||
if (nn->type == ROFFT_TEXT) {
|
||||
sz = strlen(nn->string) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 != (ssz = macro2len(nn->tok)))
|
||||
sz = ssz;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Defaults to ten ens. */
|
||||
|
||||
(void)snprintf(buf, sizeof(buf), "%un", (unsigned int)sz);
|
||||
|
||||
/*
|
||||
* We have to dynamically add this to the macro's argument list.
|
||||
* We're guaranteed that a MDOC_Width doesn't already exist.
|
||||
*/
|
||||
|
||||
assert(n->args != NULL);
|
||||
i = (int)(n->args->argc)++;
|
||||
|
||||
n->args->argv = mandoc_reallocarray(n->args->argv,
|
||||
n->args->argc, sizeof(struct mdoc_argv));
|
||||
|
||||
n->args->argv[i].arg = MDOC_Width;
|
||||
n->args->argv[i].line = n->line;
|
||||
n->args->argv[i].pos = n->pos;
|
||||
n->args->argv[i].sz = 1;
|
||||
n->args->argv[i].value = mandoc_malloc(sizeof(char *));
|
||||
n->args->argv[i].value[0] = mandoc_strdup(buf);
|
||||
|
||||
/* Set our width! */
|
||||
n->norm->Bl.width = n->args->argv[i].value[0];
|
||||
}
|
||||
|
||||
static void
|
||||
post_bl_head(POST_ARGS)
|
||||
{
|
||||
@ -1325,11 +1437,41 @@ post_bl(POST_ARGS)
|
||||
return;
|
||||
}
|
||||
while (nchild != NULL) {
|
||||
nnext = nchild->next;
|
||||
if (nchild->tok == MDOC_It ||
|
||||
(nchild->tok == MDOC_Sm &&
|
||||
nchild->next != NULL &&
|
||||
nchild->next->tok == MDOC_It)) {
|
||||
nchild = nchild->next;
|
||||
nnext != NULL && nnext->tok == MDOC_It)) {
|
||||
nchild = nnext;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* In .Bl -column, the first rows may be implicit,
|
||||
* that is, they may not start with .It macros.
|
||||
* Such rows may be followed by nodes generated on the
|
||||
* roff level, for example .TS, which cannot be moved
|
||||
* out of the list. In that case, wrap such roff nodes
|
||||
* into an implicit row.
|
||||
*/
|
||||
|
||||
if (nchild->prev != NULL) {
|
||||
mdoc->last = nchild;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_block_alloc(mdoc, nchild->line,
|
||||
nchild->pos, MDOC_It);
|
||||
roff_head_alloc(mdoc, nchild->line,
|
||||
nchild->pos, MDOC_It);
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_body_alloc(mdoc, nchild->line,
|
||||
nchild->pos, MDOC_It);
|
||||
while (nchild->tok != MDOC_It) {
|
||||
mdoc_node_relink(mdoc, nchild);
|
||||
if ((nchild = nnext) == NULL)
|
||||
break;
|
||||
nnext = nchild->next;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
mdoc->last = nbody;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1345,13 +1487,11 @@ post_bl(POST_ARGS)
|
||||
nblock = nbody->parent;
|
||||
nprev = nblock->prev;
|
||||
nparent = nblock->parent;
|
||||
nnext = nchild->next;
|
||||
|
||||
/*
|
||||
* Unlink this child.
|
||||
*/
|
||||
|
||||
assert(nchild->prev == NULL);
|
||||
nbody->child = nnext;
|
||||
if (nnext == NULL)
|
||||
nbody->last = NULL;
|
||||
@ -1461,27 +1601,6 @@ post_root(POST_ARGS)
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
post_st(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n, *nch;
|
||||
const char *p;
|
||||
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
|
||||
assert(nch->type == ROFFT_TEXT);
|
||||
|
||||
if ((p = mdoc_a2st(nch->string)) == NULL) {
|
||||
mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse,
|
||||
nch->line, nch->pos, "St %s", nch->string);
|
||||
roff_node_delete(mdoc, n);
|
||||
} else {
|
||||
free(nch->string);
|
||||
nch->string = mandoc_strdup(p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_rs(POST_ARGS)
|
||||
{
|
||||
@ -1600,7 +1719,7 @@ static void
|
||||
post_ns(POST_ARGS)
|
||||
{
|
||||
|
||||
if (mdoc->last->flags & MDOC_LINE)
|
||||
if (mdoc->last->flags & NODE_LINE)
|
||||
mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse,
|
||||
mdoc->last->line, mdoc->last->pos, NULL);
|
||||
}
|
||||
@ -1646,8 +1765,12 @@ post_sh_name(POST_ARGS)
|
||||
for (n = mdoc->last->child; n != NULL; n = n->next) {
|
||||
switch (n->tok) {
|
||||
case MDOC_Nm:
|
||||
if (hasnm && n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_NAMESEC_PUNCT,
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"Nm %s", n->child->string);
|
||||
hasnm = 1;
|
||||
break;
|
||||
continue;
|
||||
case MDOC_Nd:
|
||||
hasnd = 1;
|
||||
if (n->next != NULL)
|
||||
@ -1655,14 +1778,19 @@ post_sh_name(POST_ARGS)
|
||||
mdoc->parse, n->line, n->pos, NULL);
|
||||
break;
|
||||
case TOKEN_NONE:
|
||||
if (hasnm)
|
||||
break;
|
||||
if (n->type == ROFFT_TEXT &&
|
||||
n->string[0] == ',' && n->string[1] == '\0' &&
|
||||
n->next != NULL && n->next->tok == MDOC_Nm) {
|
||||
n = n->next;
|
||||
continue;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! hasnm)
|
||||
@ -1759,8 +1887,9 @@ post_sh_authors(POST_ARGS)
|
||||
static void
|
||||
post_sh_head(POST_ARGS)
|
||||
{
|
||||
const char *goodsec;
|
||||
enum roff_sec sec;
|
||||
struct roff_node *nch;
|
||||
const char *goodsec;
|
||||
enum roff_sec sec;
|
||||
|
||||
/*
|
||||
* Process a new section. Sections are either "named" or
|
||||
@ -1773,10 +1902,13 @@ post_sh_head(POST_ARGS)
|
||||
|
||||
/* The NAME should be first. */
|
||||
|
||||
if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed)
|
||||
if (sec != SEC_NAME && mdoc->lastnamed == SEC_NONE)
|
||||
mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse,
|
||||
mdoc->last->line, mdoc->last->pos,
|
||||
"Sh %s", secnames[sec]);
|
||||
mdoc->last->line, mdoc->last->pos, "Sh %s",
|
||||
sec != SEC_CUSTOM ? secnames[sec] :
|
||||
(nch = mdoc->last->child) == NULL ? "" :
|
||||
nch->type == ROFFT_TEXT ? nch->string :
|
||||
mdoc_macronames[nch->tok]);
|
||||
|
||||
/* The SYNOPSIS gets special attention in other areas. */
|
||||
|
||||
@ -1851,6 +1983,21 @@ post_sh_head(POST_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_xr(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n, *nch;
|
||||
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
if (nch->next == NULL) {
|
||||
mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse,
|
||||
n->line, n->pos, "Xr %s", nch->string);
|
||||
return;
|
||||
}
|
||||
assert(nch->next == n->last);
|
||||
}
|
||||
|
||||
static void
|
||||
post_ignpar(POST_ARGS)
|
||||
{
|
||||
@ -1961,6 +2108,8 @@ post_dd(POST_ARGS)
|
||||
char *datestr;
|
||||
|
||||
n = mdoc->last;
|
||||
n->flags |= NODE_NOPRT;
|
||||
|
||||
if (mdoc->meta.date != NULL) {
|
||||
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
|
||||
n->line, n->pos, "Dd");
|
||||
@ -1978,7 +2127,7 @@ post_dd(POST_ARGS)
|
||||
if (n->child == NULL || n->child->string[0] == '\0') {
|
||||
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
datestr = NULL;
|
||||
@ -1990,8 +2139,6 @@ post_dd(POST_ARGS)
|
||||
datestr, n->line, n->pos);
|
||||
free(datestr);
|
||||
}
|
||||
out:
|
||||
roff_node_delete(mdoc, n);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2002,10 +2149,12 @@ post_dt(POST_ARGS)
|
||||
char *p;
|
||||
|
||||
n = mdoc->last;
|
||||
n->flags |= NODE_NOPRT;
|
||||
|
||||
if (mdoc->flags & MDOC_PBODY) {
|
||||
mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse,
|
||||
n->line, n->pos, "Dt");
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mdoc->meta.title != NULL)
|
||||
@ -2047,7 +2196,7 @@ post_dt(POST_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
/* Mandatory second argument: section. */
|
||||
/* Mandatory second argument: section. */
|
||||
|
||||
if (nn != NULL)
|
||||
nn = nn->next;
|
||||
@ -2057,7 +2206,7 @@ post_dt(POST_ARGS)
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"Dt %s", mdoc->meta.title);
|
||||
mdoc->meta.vol = mandoc_strdup("LOCAL");
|
||||
goto out; /* msec and arch remain NULL. */
|
||||
return; /* msec and arch remain NULL. */
|
||||
}
|
||||
|
||||
mdoc->meta.msec = mandoc_strdup(nn->string);
|
||||
@ -2075,7 +2224,7 @@ post_dt(POST_ARGS)
|
||||
/* Optional third argument: architecture. */
|
||||
|
||||
if ((nn = nn->next) == NULL)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
for (p = nn->string; *p != '\0'; p++)
|
||||
*p = tolower((unsigned char)*p);
|
||||
@ -2086,15 +2235,41 @@ post_dt(POST_ARGS)
|
||||
if ((nn = nn->next) != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
|
||||
nn->line, nn->pos, "Dt ... %s", nn->string);
|
||||
|
||||
out:
|
||||
roff_node_delete(mdoc, n);
|
||||
}
|
||||
|
||||
static void
|
||||
post_bx(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
struct roff_node *n, *nch;
|
||||
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
|
||||
if (nch != NULL) {
|
||||
mdoc->last = nch;
|
||||
nch = nch->next;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
} else
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "BSD");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
|
||||
if (nch == NULL) {
|
||||
mdoc->last = n;
|
||||
return;
|
||||
}
|
||||
|
||||
roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "-");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Ns);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
|
||||
/*
|
||||
* Make `Bx's second argument always start with an uppercase
|
||||
@ -2102,8 +2277,7 @@ post_bx(POST_ARGS)
|
||||
* uppercase blindly.
|
||||
*/
|
||||
|
||||
if ((n = mdoc->last->child) != NULL && (n = n->next) != NULL)
|
||||
*n->string = (char)toupper((unsigned char)*n->string);
|
||||
*nch->string = (char)toupper((unsigned char)*nch->string);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2116,6 +2290,8 @@ post_os(POST_ARGS)
|
||||
struct roff_node *n;
|
||||
|
||||
n = mdoc->last;
|
||||
n->flags |= NODE_NOPRT;
|
||||
|
||||
if (mdoc->meta.os != NULL)
|
||||
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
|
||||
n->line, n->pos, "Os");
|
||||
@ -2136,11 +2312,11 @@ post_os(POST_ARGS)
|
||||
mdoc->meta.os = NULL;
|
||||
deroff(&mdoc->meta.os, n);
|
||||
if (mdoc->meta.os)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
if (mdoc->defos) {
|
||||
mdoc->meta.os = mandoc_strdup(mdoc->defos);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef OSNAME
|
||||
@ -2157,35 +2333,6 @@ post_os(POST_ARGS)
|
||||
}
|
||||
mdoc->meta.os = mandoc_strdup(defbuf);
|
||||
#endif /*!OSNAME*/
|
||||
|
||||
out:
|
||||
roff_node_delete(mdoc, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no argument is provided,
|
||||
* fill in the name of the current manual page.
|
||||
*/
|
||||
static void
|
||||
post_ex(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
post_std(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->child != NULL)
|
||||
return;
|
||||
|
||||
if (mdoc->meta.name == NULL) {
|
||||
mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
|
||||
n->line, n->pos, "Ex");
|
||||
return;
|
||||
}
|
||||
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
enum roff_sec
|
||||
|
67
read.c
67
read.c
@ -1,7 +1,7 @@
|
||||
/* $Id: read.c,v 1.149 2016/07/10 13:34:30 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.157 2017/01/09 01:37:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2017 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
|
||||
@ -19,10 +19,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#if HAVE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
@ -110,10 +108,11 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"no document body",
|
||||
"content before first section header",
|
||||
"first section is not \"NAME\"",
|
||||
"NAME section without name",
|
||||
"NAME section without Nm before Nd",
|
||||
"NAME section without description",
|
||||
"description not at the end of NAME",
|
||||
"bad NAME section content",
|
||||
"missing comma before name",
|
||||
"missing description line, using \"\"",
|
||||
"sections out of conventional order",
|
||||
"duplicate section title",
|
||||
@ -143,7 +142,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"empty argument, using 0n",
|
||||
"missing display type, using -ragged",
|
||||
"list type is not the first argument",
|
||||
"missing -width in -tag list, using 8n",
|
||||
"missing -width in -tag list, using 6n",
|
||||
"missing utility name, using \"\"",
|
||||
"missing function name, using \"\"",
|
||||
"empty head in list item",
|
||||
@ -152,6 +151,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"unknown font type, using \\fR",
|
||||
"nothing follows prefix",
|
||||
"empty reference block",
|
||||
"missing section argument",
|
||||
"missing -std argument, adding it",
|
||||
"missing option string, using \"\"",
|
||||
"missing resource identifier, using \"\"",
|
||||
@ -291,13 +291,6 @@ choose_parser(struct mparse *curp)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (format == MPARSE_MDOC) {
|
||||
mdoc_hash_init();
|
||||
curp->man->macroset = MACROSET_MDOC;
|
||||
@ -324,6 +317,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
const char *save_file;
|
||||
char *cp;
|
||||
size_t pos; /* byte number in the ln buffer */
|
||||
size_t j; /* auxiliary byte number in the blk buffer */
|
||||
enum rofferr rr;
|
||||
int of;
|
||||
int lnn; /* line number in the real file */
|
||||
@ -429,14 +423,21 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
}
|
||||
|
||||
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
|
||||
j = i;
|
||||
i += 2;
|
||||
/* Comment, skip to end of line */
|
||||
for (; i < blk.sz; ++i) {
|
||||
if ('\n' == blk.buf[i]) {
|
||||
++i;
|
||||
++lnn;
|
||||
break;
|
||||
}
|
||||
if (blk.buf[i] != '\n')
|
||||
continue;
|
||||
if (blk.buf[i - 1] == ' ' ||
|
||||
blk.buf[i - 1] == '\t')
|
||||
mandoc_msg(
|
||||
MANDOCERR_SPACE_EOL,
|
||||
curp, curp->line,
|
||||
pos + i-1 - j, NULL);
|
||||
++i;
|
||||
++lnn;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Backout trailing whitespaces */
|
||||
@ -562,15 +563,7 @@ rerun:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If input parsers have not been allocated, do so now.
|
||||
* We keep these instanced between parsers, but set them
|
||||
* locally per parse routine since we can use different
|
||||
* parsers with each one.
|
||||
*/
|
||||
|
||||
if (curp->man == NULL ||
|
||||
curp->man->macroset == MACROSET_NONE)
|
||||
if (curp->man->macroset == MACROSET_NONE)
|
||||
choose_parser(curp);
|
||||
|
||||
/*
|
||||
@ -613,7 +606,6 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
size_t off;
|
||||
ssize_t ssz;
|
||||
|
||||
#if HAVE_MMAP
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) == -1)
|
||||
@ -637,7 +629,6 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
if (fb->buf != MAP_FAILED)
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (curp->gzip) {
|
||||
if ((gz = gzdopen(fd, "rb")) == NULL)
|
||||
@ -683,10 +674,6 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
static void
|
||||
mparse_end(struct mparse *curp)
|
||||
{
|
||||
|
||||
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)
|
||||
@ -766,11 +753,9 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
|
||||
(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||
mparse_parse_buffer(curp, blk, file);
|
||||
curp->filenc = save_filenc;
|
||||
#if HAVE_MMAP
|
||||
if (with_mmap)
|
||||
munmap(blk.buf, blk.sz);
|
||||
else
|
||||
#endif
|
||||
free(blk.buf);
|
||||
}
|
||||
return curp->file_status;
|
||||
@ -842,11 +827,8 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||
void
|
||||
mparse_reset(struct mparse *curp)
|
||||
{
|
||||
|
||||
roff_reset(curp->roff);
|
||||
|
||||
if (curp->man != NULL)
|
||||
roff_man_reset(curp->man);
|
||||
roff_man_reset(curp->man);
|
||||
if (curp->secondary)
|
||||
curp->secondary->sz = 0;
|
||||
|
||||
@ -884,6 +866,13 @@ mparse_result(struct mparse *curp, struct roff_man **man,
|
||||
*man = curp->man;
|
||||
}
|
||||
|
||||
void
|
||||
mparse_updaterc(struct mparse *curp, enum mandoclevel *rc)
|
||||
{
|
||||
if (curp->file_status > *rc)
|
||||
*rc = curp->file_status;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_vmsg(enum mandocerr t, struct mparse *m,
|
||||
int ln, int pos, const char *fmt, ...)
|
||||
|
40
roff.c
40
roff.c
@ -1,7 +1,7 @@
|
||||
/* $Id: roff.c,v 1.284 2016/01/08 17:48:10 schwarze Exp $ */
|
||||
/* $Id: roff.c,v 1.288 2017/01/12 18:02:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -991,11 +991,11 @@ roff_node_alloc(struct roff_man *man, int line, int pos,
|
||||
n->sec = man->lastsec;
|
||||
|
||||
if (man->flags & MDOC_SYNOPSIS)
|
||||
n->flags |= MDOC_SYNPRETTY;
|
||||
n->flags |= NODE_SYNPRETTY;
|
||||
else
|
||||
n->flags &= ~MDOC_SYNPRETTY;
|
||||
n->flags &= ~NODE_SYNPRETTY;
|
||||
if (man->flags & MDOC_NEWLINE)
|
||||
n->flags |= MDOC_LINE;
|
||||
n->flags |= NODE_LINE;
|
||||
man->flags &= ~MDOC_NEWLINE;
|
||||
|
||||
return n;
|
||||
@ -1017,9 +1017,13 @@ roff_node_append(struct roff_man *man, struct roff_node *n)
|
||||
n->parent = man->last->parent;
|
||||
break;
|
||||
case ROFF_NEXT_CHILD:
|
||||
if (man->last->child != NULL) {
|
||||
n->next = man->last->child;
|
||||
man->last->child->prev = n;
|
||||
} else
|
||||
man->last->last = n;
|
||||
man->last->child = n;
|
||||
n->parent = man->last;
|
||||
n->parent->last = n;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -1059,10 +1063,7 @@ roff_word_alloc(struct roff_man *man, int line, int pos, const char *word)
|
||||
n = roff_node_alloc(man, line, pos, ROFFT_TEXT, TOKEN_NONE);
|
||||
n->string = roff_strdup(man->roff, word);
|
||||
roff_node_append(man, n);
|
||||
if (man->macroset == MACROSET_MDOC)
|
||||
n->flags |= MDOC_VALID | MDOC_ENDED;
|
||||
else
|
||||
n->flags |= MAN_VALID;
|
||||
n->flags |= NODE_VALID | NODE_ENDED;
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
|
||||
@ -1132,7 +1133,7 @@ roff_addeqn(struct roff_man *man, const struct eqn *eqn)
|
||||
n = roff_node_alloc(man, eqn->ln, eqn->pos, ROFFT_EQN, TOKEN_NONE);
|
||||
n->eqn = eqn;
|
||||
if (eqn->ln > man->last->line)
|
||||
n->flags |= MDOC_LINE;
|
||||
n->flags |= NODE_LINE;
|
||||
roff_node_append(man, n);
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
@ -1147,10 +1148,7 @@ roff_addtbl(struct roff_man *man, const struct tbl_span *tbl)
|
||||
n = roff_node_alloc(man, tbl->line, 0, ROFFT_TBL, TOKEN_NONE);
|
||||
n->span = tbl;
|
||||
roff_node_append(man, n);
|
||||
if (man->macroset == MACROSET_MDOC)
|
||||
n->flags |= MDOC_VALID | MDOC_ENDED;
|
||||
else
|
||||
n->flags |= MAN_VALID;
|
||||
n->flags |= NODE_VALID | NODE_ENDED;
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
|
||||
@ -1225,16 +1223,12 @@ deroff(char **dest, const struct roff_node *n)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Skip leading whitespace and escape sequences. */
|
||||
/* Skip leading whitespace. */
|
||||
|
||||
cp = n->string;
|
||||
while (*cp != '\0') {
|
||||
if ('\\' == *cp) {
|
||||
for (cp = n->string; *cp != '\0'; cp++) {
|
||||
if (cp[0] == '\\' && strchr(" %&0^|~", cp[1]) != NULL)
|
||||
cp++;
|
||||
mandoc_escape((const char **)&cp, NULL, NULL);
|
||||
} else if (isspace((unsigned char)*cp))
|
||||
cp++;
|
||||
else
|
||||
else if ( ! isspace((unsigned char)*cp))
|
||||
break;
|
||||
}
|
||||
|
||||
|
25
roff.h
25
roff.h
@ -1,7 +1,7 @@
|
||||
/* $OpenBSD$ */
|
||||
/* $Id: roff.h,v 1.39 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -98,17 +98,16 @@ struct roff_node {
|
||||
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
|
||||
#define NODE_VALID (1 << 0) /* Has been validated. */
|
||||
#define NODE_ENDED (1 << 1) /* Gone past body end mark. */
|
||||
#define NODE_EOS (1 << 2) /* At sentence boundary. */
|
||||
#define NODE_LINE (1 << 3) /* First macro/text on line. */
|
||||
#define NODE_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting. */
|
||||
#define NODE_BROKEN (1 << 5) /* Must validate parent when ending. */
|
||||
#define NODE_DELIMO (1 << 6)
|
||||
#define NODE_DELIMC (1 << 7)
|
||||
#define NODE_NOSRC (1 << 8) /* Generated node, not in input file. */
|
||||
#define NODE_NOPRT (1 << 9) /* Shall not print anything. */
|
||||
int prev_font; /* Before entering this node. */
|
||||
int aux; /* Decoded node data, type-dependent. */
|
||||
enum roff_type type; /* AST node type. */
|
||||
|
71
tag.c
71
tag.c
@ -1,6 +1,6 @@
|
||||
/* $Id: tag.c,v 1.12 2016/07/08 20:42:15 schwarze Exp $ */
|
||||
/* $Id: tag.c,v 1.17 2017/01/09 17:49:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -31,12 +31,14 @@
|
||||
#include "tag.h"
|
||||
|
||||
struct tag_entry {
|
||||
size_t line;
|
||||
size_t *lines;
|
||||
size_t maxlines;
|
||||
size_t nlines;
|
||||
int prio;
|
||||
char s[];
|
||||
};
|
||||
|
||||
static void tag_signal(int);
|
||||
static void tag_signal(int) __attribute__((noreturn));
|
||||
|
||||
static struct ohash tag_data;
|
||||
static struct tag_files tag_files;
|
||||
@ -128,18 +130,58 @@ tag_put(const char *s, int prio, size_t line)
|
||||
size_t len;
|
||||
unsigned int slot;
|
||||
|
||||
if (tag_files.tfd <= 0 || strchr(s, ' ') != NULL)
|
||||
/* Sanity checks. */
|
||||
|
||||
if (tag_files.tfd <= 0)
|
||||
return;
|
||||
if (s[0] == '\\' && (s[1] == '&' || s[1] == 'e'))
|
||||
s += 2;
|
||||
if (*s == '\0' || strchr(s, ' ') != NULL)
|
||||
return;
|
||||
|
||||
slot = ohash_qlookup(&tag_data, s);
|
||||
entry = ohash_find(&tag_data, slot);
|
||||
|
||||
if (entry == NULL) {
|
||||
|
||||
/* Build a new entry. */
|
||||
|
||||
len = strlen(s) + 1;
|
||||
entry = mandoc_malloc(sizeof(*entry) + len);
|
||||
memcpy(entry->s, s, len);
|
||||
entry->lines = NULL;
|
||||
entry->maxlines = entry->nlines = 0;
|
||||
ohash_insert(&tag_data, slot, entry);
|
||||
} else if (entry->prio <= prio)
|
||||
return;
|
||||
entry->line = line;
|
||||
|
||||
} else {
|
||||
|
||||
/* Handle priority 0 entries. */
|
||||
|
||||
if (prio == 0) {
|
||||
if (entry->prio == 0)
|
||||
entry->prio = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* A better entry is already present, ignore the new one. */
|
||||
|
||||
if (entry->prio > 0 && entry->prio < prio)
|
||||
return;
|
||||
|
||||
/* The existing entry is worse, clear it. */
|
||||
|
||||
if (entry->prio < 1 || entry->prio > prio)
|
||||
entry->nlines = 0;
|
||||
}
|
||||
|
||||
/* Remember the new line. */
|
||||
|
||||
if (entry->maxlines == entry->nlines) {
|
||||
entry->maxlines += 4;
|
||||
entry->lines = mandoc_reallocarray(entry->lines,
|
||||
entry->maxlines, sizeof(*entry->lines));
|
||||
}
|
||||
entry->lines[entry->nlines++] = line;
|
||||
entry->prio = prio;
|
||||
}
|
||||
|
||||
@ -152,6 +194,7 @@ tag_write(void)
|
||||
{
|
||||
FILE *stream;
|
||||
struct tag_entry *entry;
|
||||
size_t i;
|
||||
unsigned int slot;
|
||||
|
||||
if (tag_files.tfd <= 0)
|
||||
@ -159,9 +202,11 @@ tag_write(void)
|
||||
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);
|
||||
if (stream != NULL && entry->prio >= 0)
|
||||
for (i = 0; i < entry->nlines; i++)
|
||||
fprintf(stream, "%s %s %zu\n",
|
||||
entry->s, tag_files.ofn, entry->lines[i]);
|
||||
free(entry->lines);
|
||||
free(entry);
|
||||
entry = ohash_next(&tag_data, &slot);
|
||||
}
|
||||
@ -176,11 +221,11 @@ tag_unlink(void)
|
||||
pid_t tc_pgid;
|
||||
|
||||
if (tag_files.tcpgid != -1) {
|
||||
tc_pgid = tcgetpgrp(STDIN_FILENO);
|
||||
tc_pgid = tcgetpgrp(tag_files.ofd);
|
||||
if (tc_pgid == tag_files.pager_pid ||
|
||||
tc_pgid == getpgid(0) ||
|
||||
getpgid(tc_pgid) == -1)
|
||||
(void)tcsetpgrp(STDIN_FILENO, tag_files.tcpgid);
|
||||
(void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid);
|
||||
}
|
||||
if (*tag_files.ofn != '\0')
|
||||
unlink(tag_files.ofn);
|
||||
|
30
tbl_html.c
30
tbl_html.c
@ -1,7 +1,7 @@
|
||||
/* $Id: tbl_html.c,v 1.18 2015/10/12 00:08:16 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.19 2017/01/17 01:47:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -50,9 +50,6 @@ html_tbl_strlen(const char *p, void *arg)
|
||||
static void
|
||||
html_tblopen(struct html *h, const struct tbl_span *sp)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
struct roffcol *col;
|
||||
int ic;
|
||||
|
||||
if (h->tbl.cols == NULL) {
|
||||
@ -62,19 +59,12 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
|
||||
}
|
||||
|
||||
assert(NULL == h->tblt);
|
||||
PAIR_CLASS_INIT(&tag, "tbl");
|
||||
h->tblt = print_otag(h, TAG_TABLE, 1, &tag);
|
||||
h->tblt = print_otag(h, TAG_TABLE, "c", "tbl");
|
||||
|
||||
for (ic = 0; ic < sp->opts->cols; ic++) {
|
||||
bufinit(h);
|
||||
col = h->tbl.cols + ic;
|
||||
SCALE_HS_INIT(&su, col->width);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
}
|
||||
for (ic = 0; ic < sp->opts->cols; ic++)
|
||||
print_otag(h, TAG_COL, "shw", h->tbl.cols[ic].width);
|
||||
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
print_otag(h, TAG_TBODY, "");
|
||||
}
|
||||
|
||||
void
|
||||
@ -90,7 +80,6 @@ void
|
||||
print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_dat *dp;
|
||||
struct htmlpair tag;
|
||||
struct tag *tt;
|
||||
int ic;
|
||||
|
||||
@ -104,19 +93,18 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
h->flags |= HTML_NONOSPACE;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
|
||||
switch (sp->pos) {
|
||||
case TBL_SPAN_HORIZ:
|
||||
case TBL_SPAN_DHORIZ:
|
||||
PAIR_INIT(&tag, ATTR_COLSPAN, "0");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
print_otag(h, TAG_TD, "?", "colspan", "0");
|
||||
break;
|
||||
default:
|
||||
dp = sp->first;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++) {
|
||||
print_stagq(h, tt);
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
print_otag(h, TAG_TD, "");
|
||||
|
||||
if (dp == NULL || dp->layout->col > ic)
|
||||
continue;
|
||||
|
24
term.c
24
term.c
@ -1,7 +1,7 @@
|
||||
/* $Id: term.c,v 1.257 2016/04/12 15:30:00 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.259 2017/01/08 18:16:58 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-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -504,7 +504,9 @@ term_word(struct termp *p, const char *word)
|
||||
}
|
||||
}
|
||||
/* Trim trailing backspace/blank pair. */
|
||||
if (p->col > 2 && p->buf[p->col - 1] == ' ')
|
||||
if (p->col > 2 &&
|
||||
(p->buf[p->col - 1] == ' ' ||
|
||||
p->buf[p->col - 1] == '\t'))
|
||||
p->col -= 2;
|
||||
continue;
|
||||
default:
|
||||
@ -568,7 +570,7 @@ encode1(struct termp *p, int c)
|
||||
p->fontq[p->fonti] : TERMFONT_NONE;
|
||||
|
||||
if (p->flags & TERMP_BACKBEFORE) {
|
||||
if (p->buf[p->col - 1] == ' ')
|
||||
if (p->buf[p->col - 1] == ' ' || p->buf[p->col - 1] == '\t')
|
||||
p->col--;
|
||||
else
|
||||
p->buf[p->col++] = 8;
|
||||
@ -604,8 +606,20 @@ encode(struct termp *p, const char *word, size_t sz)
|
||||
if (ASCII_HYPH == word[i] ||
|
||||
isgraph((unsigned char)word[i]))
|
||||
encode1(p, word[i]);
|
||||
else
|
||||
else {
|
||||
p->buf[p->col++] = word[i];
|
||||
|
||||
/*
|
||||
* Postpone the effect of \z while handling
|
||||
* an overstrike sequence from ascii_uc2str().
|
||||
*/
|
||||
|
||||
if (word[i] == '\b' &&
|
||||
(p->flags & TERMP_BACKBEFORE)) {
|
||||
p->flags &= ~TERMP_BACKBEFORE;
|
||||
p->flags |= TERMP_BACKAFTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: term_ascii.c,v 1.53 2016/07/08 22:29:05 schwarze Exp $ */
|
||||
/* $Id: term_ascii.c,v 1.54 2016/07/31 09:29:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -98,7 +98,7 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
|
||||
|
||||
v = TERMENC_LOCALE == enc ?
|
||||
setlocale(LC_CTYPE, "") :
|
||||
setlocale(LC_CTYPE, "en_US.UTF-8");
|
||||
setlocale(LC_CTYPE, UTF8_LOCALE);
|
||||
if (NULL != v && MB_CUR_MAX > 1) {
|
||||
p->enc = enc;
|
||||
p->advance = locale_advance;
|
||||
|
118
term_ps.c
118
term_ps.c
@ -1,7 +1,7 @@
|
||||
/* $Id: term_ps.c,v 1.80 2015/12/23 20:50:13 schwarze Exp $ */
|
||||
/* $Id: term_ps.c,v 1.82 2016/08/10 11:03:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -98,15 +98,13 @@ static void ps_begin(struct termp *);
|
||||
static void ps_closepage(struct termp *);
|
||||
static void ps_end(struct termp *);
|
||||
static void ps_endline(struct termp *);
|
||||
static void ps_fclose(struct termp *);
|
||||
static void ps_growbuf(struct termp *, size_t);
|
||||
static void ps_letter(struct termp *, int);
|
||||
static void ps_pclose(struct termp *);
|
||||
static void ps_plast(struct termp *);
|
||||
static void ps_pletter(struct termp *, int);
|
||||
#if __GNUC__ - 0 >= 4
|
||||
__attribute__((__format__ (__printf__, 2, 3)))
|
||||
#endif
|
||||
static void ps_printf(struct termp *, const char *, ...);
|
||||
static void ps_printf(struct termp *, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)));
|
||||
static void ps_putchar(struct termp *, char);
|
||||
static void ps_setfont(struct termp *, enum termfont);
|
||||
static void ps_setwidth(struct termp *, int, int);
|
||||
@ -782,6 +780,9 @@ ps_end(struct termp *p)
|
||||
{
|
||||
size_t i, xref, base;
|
||||
|
||||
ps_plast(p);
|
||||
ps_pclose(p);
|
||||
|
||||
/*
|
||||
* At the end of the file, do one last showpage. This is the
|
||||
* same behaviour as groff(1) and works for multiple pages as
|
||||
@ -1025,39 +1026,53 @@ ps_pclose(struct termp *p)
|
||||
p->ps->flags &= ~PS_INLINE;
|
||||
}
|
||||
|
||||
/* If we have a `last' char that wasn't printed yet, print it now. */
|
||||
static void
|
||||
ps_fclose(struct termp *p)
|
||||
ps_plast(struct termp *p)
|
||||
{
|
||||
size_t wx;
|
||||
|
||||
/*
|
||||
* Strong closure: if we have a last-char, spit it out after
|
||||
* checking that we're in the right font mode. This will of
|
||||
* course open a new scope, if applicable.
|
||||
*
|
||||
* Following this, close out any scope that's open.
|
||||
*/
|
||||
|
||||
if (p->ps->last != '\0') {
|
||||
assert( ! (p->ps->flags & PS_BACKSP));
|
||||
if (p->ps->nextf != p->ps->lastf) {
|
||||
ps_pclose(p);
|
||||
ps_setfont(p, p->ps->nextf);
|
||||
}
|
||||
p->ps->nextf = TERMFONT_NONE;
|
||||
ps_pletter(p, p->ps->last);
|
||||
p->ps->last = '\0';
|
||||
}
|
||||
|
||||
if ( ! (PS_INLINE & p->ps->flags))
|
||||
if (p->ps->last == '\0')
|
||||
return;
|
||||
|
||||
ps_pclose(p);
|
||||
/* Check the font mode; open a new scope if it doesn't match. */
|
||||
|
||||
if (p->ps->nextf != p->ps->lastf) {
|
||||
ps_pclose(p);
|
||||
ps_setfont(p, p->ps->nextf);
|
||||
}
|
||||
p->ps->nextf = TERMFONT_NONE;
|
||||
|
||||
/*
|
||||
* For an overstrike, if a previous character
|
||||
* was wider, advance to center the new one.
|
||||
*/
|
||||
|
||||
if (p->ps->pscolnext) {
|
||||
wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx;
|
||||
if (p->ps->pscol + wx < p->ps->pscolnext)
|
||||
p->ps->pscol = (p->ps->pscol +
|
||||
p->ps->pscolnext - wx) / 2;
|
||||
}
|
||||
|
||||
ps_pletter(p, p->ps->last);
|
||||
p->ps->last = '\0';
|
||||
|
||||
/*
|
||||
* For an overstrike, if a previous character
|
||||
* was wider, advance to the end of the old one.
|
||||
*/
|
||||
|
||||
if (p->ps->pscol < p->ps->pscolnext) {
|
||||
ps_pclose(p);
|
||||
p->ps->pscol = p->ps->pscolnext;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ps_letter(struct termp *p, int arg)
|
||||
{
|
||||
size_t savecol, wx;
|
||||
size_t savecol;
|
||||
char c;
|
||||
|
||||
c = arg >= 128 || arg <= 0 ? '?' : arg;
|
||||
@ -1123,43 +1138,12 @@ ps_letter(struct termp *p, int arg)
|
||||
* Use them and print it.
|
||||
*/
|
||||
|
||||
if (p->ps->last != '\0') {
|
||||
if (p->ps->nextf != p->ps->lastf) {
|
||||
ps_pclose(p);
|
||||
ps_setfont(p, p->ps->nextf);
|
||||
}
|
||||
p->ps->nextf = TERMFONT_NONE;
|
||||
|
||||
/*
|
||||
* For an overstrike, if a previous character
|
||||
* was wider, advance to center the new one.
|
||||
*/
|
||||
|
||||
if (p->ps->pscolnext) {
|
||||
wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx;
|
||||
if (p->ps->pscol + wx < p->ps->pscolnext)
|
||||
p->ps->pscol = (p->ps->pscol +
|
||||
p->ps->pscolnext - wx) / 2;
|
||||
}
|
||||
|
||||
ps_pletter(p, p->ps->last);
|
||||
|
||||
/*
|
||||
* For an overstrike, if a previous character
|
||||
* was wider, advance to the end of the old one.
|
||||
*/
|
||||
|
||||
if (p->ps->pscol < p->ps->pscolnext) {
|
||||
ps_pclose(p);
|
||||
p->ps->pscol = p->ps->pscolnext;
|
||||
}
|
||||
}
|
||||
ps_plast(p);
|
||||
|
||||
/*
|
||||
* Do not print the current character yet because font
|
||||
* instructions might follow; only remember it.
|
||||
* For the first character, nothing else is done.
|
||||
* The final character will get printed from ps_fclose().
|
||||
* instructions might follow; only remember the character.
|
||||
* It will get printed later from ps_plast().
|
||||
*/
|
||||
|
||||
p->ps->last = c;
|
||||
@ -1192,7 +1176,8 @@ ps_advance(struct termp *p, size_t len)
|
||||
* and readjust our column settings.
|
||||
*/
|
||||
|
||||
ps_fclose(p);
|
||||
ps_plast(p);
|
||||
ps_pclose(p);
|
||||
p->ps->pscol += len;
|
||||
}
|
||||
|
||||
@ -1202,7 +1187,8 @@ ps_endline(struct termp *p)
|
||||
|
||||
/* Close out any scopes we have open: we're at eoln. */
|
||||
|
||||
ps_fclose(p);
|
||||
ps_plast(p);
|
||||
ps_pclose(p);
|
||||
|
||||
/*
|
||||
* If we're in the margin, don't try to recalculate our current
|
||||
|
7
test-EFTYPE.c
Normal file
7
test-EFTYPE.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return !EFTYPE;
|
||||
}
|
30
test-PATH_MAX.c
Normal file
30
test-PATH_MAX.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* POSIX allows PATH_MAX to not be defined, see
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html;
|
||||
* the GNU Hurd is an example of a system not having it.
|
||||
*
|
||||
* Arguably, it would be better to test sysconf(_SC_PATH_MAX),
|
||||
* but since the individual *.c files include "config.h" before
|
||||
* <limits.h>, overriding an excessive value of PATH_MAX from
|
||||
* "config.h" is impossible anyway, so for now, the simplest
|
||||
* fix is to provide a value only on systems not having any.
|
||||
* So far, we encountered no system defining PATH_MAX to an
|
||||
* impractically large value, even though POSIX explicitly
|
||||
* allows that.
|
||||
*
|
||||
* The real fix would be to replace all static buffers of size
|
||||
* PATH_MAX by dynamically allocated buffers. But that is
|
||||
* somewhat intrusive because it touches several files and
|
||||
* because it requires changing struct mlink in mandocdb.c.
|
||||
* So i'm postponing that for now.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
printf("PATH_MAX is defined to be %ld\n", (long)PATH_MAX);
|
||||
return 0;
|
||||
}
|
11
test-be32toh.c
Normal file
11
test-be32toh.c
Normal file
@ -0,0 +1,11 @@
|
||||
#ifdef SYS_ENDIAN
|
||||
#include <sys/endian.h>
|
||||
#else
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return htobe32(be32toh(0x3a7d0cdb)) != 0x3a7d0cdb;
|
||||
}
|
19
test-fts.c
19
test-fts.c
@ -2,6 +2,13 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fts.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef FTS_COMPARE_CONST
|
||||
int fts_compare(const FTSENT *const *, const FTSENT *const *);
|
||||
#else
|
||||
int fts_compare(const FTSENT **, const FTSENT **);
|
||||
#endif
|
||||
|
||||
int
|
||||
main(void)
|
||||
@ -14,7 +21,7 @@ main(void)
|
||||
argv[1] = (char *)NULL;
|
||||
|
||||
ftsp = fts_open((char * const *)argv,
|
||||
FTS_PHYSICAL | FTS_NOCHDIR, NULL);
|
||||
FTS_PHYSICAL | FTS_NOCHDIR, fts_compare);
|
||||
|
||||
if (ftsp == NULL) {
|
||||
perror("fts_open");
|
||||
@ -40,3 +47,13 @@ main(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
#ifdef FTS_COMPARE_CONST
|
||||
fts_compare(const FTSENT *const *a, const FTSENT *const *b)
|
||||
#else
|
||||
fts_compare(const FTSENT **a, const FTSENT **b)
|
||||
#endif
|
||||
{
|
||||
return strcmp((*a)->fts_name, (*b)->fts_name);
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return mmap(NULL, 1, PROT_READ, MAP_SHARED, -1, 0) != MAP_FAILED;
|
||||
}
|
17
test-nanosleep.c
Normal file
17
test-nanosleep.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
struct timespec timeout;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = 100000000; /* 0.1 seconds */
|
||||
|
||||
if (nanosleep(&timeout, NULL)) {
|
||||
perror("nanosleep");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
7
test-ntohl.c
Normal file
7
test-ntohl.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return htonl(ntohl(0x3a7d0cdb)) != 0x3a7d0cdb;
|
||||
}
|
24
test-ohash.c
24
test-ohash.c
@ -3,9 +3,27 @@
|
||||
#include <stdlib.h>
|
||||
#include <ohash.h>
|
||||
|
||||
void *xmalloc(size_t sz, void *arg) { return calloc(1,sz); }
|
||||
void *xcalloc(size_t nmemb, size_t sz, void *arg) { return calloc(nmemb,sz); }
|
||||
void xfree(void *p, void *arg) { free(p); }
|
||||
static void *xmalloc(size_t, void *);
|
||||
static void *xcalloc(size_t, size_t, void *);
|
||||
static void xfree(void *, void *);
|
||||
|
||||
|
||||
static void *
|
||||
xmalloc(size_t sz, void *arg) {
|
||||
return calloc(1,sz);
|
||||
}
|
||||
|
||||
static void *
|
||||
xcalloc(size_t nmemb, size_t sz, void *arg)
|
||||
{
|
||||
return calloc(nmemb,sz);
|
||||
}
|
||||
|
||||
static void
|
||||
xfree(void *p, void *arg)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
|
13
test-sandbox_init.c
Normal file
13
test-sandbox_init.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <sandbox.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char *ep;
|
||||
int rc;
|
||||
|
||||
rc = sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, &ep);
|
||||
if (-1 == rc)
|
||||
sandbox_free_error(ep);
|
||||
return(-1 == rc);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/* $Id: test-sqlite3.c,v 1.2 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
sqlite3 *db;
|
||||
|
||||
if (sqlite3_open_v2("test.db", &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||||
NULL) != SQLITE_OK) {
|
||||
perror("test.db");
|
||||
fprintf(stderr, "sqlite3_open_v2: %s", sqlite3_errmsg(db));
|
||||
return 1;
|
||||
}
|
||||
unlink("test.db");
|
||||
|
||||
if (sqlite3_exec(db, "PRAGMA foreign_keys = ON",
|
||||
NULL, NULL, NULL) != SQLITE_OK) {
|
||||
fprintf(stderr, "sqlite3_exec: %s", sqlite3_errmsg(db));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sqlite3_close(db) != SQLITE_OK) {
|
||||
fprintf(stderr, "sqlite3_close: %s", sqlite3_errmsg(db));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return strcmp(sqlite3_errstr(SQLITE_OK), "not an error");
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $Id: test-vasprintf.c,v 1.3 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/* $Id: test-vasprintf.c,v 1.4 2016/07/18 18:35:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -23,7 +23,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
static int testfunc(char **, const char *, ...);
|
||||
|
||||
|
||||
static int
|
||||
testfunc(char **ret, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: test-wchar.c,v 1.3 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/* $Id: test-wchar.c,v 1.4 2016/07/31 09:29:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -35,9 +35,9 @@ main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) {
|
||||
fputs("setlocale(LC_CTYPE, \"en_US.UTF-8\") failed\n",
|
||||
stderr);
|
||||
if (setlocale(LC_CTYPE, UTF8_LOCALE) == NULL) {
|
||||
fprintf(stderr, "setlocale(LC_CTYPE, \"%s\") failed\n",
|
||||
UTF8_LOCALE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
48
tree.c
48
tree.c
@ -1,7 +1,7 @@
|
||||
/* $Id: tree.c,v 1.69 2015/10/12 00:08:16 schwarze Exp $ */
|
||||
/* $Id: tree.c,v 1.72 2017/01/12 17:29:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
static void print_box(const struct eqn_box *, int);
|
||||
static void print_man(const struct roff_node *, int);
|
||||
static void print_meta(const struct roff_meta *);
|
||||
static void print_mdoc(const struct roff_node *, int);
|
||||
static void print_span(const struct tbl_span *, int);
|
||||
|
||||
@ -40,17 +41,40 @@ static void print_span(const struct tbl_span *, int);
|
||||
void
|
||||
tree_mdoc(void *arg, const struct roff_man *mdoc)
|
||||
{
|
||||
|
||||
print_meta(&mdoc->meta);
|
||||
putchar('\n');
|
||||
print_mdoc(mdoc->first->child, 0);
|
||||
}
|
||||
|
||||
void
|
||||
tree_man(void *arg, const struct roff_man *man)
|
||||
{
|
||||
|
||||
print_meta(&man->meta);
|
||||
if (man->meta.hasbody == 0)
|
||||
puts("body = empty");
|
||||
putchar('\n');
|
||||
print_man(man->first->child, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
print_meta(const struct roff_meta *meta)
|
||||
{
|
||||
if (meta->title != NULL)
|
||||
printf("title = \"%s\"\n", meta->title);
|
||||
if (meta->name != NULL)
|
||||
printf("name = \"%s\"\n", meta->name);
|
||||
if (meta->msec != NULL)
|
||||
printf("sec = \"%s\"\n", meta->msec);
|
||||
if (meta->vol != NULL)
|
||||
printf("vol = \"%s\"\n", meta->vol);
|
||||
if (meta->arch != NULL)
|
||||
printf("arch = \"%s\"\n", meta->arch);
|
||||
if (meta->os != NULL)
|
||||
printf("os = \"%s\"\n", meta->os);
|
||||
if (meta->date != NULL)
|
||||
printf("date = \"%s\"\n", meta->date);
|
||||
}
|
||||
|
||||
static void
|
||||
print_mdoc(const struct roff_node *n, int indent)
|
||||
{
|
||||
@ -159,15 +183,19 @@ print_mdoc(const struct roff_node *n, int indent)
|
||||
}
|
||||
|
||||
putchar(' ');
|
||||
if (MDOC_DELIMO & n->flags)
|
||||
if (NODE_DELIMO & n->flags)
|
||||
putchar('(');
|
||||
if (MDOC_LINE & n->flags)
|
||||
if (NODE_LINE & n->flags)
|
||||
putchar('*');
|
||||
printf("%d:%d", n->line, n->pos + 1);
|
||||
if (MDOC_DELIMC & n->flags)
|
||||
if (NODE_DELIMC & n->flags)
|
||||
putchar(')');
|
||||
if (MDOC_EOS & n->flags)
|
||||
if (NODE_EOS & n->flags)
|
||||
putchar('.');
|
||||
if (NODE_NOSRC & n->flags)
|
||||
printf(" NOSRC");
|
||||
if (NODE_NOPRT & n->flags)
|
||||
printf(" NOPRT");
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
@ -248,10 +276,10 @@ print_man(const struct roff_node *n, int indent)
|
||||
for (i = 0; i < indent; i++)
|
||||
putchar(' ');
|
||||
printf("%s (%s) ", p, t);
|
||||
if (MAN_LINE & n->flags)
|
||||
if (NODE_LINE & n->flags)
|
||||
putchar('*');
|
||||
printf("%d:%d", n->line, n->pos + 1);
|
||||
if (MAN_EOS & n->flags)
|
||||
if (NODE_EOS & n->flags)
|
||||
putchar('.');
|
||||
putchar('\n');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user