Import CVS version of mandoc as of 20141201
This commit is contained in:
parent
52c0e9552d
commit
81bffeeaab
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/mdocml/dist/; revision=275397 svn path=/vendor/mdocml/20141201/; revision=275398; tag=vendor/mandoc/20141201
93
INSTALL
93
INSTALL
@ -1,4 +1,4 @@
|
|||||||
$Id: INSTALL,v 1.2 2014/08/10 17:22:26 schwarze Exp $
|
$Id: INSTALL,v 1.5 2014/08/18 13:27:47 kristaps Exp $
|
||||||
|
|
||||||
About mdocml, the portable mandoc distribution
|
About mdocml, the portable mandoc distribution
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
@ -34,19 +34,52 @@ latest bundled and ported versions of mandoc for various operating
|
|||||||
systems is maintained at <http://mdocml.bsd.lv/ports.html>.
|
systems is maintained at <http://mdocml.bsd.lv/ports.html>.
|
||||||
|
|
||||||
If mandoc is installed, you can check the version by running "mandoc -V".
|
If mandoc is installed, you can check the version by running "mandoc -V".
|
||||||
The version contained in this distribution tarball is listed near
|
You can find the version contained in this distribution tarball
|
||||||
the beginning of the file "Makefile".
|
by running "./configure".
|
||||||
|
|
||||||
Regarding how packages and ports are maintained for your operating
|
Regarding how packages and ports are maintained for your operating
|
||||||
system, please consult your operating system documentation.
|
system, please consult your operating system documentation.
|
||||||
To install mandoc manually, the following steps are needed:
|
To install mandoc manually, the following steps are needed:
|
||||||
|
|
||||||
1. Decide whether you want to build the base tools mandoc(1),
|
1. If you want to build the CGI program, man.cgi(8), too, run the
|
||||||
preconv(1) and demandoc(1) only or whether you also want to build the
|
command "echo BUILD_CGI=1 > configure.local". Then run "cp
|
||||||
database tools apropos(1) and makewhatis(8). For the latter,
|
cgi.h.examples cgi.h" and edit cgi.h as desired.
|
||||||
the following dependencies are required:
|
|
||||||
|
|
||||||
1.1. The SQLite database system, see <http://sqlite.org/>.
|
2. 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
|
||||||
|
wish, read the file "configure.local.example", create and edit
|
||||||
|
a file "configure.local", and re-run "./configure" until the
|
||||||
|
result seems right to you.
|
||||||
|
|
||||||
|
3. 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
|
||||||
|
installed to the intended places. Otherwise, put some *DIR variables
|
||||||
|
into "configure.local" and go back to step 2.
|
||||||
|
|
||||||
|
5. 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. To set up a man.cgi(8) server, read its manual page.
|
||||||
|
|
||||||
|
7. To use mandoc(1) as your man(1) formatter, read the "Deployment"
|
||||||
|
section below.
|
||||||
|
|
||||||
|
|
||||||
|
Understanding mandoc dependencies
|
||||||
|
---------------------------------
|
||||||
|
The mandoc(1), preconv(1), and demandoc(1) utilities have no external
|
||||||
|
dependencies. However, makewhatis(8) and apropos(1) depend on the
|
||||||
|
following software:
|
||||||
|
|
||||||
|
1. The SQLite database system, see <http://sqlite.org/>.
|
||||||
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
|
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
|
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
|
older than 3.8.3 may not achieve full performance due to the
|
||||||
@ -57,47 +90,16 @@ 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.
|
older than 3.7.5 may or may not work, they have not been tested.
|
||||||
|
|
||||||
1.2. The fts(3) directory traversion functions.
|
1.2. The fts(3) directory traversion functions.
|
||||||
A compatibility version will be bundled for 1.13.2 but is not available
|
If your system does not have them, the bundled compatibility version
|
||||||
yet. If you want apropos(1) and makewhatis(8) but do not have fts(3),
|
will be used, so you need not worry in that case. But be careful: the
|
||||||
please stay with mandoc 1.12.3 for now and upgrade first to 1.12.4,
|
|
||||||
then to 1.13.2 when these versionns are released. Be careful: the
|
|
||||||
glibc version of fts(3) is known to be broken on 32bit platforms,
|
glibc version of fts(3) is known to be broken on 32bit platforms,
|
||||||
see <https://sourceware.org/bugzilla/show_bug.cgi?id=15838>.
|
see <https://sourceware.org/bugzilla/show_bug.cgi?id=15838>.
|
||||||
|
If you run into that problem, set "HAVE_FTS=0" in configure.local.
|
||||||
|
|
||||||
1.3. Marc Espie's ohash(3) library.
|
1.3. Marc Espie's ohash(3) library.
|
||||||
If your system does not have it, the bundled compatibility version
|
If your system does not have it, the bundled compatibility version
|
||||||
will be used, so you probably need not worry about it.
|
will be used, so you probably need not worry about it.
|
||||||
|
|
||||||
2. If you choose to build the database tools, too, decide whether
|
|
||||||
you also want to build the CGI program, man.cgi(8).
|
|
||||||
|
|
||||||
3. Read the beginning of the file "Makefile" from "USER SETTINGS"
|
|
||||||
to "END OF USER SETTINGS" and edit it as required. In particular,
|
|
||||||
disable "BUILD_TARGETS += db-build" if you do not want database
|
|
||||||
support or enable "BUILD_TARGETS += cgi-build" if you do want
|
|
||||||
the CGI program.
|
|
||||||
|
|
||||||
4. Run "make". No separate "./configure" or "make depend" steps
|
|
||||||
are needed. The former is run automatically by "make". The latter
|
|
||||||
is a maintainer target. If you merely want to build the released
|
|
||||||
version as opposed to doing active development, there is no need
|
|
||||||
to regenerate the dependency specifications. Any POSIX-compatible
|
|
||||||
make, in particular both BSD make and GNU make, should work.
|
|
||||||
|
|
||||||
5. Run "make -n install" and check whether everything will be
|
|
||||||
installed to the intended places. Otherwise, edit the *DIR variables
|
|
||||||
in the Makefile until it is.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
7. To set up a man.cgi(8) server, read its manual page.
|
|
||||||
|
|
||||||
8. To use mandoc(1) as your man(1) formatter, read the "Deployment"
|
|
||||||
section below.
|
|
||||||
|
|
||||||
|
|
||||||
Checking autoconfiguration quality
|
Checking autoconfiguration quality
|
||||||
----------------------------------
|
----------------------------------
|
||||||
@ -130,9 +132,9 @@ please report whatever is missing on your platform.
|
|||||||
The following steps can be used to manually check the automatic
|
The following steps can be used to manually check the automatic
|
||||||
configuration on your platform:
|
configuration on your platform:
|
||||||
|
|
||||||
1. Run "make clean".
|
1. Run "make distclean".
|
||||||
|
|
||||||
2. Run "make config.h"
|
2. Run "./configure"
|
||||||
|
|
||||||
3. Read the file "config.log". It shows the compiler commands used
|
3. Read the file "config.log". It shows the compiler commands used
|
||||||
to test the libraries installed on your system and the standard
|
to test the libraries installed on your system and the standard
|
||||||
@ -140,8 +142,7 @@ output and standard error output these commands produce. Watch out
|
|||||||
for unexpected failures. Those are most likely to happen if headers
|
for unexpected failures. Those are most likely to happen if headers
|
||||||
or libraries are installed in unusual places or interfaces defined
|
or libraries are installed in unusual places or interfaces defined
|
||||||
in unusual headers. You can also look at the file "config.h" and
|
in unusual headers. You can also look at the file "config.h" and
|
||||||
check that no expected "#define HAVE_*" lines are missing. The
|
check that no "#define HAVE_*" differ from your expectations.
|
||||||
list of tests run can be found in the file "configure".
|
|
||||||
|
|
||||||
|
|
||||||
Deployment
|
Deployment
|
||||||
|
8
LICENSE
8
LICENSE
@ -1,4 +1,4 @@
|
|||||||
$Id: LICENSE,v 1.2 2014/04/23 21:06:41 schwarze Exp $
|
$Id: LICENSE,v 1.4 2014/08/21 00:42:38 schwarze Exp $
|
||||||
|
|
||||||
With the exceptions noted below, all code and documentation
|
With the exceptions noted below, all code and documentation
|
||||||
contained in the mdocml toolkit is protected by the Copyright
|
contained in the mdocml toolkit is protected by the Copyright
|
||||||
@ -37,8 +37,10 @@ The following files included from outside sources are protected by
|
|||||||
other people's Copyright and are distributed under a 3-clause BSD
|
other people's Copyright and are distributed under a 3-clause BSD
|
||||||
license; see these individual files for details.
|
license; see these individual files for details.
|
||||||
|
|
||||||
compat_getsubopt.c, compat_strcasestr.c, compat_strsep.c:
|
compat_fts.c, compat_fts.h,
|
||||||
Copyright (c) 1990, 1993 The Regents of the University of California
|
compat_getsubopt.c, compat_strcasestr.c, compat_strsep.c,
|
||||||
|
man.1:
|
||||||
|
Copyright (c) 1989,1990,1993,1994 The Regents of the University of California
|
||||||
|
|
||||||
compat_fgetln.c:
|
compat_fgetln.c:
|
||||||
Copyright (c) 1998 The NetBSD Foundation, Inc.
|
Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
194
Makefile
194
Makefile
@ -1,4 +1,4 @@
|
|||||||
# $Id: Makefile,v 1.435 2014/08/10 02:45:04 schwarze Exp $
|
# $Id: Makefile,v 1.448 2014/11/28 18:57:31 schwarze Exp $
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
# Copyright (c) 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
# Copyright (c) 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,126 +15,31 @@
|
|||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
VERSION = 1.13.1
|
BASEBIN = mandoc demandoc
|
||||||
|
DBBIN = makewhatis
|
||||||
# === USER SETTINGS ====================================================
|
|
||||||
|
|
||||||
# --- user settings relevant for all builds ----------------------------
|
|
||||||
|
|
||||||
# Specify this if you want to hard-code the operating system to appear
|
|
||||||
# in the lower-left hand corner of -mdoc manuals.
|
|
||||||
#
|
|
||||||
# CFLAGS += -DOSNAME="\"OpenBSD 5.5\""
|
|
||||||
|
|
||||||
# IFF your system supports multi-byte functions (setlocale(), wcwidth(),
|
|
||||||
# putwchar()) AND has __STDC_ISO_10646__ (that is, wchar_t is simply a
|
|
||||||
# UCS-4 value) should you define USE_WCHAR. If you define it and your
|
|
||||||
# system DOESN'T support this, -Tlocale will produce garbage.
|
|
||||||
# If you don't define it, -Tlocale is a synonym for -Tacsii.
|
|
||||||
#
|
|
||||||
CFLAGS += -DUSE_WCHAR
|
|
||||||
|
|
||||||
CFLAGS += -g -DHAVE_CONFIG_H
|
|
||||||
CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings
|
|
||||||
PREFIX = /usr/local
|
|
||||||
BINDIR = $(PREFIX)/bin
|
|
||||||
INCLUDEDIR = $(PREFIX)/include/mandoc
|
|
||||||
LIBDIR = $(PREFIX)/lib/mandoc
|
|
||||||
MANDIR = $(PREFIX)/man
|
|
||||||
EXAMPLEDIR = $(PREFIX)/share/examples/mandoc
|
|
||||||
|
|
||||||
INSTALL = install
|
|
||||||
INSTALL_PROGRAM = $(INSTALL) -m 0555
|
|
||||||
INSTALL_DATA = $(INSTALL) -m 0444
|
|
||||||
INSTALL_LIB = $(INSTALL) -m 0444
|
|
||||||
INSTALL_SOURCE = $(INSTALL) -m 0644
|
|
||||||
INSTALL_MAN = $(INSTALL_DATA)
|
|
||||||
|
|
||||||
# --- user settings related to database support ------------------------
|
|
||||||
|
|
||||||
# Building apropos(1) and makewhatis(8) requires both SQLite3 and fts(3).
|
|
||||||
# To avoid those dependencies, comment the following line.
|
|
||||||
# Be careful: the fts(3) implementation in glibc is broken on 32bit
|
|
||||||
# machines, see: https://sourceware.org/bugzilla/show_bug.cgi?id=15838
|
|
||||||
#
|
|
||||||
BUILD_TARGETS += db-build
|
|
||||||
|
|
||||||
# The remaining settings in this section
|
|
||||||
# are only relevant if db-build is enabled.
|
|
||||||
# Otherwise, they have no effect either way.
|
|
||||||
|
|
||||||
# If your system has manpath(1), uncomment this. This is most any
|
|
||||||
# system that's not OpenBSD or NetBSD. If uncommented, apropos(1)
|
|
||||||
# and makewhatis(8) will use manpath(1) to get the MANPATH variable.
|
|
||||||
#
|
|
||||||
#CFLAGS += -DUSE_MANPATH
|
|
||||||
|
|
||||||
# On some systems, SQLite3 may be installed below /usr/local.
|
|
||||||
# In that case, uncomment the following two lines.
|
|
||||||
#
|
|
||||||
#CFLAGS += -I/usr/local/include
|
|
||||||
#DBLIB += -L/usr/local/lib
|
|
||||||
|
|
||||||
# OpenBSD has the ohash functions in libutil.
|
|
||||||
# Comment the following line if your system doesn't.
|
|
||||||
#
|
|
||||||
DBLIB += -lutil
|
|
||||||
|
|
||||||
SBINDIR = $(PREFIX)/sbin
|
|
||||||
|
|
||||||
# --- user settings related to man.cgi ---------------------------------
|
|
||||||
|
|
||||||
# To build man.cgi, copy cgi.h.example to cgi.h, edit it,
|
|
||||||
# and enable the following line.
|
|
||||||
# Obviously, this requires that db-build is enabled, too.
|
|
||||||
#
|
|
||||||
#BUILD_TARGETS += cgi-build
|
|
||||||
|
|
||||||
# The remaining settings in this section
|
|
||||||
# are only relevant if cgi-build is enabled.
|
|
||||||
# Otherwise, they have no effect either way.
|
|
||||||
|
|
||||||
# If your system does not support static binaries, comment this,
|
|
||||||
# for example on Mac OS X.
|
|
||||||
#
|
|
||||||
STATIC = -static
|
|
||||||
|
|
||||||
# Linux requires -pthread for statical linking.
|
|
||||||
#
|
|
||||||
#STATIC += -pthread
|
|
||||||
|
|
||||||
WWWPREFIX = /var/www
|
|
||||||
HTDOCDIR = $(WWWPREFIX)/htdocs
|
|
||||||
CGIBINDIR = $(WWWPREFIX)/cgi-bin
|
|
||||||
|
|
||||||
# === END OF USER SETTINGS =============================================
|
|
||||||
|
|
||||||
INSTALL_TARGETS = $(BUILD_TARGETS:-build=-install)
|
|
||||||
|
|
||||||
BASEBIN = mandoc preconv demandoc
|
|
||||||
DBBIN = apropos makewhatis
|
|
||||||
CGIBIN = man.cgi
|
CGIBIN = man.cgi
|
||||||
|
|
||||||
DBLIB += -lsqlite3
|
TESTSRCS = test-dirent-namlen.c \
|
||||||
|
test-fgetln.c \
|
||||||
TESTSRCS = test-fgetln.c \
|
test-fts.c \
|
||||||
test-getsubopt.c \
|
test-getsubopt.c \
|
||||||
test-mmap.c \
|
test-mmap.c \
|
||||||
test-ohash.c \
|
test-ohash.c \
|
||||||
test-reallocarray.c \
|
test-reallocarray.c \
|
||||||
|
test-sqlite3.c \
|
||||||
test-sqlite3_errstr.c \
|
test-sqlite3_errstr.c \
|
||||||
test-strcasestr.c \
|
test-strcasestr.c \
|
||||||
test-strlcat.c \
|
test-strlcat.c \
|
||||||
test-strlcpy.c \
|
test-strlcpy.c \
|
||||||
test-strptime.c \
|
test-strptime.c \
|
||||||
test-strsep.c
|
test-strsep.c \
|
||||||
|
test-wchar.c
|
||||||
|
|
||||||
SRCS = apropos.c \
|
SRCS = att.c \
|
||||||
arch.c \
|
|
||||||
att.c \
|
|
||||||
cgi.c \
|
cgi.c \
|
||||||
chars.c \
|
chars.c \
|
||||||
compat_fgetln.c \
|
compat_fgetln.c \
|
||||||
|
compat_fts.c \
|
||||||
compat_getsubopt.c \
|
compat_getsubopt.c \
|
||||||
compat_ohash.c \
|
compat_ohash.c \
|
||||||
compat_reallocarray.c \
|
compat_reallocarray.c \
|
||||||
@ -187,7 +92,6 @@ SRCS = apropos.c \
|
|||||||
term_ascii.c \
|
term_ascii.c \
|
||||||
term_ps.c \
|
term_ps.c \
|
||||||
tree.c \
|
tree.c \
|
||||||
vol.c \
|
|
||||||
$(TESTSRCS)
|
$(TESTSRCS)
|
||||||
|
|
||||||
DISTFILES = INSTALL \
|
DISTFILES = INSTALL \
|
||||||
@ -197,14 +101,12 @@ DISTFILES = INSTALL \
|
|||||||
NEWS \
|
NEWS \
|
||||||
TODO \
|
TODO \
|
||||||
apropos.1 \
|
apropos.1 \
|
||||||
arch.in \
|
|
||||||
att.in \
|
|
||||||
cgi.h.example \
|
cgi.h.example \
|
||||||
chars.in \
|
chars.in \
|
||||||
|
compat_fts.h \
|
||||||
compat_ohash.h \
|
compat_ohash.h \
|
||||||
config.h.post \
|
|
||||||
config.h.pre \
|
|
||||||
configure \
|
configure \
|
||||||
|
configure.local.example \
|
||||||
demandoc.1 \
|
demandoc.1 \
|
||||||
eqn.7 \
|
eqn.7 \
|
||||||
example.style.css \
|
example.style.css \
|
||||||
@ -218,6 +120,7 @@ DISTFILES = INSTALL \
|
|||||||
main.h \
|
main.h \
|
||||||
makewhatis.8 \
|
makewhatis.8 \
|
||||||
man-cgi.css \
|
man-cgi.css \
|
||||||
|
man.1 \
|
||||||
man.7 \
|
man.7 \
|
||||||
man.cgi.8 \
|
man.cgi.8 \
|
||||||
man.h \
|
man.h \
|
||||||
@ -238,7 +141,6 @@ DISTFILES = INSTALL \
|
|||||||
mdoc.h \
|
mdoc.h \
|
||||||
msec.in \
|
msec.in \
|
||||||
out.h \
|
out.h \
|
||||||
preconv.1 \
|
|
||||||
predefs.in \
|
predefs.in \
|
||||||
roff.7 \
|
roff.7 \
|
||||||
st.in \
|
st.in \
|
||||||
@ -246,7 +148,6 @@ DISTFILES = INSTALL \
|
|||||||
tbl.3 \
|
tbl.3 \
|
||||||
tbl.7 \
|
tbl.7 \
|
||||||
term.h \
|
term.h \
|
||||||
vol.in \
|
|
||||||
$(SRCS)
|
$(SRCS)
|
||||||
|
|
||||||
LIBMAN_OBJS = man.o \
|
LIBMAN_OBJS = man.o \
|
||||||
@ -254,16 +155,14 @@ LIBMAN_OBJS = man.o \
|
|||||||
man_macro.o \
|
man_macro.o \
|
||||||
man_validate.o
|
man_validate.o
|
||||||
|
|
||||||
LIBMDOC_OBJS = arch.o \
|
LIBMDOC_OBJS = att.o \
|
||||||
att.o \
|
|
||||||
lib.o \
|
lib.o \
|
||||||
mdoc.o \
|
mdoc.o \
|
||||||
mdoc_argv.o \
|
mdoc_argv.o \
|
||||||
mdoc_hash.o \
|
mdoc_hash.o \
|
||||||
mdoc_macro.o \
|
mdoc_macro.o \
|
||||||
mdoc_validate.o \
|
mdoc_validate.o \
|
||||||
st.o \
|
st.o
|
||||||
vol.o
|
|
||||||
|
|
||||||
LIBROFF_OBJS = eqn.o \
|
LIBROFF_OBJS = eqn.o \
|
||||||
roff.o \
|
roff.o \
|
||||||
@ -279,9 +178,11 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
|||||||
mandoc.o \
|
mandoc.o \
|
||||||
mandoc_aux.o \
|
mandoc_aux.o \
|
||||||
msec.o \
|
msec.o \
|
||||||
|
preconv.o \
|
||||||
read.o
|
read.o
|
||||||
|
|
||||||
COMPAT_OBJS = compat_fgetln.o \
|
COMPAT_OBJS = compat_fgetln.o \
|
||||||
|
compat_fts.o \
|
||||||
compat_getsubopt.o \
|
compat_getsubopt.o \
|
||||||
compat_ohash.o \
|
compat_ohash.o \
|
||||||
compat_reallocarray.o \
|
compat_reallocarray.o \
|
||||||
@ -314,11 +215,11 @@ MANDOC_OBJS = $(MANDOC_HTML_OBJS) \
|
|||||||
out.o \
|
out.o \
|
||||||
tree.o
|
tree.o
|
||||||
|
|
||||||
|
MAN_OBJS = $(MANDOC_OBJS)
|
||||||
|
|
||||||
MAKEWHATIS_OBJS = mandocdb.o mansearch_const.o manpath.o
|
MAKEWHATIS_OBJS = mandocdb.o mansearch_const.o manpath.o
|
||||||
|
|
||||||
PRECONV_OBJS = preconv.o
|
APROPOS_OBJS = mansearch.o mansearch_const.o manpath.o
|
||||||
|
|
||||||
APROPOS_OBJS = apropos.o mansearch.o mansearch_const.o manpath.o
|
|
||||||
|
|
||||||
CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
||||||
cgi.o \
|
cgi.o \
|
||||||
@ -332,8 +233,8 @@ DEMANDOC_OBJS = demandoc.o
|
|||||||
|
|
||||||
WWW_MANS = apropos.1.html \
|
WWW_MANS = apropos.1.html \
|
||||||
demandoc.1.html \
|
demandoc.1.html \
|
||||||
|
man.1.html \
|
||||||
mandoc.1.html \
|
mandoc.1.html \
|
||||||
preconv.1.html \
|
|
||||||
mandoc.3.html \
|
mandoc.3.html \
|
||||||
mandoc_escape.3.html \
|
mandoc_escape.3.html \
|
||||||
mandoc_html.3.html \
|
mandoc_html.3.html \
|
||||||
@ -360,9 +261,13 @@ WWW_MANS = apropos.1.html \
|
|||||||
WWW_OBJS = mdocml.tar.gz \
|
WWW_OBJS = mdocml.tar.gz \
|
||||||
mdocml.sha256
|
mdocml.sha256
|
||||||
|
|
||||||
|
include Makefile.local
|
||||||
|
|
||||||
|
INSTALL_TARGETS = $(BUILD_TARGETS:-build=-install)
|
||||||
|
|
||||||
# === DEPENDENCY HANDLING ==============================================
|
# === DEPENDENCY HANDLING ==============================================
|
||||||
|
|
||||||
all: base-build $(BUILD_TARGETS)
|
all: base-build $(BUILD_TARGETS) Makefile.local
|
||||||
|
|
||||||
base-build: $(BASEBIN)
|
base-build: $(BASEBIN)
|
||||||
|
|
||||||
@ -374,20 +279,22 @@ install: base-install $(INSTALL_TARGETS)
|
|||||||
|
|
||||||
www: $(WWW_OBJS) $(WWW_MANS)
|
www: $(WWW_OBJS) $(WWW_MANS)
|
||||||
|
|
||||||
|
$(WWW_MANS): mandoc
|
||||||
|
|
||||||
include Makefile.depend
|
include Makefile.depend
|
||||||
|
|
||||||
# === TARGETS CONTAINING SHELL COMMANDS ================================
|
# === TARGETS CONTAINING SHELL COMMANDS ================================
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile.local config.h config.h.old config.log config.log.old
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f libmandoc.a $(LIBMANDOC_OBJS)
|
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS)
|
||||||
rm -f apropos $(APROPOS_OBJS)
|
rm -f mandoc $(MANDOC_OBJS) $(APROPOS_OBJS)
|
||||||
rm -f makewhatis $(MAKEWHATIS_OBJS)
|
rm -f makewhatis $(MAKEWHATIS_OBJS)
|
||||||
rm -f preconv $(PRECONV_OBJS)
|
|
||||||
rm -f man.cgi $(CGI_OBJS)
|
rm -f man.cgi $(CGI_OBJS)
|
||||||
rm -f manpage $(MANPAGE_OBJS)
|
rm -f manpage $(MANPAGE_OBJS)
|
||||||
rm -f demandoc $(DEMANDOC_OBJS)
|
rm -f demandoc $(DEMANDOC_OBJS)
|
||||||
rm -f mandoc $(MANDOC_OBJS)
|
|
||||||
rm -f config.h config.log $(COMPAT_OBJS)
|
|
||||||
rm -f $(WWW_MANS) $(WWW_OBJS)
|
rm -f $(WWW_MANS) $(WWW_OBJS)
|
||||||
rm -rf *.dSYM
|
rm -rf *.dSYM
|
||||||
|
|
||||||
@ -403,7 +310,8 @@ base-install: base-build
|
|||||||
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
|
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
|
||||||
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \
|
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \
|
||||||
$(DESTDIR)$(INCLUDEDIR)
|
$(DESTDIR)$(INCLUDEDIR)
|
||||||
$(INSTALL_MAN) mandoc.1 preconv.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL_MAN) man.1 mandoc.1 demandoc.1 \
|
||||||
|
$(DESTDIR)$(MANDIR)/man1
|
||||||
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
|
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
|
||||||
mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
|
mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
|
||||||
$(INSTALL_MAN) man.7 mdoc.7 roff.7 eqn.7 tbl.7 mandoc_char.7 \
|
$(INSTALL_MAN) man.7 mdoc.7 roff.7 eqn.7 tbl.7 mandoc_char.7 \
|
||||||
@ -417,8 +325,8 @@ db-install: db-build
|
|||||||
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||||
mkdir -p $(DESTDIR)$(MANDIR)/man5
|
mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||||
$(INSTALL_PROGRAM) apropos $(DESTDIR)$(BINDIR)
|
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/apropos
|
||||||
ln -f $(DESTDIR)$(BINDIR)/apropos $(DESTDIR)$(BINDIR)/whatis
|
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/whatis
|
||||||
$(INSTALL_PROGRAM) makewhatis $(DESTDIR)$(SBINDIR)
|
$(INSTALL_PROGRAM) makewhatis $(DESTDIR)$(SBINDIR)
|
||||||
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
ln -f $(DESTDIR)$(MANDIR)/man1/apropos.1 \
|
ln -f $(DESTDIR)$(MANDIR)/man1/apropos.1 \
|
||||||
@ -447,30 +355,29 @@ www-install: www
|
|||||||
$(INSTALL_DATA) mdocml.sha256 \
|
$(INSTALL_DATA) mdocml.sha256 \
|
||||||
$(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256
|
$(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256
|
||||||
|
|
||||||
|
Makefile.local config.h: configure ${TESTSRCS}
|
||||||
|
@echo "$@ is out of date; please run ./configure"
|
||||||
|
@exit 1
|
||||||
|
|
||||||
depend: config.h
|
depend: config.h
|
||||||
mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
|
mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
|
||||||
perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
|
perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
|
||||||
s|\\\n||g; s| +| |g; print;' Makefile.depend > Makefile.tmp
|
s|\\\n||g; s| +| |g; s| $$||mg; print;' \
|
||||||
|
Makefile.depend > Makefile.tmp
|
||||||
mv Makefile.tmp Makefile.depend
|
mv Makefile.tmp Makefile.depend
|
||||||
|
|
||||||
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||||
$(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
$(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||||
|
|
||||||
mandoc: $(MANDOC_OBJS) libmandoc.a
|
mandoc: $(MAN_OBJS) libmandoc.a
|
||||||
$(CC) $(LDFLAGS) -o $@ $(MANDOC_OBJS) libmandoc.a
|
$(CC) $(LDFLAGS) -o $@ $(MAN_OBJS) libmandoc.a $(DBLIB)
|
||||||
|
|
||||||
makewhatis: $(MAKEWHATIS_OBJS) libmandoc.a
|
makewhatis: $(MAKEWHATIS_OBJS) libmandoc.a
|
||||||
$(CC) $(LDFLAGS) -o $@ $(MAKEWHATIS_OBJS) libmandoc.a $(DBLIB)
|
$(CC) $(LDFLAGS) -o $@ $(MAKEWHATIS_OBJS) libmandoc.a $(DBLIB)
|
||||||
|
|
||||||
preconv: $(PRECONV_OBJS)
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $(PRECONV_OBJS)
|
|
||||||
|
|
||||||
manpage: $(MANPAGE_OBJS) libmandoc.a
|
manpage: $(MANPAGE_OBJS) libmandoc.a
|
||||||
$(CC) $(LDFLAGS) -o $@ $(MANPAGE_OBJS) libmandoc.a $(DBLIB)
|
$(CC) $(LDFLAGS) -o $@ $(MANPAGE_OBJS) libmandoc.a $(DBLIB)
|
||||||
|
|
||||||
apropos: $(APROPOS_OBJS) libmandoc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $(APROPOS_OBJS) libmandoc.a $(DBLIB)
|
|
||||||
|
|
||||||
man.cgi: $(CGI_OBJS) libmandoc.a
|
man.cgi: $(CGI_OBJS) libmandoc.a
|
||||||
$(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB)
|
$(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB)
|
||||||
|
|
||||||
@ -482,18 +389,13 @@ mdocml.sha256: mdocml.tar.gz
|
|||||||
|
|
||||||
mdocml.tar.gz: $(DISTFILES)
|
mdocml.tar.gz: $(DISTFILES)
|
||||||
mkdir -p .dist/mdocml-$(VERSION)/
|
mkdir -p .dist/mdocml-$(VERSION)/
|
||||||
$(INSTALL_SOURCE) $(DISTFILES) .dist/mdocml-$(VERSION)
|
$(INSTALL) -m 0644 $(DISTFILES) .dist/mdocml-$(VERSION)
|
||||||
chmod 755 .dist/mdocml-$(VERSION)/configure
|
chmod 755 .dist/mdocml-$(VERSION)/configure
|
||||||
( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) )
|
( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) )
|
||||||
rm -rf .dist/
|
rm -rf .dist/
|
||||||
|
|
||||||
config.h: configure config.h.pre config.h.post $(TESTSRCS)
|
|
||||||
rm -f config.log
|
|
||||||
CC="$(CC)" CFLAGS="$(CFLAGS)" DBLIB="$(DBLIB)" \
|
|
||||||
VERSION="$(VERSION)" ./configure
|
|
||||||
|
|
||||||
.PHONY: base-install cgi-install db-install install www-install
|
.PHONY: base-install cgi-install db-install install www-install
|
||||||
.PHONY: clean depend
|
.PHONY: clean distclean depend
|
||||||
.SUFFIXES: .1 .3 .5 .7 .8 .h
|
.SUFFIXES: .1 .3 .5 .7 .8 .h
|
||||||
.SUFFIXES: .1.html .3.html .5.html .7.html .8.html .h.html
|
.SUFFIXES: .1.html .3.html .5.html .7.html .8.html .h.html
|
||||||
|
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
apropos.o: apropos.c config.h manpath.h mansearch.h
|
att.o: att.c config.h mdoc.h libmdoc.h
|
||||||
arch.o: arch.c config.h mdoc.h libmdoc.h arch.in
|
|
||||||
att.o: att.c config.h mdoc.h libmdoc.h att.in
|
|
||||||
cgi.o: cgi.c config.h mandoc.h mandoc_aux.h main.h manpath.h mansearch.h cgi.h
|
cgi.o: cgi.c config.h mandoc.h mandoc_aux.h main.h manpath.h mansearch.h cgi.h
|
||||||
chars.o: chars.c config.h mandoc.h mandoc_aux.h libmandoc.h chars.in
|
chars.o: chars.c config.h mandoc.h mandoc_aux.h libmandoc.h chars.in
|
||||||
compat_fgetln.o: compat_fgetln.c config.h
|
compat_fgetln.o: compat_fgetln.c config.h
|
||||||
compat_getsubopt.o: compat_getsubopt.c config.h
|
compat_fts.o: compat_fts.c config.h compat_fts.h
|
||||||
compat_ohash.o: compat_ohash.c config.h
|
compat_getsubopt.o: compat_getsubopt.c config.h
|
||||||
compat_reallocarray.o: compat_reallocarray.c config.h
|
compat_ohash.o: compat_ohash.c config.h compat_ohash.h
|
||||||
compat_sqlite3_errstr.o: compat_sqlite3_errstr.c config.h
|
compat_reallocarray.o: compat_reallocarray.c config.h
|
||||||
compat_strcasestr.o: compat_strcasestr.c config.h
|
compat_sqlite3_errstr.o: compat_sqlite3_errstr.c config.h
|
||||||
compat_strlcat.o: compat_strlcat.c config.h
|
compat_strcasestr.o: compat_strcasestr.c config.h
|
||||||
compat_strlcpy.o: compat_strlcpy.c config.h
|
compat_strlcat.o: compat_strlcat.c config.h
|
||||||
compat_strsep.o: compat_strsep.c config.h
|
compat_strlcpy.o: compat_strlcpy.c config.h
|
||||||
|
compat_strsep.o: compat_strsep.c config.h
|
||||||
demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h
|
demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h
|
||||||
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||||
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
|
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
|
||||||
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
|
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
|
||||||
html.o: html.c config.h mandoc.h mandoc_aux.h libmandoc.h out.h html.h main.h
|
html.o: html.c config.h mandoc.h mandoc_aux.h libmandoc.h out.h html.h main.h
|
||||||
lib.o: lib.c config.h mdoc.h libmdoc.h lib.in
|
lib.o: lib.c config.h mdoc.h libmdoc.h lib.in
|
||||||
main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h
|
main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h manpath.h mansearch.h
|
||||||
man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
|
man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
|
||||||
man_hash.o: man_hash.c config.h man.h mandoc.h libman.h
|
man_hash.o: man_hash.c config.h man.h mandoc.h libman.h
|
||||||
man_html.o: man_html.c config.h mandoc.h mandoc_aux.h out.h html.h man.h main.h
|
man_html.o: man_html.c config.h mandoc.h mandoc_aux.h out.h html.h man.h main.h
|
||||||
@ -27,10 +26,10 @@ man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h
|
|||||||
man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
|
man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
|
||||||
mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h
|
mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h
|
||||||
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||||
mandocdb.o: mandocdb.c config.h mdoc.h man.h mandoc.h mandoc_aux.h manpath.h mansearch.h
|
mandocdb.o: mandocdb.c config.h compat_fts.h compat_ohash.h mdoc.h man.h mandoc.h mandoc_aux.h manpath.h mansearch.h
|
||||||
manpage.o: manpage.c config.h manpath.h mansearch.h
|
manpage.o: manpage.c config.h manpath.h mansearch.h
|
||||||
manpath.o: manpath.c config.h mandoc_aux.h manpath.h
|
manpath.o: manpath.c config.h mandoc_aux.h manpath.h
|
||||||
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h manpath.h mansearch.h
|
mansearch.o: mansearch.c config.h compat_ohash.h mandoc.h mandoc_aux.h manpath.h mansearch.h
|
||||||
mansearch_const.o: mansearch_const.c config.h manpath.h mansearch.h
|
mansearch_const.o: mansearch_const.c config.h manpath.h mansearch.h
|
||||||
mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
||||||
mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
||||||
@ -42,9 +41,9 @@ mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main
|
|||||||
mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
||||||
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
||||||
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
|
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
|
||||||
preconv.o: preconv.c config.h
|
preconv.o: preconv.c config.h mandoc.h libmandoc.h
|
||||||
read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h main.h
|
read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h main.h
|
||||||
roff.o: roff.c config.h mandoc.h mandoc_aux.h libroff.h libmandoc.h predefs.in
|
roff.o: roff.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h predefs.in
|
||||||
st.o: st.c config.h mdoc.h libmdoc.h st.in
|
st.o: st.c config.h mdoc.h libmdoc.h st.in
|
||||||
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||||
tbl_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
tbl_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||||
@ -56,15 +55,18 @@ term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
|||||||
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
||||||
term_ps.o: term_ps.c config.h mandoc.h mandoc_aux.h out.h main.h term.h
|
term_ps.o: term_ps.c config.h mandoc.h mandoc_aux.h out.h main.h term.h
|
||||||
tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h
|
tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h
|
||||||
vol.o: vol.c config.h mdoc.h libmdoc.h vol.in
|
test-dirent-namlen.o: test-dirent-namlen.c
|
||||||
test-fgetln.o: test-fgetln.c
|
test-fgetln.o: test-fgetln.c
|
||||||
test-getsubopt.o: test-getsubopt.c
|
test-fts.o: test-fts.c
|
||||||
test-mmap.o: test-mmap.c
|
test-getsubopt.o: test-getsubopt.c
|
||||||
test-ohash.o: test-ohash.c
|
test-mmap.o: test-mmap.c
|
||||||
test-reallocarray.o: test-reallocarray.c
|
test-ohash.o: test-ohash.c
|
||||||
test-sqlite3_errstr.o: test-sqlite3_errstr.c
|
test-reallocarray.o: test-reallocarray.c
|
||||||
test-strcasestr.o: test-strcasestr.c
|
test-sqlite3.o: test-sqlite3.c
|
||||||
test-strlcat.o: test-strlcat.c
|
test-sqlite3_errstr.o: test-sqlite3_errstr.c
|
||||||
test-strlcpy.o: test-strlcpy.c
|
test-strcasestr.o: test-strcasestr.c
|
||||||
test-strptime.o: test-strptime.c
|
test-strlcat.o: test-strlcat.c
|
||||||
test-strsep.o: test-strsep.c
|
test-strlcpy.o: test-strlcpy.c
|
||||||
|
test-strptime.o: test-strptime.c
|
||||||
|
test-strsep.o: test-strsep.c
|
||||||
|
test-wchar.o: test-wchar.c
|
||||||
|
5
NEWS
5
NEWS
@ -1,4 +1,4 @@
|
|||||||
$Id: NEWS,v 1.5 2014/08/10 16:32:57 schwarze Exp $
|
$Id: NEWS,v 1.6 2014/08/11 01:39:00 schwarze Exp $
|
||||||
|
|
||||||
This file lists the most important changes in the mdocml.bsd.lv distribution.
|
This file lists the most important changes in the mdocml.bsd.lv distribution.
|
||||||
|
|
||||||
@ -7,9 +7,6 @@ Changes in version 1.13.1, released on August 10, 2014
|
|||||||
--- MAJOR NEW FEATURES ---
|
--- MAJOR NEW FEATURES ---
|
||||||
* A complete apropos(1)/makewhatis(8)/man.cgi(8) suite
|
* A complete apropos(1)/makewhatis(8)/man.cgi(8) suite
|
||||||
based on SQLite3 is now included.
|
based on SQLite3 is now included.
|
||||||
CAVEAT: This also requires a working fts(3) implementation.
|
|
||||||
If your system lacks that *and* you want apropos(1)/makewhatis(8),
|
|
||||||
stay with 1.12.3 for now, then go to 1.12.4 and 1.13.2.
|
|
||||||
* The roff(7) parser now provides an almost complete implementation
|
* The roff(7) parser now provides an almost complete implementation
|
||||||
of numerical expressions.
|
of numerical expressions.
|
||||||
* Warning and error messages have been improved in many ways.
|
* Warning and error messages have been improved in many ways.
|
||||||
|
176
TODO
176
TODO
@ -1,8 +1,37 @@
|
|||||||
************************************************************************
|
************************************************************************
|
||||||
* Official mandoc TODO.
|
* Official mandoc TODO.
|
||||||
* $Id: TODO,v 1.176 2014/08/09 14:24:53 schwarze Exp $
|
* $Id: TODO,v 1.189 2014/11/26 21:40:17 schwarze Exp $
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
|
Many issues are annotated for difficulty as follows:
|
||||||
|
|
||||||
|
- loc = locality of the issue
|
||||||
|
* single file issue, affects file only, or very few
|
||||||
|
** single module issue, affects several files of one module
|
||||||
|
*** cross-module issue, significantly impacts multiple modules
|
||||||
|
and may require substantial changes to internal interfaces
|
||||||
|
- exist = difficulty of the existing code in this area
|
||||||
|
* affected code is straightforward and easy to read and change
|
||||||
|
** affected code is somewhat complex, but once you understand
|
||||||
|
the design, not particularly difficult to understand
|
||||||
|
*** affected code uses a special, exceptionally tricky design
|
||||||
|
- algo = difficulty of the new algorithm to be written
|
||||||
|
* the required logic and code is straightforward
|
||||||
|
** the required logic is somewhat complex and needs a careful design
|
||||||
|
*** the required logic is exceptionally tricky,
|
||||||
|
maybe an approach to solve that is not even known yet
|
||||||
|
- size = the amount of code to be written or changed
|
||||||
|
* a small number of lines (at most 100, usually much less)
|
||||||
|
** a considerable amount of code (several dozen to a few hundred)
|
||||||
|
*** a large amount of code (many hundreds, maybe thousands)
|
||||||
|
- imp = importance of the issue
|
||||||
|
* mostly for completeness
|
||||||
|
** would be nice to have
|
||||||
|
*** issue causes considerable inconvenience
|
||||||
|
|
||||||
|
Obviously, as the issues have not been solved yet, these annotations
|
||||||
|
are mere guesses, and some may be wrong.
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* crashes
|
* crashes
|
||||||
************************************************************************
|
************************************************************************
|
||||||
@ -10,6 +39,7 @@
|
|||||||
- The abort() in bufcat(), html.c, can be triggered via buffmt_includes()
|
- The abort() in bufcat(), html.c, can be triggered via buffmt_includes()
|
||||||
by running -Thtml -Oincludes on a file containing a long .In argument.
|
by running -Thtml -Oincludes on a file containing a long .In argument.
|
||||||
Fixing this will probably require reworking the whole bufcat() concept.
|
Fixing this will probably require reworking the whole bufcat() concept.
|
||||||
|
loc ** exist * algo * size ** imp **
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* missing features
|
* missing features
|
||||||
@ -25,49 +55,62 @@
|
|||||||
.na -- temporarily disable adjustment without changing the mode
|
.na -- temporarily disable adjustment without changing the mode
|
||||||
.ad -- re-enable adjustment without changing the mode
|
.ad -- re-enable adjustment without changing the mode
|
||||||
Adjustment mode is ignored while in no-fill mode (.nf).
|
Adjustment mode is ignored while in no-fill mode (.nf).
|
||||||
|
loc *** exist *** algo ** size ** imp ** (parser reorg would help)
|
||||||
|
|
||||||
- .fc (field control)
|
- .fc (field control)
|
||||||
found by naddy@ in xloadimage(1)
|
found by naddy@ in xloadimage(1)
|
||||||
|
loc ** exist *** algo * size * imp *
|
||||||
|
|
||||||
- .nr third argument (auto-increment step size, requires \n+)
|
- .nr third argument (auto-increment step size, requires \n+)
|
||||||
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
||||||
|
loc * exist * algo * size * imp **
|
||||||
|
|
||||||
- .ns (no-space mode) occurs in xine-config(1)
|
- .ns (no-space mode) occurs in xine-config(1)
|
||||||
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
||||||
|
loc *** exist *** algo *** size ** imp *
|
||||||
|
|
||||||
- .ta (tab settings) occurs in ircbug(1) and probably gnats(1)
|
- .ta (tab settings) occurs in ircbug(1) and probably gnats(1)
|
||||||
reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500
|
reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500
|
||||||
also Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
also Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
||||||
|
loc ** exist *** algo ** size ** imp **
|
||||||
|
|
||||||
- .ti (temporary indent)
|
- .ti (temporary indent)
|
||||||
found by naddy@ in xloadimage(1)
|
found by naddy@ in xloadimage(1)
|
||||||
found by bentley@ in nmh(1) Mon, 23 Apr 2012 13:38:28 -0600
|
found by bentley@ in nmh(1) Mon, 23 Apr 2012 13:38:28 -0600
|
||||||
|
loc ** exist ** algo ** size * imp ** (parser reorg helps a lot)
|
||||||
|
|
||||||
- .while and .shift
|
- .while and .shift
|
||||||
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
||||||
|
loc * exist ** algo ** size ** imp **
|
||||||
|
|
||||||
- \c (interrupted text) should prevent the line break
|
- \c (interrupted text) should prevent the line break
|
||||||
even inside .Bd literal; that occurs in chat(8)
|
even inside .Bd literal; that occurs in chat(8)
|
||||||
also found in cclive(1) - DocBook output
|
also found in cclive(1) - DocBook output
|
||||||
|
loc ** exist *** algo ** size * imp *
|
||||||
|
|
||||||
- \h horizontal move
|
- \h horizontal move
|
||||||
found in cclive(1) DocBook output
|
found in cclive(1) DocBook output
|
||||||
Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
|
Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
|
||||||
|
loc ** exist ** algo ** size * imp ** (parser reorg helps a lot)
|
||||||
|
|
||||||
- \n+ and \n- numerical register increment and decrement
|
- \n+ and \n- numerical register increment and decrement
|
||||||
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
||||||
|
loc * exist * algo * size * imp **
|
||||||
|
|
||||||
- \w'' width measurements
|
- \w'' improve width measurements
|
||||||
would not be very useful without an expression parser, see below
|
would not be very useful without an expression parser, see below
|
||||||
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
||||||
|
loc ** exist *** algo *** size * imp ***
|
||||||
|
|
||||||
- using undefined strings or macros defines them to be empty
|
- using undefined strings or macros defines them to be empty
|
||||||
wl@ Mon, 14 Nov 2011 14:37:01 +0000
|
wl@ Mon, 14 Nov 2011 14:37:01 +0000
|
||||||
|
loc * exist * algo * size * imp *
|
||||||
|
|
||||||
--- missing mdoc features ----------------------------------------------
|
--- missing mdoc features ----------------------------------------------
|
||||||
|
|
||||||
- fix bad block nesting involving multiple identical explicit blocks
|
- fix bad block nesting involving multiple identical explicit blocks
|
||||||
see the OpenBSD mdoc_macro.c 1.47 commit message
|
see the OpenBSD mdoc_macro.c 1.47 commit message
|
||||||
|
loc * exist *** algo *** size * imp **
|
||||||
|
|
||||||
- .Bl -column .Xo support is missing
|
- .Bl -column .Xo support is missing
|
||||||
ultimate goal:
|
ultimate goal:
|
||||||
@ -75,10 +118,12 @@
|
|||||||
lib/libc/compat-43/sigvec.3
|
lib/libc/compat-43/sigvec.3
|
||||||
lib/libc/gen/signal.3
|
lib/libc/gen/signal.3
|
||||||
lib/libc/sys/sigaction.2
|
lib/libc/sys/sigaction.2
|
||||||
|
loc * exist *** algo *** size * imp **
|
||||||
|
|
||||||
- edge case: decide how to deal with blk_full bad nesting, e.g.
|
- edge case: decide how to deal with blk_full bad nesting, e.g.
|
||||||
.Sh .Nm .Bk .Nm .Ek .Sh found by jmc@ in ssh-keygen(1)
|
.Sh .Nm .Bk .Nm .Ek .Sh found by jmc@ in ssh-keygen(1)
|
||||||
from jmc@ Wed, 14 Jul 2010 18:10:32 +0100
|
from jmc@ Wed, 14 Jul 2010 18:10:32 +0100
|
||||||
|
loc * exist *** algo *** size ** imp **
|
||||||
|
|
||||||
- \\ is now implemented correctly
|
- \\ is now implemented correctly
|
||||||
* when defining strings and macros using .ds and .de
|
* when defining strings and macros using .ds and .de
|
||||||
@ -92,18 +137,22 @@
|
|||||||
we don't have either.
|
we don't have either.
|
||||||
Besides, groff has bug causing text right *before* .Bd -centered
|
Besides, groff has bug causing text right *before* .Bd -centered
|
||||||
to be centered as well.
|
to be centered as well.
|
||||||
|
loc *** exist *** algo ** size ** imp ** (parser reorg would help)
|
||||||
|
|
||||||
- .Bd -filled should not be the same as .Bd -ragged, but align both
|
- .Bd -filled should not be the same as .Bd -ragged, but align both
|
||||||
the left and right margin. In groff, it is implemented in terms
|
the left and right margin. In groff, it is implemented in terms
|
||||||
of .ad b, which we don't have either. Found in cksum(1).
|
of .ad b, which we don't have either. Found in cksum(1).
|
||||||
|
loc *** exist *** algo ** size ** imp ** (parser reorg would help)
|
||||||
|
|
||||||
- implement blank `Bl -column', such as
|
- implement blank `Bl -column', such as
|
||||||
.Bl -column
|
.Bl -column
|
||||||
.It foo Ta bar
|
.It foo Ta bar
|
||||||
.El
|
.El
|
||||||
|
loc * exist *** algo *** size * imp *
|
||||||
|
|
||||||
- explicitly disallow nested `Bl -column', which would clobber internal
|
- explicitly disallow nested `Bl -column', which would clobber internal
|
||||||
flags defined for struct mdoc_macro
|
flags defined for struct mdoc_macro
|
||||||
|
loc * exist * algo * size * imp **
|
||||||
|
|
||||||
- In .Bl -column .It, the end of the line probably has to be regarded
|
- In .Bl -column .It, the end of the line probably has to be regarded
|
||||||
as an implicit .Ta, if there could be one, see the following mildly
|
as an implicit .Ta, if there could be one, see the following mildly
|
||||||
@ -114,6 +163,7 @@
|
|||||||
Default search path.
|
Default search path.
|
||||||
reported by Michal Mazurek <akfaew at jasminek dot net>
|
reported by Michal Mazurek <akfaew at jasminek dot net>
|
||||||
via jmc@ Thu, 7 Apr 2011 16:00:53 +0059
|
via jmc@ Thu, 7 Apr 2011 16:00:53 +0059
|
||||||
|
loc * exist *** algo ** size * imp **
|
||||||
|
|
||||||
- inside `.Bl -column' phrases, punctuation is handled like normal
|
- inside `.Bl -column' phrases, punctuation is handled like normal
|
||||||
text, e.g. `.Bl -column .It Fl x . Ta ...' should give "-x -."
|
text, e.g. `.Bl -column .It Fl x . Ta ...' should give "-x -."
|
||||||
@ -123,11 +173,14 @@
|
|||||||
but should give "ab ."
|
but should give "ab ."
|
||||||
|
|
||||||
- set a meaningful default if no `Bl' list type is assigned
|
- set a meaningful default if no `Bl' list type is assigned
|
||||||
|
loc * exist * algo * size * imp ** (already done?)
|
||||||
|
|
||||||
- have a blank `It' head for `Bl -tag' not puke
|
- have a blank `It' head for `Bl -tag' not puke
|
||||||
|
loc * exist * algo * size * imp ** (already done?)
|
||||||
|
|
||||||
- check whether it is correct that `D1' uses INDENT+1;
|
- check whether it is correct that `D1' uses INDENT+1;
|
||||||
does it need its own constant?
|
does it need its own constant?
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- prohibit `Nm' from having non-text HEAD children
|
- prohibit `Nm' from having non-text HEAD children
|
||||||
(e.g., NetBSD mDNSShared/dns-sd.1)
|
(e.g., NetBSD mDNSShared/dns-sd.1)
|
||||||
@ -138,6 +191,7 @@
|
|||||||
that one uses NOMBRE because it is spanish...
|
that one uses NOMBRE because it is spanish...
|
||||||
deraadt tends to think that section-dependent macro behaviour
|
deraadt tends to think that section-dependent macro behaviour
|
||||||
is a bad idea in the first place, so this may be irrelevant
|
is a bad idea in the first place, so this may be irrelevant
|
||||||
|
loc ** exist ** algo ** size * imp **
|
||||||
|
|
||||||
- When there is free text in the SYNOPSIS and that free text contains
|
- When there is free text in the SYNOPSIS and that free text contains
|
||||||
the .Nm macro, groff somehow understands to treat the .Nm as an in-line
|
the .Nm macro, groff somehow understands to treat the .Nm as an in-line
|
||||||
@ -146,6 +200,7 @@
|
|||||||
should be, needs investigation.
|
should be, needs investigation.
|
||||||
uqs@ Thu, 2 Jun 2011 11:03:51 +0200
|
uqs@ Thu, 2 Jun 2011 11:03:51 +0200
|
||||||
uqs@ Thu, 2 Jun 2011 11:33:35 +0200
|
uqs@ Thu, 2 Jun 2011 11:33:35 +0200
|
||||||
|
loc * exist ** algo *** size * imp **
|
||||||
|
|
||||||
--- missing man features -----------------------------------------------
|
--- missing man features -----------------------------------------------
|
||||||
|
|
||||||
@ -155,18 +210,36 @@
|
|||||||
|
|
||||||
- look at the POSIX manuals in the books/man-pages-posix port,
|
- look at the POSIX manuals in the books/man-pages-posix port,
|
||||||
they use some unsupported tbl(7) features.
|
they use some unsupported tbl(7) features.
|
||||||
|
loc * exist ** algo ** size ** imp ***
|
||||||
|
|
||||||
- investigate tbl(1) errors in sox(1)
|
- use Unicode U+2500 to U+256C for table borders
|
||||||
see also naddy@ Sat, 16 Oct 2010 23:51:57 +0200
|
in tbl(7) -Tutf-8 output
|
||||||
|
suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600
|
||||||
|
loc * exist ** algo * size * imp **
|
||||||
|
|
||||||
- allow standalone `.' to be interpreted as an end-of-layout
|
- allow standalone `.' to be interpreted as an end-of-layout
|
||||||
delimiter instead of being thrown away as a no-op roff line
|
delimiter instead of being thrown away as a no-op roff line
|
||||||
reported by Yuri Pankov, Wed 18 May 2011 11:34:59 CEST
|
reported by Yuri Pankov, Wed 18 May 2011 11:34:59 CEST
|
||||||
|
loc ** exist ** algo ** size * imp **
|
||||||
|
|
||||||
|
--- missing eqn features -----------------------------------------------
|
||||||
|
|
||||||
|
- The "size" keyword is parsed, but ignored by the formatter.
|
||||||
|
loc * exist * algo * size * imp *
|
||||||
|
|
||||||
|
- The spacing characters `~', `^', and tab are currently ignored,
|
||||||
|
see User's Guide (Second Edition) page 2 section 4.
|
||||||
|
loc * exist * algo ** size * imp **
|
||||||
|
|
||||||
|
- Mark and lineup are parsed and ignored,
|
||||||
|
see User's Guide (Second Edition) page 5 section 15.
|
||||||
|
loc ** exist ** algo ** size ** imp **
|
||||||
|
|
||||||
--- missing misc features ----------------------------------------------
|
--- missing misc features ----------------------------------------------
|
||||||
|
|
||||||
- italic correction (\/) in PostScript mode
|
- italic correction (\/) in PostScript mode
|
||||||
Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46
|
Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46
|
||||||
|
loc ** exist ** algo * size * imp *
|
||||||
|
|
||||||
- When makewhatis(8) encounters a FATAL parse error,
|
- When makewhatis(8) encounters a FATAL parse error,
|
||||||
it silently treats the file as formatted, which makes no sense
|
it silently treats the file as formatted, which makes no sense
|
||||||
@ -174,13 +247,16 @@
|
|||||||
what the manual says at the end of the description.
|
what the manual says at the end of the description.
|
||||||
The end result will be ENOENT for file names returned
|
The end result will be ENOENT for file names returned
|
||||||
by mansearch() in manpage.file.
|
by mansearch() in manpage.file.
|
||||||
|
loc * exist * algo * size * imp **
|
||||||
|
|
||||||
- makewhatis(8) for preformatted pages:
|
- makewhatis(8) for preformatted pages:
|
||||||
parse the section number from the header line
|
parse the section number from the header line
|
||||||
and compare to the section number from the directory name
|
and compare to the section number from the directory name
|
||||||
|
loc * exist * algo * size * imp **
|
||||||
|
|
||||||
- Does makewhatis(8) detect missing NAME sections, missing names,
|
- Does makewhatis(8) detect missing NAME sections, missing names,
|
||||||
and missing descriptions in all the file formats?
|
and missing descriptions in all the file formats?
|
||||||
|
loc * exist * algo * size * imp ***
|
||||||
|
|
||||||
- clean up escape sequence handling, creating three classes:
|
- clean up escape sequence handling, creating three classes:
|
||||||
(1) fully implemented, or parsed and ignored without loss of content
|
(1) fully implemented, or parsed and ignored without loss of content
|
||||||
@ -188,8 +264,10 @@
|
|||||||
or serious mangling of formatting (e.g. \n) -> ERROR
|
or serious mangling of formatting (e.g. \n) -> ERROR
|
||||||
see textproc/mgdiff(1) for nice examples
|
see textproc/mgdiff(1) for nice examples
|
||||||
(3) undefined, just output the character -> perhaps WARNING
|
(3) undefined, just output the character -> perhaps WARNING
|
||||||
|
loc *** exist ** algo ** size ** imp *** (parser reorg helps)
|
||||||
|
|
||||||
- kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET)
|
- kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET)
|
||||||
|
loc ** exist ** algo ** size *** imp *
|
||||||
|
|
||||||
--- compatibility checks -----------------------------------------------
|
--- compatibility checks -----------------------------------------------
|
||||||
|
|
||||||
@ -199,6 +277,10 @@
|
|||||||
- compare output to Heirloom roff, Solaris roff, and
|
- compare output to Heirloom roff, Solaris roff, and
|
||||||
http://repo.or.cz/w/neatroff.git http://litcave.rudi.ir/
|
http://repo.or.cz/w/neatroff.git http://litcave.rudi.ir/
|
||||||
|
|
||||||
|
- look at AT&T DWB http://www2.research.att.com/sw/download
|
||||||
|
Carsten Kunze <carsten dot kunze at arcor dot de> has patches
|
||||||
|
Mon, 4 Aug 2014 17:01:28 +0200
|
||||||
|
|
||||||
- look at pages generated from reStructeredText, e.g. devel/mercurial hg(1)
|
- look at pages generated from reStructeredText, e.g. devel/mercurial hg(1)
|
||||||
These are a weird mixture of man(7) and custom autogenerated low-level
|
These are a weird mixture of man(7) and custom autogenerated low-level
|
||||||
roff stuff. Figure out to what extent we can cope.
|
roff stuff. Figure out to what extent we can cope.
|
||||||
@ -224,6 +306,11 @@
|
|||||||
- check compatibility with the man(7) formatter
|
- check compatibility with the man(7) formatter
|
||||||
https://raw.githubusercontent.com/rofl0r/hardcore-utils/master/man.c
|
https://raw.githubusercontent.com/rofl0r/hardcore-utils/master/man.c
|
||||||
|
|
||||||
|
- check compatibility with
|
||||||
|
http://ikiwiki.info/plugins/contrib/mandoc/
|
||||||
|
https://github.com/schmonz/ikiwiki/compare/mandoc
|
||||||
|
Amitai Schlair Mon, 19 May 2014 14:05:53 -0400
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* formatting issues: ugly output
|
* formatting issues: ugly output
|
||||||
************************************************************************
|
************************************************************************
|
||||||
@ -236,10 +323,12 @@
|
|||||||
ought to render "Key Length" with emphasis, too,
|
ought to render "Key Length" with emphasis, too,
|
||||||
see OpenBSD iked.conf(5).
|
see OpenBSD iked.conf(5).
|
||||||
reported again Nicolas Joly via wiz@ Wed, 12 Oct 2011 00:20:00 +0200
|
reported again Nicolas Joly via wiz@ Wed, 12 Oct 2011 00:20:00 +0200
|
||||||
|
loc * exist *** algo *** size ** imp ***
|
||||||
|
|
||||||
- empty phrases in .Bl column produce too few blanks
|
- empty phrases in .Bl column produce too few blanks
|
||||||
try e.g. .Bl -column It Ta Ta
|
try e.g. .Bl -column It Ta Ta
|
||||||
reported by millert Fri, 02 Apr 2010 16:13:46 -0400
|
reported by millert Fri, 02 Apr 2010 16:13:46 -0400
|
||||||
|
loc * exist *** algo *** size * imp **
|
||||||
|
|
||||||
- .%T can have trailing punctuation. Currently, it puts the trailing
|
- .%T can have trailing punctuation. Currently, it puts the trailing
|
||||||
punctuation into a trailing MDOC_TEXT element inside its own scope.
|
punctuation into a trailing MDOC_TEXT element inside its own scope.
|
||||||
@ -249,11 +338,13 @@
|
|||||||
slurp all arguments into one single text element - and one feature
|
slurp all arguments into one single text element - and one feature
|
||||||
of in_line() - put trailing punctuation out of scope.
|
of in_line() - put trailing punctuation out of scope.
|
||||||
Found in mount_nfs(8) and exports(5), search for "Appendix".
|
Found in mount_nfs(8) and exports(5), search for "Appendix".
|
||||||
|
loc ** exist ** algo *** size * imp **
|
||||||
|
|
||||||
- Trailing punctuation after .%T triggers EOS spacing, at least
|
- Trailing punctuation after .%T triggers EOS spacing, at least
|
||||||
outside .Rs (eek!). Simply setting ARGSFL_DELIM for .%T is not
|
outside .Rs (eek!). Simply setting ARGSFL_DELIM for .%T is not
|
||||||
the right solution, it sends mandoc into an endless loop.
|
the right solution, it sends mandoc into an endless loop.
|
||||||
reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100
|
reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- global variables in the SYNOPSIS of section 3 pages
|
- global variables in the SYNOPSIS of section 3 pages
|
||||||
.Vt vs .Vt/.Va vs .Ft/.Va vs .Ft/.Fa ...
|
.Vt vs .Vt/.Va vs .Ft/.Va vs .Ft/.Fa ...
|
||||||
@ -261,6 +352,7 @@
|
|||||||
|
|
||||||
- in enclosures, mandoc sometimes fancies a bogus end of sentence
|
- in enclosures, mandoc sometimes fancies a bogus end of sentence
|
||||||
reminded by jmc@ Thu, 23 Sep 2010 18:13:39 +0059
|
reminded by jmc@ Thu, 23 Sep 2010 18:13:39 +0059
|
||||||
|
loc * exist ** algo *** size * imp ***
|
||||||
|
|
||||||
- formatting /usr/local/man/man1/latex2man.1 with groff and mandoc
|
- formatting /usr/local/man/man1/latex2man.1 with groff and mandoc
|
||||||
reveals lots of bugs both in groff and mandoc...
|
reveals lots of bugs both in groff and mandoc...
|
||||||
@ -273,6 +365,10 @@
|
|||||||
Search the text "Routing tables".
|
Search the text "Routing tables".
|
||||||
Also check what PostScript mode does when fixing this.
|
Also check what PostScript mode does when fixing this.
|
||||||
reported by juanfra@ Wed, 04 Jun 2014 21:44:58 +0200
|
reported by juanfra@ Wed, 04 Jun 2014 21:44:58 +0200
|
||||||
|
instructions from juanfra@ Wed, 11 Jun 2014 02:21:01 +0200
|
||||||
|
add a new <</Type /Font>> block to the PDF files with /BaseFont /Courier
|
||||||
|
and change the /Name from /F0 to the new font (/F5 (?)).
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
--- HTML issues --------------------------------------------------------
|
--- HTML issues --------------------------------------------------------
|
||||||
|
|
||||||
@ -280,6 +376,20 @@
|
|||||||
hints are easy to find on the web, e.g.
|
hints are easy to find on the web, e.g.
|
||||||
http://stackoverflow.com/questions/1713048/
|
http://stackoverflow.com/questions/1713048/
|
||||||
see also matthew@ Fri, 18 Jul 2014 19:25:12 -0700
|
see also matthew@ Fri, 18 Jul 2014 19:25:12 -0700
|
||||||
|
loc * exist * algo ** size * imp ***
|
||||||
|
|
||||||
|
- jsg on icb, Nov 3, 2014:
|
||||||
|
try to guess Xr in man(7) for hyperlinking
|
||||||
|
|
||||||
|
- The tables used to render the three-part page headers actually force
|
||||||
|
the width of the <body> to the max-width given for <html>.
|
||||||
|
Not yet sure how to fix that...
|
||||||
|
Observed by an Anonymous Coward on undeadly.org:
|
||||||
|
http://undeadly.org/cgi?action=article&sid=20140925064244&pid=1
|
||||||
|
loc * exist * algo ** size * imp ***
|
||||||
|
|
||||||
|
- consider whether <var> can be used for Ar Dv Er Ev Fa Va.
|
||||||
|
from bentley@ Wed, 13 Aug 2014 09:17:55 -0600
|
||||||
|
|
||||||
- check https://github.com/trentm/mdocml
|
- check https://github.com/trentm/mdocml
|
||||||
|
|
||||||
@ -287,42 +397,57 @@
|
|||||||
* formatting issues: gratuitous differences
|
* formatting issues: gratuitous differences
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
|
- .Fn reopens a new scope after punctuation in mandoc,
|
||||||
|
but closes its scope for good in groff.
|
||||||
|
Do we want to change mandoc or groff?
|
||||||
|
Steffen Nurpmeso Sat, 08 Nov 2014 13:34:59 +0100
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- .Rv (and probably .Ex) print different text if an `Nm' has been named
|
- .Rv (and probably .Ex) print different text if an `Nm' has been named
|
||||||
or not (run a manual without `Nm blah' to see this). I'm not sure
|
or not (run a manual without `Nm blah' to see this). I'm not sure
|
||||||
that this exists in the wild, but it's still an error.
|
that this exists in the wild, but it's still an error.
|
||||||
|
loc * exist * algo * size * imp * (already done?)
|
||||||
|
|
||||||
- In .Bl -bullet, the groff bullet is "+\b+\bo\bo", the mandoc bullet
|
- In .Bl -bullet, the groff bullet is "+\b+\bo\bo", the mandoc bullet
|
||||||
is just "o\bo".
|
is just "o\bo". The problem is to not break ps/pdf when fixing.
|
||||||
see for example OpenBSD ksh(1)
|
see for example OpenBSD ksh(1)
|
||||||
|
loc ** exist ** algo ** size * imp **
|
||||||
|
|
||||||
- In .Bl -enum -width 0n, groff continues one the same line after
|
- In .Bl -enum -width 0n, groff continues one the same line after
|
||||||
the number, mandoc breaks the line.
|
the number, mandoc breaks the line.
|
||||||
mail to kristaps@ Mon, 20 Jul 2009 02:21:39 +0200
|
mail to kristaps@ Mon, 20 Jul 2009 02:21:39 +0200
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- .Pp between two .It in .Bl -column should produce one,
|
- .Pp between two .It in .Bl -column should produce one,
|
||||||
not two blank lines, see e.g. login.conf(5).
|
not two blank lines, see e.g. login.conf(5).
|
||||||
reported by jmc@ Sun, 17 Apr 2011 14:04:58 +0059
|
reported by jmc@ Sun, 17 Apr 2011 14:04:58 +0059
|
||||||
reported again by sthen@ Wed, 18 Jan 2012 02:09:39 +0000 (UTC)
|
reported again by sthen@ Wed, 18 Jan 2012 02:09:39 +0000 (UTC)
|
||||||
|
loc * exist *** algo ** size * imp **
|
||||||
|
|
||||||
- If the *first* line after .It is .Pp, break the line right after
|
- If the *first* line after .It is .Pp, break the line right after
|
||||||
the tag, do not pad with space characters before breaking.
|
the tag, do not pad with space characters before breaking.
|
||||||
See the description of the a, c, and i commands in sed(1).
|
See the description of the a, c, and i commands in sed(1).
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- If the first line after .It is .D1, do not assert a blank line
|
- If the first line after .It is .D1, do not assert a blank line
|
||||||
in between, see for example tmux(1).
|
in between, see for example tmux(1).
|
||||||
reported by nicm@ 13 Jan 2011 00:18:57 +0000
|
reported by nicm@ 13 Jan 2011 00:18:57 +0000
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- Trailing punctuation after .It should trigger EOS spacing.
|
- Trailing punctuation after .It should trigger EOS spacing.
|
||||||
reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100
|
reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100
|
||||||
Probably, this should be fixed somewhere in termp_it_pre(), not sure.
|
Probably, this should be fixed somewhere in termp_it_pre(), not sure.
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
- .Nx 1.0a
|
- .Nx 1.0a
|
||||||
should be "NetBSD 1.0A", not "NetBSD 1.0a",
|
should be "NetBSD 1.0A", not "NetBSD 1.0a",
|
||||||
see OpenBSD ccdconfig(8).
|
see OpenBSD ccdconfig(8).
|
||||||
|
loc * exist * algo * size * imp **
|
||||||
|
|
||||||
- In .Bl -tag, if a tag exceeds the right margin and must be continued
|
- In .Bl -tag, if a tag exceeds the right margin and must be continued
|
||||||
on the next line, it must be indented by -width, not width+1;
|
on the next line, it must be indented by -width, not width+1;
|
||||||
see "rule block|pass" in OpenBSD ifconfig(8).
|
see "rule block|pass" in OpenBSD ifconfig(8).
|
||||||
|
loc * exist *** algo ** size * imp **
|
||||||
|
|
||||||
- When the -width string contains macros, the macros must be rendered
|
- When the -width string contains macros, the macros must be rendered
|
||||||
before measuring the width, for example
|
before measuring the width, for example
|
||||||
@ -332,17 +457,21 @@
|
|||||||
The same applies to .Bl -column column widths;
|
The same applies to .Bl -column column widths;
|
||||||
reported again by Nicolas Joly Thu, 1 Mar 2012 13:41:26 +0100 via wiz@ 5 Mar
|
reported again by Nicolas Joly Thu, 1 Mar 2012 13:41:26 +0100 via wiz@ 5 Mar
|
||||||
reported again by Franco Fichtner Fri, 27 Sep 2013 21:02:28 +0200
|
reported again by Franco Fichtner Fri, 27 Sep 2013 21:02:28 +0200
|
||||||
|
loc *** exist *** algo *** size ** imp ***
|
||||||
An easy partial fix would be to just skip the first word if it starts
|
An easy partial fix would be to just skip the first word if it starts
|
||||||
with a dot, including any following white space, when measuring.
|
with a dot, including any following white space, when measuring.
|
||||||
|
loc * exist * algo * size * imp ***
|
||||||
|
|
||||||
- The \& zero-width character counts as output.
|
- The \& zero-width character counts as output.
|
||||||
That is, when it is alone on a line between two .Pp,
|
That is, when it is alone on a line between two .Pp,
|
||||||
we want three blank lines, not two as in mandoc.
|
we want three blank lines, not two as in mandoc.
|
||||||
|
loc ** exist ** algo ** size * imp **
|
||||||
|
|
||||||
- Header lines of excessive length:
|
- Header lines of excessive length:
|
||||||
Port OpenBSD man_term.c rev. 1.25 to mdoc_term.c
|
Port OpenBSD man_term.c rev. 1.25 to mdoc_term.c
|
||||||
and document it in mdoc(7) and man(7) COMPATIBILITY
|
and document it in mdoc(7) and man(7) COMPATIBILITY
|
||||||
found while talking to Chris Bennett
|
found while talking to Chris Bennett
|
||||||
|
loc * exist * algo * size * imp *
|
||||||
|
|
||||||
- trailing whitespace must be ignored even when followed by a font escape,
|
- trailing whitespace must be ignored even when followed by a font escape,
|
||||||
see for example
|
see for example
|
||||||
@ -350,6 +479,7 @@
|
|||||||
\fBdig \fR
|
\fBdig \fR
|
||||||
operate in batch mode
|
operate in batch mode
|
||||||
in dig(1).
|
in dig(1).
|
||||||
|
loc ** exist ** algo ** size * imp **
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* warning issues
|
* warning issues
|
||||||
@ -361,17 +491,29 @@
|
|||||||
to refer to fill mode, not literal mode
|
to refer to fill mode, not literal mode
|
||||||
See the mail from Werner LEMBERG on the groff list,
|
See the mail from Werner LEMBERG on the groff list,
|
||||||
Fri, 14 Feb 2014 18:54:42 +0100 (CET)
|
Fri, 14 Feb 2014 18:54:42 +0100 (CET)
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
|
- warn about attempts to call non-callable macros
|
||||||
|
Steffen Nurpmeso Tue, 11 Nov 2014 22:55:16 +0100
|
||||||
|
Note that formatting is inconsistent in groff.
|
||||||
|
.Fn Po prints "Po()", .Ar Sh prints "file ..." and no "Sh".
|
||||||
|
Relatively hard because the relevant code is scattered
|
||||||
|
all over mdoc_macro.c and all subtly different.
|
||||||
|
loc ** exist ** algo ** size ** imp **
|
||||||
|
|
||||||
- warn about "new sentence, new line"
|
- warn about "new sentence, new line"
|
||||||
|
loc ** exist ** algo *** size * imp **
|
||||||
|
|
||||||
- mandoc_special does not really check the escape sequence,
|
- mandoc_special does not really check the escape sequence,
|
||||||
but just the overall format
|
but just the overall format
|
||||||
|
loc ** exist ** algo *** size ** imp **
|
||||||
|
|
||||||
- integrate mdoclint into mandoc ("end-of-line whitespace" thread)
|
- integrate mdoclint into mandoc ("end-of-line whitespace" thread)
|
||||||
from jmc@ Mon, 13 Jul 2009 17:12:09 +0100
|
from jmc@ Mon, 13 Jul 2009 17:12:09 +0100
|
||||||
from kristaps@ Mon, 13 Jul 2009 18:34:53 +0200
|
from kristaps@ Mon, 13 Jul 2009 18:34:53 +0200
|
||||||
from jmc@ Mon, 13 Jul 2009 17:45:37 +0059
|
from jmc@ Mon, 13 Jul 2009 17:45:37 +0059
|
||||||
from kristaps@ Mon, 13 Jul 2009 19:02:03 +0200
|
from kristaps@ Mon, 13 Jul 2009 19:02:03 +0200
|
||||||
|
(mostly done, check what remains)
|
||||||
|
|
||||||
- -Tlint parser errors and warnings to stdout
|
- -Tlint parser errors and warnings to stdout
|
||||||
to tech@mdocml, naddy@ Wed, 28 Sep 2011 11:21:46 +0200
|
to tech@mdocml, naddy@ Wed, 28 Sep 2011 11:21:46 +0200
|
||||||
@ -395,6 +537,9 @@
|
|||||||
|
|
||||||
- mention /usr/share/misc/mdoc.template in mdoc(7)?
|
- mention /usr/share/misc/mdoc.template in mdoc(7)?
|
||||||
|
|
||||||
|
- Is all the content from http://www.std.com/obi/BSD/doc/usd/28.tbl/tbl
|
||||||
|
covered in tbl(7)?
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* performance issues
|
* performance issues
|
||||||
************************************************************************
|
************************************************************************
|
||||||
@ -413,11 +558,15 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
|||||||
|
|
||||||
- instead of re-initialising the roff predefined-strings set before each
|
- instead of re-initialising the roff predefined-strings set before each
|
||||||
parse, create a read-only version the first time and copy it
|
parse, create a read-only version the first time and copy it
|
||||||
|
loc * exist ** algo ** size * imp **
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* structural issues
|
* structural issues
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
|
- Use libz directly instead of forking gunzip(1).
|
||||||
|
Suggested by bapt at FreeBSD among others.
|
||||||
|
|
||||||
- We use the input line number at several places to distinguish
|
- We use the input line number at several places to distinguish
|
||||||
same-line from different-line input. That plainly doesn't work
|
same-line from different-line input. That plainly doesn't work
|
||||||
with user-defined macros, leading to random breakage.
|
with user-defined macros, leading to random breakage.
|
||||||
@ -430,8 +579,25 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
|||||||
Update both mdoc(7) and man(7) documentation.
|
Update both mdoc(7) and man(7) documentation.
|
||||||
Triggered by Tim van der Molen Tue, 22 Feb 2011 20:30:45 +0100
|
Triggered by Tim van der Molen Tue, 22 Feb 2011 20:30:45 +0100
|
||||||
|
|
||||||
|
- struct mparse refactoring
|
||||||
|
Steffen Nurpmeso Thu, 04 Sep 2014 12:50:00 +0200
|
||||||
|
|
||||||
- Consider creating some views that will make the database more
|
- Consider creating some views that will make the database more
|
||||||
readable from the sqlite3 shell. Consider using them to
|
readable from the sqlite3 shell. Consider using them to
|
||||||
abstract from the database structure, too.
|
abstract from the database structure, too.
|
||||||
suggested by espie@ Sat, 19 Apr 2014 14:52:57 +0200
|
suggested by espie@ Sat, 19 Apr 2014 14:52:57 +0200
|
||||||
|
|
||||||
|
************************************************************************
|
||||||
|
* CGI issues
|
||||||
|
************************************************************************
|
||||||
|
|
||||||
|
- Enable HTTP compression by detecting gzip encoding and filtering
|
||||||
|
output through libz.
|
||||||
|
- Sandbox (see OpenSSH).
|
||||||
|
- Enable caching support via HTTP 304 and If-Modified-Since.
|
||||||
|
- Allow for cgi.h to be overridden by CGI environment variables.
|
||||||
|
Otherwise, binary distributions will inherit the compile-time
|
||||||
|
behaviour, which is not optimal.
|
||||||
|
- Have Mac OSX systems automatically disable -static compilation of the
|
||||||
|
CGI: -static isn't supported.
|
||||||
|
|
||||||
|
133
apropos.1
133
apropos.1
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: apropos.1,v 1.29 2014/04/24 00:28:19 schwarze Exp $
|
.\" $Id: apropos.1,v 1.36 2014/10/25 01:03:52 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
.\" Copyright (c) 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: April 24 2014 $
|
.Dd $Mdocdate: October 25 2014 $
|
||||||
.Dt APROPOS 1
|
.Dt APROPOS 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -24,6 +24,7 @@
|
|||||||
.Nd search manual page databases
|
.Nd search manual page databases
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
|
.Op Fl acfhklVw
|
||||||
.Op Fl C Ar file
|
.Op Fl C Ar file
|
||||||
.Op Fl M Ar path
|
.Op Fl M Ar path
|
||||||
.Op Fl m Ar path
|
.Op Fl m Ar path
|
||||||
@ -41,7 +42,7 @@ utilities query manual page databases generated by
|
|||||||
evaluating
|
evaluating
|
||||||
.Ar expression
|
.Ar expression
|
||||||
for each file in each database.
|
for each file in each database.
|
||||||
By default, it displays the names, section numbers, and description lines
|
By default, they display the names, section numbers, and description lines
|
||||||
of all matching manuals.
|
of all matching manuals.
|
||||||
.Pp
|
.Pp
|
||||||
By default,
|
By default,
|
||||||
@ -56,17 +57,82 @@ over manual names and descriptions
|
|||||||
.Pq the Li \&Nm No and Li \&Nd No macro keys .
|
.Pq the Li \&Nm No and Li \&Nd No macro keys .
|
||||||
Multiple terms imply pairwise
|
Multiple terms imply pairwise
|
||||||
.Fl o .
|
.Fl o .
|
||||||
.Nm whatis
|
|
||||||
maps terms only to case-sensitive manual names.
|
|
||||||
.Pp
|
.Pp
|
||||||
Its arguments are as follows:
|
.Nm whatis
|
||||||
|
is a synonym for
|
||||||
|
.Nm
|
||||||
|
.Fl f .
|
||||||
|
.Pp
|
||||||
|
The options are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl a
|
||||||
|
Instead of showing only the title lines, show the complete manual pages,
|
||||||
|
just like
|
||||||
|
.Xr man 1
|
||||||
|
.Fl a
|
||||||
|
would.
|
||||||
|
If the standard output is a terminal device and
|
||||||
|
.Fl c
|
||||||
|
is not specified, use
|
||||||
|
.Xr more 1
|
||||||
|
to paginate them.
|
||||||
|
In
|
||||||
|
.Fl a
|
||||||
|
mode, the options
|
||||||
|
.Fl IKOTW
|
||||||
|
described in the
|
||||||
|
.Xr mandoc 1
|
||||||
|
manual are also available.
|
||||||
.It Fl C Ar file
|
.It Fl C Ar file
|
||||||
Specify an alternative configuration
|
Specify an alternative configuration
|
||||||
.Ar file
|
.Ar file
|
||||||
in
|
in
|
||||||
.Xr man.conf 5
|
.Xr man.conf 5
|
||||||
format.
|
format.
|
||||||
|
.It Fl c
|
||||||
|
In
|
||||||
|
.Fl a
|
||||||
|
mode, copy the formatted manual pages to the standard output without using
|
||||||
|
.Xr more 1
|
||||||
|
to paginate them.
|
||||||
|
.It Fl f
|
||||||
|
Search for all words in
|
||||||
|
.Ar expression
|
||||||
|
in manual page names only.
|
||||||
|
The search is case insensitive and matches whole words only.
|
||||||
|
In this mode, macro keys, comparison operators, and logical operators
|
||||||
|
are not available.
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl k
|
||||||
|
and
|
||||||
|
.Fl l
|
||||||
|
options.
|
||||||
|
.It Fl h
|
||||||
|
Instead of showing the title lines, show the SYNOPSIS sections, just like
|
||||||
|
.Xr man 1
|
||||||
|
.Fl h
|
||||||
|
would.
|
||||||
|
.It Fl k
|
||||||
|
Support the full
|
||||||
|
.Ar expression
|
||||||
|
syntax.
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl f
|
||||||
|
and
|
||||||
|
.Fl l
|
||||||
|
options.
|
||||||
|
It is the default for
|
||||||
|
.Nm .
|
||||||
|
.It Fl l
|
||||||
|
An alias for
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl a .
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl f ,
|
||||||
|
.Fl k ,
|
||||||
|
and
|
||||||
|
.Fl w
|
||||||
|
options.
|
||||||
.It Fl M Ar path
|
.It Fl M Ar path
|
||||||
Use the colon-separated path instead of the default list of paths
|
Use the colon-separated path instead of the default list of paths
|
||||||
searched for
|
searched for
|
||||||
@ -96,6 +162,14 @@ By default, pages from all sections are shown.
|
|||||||
See
|
See
|
||||||
.Xr man 1
|
.Xr man 1
|
||||||
for a listing of sections.
|
for a listing of sections.
|
||||||
|
.It Fl V
|
||||||
|
Print version and exit.
|
||||||
|
.It Fl w
|
||||||
|
Instead of showing title lines, show the pathnames of the matching
|
||||||
|
manual pages, just like
|
||||||
|
.Xr man 1
|
||||||
|
.Fl w
|
||||||
|
would.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
An
|
An
|
||||||
@ -165,11 +239,6 @@ is evaluated case-insensitively.
|
|||||||
Has no effect on substring terms.
|
Has no effect on substring terms.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
.Nm whatis
|
|
||||||
considers an
|
|
||||||
.Ar expression
|
|
||||||
to consist of an opaque keyword.
|
|
||||||
.Pp
|
|
||||||
Results are sorted by manual sections and names, with output formatted as
|
Results are sorted by manual sections and names, with output formatted as
|
||||||
.Pp
|
.Pp
|
||||||
.D1 name[, name...](sec) \- description
|
.D1 name[, name...](sec) \- description
|
||||||
@ -270,7 +339,12 @@ Text production:
|
|||||||
.It Li \&Dx Ta Dx No version reference
|
.It Li \&Dx Ta Dx No version reference
|
||||||
.El
|
.El
|
||||||
.Sh ENVIRONMENT
|
.Sh ENVIRONMENT
|
||||||
.Bl -tag -width MANPATH
|
.Bl -tag -width MANPAGER
|
||||||
|
.It Ev MANPAGER
|
||||||
|
Any non-empty value of the environment variable
|
||||||
|
.Ev MANPAGER
|
||||||
|
will be used instead of the standard pagination program,
|
||||||
|
.Xr more 1 .
|
||||||
.It Ev MANPATH
|
.It Ev MANPATH
|
||||||
The standard search path used by
|
The standard search path used by
|
||||||
.Xr man 1
|
.Xr man 1
|
||||||
@ -288,6 +362,13 @@ or if it contains two adjacent colons,
|
|||||||
the standard search path is inserted between the colons.
|
the standard search path is inserted between the colons.
|
||||||
If none of these conditions are met, it overrides the
|
If none of these conditions are met, it overrides the
|
||||||
standard search path.
|
standard search path.
|
||||||
|
.It Ev PAGER
|
||||||
|
Specifies the pagination program to use when
|
||||||
|
.Ev MANPAGER
|
||||||
|
is not defined.
|
||||||
|
If neither PAGER nor MANPAGER is defined,
|
||||||
|
.Pa /usr/bin/more Fl s
|
||||||
|
will be used.
|
||||||
.El
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width "/etc/man.conf" -compact
|
.Bl -tag -width "/etc/man.conf" -compact
|
||||||
@ -349,11 +430,19 @@ The following two invocations are equivalent:
|
|||||||
.Xr re_format 7 ,
|
.Xr re_format 7 ,
|
||||||
.Xr makewhatis 8
|
.Xr makewhatis 8
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
An
|
Part of the functionality of
|
||||||
|
.Nm whatis
|
||||||
|
was already provided by the former
|
||||||
|
.Nm manwhere
|
||||||
|
utility in
|
||||||
|
.Bx 1 .
|
||||||
|
The
|
||||||
.Nm
|
.Nm
|
||||||
utility first appeared in
|
and
|
||||||
|
.Nm whatis
|
||||||
|
utilities first appeared in
|
||||||
.Bx 2 .
|
.Bx 2 .
|
||||||
It was rewritten from scratch for
|
They were rewritten from scratch for
|
||||||
.Ox 5.6 .
|
.Ox 5.6 .
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
@ -373,13 +462,23 @@ and
|
|||||||
and
|
and
|
||||||
.Fl s
|
.Fl s
|
||||||
in
|
in
|
||||||
.Ox 4.5 .
|
.Ox 4.5
|
||||||
|
for
|
||||||
|
.Nm
|
||||||
|
and in
|
||||||
|
.Ox 5.6
|
||||||
|
for
|
||||||
|
.Nm whatis .
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An -nosplit
|
.An -nosplit
|
||||||
.An Bill Joy
|
.An Bill Joy
|
||||||
wrote the original
|
wrote
|
||||||
|
.Nm manwhere
|
||||||
|
in 1977 and the original
|
||||||
.Bx
|
.Bx
|
||||||
.Nm
|
.Nm
|
||||||
|
and
|
||||||
|
.Nm whatis
|
||||||
in February 1979.
|
in February 1979.
|
||||||
The current version was written by
|
The current version was written by
|
||||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
123
apropos.c
123
apropos.c
@ -1,123 +0,0 @@
|
|||||||
/* $Id: apropos.c,v 1.39 2014/04/20 16:46:04 schwarze Exp $ */
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
|
||||||
* Copyright (c) 2013 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.
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "manpath.h"
|
|
||||||
#include "mansearch.h"
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int ch, whatis;
|
|
||||||
struct mansearch search;
|
|
||||||
size_t i, sz;
|
|
||||||
struct manpage *res;
|
|
||||||
struct manpaths paths;
|
|
||||||
char *defpaths, *auxpaths;
|
|
||||||
char *conf_file;
|
|
||||||
char *progname;
|
|
||||||
const char *outkey;
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
progname = strrchr(argv[0], '/');
|
|
||||||
if (progname == NULL)
|
|
||||||
progname = argv[0];
|
|
||||||
else
|
|
||||||
++progname;
|
|
||||||
|
|
||||||
whatis = (0 == strncmp(progname, "whatis", 6));
|
|
||||||
|
|
||||||
memset(&paths, 0, sizeof(struct manpaths));
|
|
||||||
memset(&search, 0, sizeof(struct mansearch));
|
|
||||||
|
|
||||||
auxpaths = defpaths = NULL;
|
|
||||||
conf_file = NULL;
|
|
||||||
outkey = "Nd";
|
|
||||||
|
|
||||||
while (-1 != (ch = getopt(argc, argv, "C:M:m:O:S:s:")))
|
|
||||||
switch (ch) {
|
|
||||||
case 'C':
|
|
||||||
conf_file = optarg;
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
defpaths = optarg;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
auxpaths = optarg;
|
|
||||||
break;
|
|
||||||
case 'O':
|
|
||||||
outkey = optarg;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
search.arch = optarg;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
search.sec = optarg;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto usage;
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (0 == argc)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
search.deftype = whatis ? TYPE_Nm : TYPE_Nm | TYPE_Nd;
|
|
||||||
search.flags = whatis ? MANSEARCH_WHATIS : 0;
|
|
||||||
|
|
||||||
manpath_parse(&paths, conf_file, defpaths, auxpaths);
|
|
||||||
mansearch_setup(1);
|
|
||||||
ch = mansearch(&search, &paths, argc, argv, outkey, &res, &sz);
|
|
||||||
manpath_free(&paths);
|
|
||||||
|
|
||||||
if (0 == ch)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
for (i = 0; i < sz; i++) {
|
|
||||||
printf("%s - %s\n", res[i].names,
|
|
||||||
NULL == res[i].output ? "" : res[i].output);
|
|
||||||
free(res[i].file);
|
|
||||||
free(res[i].names);
|
|
||||||
free(res[i].output);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(res);
|
|
||||||
mansearch_setup(0);
|
|
||||||
return(sz ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
||||||
usage:
|
|
||||||
fprintf(stderr, "usage: %s [-C file] [-M path] [-m path] "
|
|
||||||
"[-O outkey] "
|
|
||||||
"[-S arch] [-s section]%s ...\n", progname,
|
|
||||||
whatis ? " name" : "\n expression");
|
|
||||||
return(EXIT_FAILURE);
|
|
||||||
}
|
|
112
arch.in
112
arch.in
@ -1,112 +0,0 @@
|
|||||||
/* $Id: arch.in,v 1.15 2014/04/27 22:42:15 schwarze Exp $ */
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file defines the architecture token of the .Dt prologue macro.
|
|
||||||
* All architectures that your system supports (or the manuals of your
|
|
||||||
* system) should be included here. The right-hand-side is the
|
|
||||||
* formatted output.
|
|
||||||
*
|
|
||||||
* Be sure to escape strings.
|
|
||||||
*
|
|
||||||
* REMEMBER TO ADD NEW ARCHITECTURES TO MDOC.7!
|
|
||||||
*/
|
|
||||||
|
|
||||||
LINE("acorn26", "Acorn26")
|
|
||||||
LINE("acorn32", "Acorn32")
|
|
||||||
LINE("algor", "Algor")
|
|
||||||
LINE("alpha", "Alpha")
|
|
||||||
LINE("amd64", "AMD64")
|
|
||||||
LINE("amiga", "Amiga")
|
|
||||||
LINE("amigappc", "AmigaPPC")
|
|
||||||
LINE("arc", "ARC")
|
|
||||||
LINE("arm", "ARM")
|
|
||||||
LINE("arm26", "ARM26")
|
|
||||||
LINE("arm32", "ARM32")
|
|
||||||
LINE("armish", "ARMISH")
|
|
||||||
LINE("armv7", "ARMv7")
|
|
||||||
LINE("aviion", "AViiON")
|
|
||||||
LINE("atari", "ATARI")
|
|
||||||
LINE("bebox", "BeBox")
|
|
||||||
LINE("cats", "cats")
|
|
||||||
LINE("cesfic", "CESFIC")
|
|
||||||
LINE("cobalt", "Cobalt")
|
|
||||||
LINE("dreamcast", "Dreamcast")
|
|
||||||
LINE("emips", "EMIPS")
|
|
||||||
LINE("evbarm", "evbARM")
|
|
||||||
LINE("evbmips", "evbMIPS")
|
|
||||||
LINE("evbppc", "evbPPC")
|
|
||||||
LINE("evbsh3", "evbSH3")
|
|
||||||
LINE("ews4800mips", "EWS4800MIPS")
|
|
||||||
LINE("hp300", "HP300")
|
|
||||||
LINE("hp700", "HP700")
|
|
||||||
LINE("hpcarm", "HPCARM")
|
|
||||||
LINE("hpcmips", "HPCMIPS")
|
|
||||||
LINE("hpcsh", "HPCSH")
|
|
||||||
LINE("hppa", "HPPA")
|
|
||||||
LINE("hppa64", "HPPA64")
|
|
||||||
LINE("ia64", "ia64")
|
|
||||||
LINE("i386", "i386")
|
|
||||||
LINE("ibmnws", "IBMNWS")
|
|
||||||
LINE("iyonix", "Iyonix")
|
|
||||||
LINE("landisk", "LANDISK")
|
|
||||||
LINE("loongson", "Loongson")
|
|
||||||
LINE("luna68k", "LUNA68K")
|
|
||||||
LINE("luna88k", "LUNA88K")
|
|
||||||
LINE("m68k", "m68k")
|
|
||||||
LINE("mac68k", "Mac68k")
|
|
||||||
LINE("macppc", "MacPPC")
|
|
||||||
LINE("mips", "MIPS")
|
|
||||||
LINE("mips64", "MIPS64")
|
|
||||||
LINE("mipsco", "MIPSCo")
|
|
||||||
LINE("mmeye", "mmEye")
|
|
||||||
LINE("mvme68k", "MVME68k")
|
|
||||||
LINE("mvme88k", "MVME88k")
|
|
||||||
LINE("mvmeppc", "MVMEPPC")
|
|
||||||
LINE("netwinder", "NetWinder")
|
|
||||||
LINE("news68k", "NeWS68k")
|
|
||||||
LINE("newsmips", "NeWSMIPS")
|
|
||||||
LINE("next68k", "NeXT68k")
|
|
||||||
LINE("octeon", "OCTEON")
|
|
||||||
LINE("ofppc", "OFPPC")
|
|
||||||
LINE("palm", "Palm")
|
|
||||||
LINE("pc532", "PC532")
|
|
||||||
LINE("playstation2", "PlayStation2")
|
|
||||||
LINE("pmax", "PMAX")
|
|
||||||
LINE("pmppc", "pmPPC")
|
|
||||||
LINE("powerpc", "PowerPC")
|
|
||||||
LINE("prep", "PReP")
|
|
||||||
LINE("rs6000", "RS6000")
|
|
||||||
LINE("sandpoint", "Sandpoint")
|
|
||||||
LINE("sbmips", "SBMIPS")
|
|
||||||
LINE("sgi", "SGI")
|
|
||||||
LINE("sgimips", "SGIMIPS")
|
|
||||||
LINE("sh3", "SH3")
|
|
||||||
LINE("shark", "Shark")
|
|
||||||
LINE("socppc", "SOCPPC")
|
|
||||||
LINE("solbourne", "Solbourne")
|
|
||||||
LINE("sparc", "SPARC")
|
|
||||||
LINE("sparc64", "SPARC64")
|
|
||||||
LINE("sun2", "Sun2")
|
|
||||||
LINE("sun3", "Sun3")
|
|
||||||
LINE("tahoe", "Tahoe")
|
|
||||||
LINE("vax", "VAX")
|
|
||||||
LINE("x68k", "X68k")
|
|
||||||
LINE("x86", "x86")
|
|
||||||
LINE("x86_64", "x86_64")
|
|
||||||
LINE("xen", "Xen")
|
|
||||||
LINE("zaurus", "Zaurus")
|
|
22
att.c
22
att.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: att.c,v 1.11 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: att.c,v 1.13 2014/11/28 18:57:31 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,24 +14,36 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "libmdoc.h"
|
#include "libmdoc.h"
|
||||||
|
|
||||||
#define LINE(x, y) \
|
#define LINE(x, y) \
|
||||||
if (0 == strcmp(p, x)) return(y);
|
if (0 == strcmp(p, x)) return(y)
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
mdoc_a2att(const char *p)
|
mdoc_a2att(const char *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
#include "att.in"
|
LINE("v1", "Version\\~1 AT&T UNIX");
|
||||||
|
LINE("v2", "Version\\~2 AT&T UNIX");
|
||||||
|
LINE("v3", "Version\\~3 AT&T UNIX");
|
||||||
|
LINE("v4", "Version\\~4 AT&T UNIX");
|
||||||
|
LINE("v5", "Version\\~5 AT&T UNIX");
|
||||||
|
LINE("v6", "Version\\~6 AT&T UNIX");
|
||||||
|
LINE("v7", "Version\\~7 AT&T UNIX");
|
||||||
|
LINE("32v", "Version\\~32V AT&T UNIX");
|
||||||
|
LINE("III", "AT&T System\\~III UNIX");
|
||||||
|
LINE("V", "AT&T System\\~V UNIX");
|
||||||
|
LINE("V.1", "AT&T System\\~V Release\\~1 UNIX");
|
||||||
|
LINE("V.2", "AT&T System\\~V Release\\~2 UNIX");
|
||||||
|
LINE("V.3", "AT&T System\\~V Release\\~3 UNIX");
|
||||||
|
LINE("V.4", "AT&T System\\~V Release\\~4 UNIX");
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
40
att.in
40
att.in
@ -1,40 +0,0 @@
|
|||||||
/* $Id: att.in,v 1.8 2011/07/31 17:30:33 schwarze Exp $ */
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file defines the AT&T versions of the .At macro. This probably
|
|
||||||
* isn't going to change. The right-hand side is the formatted string.
|
|
||||||
*
|
|
||||||
* Be sure to escape strings.
|
|
||||||
* The non-breaking blanks prevent ending an output line right before
|
|
||||||
* a number. Groff prevent line breaks at the same places.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LINE("v1", "Version\\~1 AT&T UNIX")
|
|
||||||
LINE("v2", "Version\\~2 AT&T UNIX")
|
|
||||||
LINE("v3", "Version\\~3 AT&T UNIX")
|
|
||||||
LINE("v4", "Version\\~4 AT&T UNIX")
|
|
||||||
LINE("v5", "Version\\~5 AT&T UNIX")
|
|
||||||
LINE("v6", "Version\\~6 AT&T UNIX")
|
|
||||||
LINE("v7", "Version\\~7 AT&T UNIX")
|
|
||||||
LINE("32v", "Version\\~32V AT&T UNIX")
|
|
||||||
LINE("III", "AT&T System\\~III UNIX")
|
|
||||||
LINE("V", "AT&T System\\~V UNIX")
|
|
||||||
LINE("V.1", "AT&T System\\~V Release\\~1 UNIX")
|
|
||||||
LINE("V.2", "AT&T System\\~V Release\\~2 UNIX")
|
|
||||||
LINE("V.3", "AT&T System\\~V Release\\~3 UNIX")
|
|
||||||
LINE("V.4", "AT&T System\\~V Release\\~4 UNIX")
|
|
133
cgi.c
133
cgi.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cgi.c,v 1.92 2014/08/05 15:29:30 schwarze Exp $ */
|
/* $Id: cgi.c,v 1.102 2014/11/26 17:55:27 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de>
|
||||||
@ -15,9 +15,10 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -91,14 +92,14 @@ static const char *const sec_names[] = {
|
|||||||
"All Sections",
|
"All Sections",
|
||||||
"1 - General Commands",
|
"1 - General Commands",
|
||||||
"2 - System Calls",
|
"2 - System Calls",
|
||||||
"3 - Subroutines",
|
"3 - Library Functions",
|
||||||
"3p - Perl Subroutines",
|
"3p - Perl Library",
|
||||||
"4 - Special Files",
|
"4 - Device Drivers",
|
||||||
"5 - File Formats",
|
"5 - File Formats",
|
||||||
"6 - Games",
|
"6 - Games",
|
||||||
"7 - Macros and Conventions",
|
"7 - Miscellaneous Information",
|
||||||
"8 - Maintenance Commands",
|
"8 - System Manager\'s Manual",
|
||||||
"9 - Kernel Interface"
|
"9 - Kernel Developer\'s Manual"
|
||||||
};
|
};
|
||||||
static const int sec_MAX = sizeof(sec_names) / sizeof(char *);
|
static const int sec_MAX = sizeof(sec_names) / sizeof(char *);
|
||||||
|
|
||||||
@ -162,8 +163,7 @@ http_printquery(const struct req *req, const char *sep)
|
|||||||
printf("%sarch=", sep);
|
printf("%sarch=", sep);
|
||||||
http_print(req->q.arch);
|
http_print(req->q.arch);
|
||||||
}
|
}
|
||||||
if (NULL != req->q.manpath &&
|
if (strcmp(req->q.manpath, req->p[0])) {
|
||||||
strcmp(req->q.manpath, req->p[0])) {
|
|
||||||
printf("%smanpath=", sep);
|
printf("%smanpath=", sep);
|
||||||
http_print(req->q.manpath);
|
http_print(req->q.manpath);
|
||||||
}
|
}
|
||||||
@ -297,11 +297,6 @@ http_parse(struct req *req, const char *qs)
|
|||||||
if (*qs != '\0')
|
if (*qs != '\0')
|
||||||
qs++;
|
qs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fall back to the default manpath. */
|
|
||||||
|
|
||||||
if (req->q.manpath == NULL)
|
|
||||||
req->q.manpath = mandoc_strdup(req->p[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -375,13 +370,10 @@ resp_begin_html(int code, const char *msg)
|
|||||||
|
|
||||||
resp_begin_http(code, msg);
|
resp_begin_http(code, msg);
|
||||||
|
|
||||||
printf("<!DOCTYPE HTML PUBLIC "
|
printf("<!DOCTYPE html>\n"
|
||||||
" \"-//W3C//DTD HTML 4.01//EN\""
|
|
||||||
" \"http://www.w3.org/TR/html4/strict.dtd\">\n"
|
|
||||||
"<HTML>\n"
|
"<HTML>\n"
|
||||||
"<HEAD>\n"
|
"<HEAD>\n"
|
||||||
"<META HTTP-EQUIV=\"Content-Type\""
|
"<META CHARSET=\"UTF-8\" />\n"
|
||||||
" CONTENT=\"text/html; charset=utf-8\">\n"
|
|
||||||
"<LINK REL=\"stylesheet\" HREF=\"%s/man-cgi.css\""
|
"<LINK REL=\"stylesheet\" HREF=\"%s/man-cgi.css\""
|
||||||
" TYPE=\"text/css\" media=\"all\">\n"
|
" TYPE=\"text/css\" media=\"all\">\n"
|
||||||
"<LINK REL=\"stylesheet\" HREF=\"%s/man.css\""
|
"<LINK REL=\"stylesheet\" HREF=\"%s/man.css\""
|
||||||
@ -471,8 +463,7 @@ resp_searchform(const struct req *req)
|
|||||||
puts("<SELECT NAME=\"manpath\">");
|
puts("<SELECT NAME=\"manpath\">");
|
||||||
for (i = 0; i < (int)req->psz; i++) {
|
for (i = 0; i < (int)req->psz; i++) {
|
||||||
printf("<OPTION ");
|
printf("<OPTION ");
|
||||||
if (NULL == req->q.manpath ? 0 == i :
|
if (strcmp(req->q.manpath, req->p[i]) == 0)
|
||||||
0 == strcmp(req->q.manpath, req->p[i]))
|
|
||||||
printf("SELECTED=\"selected\" ");
|
printf("SELECTED=\"selected\" ");
|
||||||
printf("VALUE=\"");
|
printf("VALUE=\"");
|
||||||
html_print(req->p[i]);
|
html_print(req->p[i]);
|
||||||
@ -826,6 +817,7 @@ static void
|
|||||||
format(const struct req *req, const char *file)
|
format(const struct req *req, const char *file)
|
||||||
{
|
{
|
||||||
struct mparse *mp;
|
struct mparse *mp;
|
||||||
|
struct mchars *mchars;
|
||||||
struct mdoc *mdoc;
|
struct mdoc *mdoc;
|
||||||
struct man *man;
|
struct man *man;
|
||||||
void *vp;
|
void *vp;
|
||||||
@ -839,8 +831,9 @@ format(const struct req *req, const char *file)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mchars = mchars_alloc();
|
||||||
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL,
|
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL,
|
||||||
req->q.manpath);
|
mchars, req->q.manpath);
|
||||||
rc = mparse_readfd(mp, fd, file);
|
rc = mparse_readfd(mp, fd, file);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@ -866,10 +859,11 @@ format(const struct req *req, const char *file)
|
|||||||
req->q.manpath, file);
|
req->q.manpath, file);
|
||||||
pg_error_internal();
|
pg_error_internal();
|
||||||
mparse_free(mp);
|
mparse_free(mp);
|
||||||
|
mchars_free(mchars);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vp = html_alloc(opts);
|
vp = html_alloc(mchars, opts);
|
||||||
|
|
||||||
if (NULL != mdoc)
|
if (NULL != mdoc)
|
||||||
html_mdoc(vp, mdoc);
|
html_mdoc(vp, mdoc);
|
||||||
@ -878,6 +872,7 @@ format(const struct req *req, const char *file)
|
|||||||
|
|
||||||
html_free(vp);
|
html_free(vp);
|
||||||
mparse_free(mp);
|
mparse_free(mp);
|
||||||
|
mchars_free(mchars);
|
||||||
free(opts);
|
free(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,10 +948,10 @@ pg_search(const struct req *req)
|
|||||||
struct mansearch search;
|
struct mansearch search;
|
||||||
struct manpaths paths;
|
struct manpaths paths;
|
||||||
struct manpage *res;
|
struct manpage *res;
|
||||||
char **cp;
|
char **argv;
|
||||||
const char *ep, *start;
|
char *query, *rp, *wp;
|
||||||
size_t ressz;
|
size_t ressz;
|
||||||
int i, sz;
|
int argc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Begin by chdir()ing into the root of the manpath.
|
* Begin by chdir()ing into the root of the manpath.
|
||||||
@ -973,54 +968,54 @@ pg_search(const struct req *req)
|
|||||||
|
|
||||||
search.arch = req->q.arch;
|
search.arch = req->q.arch;
|
||||||
search.sec = req->q.sec;
|
search.sec = req->q.sec;
|
||||||
search.deftype = req->q.equal ? TYPE_Nm : (TYPE_Nm | TYPE_Nd);
|
search.outkey = "Nd";
|
||||||
search.flags = req->q.equal ? MANSEARCH_MAN : 0;
|
search.argmode = req->q.equal ? ARG_NAME : ARG_EXPR;
|
||||||
|
search.firstmatch = 1;
|
||||||
|
|
||||||
paths.sz = 1;
|
paths.sz = 1;
|
||||||
paths.paths = mandoc_malloc(sizeof(char *));
|
paths.paths = mandoc_malloc(sizeof(char *));
|
||||||
paths.paths[0] = mandoc_strdup(".");
|
paths.paths[0] = mandoc_strdup(".");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Poor man's tokenisation: just break apart by spaces.
|
* Break apart at spaces with backslash-escaping.
|
||||||
* Yes, this is half-ass. But it works for now.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ep = req->q.query;
|
argc = 0;
|
||||||
while (ep && isspace((unsigned char)*ep))
|
argv = NULL;
|
||||||
ep++;
|
rp = query = mandoc_strdup(req->q.query);
|
||||||
|
for (;;) {
|
||||||
sz = 0;
|
while (isspace((unsigned char)*rp))
|
||||||
cp = NULL;
|
rp++;
|
||||||
while (ep && '\0' != *ep) {
|
if (*rp == '\0')
|
||||||
cp = mandoc_reallocarray(cp, sz + 1, sizeof(char *));
|
break;
|
||||||
start = ep;
|
argv = mandoc_reallocarray(argv, argc + 1, sizeof(char *));
|
||||||
while ('\0' != *ep && ! isspace((unsigned char)*ep))
|
argv[argc++] = wp = rp;
|
||||||
ep++;
|
for (;;) {
|
||||||
cp[sz] = mandoc_malloc((ep - start) + 1);
|
if (isspace((unsigned char)*rp)) {
|
||||||
memcpy(cp[sz], start, ep - start);
|
*wp = '\0';
|
||||||
cp[sz++][ep - start] = '\0';
|
rp++;
|
||||||
while (isspace((unsigned char)*ep))
|
break;
|
||||||
ep++;
|
}
|
||||||
|
if (rp[0] == '\\' && rp[1] != '\0')
|
||||||
|
rp++;
|
||||||
|
if (wp != rp)
|
||||||
|
*wp = *rp;
|
||||||
|
if (*rp == '\0')
|
||||||
|
break;
|
||||||
|
wp++;
|
||||||
|
rp++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == mansearch(&search, &paths, sz, cp, "Nd", &res, &ressz))
|
if (0 == mansearch(&search, &paths, argc, argv, &res, &ressz))
|
||||||
pg_noresult(req, "You entered an invalid query.");
|
pg_noresult(req, "You entered an invalid query.");
|
||||||
else if (0 == ressz)
|
else if (0 == ressz)
|
||||||
pg_noresult(req, "No results found.");
|
pg_noresult(req, "No results found.");
|
||||||
else
|
else
|
||||||
pg_searchres(req, res, ressz);
|
pg_searchres(req, res, ressz);
|
||||||
|
|
||||||
for (i = 0; i < sz; i++)
|
free(query);
|
||||||
free(cp[i]);
|
mansearch_free(res, ressz);
|
||||||
free(cp);
|
|
||||||
|
|
||||||
for (i = 0; i < (int)ressz; i++) {
|
|
||||||
free(res[i].file);
|
|
||||||
free(res[i].names);
|
|
||||||
free(res[i].output);
|
|
||||||
}
|
|
||||||
free(res);
|
|
||||||
|
|
||||||
free(paths.paths[0]);
|
free(paths.paths[0]);
|
||||||
free(paths.paths);
|
free(paths.paths);
|
||||||
}
|
}
|
||||||
@ -1029,10 +1024,23 @@ int
|
|||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
struct req req;
|
struct req req;
|
||||||
|
struct itimerval itimer;
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *querystring;
|
const char *querystring;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Poor man's ReDoS mitigation. */
|
||||||
|
|
||||||
|
itimer.it_value.tv_sec = 2;
|
||||||
|
itimer.it_value.tv_usec = 0;
|
||||||
|
itimer.it_interval.tv_sec = 2;
|
||||||
|
itimer.it_interval.tv_usec = 0;
|
||||||
|
if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) {
|
||||||
|
fprintf(stderr, "setitimer: %s\n", strerror(errno));
|
||||||
|
pg_error_internal();
|
||||||
|
return(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Scan our run-time environment. */
|
/* Scan our run-time environment. */
|
||||||
|
|
||||||
if (NULL == (scriptname = getenv("SCRIPT_NAME")))
|
if (NULL == (scriptname = getenv("SCRIPT_NAME")))
|
||||||
@ -1066,8 +1074,9 @@ main(void)
|
|||||||
if (NULL != (querystring = getenv("QUERY_STRING")))
|
if (NULL != (querystring = getenv("QUERY_STRING")))
|
||||||
http_parse(&req, querystring);
|
http_parse(&req, querystring);
|
||||||
|
|
||||||
if ( ! (NULL == req.q.manpath ||
|
if (req.q.manpath == NULL)
|
||||||
validate_manpath(&req, req.q.manpath))) {
|
req.q.manpath = mandoc_strdup(req.p[0]);
|
||||||
|
else if ( ! validate_manpath(&req, req.q.manpath)) {
|
||||||
pg_error_badrequest(
|
pg_error_badrequest(
|
||||||
"You specified an invalid manpath.");
|
"You specified an invalid manpath.");
|
||||||
return(EXIT_FAILURE);
|
return(EXIT_FAILURE);
|
||||||
|
53
chars.c
53
chars.c
@ -1,7 +1,7 @@
|
|||||||
/* $Id: chars.c,v 1.58 2014/07/23 15:00:08 schwarze Exp $ */
|
/* $Id: chars.c,v 1.65 2014/10/29 00:17:43 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -15,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -104,20 +104,16 @@ mchars_spec2cp(const struct mchars *arg, const char *p, size_t sz)
|
|||||||
const struct ln *ln;
|
const struct ln *ln;
|
||||||
|
|
||||||
ln = find(arg, p, sz);
|
ln = find(arg, p, sz);
|
||||||
if (NULL == ln)
|
return(ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1);
|
||||||
return(-1);
|
|
||||||
return(ln->unicode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
int
|
||||||
mchars_num2char(const char *p, size_t sz)
|
mchars_num2char(const char *p, size_t sz)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((i = mandoc_strntoi(p, sz, 10)) < 0)
|
i = mandoc_strntoi(p, sz, 10);
|
||||||
return('\0');
|
return(i >= 0 && i < 256 ? i : -1);
|
||||||
|
|
||||||
return(i > 0 && i < 256 && isprint(i) ? i : '\0');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -125,21 +121,9 @@ mchars_num2uc(const char *p, size_t sz)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((i = mandoc_strntoi(p, sz, 16)) < 0)
|
i = mandoc_strntoi(p, sz, 16);
|
||||||
return('\0');
|
assert(i >= 0 && i <= 0x10FFFF);
|
||||||
|
return(i);
|
||||||
/*
|
|
||||||
* Security warning:
|
|
||||||
* Never extend the range of accepted characters
|
|
||||||
* to overlap with the ASCII range, 0x00-0x7F
|
|
||||||
* without re-auditing the callers of this function.
|
|
||||||
* Some callers might relay on the fact that we never
|
|
||||||
* return ASCII characters for their escaping decisions.
|
|
||||||
*
|
|
||||||
* XXX Code is missing here to exclude bogus ranges.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return(i > 0x80 && i <= 0x10FFFF ? i : '\0');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
@ -149,15 +133,26 @@ mchars_spec2str(const struct mchars *arg,
|
|||||||
const struct ln *ln;
|
const struct ln *ln;
|
||||||
|
|
||||||
ln = find(arg, p, sz);
|
ln = find(arg, p, sz);
|
||||||
if (NULL == ln) {
|
if (ln == NULL) {
|
||||||
*rsz = 1;
|
*rsz = 1;
|
||||||
return(NULL);
|
return(sz == 1 ? p : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
*rsz = strlen(ln->ascii);
|
*rsz = strlen(ln->ascii);
|
||||||
return(ln->ascii);
|
return(ln->ascii);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
mchars_uc2str(int uc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < LINES_MAX; i++)
|
||||||
|
if (uc == lines[i].unicode)
|
||||||
|
return(lines[i].ascii);
|
||||||
|
return("<?>");
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ln *
|
static const struct ln *
|
||||||
find(const struct mchars *tab, const char *p, size_t sz)
|
find(const struct mchars *tab, const char *p, size_t sz)
|
||||||
{
|
{
|
||||||
|
230
chars.in
230
chars.in
@ -1,4 +1,4 @@
|
|||||||
/* $Id: chars.in,v 1.46 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: chars.in,v 1.49 2014/11/06 22:28:36 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -57,7 +57,7 @@ CHAR("\'", "\'", 180)
|
|||||||
CHAR("aa", "\'", 180)
|
CHAR("aa", "\'", 180)
|
||||||
CHAR("ga", "`", 96)
|
CHAR("ga", "`", 96)
|
||||||
CHAR("`", "`", 96)
|
CHAR("`", "`", 96)
|
||||||
CHAR("ab", "`", 728)
|
CHAR("ab", "'\b`", 728)
|
||||||
CHAR("ac", ",", 184)
|
CHAR("ac", ",", 184)
|
||||||
CHAR("ad", "\"", 168)
|
CHAR("ad", "\"", 168)
|
||||||
CHAR("ah", "v", 711)
|
CHAR("ah", "v", 711)
|
||||||
@ -86,8 +86,8 @@ CHAR("lB", "[", 91)
|
|||||||
CHAR("rB", "]", 93)
|
CHAR("rB", "]", 93)
|
||||||
CHAR("lC", "{", 123)
|
CHAR("lC", "{", 123)
|
||||||
CHAR("rC", "}", 125)
|
CHAR("rC", "}", 125)
|
||||||
CHAR("la", "<", 60)
|
CHAR("la", "<", 10216)
|
||||||
CHAR("ra", ">", 62)
|
CHAR("ra", ">", 10217)
|
||||||
CHAR("bv", "|", 9130)
|
CHAR("bv", "|", 9130)
|
||||||
CHAR("braceex", "|", 9130)
|
CHAR("braceex", "|", 9130)
|
||||||
CHAR("bracketlefttp", "|", 9121)
|
CHAR("bracketlefttp", "|", 9121)
|
||||||
@ -100,7 +100,7 @@ CHAR("lt", ",-", 9127)
|
|||||||
CHAR("bracelefttp", ",-", 9127)
|
CHAR("bracelefttp", ",-", 9127)
|
||||||
CHAR("lk", "{", 9128)
|
CHAR("lk", "{", 9128)
|
||||||
CHAR("braceleftmid", "{", 9128)
|
CHAR("braceleftmid", "{", 9128)
|
||||||
CHAR("lb", ",-", 9129)
|
CHAR("lb", "`-", 9129)
|
||||||
CHAR("braceleftbp", "`-", 9129)
|
CHAR("braceleftbp", "`-", 9129)
|
||||||
CHAR("braceleftex", "|", 9130)
|
CHAR("braceleftex", "|", 9130)
|
||||||
CHAR("rt", "-.", 9131)
|
CHAR("rt", "-.", 9131)
|
||||||
@ -120,127 +120,127 @@ CHAR("parenrightex", "|", 9119)
|
|||||||
/* Greek characters. */
|
/* Greek characters. */
|
||||||
CHAR("*A", "A", 913)
|
CHAR("*A", "A", 913)
|
||||||
CHAR("*B", "B", 914)
|
CHAR("*B", "B", 914)
|
||||||
CHAR("*G", "|", 915)
|
CHAR("*G", "G", 915)
|
||||||
CHAR("*D", "/\\", 916)
|
CHAR("*D", "_\b/_\b\\", 916)
|
||||||
CHAR("*E", "E", 917)
|
CHAR("*E", "E", 917)
|
||||||
CHAR("*Z", "Z", 918)
|
CHAR("*Z", "Z", 918)
|
||||||
CHAR("*Y", "H", 919)
|
CHAR("*Y", "H", 919)
|
||||||
CHAR("*H", "O", 920)
|
CHAR("*H", "-\bO", 920)
|
||||||
CHAR("*I", "I", 921)
|
CHAR("*I", "I", 921)
|
||||||
CHAR("*K", "K", 922)
|
CHAR("*K", "K", 922)
|
||||||
CHAR("*L", "/\\", 923)
|
CHAR("*L", "/\\", 923)
|
||||||
CHAR("*M", "M", 924)
|
CHAR("*M", "M", 924)
|
||||||
CHAR("*N", "N", 925)
|
CHAR("*N", "N", 925)
|
||||||
CHAR("*C", "H", 926)
|
CHAR("*C", "_\bH", 926)
|
||||||
CHAR("*O", "O", 927)
|
CHAR("*O", "O", 927)
|
||||||
CHAR("*P", "TT", 928)
|
CHAR("*P", "TT", 928)
|
||||||
CHAR("*R", "P", 929)
|
CHAR("*R", "P", 929)
|
||||||
CHAR("*S", ">", 931)
|
CHAR("*S", "S", 931)
|
||||||
CHAR("*T", "T", 932)
|
CHAR("*T", "T", 932)
|
||||||
CHAR("*U", "Y", 933)
|
CHAR("*U", "Y", 933)
|
||||||
CHAR("*F", "O_", 934)
|
CHAR("*F", "I\bO", 934)
|
||||||
CHAR("*X", "X", 935)
|
CHAR("*X", "X", 935)
|
||||||
CHAR("*Q", "Y", 936)
|
CHAR("*Q", "I\bY", 936)
|
||||||
CHAR("*W", "O", 937)
|
CHAR("*W", "_\bO", 937)
|
||||||
CHAR("*a", "a", 945)
|
CHAR("*a", "a", 945)
|
||||||
CHAR("*b", "B", 946)
|
CHAR("*b", "B", 946)
|
||||||
CHAR("*g", "y", 947)
|
CHAR("*g", "y", 947)
|
||||||
CHAR("*d", "d", 948)
|
CHAR("*d", "d", 948)
|
||||||
CHAR("*e", "e", 949)
|
CHAR("*e", "e", 949)
|
||||||
CHAR("*z", "C", 950)
|
CHAR("*z", ",\bC", 950)
|
||||||
CHAR("*y", "n", 951)
|
CHAR("*y", "n", 951)
|
||||||
CHAR("*h", "0", 952)
|
CHAR("*h", "-\b0", 952)
|
||||||
CHAR("*i", "i", 953)
|
CHAR("*i", "i", 953)
|
||||||
CHAR("*k", "k", 954)
|
CHAR("*k", "k", 954)
|
||||||
CHAR("*l", "\\", 955)
|
CHAR("*l", ">\b\\", 955)
|
||||||
CHAR("*m", "u", 956)
|
CHAR("*m", ",\bu", 956)
|
||||||
CHAR("*n", "v", 957)
|
CHAR("*n", "v", 957)
|
||||||
CHAR("*c", "E", 958)
|
CHAR("*c", ",\bE", 958)
|
||||||
CHAR("*o", "o", 959)
|
CHAR("*o", "o", 959)
|
||||||
CHAR("*p", "n", 960)
|
CHAR("*p", "-\bn", 960)
|
||||||
CHAR("*r", "p", 961)
|
CHAR("*r", "p", 961)
|
||||||
CHAR("*s", "o", 963)
|
CHAR("*s", "-\bo", 963)
|
||||||
CHAR("*t", "t", 964)
|
CHAR("*t", "~\bt", 964)
|
||||||
CHAR("*u", "u", 965)
|
CHAR("*u", "u", 965)
|
||||||
CHAR("*f", "o", 981)
|
CHAR("*f", "|\bo", 981)
|
||||||
CHAR("*x", "x", 967)
|
CHAR("*x", "x", 967)
|
||||||
CHAR("*q", "u", 968)
|
CHAR("*q", "|\bu", 968)
|
||||||
CHAR("*w", "w", 969)
|
CHAR("*w", "w", 969)
|
||||||
CHAR("+h", "0", 977)
|
CHAR("+h", "-\b0", 977)
|
||||||
CHAR("+f", "o", 966)
|
CHAR("+f", "|\bo", 966)
|
||||||
CHAR("+p", "w", 982)
|
CHAR("+p", "-\bw", 982)
|
||||||
CHAR("+e", "e", 1013)
|
CHAR("+e", "e", 1013)
|
||||||
CHAR("ts", "s", 962)
|
CHAR("ts", "s", 962)
|
||||||
|
|
||||||
/* Accented letters. */
|
/* Accented letters. */
|
||||||
CHAR(",C", "C", 199)
|
CHAR(",C", ",\bC", 199)
|
||||||
CHAR(",c", "c", 231)
|
CHAR(",c", ",\bc", 231)
|
||||||
CHAR("/L", "L", 321)
|
CHAR("/L", "/\bL", 321)
|
||||||
CHAR("/O", "O", 216)
|
CHAR("/O", "/\bO", 216)
|
||||||
CHAR("/l", "l", 322)
|
CHAR("/l", "/\bl", 322)
|
||||||
CHAR("/o", "o", 248)
|
CHAR("/o", "/\bo", 248)
|
||||||
CHAR("oA", "A", 197)
|
CHAR("oA", "o\bA", 197)
|
||||||
CHAR("oa", "a", 229)
|
CHAR("oa", "o\ba", 229)
|
||||||
CHAR(":A", "A", 196)
|
CHAR(":A", "\"\bA", 196)
|
||||||
CHAR(":E", "E", 203)
|
CHAR(":E", "\"\bE", 203)
|
||||||
CHAR(":I", "I", 207)
|
CHAR(":I", "\"\bI", 207)
|
||||||
CHAR(":O", "O", 214)
|
CHAR(":O", "\"\bO", 214)
|
||||||
CHAR(":U", "U", 220)
|
CHAR(":U", "\"\bU", 220)
|
||||||
CHAR(":a", "a", 228)
|
CHAR(":a", "\"\ba", 228)
|
||||||
CHAR(":e", "e", 235)
|
CHAR(":e", "\"\be", 235)
|
||||||
CHAR(":i", "i", 239)
|
CHAR(":i", "\"\bi", 239)
|
||||||
CHAR(":o", "o", 246)
|
CHAR(":o", "\"\bo", 246)
|
||||||
CHAR(":u", "u", 252)
|
CHAR(":u", "\"\bu", 252)
|
||||||
CHAR(":y", "y", 255)
|
CHAR(":y", "\"\by", 255)
|
||||||
CHAR("\'A", "A", 193)
|
CHAR("'A", "'\bA", 193)
|
||||||
CHAR("\'E", "E", 201)
|
CHAR("'E", "'\bE", 201)
|
||||||
CHAR("\'I", "I", 205)
|
CHAR("'I", "'\bI", 205)
|
||||||
CHAR("\'O", "O", 211)
|
CHAR("'O", "'\bO", 211)
|
||||||
CHAR("\'U", "U", 218)
|
CHAR("'U", "'\bU", 218)
|
||||||
CHAR("\'a", "a", 225)
|
CHAR("'a", "'\ba", 225)
|
||||||
CHAR("\'e", "e", 233)
|
CHAR("'e", "'\be", 233)
|
||||||
CHAR("\'i", "i", 237)
|
CHAR("'i", "'\bi", 237)
|
||||||
CHAR("\'o", "o", 243)
|
CHAR("'o", "'\bo", 243)
|
||||||
CHAR("\'u", "u", 250)
|
CHAR("'u", "'\bu", 250)
|
||||||
CHAR("^A", "A", 194)
|
CHAR("^A", "^\bA", 194)
|
||||||
CHAR("^E", "E", 202)
|
CHAR("^E", "^\bE", 202)
|
||||||
CHAR("^I", "I", 206)
|
CHAR("^I", "^\bI", 206)
|
||||||
CHAR("^O", "O", 212)
|
CHAR("^O", "^\bO", 212)
|
||||||
CHAR("^U", "U", 219)
|
CHAR("^U", "^\bU", 219)
|
||||||
CHAR("^a", "a", 226)
|
CHAR("^a", "^\ba", 226)
|
||||||
CHAR("^e", "e", 234)
|
CHAR("^e", "^\be", 234)
|
||||||
CHAR("^i", "i", 238)
|
CHAR("^i", "^\bi", 238)
|
||||||
CHAR("^o", "o", 244)
|
CHAR("^o", "^\bo", 244)
|
||||||
CHAR("^u", "u", 251)
|
CHAR("^u", "^\bu", 251)
|
||||||
CHAR("`A", "A", 192)
|
CHAR("`A", "`\bA", 192)
|
||||||
CHAR("`E", "E", 200)
|
CHAR("`E", "`\bE", 200)
|
||||||
CHAR("`I", "I", 204)
|
CHAR("`I", "`\bI", 204)
|
||||||
CHAR("`O", "O", 210)
|
CHAR("`O", "`\bO", 210)
|
||||||
CHAR("`U", "U", 217)
|
CHAR("`U", "`\bU", 217)
|
||||||
CHAR("`a", "a", 224)
|
CHAR("`a", "`\ba", 224)
|
||||||
CHAR("`e", "e", 232)
|
CHAR("`e", "`\be", 232)
|
||||||
CHAR("`i", "i", 236)
|
CHAR("`i", "`\bi", 236)
|
||||||
CHAR("`o", "o", 242)
|
CHAR("`o", "`\bo", 242)
|
||||||
CHAR("`u", "u", 249)
|
CHAR("`u", "`\bu", 249)
|
||||||
CHAR("~A", "A", 195)
|
CHAR("~A", "~\bA", 195)
|
||||||
CHAR("~N", "N", 209)
|
CHAR("~N", "~\bN", 209)
|
||||||
CHAR("~O", "O", 213)
|
CHAR("~O", "~\bO", 213)
|
||||||
CHAR("~a", "a", 227)
|
CHAR("~a", "~\ba", 227)
|
||||||
CHAR("~n", "n", 241)
|
CHAR("~n", "~\bn", 241)
|
||||||
CHAR("~o", "o", 245)
|
CHAR("~o", "~\bo", 245)
|
||||||
|
|
||||||
/* Arrows and lines. */
|
/* Arrows and lines. */
|
||||||
CHAR("<-", "<-", 8592)
|
CHAR("<-", "<-", 8592)
|
||||||
CHAR("->", "->", 8594)
|
CHAR("->", "->", 8594)
|
||||||
CHAR("<>", "<>", 8596)
|
CHAR("<>", "<->", 8596)
|
||||||
CHAR("da", "v", 8595)
|
CHAR("da", "|\bv", 8595)
|
||||||
CHAR("ua", "^", 8593)
|
CHAR("ua", "|\b^", 8593)
|
||||||
CHAR("va", "^v", 8597)
|
CHAR("va", "^v", 8597)
|
||||||
CHAR("lA", "<=", 8656)
|
CHAR("lA", "<=", 8656)
|
||||||
CHAR("rA", "=>", 8658)
|
CHAR("rA", "=>", 8658)
|
||||||
CHAR("hA", "<=>", 8660)
|
CHAR("hA", "<=>", 8660)
|
||||||
CHAR("dA", "v", 8659)
|
CHAR("dA", "=\bv", 8659)
|
||||||
CHAR("uA", "^", 8657)
|
CHAR("uA", "=\b^", 8657)
|
||||||
CHAR("vA", "^=v", 8661)
|
CHAR("vA", "^=v", 8661)
|
||||||
|
|
||||||
/* Logic. */
|
/* Logic. */
|
||||||
@ -249,7 +249,7 @@ CHAR("OR", "v", 8744)
|
|||||||
CHAR("no", "~", 172)
|
CHAR("no", "~", 172)
|
||||||
CHAR("tno", "~", 172)
|
CHAR("tno", "~", 172)
|
||||||
CHAR("te", "3", 8707)
|
CHAR("te", "3", 8707)
|
||||||
CHAR("fa", "V", 8704)
|
CHAR("fa", "-\bV", 8704)
|
||||||
CHAR("st", "-)", 8715)
|
CHAR("st", "-)", 8715)
|
||||||
CHAR("tf", ".:.", 8756)
|
CHAR("tf", ".:.", 8756)
|
||||||
CHAR("3d", ".:.", 8756)
|
CHAR("3d", ".:.", 8756)
|
||||||
@ -266,8 +266,8 @@ CHAR("pc", ".", 183)
|
|||||||
CHAR("md", ".", 8901)
|
CHAR("md", ".", 8901)
|
||||||
CHAR("mu", "x", 215)
|
CHAR("mu", "x", 215)
|
||||||
CHAR("tmu", "x", 215)
|
CHAR("tmu", "x", 215)
|
||||||
CHAR("c*", "x", 8855)
|
CHAR("c*", "O\bx", 8855)
|
||||||
CHAR("c+", "+", 8853)
|
CHAR("c+", "O\b+", 8853)
|
||||||
CHAR("di", "-:-", 247)
|
CHAR("di", "-:-", 247)
|
||||||
CHAR("tdi", "-:-", 247)
|
CHAR("tdi", "-:-", 247)
|
||||||
CHAR("f/", "/", 8260)
|
CHAR("f/", "/", 8260)
|
||||||
@ -293,14 +293,14 @@ CHAR("sb", "(=", 8834)
|
|||||||
CHAR("nb", "(!=", 8836)
|
CHAR("nb", "(!=", 8836)
|
||||||
CHAR("sp", "=)", 8835)
|
CHAR("sp", "=)", 8835)
|
||||||
CHAR("nc", "!=)", 8837)
|
CHAR("nc", "!=)", 8837)
|
||||||
CHAR("ib", "(=", 8838)
|
CHAR("ib", "(=\b_", 8838)
|
||||||
CHAR("ip", "=)", 8839)
|
CHAR("ip", "=\b_)", 8839)
|
||||||
CHAR("ca", "(^)", 8745)
|
CHAR("ca", "(^)", 8745)
|
||||||
CHAR("cu", "U", 8746)
|
CHAR("cu", "U", 8746)
|
||||||
CHAR("/_", "/_", 8736)
|
CHAR("/_", "_\b/", 8736)
|
||||||
CHAR("pp", "_|_", 8869)
|
CHAR("pp", "_\b|", 8869)
|
||||||
CHAR("is", "I", 8747)
|
CHAR("is", "'\b,\bI", 8747)
|
||||||
CHAR("integral", "I", 8747)
|
CHAR("integral", "'\b,\bI", 8747)
|
||||||
CHAR("sum", "E", 8721)
|
CHAR("sum", "E", 8721)
|
||||||
CHAR("product", "TT", 8719)
|
CHAR("product", "TT", 8719)
|
||||||
CHAR("coproduct", "U", 8720)
|
CHAR("coproduct", "U", 8720)
|
||||||
@ -336,22 +336,22 @@ CHAR("IJ", "IJ", 306)
|
|||||||
CHAR("ij", "ij", 307)
|
CHAR("ij", "ij", 307)
|
||||||
|
|
||||||
/* Special letters. */
|
/* Special letters. */
|
||||||
CHAR("-D", "D", 208)
|
CHAR("-D", "-\bD", 208)
|
||||||
CHAR("Sd", "o", 240)
|
CHAR("Sd", "d", 240)
|
||||||
CHAR("TP", "b", 222)
|
CHAR("TP", "Th", 222)
|
||||||
CHAR("Tp", "b", 254)
|
CHAR("Tp", "th", 254)
|
||||||
CHAR(".i", "i", 305)
|
CHAR(".i", "i", 305)
|
||||||
CHAR(".j", "j", 567)
|
CHAR(".j", "j", 567)
|
||||||
|
|
||||||
/* Currency. */
|
/* Currency. */
|
||||||
CHAR("Do", "$", 36)
|
CHAR("Do", "$", 36)
|
||||||
CHAR("ct", "c", 162)
|
CHAR("ct", "/\bc", 162)
|
||||||
CHAR("Eu", "EUR", 8364)
|
CHAR("Eu", "EUR", 8364)
|
||||||
CHAR("eu", "EUR", 8364)
|
CHAR("eu", "EUR", 8364)
|
||||||
CHAR("Ye", "Y", 165)
|
CHAR("Ye", "=\bY", 165)
|
||||||
CHAR("Po", "L", 163)
|
CHAR("Po", "GBP", 163)
|
||||||
CHAR("Cs", "x", 164)
|
CHAR("Cs", "o\bx", 164)
|
||||||
CHAR("Fn", "f", 402)
|
CHAR("Fn", ",\bf", 402)
|
||||||
|
|
||||||
/* Lines. */
|
/* Lines. */
|
||||||
CHAR("ba", "|", 124)
|
CHAR("ba", "|", 124)
|
||||||
@ -363,14 +363,14 @@ CHAR("sl", "/", 47)
|
|||||||
CHAR("rs", "\\", 92)
|
CHAR("rs", "\\", 92)
|
||||||
|
|
||||||
/* Text markers. */
|
/* Text markers. */
|
||||||
CHAR("ci", "o", 9675)
|
CHAR("ci", "O", 9675)
|
||||||
CHAR("bu", "o", 8226)
|
CHAR("bu", "+\bo", 8226)
|
||||||
CHAR("dd", "=", 8225)
|
CHAR("dd", "|\b=", 8225)
|
||||||
CHAR("dg", "-", 8224)
|
CHAR("dg", "|\b-", 8224)
|
||||||
CHAR("lz", "<>", 9674)
|
CHAR("lz", "<>", 9674)
|
||||||
CHAR("sq", "[]", 9633)
|
CHAR("sq", "[]", 9633)
|
||||||
CHAR("ps", "9|", 182)
|
CHAR("ps", "<par>", 182)
|
||||||
CHAR("sc", "S", 167)
|
CHAR("sc", "<sec>", 167)
|
||||||
CHAR("lh", "<=", 9756)
|
CHAR("lh", "<=", 9756)
|
||||||
CHAR("rh", "=>", 9758)
|
CHAR("rh", "=>", 9758)
|
||||||
CHAR("at", "@", 64)
|
CHAR("at", "@", 64)
|
||||||
@ -385,18 +385,18 @@ CHAR("tm", "tm", 8482)
|
|||||||
|
|
||||||
/* Punctuation. */
|
/* Punctuation. */
|
||||||
CHAR(".", ".", 46)
|
CHAR(".", ".", 46)
|
||||||
CHAR("r!", "i", 161)
|
CHAR("r!", "!", 161)
|
||||||
CHAR("r?", "c", 191)
|
CHAR("r?", "?", 191)
|
||||||
CHAR("em", "--", 8212)
|
CHAR("em", "--", 8212)
|
||||||
CHAR("en", "-", 8211)
|
CHAR("en", "-", 8211)
|
||||||
CHAR("hy", "-", 8208)
|
CHAR("hy", "-", 8208)
|
||||||
CHAR("e", "\\", 92)
|
CHAR("e", "\\", 92)
|
||||||
|
|
||||||
/* Units. */
|
/* Units. */
|
||||||
CHAR("de", "o", 176)
|
CHAR("de", "<deg>", 176)
|
||||||
CHAR("%0", "%o", 8240)
|
CHAR("%0", "%o", 8240)
|
||||||
CHAR("fm", "\'", 8242)
|
CHAR("fm", "\'", 8242)
|
||||||
CHAR("sd", "\"", 8243)
|
CHAR("sd", "''", 8243)
|
||||||
CHAR("mc", "mu", 181)
|
CHAR("mc", ",\bu", 181)
|
||||||
|
|
||||||
CHAR_TBL_END
|
CHAR_TBL_END
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FGETLN
|
#if HAVE_FGETLN
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
@ -41,6 +39,9 @@ int dummy;
|
|||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
826
compat_fts.c
Normal file
826
compat_fts.c
Normal file
@ -0,0 +1,826 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if HAVE_FTS
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* $Id: compat_fts.c,v 1.4 2014/08/17 20:45:59 schwarze Exp $ */
|
||||||
|
/* $OpenBSD: fts.c,v 1.46 2014/05/25 17:47:04 tedu Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "compat_fts.h"
|
||||||
|
|
||||||
|
static FTSENT *fts_alloc(FTS *, const char *, size_t);
|
||||||
|
static FTSENT *fts_build(FTS *);
|
||||||
|
static void fts_lfree(FTSENT *);
|
||||||
|
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 unsigned short fts_stat(FTS *, FTSENT *);
|
||||||
|
static int fts_safe_changedir(FTS *, FTSENT *, int, const char *);
|
||||||
|
|
||||||
|
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
|
||||||
|
|
||||||
|
#define CLR(opt) (sp->fts_options &= ~(opt))
|
||||||
|
#define ISSET(opt) (sp->fts_options & (opt))
|
||||||
|
#define SET(opt) (sp->fts_options |= (opt))
|
||||||
|
|
||||||
|
#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
|
||||||
|
|
||||||
|
FTS *
|
||||||
|
fts_open(char * const *argv, int options, void *dummy)
|
||||||
|
{
|
||||||
|
FTS *sp;
|
||||||
|
FTSENT *p, *root;
|
||||||
|
int nitems;
|
||||||
|
FTSENT *parent, *tmp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* Options check. */
|
||||||
|
if (options & ~FTS_OPTIONMASK) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate/initialize the stream */
|
||||||
|
if ((sp = calloc(1, sizeof(FTS))) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
sp->fts_options = options;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start out with 1K of path space, and enough, in any case,
|
||||||
|
* to hold the user's paths.
|
||||||
|
*/
|
||||||
|
if (fts_palloc(sp, MAX(fts_maxarglen(argv), PATH_MAX)))
|
||||||
|
goto mem1;
|
||||||
|
|
||||||
|
/* Allocate/initialize root's parent. */
|
||||||
|
if ((parent = fts_alloc(sp, "", 0)) == NULL)
|
||||||
|
goto mem2;
|
||||||
|
parent->fts_level = FTS_ROOTPARENTLEVEL;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
goto mem3;
|
||||||
|
p->fts_level = FTS_ROOTLEVEL;
|
||||||
|
p->fts_parent = parent;
|
||||||
|
p->fts_accpath = p->fts_name;
|
||||||
|
p->fts_info = fts_stat(sp, p);
|
||||||
|
|
||||||
|
/* Command-line "." and ".." are real directories. */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a dummy pointer and make fts_read think that we've just
|
||||||
|
* finished the node before the root(s); set p->fts_info to FTS_INIT
|
||||||
|
* so that everything about the "current" node is ignored.
|
||||||
|
*/
|
||||||
|
if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
|
||||||
|
goto mem3;
|
||||||
|
sp->fts_cur->fts_link = root;
|
||||||
|
sp->fts_cur->fts_info = FTS_INIT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If using chdir(2), grab a file descriptor pointing to dot to ensure
|
||||||
|
* that we can get back here; this could be avoided for some paths,
|
||||||
|
* but almost certainly not worth the effort. Slashes, symbolic links,
|
||||||
|
* and ".." are all fairly nasty problems. Note, if we can't get the
|
||||||
|
* descriptor we run anyway, just more slowly.
|
||||||
|
*/
|
||||||
|
if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
|
||||||
|
SET(FTS_NOCHDIR);
|
||||||
|
|
||||||
|
if (nitems == 0)
|
||||||
|
free(parent);
|
||||||
|
|
||||||
|
return (sp);
|
||||||
|
|
||||||
|
mem3: fts_lfree(root);
|
||||||
|
free(parent);
|
||||||
|
mem2: free(sp->fts_path);
|
||||||
|
mem1: free(sp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fts_load(FTS *sp, FTSENT *p)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the stream structure for the next traversal. Since we don't
|
||||||
|
* actually enter the directory until after the preorder visit, set
|
||||||
|
* the fts_accpath field specially so the chdir gets done to the right
|
||||||
|
* place and the user can access the first node. From fts_open it's
|
||||||
|
* known that the path will fit.
|
||||||
|
*/
|
||||||
|
len = p->fts_pathlen = p->fts_namelen;
|
||||||
|
memmove(sp->fts_path, p->fts_name, len + 1);
|
||||||
|
if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
|
||||||
|
len = strlen(++cp);
|
||||||
|
memmove(p->fts_name, cp, len + 1);
|
||||||
|
p->fts_namelen = len;
|
||||||
|
}
|
||||||
|
p->fts_accpath = p->fts_path = sp->fts_path;
|
||||||
|
sp->fts_dev = p->fts_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fts_close(FTS *sp)
|
||||||
|
{
|
||||||
|
FTSENT *freep, *p;
|
||||||
|
int rfd, error = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This still works if we haven't read anything -- the dummy structure
|
||||||
|
* points to the root list, so we step through to the end of the root
|
||||||
|
* list which has a valid parent pointer.
|
||||||
|
*/
|
||||||
|
if (sp->fts_cur) {
|
||||||
|
for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
|
||||||
|
freep = p;
|
||||||
|
p = p->fts_link ? p->fts_link : p->fts_parent;
|
||||||
|
free(freep);
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stash the original directory fd if needed. */
|
||||||
|
rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd;
|
||||||
|
|
||||||
|
/* Free up child linked list, sort array, path buffer, stream ptr.*/
|
||||||
|
if (sp->fts_child)
|
||||||
|
fts_lfree(sp->fts_child);
|
||||||
|
free(sp->fts_path);
|
||||||
|
free(sp);
|
||||||
|
|
||||||
|
/* Return to original directory, checking for error. */
|
||||||
|
if (rfd != -1) {
|
||||||
|
int saved_errno;
|
||||||
|
error = fchdir(rfd);
|
||||||
|
saved_errno = errno;
|
||||||
|
(void)close(rfd);
|
||||||
|
errno = saved_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special case of "/" at the end of the path so that slashes aren't
|
||||||
|
* appended which would cause paths to be written as "....//foo".
|
||||||
|
*/
|
||||||
|
#define NAPPEND(p) \
|
||||||
|
(p->fts_path[p->fts_pathlen - 1] == '/' \
|
||||||
|
? p->fts_pathlen - 1 : p->fts_pathlen)
|
||||||
|
|
||||||
|
FTSENT *
|
||||||
|
fts_read(FTS *sp)
|
||||||
|
{
|
||||||
|
FTSENT *p, *tmp;
|
||||||
|
int instr;
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
/* If finished or unrecoverable error, return NULL. */
|
||||||
|
if (sp->fts_cur == NULL || ISSET(FTS_STOP))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* Set current node pointer. */
|
||||||
|
p = sp->fts_cur;
|
||||||
|
|
||||||
|
/* Save and zero out user instructions. */
|
||||||
|
instr = p->fts_instr;
|
||||||
|
p->fts_instr = FTS_NOINSTR;
|
||||||
|
|
||||||
|
/* Directory in pre-order. */
|
||||||
|
if (p->fts_info == FTS_D) {
|
||||||
|
/* If skipped or crossed mount point, do post-order visit. */
|
||||||
|
if (instr == FTS_SKIP ||
|
||||||
|
(ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
|
||||||
|
if (sp->fts_child) {
|
||||||
|
fts_lfree(sp->fts_child);
|
||||||
|
sp->fts_child = NULL;
|
||||||
|
}
|
||||||
|
p->fts_info = FTS_DP;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cd to the subdirectory.
|
||||||
|
*
|
||||||
|
* If have already read and now fail to chdir, whack the list
|
||||||
|
* to make the names come out right, and set the parent errno
|
||||||
|
* so the application will eventually get an error condition.
|
||||||
|
* Set the FTS_DONTCHDIR flag so that when we logically change
|
||||||
|
* directories back to the parent we don't do a chdir.
|
||||||
|
*
|
||||||
|
* If haven't read do so. If the read fails, fts_build sets
|
||||||
|
* FTS_STOP or the fts_info field of the node.
|
||||||
|
*/
|
||||||
|
if (sp->fts_child) {
|
||||||
|
if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
|
||||||
|
p->fts_errno = errno;
|
||||||
|
p->fts_flags |= FTS_DONTCHDIR;
|
||||||
|
for (p = sp->fts_child; p; p = p->fts_link)
|
||||||
|
p->fts_accpath =
|
||||||
|
p->fts_parent->fts_accpath;
|
||||||
|
}
|
||||||
|
} else if ((sp->fts_child = fts_build(sp)) == NULL) {
|
||||||
|
if (ISSET(FTS_STOP))
|
||||||
|
return (NULL);
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
p = sp->fts_child;
|
||||||
|
sp->fts_child = NULL;
|
||||||
|
goto name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next node on this level. */
|
||||||
|
next: tmp = p;
|
||||||
|
if ((p = p->fts_link)) {
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If reached the top, return to the original directory (or
|
||||||
|
* the root of the tree), and load the paths for the next root.
|
||||||
|
*/
|
||||||
|
if (p->fts_level == FTS_ROOTLEVEL) {
|
||||||
|
if (FCHDIR(sp, sp->fts_rfd)) {
|
||||||
|
SET(FTS_STOP);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
fts_load(sp, p);
|
||||||
|
return (sp->fts_cur = p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User may have called fts_set on the node. If skipped,
|
||||||
|
* ignore. If followed, get a file descriptor so we can
|
||||||
|
* get back if necessary.
|
||||||
|
*/
|
||||||
|
if (p->fts_instr == FTS_SKIP)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
name: t = sp->fts_path + NAPPEND(p->fts_parent);
|
||||||
|
*t++ = '/';
|
||||||
|
memmove(t, p->fts_name, p->fts_namelen + 1);
|
||||||
|
return (sp->fts_cur = p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move up to the parent node. */
|
||||||
|
p = tmp->fts_parent;
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
if (p->fts_level == FTS_ROOTPARENTLEVEL) {
|
||||||
|
/*
|
||||||
|
* Done; free everything up and set errno to 0 so the user
|
||||||
|
* can distinguish between error and EOF.
|
||||||
|
*/
|
||||||
|
free(p);
|
||||||
|
errno = 0;
|
||||||
|
return (sp->fts_cur = NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NUL terminate the pathname. */
|
||||||
|
sp->fts_path[p->fts_pathlen] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return to the parent directory. If at a root node or came through
|
||||||
|
* a symlink, go back through the file descriptor. Otherwise, cd up
|
||||||
|
* one directory.
|
||||||
|
*/
|
||||||
|
if (p->fts_level == FTS_ROOTLEVEL) {
|
||||||
|
if (FCHDIR(sp, sp->fts_rfd)) {
|
||||||
|
SET(FTS_STOP);
|
||||||
|
sp->fts_cur = p;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
} else if (!(p->fts_flags & FTS_DONTCHDIR) &&
|
||||||
|
fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
|
||||||
|
SET(FTS_STOP);
|
||||||
|
sp->fts_cur = p;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
|
||||||
|
return (sp->fts_cur = p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fts_set takes the stream as an argument although it's not used in this
|
||||||
|
* implementation; it would be necessary if anyone wanted to add global
|
||||||
|
* semantics to fts using fts_set. An error return is allowed for similar
|
||||||
|
* reasons.
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
int
|
||||||
|
fts_set(FTS *sp, FTSENT *p, int instr)
|
||||||
|
{
|
||||||
|
if (instr && instr != FTS_NOINSTR && instr != FTS_SKIP) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
p->fts_instr = instr;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the tricky part -- do not casually change *anything* in here. The
|
||||||
|
* idea is to build the linked list of entries that are used by fts_children
|
||||||
|
* and fts_read. There are lots of special cases.
|
||||||
|
*
|
||||||
|
* The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
|
||||||
|
* set and it's a physical walk (so that symbolic links can't be directories),
|
||||||
|
* we can do things quickly. First, if it's a 4.4BSD file system, the type
|
||||||
|
* of the file is in the directory entry. Otherwise, we assume that the number
|
||||||
|
* of subdirectories in a node is equal to the number of links to the parent.
|
||||||
|
* The former skips all stat calls. The latter skips stat calls in any leaf
|
||||||
|
* directories and for any files after the subdirectories in the directory have
|
||||||
|
* been found, cutting the stat calls by about 2/3.
|
||||||
|
*/
|
||||||
|
static FTSENT *
|
||||||
|
fts_build(FTS *sp)
|
||||||
|
{
|
||||||
|
struct dirent *dp;
|
||||||
|
FTSENT *p, *head;
|
||||||
|
FTSENT *cur, *tail;
|
||||||
|
DIR *dirp;
|
||||||
|
void *oldaddr;
|
||||||
|
size_t dlen, len, maxlen;
|
||||||
|
int nitems, cderrno, descend, level, nlinks, nostat, doadjust;
|
||||||
|
int saved_errno;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
/* Set current node pointer. */
|
||||||
|
cur = sp->fts_cur;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the directory for reading. If this fails, we're done.
|
||||||
|
* If being called from fts_read, set the fts_info field.
|
||||||
|
*/
|
||||||
|
if ((dirp = opendir(cur->fts_accpath)) == NULL) {
|
||||||
|
cur->fts_info = FTS_DNR;
|
||||||
|
cur->fts_errno = errno;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nlinks is the number of possible entries of type directory in the
|
||||||
|
* directory if we're cheating on stat calls, 0 if we're not doing
|
||||||
|
* any stat calls at all, -1 if we're doing stats on everything.
|
||||||
|
*/
|
||||||
|
nlinks = -1;
|
||||||
|
nostat = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're going to need to stat anything or we want to descend
|
||||||
|
* and stay in the directory, chdir. If this fails we keep going,
|
||||||
|
* but set a flag so we don't chdir after the post-order visit.
|
||||||
|
* We won't be able to stat anything, but we can still return the
|
||||||
|
* names themselves. Note, that since fts_read won't be able to
|
||||||
|
* chdir into the directory, it will have to return different path
|
||||||
|
* names than before, i.e. "a/b" instead of "b". Since the node
|
||||||
|
* has already been visited in pre-order, have to wait until the
|
||||||
|
* post-order visit to return the error. There is a special case
|
||||||
|
* here, if there was nothing to stat then it's not an error to
|
||||||
|
* not be able to stat. This is all fairly nasty. If a program
|
||||||
|
* needed sorted entries or stat information, they had better be
|
||||||
|
* checking FTS_NS on the returned nodes.
|
||||||
|
*/
|
||||||
|
cderrno = 0;
|
||||||
|
if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
|
||||||
|
if (nlinks)
|
||||||
|
cur->fts_errno = errno;
|
||||||
|
cur->fts_flags |= FTS_DONTCHDIR;
|
||||||
|
descend = 0;
|
||||||
|
cderrno = errno;
|
||||||
|
(void)closedir(dirp);
|
||||||
|
dirp = NULL;
|
||||||
|
} else
|
||||||
|
descend = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure out the max file name length that can be stored in the
|
||||||
|
* current path -- the inner loop allocates more path as necessary.
|
||||||
|
* We really wouldn't have to do the maxlen calculations here, we
|
||||||
|
* could do them in fts_read before returning the path, but it's a
|
||||||
|
* lot easier here since the length is part of the dirent structure.
|
||||||
|
*
|
||||||
|
* If not changing directories set a pointer so that can just append
|
||||||
|
* each new name into the path.
|
||||||
|
*/
|
||||||
|
len = NAPPEND(cur);
|
||||||
|
if (ISSET(FTS_NOCHDIR)) {
|
||||||
|
cp = sp->fts_path + len;
|
||||||
|
*cp++ = '/';
|
||||||
|
}
|
||||||
|
len++;
|
||||||
|
maxlen = sp->fts_pathlen - len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fts_level is signed so we must prevent it from wrapping
|
||||||
|
* around to FTS_ROOTLEVEL and FTS_ROOTPARENTLEVEL.
|
||||||
|
*/
|
||||||
|
level = cur->fts_level;
|
||||||
|
if (level < FTS_MAXLEVEL)
|
||||||
|
level++;
|
||||||
|
|
||||||
|
/* Read the directory, attaching each entry to the `link' pointer. */
|
||||||
|
doadjust = 0;
|
||||||
|
for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
|
||||||
|
if (ISDOT(dp->d_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#if HAVE_DIRENT_NAMLEN
|
||||||
|
dlen = dp->d_namlen;
|
||||||
|
#else
|
||||||
|
dlen = strlen(dp->d_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(p = fts_alloc(sp, dp->d_name, dlen)))
|
||||||
|
goto mem1;
|
||||||
|
if (dlen >= maxlen) { /* include space for NUL */
|
||||||
|
oldaddr = sp->fts_path;
|
||||||
|
if (fts_palloc(sp, dlen + len + 1)) {
|
||||||
|
/*
|
||||||
|
* No more memory for path or structures. Save
|
||||||
|
* errno, free up the current structure and the
|
||||||
|
* structures already allocated.
|
||||||
|
*/
|
||||||
|
mem1: saved_errno = errno;
|
||||||
|
if (p)
|
||||||
|
free(p);
|
||||||
|
fts_lfree(head);
|
||||||
|
(void)closedir(dirp);
|
||||||
|
cur->fts_info = FTS_ERR;
|
||||||
|
SET(FTS_STOP);
|
||||||
|
errno = saved_errno;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
/* Did realloc() change the pointer? */
|
||||||
|
if (oldaddr != sp->fts_path) {
|
||||||
|
doadjust = 1;
|
||||||
|
if (ISSET(FTS_NOCHDIR))
|
||||||
|
cp = sp->fts_path + len;
|
||||||
|
}
|
||||||
|
maxlen = sp->fts_pathlen - len;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->fts_level = level;
|
||||||
|
p->fts_parent = sp->fts_cur;
|
||||||
|
p->fts_pathlen = len + dlen;
|
||||||
|
if (p->fts_pathlen < len) {
|
||||||
|
/*
|
||||||
|
* If we wrap, free up the current structure and
|
||||||
|
* the structures already allocated, then error
|
||||||
|
* out with ENAMETOOLONG.
|
||||||
|
*/
|
||||||
|
free(p);
|
||||||
|
fts_lfree(head);
|
||||||
|
(void)closedir(dirp);
|
||||||
|
cur->fts_info = FTS_ERR;
|
||||||
|
SET(FTS_STOP);
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cderrno) {
|
||||||
|
if (nlinks) {
|
||||||
|
p->fts_info = FTS_NS;
|
||||||
|
p->fts_errno = cderrno;
|
||||||
|
} else
|
||||||
|
p->fts_info = FTS_NSOK;
|
||||||
|
p->fts_accpath = cur->fts_accpath;
|
||||||
|
} else if (nlinks == 0
|
||||||
|
#ifdef DT_DIR
|
||||||
|
|| (nostat &&
|
||||||
|
dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
p->fts_accpath =
|
||||||
|
ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
|
||||||
|
p->fts_info = FTS_NSOK;
|
||||||
|
} else {
|
||||||
|
/* Build a file name for fts_stat to stat. */
|
||||||
|
if (ISSET(FTS_NOCHDIR)) {
|
||||||
|
p->fts_accpath = p->fts_path;
|
||||||
|
memmove(cp, p->fts_name, p->fts_namelen + 1);
|
||||||
|
} else
|
||||||
|
p->fts_accpath = p->fts_name;
|
||||||
|
/* Stat it. */
|
||||||
|
p->fts_info = fts_stat(sp, p);
|
||||||
|
|
||||||
|
/* Decrement link count if applicable. */
|
||||||
|
if (nlinks > 0 && (p->fts_info == FTS_D ||
|
||||||
|
p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
|
||||||
|
--nlinks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We walk in directory order so "ls -f" doesn't get upset. */
|
||||||
|
p->fts_link = NULL;
|
||||||
|
if (head == NULL)
|
||||||
|
head = tail = p;
|
||||||
|
else {
|
||||||
|
tail->fts_link = p;
|
||||||
|
tail = p;
|
||||||
|
}
|
||||||
|
++nitems;
|
||||||
|
}
|
||||||
|
if (dirp)
|
||||||
|
(void)closedir(dirp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If realloc() changed the address of the path, adjust the
|
||||||
|
* addresses for the rest of the tree and the dir list.
|
||||||
|
*/
|
||||||
|
if (doadjust)
|
||||||
|
fts_padjust(sp, head);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not changing directories, reset the path back to original
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
if (ISSET(FTS_NOCHDIR)) {
|
||||||
|
if (len == sp->fts_pathlen || nitems == 0)
|
||||||
|
--cp;
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If descended after called from fts_children or after called from
|
||||||
|
* fts_read and nothing found, get back. At the root level we use
|
||||||
|
* the saved fd; if one of fts_open()'s arguments is a relative path
|
||||||
|
* to an empty directory, we wind up here with no other way back. If
|
||||||
|
* can't get back, we're done.
|
||||||
|
*/
|
||||||
|
if (descend && !nitems &&
|
||||||
|
(cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) :
|
||||||
|
fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
|
||||||
|
cur->fts_info = FTS_ERR;
|
||||||
|
SET(FTS_STOP);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If didn't find anything, return NULL. */
|
||||||
|
if (!nitems) {
|
||||||
|
cur->fts_info = FTS_DP;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (head);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned short
|
||||||
|
fts_stat(FTS *sp, FTSENT *p)
|
||||||
|
{
|
||||||
|
FTSENT *t;
|
||||||
|
dev_t dev;
|
||||||
|
ino_t ino;
|
||||||
|
struct stat *sbp;
|
||||||
|
|
||||||
|
/* If user needs stat info, stat buffer already allocated. */
|
||||||
|
sbp = p->fts_statp;
|
||||||
|
|
||||||
|
if (lstat(p->fts_accpath, sbp)) {
|
||||||
|
p->fts_errno = errno;
|
||||||
|
memset(sbp, 0, sizeof(struct stat));
|
||||||
|
return (FTS_NS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_ISDIR(sbp->st_mode)) {
|
||||||
|
/*
|
||||||
|
* Set the device/inode. Used to find cycles and check for
|
||||||
|
* crossing mount points. Also remember the link count, used
|
||||||
|
* in fts_build to limit the number of stat calls. It is
|
||||||
|
* understood that these fields are only referenced if fts_info
|
||||||
|
* is set to FTS_D.
|
||||||
|
*/
|
||||||
|
dev = p->fts_dev = sbp->st_dev;
|
||||||
|
ino = p->fts_ino = sbp->st_ino;
|
||||||
|
p->fts_nlink = sbp->st_nlink;
|
||||||
|
|
||||||
|
if (ISDOT(p->fts_name))
|
||||||
|
return (FTS_DOT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cycle detection is done by brute force when the directory
|
||||||
|
* is first encountered. If the tree gets deep enough or the
|
||||||
|
* number of symbolic links to directories is high enough,
|
||||||
|
* something faster might be worthwhile.
|
||||||
|
*/
|
||||||
|
for (t = p->fts_parent;
|
||||||
|
t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
|
||||||
|
if (ino == t->fts_ino && dev == t->fts_dev) {
|
||||||
|
p->fts_cycle = t;
|
||||||
|
return (FTS_DC);
|
||||||
|
}
|
||||||
|
return (FTS_D);
|
||||||
|
}
|
||||||
|
if (S_ISLNK(sbp->st_mode))
|
||||||
|
return (FTS_SL);
|
||||||
|
if (S_ISREG(sbp->st_mode))
|
||||||
|
return (FTS_F);
|
||||||
|
return (FTS_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FTSENT *
|
||||||
|
fts_alloc(FTS *sp, const char *name, size_t namelen)
|
||||||
|
{
|
||||||
|
FTSENT *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = sizeof(FTSENT) + namelen;
|
||||||
|
if ((p = calloc(1, len)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->fts_path = sp->fts_path;
|
||||||
|
p->fts_namelen = namelen;
|
||||||
|
p->fts_instr = FTS_NOINSTR;
|
||||||
|
p->fts_statp = malloc(sizeof(struct stat));
|
||||||
|
if (p->fts_statp == NULL) {
|
||||||
|
free(p);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memcpy(p->fts_name, name, namelen);
|
||||||
|
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fts_lfree(FTSENT *head)
|
||||||
|
{
|
||||||
|
FTSENT *p;
|
||||||
|
|
||||||
|
/* Free a linked list of structures. */
|
||||||
|
while ((p = head)) {
|
||||||
|
head = head->fts_link;
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow essentially unlimited paths; find, rm, ls should all work on any tree.
|
||||||
|
* Most systems will allow creation of paths much longer than PATH_MAX, even
|
||||||
|
* though the kernel won't resolve them. Add the size (not just what's needed)
|
||||||
|
* plus 256 bytes so don't realloc the path 2 bytes at a time.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
fts_palloc(FTS *sp, size_t more)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for possible wraparound.
|
||||||
|
*/
|
||||||
|
more += 256;
|
||||||
|
if (sp->fts_pathlen + more < sp->fts_pathlen) {
|
||||||
|
if (sp->fts_path)
|
||||||
|
free(sp->fts_path);
|
||||||
|
sp->fts_path = NULL;
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
sp->fts_pathlen += more;
|
||||||
|
p = realloc(sp->fts_path, sp->fts_pathlen);
|
||||||
|
if (p == NULL) {
|
||||||
|
if (sp->fts_path)
|
||||||
|
free(sp->fts_path);
|
||||||
|
sp->fts_path = NULL;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
sp->fts_path = p;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the path is realloc'd, have to fix all of the pointers in structures
|
||||||
|
* already returned.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
fts_padjust(FTS *sp, FTSENT *head)
|
||||||
|
{
|
||||||
|
FTSENT *p;
|
||||||
|
char *addr = sp->fts_path;
|
||||||
|
|
||||||
|
#define ADJUST(p) { \
|
||||||
|
if ((p)->fts_accpath != (p)->fts_name) { \
|
||||||
|
(p)->fts_accpath = \
|
||||||
|
(char *)addr + ((p)->fts_accpath - (p)->fts_path); \
|
||||||
|
} \
|
||||||
|
(p)->fts_path = addr; \
|
||||||
|
}
|
||||||
|
/* Adjust the current set of children. */
|
||||||
|
for (p = sp->fts_child; p; p = p->fts_link)
|
||||||
|
ADJUST(p);
|
||||||
|
|
||||||
|
/* Adjust the rest of the tree, including the current level. */
|
||||||
|
for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
|
||||||
|
ADJUST(p);
|
||||||
|
p = p->fts_link ? p->fts_link : p->fts_parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fts_maxarglen(char * const *argv)
|
||||||
|
{
|
||||||
|
size_t len, max;
|
||||||
|
|
||||||
|
for (max = 0; *argv; ++argv)
|
||||||
|
if ((len = strlen(*argv)) > max)
|
||||||
|
max = len;
|
||||||
|
return (max + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change to dir specified by fd or p->fts_accpath without getting
|
||||||
|
* tricked by someone changing the world out from underneath us.
|
||||||
|
* Assumes p->fts_dev and p->fts_ino are filled in.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
|
||||||
|
{
|
||||||
|
int ret, oerrno, newfd;
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
newfd = fd;
|
||||||
|
if (ISSET(FTS_NOCHDIR))
|
||||||
|
return (0);
|
||||||
|
if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
|
||||||
|
return (-1);
|
||||||
|
if (fstat(newfd, &sb)) {
|
||||||
|
ret = -1;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
|
||||||
|
errno = ENOENT; /* disinformation */
|
||||||
|
ret = -1;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
ret = fchdir(newfd);
|
||||||
|
bail:
|
||||||
|
oerrno = errno;
|
||||||
|
if (fd < 0)
|
||||||
|
(void)close(newfd);
|
||||||
|
errno = oerrno;
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
106
compat_fts.h
Normal file
106
compat_fts.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* $OpenBSD: fts.h,v 1.14 2012/12/05 23:19:57 deraadt Exp $ */
|
||||||
|
/* $NetBSD: fts.h,v 1.7 2012/03/01 16:18:51 hans Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)fts.h 8.3 (Berkeley) 8/14/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FTS_H_
|
||||||
|
#define _FTS_H_
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct _ftsent *fts_cur; /* current node */
|
||||||
|
struct _ftsent *fts_child; /* linked list of children */
|
||||||
|
dev_t fts_dev; /* starting device # */
|
||||||
|
char *fts_path; /* path for this descent */
|
||||||
|
int fts_rfd; /* fd for root */
|
||||||
|
size_t fts_pathlen; /* sizeof(path) */
|
||||||
|
|
||||||
|
#define FTS_NOCHDIR 0x0004 /* don't change directories */
|
||||||
|
#define FTS_PHYSICAL 0x0010 /* physical walk */
|
||||||
|
#define FTS_XDEV 0x0040 /* don't cross devices */
|
||||||
|
#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
|
||||||
|
|
||||||
|
#define FTS_STOP 0x2000 /* (private) unrecoverable error */
|
||||||
|
int fts_options; /* fts_open options, global flags */
|
||||||
|
} FTS;
|
||||||
|
|
||||||
|
typedef struct _ftsent {
|
||||||
|
struct _ftsent *fts_cycle; /* cycle node */
|
||||||
|
struct _ftsent *fts_parent; /* parent directory */
|
||||||
|
struct _ftsent *fts_link; /* next file in directory */
|
||||||
|
char *fts_accpath; /* access path */
|
||||||
|
char *fts_path; /* root path */
|
||||||
|
int fts_errno; /* errno for this node */
|
||||||
|
size_t fts_pathlen; /* strlen(fts_path) */
|
||||||
|
size_t fts_namelen; /* strlen(fts_name) */
|
||||||
|
|
||||||
|
ino_t fts_ino; /* inode */
|
||||||
|
dev_t fts_dev; /* device */
|
||||||
|
nlink_t fts_nlink; /* link count */
|
||||||
|
|
||||||
|
#define FTS_ROOTPARENTLEVEL -1
|
||||||
|
#define FTS_ROOTLEVEL 0
|
||||||
|
#define FTS_MAXLEVEL 0x7fffffff
|
||||||
|
int fts_level; /* depth (-1 to N) */
|
||||||
|
|
||||||
|
#define FTS_D 1 /* preorder directory */
|
||||||
|
#define FTS_DC 2 /* directory that causes cycles */
|
||||||
|
#define FTS_DEFAULT 3 /* none of the above */
|
||||||
|
#define FTS_DNR 4 /* unreadable directory */
|
||||||
|
#define FTS_DOT 5 /* dot or dot-dot */
|
||||||
|
#define FTS_DP 6 /* postorder directory */
|
||||||
|
#define FTS_ERR 7 /* error; errno is set */
|
||||||
|
#define FTS_F 8 /* regular file */
|
||||||
|
#define FTS_INIT 9 /* initialized only */
|
||||||
|
#define FTS_NS 10 /* stat(2) failed */
|
||||||
|
#define FTS_NSOK 11 /* no stat(2) requested */
|
||||||
|
#define FTS_SL 12 /* symbolic link */
|
||||||
|
unsigned short fts_info; /* user flags for FTSENT structure */
|
||||||
|
|
||||||
|
#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
|
||||||
|
unsigned short fts_flags; /* private flags for FTSENT structure */
|
||||||
|
|
||||||
|
#define FTS_NOINSTR 3 /* no instructions */
|
||||||
|
#define FTS_SKIP 4 /* discard node */
|
||||||
|
unsigned short fts_instr; /* fts_set() instructions */
|
||||||
|
|
||||||
|
struct stat *fts_statp; /* stat(2) information */
|
||||||
|
char fts_name[1]; /* file name */
|
||||||
|
} FTSENT;
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
int fts_close(FTS *);
|
||||||
|
FTS *fts_open(char * const *, int, void *);
|
||||||
|
FTSENT *fts_read(FTS *);
|
||||||
|
int fts_set(FTS *, FTSENT *, int);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* !_FTS_H_ */
|
@ -1,13 +1,12 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETSUBOPT
|
#if HAVE_GETSUBOPT
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/* $Id: compat_getsubopt.c,v 1.5 2014/08/17 20:53:50 schwarze Exp $ */
|
||||||
/* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $ */
|
/* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
@ -43,18 +42,11 @@ int dummy;
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* The SVID interface to getsubopt provides no way of figuring out which
|
|
||||||
* part of the suboptions list wasn't matched. This makes error messages
|
|
||||||
* tricky... The extern variable suboptarg is a pointer to the token
|
|
||||||
* which didn't match.
|
|
||||||
*/
|
|
||||||
char *suboptarg;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
getsubopt(char **optionp, char * const *tokens, char **valuep)
|
getsubopt(char **optionp, char * const *tokens, char **valuep)
|
||||||
{
|
{
|
||||||
int cnt;
|
int cnt;
|
||||||
|
char *suboptarg;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
suboptarg = *valuep = NULL;
|
suboptarg = *valuep = NULL;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_OHASH
|
#if HAVE_OHASH
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
@ -25,6 +23,8 @@ int dummy;
|
|||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_REALLOCARRAY
|
#if HAVE_REALLOCARRAY
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SQLITE3_ERRSTR
|
#if HAVE_SQLITE3_ERRSTR
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRCASESTR
|
#if HAVE_STRCASESTR
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRLCAT
|
#if HAVE_STRLCAT
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRLCPY
|
#if HAVE_STRLCPY
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRSEP
|
#if HAVE_STRSEP
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
#if !defined(__BEGIN_DECLS)
|
|
||||||
# ifdef __cplusplus
|
|
||||||
# define __BEGIN_DECLS extern "C" {
|
|
||||||
# else
|
|
||||||
# define __BEGIN_DECLS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if !defined(__END_DECLS)
|
|
||||||
# ifdef __cplusplus
|
|
||||||
# define __END_DECLS }
|
|
||||||
# else
|
|
||||||
# define __END_DECLS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_FGETLN
|
|
||||||
extern char *fgetln(FILE *, size_t *);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_GETSUBOPT
|
|
||||||
extern int getsubopt(char **, char * const *, char **);
|
|
||||||
extern char *suboptarg;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_REALLOCARRAY
|
|
||||||
extern void *reallocarray(void *, size_t, size_t);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_SQLITE3_ERRSTR
|
|
||||||
extern const char *sqlite3_errstr(int);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_STRCASESTR
|
|
||||||
extern char *strcasestr(const char *, const char *);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_STRLCAT
|
|
||||||
extern size_t strlcat(char *, const char *, size_t);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_STRLCPY
|
|
||||||
extern size_t strlcpy(char *, const char *, size_t);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_STRSEP
|
|
||||||
extern char *strsep(char **, const char *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MANDOC_CONFIG_H */
|
|
@ -1,9 +0,0 @@
|
|||||||
#ifndef MANDOC_CONFIG_H
|
|
||||||
#define MANDOC_CONFIG_H
|
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__MINT__)
|
|
||||||
# define _GNU_SOURCE /* getsubopt(), strcasestr(), strptime() */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdio.h>
|
|
390
configure
vendored
390
configure
vendored
@ -14,36 +14,380 @@
|
|||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
echo "/* RUNNING ./CONFIGURE - SHOULD BE USED ONLY VIA MAKE, READ INSTALL */"
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
exec > config.h 2> config.log
|
|
||||||
|
|
||||||
CFLAGS="${CFLAGS} -Wno-unused -Werror"
|
[ -e config.log ] && mv config.log config.log.old
|
||||||
|
[ -e config.h ] && mv config.h config.h.old
|
||||||
|
|
||||||
runtest() {
|
# Output file descriptor usage:
|
||||||
echo ${CC} ${CFLAGS} ${3} -o test-${1} test-${1}.c 1>&2
|
# 1 (stdout): config.h, Makefile.local
|
||||||
${CC} ${CFLAGS} ${3} -o "test-${1}" "test-${1}.c" 1>&2 || return 0
|
# 2 (stderr): original stderr, usually to the console
|
||||||
"./test-${1}" && echo "#define HAVE_${2}" \
|
# 3: config.log
|
||||||
|| echo FAILURE: test-${1} returned $? 1>&2
|
|
||||||
rm "test-${1}"
|
exec 3> config.log
|
||||||
|
echo "config.log: writing..."
|
||||||
|
|
||||||
|
# --- default settings -------------------------------------------------
|
||||||
|
# Initialize all variables here,
|
||||||
|
# such that nothing can leak in from the environment.
|
||||||
|
|
||||||
|
VERSION="1.13.1"
|
||||||
|
echo "VERSION=\"${VERSION}\"" 1>&2
|
||||||
|
echo "VERSION=\"${VERSION}\"" 1>&3
|
||||||
|
|
||||||
|
OSNAME=
|
||||||
|
|
||||||
|
CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make -f -`
|
||||||
|
CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings"
|
||||||
|
DBLIB=
|
||||||
|
STATIC="-static"
|
||||||
|
|
||||||
|
BUILD_DB=1
|
||||||
|
BUILD_CGI=0
|
||||||
|
|
||||||
|
HAVE_DIRENT_NAMLEN=
|
||||||
|
HAVE_FGETLN=
|
||||||
|
HAVE_FTS=
|
||||||
|
HAVE_GETSUBOPT=
|
||||||
|
HAVE_MMAP=
|
||||||
|
HAVE_REALLOCARRAY=
|
||||||
|
HAVE_STRCASESTR=
|
||||||
|
HAVE_STRLCAT=
|
||||||
|
HAVE_STRLCPY=
|
||||||
|
HAVE_STRPTIME=
|
||||||
|
HAVE_STRSEP=
|
||||||
|
HAVE_WCHAR=
|
||||||
|
|
||||||
|
HAVE_SQLITE3=
|
||||||
|
HAVE_SQLITE3_ERRSTR=
|
||||||
|
HAVE_OHASH=
|
||||||
|
HAVE_MANPATH=
|
||||||
|
|
||||||
|
PREFIX="/usr/local"
|
||||||
|
BINDIR=
|
||||||
|
SBINDIR=
|
||||||
|
INCLUDEDIR=
|
||||||
|
LIBDIR=
|
||||||
|
MANDIR=
|
||||||
|
EXAMPLEDIR=
|
||||||
|
|
||||||
|
WWWPREFIX="/var/www"
|
||||||
|
HTDOCDIR=
|
||||||
|
CGIBINDIR=
|
||||||
|
|
||||||
|
INSTALL="install"
|
||||||
|
INSTALL_PROGRAM=
|
||||||
|
INSTALL_LIB=
|
||||||
|
INSTALL_MAN=
|
||||||
|
INSTALL_DATA=
|
||||||
|
|
||||||
|
# --- manual settings from configure.local -----------------------------
|
||||||
|
|
||||||
|
if [ -e ./configure.local ]; then
|
||||||
|
echo "configure.local: reading..." 1>&2
|
||||||
|
echo "configure.local: reading..." 1>&3
|
||||||
|
cat ./configure.local 1>&3
|
||||||
|
. ./configure.local
|
||||||
|
else
|
||||||
|
echo "configure.local: no (fully automatic configuration)" 1>&2
|
||||||
|
echo "configure.local: no (fully automatic configuration)" 1>&3
|
||||||
|
fi
|
||||||
|
echo 1>&3
|
||||||
|
|
||||||
|
# --- tests for config.h ----------------------------------------------
|
||||||
|
|
||||||
|
COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
|
||||||
|
|
||||||
|
# Check whether this HAVE_ setting is manually overridden.
|
||||||
|
# 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
|
||||||
|
echo 1>&3
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
cat config.h.pre
|
# Run a single autoconfiguration test.
|
||||||
|
# In case of success, enable the feature.
|
||||||
|
# In case of failure, do not decide anything yet.
|
||||||
|
# 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
|
||||||
|
__HEREDOC__
|
||||||
|
|
||||||
|
if ${COMP} ${3} -o "test-${1}" "test-${1}.c" 1>&3 2>&3; then
|
||||||
|
echo "${1}: ${CC} succeeded" 1>&3
|
||||||
|
else
|
||||||
|
echo "${1}: ${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
|
||||||
|
eval HAVE_${2}=1
|
||||||
|
rm "test-${1}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "${1}: execution failed with $?" 1>&3
|
||||||
|
echo 1>&3
|
||||||
|
rm "test-${1}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a complete autoconfiguration test, including the check for
|
||||||
|
# a manual override and disabling the feature on failure.
|
||||||
|
# Arguments: lower case name, upper case name, additional CFLAGS
|
||||||
|
runtest() {
|
||||||
|
eval _manual=\${HAVE_${2}}
|
||||||
|
ismanual "${1}" "${_manual}" && return 0
|
||||||
|
singletest "${1}" "${2}" "${3}" && return 0
|
||||||
|
echo "${1}: no" 1>&2
|
||||||
|
eval HAVE_${2}=0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- library functions ---
|
||||||
|
runtest dirent-namlen DIRENT_NAMLEN || true
|
||||||
|
runtest fgetln FGETLN || true
|
||||||
|
runtest fts FTS || true
|
||||||
|
runtest getsubopt GETSUBOPT || true
|
||||||
|
runtest mmap MMAP || true
|
||||||
|
runtest reallocarray REALLOCARRAY || true
|
||||||
|
runtest strcasestr STRCASESTR || true
|
||||||
|
runtest strlcat STRLCAT || true
|
||||||
|
runtest strlcpy STRLCPY || true
|
||||||
|
runtest strptime STRPTIME || true
|
||||||
|
runtest strsep STRSEP || true
|
||||||
|
runtest wchar WCHAR || true
|
||||||
|
|
||||||
|
# --- sqlite3 ---
|
||||||
|
DETECTLIB=
|
||||||
|
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
|
||||||
|
DETECTLIB="-lsqlite3"
|
||||||
|
elif [ -n "${DBLIB}" ]; then
|
||||||
|
runtest sqlite3 SQLITE3 "${DBLIB}" || true
|
||||||
|
elif singletest sqlite3 SQLITE3 "-lsqlite3"; then
|
||||||
|
DETECTLIB="-lsqlite3"
|
||||||
|
elif runtest sqlite3 SQLITE3 \
|
||||||
|
"-I/usr/local/include -L/usr/local/lib -lsqlite3"; then
|
||||||
|
DETECTLIB="-L/usr/local/lib -lsqlite3"
|
||||||
|
CFLAGS="${CFLAGS} -I/usr/local/include"
|
||||||
|
fi
|
||||||
|
if [ ${BUILD_DB} -gt 0 -a ${HAVE_SQLITE3} -eq 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
|
||||||
|
|
||||||
|
# --- sqlite3_errstr ---
|
||||||
|
if [ ${BUILD_DB} -eq 0 ]; then
|
||||||
|
HAVE_SQLITE3_ERRSTR=1
|
||||||
|
elif ismanual sqlite3_errstr "${HAVE_SQLITE3_ERRSTR}"; then
|
||||||
|
:
|
||||||
|
elif [ -n "${DBLIB}" ]; then
|
||||||
|
runtest sqlite3_errstr SQLITE3_ERRSTR "${DBLIB}" || true
|
||||||
|
else
|
||||||
|
runtest sqlite3_errstr SQLITE3_ERRSTR "${DETECTLIB}" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- ohash ---
|
||||||
|
if [ ${BUILD_DB} -eq 0 ]; then
|
||||||
|
HAVE_OHASH=1
|
||||||
|
elif ismanual ohash "${HAVE_OHASH}"; then
|
||||||
|
:
|
||||||
|
elif [ -n "${DBLIB}" ]; then
|
||||||
|
runtest ohash OHASH "${DBLIB}" || true
|
||||||
|
elif singletest ohash OHASH; then
|
||||||
|
:
|
||||||
|
elif runtest ohash OHASH "-lutil"; then
|
||||||
|
DETECTLIB="${DETECTLIB} -lutil"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- DBLIB ---
|
||||||
|
if [ ${BUILD_DB} -eq 0 ]; then
|
||||||
|
DBLIB=
|
||||||
|
elif [ -z "${DBLIB}" ]; then
|
||||||
|
DBLIB="${DETECTLIB}"
|
||||||
|
echo "DBLIB=\"${DBLIB}\"" 1>&2
|
||||||
|
echo "DBLIB=\"${DBLIB}\"" 1>&3
|
||||||
|
echo 1>&3
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- manpath ---
|
||||||
|
if [ ${BUILD_DB} -eq 0 ]; then
|
||||||
|
HAVE_MANPATH=0
|
||||||
|
elif 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
|
||||||
|
|
||||||
|
cat << __HEREDOC__
|
||||||
|
#ifndef MANDOC_CONFIG_H
|
||||||
|
#define MANDOC_CONFIG_H
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__MINT__)
|
||||||
|
#define _GNU_SOURCE /* See test-*.c what needs this. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__HEREDOC__
|
||||||
|
|
||||||
|
[ ${HAVE_FGETLN} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \
|
||||||
|
${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \
|
||||||
|
&& echo "#include <sys/types.h>"
|
||||||
|
[ ${HAVE_FGETLN} -eq 0 ] && echo "#include <stdio.h>"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "#define VERSION \"${VERSION}\""
|
echo "#define VERSION \"${VERSION}\""
|
||||||
runtest fgetln FGETLN
|
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
|
||||||
runtest getsubopt GETSUBOPT
|
|
||||||
runtest mmap MMAP
|
cat << __HEREDOC__
|
||||||
runtest ohash OHASH "${DBLIB}"
|
#define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN}
|
||||||
runtest reallocarray REALLOCARRAY
|
#define HAVE_FGETLN ${HAVE_FGETLN}
|
||||||
runtest sqlite3_errstr SQLITE3_ERRSTR "${DBLIB}"
|
#define HAVE_FTS ${HAVE_FTS}
|
||||||
runtest strcasestr STRCASESTR
|
#define HAVE_GETSUBOPT ${HAVE_GETSUBOPT}
|
||||||
runtest strlcat STRLCAT
|
#define HAVE_MMAP ${HAVE_MMAP}
|
||||||
runtest strlcpy STRLCPY
|
#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY}
|
||||||
runtest strptime STRPTIME
|
#define HAVE_STRCASESTR ${HAVE_STRCASESTR}
|
||||||
runtest strsep STRSEP
|
#define HAVE_STRLCAT ${HAVE_STRLCAT}
|
||||||
|
#define HAVE_STRLCPY ${HAVE_STRLCPY}
|
||||||
|
#define HAVE_STRPTIME ${HAVE_STRPTIME}
|
||||||
|
#define HAVE_STRSEP ${HAVE_STRSEP}
|
||||||
|
#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}
|
||||||
|
|
||||||
|
#if !defined(__BEGIN_DECLS)
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define __BEGIN_DECLS extern "C" {
|
||||||
|
# else
|
||||||
|
# define __BEGIN_DECLS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !defined(__END_DECLS)
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define __END_DECLS }
|
||||||
|
# else
|
||||||
|
# define __END_DECLS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__HEREDOC__
|
||||||
|
|
||||||
|
[ ${HAVE_FGETLN} -eq 0 ] && \
|
||||||
|
echo "extern char *fgetln(FILE *, size_t *);"
|
||||||
|
|
||||||
|
[ ${HAVE_GETSUBOPT} -eq 0 ] && \
|
||||||
|
echo "extern int getsubopt(char **, char * const *, char **);"
|
||||||
|
|
||||||
|
[ ${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 *);"
|
||||||
|
|
||||||
|
[ ${HAVE_STRLCAT} -eq 0 ] && \
|
||||||
|
echo "extern size_t strlcat(char *, const char *, size_t);"
|
||||||
|
|
||||||
|
[ ${HAVE_STRLCPY} -eq 0 ] && \
|
||||||
|
echo "extern size_t strlcpy(char *, const char *, size_t);"
|
||||||
|
|
||||||
|
[ ${HAVE_STRSEP} -eq 0 ] && \
|
||||||
|
echo "extern char *strsep(char **, const char *);"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
cat config.h.post
|
echo "#endif /* MANDOC_CONFIG_H */"
|
||||||
|
|
||||||
|
echo "config.h: written" 1>&2
|
||||||
|
echo "config.h: written" 1>&3
|
||||||
|
|
||||||
|
# --- tests for Makefile.local -----------------------------------------
|
||||||
|
|
||||||
|
exec > Makefile.local
|
||||||
|
|
||||||
|
[ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin"
|
||||||
|
[ -z "${SBINDIR}" ] && SBINDIR="${PREFIX}/sbin"
|
||||||
|
[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||||
|
[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib/mandoc"
|
||||||
|
[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"
|
||||||
|
[ -z "${EXAMPLEDIR}" ] && EXAMPLEDIR="${PREFIX}/share/examples/mandoc"
|
||||||
|
|
||||||
|
[ -z "${HTDOCDIR}" ] && HTDOCDIR="${WWWPREFIX}/htdocs"
|
||||||
|
[ -z "${CGIBINDIR}" ] && CGIBINDIR="${WWWPREFIX}/cgi-bin"
|
||||||
|
|
||||||
|
[ -z "${INSTALL_PROGRAM}" ] && INSTALL_PROGRAM="${INSTALL} -m 0555"
|
||||||
|
[ -z "${INSTALL_LIB}" ] && INSTALL_LIB="${INSTALL} -m 0444"
|
||||||
|
[ -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_DB} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} db-build"
|
||||||
|
[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} cgi-build"
|
||||||
|
|
||||||
|
cat << __HEREDOC__
|
||||||
|
VERSION = ${VERSION}
|
||||||
|
BUILD_TARGETS = ${BUILD_TARGETS}
|
||||||
|
CFLAGS = ${CFLAGS}
|
||||||
|
DBLIB = ${DBLIB}
|
||||||
|
STATIC = ${STATIC}
|
||||||
|
PREFIX = ${PREFIX}
|
||||||
|
BINDIR = ${BINDIR}
|
||||||
|
SBINDIR = ${SBINDIR}
|
||||||
|
INCLUDEDIR = ${INCLUDEDIR}
|
||||||
|
LIBDIR = ${LIBDIR}
|
||||||
|
MANDIR = ${MANDIR}
|
||||||
|
EXAMPLEDIR = ${EXAMPLEDIR}
|
||||||
|
WWWPREFIX = ${WWWPREFIX}
|
||||||
|
HTDOCDIR = ${HTDOCDIR}
|
||||||
|
CGIBINDIR = ${CGIBINDIR}
|
||||||
|
INSTALL = ${INSTALL}
|
||||||
|
INSTALL_PROGRAM = ${INSTALL_PROGRAM}
|
||||||
|
INSTALL_LIB = ${INSTALL_LIB}
|
||||||
|
INSTALL_MAN = ${INSTALL_MAN}
|
||||||
|
INSTALL_DATA = ${INSTALL_DATA}
|
||||||
|
__HEREDOC__
|
||||||
|
|
||||||
|
[ ${BUILD_DB} -gt 0 ] && \
|
||||||
|
echo "MAN_OBJS = \$(MANDOC_OBJS) \$(APROPOS_OBJS)"
|
||||||
|
|
||||||
|
echo "Makefile.local: written" 1>&2
|
||||||
|
echo "Makefile.local: written" 1>&3
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
189
configure.local.example
Normal file
189
configure.local.example
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# $Id: configure.local.example,v 1.1 2014/08/16 19:00:01 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.
|
||||||
|
|
||||||
|
# For all settings documented in this file, there are reasonable
|
||||||
|
# defaults and/or the ./configure script attempts autodetection.
|
||||||
|
# Consequently, you only need to create a file ./configure.local
|
||||||
|
# and put any of these settings into it if ./configure autodetection
|
||||||
|
# fails or if you want to make different choices for other reasons.
|
||||||
|
|
||||||
|
# If autodetection fails, please tell <tech@mdocml.bsd.lv>.
|
||||||
|
|
||||||
|
# We recommend that you write ./configure.local from scratch and
|
||||||
|
# only put the lines there you need. This file contains examples.
|
||||||
|
# It is not intended as a template to be copied as a whole.
|
||||||
|
|
||||||
|
# --- user settings relevant for all builds ----------------------------
|
||||||
|
|
||||||
|
# For -Tutf8 and -Tlocale operation, mandoc(1) requires <locale.h>
|
||||||
|
# providing setlocale(3) and <wchar.h> providing wcwidth(3) and
|
||||||
|
# putwchar(3) with a wchar_t storing UCS-4 values. Theoretically,
|
||||||
|
# the latter should be tested with the __STDC_ISO_10646__ feature
|
||||||
|
# macro. In practice, many <wchar.h> headers do not provide that
|
||||||
|
# macro even though they treat wchar_t as UCS-4. So the automatic
|
||||||
|
# test only checks that wchar_t is wide enough, that is, at least
|
||||||
|
# four bytes.
|
||||||
|
|
||||||
|
# The following line forces multi-byte support.
|
||||||
|
# If your C library does not treat wchar_t as UCS-4, the UTF-8 output
|
||||||
|
# mode will print garbage.
|
||||||
|
|
||||||
|
HAVE_WCHAR=1
|
||||||
|
|
||||||
|
# The following line disables multi-byte support.
|
||||||
|
# The output modes -Tutf8 and -Tlocale will be the same as -Tascii.
|
||||||
|
|
||||||
|
HAVE_WCHAR=0
|
||||||
|
|
||||||
|
# In manual pages written in the mdoc(7) language, the operating system
|
||||||
|
# version is displayed in the page footer line. If an operating system
|
||||||
|
# is specified as an argument to the .Os macro, that is always used.
|
||||||
|
# If the .Os macro has no argument and an operation system is specified
|
||||||
|
# with the mandoc(1) -Ios= command line option, that is used.
|
||||||
|
# Otherwise, the uname(3) library function is called at runtime to find
|
||||||
|
# the name of the operating system.
|
||||||
|
# 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.5"
|
||||||
|
|
||||||
|
# The following installation directories are used.
|
||||||
|
# It is possible to set only one or a few of these variables,
|
||||||
|
# there is no need to copy the whole block.
|
||||||
|
# Even if you set PREFIX to something else, the other variables
|
||||||
|
# pick it up without copying them all over.
|
||||||
|
|
||||||
|
PREFIX="/usr/local"
|
||||||
|
BINDIR="${PREFIX}/bin"
|
||||||
|
SBINDIR="${PREFIX}/sbin"
|
||||||
|
INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||||
|
LIBDIR="${PREFIX}/lib/mandoc"
|
||||||
|
MANDIR="${PREFIX}/man"
|
||||||
|
EXAMPLEDIR="${PREFIX}/share/examples/mandoc"
|
||||||
|
|
||||||
|
# It is possible to change the utility program used for installation
|
||||||
|
# and the modes files are installed with. The defaults are:
|
||||||
|
|
||||||
|
INSTALL="install"
|
||||||
|
INSTALL_PROGRAM="${INSTALL} -m 0555"
|
||||||
|
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
|
||||||
|
|
||||||
|
# Two libraries are needed: SQLite3 and ohash(3).
|
||||||
|
# Autoconfiguration tries the following linker flags to find them.
|
||||||
|
# If none of these work, add a working DBLIB line to configure.local,
|
||||||
|
# disabling autodetection for library directories.
|
||||||
|
|
||||||
|
DBLIB="-lsqlite3"
|
||||||
|
DBLIB="-lsqlite3 -lutil"
|
||||||
|
DBLIB="-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 DBLIB to something including -L/usr/local/lib,
|
||||||
|
# chances are you will also need the following line:
|
||||||
|
|
||||||
|
CFLAGS="${CFLAGS} -I/usr/local/include"
|
||||||
|
|
||||||
|
# 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,
|
||||||
|
# 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,
|
||||||
|
# makewhatis(8) and apropos(1) will not work properly.
|
||||||
|
|
||||||
|
HAVE_MANPATH=0
|
||||||
|
|
||||||
|
# --- user settings related 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
|
||||||
|
|
||||||
|
# The remaining settings in this section are only relevant if BUILD_CGI
|
||||||
|
# is enabled. Otherwise, they have no effect either way.
|
||||||
|
|
||||||
|
# By default, man.cgi(8) is linked statically.
|
||||||
|
# Some systems do not support static linking, for example Mac OS X.
|
||||||
|
# In that case, use the following line:
|
||||||
|
|
||||||
|
STATIC=
|
||||||
|
|
||||||
|
# Some systems, for example Linux, require -pthread for static linking:
|
||||||
|
|
||||||
|
STATIC="-static -pthread"
|
||||||
|
|
||||||
|
# Some directories.
|
||||||
|
# This works just like PREFIX, see above.
|
||||||
|
|
||||||
|
WWWPREFIX="/var/www"
|
||||||
|
HTDOCDIR="${WWWPREFIX}/htdocs"
|
||||||
|
CGIBINDIR="${WWWPREFIX}/cgi-bin"
|
||||||
|
|
||||||
|
# --- settings that rarely need to be touched --------------------------
|
||||||
|
|
||||||
|
# Do not set these variables unless you really need to.
|
||||||
|
|
||||||
|
# You can manually override the compiler to be used.
|
||||||
|
# But that's rarely useful because ./configure asks your make(1)
|
||||||
|
# which compiler to use, and that answer will hardly be wrong.
|
||||||
|
|
||||||
|
CC=cc
|
||||||
|
|
||||||
|
# The default compiler flags are:
|
||||||
|
|
||||||
|
CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings"
|
||||||
|
|
||||||
|
# In rare cases, it may be required to skip individual automatic tests.
|
||||||
|
# Each of the following variables can be set to 0 (test will not be run
|
||||||
|
# and will be regarded as failed) or 1 (test will not be run and will
|
||||||
|
# be regarded as successful).
|
||||||
|
|
||||||
|
HAVE_DIRENT_NAMLEN=0
|
||||||
|
HAVE_FGETLN=0
|
||||||
|
HAVE_FTS=0
|
||||||
|
HAVE_GETSUBOPT=0
|
||||||
|
HAVE_MMAP=0
|
||||||
|
HAVE_REALLOCARRAY=0
|
||||||
|
HAVE_STRCASESTR=0
|
||||||
|
HAVE_STRLCAT=0
|
||||||
|
HAVE_STRLCPY=0
|
||||||
|
HAVE_STRPTIME=0
|
||||||
|
HAVE_STRSEP=0
|
||||||
|
|
||||||
|
HAVE_SQLITE3=0
|
||||||
|
HAVE_SQLITE3_ERRSTR=0
|
||||||
|
HAVE_OHASH=0
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: demandoc.1,v 1.7 2013/07/13 19:41:16 schwarze Exp $
|
.\" $Id: demandoc.1,v 1.8 2014/09/12 00:10:26 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
.\"
|
.\"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: July 13 2013 $
|
.Dd $Mdocdate: September 12 2014 $
|
||||||
.Dt DEMANDOC 1
|
.Dt DEMANDOC 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -92,7 +92,7 @@ This is accomplished as follows (assuming British spelling):
|
|||||||
.Dl $ demandoc -w file.1 | spell -b
|
.Dl $ demandoc -w file.1 | spell -b
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr mandoc 1 ,
|
.Xr mandoc 1 ,
|
||||||
.Xr man 7
|
.Xr man 7 ,
|
||||||
.Xr mdoc 7
|
.Xr mdoc 7
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
.Nm
|
.Nm
|
||||||
|
11
demandoc.c
11
demandoc.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: demandoc.c,v 1.10 2014/03/19 22:20:43 schwarze Exp $ */
|
/* $Id: demandoc.c,v 1.12 2014/10/28 17:36:19 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -43,6 +43,7 @@ int
|
|||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct mparse *mp;
|
struct mparse *mp;
|
||||||
|
struct mchars *mchars;
|
||||||
int ch, i, list;
|
int ch, i, list;
|
||||||
extern int optind;
|
extern int optind;
|
||||||
|
|
||||||
@ -76,7 +77,8 @@ main(int argc, char *argv[])
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, NULL);
|
mchars = mchars_alloc();
|
||||||
|
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, mchars, NULL);
|
||||||
assert(mp);
|
assert(mp);
|
||||||
|
|
||||||
if (0 == argc)
|
if (0 == argc)
|
||||||
@ -88,6 +90,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
mparse_free(mp);
|
mparse_free(mp);
|
||||||
|
mchars_free(mchars);
|
||||||
return((int)MANDOCLEVEL_OK);
|
return((int)MANDOCLEVEL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
250
eqn.7
250
eqn.7
@ -1,6 +1,7 @@
|
|||||||
.\" $Id: eqn.7,v 1.29 2013/07/13 19:41:16 schwarze Exp $
|
.\" $Id: eqn.7,v 1.31 2014/10/12 11:57:38 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -14,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: July 13 2013 $
|
.Dd $Mdocdate: October 12 2014 $
|
||||||
.Dt EQN 7
|
.Dt EQN 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -37,7 +38,9 @@ This manual describes the
|
|||||||
.Nm
|
.Nm
|
||||||
language accepted by the
|
language accepted by the
|
||||||
.Xr mandoc 1
|
.Xr mandoc 1
|
||||||
utility, which corresponds to the Second Edition eqn specification (see
|
utility, which corresponds to the Second Edition
|
||||||
|
.Nm
|
||||||
|
specification (see
|
||||||
.Sx SEE ALSO
|
.Sx SEE ALSO
|
||||||
for references).
|
for references).
|
||||||
.Pp
|
.Pp
|
||||||
@ -77,6 +80,7 @@ box : text
|
|||||||
| \*qgsize\*q text
|
| \*qgsize\*q text
|
||||||
| \*qset\*q text text
|
| \*qset\*q text text
|
||||||
| \*qundef\*q text
|
| \*qundef\*q text
|
||||||
|
| \*qsqrt\*q box
|
||||||
| box pos box
|
| box pos box
|
||||||
| box mark
|
| box mark
|
||||||
| \*qmatrix\*q \*q{\*q [col \*q{\*q list \*q}\*q ]*
|
| \*qmatrix\*q \*q{\*q [col \*q{\*q list \*q}\*q ]*
|
||||||
@ -98,8 +102,19 @@ space : [\e^~ \et]
|
|||||||
.Pp
|
.Pp
|
||||||
White-space consists of the space, tab, circumflex, and tilde
|
White-space consists of the space, tab, circumflex, and tilde
|
||||||
characters.
|
characters.
|
||||||
|
It is required to delimit tokens consisting of alphabetic characters
|
||||||
|
and it is ignored at other places.
|
||||||
|
Braces and quotes also delimit tokens.
|
||||||
If within a quoted string, these space characters are retained.
|
If within a quoted string, these space characters are retained.
|
||||||
Quoted strings are also not scanned for replacement definitions.
|
Quoted strings are also not scanned for keywords, glyph names,
|
||||||
|
and expansion of definitions.
|
||||||
|
To print a literal quote character, it can be prepended with a
|
||||||
|
backslash or expressed with the \e(dq escape sequence.
|
||||||
|
.Pp
|
||||||
|
Subequations can be enclosed in braces to pass them as arguments
|
||||||
|
to operation keywords, overriding standard operation precedence.
|
||||||
|
Braces can be nested.
|
||||||
|
To set a brace verbatim, it needs to be enclosed in quotes.
|
||||||
.Pp
|
.Pp
|
||||||
The following text terms are translated into a rendered glyph, if
|
The following text terms are translated into a rendered glyph, if
|
||||||
available: alpha, beta, chi, delta, epsilon, eta, gamma, iota, kappa,
|
available: alpha, beta, chi, delta, epsilon, eta, gamma, iota, kappa,
|
||||||
@ -110,9 +125,12 @@ int (integral), sum (summation), grad (gradient), del (vector
|
|||||||
differential), times (multiply), cdot (centre-dot), nothing (zero-width
|
differential), times (multiply), cdot (centre-dot), nothing (zero-width
|
||||||
space), approx (approximately equals), prime (prime), half (one-half),
|
space), approx (approximately equals), prime (prime), half (one-half),
|
||||||
partial (partial differential), inf (infinity), >> (much greater), <<
|
partial (partial differential), inf (infinity), >> (much greater), <<
|
||||||
(much less), \-> (left arrow), <\- (right arrow), += (plus-minus), !=
|
(much less), \-> (left arrow), <\- (right arrow), +\- (plus-minus), !=
|
||||||
(not equal), == (equivalence), <= (less-than-equal), and >=
|
(not equal), == (equivalence), <= (less-than-equal), and >=
|
||||||
(more-than-equal).
|
(more-than-equal).
|
||||||
|
The character escape sequences documented in
|
||||||
|
.Xr mandoc_char 7
|
||||||
|
can be used, too.
|
||||||
.Pp
|
.Pp
|
||||||
The following control statements are available:
|
The following control statements are available:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
@ -120,7 +138,7 @@ The following control statements are available:
|
|||||||
Replace all occurrences of a key with a value.
|
Replace all occurrences of a key with a value.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 define Ar key cvalc
|
.D1 Cm define Ar key cvalc
|
||||||
.Pp
|
.Pp
|
||||||
The first character of the value string,
|
The first character of the value string,
|
||||||
.Ar c ,
|
.Ar c ,
|
||||||
@ -128,8 +146,8 @@ is used as the delimiter for the value
|
|||||||
.Ar val .
|
.Ar val .
|
||||||
This allows for arbitrary enclosure of terms (not just quotes), such as
|
This allows for arbitrary enclosure of terms (not just quotes), such as
|
||||||
.Pp
|
.Pp
|
||||||
.D1 define Ar foo 'bar baz'
|
.D1 Cm define Ar foo 'bar baz'
|
||||||
.D1 define Ar foo cbar bazc
|
.D1 Cm define Ar foo cbar bazc
|
||||||
.Pp
|
.Pp
|
||||||
It is an error to have an empty
|
It is an error to have an empty
|
||||||
.Ar key
|
.Ar key
|
||||||
@ -164,24 +182,26 @@ is discarded.
|
|||||||
Set the default font of subsequent output.
|
Set the default font of subsequent output.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 gfont Ar font
|
.D1 Cm gfont Ar font
|
||||||
.Pp
|
.Pp
|
||||||
In mandoc, this value is discarded.
|
In mandoc, this value is discarded.
|
||||||
.It Cm gsize
|
.It Cm gsize
|
||||||
Set the default size of subsequent output.
|
Set the default size of subsequent output.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 gsize Ar size
|
.D1 Cm gsize Oo +|\- Oc Ns Ar size
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Ar size
|
.Ar size
|
||||||
value should be an integer.
|
value should be an integer.
|
||||||
|
If prepended by a sign,
|
||||||
|
the font size is changed relative to the current size.
|
||||||
.It Cm set
|
.It Cm set
|
||||||
Set an equation mode.
|
Set an equation mode.
|
||||||
In mandoc, both arguments are thrown away.
|
In mandoc, both arguments are thrown away.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 set Ar key val
|
.D1 Cm set Ar key val
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Ar key
|
.Ar key
|
||||||
@ -193,7 +213,7 @@ This statement is a GNU extension.
|
|||||||
Unset a previously-defined key.
|
Unset a previously-defined key.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 define Ar key
|
.D1 Cm define Ar key
|
||||||
.Pp
|
.Pp
|
||||||
Once invoked, the definition for
|
Once invoked, the definition for
|
||||||
.Ar key
|
.Ar key
|
||||||
@ -203,6 +223,207 @@ The
|
|||||||
is not expanded for replacements.
|
is not expanded for replacements.
|
||||||
This statement is a GNU extension.
|
This statement is a GNU extension.
|
||||||
.El
|
.El
|
||||||
|
.Pp
|
||||||
|
Operation keywords have the following semantics:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Cm above
|
||||||
|
See
|
||||||
|
.Cm pile .
|
||||||
|
.It Cm bar
|
||||||
|
Draw a line over the preceding box.
|
||||||
|
.It Cm bold
|
||||||
|
Set the following box using bold font.
|
||||||
|
.It Cm ccol
|
||||||
|
Like
|
||||||
|
.Cm cpile ,
|
||||||
|
but for use in
|
||||||
|
.Cm matrix .
|
||||||
|
.It Cm cpile
|
||||||
|
Like
|
||||||
|
.Cm pile ,
|
||||||
|
but with slightly increased vertical spacing.
|
||||||
|
.It Cm dot
|
||||||
|
Set a single dot over the preceding box.
|
||||||
|
.It Cm dotdot
|
||||||
|
Set two dots (dieresis) over the preceding box.
|
||||||
|
.It Cm dyad
|
||||||
|
Set a dyad symbol (left-right arrow) over the preceding box.
|
||||||
|
.It Cm fat
|
||||||
|
A synonym for
|
||||||
|
.Cm bold .
|
||||||
|
.It Cm font
|
||||||
|
Set the second argument using the font specified by the first argument;
|
||||||
|
currently not recognized by the
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Nm
|
||||||
|
parser.
|
||||||
|
.It Cm from
|
||||||
|
Set the following box below the preceding box,
|
||||||
|
using a slightly smaller font.
|
||||||
|
Used for sums, integrals, limits, and the like.
|
||||||
|
.It Cm hat
|
||||||
|
Set a hat (circumflex) over the preceding box.
|
||||||
|
.It Cm italic
|
||||||
|
Set the following box using italic font.
|
||||||
|
.It Cm lcol
|
||||||
|
Like
|
||||||
|
.Cm lpile ,
|
||||||
|
but for use in
|
||||||
|
.Cm matrix .
|
||||||
|
.It Cm left
|
||||||
|
Set the first argument as a big left delimiter before the second argument.
|
||||||
|
As an optional third argument,
|
||||||
|
.Cm right
|
||||||
|
can follow.
|
||||||
|
In that case, the fourth argument is set as a big right delimiter after
|
||||||
|
the second argument.
|
||||||
|
.It Cm lpile
|
||||||
|
Like
|
||||||
|
.Cm cpile ,
|
||||||
|
but subequations are left-justified.
|
||||||
|
.It Cm matrix
|
||||||
|
Followed by a list of columns enclosed in braces.
|
||||||
|
All columns need to have the same number of subequations.
|
||||||
|
The columns are set as a matrix.
|
||||||
|
The difference compared to multiple subsequent
|
||||||
|
.Cm pile
|
||||||
|
operators is that in a
|
||||||
|
.Cm matrix ,
|
||||||
|
corresponding subequations in all columns line up horizontally,
|
||||||
|
while each
|
||||||
|
.Cm pile
|
||||||
|
does vertical spacing independently.
|
||||||
|
.It Cm over
|
||||||
|
Set a fraction.
|
||||||
|
The preceding box is the numerator, the following box is the denominator.
|
||||||
|
.It Cm pile
|
||||||
|
Followed by a list of subequations enclosed in braces,
|
||||||
|
the subequations being separated by
|
||||||
|
.Cm above
|
||||||
|
keywords.
|
||||||
|
Sets the subequations one above the other, each of them centered.
|
||||||
|
Typically used to represent vectors in coordinate representation.
|
||||||
|
.It Cm rcol
|
||||||
|
Like
|
||||||
|
.Cm rpile ,
|
||||||
|
but for use in
|
||||||
|
.Cm matrix .
|
||||||
|
.It Cm right
|
||||||
|
See
|
||||||
|
.Cm left ;
|
||||||
|
.Cm right
|
||||||
|
cannot be used without
|
||||||
|
.Cm left .
|
||||||
|
To set a big right delimiter without a big left delimiter, the following
|
||||||
|
construction can be used:
|
||||||
|
.Pp
|
||||||
|
.D1 Cm left No \(dq\(dq Ar box Cm right Ar delimiter
|
||||||
|
.It Cm roman
|
||||||
|
Set the following box using the default font.
|
||||||
|
.It Cm rpile
|
||||||
|
Like
|
||||||
|
.Cm cpile ,
|
||||||
|
but subequations are right-justified.
|
||||||
|
.It Cm size
|
||||||
|
Set the second argument with the font size specified by the first
|
||||||
|
argument; currently ignored by
|
||||||
|
.Xr mandoc 1 .
|
||||||
|
By prepending a plus or minus sign to the first argument,
|
||||||
|
the font size can be selected relative to the current size.
|
||||||
|
.It Cm sqrt
|
||||||
|
Set the square root of the following box.
|
||||||
|
.It Cm sub
|
||||||
|
Set the following box as a subscript to the preceding box.
|
||||||
|
.It Cm sup
|
||||||
|
Set the following box as a superscript to the preceding box.
|
||||||
|
As a special case, if a
|
||||||
|
.Cm sup
|
||||||
|
clause immediately follows a
|
||||||
|
.Cm sub
|
||||||
|
clause as in
|
||||||
|
.Pp
|
||||||
|
.D1 Ar mainbox Cm sub Ar subbox Cm sup Ar supbox
|
||||||
|
.Pp
|
||||||
|
both are set with respect to the same
|
||||||
|
.Ar mainbox ,
|
||||||
|
that is,
|
||||||
|
.Ar supbox
|
||||||
|
is set above
|
||||||
|
.Ar subbox .
|
||||||
|
.It Cm tilde
|
||||||
|
Set a tilde over the preceding box.
|
||||||
|
.It Cm to
|
||||||
|
Set the following box above the preceding box,
|
||||||
|
using a slightly smaller font.
|
||||||
|
Used for sums and integrals and the like.
|
||||||
|
As a special case, if a
|
||||||
|
.Cm to
|
||||||
|
clause immediately follows a
|
||||||
|
.Cm from
|
||||||
|
clause as in
|
||||||
|
.Pp
|
||||||
|
.D1 Ar mainbox Cm from Ar frombox Cm to Ar tobox
|
||||||
|
.Pp
|
||||||
|
both are set below and above the same
|
||||||
|
.Ar mainbox .
|
||||||
|
.It Cm under
|
||||||
|
Underline the preceding box.
|
||||||
|
.It Cm vec
|
||||||
|
Set a vector symbol (right arrow) over the preceding box.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The binary operations
|
||||||
|
.Cm from ,
|
||||||
|
.Cm to ,
|
||||||
|
.Cm sub ,
|
||||||
|
and
|
||||||
|
.Cm sup
|
||||||
|
group to the right, that is,
|
||||||
|
.Pp
|
||||||
|
.D1 Ar mainbox Cm sup Ar supbox Cm sub Ar subbox
|
||||||
|
.Pp
|
||||||
|
is the same as
|
||||||
|
.Pp
|
||||||
|
.D1 Ar mainbox Cm sup Brq Ar supbox Cm sub Ar subbox
|
||||||
|
.Pp
|
||||||
|
and different from
|
||||||
|
.Pp
|
||||||
|
.D1 Bro Ar mainbox Cm sup Ar supbox Brc Cm sub Ar subbox .
|
||||||
|
.Pp
|
||||||
|
By contrast,
|
||||||
|
.Cm over
|
||||||
|
groups to the left.
|
||||||
|
.Pp
|
||||||
|
In the following list, earlier operations bind more tightly than
|
||||||
|
later operations:
|
||||||
|
.Pp
|
||||||
|
.Bl -enum -compact
|
||||||
|
.It
|
||||||
|
.Cm dyad ,
|
||||||
|
.Cm vec ,
|
||||||
|
.Cm under ,
|
||||||
|
.Cm bar ,
|
||||||
|
.Cm tilde ,
|
||||||
|
.Cm hat ,
|
||||||
|
.Cm dot ,
|
||||||
|
.Cm dotdot
|
||||||
|
.It
|
||||||
|
.Cm fat ,
|
||||||
|
.Cm roman ,
|
||||||
|
.Cm italic ,
|
||||||
|
.Cm bold ,
|
||||||
|
.Cm size
|
||||||
|
.It
|
||||||
|
.Cm sub ,
|
||||||
|
.Cm sup
|
||||||
|
.It
|
||||||
|
.Cm sqrt
|
||||||
|
.It
|
||||||
|
.Cm over
|
||||||
|
.It
|
||||||
|
.Cm from ,
|
||||||
|
.Cm to
|
||||||
|
.El
|
||||||
.Sh COMPATIBILITY
|
.Sh COMPATIBILITY
|
||||||
This section documents the compatibility of mandoc
|
This section documents the compatibility of mandoc
|
||||||
.Nm
|
.Nm
|
||||||
@ -236,6 +457,11 @@ The
|
|||||||
and
|
and
|
||||||
.Cm down Ar n
|
.Cm down Ar n
|
||||||
commands are also ignored.
|
commands are also ignored.
|
||||||
|
.It
|
||||||
|
Inline equations and the
|
||||||
|
.Cm delim
|
||||||
|
control statement are not yet implemented in
|
||||||
|
.Xr mandoc 1 .
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr mandoc 1 ,
|
.Xr mandoc 1 ,
|
||||||
|
189
eqn_html.c
189
eqn_html.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: eqn_html.c,v 1.3 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: eqn_html.c,v 1.10 2014/10/12 19:31:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -27,16 +27,153 @@
|
|||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "html.h"
|
#include "html.h"
|
||||||
|
|
||||||
static const enum htmltag fontmap[EQNFONT__MAX] = {
|
static void
|
||||||
TAG_SPAN, /* EQNFONT_NONE */
|
eqn_box(struct html *p, const struct eqn_box *bp)
|
||||||
TAG_SPAN, /* EQNFONT_ROMAN */
|
{
|
||||||
TAG_B, /* EQNFONT_BOLD */
|
struct tag *post, *row, *cell, *t;
|
||||||
TAG_B, /* EQNFONT_FAT */
|
struct htmlpair tag[2];
|
||||||
TAG_I /* EQNFONT_ITALIC */
|
const struct eqn_box *child, *parent;
|
||||||
};
|
size_t i, j, rows;
|
||||||
|
|
||||||
static void eqn_box(struct html *, const struct eqn_box *);
|
if (NULL == bp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
post = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special handling for a matrix, which is presented to us in
|
||||||
|
* column order, but must be printed in row-order.
|
||||||
|
*/
|
||||||
|
if (EQN_MATRIX == bp->type) {
|
||||||
|
if (NULL == bp->first)
|
||||||
|
goto out;
|
||||||
|
if (EQN_LIST != bp->first->type) {
|
||||||
|
eqn_box(p, bp->first);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (NULL == (parent = bp->first->first))
|
||||||
|
goto out;
|
||||||
|
/* Estimate the number of rows, first. */
|
||||||
|
if (NULL == (child = parent->first))
|
||||||
|
goto out;
|
||||||
|
for (rows = 0; NULL != child; rows++)
|
||||||
|
child = child->next;
|
||||||
|
/* Print row-by-row. */
|
||||||
|
post = print_otag(p, TAG_MTABLE, 0, NULL);
|
||||||
|
for (i = 0; i < rows; i++) {
|
||||||
|
parent = bp->first->first;
|
||||||
|
row = print_otag(p, TAG_MTR, 0, NULL);
|
||||||
|
while (NULL != parent) {
|
||||||
|
child = parent->first;
|
||||||
|
for (j = 0; j < i; j++) {
|
||||||
|
if (NULL == child)
|
||||||
|
break;
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
cell = print_otag
|
||||||
|
(p, TAG_MTD, 0, NULL);
|
||||||
|
/*
|
||||||
|
* If we have no data for this
|
||||||
|
* particular cell, then print a
|
||||||
|
* placeholder and continue--don't puke.
|
||||||
|
*/
|
||||||
|
if (NULL != child)
|
||||||
|
eqn_box(p, child->first);
|
||||||
|
print_tagq(p, cell);
|
||||||
|
parent = parent->next;
|
||||||
|
}
|
||||||
|
print_tagq(p, row);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bp->pos) {
|
||||||
|
case (EQNPOS_TO):
|
||||||
|
post = print_otag(p, TAG_MOVER, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_SUP):
|
||||||
|
post = print_otag(p, TAG_MSUP, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_FROM):
|
||||||
|
post = print_otag(p, TAG_MUNDER, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_SUB):
|
||||||
|
post = print_otag(p, TAG_MSUB, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_OVER):
|
||||||
|
post = print_otag(p, TAG_MFRAC, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_FROMTO):
|
||||||
|
post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_SUBSUP):
|
||||||
|
post = print_otag(p, TAG_MSUBSUP, 0, NULL);
|
||||||
|
break;
|
||||||
|
case (EQNPOS_SQRT):
|
||||||
|
post = print_otag(p, TAG_MSQRT, 0, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp->top || bp->bottom) {
|
||||||
|
assert(NULL == post);
|
||||||
|
if (bp->top && NULL == bp->bottom)
|
||||||
|
post = print_otag(p, TAG_MOVER, 0, NULL);
|
||||||
|
else if (bp->top && bp->bottom)
|
||||||
|
post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
|
||||||
|
else if (bp->bottom)
|
||||||
|
post = print_otag(p, TAG_MUNDER, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != bp->text) {
|
||||||
|
assert(NULL == post);
|
||||||
|
post = print_otag(p, TAG_MI, 0, NULL);
|
||||||
|
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 == post)
|
||||||
|
post = print_otag(p, TAG_MROW, 0, NULL);
|
||||||
|
else
|
||||||
|
print_otag(p, TAG_MROW, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
eqn_box(p, bp->first);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (NULL != bp->bottom) {
|
||||||
|
t = print_otag(p, TAG_MO, 0, NULL);
|
||||||
|
print_text(p, bp->bottom);
|
||||||
|
print_tagq(p, t);
|
||||||
|
}
|
||||||
|
if (NULL != bp->top) {
|
||||||
|
t = print_otag(p, TAG_MO, 0, NULL);
|
||||||
|
print_text(p, bp->top);
|
||||||
|
print_tagq(p, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != post)
|
||||||
|
print_tagq(p, post);
|
||||||
|
|
||||||
|
eqn_box(p, bp->next);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_eqn(struct html *p, const struct eqn *ep)
|
print_eqn(struct html *p, const struct eqn *ep)
|
||||||
@ -45,7 +182,7 @@ print_eqn(struct html *p, const struct eqn *ep)
|
|||||||
struct tag *t;
|
struct tag *t;
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag, "eqn");
|
PAIR_CLASS_INIT(&tag, "eqn");
|
||||||
t = print_otag(p, TAG_SPAN, 1, &tag);
|
t = print_otag(p, TAG_MATH, 1, &tag);
|
||||||
|
|
||||||
p->flags |= HTML_NONOSPACE;
|
p->flags |= HTML_NONOSPACE;
|
||||||
eqn_box(p, ep->root);
|
eqn_box(p, ep->root);
|
||||||
@ -53,29 +190,3 @@ print_eqn(struct html *p, const struct eqn *ep)
|
|||||||
|
|
||||||
print_tagq(p, t);
|
print_tagq(p, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
eqn_box(struct html *p, const struct eqn_box *bp)
|
|
||||||
{
|
|
||||||
struct tag *t;
|
|
||||||
|
|
||||||
t = EQNFONT_NONE == bp->font ? NULL :
|
|
||||||
print_otag(p, fontmap[(int)bp->font], 0, NULL);
|
|
||||||
|
|
||||||
if (bp->left)
|
|
||||||
print_text(p, bp->left);
|
|
||||||
|
|
||||||
if (bp->text)
|
|
||||||
print_text(p, bp->text);
|
|
||||||
|
|
||||||
if (bp->first)
|
|
||||||
eqn_box(p, bp->first);
|
|
||||||
|
|
||||||
if (NULL != t)
|
|
||||||
print_tagq(p, t);
|
|
||||||
if (bp->right)
|
|
||||||
print_text(p, bp->right);
|
|
||||||
|
|
||||||
if (bp->next)
|
|
||||||
eqn_box(p, bp->next);
|
|
||||||
}
|
|
||||||
|
87
eqn_term.c
87
eqn_term.c
@ -1,6 +1,7 @@
|
|||||||
/* $Id: eqn_term.c,v 1.5 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: eqn_term.c,v 1.7 2014/10/12 14:49:39 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -14,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -42,36 +43,82 @@ void
|
|||||||
term_eqn(struct termp *p, const struct eqn *ep)
|
term_eqn(struct termp *p, const struct eqn *ep)
|
||||||
{
|
{
|
||||||
|
|
||||||
p->flags |= TERMP_NONOSPACE;
|
|
||||||
eqn_box(p, ep->root);
|
eqn_box(p, ep->root);
|
||||||
term_word(p, " ");
|
p->flags &= ~TERMP_NOSPACE;
|
||||||
p->flags &= ~TERMP_NONOSPACE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eqn_box(struct termp *p, const struct eqn_box *bp)
|
eqn_box(struct termp *p, const struct eqn_box *bp)
|
||||||
{
|
{
|
||||||
|
const struct eqn_box *child;
|
||||||
|
|
||||||
if (EQNFONT_NONE != bp->font)
|
if (bp->type == EQN_LIST ||
|
||||||
|
(bp->type == EQN_PILE && (bp->prev || bp->next)) ||
|
||||||
|
(bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) {
|
||||||
|
if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL)
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
term_word(p, bp->left != NULL ? bp->left : "(");
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
}
|
||||||
|
if (bp->font != EQNFONT_NONE)
|
||||||
term_fontpush(p, fontmap[(int)bp->font]);
|
term_fontpush(p, fontmap[(int)bp->font]);
|
||||||
if (bp->left)
|
|
||||||
term_word(p, bp->left);
|
|
||||||
if (EQN_SUBEXPR == bp->type)
|
|
||||||
term_word(p, "(");
|
|
||||||
|
|
||||||
if (bp->text)
|
if (bp->text != NULL)
|
||||||
term_word(p, bp->text);
|
term_word(p, bp->text);
|
||||||
|
|
||||||
if (bp->first)
|
if (bp->pos == EQNPOS_SQRT) {
|
||||||
|
term_word(p, "sqrt");
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
eqn_box(p, bp->first);
|
eqn_box(p, bp->first);
|
||||||
|
} else if (bp->type == EQN_SUBEXPR) {
|
||||||
|
child = bp->first;
|
||||||
|
eqn_box(p, child);
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
term_word(p, bp->pos == EQNPOS_OVER ? "/" :
|
||||||
|
(bp->pos == EQNPOS_SUP ||
|
||||||
|
bp->pos == EQNPOS_TO) ? "^" : "_");
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
child = child->next;
|
||||||
|
eqn_box(p, child);
|
||||||
|
if (bp->pos == EQNPOS_FROMTO ||
|
||||||
|
bp->pos == EQNPOS_SUBSUP) {
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
term_word(p, "^");
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
child = child->next;
|
||||||
|
eqn_box(p, child);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
child = bp->first;
|
||||||
|
if (bp->type == EQN_MATRIX && child->type == EQN_LIST)
|
||||||
|
child = child->first;
|
||||||
|
while (child != NULL) {
|
||||||
|
eqn_box(p,
|
||||||
|
bp->type == EQN_PILE &&
|
||||||
|
child->type == EQN_LIST &&
|
||||||
|
child->args == 1 ?
|
||||||
|
child->first : child);
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (EQN_SUBEXPR == bp->type)
|
if (bp->font != EQNFONT_NONE)
|
||||||
term_word(p, ")");
|
|
||||||
if (bp->right)
|
|
||||||
term_word(p, bp->right);
|
|
||||||
if (EQNFONT_NONE != bp->font)
|
|
||||||
term_fontpop(p);
|
term_fontpop(p);
|
||||||
|
if (bp->type == EQN_LIST ||
|
||||||
|
(bp->type == EQN_PILE && (bp->prev || bp->next)) ||
|
||||||
|
(bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) {
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
term_word(p, bp->right != NULL ? bp->right : ")");
|
||||||
|
if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL)
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
if (bp->next)
|
if (bp->top != NULL) {
|
||||||
eqn_box(p, bp->next);
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
term_word(p, bp->top);
|
||||||
|
}
|
||||||
|
if (bp->bottom != NULL) {
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
term_word(p, "_");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: example.style.css,v 1.49 2011/12/15 12:18:57 kristaps Exp $ */
|
/* $Id: example.style.css,v 1.53 2014/09/27 11:16:24 kristaps Exp $ */
|
||||||
/*
|
/*
|
||||||
* This is an example style-sheet provided for mandoc(1) and the -Thtml
|
* This is an example style-sheet provided for mandoc(1) and the -Thtml
|
||||||
* or -Txhtml output mode.
|
* or -Txhtml output mode.
|
||||||
@ -20,11 +20,11 @@ div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */
|
|||||||
div.mandoc table.synopsis { } /* SYNOPSIS section table. */
|
div.mandoc table.synopsis { } /* SYNOPSIS section table. */
|
||||||
div.mandoc table.foot { } /* Document footer. */
|
div.mandoc table.foot { } /* Document footer. */
|
||||||
div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */
|
div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */
|
||||||
div.mandoc td.foot-os { width: 50%; text-align: right; } /* Document footer: OS/source. */
|
div.mandoc td.foot-os { width: 50%; } /* Document footer: OS/source. */
|
||||||
div.mandoc table.head { } /* Document header. */
|
div.mandoc table.head { } /* Document header. */
|
||||||
div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */
|
div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */
|
||||||
div.mandoc td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */
|
div.mandoc td.head-vol { width: 80%; } /* Document header: volume. */
|
||||||
div.mandoc td.head-rtitle { width: 10%; text-align: right; } /* Document header: right-title. */
|
div.mandoc td.head-rtitle { width: 10%; } /* Document header: right-title. */
|
||||||
div.mandoc .display { } /* All Bd, D1, Dl. */
|
div.mandoc .display { } /* All Bd, D1, Dl. */
|
||||||
div.mandoc .list { } /* All Bl. */
|
div.mandoc .list { } /* All Bl. */
|
||||||
div.mandoc i { } /* Italic: BI, IB, I, (implicit). */
|
div.mandoc i { } /* Italic: BI, IB, I, (implicit). */
|
||||||
@ -108,3 +108,4 @@ div.mandoc ol.list-enum { padding-left: 2em; }
|
|||||||
div.mandoc li.list-enum { }
|
div.mandoc li.list-enum { }
|
||||||
div.mandoc span.eqn { } /* Equation modes. See eqn(7). */
|
div.mandoc span.eqn { } /* Equation modes. See eqn(7). */
|
||||||
div.mandoc table.tbl { } /* Table modes. See tbl(7). */
|
div.mandoc table.tbl { } /* Table modes. See tbl(7). */
|
||||||
|
div.mandoc div.spacer { margin: 1em 0; }
|
||||||
|
159
html.c
159
html.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: html.c,v 1.159 2014/07/23 15:00:08 schwarze Exp $ */
|
/* $Id: html.c,v 1.181 2014/10/29 00:17:43 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -70,17 +68,31 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
|||||||
{"dt", HTML_CLRLINE}, /* TAG_DT */
|
{"dt", HTML_CLRLINE}, /* TAG_DT */
|
||||||
{"dd", HTML_CLRLINE}, /* TAG_DD */
|
{"dd", HTML_CLRLINE}, /* TAG_DD */
|
||||||
{"blockquote", HTML_CLRLINE}, /* TAG_BLOCKQUOTE */
|
{"blockquote", HTML_CLRLINE}, /* TAG_BLOCKQUOTE */
|
||||||
{"p", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_P */
|
|
||||||
{"pre", HTML_CLRLINE }, /* TAG_PRE */
|
{"pre", HTML_CLRLINE }, /* TAG_PRE */
|
||||||
{"b", 0 }, /* TAG_B */
|
{"b", 0 }, /* TAG_B */
|
||||||
{"i", 0 }, /* TAG_I */
|
{"i", 0 }, /* TAG_I */
|
||||||
{"code", 0 }, /* TAG_CODE */
|
{"code", 0 }, /* TAG_CODE */
|
||||||
{"small", 0 }, /* TAG_SMALL */
|
{"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] = {
|
static const char *const htmlattrs[ATTR_MAX] = {
|
||||||
"http-equiv", /* ATTR_HTTPEQUIV */
|
|
||||||
"content", /* ATTR_CONTENT */
|
|
||||||
"name", /* ATTR_NAME */
|
"name", /* ATTR_NAME */
|
||||||
"rel", /* ATTR_REL */
|
"rel", /* ATTR_REL */
|
||||||
"href", /* ATTR_HREF */
|
"href", /* ATTR_HREF */
|
||||||
@ -88,11 +100,12 @@ static const char *const htmlattrs[ATTR_MAX] = {
|
|||||||
"media", /* ATTR_MEDIA */
|
"media", /* ATTR_MEDIA */
|
||||||
"class", /* ATTR_CLASS */
|
"class", /* ATTR_CLASS */
|
||||||
"style", /* ATTR_STYLE */
|
"style", /* ATTR_STYLE */
|
||||||
"width", /* ATTR_WIDTH */
|
|
||||||
"id", /* ATTR_ID */
|
"id", /* ATTR_ID */
|
||||||
"summary", /* ATTR_SUMMARY */
|
|
||||||
"align", /* ATTR_ALIGN */
|
|
||||||
"colspan", /* ATTR_COLSPAN */
|
"colspan", /* ATTR_COLSPAN */
|
||||||
|
"charset", /* ATTR_CHARSET */
|
||||||
|
"open", /* ATTR_OPEN */
|
||||||
|
"close", /* ATTR_CLOSE */
|
||||||
|
"mathvariant", /* ATTR_MATHVARIANT */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const roffscales[SCALE_MAX] = {
|
static const char *const roffscales[SCALE_MAX] = {
|
||||||
@ -114,11 +127,10 @@ static int print_escape(char);
|
|||||||
static int print_encode(struct html *, const char *, int);
|
static int print_encode(struct html *, const char *, int);
|
||||||
static void print_metaf(struct html *, enum mandoc_esc);
|
static void print_metaf(struct html *, enum mandoc_esc);
|
||||||
static void print_attr(struct html *, const char *, const char *);
|
static void print_attr(struct html *, const char *, const char *);
|
||||||
static void *ml_alloc(char *, enum htmltype);
|
|
||||||
|
|
||||||
|
|
||||||
static void *
|
void *
|
||||||
ml_alloc(char *outopts, enum htmltype type)
|
html_alloc(const struct mchars *mchars, char *outopts)
|
||||||
{
|
{
|
||||||
struct html *h;
|
struct html *h;
|
||||||
const char *toks[5];
|
const char *toks[5];
|
||||||
@ -132,9 +144,8 @@ ml_alloc(char *outopts, enum htmltype type)
|
|||||||
|
|
||||||
h = mandoc_calloc(1, sizeof(struct html));
|
h = mandoc_calloc(1, sizeof(struct html));
|
||||||
|
|
||||||
h->type = type;
|
|
||||||
h->tags.head = NULL;
|
h->tags.head = NULL;
|
||||||
h->symtab = mchars_alloc();
|
h->symtab = mchars;
|
||||||
|
|
||||||
while (outopts && *outopts)
|
while (outopts && *outopts)
|
||||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||||
@ -157,20 +168,6 @@ ml_alloc(char *outopts, enum htmltype type)
|
|||||||
return(h);
|
return(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
html_alloc(char *outopts)
|
|
||||||
{
|
|
||||||
|
|
||||||
return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
xhtml_alloc(char *outopts)
|
|
||||||
{
|
|
||||||
|
|
||||||
return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
html_free(void *p)
|
html_free(void *p)
|
||||||
{
|
{
|
||||||
@ -184,9 +181,6 @@ html_free(void *p)
|
|||||||
free(tag);
|
free(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->symtab)
|
|
||||||
mchars_free(h->symtab);
|
|
||||||
|
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,18 +188,23 @@ void
|
|||||||
print_gen_head(struct html *h)
|
print_gen_head(struct html *h)
|
||||||
{
|
{
|
||||||
struct htmlpair tag[4];
|
struct htmlpair tag[4];
|
||||||
|
struct tag *t;
|
||||||
|
|
||||||
tag[0].key = ATTR_HTTPEQUIV;
|
tag[0].key = ATTR_CHARSET;
|
||||||
tag[0].val = "Content-Type";
|
tag[0].val = "utf-8";
|
||||||
tag[1].key = ATTR_CONTENT;
|
print_otag(h, TAG_META, 1, tag);
|
||||||
tag[1].val = "text/html; charset=utf-8";
|
|
||||||
print_otag(h, TAG_META, 2, tag);
|
|
||||||
|
|
||||||
tag[0].key = ATTR_NAME;
|
/*
|
||||||
tag[0].val = "resource-type";
|
* Print a default style-sheet.
|
||||||
tag[1].key = ATTR_CONTENT;
|
*/
|
||||||
tag[1].val = "document";
|
t = print_otag(h, TAG_STYLE, 0, NULL);
|
||||||
print_otag(h, TAG_META, 2, tag);
|
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");
|
||||||
|
print_tagq(h, t);
|
||||||
|
|
||||||
if (h->style) {
|
if (h->style) {
|
||||||
tag[0].key = ATTR_REL;
|
tag[0].key = ATTR_REL;
|
||||||
@ -420,29 +419,31 @@ print_encode(struct html *h, const char *p, int norecurse)
|
|||||||
case ESCAPE_UNICODE:
|
case ESCAPE_UNICODE:
|
||||||
/* Skip past "u" header. */
|
/* Skip past "u" header. */
|
||||||
c = mchars_num2uc(seq + 1, len - 1);
|
c = mchars_num2uc(seq + 1, len - 1);
|
||||||
if ('\0' != c)
|
|
||||||
printf("&#x%x;", c);
|
|
||||||
break;
|
break;
|
||||||
case ESCAPE_NUMBERED:
|
case ESCAPE_NUMBERED:
|
||||||
c = mchars_num2char(seq, len);
|
c = mchars_num2char(seq, len);
|
||||||
if ( ! ('\0' == c || print_escape(c)))
|
if (c < 0)
|
||||||
putchar(c);
|
continue;
|
||||||
break;
|
break;
|
||||||
case ESCAPE_SPECIAL:
|
case ESCAPE_SPECIAL:
|
||||||
c = mchars_spec2cp(h->symtab, seq, len);
|
c = mchars_spec2cp(h->symtab, seq, len);
|
||||||
if (c > 0)
|
if (c <= 0)
|
||||||
printf("&#%d;", c);
|
continue;
|
||||||
else if (-1 == c && 1 == len &&
|
|
||||||
!print_escape(*seq))
|
|
||||||
putchar((int)*seq);
|
|
||||||
break;
|
break;
|
||||||
case ESCAPE_NOSPACE:
|
case ESCAPE_NOSPACE:
|
||||||
if ('\0' == *p)
|
if ('\0' == *p)
|
||||||
nospace = 1;
|
nospace = 1;
|
||||||
break;
|
continue;
|
||||||
default:
|
default:
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ((c < 0x20 && c != 0x09) ||
|
||||||
|
(c > 0x7E && c < 0xA0))
|
||||||
|
c = 0xFFFD;
|
||||||
|
if (c > 0x7E)
|
||||||
|
printf("&#%d;", c);
|
||||||
|
else if ( ! print_escape(c))
|
||||||
|
putchar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(nospace);
|
return(nospace);
|
||||||
@ -495,24 +496,10 @@ print_otag(struct html *h, enum htmltag tag,
|
|||||||
for (i = 0; i < sz; i++)
|
for (i = 0; i < sz; i++)
|
||||||
print_attr(h, htmlattrs[p[i].key], p[i].val);
|
print_attr(h, htmlattrs[p[i].key], p[i].val);
|
||||||
|
|
||||||
/* Add non-overridable attributes. */
|
/* Accommodate for "well-formed" singleton escaping. */
|
||||||
|
|
||||||
if (TAG_HTML == tag && HTML_XHTML_1_0_STRICT == h->type) {
|
|
||||||
print_attr(h, "xmlns", "http://www.w3.org/1999/xhtml");
|
|
||||||
print_attr(h, "xml:lang", "en");
|
|
||||||
print_attr(h, "lang", "en");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Accommodate for XML "well-formed" singleton escaping. */
|
|
||||||
|
|
||||||
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
||||||
switch (h->type) {
|
putchar('/');
|
||||||
case HTML_XHTML_1_0_STRICT:
|
|
||||||
putchar('/');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
putchar('>');
|
putchar('>');
|
||||||
|
|
||||||
@ -538,26 +525,8 @@ print_ctag(struct html *h, enum htmltag tag)
|
|||||||
void
|
void
|
||||||
print_gen_decls(struct html *h)
|
print_gen_decls(struct html *h)
|
||||||
{
|
{
|
||||||
const char *doctype;
|
|
||||||
const char *dtd;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
switch (h->type) {
|
puts("<!DOCTYPE html>");
|
||||||
case HTML_HTML_4_01_STRICT:
|
|
||||||
name = "HTML";
|
|
||||||
doctype = "-//W3C//DTD HTML 4.01//EN";
|
|
||||||
dtd = "http://www.w3.org/TR/html4/strict.dtd";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
|
||||||
name = "html";
|
|
||||||
doctype = "-//W3C//DTD XHTML 1.0 Strict//EN";
|
|
||||||
dtd = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n",
|
|
||||||
name, doctype, dtd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -649,6 +618,18 @@ print_stagq(struct html *h, const struct tag *suntil)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
print_tagq(h, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
bufinit(struct html *h)
|
bufinit(struct html *h)
|
||||||
{
|
{
|
||||||
@ -761,6 +742,8 @@ bufcat_su(struct html *h, const char *p, const struct roffsu *su)
|
|||||||
v = su->scale;
|
v = su->scale;
|
||||||
if (SCALE_MM == su->unit && 0.0 == (v /= 100.0))
|
if (SCALE_MM == su->unit && 0.0 == (v /= 100.0))
|
||||||
v = 1.0;
|
v = 1.0;
|
||||||
|
else if (SCALE_BU == su->unit)
|
||||||
|
v /= 24.0;
|
||||||
|
|
||||||
bufcat_fmt(h, "%s: %.2f%s;", p, v, roffscales[su->unit]);
|
bufcat_fmt(h, "%s: %.2f%s;", p, v, roffscales[su->unit]);
|
||||||
}
|
}
|
||||||
|
43
html.h
43
html.h
@ -1,6 +1,6 @@
|
|||||||
/* $Id: html.h,v 1.51 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: html.h,v 1.67 2014/10/28 17:36:19 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -44,18 +44,32 @@ enum htmltag {
|
|||||||
TAG_DT,
|
TAG_DT,
|
||||||
TAG_DD,
|
TAG_DD,
|
||||||
TAG_BLOCKQUOTE,
|
TAG_BLOCKQUOTE,
|
||||||
TAG_P,
|
|
||||||
TAG_PRE,
|
TAG_PRE,
|
||||||
TAG_B,
|
TAG_B,
|
||||||
TAG_I,
|
TAG_I,
|
||||||
TAG_CODE,
|
TAG_CODE,
|
||||||
TAG_SMALL,
|
TAG_SMALL,
|
||||||
|
TAG_STYLE,
|
||||||
|
TAG_MATH,
|
||||||
|
TAG_MROW,
|
||||||
|
TAG_MI,
|
||||||
|
TAG_MO,
|
||||||
|
TAG_MSUP,
|
||||||
|
TAG_MSUB,
|
||||||
|
TAG_MSUBSUP,
|
||||||
|
TAG_MFRAC,
|
||||||
|
TAG_MSQRT,
|
||||||
|
TAG_MFENCED,
|
||||||
|
TAG_MTABLE,
|
||||||
|
TAG_MTR,
|
||||||
|
TAG_MTD,
|
||||||
|
TAG_MUNDEROVER,
|
||||||
|
TAG_MUNDER,
|
||||||
|
TAG_MOVER,
|
||||||
TAG_MAX
|
TAG_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum htmlattr {
|
enum htmlattr {
|
||||||
ATTR_HTTPEQUIV,
|
|
||||||
ATTR_CONTENT,
|
|
||||||
ATTR_NAME,
|
ATTR_NAME,
|
||||||
ATTR_REL,
|
ATTR_REL,
|
||||||
ATTR_HREF,
|
ATTR_HREF,
|
||||||
@ -63,11 +77,12 @@ enum htmlattr {
|
|||||||
ATTR_MEDIA,
|
ATTR_MEDIA,
|
||||||
ATTR_CLASS,
|
ATTR_CLASS,
|
||||||
ATTR_STYLE,
|
ATTR_STYLE,
|
||||||
ATTR_WIDTH,
|
|
||||||
ATTR_ID,
|
ATTR_ID,
|
||||||
ATTR_SUMMARY,
|
|
||||||
ATTR_ALIGN,
|
|
||||||
ATTR_COLSPAN,
|
ATTR_COLSPAN,
|
||||||
|
ATTR_CHARSET,
|
||||||
|
ATTR_OPEN,
|
||||||
|
ATTR_CLOSE,
|
||||||
|
ATTR_MATHVARIANT,
|
||||||
ATTR_MAX
|
ATTR_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,12 +118,6 @@ struct htmlpair {
|
|||||||
#define PAIR_CLASS_INIT(p, v) PAIR_INIT(p, ATTR_CLASS, 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_HREF_INIT(p, v) PAIR_INIT(p, ATTR_HREF, v)
|
||||||
#define PAIR_STYLE_INIT(p, h) PAIR_INIT(p, ATTR_STYLE, (h)->buf)
|
#define PAIR_STYLE_INIT(p, h) PAIR_INIT(p, ATTR_STYLE, (h)->buf)
|
||||||
#define PAIR_SUMMARY_INIT(p, v) PAIR_INIT(p, ATTR_SUMMARY, v)
|
|
||||||
|
|
||||||
enum htmltype {
|
|
||||||
HTML_HTML_4_01_STRICT,
|
|
||||||
HTML_XHTML_1_0_STRICT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct html {
|
struct html {
|
||||||
int flags;
|
int flags;
|
||||||
@ -119,10 +128,12 @@ struct html {
|
|||||||
#define HTML_NONOSPACE (1 << 4) /* never add spaces */
|
#define HTML_NONOSPACE (1 << 4) /* never add spaces */
|
||||||
#define HTML_LITERAL (1 << 5) /* literal (e.g., <PRE>) context */
|
#define HTML_LITERAL (1 << 5) /* literal (e.g., <PRE>) context */
|
||||||
#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
|
#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
|
||||||
|
#define HTML_NOSPLIT (1 << 7) /* do not break line before .An */
|
||||||
|
#define HTML_SPLIT (1 << 8) /* break line before .An */
|
||||||
struct tagq tags; /* stack of open tags */
|
struct tagq tags; /* stack of open tags */
|
||||||
struct rofftbl tbl; /* current table */
|
struct rofftbl tbl; /* current table */
|
||||||
struct tag *tblt; /* current open table scope */
|
struct tag *tblt; /* current open table scope */
|
||||||
struct mchars *symtab; /* character-escapes */
|
const struct mchars *symtab; /* character table */
|
||||||
char *base_man; /* base for manpage href */
|
char *base_man; /* base for manpage href */
|
||||||
char *base_includes; /* base for include href */
|
char *base_includes; /* base for include href */
|
||||||
char *style; /* style-sheet URI */
|
char *style; /* style-sheet URI */
|
||||||
@ -131,7 +142,6 @@ struct html {
|
|||||||
struct tag *metaf; /* current open font scope */
|
struct tag *metaf; /* current open font scope */
|
||||||
enum htmlfont metal; /* last used font */
|
enum htmlfont metal; /* last used font */
|
||||||
enum htmlfont metac; /* current font mode */
|
enum htmlfont metac; /* current font mode */
|
||||||
enum htmltype type; /* output media type */
|
|
||||||
int oflags; /* output options */
|
int oflags; /* output options */
|
||||||
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
|
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
|
||||||
};
|
};
|
||||||
@ -146,6 +156,7 @@ void print_text(struct html *, const char *);
|
|||||||
void print_tblclose(struct html *);
|
void print_tblclose(struct html *);
|
||||||
void print_tbl(struct html *, const struct tbl_span *);
|
void print_tbl(struct html *, const struct tbl_span *);
|
||||||
void print_eqn(struct html *, const struct eqn *);
|
void print_eqn(struct html *, const struct eqn *);
|
||||||
|
void print_paragraph(struct html *);
|
||||||
|
|
||||||
#if __GNUC__ - 0 >= 4
|
#if __GNUC__ - 0 >= 4
|
||||||
__attribute__((__format__ (__printf__, 2, 3)))
|
__attribute__((__format__ (__printf__, 2, 3)))
|
||||||
|
6
lib.c
6
lib.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: lib.c,v 1.10 2014/03/23 11:25:26 schwarze Exp $ */
|
/* $Id: lib.c,v 1.11 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
24
libman.h
24
libman.h
@ -1,6 +1,7 @@
|
|||||||
/* $Id: libman.h,v 1.63 2014/08/01 21:24:17 schwarze Exp $ */
|
/* $Id: libman.h,v 1.65 2014/11/28 05:51:32 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -45,7 +46,7 @@ struct man {
|
|||||||
char *buf
|
char *buf
|
||||||
|
|
||||||
struct man_macro {
|
struct man_macro {
|
||||||
int (*fp)(MACRO_PROT_ARGS);
|
void (*fp)(MACRO_PROT_ARGS);
|
||||||
int flags;
|
int flags;
|
||||||
#define MAN_SCOPED (1 << 0)
|
#define MAN_SCOPED (1 << 0)
|
||||||
#define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */
|
#define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */
|
||||||
@ -53,24 +54,25 @@ struct man_macro {
|
|||||||
#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */
|
#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */
|
||||||
#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */
|
#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */
|
||||||
#define MAN_BSCOPE (1 << 5) /* Break BLINE scope. */
|
#define MAN_BSCOPE (1 << 5) /* Break BLINE scope. */
|
||||||
|
#define MAN_JOIN (1 << 6) /* Join arguments together. */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct man_macro *const man_macros;
|
extern const struct man_macro *const man_macros;
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
int man_word_alloc(struct man *, int, int, const char *);
|
void man_word_alloc(struct man *, int, int, const char *);
|
||||||
int man_block_alloc(struct man *, int, int, enum mant);
|
void man_word_append(struct man *, const char *);
|
||||||
int man_head_alloc(struct man *, int, int, enum mant);
|
void man_block_alloc(struct man *, int, int, enum mant);
|
||||||
int man_tail_alloc(struct man *, int, int, enum mant);
|
void man_head_alloc(struct man *, int, int, enum mant);
|
||||||
int man_body_alloc(struct man *, int, int, enum mant);
|
void man_body_alloc(struct man *, int, int, enum mant);
|
||||||
int man_elem_alloc(struct man *, int, int, enum mant);
|
void man_elem_alloc(struct man *, int, int, enum mant);
|
||||||
void man_node_delete(struct man *, struct man_node *);
|
void man_node_delete(struct man *, struct man_node *);
|
||||||
void man_hash_init(void);
|
void man_hash_init(void);
|
||||||
enum mant man_hash_find(const char *);
|
enum mant man_hash_find(const char *);
|
||||||
int man_macroend(struct man *);
|
void man_macroend(struct man *);
|
||||||
int man_valid_post(struct man *);
|
void man_valid_post(struct man *);
|
||||||
int man_unscope(struct man *, const struct man_node *);
|
void man_unscope(struct man *, const struct man_node *);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
31
libmandoc.h
31
libmandoc.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: libmandoc.h,v 1.42 2014/07/09 11:31:43 schwarze Exp $ */
|
/* $Id: libmandoc.h,v 1.49 2014/11/28 06:27:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -30,6 +30,11 @@ enum rofferr {
|
|||||||
ROFF_ERR /* badness: puke and stop */
|
ROFF_ERR /* badness: puke and stop */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct buf {
|
||||||
|
char *buf;
|
||||||
|
size_t sz;
|
||||||
|
};
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
struct roff;
|
struct roff;
|
||||||
@ -55,34 +60,32 @@ struct mdoc *mdoc_alloc(struct roff *, struct mparse *,
|
|||||||
void mdoc_reset(struct mdoc *);
|
void mdoc_reset(struct mdoc *);
|
||||||
int mdoc_parseln(struct mdoc *, int, char *, int);
|
int mdoc_parseln(struct mdoc *, int, char *, int);
|
||||||
int mdoc_endparse(struct mdoc *);
|
int mdoc_endparse(struct mdoc *);
|
||||||
int mdoc_addspan(struct mdoc *, const struct tbl_span *);
|
void mdoc_addspan(struct mdoc *, const struct tbl_span *);
|
||||||
int mdoc_addeqn(struct mdoc *, const struct eqn *);
|
void mdoc_addeqn(struct mdoc *, const struct eqn *);
|
||||||
|
|
||||||
void man_free(struct man *);
|
void man_free(struct man *);
|
||||||
struct man *man_alloc(struct roff *, struct mparse *, int);
|
struct man *man_alloc(struct roff *, struct mparse *, int);
|
||||||
void man_reset(struct man *);
|
void man_reset(struct man *);
|
||||||
int man_parseln(struct man *, int, char *, int);
|
int man_parseln(struct man *, int, char *, int);
|
||||||
int man_endparse(struct man *);
|
int man_endparse(struct man *);
|
||||||
int man_addspan(struct man *, const struct tbl_span *);
|
void man_addspan(struct man *, const struct tbl_span *);
|
||||||
int man_addeqn(struct man *, const struct eqn *);
|
void man_addeqn(struct man *, const struct eqn *);
|
||||||
|
|
||||||
|
int preconv_cue(const struct buf *, size_t);
|
||||||
|
int preconv_encode(struct buf *, size_t *,
|
||||||
|
struct buf *, size_t *, int *);
|
||||||
|
|
||||||
void roff_free(struct roff *);
|
void roff_free(struct roff *);
|
||||||
struct roff *roff_alloc(struct mparse *, int);
|
struct roff *roff_alloc(struct mparse *, const struct mchars *, int);
|
||||||
void roff_reset(struct roff *);
|
void roff_reset(struct roff *);
|
||||||
enum rofferr roff_parseln(struct roff *, int,
|
enum rofferr roff_parseln(struct roff *, int, struct buf *, int *);
|
||||||
char **, size_t *, int, int *);
|
|
||||||
void roff_endparse(struct roff *);
|
void roff_endparse(struct roff *);
|
||||||
void roff_setreg(struct roff *, const char *, int, char sign);
|
void roff_setreg(struct roff *, const char *, int, char sign);
|
||||||
int roff_getreg(const struct roff *, const char *);
|
int roff_getreg(const struct roff *, const char *);
|
||||||
char *roff_strdup(const struct roff *, const char *);
|
char *roff_strdup(const struct roff *, const char *);
|
||||||
int roff_getcontrol(const struct roff *,
|
int roff_getcontrol(const struct roff *,
|
||||||
const char *, int *);
|
const char *, int *);
|
||||||
#if 0
|
int roff_getformat(const struct roff *);
|
||||||
char roff_eqndelim(const struct roff *);
|
|
||||||
void roff_openeqn(struct roff *, const char *,
|
|
||||||
int, int, const char *);
|
|
||||||
int roff_closeeqn(struct roff *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const struct tbl_span *roff_span(const struct roff *);
|
const struct tbl_span *roff_span(const struct roff *);
|
||||||
const struct eqn *roff_eqn(const struct roff *);
|
const struct eqn *roff_eqn(const struct roff *);
|
||||||
|
44
libmdoc.h
44
libmdoc.h
@ -1,7 +1,7 @@
|
|||||||
/* $Id: libmdoc.h,v 1.88 2014/08/01 17:40:34 schwarze Exp $ */
|
/* $Id: libmdoc.h,v 1.95 2014/11/29 03:37:44 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -37,6 +37,7 @@ struct mdoc {
|
|||||||
#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */
|
#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */
|
||||||
#define MDOC_KEEP (1 << 8) /* in a word keep */
|
#define MDOC_KEEP (1 << 8) /* in a word keep */
|
||||||
#define MDOC_SMOFF (1 << 9) /* spacing is off */
|
#define MDOC_SMOFF (1 << 9) /* spacing is off */
|
||||||
|
#define MDOC_NODELIMC (1 << 10) /* disable closing delimiter handling */
|
||||||
enum mdoc_next next; /* where to put the next node */
|
enum mdoc_next next; /* where to put the next node */
|
||||||
struct mdoc_node *last; /* the last node parsed */
|
struct mdoc_node *last; /* the last node parsed */
|
||||||
struct mdoc_node *first; /* the first node parsed */
|
struct mdoc_node *first; /* the first node parsed */
|
||||||
@ -55,7 +56,7 @@ struct mdoc {
|
|||||||
char *buf
|
char *buf
|
||||||
|
|
||||||
struct mdoc_macro {
|
struct mdoc_macro {
|
||||||
int (*fp)(MACRO_PROT_ARGS);
|
void (*fp)(MACRO_PROT_ARGS);
|
||||||
int flags;
|
int flags;
|
||||||
#define MDOC_CALLABLE (1 << 0)
|
#define MDOC_CALLABLE (1 << 0)
|
||||||
#define MDOC_PARSED (1 << 1)
|
#define MDOC_PARSED (1 << 1)
|
||||||
@ -76,13 +77,6 @@ enum margserr {
|
|||||||
ARGS_PEND /* last phrase (-column) */
|
ARGS_PEND /* last phrase (-column) */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum margverr {
|
|
||||||
ARGV_ERROR,
|
|
||||||
ARGV_EOLN, /* end of line */
|
|
||||||
ARGV_ARG, /* valid argument */
|
|
||||||
ARGV_WORD /* normal word (or bad argument---same thing) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A punctuation delimiter is opening, closing, or "middle mark"
|
* A punctuation delimiter is opening, closing, or "middle mark"
|
||||||
* punctuation. These govern spacing.
|
* punctuation. These govern spacing.
|
||||||
@ -104,38 +98,34 @@ extern const struct mdoc_macro *const mdoc_macros;
|
|||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
int mdoc_macro(MACRO_PROT_ARGS);
|
void mdoc_macro(MACRO_PROT_ARGS);
|
||||||
int mdoc_word_alloc(struct mdoc *,
|
void mdoc_word_alloc(struct mdoc *, int, int, const char *);
|
||||||
int, int, const char *);
|
|
||||||
void mdoc_word_append(struct mdoc *, const char *);
|
void mdoc_word_append(struct mdoc *, const char *);
|
||||||
int mdoc_elem_alloc(struct mdoc *, int, int,
|
void mdoc_elem_alloc(struct mdoc *, int, int,
|
||||||
enum mdoct, struct mdoc_arg *);
|
enum mdoct, struct mdoc_arg *);
|
||||||
int mdoc_block_alloc(struct mdoc *, int, int,
|
struct mdoc_node *mdoc_block_alloc(struct mdoc *, int, int,
|
||||||
enum mdoct, struct mdoc_arg *);
|
enum mdoct, struct mdoc_arg *);
|
||||||
int mdoc_head_alloc(struct mdoc *, int, int, enum mdoct);
|
struct mdoc_node *mdoc_head_alloc(struct mdoc *, int, int, enum mdoct);
|
||||||
int mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct);
|
void mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct);
|
||||||
int mdoc_body_alloc(struct mdoc *, int, int, enum mdoct);
|
struct mdoc_node *mdoc_body_alloc(struct mdoc *, int, int, enum mdoct);
|
||||||
int mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct,
|
void mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct,
|
||||||
struct mdoc_node *, enum mdoc_endbody);
|
struct mdoc_node *, enum mdoc_endbody);
|
||||||
void mdoc_node_delete(struct mdoc *, struct mdoc_node *);
|
void mdoc_node_delete(struct mdoc *, struct mdoc_node *);
|
||||||
int mdoc_node_relink(struct mdoc *, struct mdoc_node *);
|
void mdoc_node_relink(struct mdoc *, struct mdoc_node *);
|
||||||
void mdoc_hash_init(void);
|
void mdoc_hash_init(void);
|
||||||
enum mdoct mdoc_hash_find(const char *);
|
enum mdoct mdoc_hash_find(const char *);
|
||||||
const char *mdoc_a2att(const char *);
|
const char *mdoc_a2att(const char *);
|
||||||
const char *mdoc_a2lib(const char *);
|
const char *mdoc_a2lib(const char *);
|
||||||
const char *mdoc_a2st(const char *);
|
const char *mdoc_a2st(const char *);
|
||||||
const char *mdoc_a2arch(const char *);
|
const char *mdoc_a2arch(const char *);
|
||||||
const char *mdoc_a2vol(const char *);
|
void mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
|
||||||
int mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
|
void mdoc_valid_post(struct mdoc *);
|
||||||
int mdoc_valid_post(struct mdoc *);
|
void mdoc_argv(struct mdoc *, int, enum mdoct,
|
||||||
enum margverr mdoc_argv(struct mdoc *, int, enum mdoct,
|
|
||||||
struct mdoc_arg **, int *, char *);
|
struct mdoc_arg **, int *, char *);
|
||||||
void mdoc_argv_free(struct mdoc_arg *);
|
void mdoc_argv_free(struct mdoc_arg *);
|
||||||
enum margserr mdoc_args(struct mdoc *, int,
|
enum margserr mdoc_args(struct mdoc *, int,
|
||||||
int *, char *, enum mdoct, char **);
|
int *, char *, enum mdoct, char **);
|
||||||
enum margserr mdoc_zargs(struct mdoc *, int,
|
void mdoc_macroend(struct mdoc *);
|
||||||
int *, char *, char **);
|
|
||||||
int mdoc_macroend(struct mdoc *);
|
|
||||||
enum mdelim mdoc_isdelim(const char *);
|
enum mdelim mdoc_isdelim(const char *);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
28
libroff.h
28
libroff.h
@ -1,6 +1,7 @@
|
|||||||
/* $Id: libroff.h,v 1.29 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: libroff.h,v 1.31 2014/10/25 14:35:37 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -43,16 +44,19 @@ struct tbl_node {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct eqn_node {
|
struct eqn_node {
|
||||||
struct eqn_def *defs;
|
struct eqn eqn; /* syntax tree of this equation */
|
||||||
size_t defsz;
|
struct mparse *parse; /* main parser, for error reporting */
|
||||||
char *data;
|
struct eqn_node *next; /* singly linked list of equations */
|
||||||
size_t rew;
|
struct eqn_def *defs; /* array of definitions */
|
||||||
size_t cur;
|
char *data; /* source code of this equation */
|
||||||
size_t sz;
|
size_t defsz; /* number of definitions */
|
||||||
int gsize;
|
size_t sz; /* length of the source code */
|
||||||
struct eqn eqn;
|
size_t cur; /* parse point in the source code */
|
||||||
struct mparse *parse;
|
size_t rew; /* beginning of the current token */
|
||||||
struct eqn_node *next;
|
int gsize; /* default point size */
|
||||||
|
int delim; /* in-line delimiters enabled */
|
||||||
|
char odelim; /* in-line opening delimiter */
|
||||||
|
char cdelim; /* in-line closing delimiter */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eqn_def {
|
struct eqn_def {
|
||||||
@ -73,7 +77,7 @@ int tbl_data(struct tbl_node *, int, const char *);
|
|||||||
int tbl_cdata(struct tbl_node *, int, const char *);
|
int tbl_cdata(struct tbl_node *, int, const char *);
|
||||||
const struct tbl_span *tbl_span(struct tbl_node *);
|
const struct tbl_span *tbl_span(struct tbl_node *);
|
||||||
void tbl_end(struct tbl_node **);
|
void tbl_end(struct tbl_node **);
|
||||||
struct eqn_node *eqn_alloc(const char *, int, int, struct mparse *);
|
struct eqn_node *eqn_alloc(int, int, struct mparse *);
|
||||||
enum rofferr eqn_end(struct eqn_node **);
|
enum rofferr eqn_end(struct eqn_node **);
|
||||||
void eqn_free(struct eqn_node *);
|
void eqn_free(struct eqn_node *);
|
||||||
enum rofferr eqn_read(struct eqn_node **, int,
|
enum rofferr eqn_read(struct eqn_node **, int,
|
||||||
|
539
main.c
539
main.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: main.c,v 1.177 2014/06/21 22:24:01 schwarze Exp $ */
|
/* $Id: main.c,v 1.200 2014/11/26 21:40:17 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||||
*
|
*
|
||||||
@ -16,11 +16,14 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -32,6 +35,8 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
|
#include "manpath.h"
|
||||||
|
#include "mansearch.h"
|
||||||
|
|
||||||
#if !defined(__GNUC__) || (__GNUC__ < 2)
|
#if !defined(__GNUC__) || (__GNUC__ < 2)
|
||||||
# if !defined(lint)
|
# if !defined(lint)
|
||||||
@ -39,6 +44,15 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
|
#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
|
||||||
|
|
||||||
|
enum outmode {
|
||||||
|
OUTMODE_DEF = 0,
|
||||||
|
OUTMODE_FLN,
|
||||||
|
OUTMODE_LST,
|
||||||
|
OUTMODE_ALL,
|
||||||
|
OUTMODE_INT,
|
||||||
|
OUTMODE_ONE
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*out_mdoc)(void *, const struct mdoc *);
|
typedef void (*out_mdoc)(void *, const struct mdoc *);
|
||||||
typedef void (*out_man)(void *, const struct man *);
|
typedef void (*out_man)(void *, const struct man *);
|
||||||
typedef void (*out_free)(void *);
|
typedef void (*out_free)(void *);
|
||||||
@ -50,7 +64,6 @@ enum outt {
|
|||||||
OUTT_TREE, /* -Ttree */
|
OUTT_TREE, /* -Ttree */
|
||||||
OUTT_MAN, /* -Tman */
|
OUTT_MAN, /* -Tman */
|
||||||
OUTT_HTML, /* -Thtml */
|
OUTT_HTML, /* -Thtml */
|
||||||
OUTT_XHTML, /* -Txhtml */
|
|
||||||
OUTT_LINT, /* -Tlint */
|
OUTT_LINT, /* -Tlint */
|
||||||
OUTT_PS, /* -Tps */
|
OUTT_PS, /* -Tps */
|
||||||
OUTT_PDF /* -Tpdf */
|
OUTT_PDF /* -Tpdf */
|
||||||
@ -58,6 +71,7 @@ enum outt {
|
|||||||
|
|
||||||
struct curparse {
|
struct curparse {
|
||||||
struct mparse *mp;
|
struct mparse *mp;
|
||||||
|
struct mchars *mchars; /* character table */
|
||||||
enum mandoclevel wlevel; /* ignore messages below this */
|
enum mandoclevel wlevel; /* ignore messages below this */
|
||||||
int wstop; /* stop after a file with a warning */
|
int wstop; /* stop after a file with a warning */
|
||||||
enum outt outtype; /* which output to use */
|
enum outt outtype; /* which output to use */
|
||||||
@ -68,27 +82,45 @@ struct curparse {
|
|||||||
char outopts[BUFSIZ]; /* buf of output opts */
|
char outopts[BUFSIZ]; /* buf of output opts */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int koptions(int *, char *);
|
||||||
static int moptions(int *, char *);
|
static int moptions(int *, char *);
|
||||||
static void mmsg(enum mandocerr, enum mandoclevel,
|
static void mmsg(enum mandocerr, enum mandoclevel,
|
||||||
const char *, int, int, const char *);
|
const char *, int, int, const char *);
|
||||||
static void parse(struct curparse *, int,
|
static void parse(struct curparse *, int,
|
||||||
const char *, enum mandoclevel *);
|
const char *, enum mandoclevel *);
|
||||||
|
static enum mandoclevel passthrough(const char *, int, int);
|
||||||
|
static void spawn_pager(void);
|
||||||
static int toptions(struct curparse *, char *);
|
static int toptions(struct curparse *, char *);
|
||||||
static void usage(void) __attribute__((noreturn));
|
static void usage(enum argmode) __attribute__((noreturn));
|
||||||
static void version(void) __attribute__((noreturn));
|
static void version(void) __attribute__((noreturn));
|
||||||
static int woptions(struct curparse *, char *);
|
static int woptions(struct curparse *, char *);
|
||||||
|
|
||||||
|
static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
|
||||||
static const char *progname;
|
static const char *progname;
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
|
||||||
struct curparse curp;
|
struct curparse curp;
|
||||||
int options;
|
struct mansearch search;
|
||||||
enum mandoclevel rc;
|
struct manpaths paths;
|
||||||
|
char *conf_file, *defpaths, *auxpaths;
|
||||||
char *defos;
|
char *defos;
|
||||||
|
#if HAVE_SQLITE3
|
||||||
|
struct manpage *res, *resp;
|
||||||
|
size_t isec, i, sz;
|
||||||
|
int prio, best_prio;
|
||||||
|
char sec;
|
||||||
|
#endif
|
||||||
|
enum mandoclevel rc;
|
||||||
|
enum outmode outmode;
|
||||||
|
int fd;
|
||||||
|
int show_usage;
|
||||||
|
int use_pager;
|
||||||
|
int synopsis_only;
|
||||||
|
int options;
|
||||||
|
int c;
|
||||||
|
|
||||||
progname = strrchr(argv[0], '/');
|
progname = strrchr(argv[0], '/');
|
||||||
if (progname == NULL)
|
if (progname == NULL)
|
||||||
@ -96,15 +128,57 @@ main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
++progname;
|
++progname;
|
||||||
|
|
||||||
memset(&curp, 0, sizeof(struct curparse));
|
/* Search options. */
|
||||||
|
|
||||||
options = MPARSE_SO;
|
memset(&paths, 0, sizeof(struct manpaths));
|
||||||
|
conf_file = defpaths = auxpaths = NULL;
|
||||||
|
|
||||||
|
memset(&search, 0, sizeof(struct mansearch));
|
||||||
|
search.outkey = "Nd";
|
||||||
|
|
||||||
|
if (strcmp(progname, "man") == 0)
|
||||||
|
search.argmode = ARG_NAME;
|
||||||
|
else if (strncmp(progname, "apropos", 7) == 0)
|
||||||
|
search.argmode = ARG_EXPR;
|
||||||
|
else if (strncmp(progname, "whatis", 6) == 0)
|
||||||
|
search.argmode = ARG_WORD;
|
||||||
|
else
|
||||||
|
search.argmode = ARG_FILE;
|
||||||
|
|
||||||
|
/* Parser and formatter options. */
|
||||||
|
|
||||||
|
memset(&curp, 0, sizeof(struct curparse));
|
||||||
curp.outtype = OUTT_ASCII;
|
curp.outtype = OUTT_ASCII;
|
||||||
curp.wlevel = MANDOCLEVEL_FATAL;
|
curp.wlevel = MANDOCLEVEL_FATAL;
|
||||||
|
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
|
||||||
defos = NULL;
|
defos = NULL;
|
||||||
|
|
||||||
while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:")))
|
use_pager = 1;
|
||||||
|
show_usage = 0;
|
||||||
|
synopsis_only = 0;
|
||||||
|
outmode = OUTMODE_DEF;
|
||||||
|
|
||||||
|
while (-1 != (c = getopt(argc, argv,
|
||||||
|
"aC:cfhI:iK:klM:m:O:S:s:T:VW:w"))) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
outmode = OUTMODE_ALL;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
conf_file = optarg;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
use_pager = 0;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
search.argmode = ARG_WORD;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
(void)strlcat(curp.outopts, "synopsis,", BUFSIZ);
|
||||||
|
synopsis_only = 1;
|
||||||
|
use_pager = 0;
|
||||||
|
outmode = OUTMODE_ALL;
|
||||||
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
if (strncmp(optarg, "os=", 3)) {
|
if (strncmp(optarg, "os=", 3)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -120,14 +194,37 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
defos = mandoc_strdup(optarg + 3);
|
defos = mandoc_strdup(optarg + 3);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'i':
|
||||||
if ( ! moptions(&options, optarg))
|
outmode = OUTMODE_INT;
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
if ( ! koptions(&options, optarg))
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
break;
|
break;
|
||||||
|
case 'k':
|
||||||
|
search.argmode = ARG_EXPR;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
search.argmode = ARG_FILE;
|
||||||
|
outmode = OUTMODE_ALL;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
defpaths = optarg;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
auxpaths = optarg;
|
||||||
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
|
search.outkey = optarg;
|
||||||
(void)strlcat(curp.outopts, optarg, BUFSIZ);
|
(void)strlcat(curp.outopts, optarg, BUFSIZ);
|
||||||
(void)strlcat(curp.outopts, ",", BUFSIZ);
|
(void)strlcat(curp.outopts, ",", BUFSIZ);
|
||||||
break;
|
break;
|
||||||
|
case 'S':
|
||||||
|
search.arch = optarg;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
search.sec = optarg;
|
||||||
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
if ( ! toptions(&curp, optarg))
|
if ( ! toptions(&curp, optarg))
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
@ -136,15 +233,147 @@ main(int argc, char *argv[])
|
|||||||
if ( ! woptions(&curp, optarg))
|
if ( ! woptions(&curp, optarg))
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
outmode = OUTMODE_FLN;
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
version();
|
version();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
default:
|
default:
|
||||||
usage();
|
show_usage = 1;
|
||||||
/* NOTREACHED */
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_usage)
|
||||||
|
usage(search.argmode);
|
||||||
|
|
||||||
|
/* Postprocess options. */
|
||||||
|
|
||||||
|
if (outmode == OUTMODE_DEF) {
|
||||||
|
switch (search.argmode) {
|
||||||
|
case ARG_FILE:
|
||||||
|
outmode = OUTMODE_ALL;
|
||||||
|
use_pager = 0;
|
||||||
|
break;
|
||||||
|
case ARG_NAME:
|
||||||
|
outmode = OUTMODE_ONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
outmode = OUTMODE_LST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse arguments. */
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
#if HAVE_SQLITE3
|
||||||
|
resp = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Quirk for a man(1) section argument without -s. */
|
||||||
|
|
||||||
|
if (search.argmode == ARG_NAME &&
|
||||||
|
argv[0] != NULL &&
|
||||||
|
isdigit((unsigned char)argv[0][0]) &&
|
||||||
|
(argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) {
|
||||||
|
search.sec = argv[0];
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = MANDOCLEVEL_OK;
|
||||||
|
|
||||||
|
/* man(1), whatis(1), apropos(1) */
|
||||||
|
|
||||||
|
if (search.argmode != ARG_FILE) {
|
||||||
|
#if HAVE_SQLITE3
|
||||||
|
if (argc == 0)
|
||||||
|
usage(search.argmode);
|
||||||
|
|
||||||
|
if (search.argmode == ARG_NAME &&
|
||||||
|
outmode == OUTMODE_ONE)
|
||||||
|
search.firstmatch = 1;
|
||||||
|
|
||||||
|
/* Access the mandoc database. */
|
||||||
|
|
||||||
|
manpath_parse(&paths, conf_file, defpaths, auxpaths);
|
||||||
|
mansearch_setup(1);
|
||||||
|
if( ! mansearch(&search, &paths, argc, argv, &res, &sz))
|
||||||
|
usage(search.argmode);
|
||||||
|
resp = res;
|
||||||
|
|
||||||
|
if (sz == 0) {
|
||||||
|
if (search.argmode == ARG_NAME)
|
||||||
|
fprintf(stderr, "%s: No entry for %s "
|
||||||
|
"in the manual.\n", progname, argv[0]);
|
||||||
|
rc = MANDOCLEVEL_BADARG;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
|
/*
|
||||||
|
* For standard man(1) and -a output mode,
|
||||||
|
* prepare for copying filename pointers
|
||||||
|
* into the program parameter array.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (outmode == OUTMODE_ONE) {
|
||||||
|
argc = 1;
|
||||||
|
best_prio = 10;
|
||||||
|
} else if (outmode == OUTMODE_ALL)
|
||||||
|
argc = (int)sz;
|
||||||
|
|
||||||
|
/* Iterate all matching manuals. */
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++) {
|
||||||
|
if (outmode == OUTMODE_FLN)
|
||||||
|
puts(res[i].file);
|
||||||
|
else if (outmode == OUTMODE_LST)
|
||||||
|
printf("%s - %s\n", res[i].names,
|
||||||
|
res[i].output == NULL ? "" :
|
||||||
|
res[i].output);
|
||||||
|
else if (outmode == OUTMODE_ONE) {
|
||||||
|
/* Search for the best section. */
|
||||||
|
isec = strcspn(res[i].file, "123456789");
|
||||||
|
sec = res[i].file[isec];
|
||||||
|
if ('\0' == sec)
|
||||||
|
continue;
|
||||||
|
prio = sec_prios[sec - '1'];
|
||||||
|
if (prio >= best_prio)
|
||||||
|
continue;
|
||||||
|
best_prio = prio;
|
||||||
|
resp = res + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For man(1), -a and -i output mode, fall through
|
||||||
|
* to the main mandoc(1) code iterating files
|
||||||
|
* and running the parsers on each of them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST)
|
||||||
|
goto out;
|
||||||
|
#else
|
||||||
|
fputs("mandoc: database support not compiled in\n",
|
||||||
|
stderr);
|
||||||
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mandoc(1) */
|
||||||
|
|
||||||
|
if ( ! moptions(&options, auxpaths))
|
||||||
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
|
|
||||||
|
if (use_pager && isatty(STDOUT_FILENO))
|
||||||
|
spawn_pager();
|
||||||
|
|
||||||
|
curp.mchars = mchars_alloc();
|
||||||
|
curp.mp = mparse_alloc(options, curp.wlevel, mmsg,
|
||||||
|
curp.mchars, defos);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conditionally start up the lookaside buffer before parsing.
|
* Conditionally start up the lookaside buffer before parsing.
|
||||||
@ -152,25 +381,53 @@ main(int argc, char *argv[])
|
|||||||
if (OUTT_MAN == curp.outtype)
|
if (OUTT_MAN == curp.outtype)
|
||||||
mparse_keep(curp.mp);
|
mparse_keep(curp.mp);
|
||||||
|
|
||||||
argc -= optind;
|
if (argc == 0)
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
rc = MANDOCLEVEL_OK;
|
|
||||||
|
|
||||||
if (NULL == *argv)
|
|
||||||
parse(&curp, STDIN_FILENO, "<stdin>", &rc);
|
parse(&curp, STDIN_FILENO, "<stdin>", &rc);
|
||||||
|
|
||||||
while (*argv) {
|
while (argc) {
|
||||||
parse(&curp, -1, *argv, &rc);
|
#if HAVE_SQLITE3
|
||||||
|
if (resp != NULL) {
|
||||||
|
rc = mparse_open(curp.mp, &fd, resp->file);
|
||||||
|
if (fd == -1)
|
||||||
|
/* nothing */;
|
||||||
|
else if (resp->form & FORM_SRC) {
|
||||||
|
/* For .so only; ignore failure. */
|
||||||
|
chdir(paths.paths[resp->ipath]);
|
||||||
|
parse(&curp, fd, resp->file, &rc);
|
||||||
|
} else
|
||||||
|
rc = passthrough(resp->file, fd,
|
||||||
|
synopsis_only);
|
||||||
|
resp++;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
rc = mparse_open(curp.mp, &fd, *argv++);
|
||||||
|
if (fd != -1)
|
||||||
|
parse(&curp, fd, argv[-1], &rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mparse_wait(curp.mp) != MANDOCLEVEL_OK)
|
||||||
|
rc = MANDOCLEVEL_SYSERR;
|
||||||
|
|
||||||
if (MANDOCLEVEL_OK != rc && curp.wstop)
|
if (MANDOCLEVEL_OK != rc && curp.wstop)
|
||||||
break;
|
break;
|
||||||
++argv;
|
argc--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curp.outfree)
|
if (curp.outfree)
|
||||||
(*curp.outfree)(curp.outdata);
|
(*curp.outfree)(curp.outdata);
|
||||||
if (curp.mp)
|
mparse_free(curp.mp);
|
||||||
mparse_free(curp.mp);
|
mchars_free(curp.mchars);
|
||||||
|
|
||||||
|
#if HAVE_SQLITE3
|
||||||
|
out:
|
||||||
|
if (search.argmode != ARG_FILE) {
|
||||||
|
manpath_free(&paths);
|
||||||
|
mansearch_free(res, sz);
|
||||||
|
mansearch_setup(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
free(defos);
|
free(defos);
|
||||||
|
|
||||||
return((int)rc);
|
return((int)rc);
|
||||||
@ -180,24 +437,36 @@ static void
|
|||||||
version(void)
|
version(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("%s %s\n", progname, VERSION);
|
printf("mandoc %s\n", VERSION);
|
||||||
exit((int)MANDOCLEVEL_OK);
|
exit((int)MANDOCLEVEL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(enum argmode argmode)
|
||||||
{
|
{
|
||||||
|
|
||||||
fprintf(stderr, "usage: %s "
|
switch (argmode) {
|
||||||
"[-V] "
|
case ARG_FILE:
|
||||||
"[-Ios=name] "
|
fputs("usage: mandoc [-acfhklV] [-Ios=name] "
|
||||||
"[-mformat] "
|
"[-Kencoding] [-mformat] [-Ooption]\n"
|
||||||
"[-Ooption] "
|
"\t [-Toutput] [-Wlevel] [file ...]\n", stderr);
|
||||||
"[-Toutput] "
|
break;
|
||||||
"[-Wlevel]\n"
|
case ARG_NAME:
|
||||||
"\t [file ...]\n",
|
fputs("usage: man [-acfhklVw] [-C file] "
|
||||||
progname);
|
"[-M path] [-m path] [-S arch] [-s section]\n"
|
||||||
|
"\t [section] name ...\n", stderr);
|
||||||
|
break;
|
||||||
|
case ARG_WORD:
|
||||||
|
fputs("usage: whatis [-acfhklVw] [-C file] "
|
||||||
|
"[-M path] [-m path] [-O outkey] [-S arch]\n"
|
||||||
|
"\t [-s section] name ...\n", stderr);
|
||||||
|
break;
|
||||||
|
case ARG_EXPR:
|
||||||
|
fputs("usage: apropos [-acfhklVw] [-C file] "
|
||||||
|
"[-M path] [-m path] [-O outkey] [-S arch]\n"
|
||||||
|
"\t [-s section] expression ...\n", stderr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
exit((int)MANDOCLEVEL_BADARG);
|
exit((int)MANDOCLEVEL_BADARG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,32 +502,34 @@ parse(struct curparse *curp, int fd, const char *file,
|
|||||||
|
|
||||||
if ( ! (curp->outman && curp->outmdoc)) {
|
if ( ! (curp->outman && curp->outmdoc)) {
|
||||||
switch (curp->outtype) {
|
switch (curp->outtype) {
|
||||||
case OUTT_XHTML:
|
|
||||||
curp->outdata = xhtml_alloc(curp->outopts);
|
|
||||||
curp->outfree = html_free;
|
|
||||||
break;
|
|
||||||
case OUTT_HTML:
|
case OUTT_HTML:
|
||||||
curp->outdata = html_alloc(curp->outopts);
|
curp->outdata = html_alloc(curp->mchars,
|
||||||
|
curp->outopts);
|
||||||
curp->outfree = html_free;
|
curp->outfree = html_free;
|
||||||
break;
|
break;
|
||||||
case OUTT_UTF8:
|
case OUTT_UTF8:
|
||||||
curp->outdata = utf8_alloc(curp->outopts);
|
curp->outdata = utf8_alloc(curp->mchars,
|
||||||
|
curp->outopts);
|
||||||
curp->outfree = ascii_free;
|
curp->outfree = ascii_free;
|
||||||
break;
|
break;
|
||||||
case OUTT_LOCALE:
|
case OUTT_LOCALE:
|
||||||
curp->outdata = locale_alloc(curp->outopts);
|
curp->outdata = locale_alloc(curp->mchars,
|
||||||
|
curp->outopts);
|
||||||
curp->outfree = ascii_free;
|
curp->outfree = ascii_free;
|
||||||
break;
|
break;
|
||||||
case OUTT_ASCII:
|
case OUTT_ASCII:
|
||||||
curp->outdata = ascii_alloc(curp->outopts);
|
curp->outdata = ascii_alloc(curp->mchars,
|
||||||
|
curp->outopts);
|
||||||
curp->outfree = ascii_free;
|
curp->outfree = ascii_free;
|
||||||
break;
|
break;
|
||||||
case OUTT_PDF:
|
case OUTT_PDF:
|
||||||
curp->outdata = pdf_alloc(curp->outopts);
|
curp->outdata = pdf_alloc(curp->mchars,
|
||||||
|
curp->outopts);
|
||||||
curp->outfree = pspdf_free;
|
curp->outfree = pspdf_free;
|
||||||
break;
|
break;
|
||||||
case OUTT_PS:
|
case OUTT_PS:
|
||||||
curp->outdata = ps_alloc(curp->outopts);
|
curp->outdata = ps_alloc(curp->mchars,
|
||||||
|
curp->outopts);
|
||||||
curp->outfree = pspdf_free;
|
curp->outfree = pspdf_free;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -267,8 +538,6 @@ parse(struct curparse *curp, int fd, const char *file,
|
|||||||
|
|
||||||
switch (curp->outtype) {
|
switch (curp->outtype) {
|
||||||
case OUTT_HTML:
|
case OUTT_HTML:
|
||||||
/* FALLTHROUGH */
|
|
||||||
case OUTT_XHTML:
|
|
||||||
curp->outman = html_man;
|
curp->outman = html_man;
|
||||||
curp->outmdoc = html_mdoc;
|
curp->outmdoc = html_mdoc;
|
||||||
break;
|
break;
|
||||||
@ -314,11 +583,97 @@ parse(struct curparse *curp, int fd, const char *file,
|
|||||||
*level = rc;
|
*level = rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum mandoclevel
|
||||||
|
passthrough(const char *file, int fd, int synopsis_only)
|
||||||
|
{
|
||||||
|
const char synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS";
|
||||||
|
const char synr[] = "SYNOPSIS";
|
||||||
|
|
||||||
|
FILE *stream;
|
||||||
|
const char *syscall;
|
||||||
|
char *line;
|
||||||
|
size_t len, off;
|
||||||
|
ssize_t nw;
|
||||||
|
int print;
|
||||||
|
|
||||||
|
if ((stream = fdopen(fd, "r")) == NULL) {
|
||||||
|
close(fd);
|
||||||
|
syscall = "fdopen";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
print = 0;
|
||||||
|
while ((line = fgetln(stream, &len)) != NULL) {
|
||||||
|
if (synopsis_only) {
|
||||||
|
if (print) {
|
||||||
|
if ( ! isspace((unsigned char)*line))
|
||||||
|
goto done;
|
||||||
|
while (len &&
|
||||||
|
isspace((unsigned char)*line)) {
|
||||||
|
line++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((len == sizeof(synb) &&
|
||||||
|
! strncmp(line, synb, len - 1)) ||
|
||||||
|
(len == sizeof(synr) &&
|
||||||
|
! strncmp(line, synr, len - 1)))
|
||||||
|
print = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (off = 0; off < len; off += nw)
|
||||||
|
if ((nw = write(STDOUT_FILENO, line + off,
|
||||||
|
len - off)) == -1 || nw == 0) {
|
||||||
|
fclose(stream);
|
||||||
|
syscall = "write";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ferror(stream)) {
|
||||||
|
fclose(stream);
|
||||||
|
syscall = "fgetln";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
fclose(stream);
|
||||||
|
return(MANDOCLEVEL_OK);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
fprintf(stderr, "%s: %s: SYSERR: %s: %s",
|
||||||
|
progname, file, syscall, strerror(errno));
|
||||||
|
return(MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
koptions(int *options, char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( ! strcmp(arg, "utf-8")) {
|
||||||
|
*options |= MPARSE_UTF8;
|
||||||
|
*options &= ~MPARSE_LATIN1;
|
||||||
|
} else if ( ! strcmp(arg, "iso-8859-1")) {
|
||||||
|
*options |= MPARSE_LATIN1;
|
||||||
|
*options &= ~MPARSE_UTF8;
|
||||||
|
} else if ( ! strcmp(arg, "us-ascii")) {
|
||||||
|
*options &= ~(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: -K%s: Bad argument\n",
|
||||||
|
progname, arg);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
moptions(int *options, char *arg)
|
moptions(int *options, char *arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (0 == strcmp(arg, "doc"))
|
if (arg == NULL)
|
||||||
|
/* nothing to do */;
|
||||||
|
else if (0 == strcmp(arg, "doc"))
|
||||||
*options |= MPARSE_MDOC;
|
*options |= MPARSE_MDOC;
|
||||||
else if (0 == strcmp(arg, "andoc"))
|
else if (0 == strcmp(arg, "andoc"))
|
||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
@ -353,7 +708,7 @@ toptions(struct curparse *curp, char *arg)
|
|||||||
else if (0 == strcmp(arg, "locale"))
|
else if (0 == strcmp(arg, "locale"))
|
||||||
curp->outtype = OUTT_LOCALE;
|
curp->outtype = OUTT_LOCALE;
|
||||||
else if (0 == strcmp(arg, "xhtml"))
|
else if (0 == strcmp(arg, "xhtml"))
|
||||||
curp->outtype = OUTT_XHTML;
|
curp->outtype = OUTT_HTML;
|
||||||
else if (0 == strcmp(arg, "ps"))
|
else if (0 == strcmp(arg, "ps"))
|
||||||
curp->outtype = OUTT_PS;
|
curp->outtype = OUTT_PS;
|
||||||
else if (0 == strcmp(arg, "pdf"))
|
else if (0 == strcmp(arg, "pdf"))
|
||||||
@ -428,3 +783,79 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
|
|||||||
|
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spawn_pager(void)
|
||||||
|
{
|
||||||
|
#define MAX_PAGER_ARGS 16
|
||||||
|
char *argv[MAX_PAGER_ARGS];
|
||||||
|
const char *pager;
|
||||||
|
char *cp;
|
||||||
|
int fildes[2];
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
if (pipe(fildes) == -1) {
|
||||||
|
fprintf(stderr, "%s: pipe: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fork()) {
|
||||||
|
case -1:
|
||||||
|
fprintf(stderr, "%s: fork: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
case 0:
|
||||||
|
close(fildes[0]);
|
||||||
|
if (dup2(fildes[1], STDOUT_FILENO) == -1) {
|
||||||
|
fprintf(stderr, "%s: dup output: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The original process becomes the pager. */
|
||||||
|
|
||||||
|
close(fildes[1]);
|
||||||
|
if (dup2(fildes[0], STDIN_FILENO) == -1) {
|
||||||
|
fprintf(stderr, "%s: dup input: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
pager = getenv("MANPAGER");
|
||||||
|
if (pager == NULL || *pager == '\0')
|
||||||
|
pager = getenv("PAGER");
|
||||||
|
if (pager == NULL || *pager == '\0')
|
||||||
|
pager = "/usr/bin/more -s";
|
||||||
|
cp = mandoc_strdup(pager);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the pager command into words.
|
||||||
|
* Intentionally do not do anything fancy here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
argc = 0;
|
||||||
|
while (argc + 1 < MAX_PAGER_ARGS) {
|
||||||
|
argv[argc++] = cp;
|
||||||
|
cp = strchr(cp, ' ');
|
||||||
|
if (cp == NULL)
|
||||||
|
break;
|
||||||
|
*cp++ = '\0';
|
||||||
|
while (*cp == ' ')
|
||||||
|
cp++;
|
||||||
|
if (*cp == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
argv[argc] = NULL;
|
||||||
|
|
||||||
|
/* Hand over to the pager. */
|
||||||
|
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
fprintf(stderr, "%s: exec: %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
15
main.h
15
main.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: main.h,v 1.16 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: main.h,v 1.17 2014/10/28 17:36:19 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -32,8 +32,7 @@ struct man;
|
|||||||
* terminal output routines with different character settings.
|
* terminal output routines with different character settings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *html_alloc(char *);
|
void *html_alloc(const struct mchars *, char *);
|
||||||
void *xhtml_alloc(char *);
|
|
||||||
void html_mdoc(void *, const struct mdoc *);
|
void html_mdoc(void *, const struct mdoc *);
|
||||||
void html_man(void *, const struct man *);
|
void html_man(void *, const struct man *);
|
||||||
void html_free(void *);
|
void html_free(void *);
|
||||||
@ -44,13 +43,13 @@ void tree_man(void *, const struct man *);
|
|||||||
void man_mdoc(void *, const struct mdoc *);
|
void man_mdoc(void *, const struct mdoc *);
|
||||||
void man_man(void *, const struct man *);
|
void man_man(void *, const struct man *);
|
||||||
|
|
||||||
void *locale_alloc(char *);
|
void *locale_alloc(const struct mchars *, char *);
|
||||||
void *utf8_alloc(char *);
|
void *utf8_alloc(const struct mchars *, char *);
|
||||||
void *ascii_alloc(char *);
|
void *ascii_alloc(const struct mchars *, char *);
|
||||||
void ascii_free(void *);
|
void ascii_free(void *);
|
||||||
|
|
||||||
void *pdf_alloc(char *);
|
void *pdf_alloc(const struct mchars *, char *);
|
||||||
void *ps_alloc(char *);
|
void *ps_alloc(const struct mchars *, char *);
|
||||||
void pspdf_free(void *);
|
void pspdf_free(void *);
|
||||||
|
|
||||||
void terminal_mdoc(void *, const struct mdoc *);
|
void terminal_mdoc(void *, const struct mdoc *);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: makewhatis.8,v 1.2 2014/04/25 12:13:15 schwarze Exp $
|
.\" $Id: makewhatis.8,v 1.3 2014/08/17 21:03:06 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
.\" Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: April 25 2014 $
|
.Dd $Mdocdate: August 17 2014 $
|
||||||
.Dt MAKEWHATIS 8
|
.Dt MAKEWHATIS 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -98,7 +98,7 @@ format.
|
|||||||
Display all files added or removed to the index.
|
Display all files added or removed to the index.
|
||||||
With a second
|
With a second
|
||||||
.Fl D ,
|
.Fl D ,
|
||||||
also show all keyswords added for each file.
|
also show all keywords added for each file.
|
||||||
.It Fl d Ar dir
|
.It Fl d Ar dir
|
||||||
Merge (remove and re-add)
|
Merge (remove and re-add)
|
||||||
.Ar
|
.Ar
|
||||||
|
402
man.1
Normal file
402
man.1
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
.\" $Id: man.1,v 1.7 2014/11/11 02:43:41 schwarze Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1989, 1990, 1993
|
||||||
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
.\" Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
|
||||||
|
.\" Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of the University nor the names of its contributors
|
||||||
|
.\" may be used to endorse or promote products derived from this software
|
||||||
|
.\" without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: November 11 2014 $
|
||||||
|
.Dt MAN 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm man
|
||||||
|
.Nd display manual pages
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm man
|
||||||
|
.Op Fl acfhklVw
|
||||||
|
.Op Fl C Ar file
|
||||||
|
.Op Fl M Ar path
|
||||||
|
.Op Fl m Ar path
|
||||||
|
.Op Fl S Ar subsection
|
||||||
|
.Op Fl s Ar section
|
||||||
|
.Op Ar section
|
||||||
|
.Ar name ...
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility
|
||||||
|
displays the
|
||||||
|
manual pages entitled
|
||||||
|
.Ar name .
|
||||||
|
Pages may be selected according to
|
||||||
|
a specific category
|
||||||
|
.Pq Ar section
|
||||||
|
or
|
||||||
|
machine architecture
|
||||||
|
.Pq Ar subsection .
|
||||||
|
.Pp
|
||||||
|
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.
|
||||||
|
.It Fl C Ar file
|
||||||
|
Use the specified
|
||||||
|
.Ar file
|
||||||
|
instead of the default configuration file.
|
||||||
|
This permits users to configure their own manual environment.
|
||||||
|
See
|
||||||
|
.Xr man.conf 5
|
||||||
|
for a description of the contents of this file.
|
||||||
|
.It Fl c
|
||||||
|
Copy the manual page to the standard output instead of using
|
||||||
|
.Xr more 1
|
||||||
|
to paginate it.
|
||||||
|
This is done by default if the standard output is not a terminal device.
|
||||||
|
.It Fl f
|
||||||
|
A synonym for
|
||||||
|
.Xr whatis 1 .
|
||||||
|
It searches for
|
||||||
|
.Ar name
|
||||||
|
in manual page names and displays the header lines from all matching pages.
|
||||||
|
The search is case insensitive and matches whole words only.
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl k
|
||||||
|
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 k
|
||||||
|
A synonym for
|
||||||
|
.Xr apropos 1 .
|
||||||
|
Instead of
|
||||||
|
.Ar name ,
|
||||||
|
an expression can be provided using the syntax described in the
|
||||||
|
.Xr apropos 1
|
||||||
|
manual.
|
||||||
|
By default, it displays the header lines of all matching pages.
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl f
|
||||||
|
and
|
||||||
|
.Fl l
|
||||||
|
options.
|
||||||
|
.It Fl l
|
||||||
|
A synonym for
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl a .
|
||||||
|
The
|
||||||
|
.Ar name
|
||||||
|
arguments are interpreted as filenames.
|
||||||
|
No search is done and
|
||||||
|
.Ar file ,
|
||||||
|
.Ar path ,
|
||||||
|
.Ar section ,
|
||||||
|
and
|
||||||
|
.Ar subsection
|
||||||
|
are ignored.
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl f ,
|
||||||
|
.Fl k ,
|
||||||
|
and
|
||||||
|
.Fl w
|
||||||
|
options.
|
||||||
|
.It Fl M Ar path
|
||||||
|
Override the list of standard directories which
|
||||||
|
.Nm
|
||||||
|
searches for manual pages.
|
||||||
|
The supplied
|
||||||
|
.Ar path
|
||||||
|
must be a colon
|
||||||
|
.Pq Ql \&:
|
||||||
|
separated list of directories.
|
||||||
|
This search path may also be set using the environment variable
|
||||||
|
.Ev MANPATH .
|
||||||
|
The subdirectories to be searched, and their search order,
|
||||||
|
are specified by the
|
||||||
|
.Dq _subdir
|
||||||
|
line in the
|
||||||
|
.Nm
|
||||||
|
configuration file.
|
||||||
|
.It Fl m Ar path
|
||||||
|
Augment the list of standard directories which
|
||||||
|
.Nm
|
||||||
|
searches for manual pages.
|
||||||
|
The supplied
|
||||||
|
.Ar path
|
||||||
|
must be a colon
|
||||||
|
.Pq Ql \&:
|
||||||
|
separated list of directories.
|
||||||
|
These directories will be searched before the standard directories or
|
||||||
|
the directories specified using the
|
||||||
|
.Fl M
|
||||||
|
option or the
|
||||||
|
.Ev MANPATH
|
||||||
|
environment variable.
|
||||||
|
The subdirectories to be searched, and their search order,
|
||||||
|
are specified by the
|
||||||
|
.Dq _subdir
|
||||||
|
line in the
|
||||||
|
.Nm
|
||||||
|
configuration file.
|
||||||
|
.It Fl S Ar subsection
|
||||||
|
Restricts the directories that
|
||||||
|
.Nm
|
||||||
|
will search to those of a specific
|
||||||
|
.Xr machine 1
|
||||||
|
architecture.
|
||||||
|
.Ar subsection
|
||||||
|
is case insensitive.
|
||||||
|
.Pp
|
||||||
|
By default manual pages for all architectures are installed.
|
||||||
|
Therefore this option can be used to view pages for one
|
||||||
|
architecture whilst using another.
|
||||||
|
.Pp
|
||||||
|
This option overrides the
|
||||||
|
.Ev MACHINE
|
||||||
|
environment variable.
|
||||||
|
.It Xo
|
||||||
|
.Op Fl s
|
||||||
|
.Ar section
|
||||||
|
.Xc
|
||||||
|
Restricts the directories that
|
||||||
|
.Nm
|
||||||
|
will search to a specific section.
|
||||||
|
The currently available sections are:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "localXXX" -offset indent -compact
|
||||||
|
.It 1
|
||||||
|
General commands
|
||||||
|
.Pq tools and utilities .
|
||||||
|
.It 2
|
||||||
|
System calls and error numbers.
|
||||||
|
.It 3
|
||||||
|
Libraries.
|
||||||
|
.It 3f
|
||||||
|
Fortran programmer's reference guide.
|
||||||
|
.It 3p
|
||||||
|
.Xr perl 1
|
||||||
|
programmer's reference guide.
|
||||||
|
.It 4
|
||||||
|
Device drivers.
|
||||||
|
.It 5
|
||||||
|
File formats.
|
||||||
|
.It 6
|
||||||
|
Games.
|
||||||
|
.It 7
|
||||||
|
Miscellaneous.
|
||||||
|
.It 8
|
||||||
|
System maintenance and operation commands.
|
||||||
|
.It 9
|
||||||
|
Kernel internals.
|
||||||
|
.It X11
|
||||||
|
An alias for X11R6.
|
||||||
|
.It X11R6
|
||||||
|
X Window System.
|
||||||
|
.It local
|
||||||
|
Pages located in
|
||||||
|
.Pa /usr/local .
|
||||||
|
.It n
|
||||||
|
Tcl/Tk commands.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
configuration file,
|
||||||
|
.Xr man.conf 5 ,
|
||||||
|
specifies the possible
|
||||||
|
.Ar section
|
||||||
|
values, and their search order.
|
||||||
|
Additional sections may be specified.
|
||||||
|
.It Fl V
|
||||||
|
Print version and exit.
|
||||||
|
.It Fl w
|
||||||
|
List the pathnames of the manual pages which
|
||||||
|
.Nm
|
||||||
|
would display for the specified
|
||||||
|
.Ar section
|
||||||
|
and
|
||||||
|
.Ar name
|
||||||
|
combination.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility also supports the options
|
||||||
|
.Fl IKOTW
|
||||||
|
described in the
|
||||||
|
.Xr mandoc 1
|
||||||
|
manual.
|
||||||
|
.Pp
|
||||||
|
Guidelines for writing
|
||||||
|
man pages can be found in
|
||||||
|
.Xr mdoc 7 .
|
||||||
|
.Pp
|
||||||
|
If both a formatted and an unformatted version of the same manual page,
|
||||||
|
for example
|
||||||
|
.Pa cat1/foo.0
|
||||||
|
and
|
||||||
|
.Pa man1/foo.1 ,
|
||||||
|
exist in the same directory, and at least one of them is selected,
|
||||||
|
only the newer one is used.
|
||||||
|
However, if both the
|
||||||
|
.Fl a
|
||||||
|
and the
|
||||||
|
.Fl w
|
||||||
|
options are specified, both file names are printed.
|
||||||
|
.Sh ENVIRONMENT
|
||||||
|
.Bl -tag -width MANPATHX
|
||||||
|
.It Ev MACHINE
|
||||||
|
As some manual pages are intended only for specific architectures,
|
||||||
|
.Nm
|
||||||
|
searches any subdirectories,
|
||||||
|
with the same name as the current architecture,
|
||||||
|
in every directory which it searches.
|
||||||
|
Machine specific areas are checked before general areas.
|
||||||
|
The current machine type may be overridden by setting the environment
|
||||||
|
variable
|
||||||
|
.Ev MACHINE
|
||||||
|
to the name of a specific architecture,
|
||||||
|
or with the
|
||||||
|
.Fl S
|
||||||
|
option.
|
||||||
|
.Ev MACHINE
|
||||||
|
is case insensitive.
|
||||||
|
.It Ev MANPAGER
|
||||||
|
Any non-empty value of the environment variable
|
||||||
|
.Ev MANPAGER
|
||||||
|
will be used instead of the standard pagination program,
|
||||||
|
.Xr more 1 .
|
||||||
|
.It Ev MANPATH
|
||||||
|
The standard search path used by
|
||||||
|
.Nm
|
||||||
|
may be overridden by specifying a path in the
|
||||||
|
.Ev MANPATH
|
||||||
|
environment
|
||||||
|
variable.
|
||||||
|
The format of the path is a colon
|
||||||
|
.Pq Ql \&:
|
||||||
|
separated list of directories.
|
||||||
|
The subdirectories to be searched, as well as their search order,
|
||||||
|
are specified by the
|
||||||
|
.Dq _subdir
|
||||||
|
line in the
|
||||||
|
.Nm
|
||||||
|
configuration file.
|
||||||
|
.It Ev PAGER
|
||||||
|
Specifies the pagination program to use when
|
||||||
|
.Ev MANPAGER
|
||||||
|
is not defined.
|
||||||
|
If neither PAGER nor MANPAGER is defined,
|
||||||
|
.Pa /usr/bin/more Fl s
|
||||||
|
will be used.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/man.conf -compact
|
||||||
|
.It Pa /etc/man.conf
|
||||||
|
default man configuration file
|
||||||
|
.El
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
.Ex -std man
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
.Xr intro 1 ,
|
||||||
|
.Xr whatis 1 ,
|
||||||
|
.Xr whereis 1 ,
|
||||||
|
.Xr intro 2 ,
|
||||||
|
.Xr intro 3 ,
|
||||||
|
.Xr intro 4 ,
|
||||||
|
.Xr intro 5 ,
|
||||||
|
.Xr man.conf 5 ,
|
||||||
|
.Xr intro 6 ,
|
||||||
|
.Xr intro 7 ,
|
||||||
|
.Xr mdoc 7 ,
|
||||||
|
.Xr intro 8 ,
|
||||||
|
.Xr intro 9
|
||||||
|
.Sh STANDARDS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is compliant with the
|
||||||
|
.St -p1003.1-2008
|
||||||
|
specification.
|
||||||
|
.Pp
|
||||||
|
The flags
|
||||||
|
.Op Fl aCcfhMmSsw ,
|
||||||
|
as well as the environment variables
|
||||||
|
.Ev MACHINE ,
|
||||||
|
.Ev MANPAGER ,
|
||||||
|
and
|
||||||
|
.Ev MANPATH ,
|
||||||
|
are extensions to that specification.
|
||||||
|
.Sh HISTORY
|
||||||
|
A
|
||||||
|
.Nm
|
||||||
|
command first appeared in
|
||||||
|
.At v3 .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl w
|
||||||
|
option first appeared in
|
||||||
|
.At v7 ;
|
||||||
|
.Fl f
|
||||||
|
and
|
||||||
|
.Fl k
|
||||||
|
in
|
||||||
|
.Bx 4 ;
|
||||||
|
.Fl M
|
||||||
|
in
|
||||||
|
.Bx 4.3 ;
|
||||||
|
.Fl a
|
||||||
|
in
|
||||||
|
.Bx 4.3 Tahoe ;
|
||||||
|
.Fl c
|
||||||
|
and
|
||||||
|
.Fl m
|
||||||
|
in
|
||||||
|
.Bx 4.3 Reno ;
|
||||||
|
.Fl h
|
||||||
|
in
|
||||||
|
.Bx 4.3 Net/2 ;
|
||||||
|
.Fl C
|
||||||
|
in
|
||||||
|
.Nx 1.0 ;
|
||||||
|
and
|
||||||
|
.Fl s
|
||||||
|
and
|
||||||
|
.Fl S
|
||||||
|
in
|
||||||
|
.Ox 2.3 .
|
246
man.c
246
man.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man.c,v 1.137 2014/08/01 21:24:17 schwarze Exp $ */
|
/* $Id: man.c,v 1.145 2014/11/28 06:27:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -16,9 +16,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -52,8 +50,7 @@ const char * const *man_macronames = __man_macronames;
|
|||||||
|
|
||||||
static struct man_node *man_node_alloc(struct man *, int, int,
|
static struct man_node *man_node_alloc(struct man *, int, int,
|
||||||
enum man_type, enum mant);
|
enum man_type, enum mant);
|
||||||
static int man_node_append(struct man *,
|
static void man_node_append(struct man *, struct man_node *);
|
||||||
struct man_node *);
|
|
||||||
static void man_node_free(struct man_node *);
|
static void man_node_free(struct man_node *);
|
||||||
static void man_node_unlink(struct man *,
|
static void man_node_unlink(struct man *,
|
||||||
struct man_node *);
|
struct man_node *);
|
||||||
@ -61,7 +58,7 @@ static int man_ptext(struct man *, int, char *, int);
|
|||||||
static int man_pmacro(struct man *, int, char *, int);
|
static int man_pmacro(struct man *, int, char *, int);
|
||||||
static void man_free1(struct man *);
|
static void man_free1(struct man *);
|
||||||
static void man_alloc1(struct man *);
|
static void man_alloc1(struct man *);
|
||||||
static int man_descope(struct man *, int, int);
|
static void man_descope(struct man *, int, int);
|
||||||
|
|
||||||
|
|
||||||
const struct man_node *
|
const struct man_node *
|
||||||
@ -114,14 +111,16 @@ int
|
|||||||
man_endparse(struct man *man)
|
man_endparse(struct man *man)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(man_macroend(man));
|
man_macroend(man);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
man_parseln(struct man *man, int ln, char *buf, int offs)
|
man_parseln(struct man *man, int ln, char *buf, int offs)
|
||||||
{
|
{
|
||||||
|
|
||||||
man->flags |= MAN_NEWLINE;
|
if (man->last->type != MAN_EQN || ln > man->last->line)
|
||||||
|
man->flags |= MAN_NEWLINE;
|
||||||
|
|
||||||
return (roff_getcontrol(man->roff, buf, &offs) ?
|
return (roff_getcontrol(man->roff, buf, &offs) ?
|
||||||
man_pmacro(man, ln, buf, offs) :
|
man_pmacro(man, ln, buf, offs) :
|
||||||
@ -134,16 +133,11 @@ man_free1(struct man *man)
|
|||||||
|
|
||||||
if (man->first)
|
if (man->first)
|
||||||
man_node_delete(man, man->first);
|
man_node_delete(man, man->first);
|
||||||
if (man->meta.title)
|
free(man->meta.title);
|
||||||
free(man->meta.title);
|
free(man->meta.source);
|
||||||
if (man->meta.source)
|
free(man->meta.date);
|
||||||
free(man->meta.source);
|
free(man->meta.vol);
|
||||||
if (man->meta.date)
|
free(man->meta.msec);
|
||||||
free(man->meta.date);
|
|
||||||
if (man->meta.vol)
|
|
||||||
free(man->meta.vol);
|
|
||||||
if (man->meta.msec)
|
|
||||||
free(man->meta.msec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -160,13 +154,13 @@ man_alloc1(struct man *man)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
man_node_append(struct man *man, struct man_node *p)
|
man_node_append(struct man *man, struct man_node *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(man->last);
|
assert(man->last);
|
||||||
assert(man->first);
|
assert(man->first);
|
||||||
assert(MAN_ROOT != p->type);
|
assert(p->type != MAN_ROOT);
|
||||||
|
|
||||||
switch (man->next) {
|
switch (man->next) {
|
||||||
case MAN_NEXT_SIBLING:
|
case MAN_NEXT_SIBLING:
|
||||||
@ -192,15 +186,11 @@ man_node_append(struct man *man, struct man_node *p)
|
|||||||
man->flags &= ~MAN_LITERAL;
|
man->flags &= ~MAN_LITERAL;
|
||||||
break;
|
break;
|
||||||
case MAN_HEAD:
|
case MAN_HEAD:
|
||||||
assert(MAN_BLOCK == p->parent->type);
|
assert(p->parent->type == MAN_BLOCK);
|
||||||
p->parent->head = p;
|
p->parent->head = p;
|
||||||
break;
|
break;
|
||||||
case MAN_TAIL:
|
|
||||||
assert(MAN_BLOCK == p->parent->type);
|
|
||||||
p->parent->tail = p;
|
|
||||||
break;
|
|
||||||
case MAN_BODY:
|
case MAN_BODY:
|
||||||
assert(MAN_BLOCK == p->parent->type);
|
assert(p->parent->type == MAN_BLOCK);
|
||||||
p->parent->body = p;
|
p->parent->body = p;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -213,14 +203,11 @@ man_node_append(struct man *man, struct man_node *p)
|
|||||||
case MAN_TBL:
|
case MAN_TBL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MAN_TEXT:
|
case MAN_TEXT:
|
||||||
if ( ! man_valid_post(man))
|
man_valid_post(man);
|
||||||
return(0);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct man_node *
|
static struct man_node *
|
||||||
@ -235,85 +222,76 @@ man_node_alloc(struct man *man, int line, int pos,
|
|||||||
p->type = type;
|
p->type = type;
|
||||||
p->tok = tok;
|
p->tok = tok;
|
||||||
|
|
||||||
if (MAN_NEWLINE & man->flags)
|
if (man->flags & MAN_NEWLINE)
|
||||||
p->flags |= MAN_LINE;
|
p->flags |= MAN_LINE;
|
||||||
man->flags &= ~MAN_NEWLINE;
|
man->flags &= ~MAN_NEWLINE;
|
||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_elem_alloc(struct man *man, int line, int pos, enum mant tok)
|
man_elem_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||||
{
|
{
|
||||||
struct man_node *p;
|
struct man_node *p;
|
||||||
|
|
||||||
p = man_node_alloc(man, line, pos, MAN_ELEM, tok);
|
p = man_node_alloc(man, line, pos, MAN_ELEM, tok);
|
||||||
if ( ! man_node_append(man, p))
|
man_node_append(man, p);
|
||||||
return(0);
|
|
||||||
man->next = MAN_NEXT_CHILD;
|
man->next = MAN_NEXT_CHILD;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_tail_alloc(struct man *man, int line, int pos, enum mant tok)
|
|
||||||
{
|
|
||||||
struct man_node *p;
|
|
||||||
|
|
||||||
p = man_node_alloc(man, line, pos, MAN_TAIL, tok);
|
|
||||||
if ( ! man_node_append(man, p))
|
|
||||||
return(0);
|
|
||||||
man->next = MAN_NEXT_CHILD;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
man_head_alloc(struct man *man, int line, int pos, enum mant tok)
|
man_head_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||||
{
|
{
|
||||||
struct man_node *p;
|
struct man_node *p;
|
||||||
|
|
||||||
p = man_node_alloc(man, line, pos, MAN_HEAD, tok);
|
p = man_node_alloc(man, line, pos, MAN_HEAD, tok);
|
||||||
if ( ! man_node_append(man, p))
|
man_node_append(man, p);
|
||||||
return(0);
|
|
||||||
man->next = MAN_NEXT_CHILD;
|
man->next = MAN_NEXT_CHILD;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_body_alloc(struct man *man, int line, int pos, enum mant tok)
|
man_body_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||||
{
|
{
|
||||||
struct man_node *p;
|
struct man_node *p;
|
||||||
|
|
||||||
p = man_node_alloc(man, line, pos, MAN_BODY, tok);
|
p = man_node_alloc(man, line, pos, MAN_BODY, tok);
|
||||||
if ( ! man_node_append(man, p))
|
man_node_append(man, p);
|
||||||
return(0);
|
|
||||||
man->next = MAN_NEXT_CHILD;
|
man->next = MAN_NEXT_CHILD;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_block_alloc(struct man *man, int line, int pos, enum mant tok)
|
man_block_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||||
{
|
{
|
||||||
struct man_node *p;
|
struct man_node *p;
|
||||||
|
|
||||||
p = man_node_alloc(man, line, pos, MAN_BLOCK, tok);
|
p = man_node_alloc(man, line, pos, MAN_BLOCK, tok);
|
||||||
if ( ! man_node_append(man, p))
|
man_node_append(man, p);
|
||||||
return(0);
|
|
||||||
man->next = MAN_NEXT_CHILD;
|
man->next = MAN_NEXT_CHILD;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_word_alloc(struct man *man, int line, int pos, const char *word)
|
man_word_alloc(struct man *man, int line, int pos, const char *word)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX);
|
n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX);
|
||||||
n->string = roff_strdup(man->roff, word);
|
n->string = roff_strdup(man->roff, word);
|
||||||
|
man_node_append(man, n);
|
||||||
if ( ! man_node_append(man, n))
|
man->next = MAN_NEXT_SIBLING;
|
||||||
return(0);
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
man_word_append(struct man *man, const char *word)
|
||||||
|
{
|
||||||
|
struct man_node *n;
|
||||||
|
char *addstr, *newstr;
|
||||||
|
|
||||||
|
n = man->last;
|
||||||
|
addstr = roff_strdup(man->roff, word);
|
||||||
|
mandoc_asprintf(&newstr, "%s %s", n->string, addstr);
|
||||||
|
free(addstr);
|
||||||
|
free(n->string);
|
||||||
|
n->string = newstr;
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -324,8 +302,7 @@ static void
|
|||||||
man_node_free(struct man_node *p)
|
man_node_free(struct man_node *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (p->string)
|
free(p->string);
|
||||||
free(p->string);
|
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,37 +317,33 @@ man_node_delete(struct man *man, struct man_node *p)
|
|||||||
man_node_free(p);
|
man_node_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_addeqn(struct man *man, const struct eqn *ep)
|
man_addeqn(struct man *man, const struct eqn *ep)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
|
n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
|
||||||
n->eqn = ep;
|
n->eqn = ep;
|
||||||
|
if (ep->ln > man->last->line)
|
||||||
if ( ! man_node_append(man, n))
|
n->flags |= MAN_LINE;
|
||||||
return(0);
|
man_node_append(man, n);
|
||||||
|
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
return(man_descope(man, ep->ln, ep->pos));
|
man_descope(man, ep->ln, ep->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
man_addspan(struct man *man, const struct tbl_span *sp)
|
man_addspan(struct man *man, const struct tbl_span *sp)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX);
|
n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX);
|
||||||
n->span = sp;
|
n->span = sp;
|
||||||
|
man_node_append(man, n);
|
||||||
if ( ! man_node_append(man, n))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
return(man_descope(man, sp->line, 0));
|
man_descope(man, sp->line, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
man_descope(struct man *man, int line, int offs)
|
man_descope(struct man *man, int line, int offs)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -379,19 +352,15 @@ man_descope(struct man *man, int line, int offs)
|
|||||||
* out the block scope (also if applicable).
|
* out the block scope (also if applicable).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (MAN_ELINE & man->flags) {
|
if (man->flags & MAN_ELINE) {
|
||||||
man->flags &= ~MAN_ELINE;
|
man->flags &= ~MAN_ELINE;
|
||||||
if ( ! man_unscope(man, man->last->parent))
|
man_unscope(man, man->last->parent);
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
if ( ! (man->flags & MAN_BLINE))
|
||||||
if ( ! (MAN_BLINE & man->flags))
|
return;
|
||||||
return(1);
|
|
||||||
man->flags &= ~MAN_BLINE;
|
man->flags &= ~MAN_BLINE;
|
||||||
|
man_unscope(man, man->last->parent);
|
||||||
if ( ! man_unscope(man, man->last->parent))
|
man_body_alloc(man, line, offs, man->last->tok);
|
||||||
return(0);
|
|
||||||
return(man_body_alloc(man, line, offs, man->last->tok));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -401,13 +370,13 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
|
|
||||||
/* Literal free-form text whitespace is preserved. */
|
/* Literal free-form text whitespace is preserved. */
|
||||||
|
|
||||||
if (MAN_LITERAL & man->flags) {
|
if (man->flags & MAN_LITERAL) {
|
||||||
if ( ! man_word_alloc(man, line, offs, buf + offs))
|
man_word_alloc(man, line, offs, buf + offs);
|
||||||
return(0);
|
man_descope(man, line, offs);
|
||||||
return(man_descope(man, line, offs));
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = offs; ' ' == buf[i]; i++)
|
for (i = offs; buf[i] == ' '; i++)
|
||||||
/* Skip leading whitespace. */ ;
|
/* Skip leading whitespace. */ ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -415,12 +384,11 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
* but add a single vertical space elsewhere.
|
* but add a single vertical space elsewhere.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\0' == buf[i]) {
|
if (buf[i] == '\0') {
|
||||||
/* Allocate a blank entry. */
|
/* Allocate a blank entry. */
|
||||||
if (MAN_SH != man->last->tok &&
|
if (man->last->tok != MAN_SH &&
|
||||||
MAN_SS != man->last->tok) {
|
man->last->tok != MAN_SS) {
|
||||||
if ( ! man_elem_alloc(man, line, offs, MAN_sp))
|
man_elem_alloc(man, line, offs, MAN_sp);
|
||||||
return(0);
|
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
}
|
}
|
||||||
return(1);
|
return(1);
|
||||||
@ -447,9 +415,7 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
|
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
}
|
}
|
||||||
|
man_word_alloc(man, line, offs, buf + offs);
|
||||||
if ( ! man_word_alloc(man, line, offs, buf + offs))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End-of-sentence check. If the last character is an unescaped
|
* End-of-sentence check. If the last character is an unescaped
|
||||||
@ -461,50 +427,59 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
if (mandoc_eos(buf, (size_t)i))
|
if (mandoc_eos(buf, (size_t)i))
|
||||||
man->last->flags |= MAN_EOS;
|
man->last->flags |= MAN_EOS;
|
||||||
|
|
||||||
return(man_descope(man, line, offs));
|
man_descope(man, line, offs);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
man_pmacro(struct man *man, int ln, char *buf, int offs)
|
man_pmacro(struct man *man, int ln, char *buf, int offs)
|
||||||
{
|
{
|
||||||
char mac[5];
|
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
const char *cp;
|
||||||
enum mant tok;
|
enum mant tok;
|
||||||
int i, ppos;
|
int i, ppos;
|
||||||
int bline;
|
int bline;
|
||||||
|
char mac[5];
|
||||||
if ('"' == buf[offs]) {
|
|
||||||
mandoc_msg(MANDOCERR_COMMENT_BAD, man->parse,
|
|
||||||
ln, offs, NULL);
|
|
||||||
return(1);
|
|
||||||
} else if ('\0' == buf[offs])
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
ppos = offs;
|
ppos = offs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the first word into a nil-terminated buffer.
|
* Copy the first word into a nil-terminated buffer.
|
||||||
* Stop copying when a tab, space, or eoln is encountered.
|
* Stop when a space, tab, escape, or eoln is encountered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < 4 && '\0' != buf[offs] && ' ' != buf[offs] &&
|
while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
|
||||||
'\t' != buf[offs])
|
|
||||||
mac[i++] = buf[offs++];
|
mac[i++] = buf[offs++];
|
||||||
|
|
||||||
mac[i] = '\0';
|
mac[i] = '\0';
|
||||||
|
|
||||||
tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
|
tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
|
||||||
|
|
||||||
if (MAN_MAX == tok) {
|
if (tok == MAN_MAX) {
|
||||||
mandoc_msg(MANDOCERR_MACRO, man->parse,
|
mandoc_msg(MANDOCERR_MACRO, man->parse,
|
||||||
ln, ppos, buf + ppos - 1);
|
ln, ppos, buf + ppos - 1);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The macro is sane. Jump to the next word. */
|
/* Skip a leading escape sequence or tab. */
|
||||||
|
|
||||||
while (buf[offs] && ' ' == buf[offs])
|
switch (buf[offs]) {
|
||||||
|
case '\\':
|
||||||
|
cp = buf + offs + 1;
|
||||||
|
mandoc_escape(&cp, NULL, NULL);
|
||||||
|
offs = cp - buf;
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
offs++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jump to the next non-whitespace word. */
|
||||||
|
|
||||||
|
while (buf[offs] && buf[offs] == ' ')
|
||||||
offs++;
|
offs++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -512,7 +487,7 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
* into the parser as "text", so we only warn about spaces here.
|
* into the parser as "text", so we only warn about spaces here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
if (buf[offs] == '\0' && buf[offs - 1] == ' ')
|
||||||
mandoc_msg(MANDOCERR_SPACE_EOL, man->parse,
|
mandoc_msg(MANDOCERR_SPACE_EOL, man->parse,
|
||||||
ln, offs - 1, NULL);
|
ln, offs - 1, NULL);
|
||||||
|
|
||||||
@ -522,14 +497,14 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
* macros---they don't print text---so we let those slip by.
|
* macros---they don't print text---so we let those slip by.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
|
if ( ! (man_macros[tok].flags & MAN_NSCOPED) &&
|
||||||
man->flags & MAN_ELINE) {
|
man->flags & MAN_ELINE) {
|
||||||
n = man->last;
|
n = man->last;
|
||||||
assert(MAN_TEXT != n->type);
|
assert(MAN_TEXT != n->type);
|
||||||
|
|
||||||
/* Remove repeated NSCOPED macros causing ELINE. */
|
/* Remove repeated NSCOPED macros causing ELINE. */
|
||||||
|
|
||||||
if (MAN_NSCOPED & man_macros[n->tok].flags)
|
if (man_macros[n->tok].flags & MAN_NSCOPED)
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
|
|
||||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line,
|
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line,
|
||||||
@ -544,24 +519,24 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
* Remove prior BLINE macro that is being clobbered.
|
* Remove prior BLINE macro that is being clobbered.
|
||||||
*/
|
*/
|
||||||
if ((man->flags & MAN_BLINE) &&
|
if ((man->flags & MAN_BLINE) &&
|
||||||
(MAN_BSCOPE & man_macros[tok].flags)) {
|
(man_macros[tok].flags & MAN_BSCOPE)) {
|
||||||
n = man->last;
|
n = man->last;
|
||||||
|
|
||||||
/* Might be a text node like 8 in
|
/* Might be a text node like 8 in
|
||||||
* .TP 8
|
* .TP 8
|
||||||
* .SH foo
|
* .SH foo
|
||||||
*/
|
*/
|
||||||
if (MAN_TEXT == n->type)
|
if (n->type == MAN_TEXT)
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
|
|
||||||
/* Remove element that didn't end BLINE, if any. */
|
/* Remove element that didn't end BLINE, if any. */
|
||||||
if ( ! (MAN_BSCOPE & man_macros[n->tok].flags))
|
if ( ! (man_macros[n->tok].flags & MAN_BSCOPE))
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
|
|
||||||
assert(MAN_HEAD == n->type);
|
assert(n->type == MAN_HEAD);
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
assert(MAN_BLOCK == n->type);
|
assert(n->type == MAN_BLOCK);
|
||||||
assert(MAN_SCOPED & man_macros[n->tok].flags);
|
assert(man_macros[n->tok].flags & MAN_SCOPED);
|
||||||
|
|
||||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line,
|
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line,
|
||||||
n->pos, "%s breaks %s", man_macronames[tok],
|
n->pos, "%s breaks %s", man_macronames[tok],
|
||||||
@ -578,14 +553,13 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
/* Call to handler... */
|
/* Call to handler... */
|
||||||
|
|
||||||
assert(man_macros[tok].fp);
|
assert(man_macros[tok].fp);
|
||||||
if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf))
|
(*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf);
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* In quick mode (for mandocdb), abort after the NAME section. */
|
/* In quick mode (for mandocdb), abort after the NAME section. */
|
||||||
|
|
||||||
if (man->quick && MAN_SH == tok) {
|
if (man->quick && tok == MAN_SH) {
|
||||||
n = man->last;
|
n = man->last;
|
||||||
if (MAN_BODY == n->type &&
|
if (n->type == MAN_BODY &&
|
||||||
strcmp(n->prev->child->string, "NAME"))
|
strcmp(n->prev->child->string, "NAME"))
|
||||||
return(2);
|
return(2);
|
||||||
}
|
}
|
||||||
@ -600,12 +574,12 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
man_macros[tok].flags & MAN_NSCOPED)
|
man_macros[tok].flags & MAN_NSCOPED)
|
||||||
return(1);
|
return(1);
|
||||||
|
|
||||||
assert(MAN_BLINE & man->flags);
|
assert(man->flags & MAN_BLINE);
|
||||||
man->flags &= ~MAN_BLINE;
|
man->flags &= ~MAN_BLINE;
|
||||||
|
|
||||||
if ( ! man_unscope(man, man->last->parent))
|
man_unscope(man, man->last->parent);
|
||||||
return(0);
|
man_body_alloc(man, ln, ppos, man->last->tok);
|
||||||
return(man_body_alloc(man, ln, ppos, man->last->tok));
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -663,7 +637,7 @@ man_deroff(char **dest, const struct man_node *n)
|
|||||||
char *cp;
|
char *cp;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
if (MAN_TEXT != n->type) {
|
if (n->type != MAN_TEXT) {
|
||||||
for (n = n->child; n; n = n->next)
|
for (n = n->child; n; n = n->next)
|
||||||
man_deroff(dest, n);
|
man_deroff(dest, n);
|
||||||
return;
|
return;
|
||||||
|
12
man.cgi.8
12
man.cgi.8
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: man.cgi.8,v 1.9 2014/07/22 18:14:13 schwarze Exp $
|
.\" $Id: man.cgi.8,v 1.11 2014/09/14 19:44:28 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: July 22 2014 $
|
.Dd $Mdocdate: September 14 2014 $
|
||||||
.Dt MAN.CGI 8
|
.Dt MAN.CGI 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -43,6 +43,12 @@ either a name of a manual page or an
|
|||||||
using the syntax described in the
|
using the syntax described in the
|
||||||
.Xr apropos 1
|
.Xr apropos 1
|
||||||
manual; filling this in is required for each search.
|
manual; filling this in is required for each search.
|
||||||
|
.Pp
|
||||||
|
The expression is broken into words at whitespace.
|
||||||
|
Whitespace characters and backslashes can be escaped
|
||||||
|
by prepending a backslash.
|
||||||
|
The effect of prepending a backslash to another character is undefined;
|
||||||
|
in the current implementation, it has no effect.
|
||||||
.It
|
.It
|
||||||
A
|
A
|
||||||
.Dq Submit
|
.Dq Submit
|
||||||
@ -307,7 +313,7 @@ and ending before the
|
|||||||
.Ev QUERY_STRING .
|
.Ev QUERY_STRING .
|
||||||
It is used by the
|
It is used by the
|
||||||
.Cm show
|
.Cm show
|
||||||
page to aquire the manpath and filename it needs.
|
page to acquire the manpath and filename it needs.
|
||||||
.It Ev QUERY_STRING
|
.It Ev QUERY_STRING
|
||||||
The HTTP query string passed from the client to the server.
|
The HTTP query string passed from the client to the server.
|
||||||
It is the final part of the URI, after the question mark.
|
It is the final part of the URI, after the question mark.
|
||||||
|
3
man.h
3
man.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man.h,v 1.65 2014/06/20 23:02:31 schwarze Exp $ */
|
/* $Id: man.h,v 1.66 2014/11/28 05:51:32 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -68,7 +68,6 @@ enum man_type {
|
|||||||
MAN_BLOCK,
|
MAN_BLOCK,
|
||||||
MAN_HEAD,
|
MAN_HEAD,
|
||||||
MAN_BODY,
|
MAN_BODY,
|
||||||
MAN_TAIL,
|
|
||||||
MAN_TBL,
|
MAN_TBL,
|
||||||
MAN_EQN
|
MAN_EQN
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man_hash.c,v 1.27 2014/04/20 16:46:04 schwarze Exp $ */
|
/* $Id: man_hash.c,v 1.28 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
63
man_html.c
63
man_html.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: man_html.c,v 1.96 2014/08/01 19:25:52 schwarze Exp $ */
|
/* $Id: man_html.c,v 1.104 2014/09/27 11:17:19 kristaps Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -144,7 +142,7 @@ print_bvspace(struct html *h, const struct man_node *n)
|
|||||||
if (NULL == n->prev)
|
if (NULL == n->prev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -221,7 +219,7 @@ print_man_node(MAN_ARGS)
|
|||||||
* before printing the line's data.
|
* before printing the line's data.
|
||||||
*/
|
*/
|
||||||
if ('\0' == *n->string) {
|
if ('\0' == *n->string) {
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +299,7 @@ a2width(const struct man_node *n, struct roffsu *su)
|
|||||||
static void
|
static void
|
||||||
man_root_pre(MAN_ARGS)
|
man_root_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
struct htmlpair tag[3];
|
struct htmlpair tag;
|
||||||
struct tag *t, *tt;
|
struct tag *t, *tt;
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
@ -309,34 +307,26 @@ man_root_pre(MAN_ARGS)
|
|||||||
assert(man->msec);
|
assert(man->msec);
|
||||||
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
|
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
|
||||||
|
|
||||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
PAIR_CLASS_INIT(&tag, "head");
|
||||||
PAIR_CLASS_INIT(&tag[1], "head");
|
t = print_otag(h, TAG_TABLE, 1, &tag);
|
||||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
|
||||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
|
||||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
|
|
||||||
print_otag(h, TAG_TBODY, 0, NULL);
|
print_otag(h, TAG_TBODY, 0, NULL);
|
||||||
|
|
||||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "head-ltitle");
|
PAIR_CLASS_INIT(&tag, "head-ltitle");
|
||||||
print_otag(h, TAG_TD, 1, tag);
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_text(h, title);
|
print_text(h, title);
|
||||||
print_stagq(h, tt);
|
print_stagq(h, tt);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
PAIR_CLASS_INIT(&tag, "head-vol");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
|
||||||
if (NULL != man->vol)
|
if (NULL != man->vol)
|
||||||
print_text(h, man->vol);
|
print_text(h, man->vol);
|
||||||
print_stagq(h, tt);
|
print_stagq(h, tt);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "head-rtitle");
|
PAIR_CLASS_INIT(&tag, "head-rtitle");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
|
||||||
print_text(h, title);
|
print_text(h, title);
|
||||||
print_tagq(h, t);
|
print_tagq(h, t);
|
||||||
free(title);
|
free(title);
|
||||||
@ -345,29 +335,23 @@ man_root_pre(MAN_ARGS)
|
|||||||
static void
|
static void
|
||||||
man_root_post(MAN_ARGS)
|
man_root_post(MAN_ARGS)
|
||||||
{
|
{
|
||||||
struct htmlpair tag[3];
|
struct htmlpair tag;
|
||||||
struct tag *t, *tt;
|
struct tag *t, *tt;
|
||||||
|
|
||||||
PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
|
PAIR_CLASS_INIT(&tag, "foot");
|
||||||
PAIR_CLASS_INIT(&tag[1], "foot");
|
t = print_otag(h, TAG_TABLE, 1, &tag);
|
||||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
|
||||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
|
||||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
|
|
||||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
PAIR_CLASS_INIT(&tag, "foot-date");
|
||||||
print_otag(h, TAG_TD, 1, tag);
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
|
|
||||||
assert(man->date);
|
assert(man->date);
|
||||||
print_text(h, man->date);
|
print_text(h, man->date);
|
||||||
print_stagq(h, tt);
|
print_stagq(h, tt);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
PAIR_CLASS_INIT(&tag, "foot-os");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
|
||||||
|
|
||||||
if (man->source)
|
if (man->source)
|
||||||
print_text(h, man->source);
|
print_text(h, man->source);
|
||||||
@ -554,7 +538,7 @@ man_IP_pre(MAN_ARGS)
|
|||||||
static int
|
static int
|
||||||
man_HP_pre(MAN_ARGS)
|
man_HP_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
struct htmlpair tag;
|
struct htmlpair tag[2];
|
||||||
struct roffsu su;
|
struct roffsu su;
|
||||||
const struct man_node *np;
|
const struct man_node *np;
|
||||||
|
|
||||||
@ -574,8 +558,9 @@ man_HP_pre(MAN_ARGS)
|
|||||||
bufcat_su(h, "margin-left", &su);
|
bufcat_su(h, "margin-left", &su);
|
||||||
su.scale = -su.scale;
|
su.scale = -su.scale;
|
||||||
bufcat_su(h, "text-indent", &su);
|
bufcat_su(h, "text-indent", &su);
|
||||||
PAIR_STYLE_INIT(&tag, h);
|
PAIR_STYLE_INIT(&tag[0], h);
|
||||||
print_otag(h, TAG_P, 1, &tag);
|
PAIR_CLASS_INIT(&tag[1], "spacer");
|
||||||
|
print_otag(h, TAG_DIV, 2, tag);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
171
man_macro.c
171
man_macro.c
@ -1,7 +1,7 @@
|
|||||||
/* $Id: man_macro.c,v 1.87 2014/07/30 23:01:39 schwarze Exp $ */
|
/* $Id: man_macro.c,v 1.91 2014/11/28 05:51:32 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@ -16,9 +16,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -36,14 +36,14 @@ enum rew {
|
|||||||
REW_HALT
|
REW_HALT
|
||||||
};
|
};
|
||||||
|
|
||||||
static int blk_close(MACRO_PROT_ARGS);
|
static void blk_close(MACRO_PROT_ARGS);
|
||||||
static int blk_exp(MACRO_PROT_ARGS);
|
static void blk_exp(MACRO_PROT_ARGS);
|
||||||
static int blk_imp(MACRO_PROT_ARGS);
|
static void blk_imp(MACRO_PROT_ARGS);
|
||||||
static int in_line_eoln(MACRO_PROT_ARGS);
|
static void in_line_eoln(MACRO_PROT_ARGS);
|
||||||
static int man_args(struct man *, int,
|
static int man_args(struct man *, int,
|
||||||
int *, char *, char **);
|
int *, char *, char **);
|
||||||
|
|
||||||
static int rew_scope(enum man_type,
|
static void rew_scope(enum man_type,
|
||||||
struct man *, enum mant);
|
struct man *, enum mant);
|
||||||
static enum rew rew_dohalt(enum mant, enum man_type,
|
static enum rew rew_dohalt(enum mant, enum man_type,
|
||||||
const struct man_node *);
|
const struct man_node *);
|
||||||
@ -61,15 +61,15 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
|||||||
{ blk_imp, MAN_BSCOPE }, /* P */
|
{ blk_imp, MAN_BSCOPE }, /* P */
|
||||||
{ blk_imp, MAN_BSCOPE }, /* IP */
|
{ blk_imp, MAN_BSCOPE }, /* IP */
|
||||||
{ blk_imp, MAN_BSCOPE }, /* HP */
|
{ blk_imp, MAN_BSCOPE }, /* HP */
|
||||||
{ in_line_eoln, MAN_SCOPED }, /* SM */
|
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* SM */
|
||||||
{ in_line_eoln, MAN_SCOPED }, /* SB */
|
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* SB */
|
||||||
{ in_line_eoln, 0 }, /* BI */
|
{ in_line_eoln, 0 }, /* BI */
|
||||||
{ in_line_eoln, 0 }, /* IB */
|
{ in_line_eoln, 0 }, /* IB */
|
||||||
{ in_line_eoln, 0 }, /* BR */
|
{ in_line_eoln, 0 }, /* BR */
|
||||||
{ in_line_eoln, 0 }, /* RB */
|
{ in_line_eoln, 0 }, /* RB */
|
||||||
{ in_line_eoln, MAN_SCOPED }, /* R */
|
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* R */
|
||||||
{ in_line_eoln, MAN_SCOPED }, /* B */
|
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* B */
|
||||||
{ in_line_eoln, MAN_SCOPED }, /* I */
|
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* I */
|
||||||
{ in_line_eoln, 0 }, /* IR */
|
{ in_line_eoln, 0 }, /* IR */
|
||||||
{ in_line_eoln, 0 }, /* RI */
|
{ in_line_eoln, 0 }, /* RI */
|
||||||
{ in_line_eoln, MAN_NSCOPED }, /* na */
|
{ in_line_eoln, MAN_NSCOPED }, /* na */
|
||||||
@ -95,12 +95,11 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
|||||||
const struct man_macro * const man_macros = __man_macros;
|
const struct man_macro * const man_macros = __man_macros;
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
man_unscope(struct man *man, const struct man_node *to)
|
man_unscope(struct man *man, const struct man_node *to)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
man->next = MAN_NEXT_SIBLING;
|
|
||||||
to = to->parent;
|
to = to->parent;
|
||||||
n = man->last;
|
n = man->last;
|
||||||
while (n != to) {
|
while (n != to) {
|
||||||
@ -139,20 +138,29 @@ man_unscope(struct man *man, const struct man_node *to)
|
|||||||
* Save a pointer to the parent such that
|
* Save a pointer to the parent such that
|
||||||
* we know where to continue the iteration.
|
* we know where to continue the iteration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
man->last = n;
|
man->last = n;
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
if ( ! man_valid_post(man))
|
man_valid_post(man);
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
return(1);
|
|
||||||
|
/*
|
||||||
|
* If we ended up at the parent of the node we were
|
||||||
|
* supposed to rewind to, that means the target node
|
||||||
|
* got deleted, so add the next node we parse as a child
|
||||||
|
* of the parent instead of as a sibling of the target.
|
||||||
|
*/
|
||||||
|
|
||||||
|
man->next = (man->last == to) ?
|
||||||
|
MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum rew
|
static enum rew
|
||||||
rew_block(enum mant ntok, enum man_type type, const struct man_node *n)
|
rew_block(enum mant ntok, enum man_type type, const struct man_node *n)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MAN_BLOCK == type && ntok == n->parent->tok &&
|
if (type == MAN_BLOCK && ntok == n->parent->tok &&
|
||||||
MAN_BODY == n->parent->type)
|
n->parent->type == MAN_BODY)
|
||||||
return(REW_REWIND);
|
return(REW_REWIND);
|
||||||
return(ntok == n->tok ? REW_HALT : REW_NOHALT);
|
return(ntok == n->tok ? REW_HALT : REW_NOHALT);
|
||||||
}
|
}
|
||||||
@ -235,7 +243,7 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
|||||||
* for example, the `SH' macro will close out any intervening `SS'
|
* for example, the `SH' macro will close out any intervening `SS'
|
||||||
* scopes. When a scope is closed, it must be validated and actioned.
|
* scopes. When a scope is closed, it must be validated and actioned.
|
||||||
*/
|
*/
|
||||||
static int
|
static void
|
||||||
rew_scope(enum man_type type, struct man *man, enum mant tok)
|
rew_scope(enum man_type type, struct man *man, enum mant tok)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
@ -249,7 +257,7 @@ rew_scope(enum man_type type, struct man *man, enum mant tok)
|
|||||||
*/
|
*/
|
||||||
c = rew_dohalt(tok, type, n);
|
c = rew_dohalt(tok, type, n);
|
||||||
if (REW_HALT == c)
|
if (REW_HALT == c)
|
||||||
return(1);
|
return;
|
||||||
if (REW_REWIND == c)
|
if (REW_REWIND == c)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -258,16 +266,15 @@ rew_scope(enum man_type type, struct man *man, enum mant tok)
|
|||||||
* Rewind until the current point. Warn if we're a roff
|
* Rewind until the current point. Warn if we're a roff
|
||||||
* instruction that's mowing over explicit scopes.
|
* instruction that's mowing over explicit scopes.
|
||||||
*/
|
*/
|
||||||
assert(n);
|
|
||||||
|
|
||||||
return(man_unscope(man, n));
|
man_unscope(man, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close out a generic explicit macro.
|
* Close out a generic explicit macro.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
blk_close(MACRO_PROT_ARGS)
|
blk_close(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
enum mant ntok;
|
enum mant ntok;
|
||||||
@ -286,57 +293,46 @@ blk_close(MACRO_PROT_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (nn = man->last->parent; nn; nn = nn->parent)
|
for (nn = man->last->parent; nn; nn = nn->parent)
|
||||||
if (ntok == nn->tok && MAN_BLOCK == nn->type)
|
if (nn->tok == ntok && nn->type == MAN_BLOCK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (NULL == nn) {
|
if (nn == NULL) {
|
||||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse,
|
mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse,
|
||||||
line, ppos, man_macronames[tok]);
|
line, ppos, man_macronames[tok]);
|
||||||
if ( ! rew_scope(MAN_BLOCK, man, MAN_PP))
|
rew_scope(MAN_BLOCK, man, MAN_PP);
|
||||||
return(0);
|
|
||||||
} else
|
} else
|
||||||
man_unscope(man, nn);
|
man_unscope(man, nn);
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
blk_exp(MACRO_PROT_ARGS)
|
blk_exp(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
int la;
|
int la;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
/* Close out prior implicit scopes. */
|
rew_scope(MAN_BLOCK, man, tok);
|
||||||
|
man_block_alloc(man, line, ppos, tok);
|
||||||
if ( ! rew_scope(MAN_BLOCK, man, tok))
|
man_head_alloc(man, line, ppos, tok);
|
||||||
return(0);
|
|
||||||
|
|
||||||
if ( ! man_block_alloc(man, line, ppos, tok))
|
|
||||||
return(0);
|
|
||||||
if ( ! man_head_alloc(man, line, ppos, tok))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
la = *pos;
|
la = *pos;
|
||||||
if ( ! man_args(man, line, pos, buf, &p))
|
if ( ! man_args(man, line, pos, buf, &p))
|
||||||
break;
|
break;
|
||||||
if ( ! man_word_alloc(man, line, la, p))
|
man_word_alloc(man, line, la, p);
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(man);
|
assert(man);
|
||||||
assert(tok != MAN_MAX);
|
assert(tok != MAN_MAX);
|
||||||
|
|
||||||
for (n = man->last; n; n = n->parent) {
|
for (n = man->last; n; n = n->parent)
|
||||||
if (n->tok != tok)
|
if (n->tok == tok) {
|
||||||
continue;
|
assert(n->type == MAN_HEAD);
|
||||||
assert(MAN_HEAD == n->type);
|
man_unscope(man, n);
|
||||||
man_unscope(man, n);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return(man_body_alloc(man, line, ppos, tok));
|
man_body_alloc(man, line, ppos, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -345,27 +341,17 @@ blk_exp(MACRO_PROT_ARGS)
|
|||||||
* scopes, such as `SH' closing out an `SS', are defined in the rew
|
* scopes, such as `SH' closing out an `SS', are defined in the rew
|
||||||
* routines.
|
* routines.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
blk_imp(MACRO_PROT_ARGS)
|
blk_imp(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
int la;
|
int la;
|
||||||
char *p;
|
char *p;
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
/* Close out prior scopes. */
|
rew_scope(MAN_BODY, man, tok);
|
||||||
|
rew_scope(MAN_BLOCK, man, tok);
|
||||||
if ( ! rew_scope(MAN_BODY, man, tok))
|
man_block_alloc(man, line, ppos, tok);
|
||||||
return(0);
|
man_head_alloc(man, line, ppos, tok);
|
||||||
if ( ! rew_scope(MAN_BLOCK, man, tok))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* Allocate new block & head scope. */
|
|
||||||
|
|
||||||
if ( ! man_block_alloc(man, line, ppos, tok))
|
|
||||||
return(0);
|
|
||||||
if ( ! man_head_alloc(man, line, ppos, tok))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
n = man->last;
|
n = man->last;
|
||||||
|
|
||||||
/* Add line arguments. */
|
/* Add line arguments. */
|
||||||
@ -374,46 +360,44 @@ blk_imp(MACRO_PROT_ARGS)
|
|||||||
la = *pos;
|
la = *pos;
|
||||||
if ( ! man_args(man, line, pos, buf, &p))
|
if ( ! man_args(man, line, pos, buf, &p))
|
||||||
break;
|
break;
|
||||||
if ( ! man_word_alloc(man, line, la, p))
|
man_word_alloc(man, line, la, p);
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close out head and open body (unless MAN_SCOPE). */
|
/* Close out head and open body (unless MAN_SCOPE). */
|
||||||
|
|
||||||
if (MAN_SCOPED & man_macros[tok].flags) {
|
if (man_macros[tok].flags & MAN_SCOPED) {
|
||||||
/* If we're forcing scope (`TP'), keep it open. */
|
/* If we're forcing scope (`TP'), keep it open. */
|
||||||
if (MAN_FSCOPED & man_macros[tok].flags) {
|
if (man_macros[tok].flags & MAN_FSCOPED) {
|
||||||
man->flags |= MAN_BLINE;
|
man->flags |= MAN_BLINE;
|
||||||
return(1);
|
return;
|
||||||
} else if (n == man->last) {
|
} else if (n == man->last) {
|
||||||
man->flags |= MAN_BLINE;
|
man->flags |= MAN_BLINE;
|
||||||
return(1);
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rew_scope(MAN_HEAD, man, tok);
|
||||||
if ( ! rew_scope(MAN_HEAD, man, tok))
|
man_body_alloc(man, line, ppos, tok);
|
||||||
return(0);
|
|
||||||
return(man_body_alloc(man, line, ppos, tok));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
in_line_eoln(MACRO_PROT_ARGS)
|
in_line_eoln(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
int la;
|
int la;
|
||||||
char *p;
|
char *p;
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
if ( ! man_elem_alloc(man, line, ppos, tok))
|
man_elem_alloc(man, line, ppos, tok);
|
||||||
return(0);
|
|
||||||
|
|
||||||
n = man->last;
|
n = man->last;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
la = *pos;
|
la = *pos;
|
||||||
if ( ! man_args(man, line, pos, buf, &p))
|
if ( ! man_args(man, line, pos, buf, &p))
|
||||||
break;
|
break;
|
||||||
if ( ! man_word_alloc(man, line, la, p))
|
if (man_macros[tok].flags & MAN_JOIN &&
|
||||||
return(0);
|
man->last->type == MAN_TEXT)
|
||||||
|
man_word_append(man, p);
|
||||||
|
else
|
||||||
|
man_word_alloc(man, line, la, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -431,13 +415,13 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||||||
* waiting for terms to load into our context.
|
* waiting for terms to load into our context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (n == man->last && MAN_SCOPED & man_macros[tok].flags) {
|
if (n == man->last && man_macros[tok].flags & MAN_SCOPED) {
|
||||||
assert( ! (MAN_NSCOPED & man_macros[tok].flags));
|
assert( ! (man_macros[tok].flags & MAN_NSCOPED));
|
||||||
man->flags |= MAN_ELINE;
|
man->flags |= MAN_ELINE;
|
||||||
return(1);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(MAN_ROOT != man->last->type);
|
assert(man->last->type != MAN_ROOT);
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -451,8 +435,7 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||||||
break;
|
break;
|
||||||
if (man->last->type == MAN_ROOT)
|
if (man->last->type == MAN_ROOT)
|
||||||
break;
|
break;
|
||||||
if ( ! man_valid_post(man))
|
man_valid_post(man);
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(man->last);
|
assert(man->last);
|
||||||
@ -461,18 +444,16 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||||||
* Same here regarding whether we're back at the root.
|
* Same here regarding whether we're back at the root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (man->last->type != MAN_ROOT && ! man_valid_post(man))
|
if (man->last->type != MAN_ROOT)
|
||||||
return(0);
|
man_valid_post(man);
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
man_macroend(struct man *man)
|
man_macroend(struct man *man)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(man_unscope(man, man->first));
|
man_unscope(man, man->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
77
man_term.c
77
man_term.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man_term.c,v 1.149 2014/06/20 23:02:31 schwarze Exp $ */
|
/* $Id: man_term.c,v 1.156 2014/11/21 01:52:53 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -143,38 +141,47 @@ void
|
|||||||
terminal_man(void *arg, const struct man *man)
|
terminal_man(void *arg, const struct man *man)
|
||||||
{
|
{
|
||||||
struct termp *p;
|
struct termp *p;
|
||||||
const struct man_node *n;
|
|
||||||
const struct man_meta *meta;
|
const struct man_meta *meta;
|
||||||
|
struct man_node *n;
|
||||||
struct mtermp mt;
|
struct mtermp mt;
|
||||||
|
|
||||||
p = (struct termp *)arg;
|
p = (struct termp *)arg;
|
||||||
|
|
||||||
if (0 == p->defindent)
|
|
||||||
p->defindent = 7;
|
|
||||||
|
|
||||||
p->overstep = 0;
|
p->overstep = 0;
|
||||||
p->maxrmargin = p->defrmargin;
|
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||||
p->tabwidth = term_len(p, 5);
|
p->tabwidth = term_len(p, 5);
|
||||||
|
|
||||||
if (NULL == p->symtab)
|
n = man_node(man)->child;
|
||||||
p->symtab = mchars_alloc();
|
|
||||||
|
|
||||||
n = man_node(man);
|
|
||||||
meta = man_meta(man);
|
meta = man_meta(man);
|
||||||
|
|
||||||
term_begin(p, print_man_head, print_man_foot, meta);
|
|
||||||
p->flags |= TERMP_NOSPACE;
|
|
||||||
|
|
||||||
memset(&mt, 0, sizeof(struct mtermp));
|
memset(&mt, 0, sizeof(struct mtermp));
|
||||||
|
|
||||||
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
||||||
mt.offset = term_len(p, p->defindent);
|
mt.offset = term_len(p, p->defindent);
|
||||||
mt.pardist = 1;
|
mt.pardist = 1;
|
||||||
|
|
||||||
if (n->child)
|
if (p->synopsisonly) {
|
||||||
print_man_nodelist(p, &mt, n->child, meta);
|
while (n != NULL) {
|
||||||
|
if (n->tok == MAN_SH &&
|
||||||
term_end(p);
|
n->child->child->type == MAN_TEXT &&
|
||||||
|
!strcmp(n->child->child->string, "SYNOPSIS")) {
|
||||||
|
if (n->child->next->child != NULL)
|
||||||
|
print_man_nodelist(p, &mt,
|
||||||
|
n->child->next->child, meta);
|
||||||
|
term_newln(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n = n->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p->defindent == 0)
|
||||||
|
p->defindent = 7;
|
||||||
|
term_begin(p, print_man_head, print_man_foot, meta);
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
if (n != NULL)
|
||||||
|
print_man_nodelist(p, &mt, n, meta);
|
||||||
|
term_end(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -449,11 +456,6 @@ pre_in(DECL_ARGS)
|
|||||||
else
|
else
|
||||||
p->offset = v;
|
p->offset = v;
|
||||||
|
|
||||||
/* Don't let this creep beyond the right margin. */
|
|
||||||
|
|
||||||
if (p->offset > p->rmargin)
|
|
||||||
p->offset = p->rmargin;
|
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,8 +649,7 @@ pre_IP(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
case MAN_BODY:
|
case MAN_BODY:
|
||||||
p->offset = mt->offset + len;
|
p->offset = mt->offset + len;
|
||||||
p->rmargin = p->maxrmargin > p->offset ?
|
p->rmargin = p->maxrmargin;
|
||||||
p->maxrmargin : p->offset;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -739,8 +740,7 @@ pre_TP(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
case MAN_BODY:
|
case MAN_BODY:
|
||||||
p->offset = mt->offset + len;
|
p->offset = mt->offset + len;
|
||||||
p->rmargin = p->maxrmargin > p->offset ?
|
p->rmargin = p->maxrmargin;
|
||||||
p->maxrmargin : p->offset;
|
|
||||||
p->trailspace = 0;
|
p->trailspace = 0;
|
||||||
p->flags &= ~TERMP_NOBREAK;
|
p->flags &= ~TERMP_NOBREAK;
|
||||||
break;
|
break;
|
||||||
@ -891,8 +891,7 @@ pre_RS(DECL_ARGS)
|
|||||||
|
|
||||||
mt->offset += sz;
|
mt->offset += sz;
|
||||||
p->offset = mt->offset;
|
p->offset = mt->offset;
|
||||||
p->rmargin = p->maxrmargin > p->offset ?
|
p->rmargin = p->maxrmargin;
|
||||||
p->maxrmargin : p->offset;
|
|
||||||
|
|
||||||
if (++mt->lmarginsz < MAXMARGINS)
|
if (++mt->lmarginsz < MAXMARGINS)
|
||||||
mt->lmargincur = mt->lmarginsz;
|
mt->lmargincur = mt->lmarginsz;
|
||||||
@ -977,7 +976,11 @@ print_man_node(DECL_ARGS)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
case MAN_EQN:
|
case MAN_EQN:
|
||||||
|
if ( ! (n->flags & MAN_LINE))
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
term_eqn(p, n->eqn);
|
term_eqn(p, n->eqn);
|
||||||
|
if (n->next != NULL && ! (n->next->flags & MAN_LINE))
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
return;
|
return;
|
||||||
case MAN_TBL:
|
case MAN_TBL:
|
||||||
/*
|
/*
|
||||||
@ -1052,7 +1055,7 @@ print_man_foot(struct termp *p, const void *arg)
|
|||||||
{
|
{
|
||||||
const struct man_meta *meta;
|
const struct man_meta *meta;
|
||||||
char *title;
|
char *title;
|
||||||
size_t datelen;
|
size_t datelen, titlen;
|
||||||
|
|
||||||
meta = (const struct man_meta *)arg;
|
meta = (const struct man_meta *)arg;
|
||||||
assert(meta->title);
|
assert(meta->title);
|
||||||
@ -1089,7 +1092,8 @@ print_man_foot(struct termp *p, const void *arg)
|
|||||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||||
p->trailspace = 1;
|
p->trailspace = 1;
|
||||||
p->offset = 0;
|
p->offset = 0;
|
||||||
p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2;
|
p->rmargin = p->maxrmargin > datelen ?
|
||||||
|
(p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0;
|
||||||
|
|
||||||
if (meta->source)
|
if (meta->source)
|
||||||
term_word(p, meta->source);
|
term_word(p, meta->source);
|
||||||
@ -1097,11 +1101,10 @@ print_man_foot(struct termp *p, const void *arg)
|
|||||||
|
|
||||||
/* At the bottom in the middle: manual date. */
|
/* At the bottom in the middle: manual date. */
|
||||||
|
|
||||||
p->flags |= TERMP_NOSPACE;
|
|
||||||
p->offset = p->rmargin;
|
p->offset = p->rmargin;
|
||||||
p->rmargin = p->maxrmargin - term_strlen(p, title);
|
titlen = term_strlen(p, title);
|
||||||
if (p->offset + datelen >= p->rmargin)
|
p->rmargin = p->maxrmargin > titlen ? p->maxrmargin - titlen : 0;
|
||||||
p->rmargin = p->offset + datelen;
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
|
||||||
term_word(p, meta->date);
|
term_word(p, meta->date);
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
@ -1144,7 +1147,7 @@ print_man_head(struct termp *p, const void *arg)
|
|||||||
p->offset = 0;
|
p->offset = 0;
|
||||||
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||||
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
||||||
p->maxrmargin - vollen;
|
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
|
||||||
|
|
||||||
term_word(p, title);
|
term_word(p, title);
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
|
113
man_validate.c
113
man_validate.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man_validate.c,v 1.105 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $OpenBSD$ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -38,26 +36,26 @@
|
|||||||
|
|
||||||
#define CHKARGS struct man *man, struct man_node *n
|
#define CHKARGS struct man *man, struct man_node *n
|
||||||
|
|
||||||
typedef int (*v_check)(CHKARGS);
|
typedef void (*v_check)(CHKARGS);
|
||||||
|
|
||||||
static int check_eq0(CHKARGS);
|
static void check_eq0(CHKARGS);
|
||||||
static int check_eq2(CHKARGS);
|
static void check_eq2(CHKARGS);
|
||||||
static int check_le1(CHKARGS);
|
static void check_le1(CHKARGS);
|
||||||
static int check_le5(CHKARGS);
|
static void check_le5(CHKARGS);
|
||||||
static int check_par(CHKARGS);
|
static void check_par(CHKARGS);
|
||||||
static int check_part(CHKARGS);
|
static void check_part(CHKARGS);
|
||||||
static int check_root(CHKARGS);
|
static void check_root(CHKARGS);
|
||||||
static int check_text(CHKARGS);
|
static void check_text(CHKARGS);
|
||||||
|
|
||||||
static int post_AT(CHKARGS);
|
static void post_AT(CHKARGS);
|
||||||
static int post_IP(CHKARGS);
|
static void post_IP(CHKARGS);
|
||||||
static int post_vs(CHKARGS);
|
static void post_vs(CHKARGS);
|
||||||
static int post_fi(CHKARGS);
|
static void post_fi(CHKARGS);
|
||||||
static int post_ft(CHKARGS);
|
static void post_ft(CHKARGS);
|
||||||
static int post_nf(CHKARGS);
|
static void post_nf(CHKARGS);
|
||||||
static int post_TH(CHKARGS);
|
static void post_TH(CHKARGS);
|
||||||
static int post_UC(CHKARGS);
|
static void post_UC(CHKARGS);
|
||||||
static int post_UR(CHKARGS);
|
static void post_UR(CHKARGS);
|
||||||
|
|
||||||
static v_check man_valids[MAN_MAX] = {
|
static v_check man_valids[MAN_MAX] = {
|
||||||
post_vs, /* br */
|
post_vs, /* br */
|
||||||
@ -102,7 +100,7 @@ static v_check man_valids[MAN_MAX] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
man_valid_post(struct man *man)
|
man_valid_post(struct man *man)
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
@ -110,25 +108,29 @@ man_valid_post(struct man *man)
|
|||||||
|
|
||||||
n = man->last;
|
n = man->last;
|
||||||
if (n->flags & MAN_VALID)
|
if (n->flags & MAN_VALID)
|
||||||
return(1);
|
return;
|
||||||
n->flags |= MAN_VALID;
|
n->flags |= MAN_VALID;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case MAN_TEXT:
|
case MAN_TEXT:
|
||||||
return(check_text(man, n));
|
check_text(man, n);
|
||||||
|
break;
|
||||||
case MAN_ROOT:
|
case MAN_ROOT:
|
||||||
return(check_root(man, n));
|
check_root(man, n);
|
||||||
|
break;
|
||||||
case MAN_EQN:
|
case MAN_EQN:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MAN_TBL:
|
case MAN_TBL:
|
||||||
return(1);
|
break;
|
||||||
default:
|
default:
|
||||||
cp = man_valids + n->tok;
|
cp = man_valids + n->tok;
|
||||||
return(*cp ? (*cp)(man, n) : 1);
|
if (*cp)
|
||||||
|
(*cp)(man, n);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
check_root(CHKARGS)
|
check_root(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -154,35 +156,31 @@ check_root(CHKARGS)
|
|||||||
man->meta.date = man->quick ? mandoc_strdup("") :
|
man->meta.date = man->quick ? mandoc_strdup("") :
|
||||||
mandoc_normdate(man->parse, NULL, n->line, n->pos);
|
mandoc_normdate(man->parse, NULL, n->line, n->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
check_text(CHKARGS)
|
check_text(CHKARGS)
|
||||||
{
|
{
|
||||||
char *cp, *p;
|
char *cp, *p;
|
||||||
|
|
||||||
if (MAN_LITERAL & man->flags)
|
if (MAN_LITERAL & man->flags)
|
||||||
return(1);
|
return;
|
||||||
|
|
||||||
cp = n->string;
|
cp = n->string;
|
||||||
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
||||||
mandoc_msg(MANDOCERR_FI_TAB, man->parse,
|
mandoc_msg(MANDOCERR_FI_TAB, man->parse,
|
||||||
n->line, n->pos + (p - cp), NULL);
|
n->line, n->pos + (p - cp), NULL);
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INEQ_DEFINE(x, ineq, name) \
|
#define INEQ_DEFINE(x, ineq, name) \
|
||||||
static int \
|
static void \
|
||||||
check_##name(CHKARGS) \
|
check_##name(CHKARGS) \
|
||||||
{ \
|
{ \
|
||||||
if (n->nchild ineq (x)) \
|
if (n->nchild ineq (x)) \
|
||||||
return(1); \
|
return; \
|
||||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \
|
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \
|
||||||
"line arguments %s %d (have %d)", \
|
"line arguments %s %d (have %d)", \
|
||||||
#ineq, (x), n->nchild); \
|
#ineq, (x), n->nchild); \
|
||||||
return(1); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INEQ_DEFINE(0, ==, eq0)
|
INEQ_DEFINE(0, ==, eq0)
|
||||||
@ -190,25 +188,24 @@ INEQ_DEFINE(2, ==, eq2)
|
|||||||
INEQ_DEFINE(1, <=, le1)
|
INEQ_DEFINE(1, <=, le1)
|
||||||
INEQ_DEFINE(5, <=, le5)
|
INEQ_DEFINE(5, <=, le5)
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_UR(CHKARGS)
|
post_UR(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MAN_HEAD == n->type && 1 != n->nchild)
|
if (MAN_HEAD == n->type && 1 != n->nchild)
|
||||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
||||||
n->pos, "line arguments eq 1 (have %d)", n->nchild);
|
n->pos, "line arguments eq 1 (have %d)", n->nchild);
|
||||||
|
check_part(man, n);
|
||||||
return(check_part(man, n));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_ft(CHKARGS)
|
post_ft(CHKARGS)
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
if (0 == n->nchild)
|
if (0 == n->nchild)
|
||||||
return(1);
|
return;
|
||||||
|
|
||||||
ok = 0;
|
ok = 0;
|
||||||
cp = n->child->string;
|
cp = n->child->string;
|
||||||
@ -250,22 +247,18 @@ post_ft(CHKARGS)
|
|||||||
if (1 < n->nchild)
|
if (1 < n->nchild)
|
||||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
||||||
n->pos, "want one child (have %d)", n->nchild);
|
n->pos, "want one child (have %d)", n->nchild);
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
check_part(CHKARGS)
|
check_part(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MAN_BODY == n->type && 0 == n->nchild)
|
if (MAN_BODY == n->type && 0 == n->nchild)
|
||||||
mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line,
|
mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line,
|
||||||
n->pos, "want children (have none)");
|
n->pos, "want children (have none)");
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
check_par(CHKARGS)
|
check_par(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -291,11 +284,9 @@ check_par(CHKARGS)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_IP(CHKARGS)
|
post_IP(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -313,10 +304,9 @@ post_IP(CHKARGS)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_TH(CHKARGS)
|
post_TH(CHKARGS)
|
||||||
{
|
{
|
||||||
struct man_node *nb;
|
struct man_node *nb;
|
||||||
@ -404,10 +394,9 @@ post_TH(CHKARGS)
|
|||||||
* meta-data.
|
* meta-data.
|
||||||
*/
|
*/
|
||||||
man_node_delete(man, man->last);
|
man_node_delete(man, man->last);
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_nf(CHKARGS)
|
post_nf(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -418,10 +407,9 @@ post_nf(CHKARGS)
|
|||||||
n->line, n->pos, "nf");
|
n->line, n->pos, "nf");
|
||||||
|
|
||||||
man->flags |= MAN_LITERAL;
|
man->flags |= MAN_LITERAL;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_fi(CHKARGS)
|
post_fi(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -432,10 +420,9 @@ post_fi(CHKARGS)
|
|||||||
n->line, n->pos, "fi");
|
n->line, n->pos, "fi");
|
||||||
|
|
||||||
man->flags &= ~MAN_LITERAL;
|
man->flags &= ~MAN_LITERAL;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_UC(CHKARGS)
|
post_UC(CHKARGS)
|
||||||
{
|
{
|
||||||
static const char * const bsd_versions[] = {
|
static const char * const bsd_versions[] = {
|
||||||
@ -470,10 +457,9 @@ post_UC(CHKARGS)
|
|||||||
|
|
||||||
free(man->meta.source);
|
free(man->meta.source);
|
||||||
man->meta.source = mandoc_strdup(p);
|
man->meta.source = mandoc_strdup(p);
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_AT(CHKARGS)
|
post_AT(CHKARGS)
|
||||||
{
|
{
|
||||||
static const char * const unix_versions[] = {
|
static const char * const unix_versions[] = {
|
||||||
@ -508,10 +494,9 @@ post_AT(CHKARGS)
|
|||||||
|
|
||||||
free(man->meta.source);
|
free(man->meta.source);
|
||||||
man->meta.source = mandoc_strdup(p);
|
man->meta.source = mandoc_strdup(p);
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
post_vs(CHKARGS)
|
post_vs(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -521,7 +506,7 @@ post_vs(CHKARGS)
|
|||||||
check_le1(man, n);
|
check_le1(man, n);
|
||||||
|
|
||||||
if (NULL != n->prev)
|
if (NULL != n->prev)
|
||||||
return(1);
|
return;
|
||||||
|
|
||||||
switch (n->parent->tok) {
|
switch (n->parent->tok) {
|
||||||
case MAN_SH:
|
case MAN_SH:
|
||||||
@ -541,6 +526,4 @@ post_vs(CHKARGS)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
254
mandoc.1
254
mandoc.1
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mandoc.1,v 1.106 2014/08/08 01:50:59 schwarze Exp $
|
.\" $Id: mandoc.1,v 1.125 2014/11/28 18:09:01 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
.\" Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 8 2014 $
|
.Dd $Mdocdate: November 28 2014 $
|
||||||
.Dt MANDOC 1
|
.Dt MANDOC 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -23,10 +23,11 @@
|
|||||||
.Nd format and display UNIX manuals
|
.Nd format and display UNIX manuals
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm mandoc
|
.Nm mandoc
|
||||||
.Op Fl V
|
.Op Fl acfhklV
|
||||||
.Sm off
|
.Sm off
|
||||||
.Op Fl I Cm os Li = Ar name
|
.Op Fl I Cm os Li = Ar name
|
||||||
.Sm on
|
.Sm on
|
||||||
|
.Op Fl K Ns Ar encoding
|
||||||
.Op Fl m Ns Ar format
|
.Op Fl m Ns Ar format
|
||||||
.Op Fl O Ns Ar option
|
.Op Fl O Ns Ar option
|
||||||
.Op Fl T Ns Ar output
|
.Op Fl T Ns Ar output
|
||||||
@ -51,8 +52,31 @@ and produces
|
|||||||
.Fl T Ns Cm ascii
|
.Fl T Ns Cm ascii
|
||||||
output.
|
output.
|
||||||
.Pp
|
.Pp
|
||||||
The arguments are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl a
|
||||||
|
If the standard output is a terminal device and
|
||||||
|
.Fl c
|
||||||
|
is not specified, use
|
||||||
|
.Xr more 1
|
||||||
|
to paginate the output, just like
|
||||||
|
.Xr man 1
|
||||||
|
would.
|
||||||
|
.It Fl c
|
||||||
|
Copy the formatted manual pages to the standard output without using
|
||||||
|
.Xr more 1
|
||||||
|
to paginate them.
|
||||||
|
This is the default.
|
||||||
|
It can be specified to override
|
||||||
|
.Fl a .
|
||||||
|
.It Fl f
|
||||||
|
A synonym for
|
||||||
|
.Xr whatis 1 .
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl k
|
||||||
|
and
|
||||||
|
.Fl l
|
||||||
|
options.
|
||||||
.Sm off
|
.Sm off
|
||||||
.It Fl I Cm os Li = Ar name
|
.It Fl I Cm os Li = Ar name
|
||||||
.Sm on
|
.Sm on
|
||||||
@ -62,6 +86,51 @@ for the
|
|||||||
.Xr mdoc 7
|
.Xr mdoc 7
|
||||||
.Sq \&Os
|
.Sq \&Os
|
||||||
macro.
|
macro.
|
||||||
|
.It Fl h
|
||||||
|
Display only the SYNOPSIS lines.
|
||||||
|
Implies
|
||||||
|
.Fl c .
|
||||||
|
.It Fl K Ns Ar encoding
|
||||||
|
Specify the input encoding.
|
||||||
|
The supported
|
||||||
|
.Ar encoding
|
||||||
|
arguments are
|
||||||
|
.Cm us-ascii ,
|
||||||
|
.Cm iso-8859-1 ,
|
||||||
|
and
|
||||||
|
.Cm utf-8 .
|
||||||
|
If not specified, autodetection uses the first match:
|
||||||
|
.Bl -tag -width iso-8859-1
|
||||||
|
.It Cm utf-8
|
||||||
|
if the first three bytes of the input file
|
||||||
|
are the UTF-8 byte order mark (BOM, 0xefbbbf)
|
||||||
|
.It Ar encoding
|
||||||
|
if the first or second line of the input file matches the
|
||||||
|
.Sy emacs
|
||||||
|
mode line format
|
||||||
|
.Pp
|
||||||
|
.D1 .\e" -*- Oo ...; Oc coding: Ar encoding ; No -*-
|
||||||
|
.It Cm utf-8
|
||||||
|
if the first non-ASCII byte in the file introduces a valid UTF-8 sequence
|
||||||
|
.It Cm iso-8859-1
|
||||||
|
otherwise
|
||||||
|
.El
|
||||||
|
.It Fl k
|
||||||
|
A synonym for
|
||||||
|
.Xr apropos 1 .
|
||||||
|
This overrides any earlier
|
||||||
|
.Fl f
|
||||||
|
and
|
||||||
|
.Fl l
|
||||||
|
options.
|
||||||
|
.It Fl l
|
||||||
|
A synonym for
|
||||||
|
.Fl a .
|
||||||
|
Also reverts any earlier
|
||||||
|
.Fl f
|
||||||
|
and
|
||||||
|
.Fl k
|
||||||
|
options.
|
||||||
.It Fl m Ns Ar format
|
.It Fl m Ns Ar format
|
||||||
Input format.
|
Input format.
|
||||||
See
|
See
|
||||||
@ -122,6 +191,18 @@ If multiple files are specified,
|
|||||||
.Nm
|
.Nm
|
||||||
will halt with the first failed parse.
|
will halt with the first failed parse.
|
||||||
.El
|
.El
|
||||||
|
.Pp
|
||||||
|
In
|
||||||
|
.Fl f
|
||||||
|
and
|
||||||
|
.Fl k
|
||||||
|
mode,
|
||||||
|
.Nm
|
||||||
|
also supports the options
|
||||||
|
.Fl CMmOSsw
|
||||||
|
described in the
|
||||||
|
.Xr apropos 1
|
||||||
|
manual.
|
||||||
.Ss Input Formats
|
.Ss Input Formats
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
@ -178,7 +259,7 @@ This is the default.
|
|||||||
See
|
See
|
||||||
.Sx ASCII Output .
|
.Sx ASCII Output .
|
||||||
.It Fl T Ns Cm html
|
.It Fl T Ns Cm html
|
||||||
Produce strict CSS1/HTML-4.01 output.
|
Produce HTML5, CSS1, and MathML output.
|
||||||
See
|
See
|
||||||
.Sx HTML Output .
|
.Sx HTML Output .
|
||||||
.It Fl T Ns Cm lint
|
.It Fl T Ns Cm lint
|
||||||
@ -210,9 +291,8 @@ Encode output in the UTF\-8 multi-byte format.
|
|||||||
See
|
See
|
||||||
.Sx UTF\-8 Output .
|
.Sx UTF\-8 Output .
|
||||||
.It Fl T Ns Cm xhtml
|
.It Fl T Ns Cm xhtml
|
||||||
Produce strict CSS1/XHTML-1.0 output.
|
This is a synonym for
|
||||||
See
|
.Fl T Ns Cm html .
|
||||||
.Sx XHTML Output .
|
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
If multiple input files are specified, these will be processed by the
|
If multiple input files are specified, these will be processed by the
|
||||||
@ -265,7 +345,11 @@ which will normalise to \(>=60.
|
|||||||
.Ss HTML Output
|
.Ss HTML Output
|
||||||
Output produced by
|
Output produced by
|
||||||
.Fl T Ns Cm html
|
.Fl T Ns Cm html
|
||||||
conforms to HTML-4.01 strict.
|
conforms to HTML5 using optional self-closing tags.
|
||||||
|
Default styles use only CSS1.
|
||||||
|
Equations rendered from
|
||||||
|
.Xr eqn 7
|
||||||
|
blocks use MathML.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Pa example.style.css
|
.Pa example.style.css
|
||||||
@ -273,7 +357,8 @@ file documents style-sheet classes available for customising output.
|
|||||||
If a style-sheet is not specified with
|
If a style-sheet is not specified with
|
||||||
.Fl O Ns Ar style ,
|
.Fl O Ns Ar style ,
|
||||||
.Fl T Ns Cm html
|
.Fl T Ns Cm html
|
||||||
defaults to simple output readable in any graphical or text-based web
|
defaults to simple output (via an embedded style-sheet)
|
||||||
|
readable in any graphical or text-based web
|
||||||
browser.
|
browser.
|
||||||
.Pp
|
.Pp
|
||||||
Special characters are rendered in decimal-encoded UTF\-8.
|
Special characters are rendered in decimal-encoded UTF\-8.
|
||||||
@ -283,16 +368,8 @@ The following
|
|||||||
arguments are accepted:
|
arguments are accepted:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Cm fragment
|
.It Cm fragment
|
||||||
Omit the
|
Omit the <!DOCTYPE> declaration and the <html>, <head>, and <body>
|
||||||
.Aq !DOCTYPE
|
elements and only emit the subtree below the <body> element.
|
||||||
declaration and the
|
|
||||||
.Aq html ,
|
|
||||||
.Aq head ,
|
|
||||||
and
|
|
||||||
.Aq body
|
|
||||||
elements and only emit the subtree below the
|
|
||||||
.Aq body
|
|
||||||
element.
|
|
||||||
The
|
The
|
||||||
.Cm style
|
.Cm style
|
||||||
argument will be ignored.
|
argument will be ignored.
|
||||||
@ -416,15 +493,21 @@ to force a UTF\-8 locale.
|
|||||||
See
|
See
|
||||||
.Sx Locale Output
|
.Sx Locale Output
|
||||||
for details and options.
|
for details and options.
|
||||||
.Ss XHTML Output
|
.Sh ENVIRONMENT
|
||||||
Output produced by
|
.Bl -tag -width MANPAGER
|
||||||
.Fl T Ns Cm xhtml
|
.It Ev MANPAGER
|
||||||
conforms to XHTML-1.0 strict.
|
Any non-empty value of the environment variable
|
||||||
.Pp
|
.Ev MANPAGER
|
||||||
See
|
will be used instead of the standard pagination program,
|
||||||
.Sx HTML Output
|
.Xr more 1 .
|
||||||
for details; beyond generating XHTML tags instead of HTML tags, these
|
.It Ev PAGER
|
||||||
output modes are identical.
|
Specifies the pagination program to use when
|
||||||
|
.Ev MANPAGER
|
||||||
|
is not defined.
|
||||||
|
If neither PAGER nor MANPAGER is defined,
|
||||||
|
.Pa /usr/bin/more Fl s
|
||||||
|
will be used.
|
||||||
|
.El
|
||||||
.Sh EXIT STATUS
|
.Sh EXIT STATUS
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
@ -582,12 +665,6 @@ macro lacks the mandatory section argument.
|
|||||||
The section number in a
|
The section number in a
|
||||||
.Ic \&Dt
|
.Ic \&Dt
|
||||||
line is invalid, but still used.
|
line is invalid, but still used.
|
||||||
.It Sy "unknown manual volume or arch"
|
|
||||||
.Pq mdoc
|
|
||||||
The volume name in a
|
|
||||||
.Ic \&Dt
|
|
||||||
line is invalid, but still used.
|
|
||||||
The manual is assumed to be architecture-independent.
|
|
||||||
.It Sy "missing date, using today's date"
|
.It Sy "missing date, using today's date"
|
||||||
.Pq mdoc, man
|
.Pq mdoc, man
|
||||||
The document was parsed as
|
The document was parsed as
|
||||||
@ -696,6 +773,28 @@ The same standard section title occurs more than once.
|
|||||||
.Pq mdoc
|
.Pq mdoc
|
||||||
A standard section header occurs in a section of the manual
|
A standard section header occurs in a section of the manual
|
||||||
where it normally isn't useful.
|
where it normally isn't useful.
|
||||||
|
.It Sy "unusual Xr order"
|
||||||
|
.Pq mdoc
|
||||||
|
In the SEE ALSO section, an
|
||||||
|
.Ic \&Xr
|
||||||
|
macro with a lower section number follows one with a higher number,
|
||||||
|
or two
|
||||||
|
.Ic \&Xr
|
||||||
|
macros refering to the same section are out of alphabetical order.
|
||||||
|
.It Sy "unusual Xr punctuation"
|
||||||
|
.Pq mdoc
|
||||||
|
In the SEE ALSO section, punctuation between two
|
||||||
|
.Ic \&Xr
|
||||||
|
macros differs from a single comma, or there is trailing punctuation
|
||||||
|
after the last
|
||||||
|
.Ic \&Xr
|
||||||
|
macro.
|
||||||
|
.It Sy "AUTHORS section without An macro"
|
||||||
|
.Pq mdoc
|
||||||
|
An AUTHORS sections contains no
|
||||||
|
.Ic \&An
|
||||||
|
macros, or only empty ones.
|
||||||
|
Probably, there are author names lacking markup.
|
||||||
.El
|
.El
|
||||||
.Ss "Warnings related to macros and nesting"
|
.Ss "Warnings related to macros and nesting"
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
@ -824,8 +923,11 @@ The previous, interrupted macro is deleted from the parse tree.
|
|||||||
.Ss "Warnings related to missing arguments"
|
.Ss "Warnings related to missing arguments"
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
.It Sy "skipping empty request"
|
.It Sy "skipping empty request"
|
||||||
.Pq roff
|
.Pq roff , eqn
|
||||||
The macro name is missing from a macro definition request.
|
The macro name is missing from a macro definition request,
|
||||||
|
or an
|
||||||
|
.Xr eqn 7
|
||||||
|
control statement or operation keyword lacks its required argument.
|
||||||
.It Sy "conditional request controls empty scope"
|
.It Sy "conditional request controls empty scope"
|
||||||
.Pq roff
|
.Pq roff
|
||||||
A conditional request is only useful if any of the following
|
A conditional request is only useful if any of the following
|
||||||
@ -959,6 +1061,11 @@ The
|
|||||||
utility assumes
|
utility assumes
|
||||||
.Fl std
|
.Fl std
|
||||||
even when it is not specified, but other implementations may not.
|
even when it is not specified, but other implementations may not.
|
||||||
|
.It Sy "missing eqn box, using \(dq\(dq"
|
||||||
|
.Pq eqn
|
||||||
|
A diacritic mark or a binary operator is found,
|
||||||
|
but there is nothing to the left of it.
|
||||||
|
An empty box is inserted.
|
||||||
.El
|
.El
|
||||||
.Ss "Warnings related to bad macro arguments"
|
.Ss "Warnings related to bad macro arguments"
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
@ -1026,6 +1133,21 @@ macro has an invalid argument.
|
|||||||
It is used verbatim, with
|
It is used verbatim, with
|
||||||
.Qq "AT&T UNIX "
|
.Qq "AT&T UNIX "
|
||||||
prefixed to it.
|
prefixed to it.
|
||||||
|
.It Sy "comma in function argument"
|
||||||
|
.Pq mdoc
|
||||||
|
An argument of an
|
||||||
|
.Ic \&Fa
|
||||||
|
or
|
||||||
|
.Ic \&Fn
|
||||||
|
macro contains a comma; it should probably be split into two arguments.
|
||||||
|
.It Sy "parenthesis in function name"
|
||||||
|
.Pq mdoc
|
||||||
|
The first argument of an
|
||||||
|
.Ic \&Fc
|
||||||
|
or
|
||||||
|
.Ic \&Fn
|
||||||
|
macro contains an opening or closing parenthesis; that's probably wrong,
|
||||||
|
parentheses are added automatically.
|
||||||
.It Sy "invalid content in Rs block"
|
.It Sy "invalid content in Rs block"
|
||||||
.Pq mdoc
|
.Pq mdoc
|
||||||
An
|
An
|
||||||
@ -1044,11 +1166,16 @@ or
|
|||||||
The invalid argument is moved out of the macro, which leaves the macro
|
The invalid argument is moved out of the macro, which leaves the macro
|
||||||
empty, causing it to toggle the spacing mode.
|
empty, causing it to toggle the spacing mode.
|
||||||
.It Sy "unknown font, skipping request"
|
.It Sy "unknown font, skipping request"
|
||||||
.Pq man
|
.Pq man , tbl
|
||||||
A
|
A
|
||||||
.Xr roff 7
|
.Xr roff 7
|
||||||
.Ic \&ft
|
.Ic \&ft
|
||||||
request has an invalid argument.
|
request or a
|
||||||
|
.Xr tbl 7
|
||||||
|
.Ic \&f
|
||||||
|
layout modifier has an unknown
|
||||||
|
.Ar font
|
||||||
|
argument.
|
||||||
.El
|
.El
|
||||||
.Ss "Warnings related to plain text"
|
.Ss "Warnings related to plain text"
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
@ -1111,7 +1238,6 @@ keeps the code more readable.
|
|||||||
.It "equation scope open on exit"
|
.It "equation scope open on exit"
|
||||||
.It "overlapping equation scopes"
|
.It "overlapping equation scopes"
|
||||||
.It "unexpected end of equation"
|
.It "unexpected end of equation"
|
||||||
.It "equation syntax error"
|
|
||||||
.El
|
.El
|
||||||
.Ss "Errors related to tables"
|
.Ss "Errors related to tables"
|
||||||
.Bl -inset -compact
|
.Bl -inset -compact
|
||||||
@ -1165,12 +1291,15 @@ macro.
|
|||||||
It may be mistyped or unsupported.
|
It may be mistyped or unsupported.
|
||||||
The request or macro is discarded including its arguments.
|
The request or macro is discarded including its arguments.
|
||||||
.It Sy "skipping item outside list"
|
.It Sy "skipping item outside list"
|
||||||
.Pq mdoc
|
.Pq mdoc , eqn
|
||||||
An
|
An
|
||||||
.Ic \&It
|
.Ic \&It
|
||||||
macro occurs outside any
|
macro occurs outside any
|
||||||
.Ic \&Bl
|
.Ic \&Bl
|
||||||
list.
|
list, or an
|
||||||
|
.Xr eqn 7
|
||||||
|
.Ic above
|
||||||
|
delimiter occurs outside any pile.
|
||||||
It is discarded including its arguments.
|
It is discarded including its arguments.
|
||||||
.It Sy "skipping column outside column list"
|
.It Sy "skipping column outside column list"
|
||||||
.Pq mdoc
|
.Pq mdoc
|
||||||
@ -1191,7 +1320,9 @@ block closing macro, a
|
|||||||
.Ic \&RE
|
.Ic \&RE
|
||||||
or
|
or
|
||||||
.Ic \&UE
|
.Ic \&UE
|
||||||
macro, or the end of an equation, table, or
|
macro, an
|
||||||
|
.Xr eqn 7
|
||||||
|
right delimiter or closing brace, or the end of an equation, table, or
|
||||||
.Xr roff 7
|
.Xr roff 7
|
||||||
conditional request is encountered but no matching block is open.
|
conditional request is encountered but no matching block is open.
|
||||||
The offending request or macro is discarded.
|
The offending request or macro is discarded.
|
||||||
@ -1259,6 +1390,17 @@ The indicated request or macro has too few or too many arguments.
|
|||||||
The syntax tree will contain the wrong number of arguments as given.
|
The syntax tree will contain the wrong number of arguments as given.
|
||||||
Formatting behaviour depends on the specific request or macro in question.
|
Formatting behaviour depends on the specific request or macro in question.
|
||||||
Note that the same message may also occur as a WARNING, see above.
|
Note that the same message may also occur as a WARNING, see above.
|
||||||
|
.It Sy "NOT IMPLEMENTED: Bd -file"
|
||||||
|
.Pq mdoc
|
||||||
|
For security reasons, the
|
||||||
|
.Ic \&Bd
|
||||||
|
macro does not support the
|
||||||
|
.Fl file
|
||||||
|
argument.
|
||||||
|
By requesting the inclusion of a sensitive file, a malicious document
|
||||||
|
might otherwise trick a privileged user into inadvertently displaying
|
||||||
|
the file on the screen, revealing the file content to bystanders.
|
||||||
|
The argument is ignored including the file name following it.
|
||||||
.It Sy "missing list type, using -item"
|
.It Sy "missing list type, using -item"
|
||||||
.Pq mdoc
|
.Pq mdoc
|
||||||
A
|
A
|
||||||
@ -1288,11 +1430,16 @@ An
|
|||||||
.Ic \&St
|
.Ic \&St
|
||||||
macro has an unknown argument and is discarded.
|
macro has an unknown argument and is discarded.
|
||||||
.It Sy "skipping request without numeric argument"
|
.It Sy "skipping request without numeric argument"
|
||||||
.Pq roff
|
.Pq roff , eqn
|
||||||
An
|
An
|
||||||
.Ic \&it
|
.Ic \&it
|
||||||
request has a non-numeric or negative argument or no argument at all.
|
request or an
|
||||||
The invalid request is ignored.
|
.Xr eqn 7
|
||||||
|
.Ic \&size
|
||||||
|
or
|
||||||
|
.Ic \&gsize
|
||||||
|
statement has a non-numeric or negative argument or no argument at all.
|
||||||
|
The invalid request or statement is ignored.
|
||||||
.It Sy "skipping all arguments"
|
.It Sy "skipping all arguments"
|
||||||
.Pq mdoc , man , eqn , roff
|
.Pq mdoc , man , eqn , roff
|
||||||
An
|
An
|
||||||
@ -1315,6 +1462,8 @@ or
|
|||||||
.Ic \&PP
|
.Ic \&PP
|
||||||
macro, an
|
macro, an
|
||||||
.Xr eqn 7
|
.Xr eqn 7
|
||||||
|
.Ic \&EQ
|
||||||
|
or
|
||||||
.Ic \&EN
|
.Ic \&EN
|
||||||
macro, or a
|
macro, or a
|
||||||
.Xr roff 7
|
.Xr roff 7
|
||||||
@ -1340,17 +1489,6 @@ cannot handle input files larger than its arbitrary size limit
|
|||||||
of 2^31 bytes (2 Gigabytes).
|
of 2^31 bytes (2 Gigabytes).
|
||||||
Since useful manuals are always small, this is not a problem in practice.
|
Since useful manuals are always small, this is not a problem in practice.
|
||||||
Parsing is aborted as soon as the condition is detected.
|
Parsing is aborted as soon as the condition is detected.
|
||||||
.It Sy "NOT IMPLEMENTED: Bd -file"
|
|
||||||
.Pq mdoc
|
|
||||||
For security reasons, the
|
|
||||||
.Ic \&Bd
|
|
||||||
macro does not support the
|
|
||||||
.Fl file
|
|
||||||
argument.
|
|
||||||
By requesting the inclusion of a sensitive file, a malicious document
|
|
||||||
might otherwise trick a privileged user into inadvertently displaying
|
|
||||||
the file on the screen, revealing the file content to bystanders.
|
|
||||||
The parser exits immediately.
|
|
||||||
.It Sy "NOT IMPLEMENTED: .so with absolute path or \(dq..\(dq"
|
.It Sy "NOT IMPLEMENTED: .so with absolute path or \(dq..\(dq"
|
||||||
.Pq roff
|
.Pq roff
|
||||||
For security reasons,
|
For security reasons,
|
||||||
@ -1430,7 +1568,7 @@ has no effect.
|
|||||||
.It
|
.It
|
||||||
Words aren't hyphenated.
|
Words aren't hyphenated.
|
||||||
.El
|
.El
|
||||||
.Ss HTML/XHTML Compatibility
|
.Ss HTML Compatibility
|
||||||
.Bl -bullet -compact
|
.Bl -bullet -compact
|
||||||
.It
|
.It
|
||||||
The
|
The
|
||||||
|
89
mandoc.3
89
mandoc.3
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mandoc.3,v 1.25 2014/08/05 05:48:56 schwarze Exp $
|
.\" $Id: mandoc.3,v 1.29 2014/11/26 23:42:14 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 5 2014 $
|
.Dd $Mdocdate: November 26 2014 $
|
||||||
.Dt MANDOC 3
|
.Dt MANDOC 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -31,11 +31,13 @@
|
|||||||
.Nm mparse_free ,
|
.Nm mparse_free ,
|
||||||
.Nm mparse_getkeep ,
|
.Nm mparse_getkeep ,
|
||||||
.Nm mparse_keep ,
|
.Nm mparse_keep ,
|
||||||
|
.Nm mparse_open ,
|
||||||
.Nm mparse_readfd ,
|
.Nm mparse_readfd ,
|
||||||
.Nm mparse_reset ,
|
.Nm mparse_reset ,
|
||||||
.Nm mparse_result ,
|
.Nm mparse_result ,
|
||||||
.Nm mparse_strerror ,
|
.Nm mparse_strerror ,
|
||||||
.Nm mparse_strlevel
|
.Nm mparse_strlevel
|
||||||
|
.Nm mparse_wait ,
|
||||||
.Nd mandoc macro compiler library
|
.Nd mandoc macro compiler library
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
.Lb libmandoc
|
.Lb libmandoc
|
||||||
@ -50,6 +52,7 @@
|
|||||||
.Fa "int options"
|
.Fa "int options"
|
||||||
.Fa "enum mandoclevel wlevel"
|
.Fa "enum mandoclevel wlevel"
|
||||||
.Fa "mandocmsg mmsg"
|
.Fa "mandocmsg mmsg"
|
||||||
|
.Fa "const struct mchars *mchars"
|
||||||
.Fa "char *defos"
|
.Fa "char *defos"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft void
|
.Ft void
|
||||||
@ -74,6 +77,12 @@
|
|||||||
.Fa "struct mparse *parse"
|
.Fa "struct mparse *parse"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft "enum mandoclevel"
|
.Ft "enum mandoclevel"
|
||||||
|
.Fo mparse_open
|
||||||
|
.Fa "struct mparse *parse"
|
||||||
|
.Fa "int *fd"
|
||||||
|
.Fa "const char *fname"
|
||||||
|
.Fc
|
||||||
|
.Ft "enum mandoclevel"
|
||||||
.Fo mparse_readfd
|
.Fo mparse_readfd
|
||||||
.Fa "struct mparse *parse"
|
.Fa "struct mparse *parse"
|
||||||
.Fa "int fd"
|
.Fa "int fd"
|
||||||
@ -98,6 +107,10 @@
|
|||||||
.Fo mparse_strlevel
|
.Fo mparse_strlevel
|
||||||
.Fa "enum mandoclevel"
|
.Fa "enum mandoclevel"
|
||||||
.Fc
|
.Fc
|
||||||
|
.Ft "enum mandoclevel"
|
||||||
|
.Fo mparse_wait
|
||||||
|
.Fa "struct mparse *parse"
|
||||||
|
.Fc
|
||||||
.In sys/types.h
|
.In sys/types.h
|
||||||
.In mandoc.h
|
.In mandoc.h
|
||||||
.In mdoc.h
|
.In mdoc.h
|
||||||
@ -159,6 +172,8 @@ The following describes a general parse sequence:
|
|||||||
.Bl -enum
|
.Bl -enum
|
||||||
.It
|
.It
|
||||||
initiate a parsing sequence with
|
initiate a parsing sequence with
|
||||||
|
.Xr mchars_alloc 3
|
||||||
|
and
|
||||||
.Fn mparse_alloc ;
|
.Fn mparse_alloc ;
|
||||||
.It
|
.It
|
||||||
parse files or file descriptors with
|
parse files or file descriptors with
|
||||||
@ -173,7 +188,9 @@ or
|
|||||||
.Fn man_node ;
|
.Fn man_node ;
|
||||||
.It
|
.It
|
||||||
free all allocated memory with
|
free all allocated memory with
|
||||||
.Fn mparse_free ,
|
.Fn mparse_free
|
||||||
|
and
|
||||||
|
.Xr mchars_free 3 ,
|
||||||
or invoke
|
or invoke
|
||||||
.Fn mparse_reset
|
.Fn mparse_reset
|
||||||
and parse new files.
|
and parse new files.
|
||||||
@ -194,6 +211,12 @@ A fatal error, error, or warning message during parsing.
|
|||||||
A classification of an
|
A classification of an
|
||||||
.Vt "enum mandocerr"
|
.Vt "enum mandocerr"
|
||||||
as regards system operation.
|
as regards system operation.
|
||||||
|
.It Vt "struct mchars"
|
||||||
|
An opaque pointer to a a character table.
|
||||||
|
Created with
|
||||||
|
.Xr mchars_alloc 3
|
||||||
|
and freed with
|
||||||
|
.Xr mchars_free 3 .
|
||||||
.It Vt "struct mparse"
|
.It Vt "struct mparse"
|
||||||
An opaque pointer to a running parse sequence.
|
An opaque pointer to a running parse sequence.
|
||||||
Created with
|
Created with
|
||||||
@ -318,6 +341,9 @@ A callback function to handle errors and warnings.
|
|||||||
See
|
See
|
||||||
.Pa main.c
|
.Pa main.c
|
||||||
for an example.
|
for an example.
|
||||||
|
.It Ar mchars
|
||||||
|
An opaque pointer to a a character table obtained from
|
||||||
|
.Xr mchars_alloc 3 .
|
||||||
.It Ar defos
|
.It Ar defos
|
||||||
A default string for the
|
A default string for the
|
||||||
.Xr mdoc 7
|
.Xr mdoc 7
|
||||||
@ -361,18 +387,47 @@ Declared in
|
|||||||
.In mandoc.h ,
|
.In mandoc.h ,
|
||||||
implemented in
|
implemented in
|
||||||
.Pa read.c .
|
.Pa read.c .
|
||||||
|
.It Fn mparse_open
|
||||||
|
If the
|
||||||
|
.Fa fname
|
||||||
|
ends in
|
||||||
|
.Pa .gz ,
|
||||||
|
open with
|
||||||
|
.Xr gunzip 1 ;
|
||||||
|
otherwise, with
|
||||||
|
.Xr open 2 .
|
||||||
|
If
|
||||||
|
.Xr open 2
|
||||||
|
fails, append
|
||||||
|
.Pa .gz
|
||||||
|
and try with
|
||||||
|
.Xr gunzip 1 .
|
||||||
|
Return a file descriptor open for reading in
|
||||||
|
.Fa fd ,
|
||||||
|
or -1 on failure.
|
||||||
|
It can be passed to
|
||||||
|
.Fn mparse_readfd
|
||||||
|
or used directly.
|
||||||
|
Declared in
|
||||||
|
.In mandoc.h ,
|
||||||
|
implemented in
|
||||||
|
.Pa read.c .
|
||||||
.It Fn mparse_readfd
|
.It Fn mparse_readfd
|
||||||
Parse a file or file descriptor.
|
Parse a file or file descriptor.
|
||||||
If
|
If
|
||||||
.Va fd
|
.Va fd
|
||||||
is -1,
|
is -1, open
|
||||||
.Va fname
|
.Va fname
|
||||||
is opened for reading.
|
with
|
||||||
|
.Fn mparse_open .
|
||||||
Otherwise,
|
Otherwise,
|
||||||
.Va fname
|
.Va fname
|
||||||
is assumed to be the name associated with
|
is assumed to be the name associated with
|
||||||
.Va fd .
|
.Va fd .
|
||||||
This may be called multiple times with different parameters; however,
|
Calls
|
||||||
|
.Fn mparse_wait
|
||||||
|
before returning.
|
||||||
|
This function may be called multiple times with different parameters; however,
|
||||||
.Fn mparse_reset
|
.Fn mparse_reset
|
||||||
should be invoked between parses.
|
should be invoked between parses.
|
||||||
Declared in
|
Declared in
|
||||||
@ -413,6 +468,28 @@ Declared in
|
|||||||
.In mandoc.h ,
|
.In mandoc.h ,
|
||||||
implemented in
|
implemented in
|
||||||
.Pa read.c .
|
.Pa read.c .
|
||||||
|
.It Fn mparse_wait
|
||||||
|
Bury a
|
||||||
|
.Xr gunzip 1
|
||||||
|
child process that was spawned with
|
||||||
|
.Fn mparse_open .
|
||||||
|
To be called after the parse sequence is complete.
|
||||||
|
Not needed after
|
||||||
|
.Fn mparse_readfd ,
|
||||||
|
but does no harm in that case, either.
|
||||||
|
Returns
|
||||||
|
.Dv MANDOCLEVEL_OK
|
||||||
|
on success and
|
||||||
|
.Dv MANDOCLEVEL_SYSERR
|
||||||
|
on failure, that is, when
|
||||||
|
.Xr wait 2
|
||||||
|
fails, or when
|
||||||
|
.Xr gunzip 1
|
||||||
|
died from a signal or exited with non-zero status.
|
||||||
|
Declared in
|
||||||
|
.In mandoc.h ,
|
||||||
|
implemented in
|
||||||
|
.Pa read.c .
|
||||||
.El
|
.El
|
||||||
.Ss Variables
|
.Ss Variables
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
|
37
mandoc.c
37
mandoc.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mandoc.c,v 1.83 2014/07/06 19:09:00 schwarze Exp $ */
|
/* $Id: mandoc.c,v 1.88 2014/10/28 13:24:44 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -81,24 +79,13 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
gly = ESCAPE_SPECIAL;
|
gly = ESCAPE_SPECIAL;
|
||||||
/*
|
|
||||||
* Unicode escapes are defined in groff as \[uXXXX] to
|
|
||||||
* \[u10FFFF], where the contained value must be a valid
|
|
||||||
* Unicode codepoint. Here, however, only check whether
|
|
||||||
* it's not a zero-width escape.
|
|
||||||
*/
|
|
||||||
if ('u' == (*start)[0] && ']' != (*start)[1])
|
|
||||||
gly = ESCAPE_UNICODE;
|
|
||||||
term = ']';
|
term = ']';
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if ('\'' != **start)
|
if ('\'' != **start)
|
||||||
return(ESCAPE_ERROR);
|
return(ESCAPE_ERROR);
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
if ('u' == (*start)[0] && '\'' != (*start)[1])
|
gly = ESCAPE_SPECIAL;
|
||||||
gly = ESCAPE_UNICODE;
|
|
||||||
else
|
|
||||||
gly = ESCAPE_SPECIAL;
|
|
||||||
term = '\'';
|
term = '\'';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -201,7 +188,8 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 'x':
|
case 'x':
|
||||||
if (strchr(" %&()*+-./0123456789:<=>", **start)) {
|
if (strchr(" %&()*+-./0123456789:<=>", **start)) {
|
||||||
++*end;
|
if ('\0' != **start)
|
||||||
|
++*end;
|
||||||
return(ESCAPE_ERROR);
|
return(ESCAPE_ERROR);
|
||||||
}
|
}
|
||||||
gly = ESCAPE_IGNORE;
|
gly = ESCAPE_IGNORE;
|
||||||
@ -345,6 +333,21 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
case ESCAPE_SPECIAL:
|
case ESCAPE_SPECIAL:
|
||||||
if (1 == *sz && 'c' == **start)
|
if (1 == *sz && 'c' == **start)
|
||||||
gly = ESCAPE_NOSPACE;
|
gly = ESCAPE_NOSPACE;
|
||||||
|
/*
|
||||||
|
* Unicode escapes are defined in groff as \[u0000]
|
||||||
|
* to \[u10FFFF], where the contained value must be
|
||||||
|
* a valid Unicode codepoint. Here, however, only
|
||||||
|
* check the length and range.
|
||||||
|
*/
|
||||||
|
if (**start != 'u' || *sz < 5 || *sz > 7)
|
||||||
|
break;
|
||||||
|
if (*sz == 7 && ((*start)[1] != '1' || (*start)[2] != '0'))
|
||||||
|
break;
|
||||||
|
if (*sz == 6 && (*start)[1] == '0')
|
||||||
|
break;
|
||||||
|
if ((int)strspn(*start + 1, "0123456789ABCDEFabcdef")
|
||||||
|
+ 1 == *sz)
|
||||||
|
gly = ESCAPE_UNICODE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -457,7 +460,7 @@ a2time(time_t *t, const char *fmt, const char *p)
|
|||||||
memset(&tm, 0, sizeof(struct tm));
|
memset(&tm, 0, sizeof(struct tm));
|
||||||
|
|
||||||
pp = NULL;
|
pp = NULL;
|
||||||
#ifdef HAVE_STRPTIME
|
#if HAVE_STRPTIME
|
||||||
pp = strptime(p, fmt, &tm);
|
pp = strptime(p, fmt, &tm);
|
||||||
#endif
|
#endif
|
||||||
if (NULL != pp && '\0' == *pp) {
|
if (NULL != pp && '\0' == *pp) {
|
||||||
|
23
mandoc.db.5
23
mandoc.db.5
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mandoc.db.5,v 1.1 2014/04/15 20:18:26 schwarze Exp $
|
.\" $Id: mandoc.db.5,v 1.2 2014/09/03 18:09:14 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: April 15 2014 $
|
.Dd $Mdocdate: September 3 2014 $
|
||||||
.Dt MANDOC.DB 5
|
.Dt MANDOC.DB 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -67,13 +67,26 @@ The description line
|
|||||||
.Pq Sq \&Nd
|
.Pq Sq \&Nd
|
||||||
of the page.
|
of the page.
|
||||||
.It Sy mpages.form
|
.It Sy mpages.form
|
||||||
The
|
An
|
||||||
.Vt INTEGER
|
.Vt INTEGER
|
||||||
1 if the page is unformatted, i.e. in
|
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
|
||||||
.Xr mdoc 7
|
.Xr mdoc 7
|
||||||
or
|
or
|
||||||
.Xr man 7
|
.Xr man 7
|
||||||
format, and 2 if it is formatted, i.e. a
|
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
|
.Sq cat
|
||||||
page.
|
page.
|
||||||
.It Sy mlinks.sec
|
.It Sy mlinks.sec
|
||||||
|
68
mandoc.h
68
mandoc.h
@ -1,6 +1,6 @@
|
|||||||
/* $Id: mandoc.h,v 1.152 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: mandoc.h,v 1.171 2014/11/28 18:09:01 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@ -54,7 +54,6 @@ enum mandocerr {
|
|||||||
MANDOCERR_TITLE_CASE, /* lower case character in document title */
|
MANDOCERR_TITLE_CASE, /* lower case character in document title */
|
||||||
MANDOCERR_MSEC_MISSING, /* missing manual section, using "": macro */
|
MANDOCERR_MSEC_MISSING, /* missing manual section, using "": macro */
|
||||||
MANDOCERR_MSEC_BAD, /* unknown manual section: Dt ... section */
|
MANDOCERR_MSEC_BAD, /* unknown manual section: Dt ... section */
|
||||||
MANDOCERR_ARCH_BAD, /* unknown manual volume or arch: Dt ... volume */
|
|
||||||
MANDOCERR_DATE_MISSING, /* missing date, using today's date */
|
MANDOCERR_DATE_MISSING, /* missing date, using today's date */
|
||||||
MANDOCERR_DATE_BAD, /* cannot parse date, using it verbatim: date */
|
MANDOCERR_DATE_BAD, /* cannot parse date, using it verbatim: date */
|
||||||
MANDOCERR_OS_MISSING, /* missing Os macro, using "" */
|
MANDOCERR_OS_MISSING, /* missing Os macro, using "" */
|
||||||
@ -72,6 +71,9 @@ enum mandocerr {
|
|||||||
MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
|
MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
|
||||||
MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
|
MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
|
||||||
MANDOCERR_SEC_MSEC, /* unexpected section: Sh title for ... only */
|
MANDOCERR_SEC_MSEC, /* unexpected section: Sh title for ... only */
|
||||||
|
MANDOCERR_XR_ORDER, /* unusual Xr order: ... after ... */
|
||||||
|
MANDOCERR_XR_PUNCT, /* unusual Xr punctuation: ... after ... */
|
||||||
|
MANDOCERR_AN_MISSING, /* AUTHORS section without An macro */
|
||||||
|
|
||||||
/* related to macros and nesting */
|
/* related to macros and nesting */
|
||||||
MANDOCERR_MACRO_OBS, /* obsolete macro: macro */
|
MANDOCERR_MACRO_OBS, /* obsolete macro: macro */
|
||||||
@ -101,6 +103,7 @@ enum mandocerr {
|
|||||||
MANDOCERR_BF_NOFONT, /* missing font type, using \fR: Bf */
|
MANDOCERR_BF_NOFONT, /* missing font type, using \fR: Bf */
|
||||||
MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */
|
MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */
|
||||||
MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
|
MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
|
||||||
|
MANDOCERR_EQN_NOBOX, /* missing eqn box, using "": op */
|
||||||
|
|
||||||
/* related to bad arguments */
|
/* related to bad arguments */
|
||||||
MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */
|
MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */
|
||||||
@ -110,6 +113,8 @@ enum mandocerr {
|
|||||||
MANDOCERR_BL_REP, /* skipping duplicate list type: Bl -type */
|
MANDOCERR_BL_REP, /* skipping duplicate list type: Bl -type */
|
||||||
MANDOCERR_BL_SKIPW, /* skipping -width argument: Bl -type */
|
MANDOCERR_BL_SKIPW, /* skipping -width argument: Bl -type */
|
||||||
MANDOCERR_AT_BAD, /* unknown AT&T UNIX version: At version */
|
MANDOCERR_AT_BAD, /* unknown AT&T UNIX version: At version */
|
||||||
|
MANDOCERR_FA_COMMA, /* comma in function argument: arg */
|
||||||
|
MANDOCERR_FN_PAREN, /* parenthesis in function name: arg */
|
||||||
MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */
|
MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */
|
||||||
MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */
|
MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */
|
||||||
MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */
|
MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */
|
||||||
@ -129,7 +134,6 @@ enum mandocerr {
|
|||||||
MANDOCERR_EQNSCOPE, /* equation scope open on exit */
|
MANDOCERR_EQNSCOPE, /* equation scope open on exit */
|
||||||
MANDOCERR_EQNBADSCOPE, /* overlapping equation scopes */
|
MANDOCERR_EQNBADSCOPE, /* overlapping equation scopes */
|
||||||
MANDOCERR_EQNEOF, /* unexpected end of equation */
|
MANDOCERR_EQNEOF, /* unexpected end of equation */
|
||||||
MANDOCERR_EQNSYNT, /* equation syntax error */
|
|
||||||
|
|
||||||
/* related to tables */
|
/* related to tables */
|
||||||
MANDOCERR_TBL, /* bad table syntax */
|
MANDOCERR_TBL, /* bad table syntax */
|
||||||
@ -154,6 +158,7 @@ enum mandocerr {
|
|||||||
/* related to request and macro arguments */
|
/* related to request and macro arguments */
|
||||||
MANDOCERR_NAMESC, /* escaped character not allowed in a name: name */
|
MANDOCERR_NAMESC, /* escaped character not allowed in a name: name */
|
||||||
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
||||||
|
MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
|
||||||
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
|
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
|
||||||
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
|
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
|
||||||
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
|
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
|
||||||
@ -161,19 +166,26 @@ enum mandocerr {
|
|||||||
MANDOCERR_IT_NONUM, /* skipping request without numeric argument */
|
MANDOCERR_IT_NONUM, /* skipping request without numeric argument */
|
||||||
MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */
|
MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */
|
||||||
MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */
|
MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */
|
||||||
|
MANDOCERR_DIVZERO, /* divide by zero */
|
||||||
|
|
||||||
MANDOCERR_FATAL, /* ===== start of fatal errors ===== */
|
MANDOCERR_FATAL, /* ===== start of fatal errors ===== */
|
||||||
|
|
||||||
MANDOCERR_TOOLARGE, /* input too large */
|
MANDOCERR_TOOLARGE, /* input too large */
|
||||||
MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
|
|
||||||
MANDOCERR_SO_PATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
MANDOCERR_SO_PATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
||||||
MANDOCERR_SO_FAIL, /* .so request failed */
|
MANDOCERR_SO_FAIL, /* .so request failed */
|
||||||
|
|
||||||
/* ===== system errors ===== */
|
/* ===== system errors ===== */
|
||||||
|
|
||||||
|
MANDOCERR_SYSDUP, /* cannot dup file descriptor */
|
||||||
|
MANDOCERR_SYSEXEC, /* cannot exec */
|
||||||
|
MANDOCERR_SYSEXIT, /* gunzip failed with code */
|
||||||
|
MANDOCERR_SYSFORK, /* cannot fork */
|
||||||
MANDOCERR_SYSOPEN, /* cannot open file */
|
MANDOCERR_SYSOPEN, /* cannot open file */
|
||||||
MANDOCERR_SYSSTAT, /* cannot stat file */
|
MANDOCERR_SYSPIPE, /* cannot open pipe */
|
||||||
MANDOCERR_SYSREAD, /* cannot read file */
|
MANDOCERR_SYSREAD, /* cannot read file */
|
||||||
|
MANDOCERR_SYSSIG, /* gunzip died from signal */
|
||||||
|
MANDOCERR_SYSSTAT, /* cannot stat file */
|
||||||
|
MANDOCERR_SYSWAIT, /* wait failed */
|
||||||
|
|
||||||
MANDOCERR_MAX
|
MANDOCERR_MAX
|
||||||
};
|
};
|
||||||
@ -234,6 +246,7 @@ struct tbl_cell {
|
|||||||
#define TBL_CELL_EQUAL (1 << 4) /* e, E */
|
#define TBL_CELL_EQUAL (1 << 4) /* e, E */
|
||||||
#define TBL_CELL_UP (1 << 5) /* u, U */
|
#define TBL_CELL_UP (1 << 5) /* u, U */
|
||||||
#define TBL_CELL_WIGN (1 << 6) /* z, Z */
|
#define TBL_CELL_WIGN (1 << 6) /* z, Z */
|
||||||
|
#define TBL_CELL_WMAX (1 << 7) /* x, X */
|
||||||
struct tbl_head *head;
|
struct tbl_head *head;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -295,21 +308,10 @@ enum eqn_boxt {
|
|||||||
EQN_ROOT, /* root of parse tree */
|
EQN_ROOT, /* root of parse tree */
|
||||||
EQN_TEXT, /* text (number, variable, whatever) */
|
EQN_TEXT, /* text (number, variable, whatever) */
|
||||||
EQN_SUBEXPR, /* nested `eqn' subexpression */
|
EQN_SUBEXPR, /* nested `eqn' subexpression */
|
||||||
EQN_LIST, /* subexpressions list */
|
EQN_LIST, /* list (braces, etc.) */
|
||||||
EQN_MATRIX /* matrix subexpression */
|
EQN_LISTONE, /* singleton list */
|
||||||
};
|
EQN_PILE, /* vertical pile */
|
||||||
|
EQN_MATRIX /* pile of piles */
|
||||||
enum eqn_markt {
|
|
||||||
EQNMARK_NONE = 0,
|
|
||||||
EQNMARK_DOT,
|
|
||||||
EQNMARK_DOTDOT,
|
|
||||||
EQNMARK_HAT,
|
|
||||||
EQNMARK_TILDE,
|
|
||||||
EQNMARK_VEC,
|
|
||||||
EQNMARK_DYAD,
|
|
||||||
EQNMARK_BAR,
|
|
||||||
EQNMARK_UNDER,
|
|
||||||
EQNMARK__MAX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eqn_fontt {
|
enum eqn_fontt {
|
||||||
@ -323,11 +325,14 @@ enum eqn_fontt {
|
|||||||
|
|
||||||
enum eqn_post {
|
enum eqn_post {
|
||||||
EQNPOS_NONE = 0,
|
EQNPOS_NONE = 0,
|
||||||
EQNPOS_OVER,
|
|
||||||
EQNPOS_SUP,
|
EQNPOS_SUP,
|
||||||
|
EQNPOS_SUBSUP,
|
||||||
EQNPOS_SUB,
|
EQNPOS_SUB,
|
||||||
EQNPOS_TO,
|
EQNPOS_TO,
|
||||||
EQNPOS_FROM,
|
EQNPOS_FROM,
|
||||||
|
EQNPOS_FROMTO,
|
||||||
|
EQNPOS_OVER,
|
||||||
|
EQNPOS_SQRT,
|
||||||
EQNPOS__MAX
|
EQNPOS__MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -355,12 +360,16 @@ struct eqn_box {
|
|||||||
struct eqn_box *first; /* first child node */
|
struct eqn_box *first; /* first child node */
|
||||||
struct eqn_box *last; /* last child node */
|
struct eqn_box *last; /* last child node */
|
||||||
struct eqn_box *next; /* node sibling */
|
struct eqn_box *next; /* node sibling */
|
||||||
|
struct eqn_box *prev; /* node sibling */
|
||||||
struct eqn_box *parent; /* node sibling */
|
struct eqn_box *parent; /* node sibling */
|
||||||
char *text; /* text (or NULL) */
|
char *text; /* text (or NULL) */
|
||||||
char *left;
|
char *left; /* fence left-hand */
|
||||||
char *right;
|
char *right; /* fence right-hand */
|
||||||
|
char *top; /* expression over-symbol */
|
||||||
|
char *bottom; /* expression under-symbol */
|
||||||
|
size_t args; /* arguments in parent */
|
||||||
|
size_t expectargs; /* max arguments in parent */
|
||||||
enum eqn_post pos; /* position of next box */
|
enum eqn_post pos; /* position of next box */
|
||||||
enum eqn_markt mark; /* a mark about the box */
|
|
||||||
enum eqn_fontt font; /* font of box */
|
enum eqn_fontt font; /* font of box */
|
||||||
enum eqn_pilet pile; /* equation piling */
|
enum eqn_pilet pile; /* equation piling */
|
||||||
};
|
};
|
||||||
@ -383,6 +392,8 @@ struct eqn {
|
|||||||
#define MPARSE_MAN 2 /* assume -man */
|
#define MPARSE_MAN 2 /* assume -man */
|
||||||
#define MPARSE_SO 4 /* honour .so requests */
|
#define MPARSE_SO 4 /* honour .so requests */
|
||||||
#define MPARSE_QUICK 8 /* abort the parse early */
|
#define MPARSE_QUICK 8 /* abort the parse early */
|
||||||
|
#define MPARSE_UTF8 16 /* accept UTF-8 input */
|
||||||
|
#define MPARSE_LATIN1 32 /* accept ISO-LATIN-1 input */
|
||||||
|
|
||||||
enum mandoc_esc {
|
enum mandoc_esc {
|
||||||
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
||||||
@ -413,16 +424,18 @@ __BEGIN_DECLS
|
|||||||
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
||||||
struct mchars *mchars_alloc(void);
|
struct mchars *mchars_alloc(void);
|
||||||
void mchars_free(struct mchars *);
|
void mchars_free(struct mchars *);
|
||||||
char mchars_num2char(const char *, size_t);
|
int mchars_num2char(const char *, size_t);
|
||||||
|
const char *mchars_uc2str(int);
|
||||||
int mchars_num2uc(const char *, size_t);
|
int mchars_num2uc(const char *, size_t);
|
||||||
int mchars_spec2cp(const struct mchars *,
|
int mchars_spec2cp(const struct mchars *,
|
||||||
const char *, size_t);
|
const char *, size_t);
|
||||||
const char *mchars_spec2str(const struct mchars *,
|
const char *mchars_spec2str(const struct mchars *,
|
||||||
const char *, size_t, size_t *);
|
const char *, size_t, size_t *);
|
||||||
struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg,
|
struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg,
|
||||||
const char *);
|
const struct mchars *, const char *);
|
||||||
void mparse_free(struct mparse *);
|
void mparse_free(struct mparse *);
|
||||||
void mparse_keep(struct mparse *);
|
void mparse_keep(struct mparse *);
|
||||||
|
enum mandoclevel mparse_open(struct mparse *, int *, const char *);
|
||||||
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
|
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
|
||||||
enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t,
|
enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t,
|
||||||
const char *);
|
const char *);
|
||||||
@ -432,6 +445,7 @@ void mparse_result(struct mparse *,
|
|||||||
const char *mparse_getkeep(const struct mparse *);
|
const char *mparse_getkeep(const struct mparse *);
|
||||||
const char *mparse_strerror(enum mandocerr);
|
const char *mparse_strerror(enum mandocerr);
|
||||||
const char *mparse_strlevel(enum mandoclevel);
|
const char *mparse_strlevel(enum mandoclevel);
|
||||||
|
enum mandoclevel mparse_wait(struct mparse *);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mandoc_aux.c,v 1.3 2014/07/09 08:20:34 schwarze Exp $ */
|
/* $Id: mandoc_aux.c,v 1.4 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mandoc_escape.3,v 1.1 2014/08/05 05:48:56 schwarze Exp $
|
.\" $Id: mandoc_escape.3,v 1.2 2014/10/28 14:06:31 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 5 2014 $
|
.Dd $Mdocdate: October 28 2014 $
|
||||||
.Dt MANDOC_ESCAPE 3
|
.Dt MANDOC_ESCAPE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -197,15 +197,9 @@ form, directly follows the initial backslash:
|
|||||||
Note that the one-character argument short form can only be used for
|
Note that the one-character argument short form can only be used for
|
||||||
argument characters that do not clash with escape sequence identifiers.
|
argument characters that do not clash with escape sequence identifiers.
|
||||||
.Pp
|
.Pp
|
||||||
If the argument consists of more than one character
|
If the argument matches one of the forms described below under
|
||||||
and starts with the character
|
.Dv ESCAPE_UNICODE ,
|
||||||
.Sq u ,
|
that value is returned instead.
|
||||||
.Dv ESCAPE_UNICODE
|
|
||||||
is returned as described below.
|
|
||||||
If the argument is just the single character
|
|
||||||
.Sq u ,
|
|
||||||
.Dv ESCAPE_ERROR
|
|
||||||
is returned.
|
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Dv ESCAPE_SPECIAL
|
.Dv ESCAPE_SPECIAL
|
||||||
@ -219,17 +213,27 @@ manual.
|
|||||||
.It Dv ESCAPE_UNICODE
|
.It Dv ESCAPE_UNICODE
|
||||||
Escape sequences of the same format as described above under
|
Escape sequences of the same format as described above under
|
||||||
.Dv ESCAPE_SPECIAL ,
|
.Dv ESCAPE_SPECIAL ,
|
||||||
but with an argument starting with the character
|
but with an argument of the forms
|
||||||
.Sq u :
|
.Ic u Ns Ar XXXX ,
|
||||||
|
.Ic u Ns Ar YXXXX ,
|
||||||
|
or
|
||||||
|
.Ic u10 Ns Ar XXXX
|
||||||
|
where
|
||||||
|
.Ar X
|
||||||
|
and
|
||||||
|
.Ar Y
|
||||||
|
are hexadecimal digits and
|
||||||
|
.Ar Y
|
||||||
|
is not zero:
|
||||||
.Ic \eC'u , \e[u .
|
.Ic \eC'u , \e[u .
|
||||||
As a special exception,
|
As a special exception,
|
||||||
.Fa start
|
.Fa start
|
||||||
is set to the character after the
|
is set to the character after the
|
||||||
.Sq u ,
|
.Ic u ,
|
||||||
and the
|
and the
|
||||||
.Fa sz
|
.Fa sz
|
||||||
return value does not include the
|
return value does not include the
|
||||||
.Sq u
|
.Ic u
|
||||||
either.
|
either.
|
||||||
.Pp
|
.Pp
|
||||||
Such Unicode character escape sequences can be rendered using the function
|
Such Unicode character escape sequences can be rendered using the function
|
||||||
|
184
mandocdb.c
184
mandocdb.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mandocdb.c,v 1.155 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: mandocdb.c,v 1.171 2014/11/27 01:58:21 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,10 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
@ -26,7 +25,11 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#if HAVE_FTS
|
||||||
#include <fts.h>
|
#include <fts.h>
|
||||||
|
#else
|
||||||
|
#include "compat_fts.h"
|
||||||
|
#endif
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -36,7 +39,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef HAVE_OHASH
|
#if HAVE_OHASH
|
||||||
#include <ohash.h>
|
#include <ohash.h>
|
||||||
#else
|
#else
|
||||||
#include "compat_ohash.h"
|
#include "compat_ohash.h"
|
||||||
@ -80,12 +83,6 @@ enum op {
|
|||||||
OP_TEST /* change no databases, report potential problems */
|
OP_TEST /* change no databases, report potential problems */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum form {
|
|
||||||
FORM_NONE, /* format is unknown */
|
|
||||||
FORM_SRC, /* format is -man or -mdoc */
|
|
||||||
FORM_CAT /* format is cat */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct str {
|
struct str {
|
||||||
char *rendered; /* key in UTF-8 or ASCII form */
|
char *rendered; /* key in UTF-8 or ASCII form */
|
||||||
const struct mpage *mpage; /* if set, the owning parse */
|
const struct mpage *mpage; /* if set, the owning parse */
|
||||||
@ -101,24 +98,24 @@ struct inodev {
|
|||||||
struct mpage {
|
struct mpage {
|
||||||
struct inodev inodev; /* used for hashing routine */
|
struct inodev inodev; /* used for hashing routine */
|
||||||
int64_t pageid; /* pageid in mpages SQL table */
|
int64_t pageid; /* pageid in mpages SQL table */
|
||||||
enum form form; /* format from file content */
|
|
||||||
char *sec; /* section from file content */
|
char *sec; /* section from file content */
|
||||||
char *arch; /* architecture from file content */
|
char *arch; /* architecture from file content */
|
||||||
char *title; /* title from file content */
|
char *title; /* title from file content */
|
||||||
char *desc; /* description from file content */
|
char *desc; /* description from file content */
|
||||||
struct mlink *mlinks; /* singly linked list */
|
struct mlink *mlinks; /* singly linked list */
|
||||||
|
int form; /* format from file content */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlink {
|
struct mlink {
|
||||||
char file[PATH_MAX]; /* filename rel. to manpath */
|
char file[PATH_MAX]; /* filename rel. to manpath */
|
||||||
enum form dform; /* format from directory */
|
|
||||||
enum form fform; /* format from file name suffix */
|
|
||||||
char *dsec; /* section from directory */
|
char *dsec; /* section from directory */
|
||||||
char *arch; /* architecture from directory */
|
char *arch; /* architecture from directory */
|
||||||
char *name; /* name from file name (not empty) */
|
char *name; /* name from file name (not empty) */
|
||||||
char *fsec; /* section from file name suffix */
|
char *fsec; /* section from file name suffix */
|
||||||
struct mlink *next; /* singly linked list */
|
struct mlink *next; /* singly linked list */
|
||||||
struct mpage *mpage; /* parent */
|
struct mpage *mpage; /* parent */
|
||||||
|
int dform; /* format from directory */
|
||||||
|
int fform; /* format from file name suffix */
|
||||||
int gzip; /* filename has a .gz suffix */
|
int gzip; /* filename has a .gz suffix */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,6 +138,7 @@ struct mdoc_handler {
|
|||||||
static void dbclose(int);
|
static void dbclose(int);
|
||||||
static void dbadd(struct mpage *, struct mchars *);
|
static void dbadd(struct mpage *, struct mchars *);
|
||||||
static void dbadd_mlink(const struct mlink *mlink);
|
static void dbadd_mlink(const struct mlink *mlink);
|
||||||
|
static void dbadd_mlink_name(const struct mlink *mlink);
|
||||||
static int dbopen(int);
|
static int dbopen(int);
|
||||||
static void dbprune(void);
|
static void dbprune(void);
|
||||||
static void filescan(const char *);
|
static void filescan(const char *);
|
||||||
@ -172,7 +170,7 @@ static void putmdockey(const struct mpage *,
|
|||||||
const struct mdoc_node *, uint64_t);
|
const struct mdoc_node *, uint64_t);
|
||||||
static void render_key(struct mchars *, struct str *);
|
static void render_key(struct mchars *, struct str *);
|
||||||
static void say(const char *, const char *, ...);
|
static void say(const char *, const char *, ...);
|
||||||
static int set_basedir(const char *);
|
static int set_basedir(const char *, int);
|
||||||
static int treescan(void);
|
static int treescan(void);
|
||||||
static size_t utf8(unsigned int, char [7]);
|
static size_t utf8(unsigned int, char [7]);
|
||||||
|
|
||||||
@ -318,6 +316,7 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
|
|||||||
{ NULL, 0 }, /* sp */
|
{ NULL, 0 }, /* sp */
|
||||||
{ NULL, 0 }, /* %U */
|
{ NULL, 0 }, /* %U */
|
||||||
{ NULL, 0 }, /* Ta */
|
{ NULL, 0 }, /* Ta */
|
||||||
|
{ NULL, 0 }, /* ll */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -427,9 +426,9 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
exitcode = (int)MANDOCLEVEL_OK;
|
exitcode = (int)MANDOCLEVEL_OK;
|
||||||
mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL, NULL);
|
|
||||||
mc = mchars_alloc();
|
mc = mchars_alloc();
|
||||||
|
mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL,
|
||||||
|
mc, NULL);
|
||||||
ohash_init(&mpages, 6, &mpages_info);
|
ohash_init(&mpages, 6, &mpages_info);
|
||||||
ohash_init(&mlinks, 6, &mlinks_info);
|
ohash_init(&mlinks, 6, &mlinks_info);
|
||||||
|
|
||||||
@ -439,7 +438,7 @@ main(int argc, char *argv[])
|
|||||||
* Most of these deal with a specific directory.
|
* Most of these deal with a specific directory.
|
||||||
* Jump into that directory first.
|
* Jump into that directory first.
|
||||||
*/
|
*/
|
||||||
if (OP_TEST != op && 0 == set_basedir(path_arg))
|
if (OP_TEST != op && 0 == set_basedir(path_arg, 1))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (dbopen(1)) {
|
if (dbopen(1)) {
|
||||||
@ -505,12 +504,12 @@ main(int argc, char *argv[])
|
|||||||
ohash_init(&mlinks, 6, &mlinks_info);
|
ohash_init(&mlinks, 6, &mlinks_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == set_basedir(dirs.paths[j]))
|
if (0 == set_basedir(dirs.paths[j], argc > 0))
|
||||||
goto out;
|
continue;
|
||||||
if (0 == treescan())
|
if (0 == treescan())
|
||||||
goto out;
|
continue;
|
||||||
if (0 == dbopen(0))
|
if (0 == dbopen(0))
|
||||||
goto out;
|
continue;
|
||||||
|
|
||||||
mpages_merge(mc, mp);
|
mpages_merge(mc, mp);
|
||||||
if (warnings && !nodb &&
|
if (warnings && !nodb &&
|
||||||
@ -527,8 +526,8 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
manpath_free(&dirs);
|
manpath_free(&dirs);
|
||||||
mchars_free(mc);
|
|
||||||
mparse_free(mp);
|
mparse_free(mp);
|
||||||
|
mchars_free(mc);
|
||||||
mpages_free();
|
mpages_free();
|
||||||
ohash_delete(&mpages);
|
ohash_delete(&mpages);
|
||||||
ohash_delete(&mlinks);
|
ohash_delete(&mlinks);
|
||||||
@ -835,6 +834,7 @@ filescan(const char *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mlink = mandoc_calloc(1, sizeof(struct mlink));
|
mlink = mandoc_calloc(1, sizeof(struct mlink));
|
||||||
|
mlink->dform = FORM_NONE;
|
||||||
if (strlcpy(mlink->file, start, sizeof(mlink->file)) >=
|
if (strlcpy(mlink->file, start, sizeof(mlink->file)) >=
|
||||||
sizeof(mlink->file)) {
|
sizeof(mlink->file)) {
|
||||||
say(start, "Filename too long");
|
say(start, "Filename too long");
|
||||||
@ -1078,15 +1078,13 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
{
|
{
|
||||||
char any[] = "any";
|
char any[] = "any";
|
||||||
struct ohash_info str_info;
|
struct ohash_info str_info;
|
||||||
int fd[2];
|
|
||||||
struct mpage *mpage, *mpage_dest;
|
struct mpage *mpage, *mpage_dest;
|
||||||
struct mlink *mlink, *mlink_dest;
|
struct mlink *mlink, *mlink_dest;
|
||||||
struct mdoc *mdoc;
|
struct mdoc *mdoc;
|
||||||
struct man *man;
|
struct man *man;
|
||||||
char *sodest;
|
char *sodest;
|
||||||
char *cp;
|
char *cp;
|
||||||
pid_t child_pid;
|
int fd;
|
||||||
int status;
|
|
||||||
unsigned int pslot;
|
unsigned int pslot;
|
||||||
enum mandoclevel lvl;
|
enum mandoclevel lvl;
|
||||||
|
|
||||||
@ -1095,13 +1093,13 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
str_info.free = hash_free;
|
str_info.free = hash_free;
|
||||||
str_info.key_offset = offsetof(struct str, key);
|
str_info.key_offset = offsetof(struct str, key);
|
||||||
|
|
||||||
if (0 == nodb)
|
if ( ! nodb)
|
||||||
SQL_EXEC("BEGIN TRANSACTION");
|
SQL_EXEC("BEGIN TRANSACTION");
|
||||||
|
|
||||||
mpage = ohash_first(&mpages, &pslot);
|
mpage = ohash_first(&mpages, &pslot);
|
||||||
while (NULL != mpage) {
|
while (mpage != NULL) {
|
||||||
mlinks_undupe(mpage);
|
mlinks_undupe(mpage);
|
||||||
if (NULL == mpage->mlinks) {
|
if (mpage->mlinks == NULL) {
|
||||||
mpage = ohash_next(&mpages, &pslot);
|
mpage = ohash_next(&mpages, &pslot);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1113,39 +1111,11 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
mdoc = NULL;
|
mdoc = NULL;
|
||||||
man = NULL;
|
man = NULL;
|
||||||
sodest = NULL;
|
sodest = NULL;
|
||||||
child_pid = 0;
|
|
||||||
fd[0] = -1;
|
|
||||||
fd[1] = -1;
|
|
||||||
|
|
||||||
if (mpage->mlinks->gzip) {
|
mparse_open(mp, &fd, mpage->mlinks->file);
|
||||||
if (-1 == pipe(fd)) {
|
if (fd == -1) {
|
||||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
say(mpage->mlinks->file, "&open");
|
||||||
say(mpage->mlinks->file, "&pipe gunzip");
|
goto nextpage;
|
||||||
goto nextpage;
|
|
||||||
}
|
|
||||||
switch (child_pid = fork()) {
|
|
||||||
case -1:
|
|
||||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
|
||||||
say(mpage->mlinks->file, "&fork gunzip");
|
|
||||||
child_pid = 0;
|
|
||||||
close(fd[1]);
|
|
||||||
close(fd[0]);
|
|
||||||
goto nextpage;
|
|
||||||
case 0:
|
|
||||||
close(fd[0]);
|
|
||||||
if (-1 == dup2(fd[1], STDOUT_FILENO)) {
|
|
||||||
say(mpage->mlinks->file,
|
|
||||||
"&dup gunzip");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
execlp("gunzip", "gunzip", "-c",
|
|
||||||
mpage->mlinks->file, NULL);
|
|
||||||
say(mpage->mlinks->file, "&exec gunzip");
|
|
||||||
exit(1);
|
|
||||||
default:
|
|
||||||
close(fd[1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1153,17 +1123,23 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
* source code, unless it is already known to be
|
* source code, unless it is already known to be
|
||||||
* formatted. Fall back to formatted mode.
|
* formatted. Fall back to formatted mode.
|
||||||
*/
|
*/
|
||||||
if (FORM_CAT != mpage->mlinks->dform ||
|
if (mpage->mlinks->dform != FORM_CAT ||
|
||||||
FORM_CAT != mpage->mlinks->fform) {
|
mpage->mlinks->fform != FORM_CAT) {
|
||||||
lvl = mparse_readfd(mp, fd[0], mpage->mlinks->file);
|
lvl = mparse_readfd(mp, fd, mpage->mlinks->file);
|
||||||
if (lvl < MANDOCLEVEL_FATAL)
|
if (lvl < MANDOCLEVEL_FATAL)
|
||||||
mparse_result(mp, &mdoc, &man, &sodest);
|
mparse_result(mp, &mdoc, &man, &sodest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != sodest) {
|
if (sodest != NULL) {
|
||||||
mlink_dest = ohash_find(&mlinks,
|
mlink_dest = ohash_find(&mlinks,
|
||||||
ohash_qlookup(&mlinks, sodest));
|
ohash_qlookup(&mlinks, sodest));
|
||||||
if (NULL != mlink_dest) {
|
if (mlink_dest == NULL) {
|
||||||
|
mandoc_asprintf(&cp, "%s.gz", sodest);
|
||||||
|
mlink_dest = ohash_find(&mlinks,
|
||||||
|
ohash_qlookup(&mlinks, cp));
|
||||||
|
free(cp);
|
||||||
|
}
|
||||||
|
if (mlink_dest != NULL) {
|
||||||
|
|
||||||
/* The .so target exists. */
|
/* The .so target exists. */
|
||||||
|
|
||||||
@ -1182,9 +1158,9 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (mpage_dest->pageid)
|
if (mpage_dest->pageid)
|
||||||
dbadd_mlink(mlink);
|
dbadd_mlink_name(mlink);
|
||||||
|
|
||||||
if (NULL == mlink->next)
|
if (mlink->next == NULL)
|
||||||
break;
|
break;
|
||||||
mlink = mlink->next;
|
mlink = mlink->next;
|
||||||
}
|
}
|
||||||
@ -1196,17 +1172,17 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
mpage->mlinks = NULL;
|
mpage->mlinks = NULL;
|
||||||
}
|
}
|
||||||
goto nextpage;
|
goto nextpage;
|
||||||
} else if (NULL != mdoc) {
|
} else if (mdoc != NULL) {
|
||||||
mpage->form = FORM_SRC;
|
mpage->form = FORM_SRC;
|
||||||
mpage->sec = mdoc_meta(mdoc)->msec;
|
mpage->sec = mdoc_meta(mdoc)->msec;
|
||||||
mpage->sec = mandoc_strdup(
|
mpage->sec = mandoc_strdup(
|
||||||
NULL == mpage->sec ? "" : mpage->sec);
|
mpage->sec == NULL ? "" : mpage->sec);
|
||||||
mpage->arch = mdoc_meta(mdoc)->arch;
|
mpage->arch = mdoc_meta(mdoc)->arch;
|
||||||
mpage->arch = mandoc_strdup(
|
mpage->arch = mandoc_strdup(
|
||||||
NULL == mpage->arch ? "" : mpage->arch);
|
mpage->arch == NULL ? "" : mpage->arch);
|
||||||
mpage->title =
|
mpage->title =
|
||||||
mandoc_strdup(mdoc_meta(mdoc)->title);
|
mandoc_strdup(mdoc_meta(mdoc)->title);
|
||||||
} else if (NULL != man) {
|
} else if (man != NULL) {
|
||||||
mpage->form = FORM_SRC;
|
mpage->form = FORM_SRC;
|
||||||
mpage->sec =
|
mpage->sec =
|
||||||
mandoc_strdup(man_meta(man)->msec);
|
mandoc_strdup(man_meta(man)->msec);
|
||||||
@ -1224,8 +1200,8 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
mandoc_strdup(mpage->mlinks->name);
|
mandoc_strdup(mpage->mlinks->name);
|
||||||
}
|
}
|
||||||
putkey(mpage, mpage->sec, TYPE_sec);
|
putkey(mpage, mpage->sec, TYPE_sec);
|
||||||
putkey(mpage, '\0' == *mpage->arch ?
|
if (*mpage->arch != '\0')
|
||||||
any : mpage->arch, TYPE_arch);
|
putkey(mpage, mpage->arch, TYPE_arch);
|
||||||
|
|
||||||
for (mlink = mpage->mlinks; mlink; mlink = mlink->next) {
|
for (mlink = mpage->mlinks; mlink; mlink = mlink->next) {
|
||||||
if ('\0' != *mlink->dsec)
|
if ('\0' != *mlink->dsec)
|
||||||
@ -1245,7 +1221,7 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
} else if (NULL != man)
|
} else if (NULL != man)
|
||||||
parse_man(mpage, man_node(man));
|
parse_man(mpage, man_node(man));
|
||||||
else
|
else
|
||||||
parse_cat(mpage, fd[0]);
|
parse_cat(mpage, fd);
|
||||||
if (NULL == mpage->desc)
|
if (NULL == mpage->desc)
|
||||||
mpage->desc = mandoc_strdup(mpage->mlinks->name);
|
mpage->desc = mandoc_strdup(mpage->mlinks->name);
|
||||||
|
|
||||||
@ -1257,21 +1233,9 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
|
|||||||
dbadd(mpage, mc);
|
dbadd(mpage, mc);
|
||||||
|
|
||||||
nextpage:
|
nextpage:
|
||||||
if (child_pid) {
|
if (mparse_wait(mp) != MANDOCLEVEL_OK) {
|
||||||
if (-1 == waitpid(child_pid, &status, 0)) {
|
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
say(mpage->mlinks->file, "&wait gunzip");
|
||||||
say(mpage->mlinks->file, "&wait gunzip");
|
|
||||||
} else if (WIFSIGNALED(status)) {
|
|
||||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
|
||||||
say(mpage->mlinks->file,
|
|
||||||
"gunzip died from signal %d",
|
|
||||||
WTERMSIG(status));
|
|
||||||
} else if (WEXITSTATUS(status)) {
|
|
||||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
|
||||||
say(mpage->mlinks->file,
|
|
||||||
"gunzip failed with code %d",
|
|
||||||
WEXITSTATUS(status));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ohash_delete(&strings);
|
ohash_delete(&strings);
|
||||||
ohash_delete(&names);
|
ohash_delete(&names);
|
||||||
@ -1329,6 +1293,8 @@ parse_cat(struct mpage *mpage, int fd)
|
|||||||
fopen(mpage->mlinks->file, "r") :
|
fopen(mpage->mlinks->file, "r") :
|
||||||
fdopen(fd, "r");
|
fdopen(fd, "r");
|
||||||
if (NULL == stream) {
|
if (NULL == stream) {
|
||||||
|
if (-1 != fd)
|
||||||
|
close(fd);
|
||||||
if (warnings)
|
if (warnings)
|
||||||
say(mpage->mlinks->file, "&fopen");
|
say(mpage->mlinks->file, "&fopen");
|
||||||
return;
|
return;
|
||||||
@ -1764,7 +1730,8 @@ putkeys(const struct mpage *mpage,
|
|||||||
if (TYPE_Nm & v) {
|
if (TYPE_Nm & v) {
|
||||||
htab = &names;
|
htab = &names;
|
||||||
v &= name_mask;
|
v &= name_mask;
|
||||||
name_mask &= ~NAME_FIRST;
|
if (v & NAME_FIRST)
|
||||||
|
name_mask &= ~NAME_FIRST;
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
say(mpage->mlinks->file,
|
say(mpage->mlinks->file,
|
||||||
"Adding name %*s", sz, cp);
|
"Adding name %*s", sz, cp);
|
||||||
@ -1772,7 +1739,7 @@ putkeys(const struct mpage *mpage,
|
|||||||
htab = &strings;
|
htab = &strings;
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
for (i = 0; i < mansearch_keymax; i++)
|
for (i = 0; i < mansearch_keymax; i++)
|
||||||
if (1 << i & v)
|
if ((uint64_t)1 << i & v)
|
||||||
say(mpage->mlinks->file,
|
say(mpage->mlinks->file,
|
||||||
"Adding key %s=%*s",
|
"Adding key %s=%*s",
|
||||||
mansearch_keynames[i], sz, cp);
|
mansearch_keynames[i], sz, cp);
|
||||||
@ -1939,7 +1906,7 @@ render_key(struct mchars *mc, struct str *key)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (write_utf8) {
|
if (write_utf8) {
|
||||||
if (0 == (u = mchars_spec2cp(mc, seq, len)))
|
if ((u = mchars_spec2cp(mc, seq, len)) <= 0)
|
||||||
continue;
|
continue;
|
||||||
cpp = utfbuf;
|
cpp = utfbuf;
|
||||||
if (0 == (sz = utf8(u, utfbuf)))
|
if (0 == (sz = utf8(u, utfbuf)))
|
||||||
@ -1981,6 +1948,21 @@ dbadd_mlink(const struct mlink *mlink)
|
|||||||
sqlite3_reset(stmts[STMT_INSERT_LINK]);
|
sqlite3_reset(stmts[STMT_INSERT_LINK]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbadd_mlink_name(const struct mlink *mlink)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
dbadd_mlink(mlink);
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, NAME_FILE & NAME_MASK);
|
||||||
|
SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, mlink->name);
|
||||||
|
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mlink->mpage->pageid);
|
||||||
|
SQL_STEP(stmts[STMT_INSERT_NAME]);
|
||||||
|
sqlite3_reset(stmts[STMT_INSERT_NAME]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush the current page's terms (and their bits) into the database.
|
* Flush the current page's terms (and their bits) into the database.
|
||||||
* Wrap the entire set of additions in a transaction to make sqlite be a
|
* Wrap the entire set of additions in a transaction to make sqlite be a
|
||||||
@ -2045,7 +2027,7 @@ dbadd(struct mpage *mpage, struct mchars *mc)
|
|||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, key->rendered);
|
SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, key->rendered);
|
||||||
SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, FORM_SRC == mpage->form);
|
SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, mpage->form);
|
||||||
SQL_STEP(stmts[STMT_INSERT_PAGE]);
|
SQL_STEP(stmts[STMT_INSERT_PAGE]);
|
||||||
mpage->pageid = sqlite3_last_insert_rowid(db);
|
mpage->pageid = sqlite3_last_insert_rowid(db);
|
||||||
sqlite3_reset(stmts[STMT_INSERT_PAGE]);
|
sqlite3_reset(stmts[STMT_INSERT_PAGE]);
|
||||||
@ -2342,7 +2324,7 @@ dbopen(int real)
|
|||||||
"PRAGMA synchronous = OFF", NULL, NULL, NULL)) {
|
"PRAGMA synchronous = OFF", NULL, NULL, NULL)) {
|
||||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||||
say(MANDOC_DB, "PRAGMA synchronous: %s",
|
say(MANDOC_DB, "PRAGMA synchronous: %s",
|
||||||
sqlite3_errmsg(db));
|
sqlite3_errmsg(db));
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -2373,7 +2355,7 @@ hash_free(void *p, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_basedir(const char *targetdir)
|
set_basedir(const char *targetdir, int report_baddir)
|
||||||
{
|
{
|
||||||
static char startdir[PATH_MAX];
|
static char startdir[PATH_MAX];
|
||||||
static int getcwd_status; /* 1 = ok, 2 = failure */
|
static int getcwd_status; /* 1 = ok, 2 = failure */
|
||||||
@ -2426,12 +2408,16 @@ set_basedir(const char *targetdir)
|
|||||||
* we can reliably check whether files are inside.
|
* we can reliably check whether files are inside.
|
||||||
*/
|
*/
|
||||||
if (NULL == realpath(targetdir, basedir)) {
|
if (NULL == realpath(targetdir, basedir)) {
|
||||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
if (report_baddir || errno != ENOENT) {
|
||||||
say("", "&%s: realpath", targetdir);
|
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||||
|
say("", "&%s: realpath", targetdir);
|
||||||
|
}
|
||||||
return(0);
|
return(0);
|
||||||
} else if (-1 == chdir(basedir)) {
|
} else if (-1 == chdir(basedir)) {
|
||||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
if (report_baddir || errno != ENOENT) {
|
||||||
say("", "&chdir");
|
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||||
|
say("", "&chdir");
|
||||||
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
chdir_status = 1;
|
chdir_status = 1;
|
||||||
|
11
manpage.c
11
manpage.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: manpage.c,v 1.7 2014/01/06 03:02:46 schwarze Exp $ */
|
/* $Id: manpage.c,v 1.9 2014/08/17 03:24:47 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -87,10 +87,11 @@ main(int argc, char *argv[])
|
|||||||
if (0 == argc)
|
if (0 == argc)
|
||||||
goto usage;
|
goto usage;
|
||||||
|
|
||||||
search.deftype = TYPE_Nm | TYPE_Nd;
|
search.outkey = "Nd";
|
||||||
|
search.argmode = ARG_EXPR;
|
||||||
|
|
||||||
manpath_parse(&paths, conf_file, defpaths, auxpaths);
|
manpath_parse(&paths, conf_file, defpaths, auxpaths);
|
||||||
ch = mansearch(&search, &paths, argc, argv, "Nd", &res, &sz);
|
ch = mansearch(&search, &paths, argc, argv, &res, &sz);
|
||||||
manpath_free(&paths);
|
manpath_free(&paths);
|
||||||
|
|
||||||
if (0 == ch)
|
if (0 == ch)
|
||||||
|
55
manpath.c
55
manpath.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: manpath.c,v 1.15 2014/04/23 21:06:41 schwarze Exp $ */
|
/* $Id: manpath.c,v 1.19 2014/11/27 00:30:40 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@ -15,9 +15,10 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -32,14 +33,14 @@
|
|||||||
#define MAN_CONF_FILE "/etc/man.conf"
|
#define MAN_CONF_FILE "/etc/man.conf"
|
||||||
#define MAN_CONF_KEY "_whatdb"
|
#define MAN_CONF_KEY "_whatdb"
|
||||||
|
|
||||||
static void manpath_add(struct manpaths *, const char *);
|
static void manpath_add(struct manpaths *, const char *, int);
|
||||||
static void manpath_parseline(struct manpaths *, char *);
|
static void manpath_parseline(struct manpaths *, char *, int);
|
||||||
|
|
||||||
void
|
void
|
||||||
manpath_parse(struct manpaths *dirs, const char *file,
|
manpath_parse(struct manpaths *dirs, const char *file,
|
||||||
char *defp, char *auxp)
|
char *defp, char *auxp)
|
||||||
{
|
{
|
||||||
#ifdef USE_MANPATH
|
#if HAVE_MANPATH
|
||||||
char cmd[(PATH_MAX * 3) + 20];
|
char cmd[(PATH_MAX * 3) + 20];
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -79,7 +80,7 @@ manpath_parse(struct manpaths *dirs, const char *file,
|
|||||||
if ( ! ferror(stream) && feof(stream) &&
|
if ( ! ferror(stream) && feof(stream) &&
|
||||||
bsz && '\n' == buf[bsz - 1]) {
|
bsz && '\n' == buf[bsz - 1]) {
|
||||||
buf[bsz - 1] = '\0';
|
buf[bsz - 1] = '\0';
|
||||||
manpath_parseline(dirs, buf);
|
manpath_parseline(dirs, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
@ -88,11 +89,11 @@ manpath_parse(struct manpaths *dirs, const char *file,
|
|||||||
char *insert;
|
char *insert;
|
||||||
|
|
||||||
/* Always prepend -m. */
|
/* Always prepend -m. */
|
||||||
manpath_parseline(dirs, auxp);
|
manpath_parseline(dirs, auxp, 1);
|
||||||
|
|
||||||
/* If -M is given, it overrides everything else. */
|
/* If -M is given, it overrides everything else. */
|
||||||
if (NULL != defp) {
|
if (NULL != defp) {
|
||||||
manpath_parseline(dirs, defp);
|
manpath_parseline(dirs, defp, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,13 +111,13 @@ manpath_parse(struct manpaths *dirs, const char *file,
|
|||||||
/* Prepend man.conf(5) to MANPATH. */
|
/* Prepend man.conf(5) to MANPATH. */
|
||||||
if (':' == defp[0]) {
|
if (':' == defp[0]) {
|
||||||
manpath_manconf(dirs, file);
|
manpath_manconf(dirs, file);
|
||||||
manpath_parseline(dirs, defp);
|
manpath_parseline(dirs, defp, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append man.conf(5) to MANPATH. */
|
/* Append man.conf(5) to MANPATH. */
|
||||||
if (':' == defp[strlen(defp) - 1]) {
|
if (':' == defp[strlen(defp) - 1]) {
|
||||||
manpath_parseline(dirs, defp);
|
manpath_parseline(dirs, defp, 0);
|
||||||
manpath_manconf(dirs, file);
|
manpath_manconf(dirs, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -125,14 +126,14 @@ manpath_parse(struct manpaths *dirs, const char *file,
|
|||||||
insert = strstr(defp, "::");
|
insert = strstr(defp, "::");
|
||||||
if (NULL != insert) {
|
if (NULL != insert) {
|
||||||
*insert++ = '\0';
|
*insert++ = '\0';
|
||||||
manpath_parseline(dirs, defp);
|
manpath_parseline(dirs, defp, 0);
|
||||||
manpath_manconf(dirs, file);
|
manpath_manconf(dirs, file);
|
||||||
manpath_parseline(dirs, insert + 1);
|
manpath_parseline(dirs, insert + 1, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MANPATH overrides man.conf(5) completely. */
|
/* MANPATH overrides man.conf(5) completely. */
|
||||||
manpath_parseline(dirs, defp);
|
manpath_parseline(dirs, defp, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ manpath_parse(struct manpaths *dirs, const char *file,
|
|||||||
* Parse a FULL pathname from a colon-separated list of arrays.
|
* Parse a FULL pathname from a colon-separated list of arrays.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
manpath_parseline(struct manpaths *dirs, char *path)
|
manpath_parseline(struct manpaths *dirs, char *path, int complain)
|
||||||
{
|
{
|
||||||
char *dir;
|
char *dir;
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ manpath_parseline(struct manpaths *dirs, char *path)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
|
for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
|
||||||
manpath_add(dirs, dir);
|
manpath_add(dirs, dir, complain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -156,19 +157,33 @@ manpath_parseline(struct manpaths *dirs, char *path)
|
|||||||
* Grow the array one-by-one for simplicity's sake.
|
* Grow the array one-by-one for simplicity's sake.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
manpath_add(struct manpaths *dirs, const char *dir)
|
manpath_add(struct manpaths *dirs, const char *dir, int complain)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
struct stat sb;
|
||||||
char *cp;
|
char *cp;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (NULL == (cp = realpath(dir, buf)))
|
if (NULL == (cp = realpath(dir, buf))) {
|
||||||
|
if (complain) {
|
||||||
|
fputs("manpath: ", stderr);
|
||||||
|
perror(dir);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < dirs->sz; i++)
|
for (i = 0; i < dirs->sz; i++)
|
||||||
if (0 == strcmp(dirs->paths[i], dir))
|
if (0 == strcmp(dirs->paths[i], dir))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (stat(cp, &sb) == -1) {
|
||||||
|
if (complain) {
|
||||||
|
fputs("manpath: ", stderr);
|
||||||
|
perror(dir);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dirs->paths = mandoc_reallocarray(dirs->paths,
|
dirs->paths = mandoc_reallocarray(dirs->paths,
|
||||||
dirs->sz + 1, sizeof(char *));
|
dirs->sz + 1, sizeof(char *));
|
||||||
|
|
||||||
@ -215,7 +230,7 @@ manpath_manconf(struct manpaths *dirs, const char *file)
|
|||||||
if (NULL == (q = strrchr(p, '/')))
|
if (NULL == (q = strrchr(p, '/')))
|
||||||
continue;
|
continue;
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
manpath_add(dirs, p);
|
manpath_add(dirs, p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
|
104
mansearch.c
104
mansearch.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mansearch.c,v 1.42 2014/08/09 14:24:53 schwarze Exp $ */
|
/* $Id: mansearch.c,v 1.51 2014/11/27 01:58:21 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,11 +15,11 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef HAVE_OHASH
|
#if HAVE_OHASH
|
||||||
#include <ohash.h>
|
#include <ohash.h>
|
||||||
#else
|
#else
|
||||||
#include "compat_ohash.h"
|
#include "compat_ohash.h"
|
||||||
@ -79,8 +79,9 @@ struct expr {
|
|||||||
|
|
||||||
struct match {
|
struct match {
|
||||||
uint64_t pageid; /* identifier in database */
|
uint64_t pageid; /* identifier in database */
|
||||||
|
uint64_t bits; /* name type mask */
|
||||||
char *desc; /* manual page description */
|
char *desc; /* manual page description */
|
||||||
int form; /* 0 == catpage */
|
int form; /* bit field: formatted, zipped? */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void buildnames(struct manpage *, sqlite3 *,
|
static void buildnames(struct manpage *, sqlite3 *,
|
||||||
@ -159,7 +160,6 @@ int
|
|||||||
mansearch(const struct mansearch *search,
|
mansearch(const struct mansearch *search,
|
||||||
const struct manpaths *paths,
|
const struct manpaths *paths,
|
||||||
int argc, char *argv[],
|
int argc, char *argv[],
|
||||||
const char *outkey,
|
|
||||||
struct manpage **res, size_t *sz)
|
struct manpage **res, size_t *sz)
|
||||||
{
|
{
|
||||||
int fd, rc, c, indexbit;
|
int fd, rc, c, indexbit;
|
||||||
@ -195,11 +195,11 @@ mansearch(const struct mansearch *search,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
outbit = 0;
|
outbit = 0;
|
||||||
if (NULL != outkey) {
|
if (NULL != search->outkey) {
|
||||||
for (indexbit = 0, iterbit = 1;
|
for (indexbit = 0, iterbit = 1;
|
||||||
indexbit < mansearch_keymax;
|
indexbit < mansearch_keymax;
|
||||||
indexbit++, iterbit <<= 1) {
|
indexbit++, iterbit <<= 1) {
|
||||||
if (0 == strcasecmp(outkey,
|
if (0 == strcasecmp(search->outkey,
|
||||||
mansearch_keynames[indexbit])) {
|
mansearch_keynames[indexbit])) {
|
||||||
outbit = iterbit;
|
outbit = iterbit;
|
||||||
break;
|
break;
|
||||||
@ -302,6 +302,7 @@ mansearch(const struct mansearch *search,
|
|||||||
mp = mandoc_calloc(1, sizeof(struct match));
|
mp = mandoc_calloc(1, sizeof(struct match));
|
||||||
mp->pageid = pageid;
|
mp->pageid = pageid;
|
||||||
mp->form = sqlite3_column_int(s, 1);
|
mp->form = sqlite3_column_int(s, 1);
|
||||||
|
mp->bits = sqlite3_column_int64(s, 3);
|
||||||
if (TYPE_Nd == outbit)
|
if (TYPE_Nd == outbit)
|
||||||
mp->desc = mandoc_strdup((const char *)
|
mp->desc = mandoc_strdup((const char *)
|
||||||
sqlite3_column_text(s, 0));
|
sqlite3_column_text(s, 0));
|
||||||
@ -336,6 +337,8 @@ mansearch(const struct mansearch *search,
|
|||||||
maxres, sizeof(struct manpage));
|
maxres, sizeof(struct manpage));
|
||||||
}
|
}
|
||||||
mpage = *res + cur;
|
mpage = *res + cur;
|
||||||
|
mpage->ipath = i;
|
||||||
|
mpage->bits = mp->bits;
|
||||||
mpage->sec = 10;
|
mpage->sec = 10;
|
||||||
mpage->form = mp->form;
|
mpage->form = mp->form;
|
||||||
buildnames(mpage, db, s, mp->pageid,
|
buildnames(mpage, db, s, mp->pageid,
|
||||||
@ -352,6 +355,14 @@ mansearch(const struct mansearch *search,
|
|||||||
sqlite3_finalize(s2);
|
sqlite3_finalize(s2);
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
ohash_delete(&htab);
|
ohash_delete(&htab);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In man(1) mode, prefer matches in earlier trees
|
||||||
|
* over matches in later trees.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (cur && search->firstmatch)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
|
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
|
||||||
rc = 1;
|
rc = 1;
|
||||||
@ -367,6 +378,19 @@ mansearch(const struct mansearch *search,
|
|||||||
return(rc);
|
return(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mansearch_free(struct manpage *res, size_t sz)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++) {
|
||||||
|
free(res[i].file);
|
||||||
|
free(res[i].names);
|
||||||
|
free(res[i].output);
|
||||||
|
}
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
manpage_compare(const void *vp1, const void *vp2)
|
manpage_compare(const void *vp1, const void *vp2)
|
||||||
{
|
{
|
||||||
@ -375,8 +399,9 @@ manpage_compare(const void *vp1, const void *vp2)
|
|||||||
|
|
||||||
mp1 = vp1;
|
mp1 = vp1;
|
||||||
mp2 = vp2;
|
mp2 = vp2;
|
||||||
diff = mp1->sec - mp2->sec;
|
return( (diff = mp2->bits - mp1->bits) ? diff :
|
||||||
return(diff ? diff : strcasecmp(mp1->names, mp2->names));
|
(diff = mp1->sec - mp2->sec) ? diff :
|
||||||
|
strcasecmp(mp1->names, mp2->names));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -447,28 +472,28 @@ buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
|
|||||||
|
|
||||||
/* Also save the first file name encountered. */
|
/* Also save the first file name encountered. */
|
||||||
|
|
||||||
if (NULL != mpage->file)
|
if (mpage->file != NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (form) {
|
if (form & FORM_SRC) {
|
||||||
sep1 = "man";
|
sep1 = "man";
|
||||||
fsec = sec;
|
fsec = sec;
|
||||||
} else {
|
} else {
|
||||||
sep1 = "cat";
|
sep1 = "cat";
|
||||||
fsec = "0";
|
fsec = "0";
|
||||||
}
|
}
|
||||||
sep2 = '\0' == *arch ? "" : "/";
|
sep2 = *arch == '\0' ? "" : "/";
|
||||||
mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
|
mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
|
||||||
path, sep1, sec, sep2, arch, name, fsec);
|
path, sep1, sec, sep2, arch, name, fsec);
|
||||||
}
|
}
|
||||||
if (SQLITE_DONE != c)
|
if (c != SQLITE_DONE)
|
||||||
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
sqlite3_reset(s);
|
sqlite3_reset(s);
|
||||||
|
|
||||||
/* Append one final section to the names. */
|
/* Append one final section to the names. */
|
||||||
|
|
||||||
if (NULL != prevsec) {
|
if (prevsec != NULL) {
|
||||||
sep2 = '\0' == *prevarch ? "" : "/";
|
sep2 = *prevarch == '\0' ? "" : "/";
|
||||||
mandoc_asprintf(&newnames, "%s(%s%s%s)",
|
mandoc_asprintf(&newnames, "%s(%s%s%s)",
|
||||||
mpage->names, prevsec, sep2, prevarch);
|
mpage->names, prevsec, sep2, prevarch);
|
||||||
free(mpage->names);
|
free(mpage->names);
|
||||||
@ -566,8 +591,10 @@ sql_statement(const struct expr *e)
|
|||||||
size_t sz;
|
size_t sz;
|
||||||
int needop;
|
int needop;
|
||||||
|
|
||||||
sql = mandoc_strdup(
|
sql = mandoc_strdup(e->equal ?
|
||||||
"SELECT desc, form, pageid FROM mpages WHERE ");
|
"SELECT desc, form, pageid, bits "
|
||||||
|
"FROM mpages NATURAL JOIN names WHERE " :
|
||||||
|
"SELECT desc, form, pageid, 0 FROM mpages WHERE ");
|
||||||
sz = strlen(sql);
|
sz = strlen(sql);
|
||||||
|
|
||||||
for (needop = 0; NULL != e; e = e->next) {
|
for (needop = 0; NULL != e; e = e->next) {
|
||||||
@ -587,8 +614,7 @@ sql_statement(const struct expr *e)
|
|||||||
? "pageid IN (SELECT pageid FROM names "
|
? "pageid IN (SELECT pageid FROM names "
|
||||||
"WHERE name REGEXP ?)"
|
"WHERE name REGEXP ?)"
|
||||||
: e->equal
|
: e->equal
|
||||||
? "pageid IN (SELECT pageid FROM names "
|
? "name = ? "
|
||||||
"WHERE name = ?)"
|
|
||||||
: "pageid IN (SELECT pageid FROM names "
|
: "pageid IN (SELECT pageid FROM names "
|
||||||
"WHERE name MATCH ?)")
|
"WHERE name MATCH ?)")
|
||||||
: (NULL == e->substr
|
: (NULL == e->substr
|
||||||
@ -739,35 +765,30 @@ exprterm(const struct mansearch *search, char *buf, int cs)
|
|||||||
|
|
||||||
e = mandoc_calloc(1, sizeof(struct expr));
|
e = mandoc_calloc(1, sizeof(struct expr));
|
||||||
|
|
||||||
if (MANSEARCH_MAN & search->flags) {
|
if (search->argmode == ARG_NAME) {
|
||||||
e->bits = search->deftype;
|
e->bits = TYPE_Nm;
|
||||||
e->substr = buf;
|
e->substr = buf;
|
||||||
e->equal = 1;
|
e->equal = 1;
|
||||||
return(e);
|
return(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for an '=' or '~' operator,
|
* Separate macro keys from search string.
|
||||||
* unless forced to some fixed macro keys.
|
* If needed, request regular expression handling
|
||||||
|
* by setting e->substr to NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (MANSEARCH_WHATIS & search->flags)
|
if (search->argmode == ARG_WORD) {
|
||||||
val = NULL;
|
e->bits = TYPE_Nm;
|
||||||
else
|
e->substr = NULL;
|
||||||
val = strpbrk(buf, "=~");
|
mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
|
||||||
|
cs = 0;
|
||||||
if (NULL == val) {
|
} else if ((val = strpbrk(buf, "=~")) == NULL) {
|
||||||
e->bits = search->deftype;
|
e->bits = TYPE_Nm | TYPE_Nd;
|
||||||
e->substr = buf;
|
e->substr = buf;
|
||||||
|
|
||||||
/*
|
|
||||||
* Found an operator.
|
|
||||||
* Regexp search is requested by !e->substr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (val == buf)
|
if (val == buf)
|
||||||
e->bits = search->deftype;
|
e->bits = TYPE_Nm | TYPE_Nd;
|
||||||
if ('=' == *val)
|
if ('=' == *val)
|
||||||
e->substr = val + 1;
|
e->substr = val + 1;
|
||||||
*val++ = '\0';
|
*val++ = '\0';
|
||||||
@ -777,15 +798,10 @@ exprterm(const struct mansearch *search, char *buf, int cs)
|
|||||||
|
|
||||||
/* Compile regular expressions. */
|
/* Compile regular expressions. */
|
||||||
|
|
||||||
if (MANSEARCH_WHATIS & search->flags) {
|
|
||||||
e->substr = NULL;
|
|
||||||
mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == e->substr) {
|
if (NULL == e->substr) {
|
||||||
irc = regcomp(&e->regexp, val,
|
irc = regcomp(&e->regexp, val,
|
||||||
REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
|
REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
|
||||||
if (MANSEARCH_WHATIS & search->flags)
|
if (search->argmode == ARG_WORD)
|
||||||
free(val);
|
free(val);
|
||||||
if (irc) {
|
if (irc) {
|
||||||
regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
|
regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
|
||||||
|
36
mansearch.h
36
mansearch.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mansearch.h,v 1.15 2014/07/24 20:30:45 schwarze Exp $ */
|
/* $Id: mansearch.h,v 1.21 2014/11/27 01:58:21 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -62,18 +62,29 @@
|
|||||||
#define TYPE_Nd 0x0000008000000000ULL
|
#define TYPE_Nd 0x0000008000000000ULL
|
||||||
|
|
||||||
#define NAME_SYN 0x0000004000000001ULL
|
#define NAME_SYN 0x0000004000000001ULL
|
||||||
#define NAME_FILE 0x0000004000000002ULL
|
#define NAME_FIRST 0x0000004000000004ULL
|
||||||
#define NAME_TITLE 0x000000400000000cULL
|
#define NAME_TITLE 0x0000004000000006ULL
|
||||||
#define NAME_FIRST 0x0000004000000008ULL
|
#define NAME_HEAD 0x0000004000000008ULL
|
||||||
#define NAME_HEAD 0x0000004000000010ULL
|
#define NAME_FILE 0x0000004000000010ULL
|
||||||
#define NAME_MASK 0x000000000000001fULL
|
#define NAME_MASK 0x000000000000001fULL
|
||||||
|
|
||||||
__BEGIN_DECLS
|
#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 argmode {
|
||||||
|
ARG_FILE = 0,
|
||||||
|
ARG_NAME,
|
||||||
|
ARG_WORD,
|
||||||
|
ARG_EXPR
|
||||||
|
};
|
||||||
|
|
||||||
struct manpage {
|
struct manpage {
|
||||||
char *file; /* to be prefixed by manpath */
|
char *file; /* to be prefixed by manpath */
|
||||||
char *names; /* a list of names with sections */
|
char *names; /* a list of names with sections */
|
||||||
char *output; /* user-defined additional output */
|
char *output; /* user-defined additional output */
|
||||||
|
size_t ipath; /* number of the manpath */
|
||||||
|
uint64_t bits; /* name type mask */
|
||||||
int sec; /* section number, 10 means invalid */
|
int sec; /* section number, 10 means invalid */
|
||||||
int form; /* 0 == catpage */
|
int form; /* 0 == catpage */
|
||||||
};
|
};
|
||||||
@ -81,21 +92,22 @@ struct manpage {
|
|||||||
struct mansearch {
|
struct mansearch {
|
||||||
const char *arch; /* architecture/NULL */
|
const char *arch; /* architecture/NULL */
|
||||||
const char *sec; /* mansection/NULL */
|
const char *sec; /* mansection/NULL */
|
||||||
uint64_t deftype; /* type if no key */
|
const char *outkey; /* show content of this macro */
|
||||||
int flags;
|
enum argmode argmode; /* interpretation of arguments */
|
||||||
#define MANSEARCH_WHATIS 0x01 /* whatis(1) mode: whole words, no keys */
|
int firstmatch; /* first matching database only */
|
||||||
#define MANSEARCH_MAN 0x02 /* man(1) mode: string equality, no keys */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
int mansearch_setup(int);
|
int mansearch_setup(int);
|
||||||
int mansearch(const struct mansearch *cfg, /* options */
|
int mansearch(const struct mansearch *cfg, /* options */
|
||||||
const struct manpaths *paths, /* manpaths */
|
const struct manpaths *paths, /* manpaths */
|
||||||
int argc, /* size of argv */
|
int argc, /* size of argv */
|
||||||
char *argv[], /* search terms */
|
char *argv[], /* search terms */
|
||||||
const char *outkey, /* name of additional output key */
|
|
||||||
struct manpage **res, /* results */
|
struct manpage **res, /* results */
|
||||||
size_t *ressz); /* results returned */
|
size_t *ressz); /* results returned */
|
||||||
|
void mansearch_free(struct manpage *, size_t);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif /*!MANSEARCH_H*/
|
#endif /* MANSEARCH_H */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mansearch_const.c,v 1.5 2014/08/09 14:05:21 schwarze Exp $ */
|
/* $Id: mansearch_const.c,v 1.6 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -14,11 +14,10 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "manpath.h"
|
#include "manpath.h"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mchars_alloc.3,v 1.1 2014/08/05 05:48:56 schwarze Exp $
|
.\" $Id: mchars_alloc.3,v 1.2 2014/10/26 18:07:28 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 5 2014 $
|
.Dd $Mdocdate: October 26 2014 $
|
||||||
.Dt MCHARS_ALLOC 3
|
.Dt MCHARS_ALLOC 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -59,6 +59,8 @@
|
|||||||
.Fa "size_t sz"
|
.Fa "size_t sz"
|
||||||
.Fa "size_t *rsz"
|
.Fa "size_t *rsz"
|
||||||
.Fc
|
.Fc
|
||||||
|
.Ft "const char *"
|
||||||
|
.Fn mchars_uc2str "int codepoint"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
These functions translate Unicode character numbers and
|
These functions translate Unicode character numbers and
|
||||||
.Xr roff 7
|
.Xr roff 7
|
||||||
@ -199,6 +201,14 @@ output module use this function to render
|
|||||||
and
|
and
|
||||||
.Ic \eC\(aq Ns Ar name Ns Ic \(aq
|
.Ic \eC\(aq Ns Ar name Ns Ic \(aq
|
||||||
escape sequences.
|
escape sequences.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mchars_uc2str
|
||||||
|
performs a reverse lookup of the Unicode
|
||||||
|
.Fa codepoint
|
||||||
|
and returns an ASCII string representation, or the string
|
||||||
|
.Qq <?>
|
||||||
|
if none is available.
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
These funtions are implemented in the file
|
These funtions are implemented in the file
|
||||||
.Pa chars.c .
|
.Pa chars.c .
|
||||||
@ -218,6 +228,7 @@ following mandoc versions:
|
|||||||
.It Fn mchars_num2uc Ta 1.11.3 Ta \(em Ta \(em
|
.It Fn mchars_num2uc Ta 1.11.3 Ta \(em Ta \(em
|
||||||
.It Fn mchars_spec2cp Ta 1.11.2 Ta Fn chars_spec2cp Ta 1.10.5
|
.It Fn mchars_spec2cp Ta 1.11.2 Ta Fn chars_spec2cp Ta 1.10.5
|
||||||
.It Fn mchars_spec2str Ta 1.11.2 Ta Fn a2ascii Ta 1.5.3
|
.It Fn mchars_spec2str Ta 1.11.2 Ta Fn a2ascii Ta 1.5.3
|
||||||
|
.It Fn mchars_uc2str Ta 1.13.2 Ta \(em Ta \(em
|
||||||
.El
|
.El
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
175
mdoc.7
175
mdoc.7
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mdoc.7,v 1.234 2014/08/08 16:38:06 schwarze Exp $
|
.\" $Id: mdoc.7,v 1.244 2014/11/28 18:36:35 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" 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 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 8 2014 $
|
.Dd $Mdocdate: November 28 2014 $
|
||||||
.Dt MDOC 7
|
.Dt MDOC 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -388,7 +388,7 @@ See
|
|||||||
References other manuals with related topics.
|
References other manuals with related topics.
|
||||||
This section should exist for most manuals.
|
This section should exist for most manuals.
|
||||||
Cross-references should conventionally be ordered first by section, then
|
Cross-references should conventionally be ordered first by section, then
|
||||||
alphabetically.
|
alphabetically (ignoring case).
|
||||||
.Pp
|
.Pp
|
||||||
References to other documentation concerning the topic of the manual page,
|
References to other documentation concerning the topic of the manual page,
|
||||||
for example authoritative books or journal articles, may also be
|
for example authoritative books or journal articles, may also be
|
||||||
@ -433,7 +433,7 @@ in the alphabetical
|
|||||||
.Ss Document preamble and NAME section macros
|
.Ss Document preamble and NAME section macros
|
||||||
.Bl -column "Brq, Bro, Brc" description
|
.Bl -column "Brq, Bro, Brc" description
|
||||||
.It Sx \&Dd Ta document date: Cm $\&Mdocdate$ | Ar month day , year
|
.It Sx \&Dd Ta document date: Cm $\&Mdocdate$ | Ar month day , year
|
||||||
.It Sx \&Dt Ta document title: Ar TITLE section Op Ar volume | arch
|
.It Sx \&Dt Ta document title: Ar TITLE section Op Ar arch
|
||||||
.It Sx \&Os Ta operating system version: Op Ar system Op Ar version
|
.It Sx \&Os Ta operating system version: Op Ar system Op Ar version
|
||||||
.It Sx \&Nm Ta document name (one argument)
|
.It Sx \&Nm Ta document name (one argument)
|
||||||
.It Sx \&Nd Ta document description (one line)
|
.It Sx \&Nd Ta document description (one line)
|
||||||
@ -937,8 +937,11 @@ The
|
|||||||
.Fl width
|
.Fl width
|
||||||
and
|
and
|
||||||
.Fl offset
|
.Fl offset
|
||||||
arguments accept scaling widths as described in
|
arguments accept macro names as described for
|
||||||
.Xr roff 7
|
.Sx \&Bd
|
||||||
|
.Fl offset ,
|
||||||
|
scaling widths as described in
|
||||||
|
.Xr roff 7 ,
|
||||||
or use the length of the given string.
|
or use the length of the given string.
|
||||||
The
|
The
|
||||||
.Fl offset
|
.Fl offset
|
||||||
@ -1182,13 +1185,12 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Dl .
|
.Sx \&Dl .
|
||||||
.Ss \&Db
|
.Ss \&Db
|
||||||
Switch debugging mode.
|
This macro is obsolete.
|
||||||
Its syntax is as follows:
|
No replacement is needed.
|
||||||
.Pp
|
It is ignored by
|
||||||
.D1 Pf \. Sx \&Db Cm on | off
|
.Xr mandoc 1
|
||||||
.Pp
|
and groff including its arguments.
|
||||||
This macro is ignored by
|
It was formerly used to toggle a debugging mode.
|
||||||
.Xr mandoc 1 .
|
|
||||||
.Ss \&Dc
|
.Ss \&Dc
|
||||||
Close a
|
Close a
|
||||||
.Sx \&Do
|
.Sx \&Do
|
||||||
@ -1245,7 +1247,7 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Os .
|
.Sx \&Os .
|
||||||
.Ss \&Dl
|
.Ss \&Dl
|
||||||
One-line intended display.
|
One-line indented display.
|
||||||
This is formatted as literal text and is useful for commands and
|
This is formatted as literal text and is useful for commands and
|
||||||
invocations.
|
invocations.
|
||||||
It is followed by a newline.
|
It is followed by a newline.
|
||||||
@ -1297,7 +1299,7 @@ Its syntax is as follows:
|
|||||||
.Pf \. Sx \&Dt
|
.Pf \. Sx \&Dt
|
||||||
.Ar TITLE
|
.Ar TITLE
|
||||||
.Ar section
|
.Ar section
|
||||||
.Op Ar volume | arch
|
.Op Ar arch
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
Its arguments are as follows:
|
Its arguments are as follows:
|
||||||
@ -1346,35 +1348,6 @@ or
|
|||||||
.Pq paper .
|
.Pq paper .
|
||||||
It should correspond to the manual's filename suffix and defaults to
|
It should correspond to the manual's filename suffix and defaults to
|
||||||
the empty string if unspecified.
|
the empty string if unspecified.
|
||||||
.It Ar volume
|
|
||||||
This overrides the volume inferred from
|
|
||||||
.Ar section .
|
|
||||||
This field is optional, and if specified, must be one of
|
|
||||||
.Cm USD
|
|
||||||
.Pq users' supplementary documents ,
|
|
||||||
.Cm PS1
|
|
||||||
.Pq programmers' supplementary documents ,
|
|
||||||
.Cm AMD
|
|
||||||
.Pq administrators' supplementary documents ,
|
|
||||||
.Cm SMM
|
|
||||||
.Pq system managers' manuals ,
|
|
||||||
.Cm URM
|
|
||||||
.Pq users' reference manuals ,
|
|
||||||
.Cm PRM
|
|
||||||
.Pq programmers' reference manuals ,
|
|
||||||
.Cm KM
|
|
||||||
.Pq kernel manuals ,
|
|
||||||
.Cm IND
|
|
||||||
.Pq master index ,
|
|
||||||
.Cm MMI
|
|
||||||
.Pq master index ,
|
|
||||||
.Cm LOCAL
|
|
||||||
.Pq local manuals ,
|
|
||||||
.Cm LOC
|
|
||||||
.Pq local manuals ,
|
|
||||||
or
|
|
||||||
.Cm CON
|
|
||||||
.Pq contributed manuals .
|
|
||||||
.It Ar arch
|
.It Ar arch
|
||||||
This specifies the machine architecture a manual page applies to,
|
This specifies the machine architecture a manual page applies to,
|
||||||
where relevant, for example
|
where relevant, for example
|
||||||
@ -1383,17 +1356,11 @@ where relevant, for example
|
|||||||
.Cm i386 ,
|
.Cm i386 ,
|
||||||
or
|
or
|
||||||
.Cm sparc64 .
|
.Cm sparc64 .
|
||||||
The list of supported architectures varies by operating system.
|
The list of valid architectures varies by operating system.
|
||||||
For the full list of all architectures recognized by
|
|
||||||
.Xr mandoc 1 ,
|
|
||||||
see the file
|
|
||||||
.Pa arch.in
|
|
||||||
in the source distribution.
|
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Examples:
|
Examples:
|
||||||
.Dl \&.Dt FOO 1
|
.Dl \&.Dt FOO 1
|
||||||
.Dl \&.Dt FOO 4 KM
|
|
||||||
.Dl \&.Dt FOO 9 i386
|
.Dl \&.Dt FOO 9 i386
|
||||||
.Pp
|
.Pp
|
||||||
See also
|
See also
|
||||||
@ -1467,16 +1434,29 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&It .
|
.Sx \&It .
|
||||||
.Ss \&Em
|
.Ss \&Em
|
||||||
Denotes text that should be
|
Request an italic font.
|
||||||
.Em emphasised .
|
If the output device does not provide that, underline.
|
||||||
Note that this is a presentation term and should not be used for
|
.Pp
|
||||||
stylistically decorating technical terms.
|
This is most often used for stress emphasis (not to be confused with
|
||||||
Depending on the output device, this is usually represented
|
importance, see
|
||||||
using an italic font or underlined characters.
|
.Sx \&Sy ) .
|
||||||
|
In the rare cases where none of the semantic markup macros fit,
|
||||||
|
it can also be used for technical terms and placeholders, except
|
||||||
|
that for syntax elements,
|
||||||
|
.Sx \&Sy
|
||||||
|
and
|
||||||
|
.Sx \&Ar
|
||||||
|
are preferred, respectively.
|
||||||
.Pp
|
.Pp
|
||||||
Examples:
|
Examples:
|
||||||
.Dl \&.Em Warnings!
|
.Bd -literal -compact -offset indent
|
||||||
.Dl \&.Em Remarks :
|
Selected lines are those
|
||||||
|
\&.Em not
|
||||||
|
matching any of the specified patterns.
|
||||||
|
Some of the functions use a
|
||||||
|
\&.Em hold space
|
||||||
|
to save the pattern space for subsequent retrieval.
|
||||||
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
See also
|
See also
|
||||||
.Sx \&Bf ,
|
.Sx \&Bf ,
|
||||||
@ -1557,7 +1537,7 @@ arguments are treated as separate utilities.
|
|||||||
See also
|
See also
|
||||||
.Sx \&Rv .
|
.Sx \&Rv .
|
||||||
.Ss \&Fa
|
.Ss \&Fa
|
||||||
Function argument.
|
Function argument or parameter.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Bd -ragged -offset indent
|
.Bd -ragged -offset indent
|
||||||
.Pf \. Sx \&Fa
|
.Pf \. Sx \&Fa
|
||||||
@ -2497,10 +2477,12 @@ Based on POSIX.1 and POSIX.2, published in 1992.
|
|||||||
.It Single UNIX Specification version 1 and related standards
|
.It Single UNIX Specification version 1 and related standards
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
|
.It \-susv1
|
||||||
|
.St -susv1
|
||||||
.It \-xpg4.2
|
.It \-xpg4.2
|
||||||
.St -xpg4.2
|
.St -xpg4.2
|
||||||
.br
|
.br
|
||||||
This standard was published in 1994 and is also called SUSv1.
|
This standard was published in 1994.
|
||||||
It was used as the basis for UNIX 95 certification.
|
It was used as the basis for UNIX 95 certification.
|
||||||
The following three refer to parts of it.
|
The following three refer to parts of it.
|
||||||
.Pp
|
.Pp
|
||||||
@ -2544,17 +2526,8 @@ The following refer to parts of it.
|
|||||||
.Pp
|
.Pp
|
||||||
.It \-xns5
|
.It \-xns5
|
||||||
.St -xns5
|
.St -xns5
|
||||||
.It \-xns5.2d2.0
|
|
||||||
.St -xns5.2d2.0
|
|
||||||
.It \-xns5.2
|
.It \-xns5.2
|
||||||
.St -xns5.2
|
.St -xns5.2
|
||||||
.Pp
|
|
||||||
.It \-p1387.2
|
|
||||||
.St -p1387.2
|
|
||||||
.It \-p1387.2-95
|
|
||||||
.St -p1387.2-95
|
|
||||||
.br
|
|
||||||
POSIX software administration.
|
|
||||||
.El
|
.El
|
||||||
.It Single UNIX Specification version 3 and related standards
|
.It Single UNIX Specification version 3 and related standards
|
||||||
.Pp
|
.Pp
|
||||||
@ -2564,16 +2537,6 @@ POSIX software administration.
|
|||||||
.br
|
.br
|
||||||
Additional real-time extensions.
|
Additional real-time extensions.
|
||||||
.Pp
|
.Pp
|
||||||
.It \-p1003.1j-2000
|
|
||||||
.St -p1003.1j-2000
|
|
||||||
.br
|
|
||||||
Advanced real-time extensions.
|
|
||||||
.Pp
|
|
||||||
.It \-p1003.1q-2000
|
|
||||||
.St -p1003.1q-2000
|
|
||||||
.br
|
|
||||||
Amendment 7: Tracing [C Language].
|
|
||||||
.Pp
|
|
||||||
.It \-p1003.1-2001
|
.It \-p1003.1-2001
|
||||||
.St -p1003.1-2001
|
.St -p1003.1-2001
|
||||||
.It \-susv3
|
.It \-susv3
|
||||||
@ -2593,8 +2556,10 @@ The second and last Technical Corrigendum.
|
|||||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
.It \-p1003.1-2008
|
.It \-p1003.1-2008
|
||||||
.St -p1003.1-2008
|
.St -p1003.1-2008
|
||||||
|
.It \-susv4
|
||||||
|
.St -susv4
|
||||||
.br
|
.br
|
||||||
This standard is also called SUSv4 and
|
This standard is also called
|
||||||
X/Open Portability Guide version 7.
|
X/Open Portability Guide version 7.
|
||||||
.Pp
|
.Pp
|
||||||
.It \-p1003.1-2013
|
.It \-p1003.1-2013
|
||||||
@ -2637,10 +2602,24 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Ss .
|
.Sx \&Ss .
|
||||||
.Ss \&Sy
|
.Ss \&Sy
|
||||||
Format enclosed arguments in symbolic
|
Request a boldface font.
|
||||||
.Pq Dq boldface .
|
.Pp
|
||||||
Note that this is a presentation term and should not be used for
|
This is most often used to indicate importance or seriousness (not to be
|
||||||
stylistically decorating technical terms.
|
confused with stress emphasis, see
|
||||||
|
.Sx \&Em ) .
|
||||||
|
When none of the semantic macros fit, it is also adequate for syntax
|
||||||
|
elements that have to be given or that appear verbatim.
|
||||||
|
.Pp
|
||||||
|
Examples:
|
||||||
|
.Bd -literal -compact -offset indent
|
||||||
|
\&.Sy Warning :
|
||||||
|
If
|
||||||
|
\&.Sy s
|
||||||
|
appears in the owner permissions, set-user-ID mode is set.
|
||||||
|
This utility replaces the former
|
||||||
|
\&.Sy dumpdir
|
||||||
|
program.
|
||||||
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
See also
|
See also
|
||||||
.Sx \&Bf ,
|
.Sx \&Bf ,
|
||||||
@ -2673,8 +2652,17 @@ A variable name.
|
|||||||
Examples:
|
Examples:
|
||||||
.Dl \&.Va foo
|
.Dl \&.Va foo
|
||||||
.Dl \&.Va const char *bar ;
|
.Dl \&.Va const char *bar ;
|
||||||
|
.Pp
|
||||||
|
For function arguments and parameters, use
|
||||||
|
.Sx \&Fa
|
||||||
|
instead.
|
||||||
|
For declarations of global variables in the
|
||||||
|
.Em SYNOPSIS
|
||||||
|
section, use
|
||||||
|
.Sx \&Vt .
|
||||||
.Ss \&Vt
|
.Ss \&Vt
|
||||||
A variable type.
|
A variable type.
|
||||||
|
.Pp
|
||||||
This is also used for indicating global variables in the
|
This is also used for indicating global variables in the
|
||||||
.Em SYNOPSIS
|
.Em SYNOPSIS
|
||||||
section, in which case a variable name is also specified.
|
section, in which case a variable name is also specified.
|
||||||
@ -2689,18 +2677,21 @@ In the former case, this macro starts a new output line,
|
|||||||
and a blank line is inserted in front if there is a preceding
|
and a blank line is inserted in front if there is a preceding
|
||||||
function definition or include directive.
|
function definition or include directive.
|
||||||
.Pp
|
.Pp
|
||||||
Note that this should not be confused with
|
|
||||||
.Sx \&Ft ,
|
|
||||||
which is used for function return types.
|
|
||||||
.Pp
|
|
||||||
Examples:
|
Examples:
|
||||||
.Dl \&.Vt unsigned char
|
.Dl \&.Vt unsigned char
|
||||||
.Dl \&.Vt extern const char * const sys_signame[] \&;
|
.Dl \&.Vt extern const char * const sys_signame[] \&;
|
||||||
.Pp
|
.Pp
|
||||||
|
For parameters in function prototypes, use
|
||||||
|
.Sx \&Fa
|
||||||
|
instead, for function return types
|
||||||
|
.Sx \&Ft ,
|
||||||
|
and for variable names outside the
|
||||||
|
.Em SYNOPSIS
|
||||||
|
section
|
||||||
|
.Sx \&Va ,
|
||||||
|
even when including a type with the name.
|
||||||
See also
|
See also
|
||||||
.Sx MANUAL STRUCTURE
|
.Sx MANUAL STRUCTURE .
|
||||||
and
|
|
||||||
.Sx \&Va .
|
|
||||||
.Ss \&Xc
|
.Ss \&Xc
|
||||||
Close a scope opened by
|
Close a scope opened by
|
||||||
.Sx \&Xo .
|
.Sx \&Xo .
|
||||||
|
229
mdoc.c
229
mdoc.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc.c,v 1.223 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: mdoc.c,v 1.233 2014/11/28 06:27:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -91,11 +89,7 @@ static void mdoc_free1(struct mdoc *);
|
|||||||
static void mdoc_alloc1(struct mdoc *);
|
static void mdoc_alloc1(struct mdoc *);
|
||||||
static struct mdoc_node *node_alloc(struct mdoc *, int, int,
|
static struct mdoc_node *node_alloc(struct mdoc *, int, int,
|
||||||
enum mdoct, enum mdoc_type);
|
enum mdoct, enum mdoc_type);
|
||||||
static int node_append(struct mdoc *,
|
static void node_append(struct mdoc *, struct mdoc_node *);
|
||||||
struct mdoc_node *);
|
|
||||||
#if 0
|
|
||||||
static int mdoc_preptext(struct mdoc *, int, char *, int);
|
|
||||||
#endif
|
|
||||||
static int mdoc_ptext(struct mdoc *, int, char *, int);
|
static int mdoc_ptext(struct mdoc *, int, char *, int);
|
||||||
static int mdoc_pmacro(struct mdoc *, int, char *, int);
|
static int mdoc_pmacro(struct mdoc *, int, char *, int);
|
||||||
|
|
||||||
@ -200,37 +194,32 @@ int
|
|||||||
mdoc_endparse(struct mdoc *mdoc)
|
mdoc_endparse(struct mdoc *mdoc)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(mdoc_macroend(mdoc));
|
mdoc_macroend(mdoc);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep)
|
mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep)
|
||||||
{
|
{
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
|
||||||
n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
|
n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
|
||||||
n->eqn = ep;
|
n->eqn = ep;
|
||||||
|
if (ep->ln > mdoc->last->line)
|
||||||
if ( ! node_append(mdoc, n))
|
n->flags |= MDOC_LINE;
|
||||||
return(0);
|
node_append(mdoc, n);
|
||||||
|
|
||||||
mdoc->next = MDOC_NEXT_SIBLING;
|
mdoc->next = MDOC_NEXT_SIBLING;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
|
mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
|
||||||
{
|
{
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
|
||||||
n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL);
|
n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL);
|
||||||
n->span = sp;
|
n->span = sp;
|
||||||
|
node_append(mdoc, n);
|
||||||
if ( ! node_append(mdoc, n))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
mdoc->next = MDOC_NEXT_SIBLING;
|
mdoc->next = MDOC_NEXT_SIBLING;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -241,7 +230,8 @@ int
|
|||||||
mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
|
mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
|
||||||
{
|
{
|
||||||
|
|
||||||
mdoc->flags |= MDOC_NEWLINE;
|
if (mdoc->last->type != MDOC_EQN || ln > mdoc->last->line)
|
||||||
|
mdoc->flags |= MDOC_NEWLINE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let the roff nS register switch SYNOPSIS mode early,
|
* Let the roff nS register switch SYNOPSIS mode early,
|
||||||
@ -259,7 +249,7 @@ mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
mdoc_ptext(mdoc, ln, buf, offs));
|
mdoc_ptext(mdoc, ln, buf, offs));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_macro(MACRO_PROT_ARGS)
|
mdoc_macro(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
assert(tok < MDOC_MAX);
|
assert(tok < MDOC_MAX);
|
||||||
@ -269,7 +259,7 @@ mdoc_macro(MACRO_PROT_ARGS)
|
|||||||
mandoc_vmsg(MANDOCERR_DT_LATE,
|
mandoc_vmsg(MANDOCERR_DT_LATE,
|
||||||
mdoc->parse, line, ppos,
|
mdoc->parse, line, ppos,
|
||||||
"Dt %s", buf + *pos);
|
"Dt %s", buf + *pos);
|
||||||
return(1);
|
return;
|
||||||
}
|
}
|
||||||
} else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) {
|
} else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) {
|
||||||
if (mdoc->meta.title == NULL) {
|
if (mdoc->meta.title == NULL) {
|
||||||
@ -282,12 +272,11 @@ mdoc_macro(MACRO_PROT_ARGS)
|
|||||||
mdoc->meta.vol = mandoc_strdup("LOCAL");
|
mdoc->meta.vol = mandoc_strdup("LOCAL");
|
||||||
mdoc->flags |= MDOC_PBODY;
|
mdoc->flags |= MDOC_PBODY;
|
||||||
}
|
}
|
||||||
|
(*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf);
|
||||||
return((*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -331,8 +320,7 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! mdoc_valid_pre(mdoc, p))
|
mdoc_valid_pre(mdoc, p);
|
||||||
return(0);
|
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case MDOC_HEAD:
|
case MDOC_HEAD:
|
||||||
@ -359,14 +347,11 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
case MDOC_TBL:
|
case MDOC_TBL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MDOC_TEXT:
|
case MDOC_TEXT:
|
||||||
if ( ! mdoc_valid_post(mdoc))
|
mdoc_valid_post(mdoc);
|
||||||
return(0);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mdoc_node *
|
static struct mdoc_node *
|
||||||
@ -396,46 +381,41 @@ node_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
||||||
{
|
{
|
||||||
struct mdoc_node *p;
|
struct mdoc_node *p;
|
||||||
|
|
||||||
p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL);
|
p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL);
|
||||||
if ( ! node_append(mdoc, p))
|
node_append(mdoc, p);
|
||||||
return(0);
|
|
||||||
mdoc->next = MDOC_NEXT_CHILD;
|
mdoc->next = MDOC_NEXT_CHILD;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
struct mdoc_node *
|
||||||
mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
||||||
{
|
{
|
||||||
struct mdoc_node *p;
|
struct mdoc_node *p;
|
||||||
|
|
||||||
assert(mdoc->first);
|
assert(mdoc->first);
|
||||||
assert(mdoc->last);
|
assert(mdoc->last);
|
||||||
|
|
||||||
p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD);
|
p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD);
|
||||||
if ( ! node_append(mdoc, p))
|
node_append(mdoc, p);
|
||||||
return(0);
|
|
||||||
mdoc->next = MDOC_NEXT_CHILD;
|
mdoc->next = MDOC_NEXT_CHILD;
|
||||||
return(1);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
struct mdoc_node *
|
||||||
mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
||||||
{
|
{
|
||||||
struct mdoc_node *p;
|
struct mdoc_node *p;
|
||||||
|
|
||||||
p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
|
p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
|
||||||
if ( ! node_append(mdoc, p))
|
node_append(mdoc, p);
|
||||||
return(0);
|
|
||||||
mdoc->next = MDOC_NEXT_CHILD;
|
mdoc->next = MDOC_NEXT_CHILD;
|
||||||
return(1);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
|
mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
|
||||||
struct mdoc_node *body, enum mdoc_endbody end)
|
struct mdoc_node *body, enum mdoc_endbody end)
|
||||||
{
|
{
|
||||||
@ -445,13 +425,11 @@ mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
|
|||||||
p->pending = body;
|
p->pending = body;
|
||||||
p->norm = body->norm;
|
p->norm = body->norm;
|
||||||
p->end = end;
|
p->end = end;
|
||||||
if ( ! node_append(mdoc, p))
|
node_append(mdoc, p);
|
||||||
return(0);
|
|
||||||
mdoc->next = MDOC_NEXT_SIBLING;
|
mdoc->next = MDOC_NEXT_SIBLING;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
struct mdoc_node *
|
||||||
mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
|
mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
|
||||||
enum mdoct tok, struct mdoc_arg *args)
|
enum mdoct tok, struct mdoc_arg *args)
|
||||||
{
|
{
|
||||||
@ -477,14 +455,12 @@ mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
node_append(mdoc, p);
|
||||||
if ( ! node_append(mdoc, p))
|
|
||||||
return(0);
|
|
||||||
mdoc->next = MDOC_NEXT_CHILD;
|
mdoc->next = MDOC_NEXT_CHILD;
|
||||||
return(1);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
|
mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
|
||||||
enum mdoct tok, struct mdoc_arg *args)
|
enum mdoct tok, struct mdoc_arg *args)
|
||||||
{
|
{
|
||||||
@ -502,26 +478,19 @@ mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
node_append(mdoc, p);
|
||||||
if ( ! node_append(mdoc, p))
|
|
||||||
return(0);
|
|
||||||
mdoc->next = MDOC_NEXT_CHILD;
|
mdoc->next = MDOC_NEXT_CHILD;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p)
|
mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p)
|
||||||
{
|
{
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
|
||||||
n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT);
|
n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT);
|
||||||
n->string = roff_strdup(mdoc->roff, p);
|
n->string = roff_strdup(mdoc->roff, p);
|
||||||
|
node_append(mdoc, n);
|
||||||
if ( ! node_append(mdoc, n))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
mdoc->next = MDOC_NEXT_SIBLING;
|
mdoc->next = MDOC_NEXT_SIBLING;
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -603,68 +572,14 @@ mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
mdoc_node_free(p);
|
mdoc_node_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p)
|
mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
mdoc_node_unlink(mdoc, p);
|
mdoc_node_unlink(mdoc, p);
|
||||||
return(node_append(mdoc, p));
|
node_append(mdoc, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* Pre-treat a text line.
|
|
||||||
* Text lines can consist of equations, which must be handled apart from
|
|
||||||
* the regular text.
|
|
||||||
* Thus, use this function to step through a line checking if it has any
|
|
||||||
* equations embedded in it.
|
|
||||||
* This must handle multiple equations AND equations that do not end at
|
|
||||||
* the end-of-line, i.e., will re-enter in the next roff parse.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
mdoc_preptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|
||||||
{
|
|
||||||
char *start, *end;
|
|
||||||
char delim;
|
|
||||||
|
|
||||||
while ('\0' != buf[offs]) {
|
|
||||||
/* Mark starting position if eqn is set. */
|
|
||||||
start = NULL;
|
|
||||||
if ('\0' != (delim = roff_eqndelim(mdoc->roff)))
|
|
||||||
if (NULL != (start = strchr(buf + offs, delim)))
|
|
||||||
*start++ = '\0';
|
|
||||||
|
|
||||||
/* Parse text as normal. */
|
|
||||||
if ( ! mdoc_ptext(mdoc, line, buf, offs))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* Continue only if an equation exists. */
|
|
||||||
if (NULL == start)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Read past the end of the equation. */
|
|
||||||
offs += start - (buf + offs);
|
|
||||||
assert(start == &buf[offs]);
|
|
||||||
if (NULL != (end = strchr(buf + offs, delim))) {
|
|
||||||
*end++ = '\0';
|
|
||||||
while (' ' == *end)
|
|
||||||
end++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the equation itself. */
|
|
||||||
roff_openeqn(mdoc->roff, NULL, line, offs, buf);
|
|
||||||
|
|
||||||
/* Process a finished equation? */
|
|
||||||
if (roff_closeeqn(mdoc->roff))
|
|
||||||
if ( ! mdoc_addeqn(mdoc, roff_eqn(mdoc->roff)))
|
|
||||||
return(0);
|
|
||||||
offs += (end - (buf + offs));
|
|
||||||
}
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse free-form text, that is, a line that does not begin with the
|
* Parse free-form text, that is, a line that does not begin with the
|
||||||
* control character.
|
* control character.
|
||||||
@ -689,7 +604,8 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
LIST_column == n->norm->Bl.type) {
|
LIST_column == n->norm->Bl.type) {
|
||||||
/* `Bl' is open without any children. */
|
/* `Bl' is open without any children. */
|
||||||
mdoc->flags |= MDOC_FREECOL;
|
mdoc->flags |= MDOC_FREECOL;
|
||||||
return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf));
|
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
|
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
|
||||||
@ -698,7 +614,8 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
LIST_column == n->parent->norm->Bl.type) {
|
LIST_column == n->parent->norm->Bl.type) {
|
||||||
/* `Bl' has block-level `It' children. */
|
/* `Bl' has block-level `It' children. */
|
||||||
mdoc->flags |= MDOC_FREECOL;
|
mdoc->flags |= MDOC_FREECOL;
|
||||||
return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf));
|
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -746,7 +663,7 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||||
line, (int)(ws-buf), NULL);
|
line, (int)(ws-buf), NULL);
|
||||||
|
|
||||||
if ('\0' == buf[offs] && ! (MDOC_LITERAL & mdoc->flags)) {
|
if (buf[offs] == '\0' && ! (mdoc->flags & MDOC_LITERAL)) {
|
||||||
mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse,
|
mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse,
|
||||||
line, (int)(c - buf), NULL);
|
line, (int)(c - buf), NULL);
|
||||||
|
|
||||||
@ -755,18 +672,15 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
* blank lines aren't allowed, but enough manuals assume this
|
* blank lines aren't allowed, but enough manuals assume this
|
||||||
* behaviour that we want to work around it.
|
* behaviour that we want to work around it.
|
||||||
*/
|
*/
|
||||||
if ( ! mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL))
|
mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL);
|
||||||
return(0);
|
|
||||||
|
|
||||||
mdoc->next = MDOC_NEXT_SIBLING;
|
mdoc->next = MDOC_NEXT_SIBLING;
|
||||||
|
mdoc_valid_post(mdoc);
|
||||||
return(mdoc_valid_post(mdoc));
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! mdoc_word_alloc(mdoc, line, offs, buf+offs))
|
mdoc_word_alloc(mdoc, line, offs, buf+offs);
|
||||||
return(0);
|
|
||||||
|
|
||||||
if (MDOC_LITERAL & mdoc->flags)
|
if (mdoc->flags & MDOC_LITERAL)
|
||||||
return(1);
|
return(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -779,7 +693,6 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
|
|
||||||
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
|
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
|
||||||
mdoc->last->flags |= MDOC_EOS;
|
mdoc->last->flags |= MDOC_EOS;
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,46 +703,47 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
static int
|
static int
|
||||||
mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
||||||
{
|
{
|
||||||
|
struct mdoc_node *n;
|
||||||
|
const char *cp;
|
||||||
enum mdoct tok;
|
enum mdoct tok;
|
||||||
int i, sv;
|
int i, sv;
|
||||||
char mac[5];
|
char mac[5];
|
||||||
struct mdoc_node *n;
|
|
||||||
|
|
||||||
/* Empty post-control lines are ignored. */
|
|
||||||
|
|
||||||
if ('"' == buf[offs]) {
|
|
||||||
mandoc_msg(MANDOCERR_COMMENT_BAD, mdoc->parse,
|
|
||||||
ln, offs, NULL);
|
|
||||||
return(1);
|
|
||||||
} else if ('\0' == buf[offs])
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
sv = offs;
|
sv = offs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the first word into a nil-terminated buffer.
|
* Copy the first word into a nil-terminated buffer.
|
||||||
* Stop copying when a tab, space, or eoln is encountered.
|
* Stop when a space, tab, escape, or eoln is encountered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < 4 && '\0' != buf[offs] && ' ' != buf[offs] &&
|
while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
|
||||||
'\t' != buf[offs])
|
|
||||||
mac[i++] = buf[offs++];
|
mac[i++] = buf[offs++];
|
||||||
|
|
||||||
mac[i] = '\0';
|
mac[i] = '\0';
|
||||||
|
|
||||||
tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
|
tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
|
||||||
|
|
||||||
if (MDOC_MAX == tok) {
|
if (tok == MDOC_MAX) {
|
||||||
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
|
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
|
||||||
ln, sv, buf + sv - 1);
|
ln, sv, buf + sv - 1);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disregard the first trailing tab, if applicable. */
|
/* Skip a leading escape sequence or tab. */
|
||||||
|
|
||||||
if ('\t' == buf[offs])
|
switch (buf[offs]) {
|
||||||
|
case '\\':
|
||||||
|
cp = buf + offs + 1;
|
||||||
|
mandoc_escape(&cp, NULL, NULL);
|
||||||
|
offs = cp - buf;
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
offs++;
|
offs++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Jump to the next non-whitespace word. */
|
/* Jump to the next non-whitespace word. */
|
||||||
|
|
||||||
@ -850,8 +764,10 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
* into macro processing.
|
* into macro processing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok)
|
if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
|
||||||
return(mdoc_macro(mdoc, tok, ln, sv, &offs, buf));
|
mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
n = mdoc->last;
|
n = mdoc->last;
|
||||||
assert(mdoc->last);
|
assert(mdoc->last);
|
||||||
@ -864,7 +780,8 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
|
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
|
||||||
LIST_column == n->norm->Bl.type) {
|
LIST_column == n->norm->Bl.type) {
|
||||||
mdoc->flags |= MDOC_FREECOL;
|
mdoc->flags |= MDOC_FREECOL;
|
||||||
return(mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf));
|
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -878,13 +795,13 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
MDOC_Bl == n->parent->tok &&
|
MDOC_Bl == n->parent->tok &&
|
||||||
LIST_column == n->parent->norm->Bl.type) {
|
LIST_column == n->parent->norm->Bl.type) {
|
||||||
mdoc->flags |= MDOC_FREECOL;
|
mdoc->flags |= MDOC_FREECOL;
|
||||||
return(mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf));
|
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal processing of a macro. */
|
/* Normal processing of a macro. */
|
||||||
|
|
||||||
if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf))
|
mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* In quick mode (for mandocdb), abort after the NAME section. */
|
/* In quick mode (for mandocdb), abort after the NAME section. */
|
||||||
|
|
||||||
|
214
mdoc_argv.c
214
mdoc_argv.c
@ -1,7 +1,7 @@
|
|||||||
/* $Id: mdoc_argv.c,v 1.95 2014/07/06 19:09:00 schwarze Exp $ */
|
/* $OpenBSD$ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -56,9 +54,9 @@ static void argn_free(struct mdoc_arg *, int);
|
|||||||
static enum margserr args(struct mdoc *, int, int *,
|
static enum margserr args(struct mdoc *, int, int *,
|
||||||
char *, enum argsflag, char **);
|
char *, enum argsflag, char **);
|
||||||
static int args_checkpunct(const char *, int);
|
static int args_checkpunct(const char *, int);
|
||||||
static int argv_multi(struct mdoc *, int,
|
static void argv_multi(struct mdoc *, int,
|
||||||
struct mdoc_argv *, int *, char *);
|
struct mdoc_argv *, int *, char *);
|
||||||
static int argv_single(struct mdoc *, int,
|
static void argv_single(struct mdoc *, int,
|
||||||
struct mdoc_argv *, int *, char *);
|
struct mdoc_argv *, int *, char *);
|
||||||
|
|
||||||
static const enum argvflag argvflags[MDOC_ARG_MAX] = {
|
static const enum argvflag argvflags[MDOC_ARG_MAX] = {
|
||||||
@ -272,100 +270,105 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse an argument from line text. This comes in the form of -key
|
* Parse flags and their arguments from the input line.
|
||||||
* [value0...], which may either have a single mandatory value, at least
|
* These come in the form -flag [argument ...].
|
||||||
* one mandatory value, an optional single value, or no value.
|
* Some flags take no argument, some one, some multiple.
|
||||||
*/
|
*/
|
||||||
enum margverr
|
void
|
||||||
mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
|
mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
|
||||||
struct mdoc_arg **v, int *pos, char *buf)
|
struct mdoc_arg **reta, int *pos, char *buf)
|
||||||
{
|
{
|
||||||
char *p, sv;
|
struct mdoc_argv tmpv;
|
||||||
struct mdoc_argv tmp;
|
struct mdoc_argv **retv;
|
||||||
struct mdoc_arg *arg;
|
const enum mdocargt *argtable;
|
||||||
const enum mdocargt *ap;
|
char *argname;
|
||||||
|
int ipos, retc;
|
||||||
|
char savechar;
|
||||||
|
|
||||||
if ('\0' == buf[*pos])
|
*reta = NULL;
|
||||||
return(ARGV_EOLN);
|
|
||||||
else if (NULL == (ap = mdocargs[tok].argvs))
|
|
||||||
return(ARGV_WORD);
|
|
||||||
else if ('-' != buf[*pos])
|
|
||||||
return(ARGV_WORD);
|
|
||||||
|
|
||||||
/* Seek to the first unescaped space. */
|
/* Which flags does this macro support? */
|
||||||
|
|
||||||
p = &buf[++(*pos)];
|
argtable = mdocargs[tok].argvs;
|
||||||
|
if (argtable == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(*pos > 0);
|
/* Loop over the flags on the input line. */
|
||||||
|
|
||||||
for ( ; buf[*pos] ; (*pos)++)
|
ipos = *pos;
|
||||||
if (' ' == buf[*pos] && '\\' != buf[*pos - 1])
|
while (buf[ipos] == '-') {
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
/* Seek to the first unescaped space. */
|
||||||
* We want to nil-terminate the word to look it up (it's easier
|
|
||||||
* that way). But we may not have a flag, in which case we need
|
|
||||||
* to restore the line as-is. So keep around the stray byte,
|
|
||||||
* which we'll reset upon exiting (if necessary).
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ('\0' != (sv = buf[*pos]))
|
for (argname = buf + ++ipos; buf[ipos] != '\0'; ipos++)
|
||||||
buf[(*pos)++] = '\0';
|
if (buf[ipos] == ' ' && buf[ipos - 1] != '\\')
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
* Now look up the word as a flag. Use temporary storage that
|
|
||||||
* we'll copy into the node's flags, if necessary.
|
|
||||||
*/
|
|
||||||
|
|
||||||
memset(&tmp, 0, sizeof(struct mdoc_argv));
|
|
||||||
|
|
||||||
tmp.line = line;
|
|
||||||
tmp.pos = *pos;
|
|
||||||
tmp.arg = MDOC_ARG_MAX;
|
|
||||||
|
|
||||||
while (MDOC_ARG_MAX != (tmp.arg = *ap++))
|
|
||||||
if (0 == strcmp(p, mdoc_argnames[tmp.arg]))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (MDOC_ARG_MAX == tmp.arg) {
|
|
||||||
/*
|
/*
|
||||||
* The flag was not found.
|
* We want to nil-terminate the word to look it up.
|
||||||
* Restore saved zeroed byte and return as a word.
|
* But we may not have a flag, in which case we need
|
||||||
|
* to restore the line as-is. So keep around the
|
||||||
|
* stray byte, which we'll reset upon exiting.
|
||||||
*/
|
*/
|
||||||
if (sv)
|
|
||||||
buf[*pos - 1] = sv;
|
if ((savechar = buf[ipos]) != '\0')
|
||||||
return(ARGV_WORD);
|
buf[ipos++] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now look up the word as a flag. Use temporary
|
||||||
|
* storage that we'll copy into the node's flags.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while ((tmpv.arg = *argtable++) != MDOC_ARG_MAX)
|
||||||
|
if ( ! strcmp(argname, mdoc_argnames[tmpv.arg]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* If it isn't a flag, restore the saved byte. */
|
||||||
|
|
||||||
|
if (tmpv.arg == MDOC_ARG_MAX) {
|
||||||
|
if (savechar != '\0')
|
||||||
|
buf[ipos - 1] = savechar;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read to the next word (the first argument). */
|
||||||
|
|
||||||
|
while (buf[ipos] == ' ')
|
||||||
|
ipos++;
|
||||||
|
|
||||||
|
/* Parse the arguments of the flag. */
|
||||||
|
|
||||||
|
tmpv.line = line;
|
||||||
|
tmpv.pos = ipos;
|
||||||
|
tmpv.sz = 0;
|
||||||
|
tmpv.value = NULL;
|
||||||
|
|
||||||
|
switch (argvflags[tmpv.arg]) {
|
||||||
|
case ARGV_SINGLE:
|
||||||
|
argv_single(mdoc, line, &tmpv, &ipos, buf);
|
||||||
|
break;
|
||||||
|
case ARGV_MULTI:
|
||||||
|
argv_multi(mdoc, line, &tmpv, &ipos, buf);
|
||||||
|
break;
|
||||||
|
case ARGV_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append to the return values. */
|
||||||
|
|
||||||
|
if (*reta == NULL)
|
||||||
|
*reta = mandoc_calloc(1, sizeof(**reta));
|
||||||
|
|
||||||
|
retc = ++(*reta)->argc;
|
||||||
|
retv = &(*reta)->argv;
|
||||||
|
*retv = mandoc_reallocarray(*retv, retc, sizeof(**retv));
|
||||||
|
memcpy(*retv + retc - 1, &tmpv, sizeof(**retv));
|
||||||
|
|
||||||
|
/* Prepare for parsing the next flag. */
|
||||||
|
|
||||||
|
*pos = ipos;
|
||||||
|
argtable = mdocargs[tok].argvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read to the next word (the argument). */
|
|
||||||
|
|
||||||
while (buf[*pos] && ' ' == buf[*pos])
|
|
||||||
(*pos)++;
|
|
||||||
|
|
||||||
switch (argvflags[tmp.arg]) {
|
|
||||||
case ARGV_SINGLE:
|
|
||||||
if ( ! argv_single(mdoc, line, &tmp, pos, buf))
|
|
||||||
return(ARGV_ERROR);
|
|
||||||
break;
|
|
||||||
case ARGV_MULTI:
|
|
||||||
if ( ! argv_multi(mdoc, line, &tmp, pos, buf))
|
|
||||||
return(ARGV_ERROR);
|
|
||||||
break;
|
|
||||||
case ARGV_NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == (arg = *v))
|
|
||||||
arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
|
|
||||||
|
|
||||||
arg->argc++;
|
|
||||||
arg->argv = mandoc_reallocarray(arg->argv,
|
|
||||||
arg->argc, sizeof(struct mdoc_argv));
|
|
||||||
|
|
||||||
memcpy(&arg->argv[(int)arg->argc - 1], &tmp,
|
|
||||||
sizeof(struct mdoc_argv));
|
|
||||||
|
|
||||||
return(ARGV_ARG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -408,23 +411,18 @@ argn_free(struct mdoc_arg *p, int iarg)
|
|||||||
p->argv[iarg] = p->argv[iarg+1];
|
p->argv[iarg] = p->argv[iarg+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
enum margserr
|
|
||||||
mdoc_zargs(struct mdoc *mdoc, int line, int *pos, char *buf, char **v)
|
|
||||||
{
|
|
||||||
|
|
||||||
return(args(mdoc, line, pos, buf, ARGSFL_NONE, v));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum margserr
|
enum margserr
|
||||||
mdoc_args(struct mdoc *mdoc, int line, int *pos,
|
mdoc_args(struct mdoc *mdoc, int line, int *pos,
|
||||||
char *buf, enum mdoct tok, char **v)
|
char *buf, enum mdoct tok, char **v)
|
||||||
{
|
{
|
||||||
enum argsflag fl;
|
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
char *v_local;
|
||||||
|
enum argsflag fl;
|
||||||
|
|
||||||
fl = mdocargs[tok].flags;
|
if (v == NULL)
|
||||||
|
v = &v_local;
|
||||||
if (MDOC_It != tok)
|
fl = tok == MDOC_MAX ? ARGSFL_NONE : mdocargs[tok].flags;
|
||||||
|
if (tok != MDOC_It)
|
||||||
return(args(mdoc, line, pos, buf, fl, v));
|
return(args(mdoc, line, pos, buf, fl, v));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -654,7 +652,7 @@ args_checkpunct(const char *buf, int i)
|
|||||||
return('\0' == buf[i]);
|
return('\0' == buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
argv_multi(struct mdoc *mdoc, int line,
|
argv_multi(struct mdoc *mdoc, int line,
|
||||||
struct mdoc_argv *v, int *pos, char *buf)
|
struct mdoc_argv *v, int *pos, char *buf)
|
||||||
{
|
{
|
||||||
@ -662,25 +660,21 @@ argv_multi(struct mdoc *mdoc, int line,
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
for (v->sz = 0; ; v->sz++) {
|
for (v->sz = 0; ; v->sz++) {
|
||||||
if ('-' == buf[*pos])
|
if (buf[*pos] == '-')
|
||||||
break;
|
break;
|
||||||
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
|
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
|
||||||
if (ARGS_ERROR == ac)
|
if (ac == ARGS_EOLN)
|
||||||
return(0);
|
|
||||||
else if (ARGS_EOLN == ac)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (0 == v->sz % MULTI_STEP)
|
if (v->sz % MULTI_STEP == 0)
|
||||||
v->value = mandoc_reallocarray(v->value,
|
v->value = mandoc_reallocarray(v->value,
|
||||||
v->sz + MULTI_STEP, sizeof(char *));
|
v->sz + MULTI_STEP, sizeof(char *));
|
||||||
|
|
||||||
v->value[(int)v->sz] = mandoc_strdup(p);
|
v->value[(int)v->sz] = mandoc_strdup(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
argv_single(struct mdoc *mdoc, int line,
|
argv_single(struct mdoc *mdoc, int line,
|
||||||
struct mdoc_argv *v, int *pos, char *buf)
|
struct mdoc_argv *v, int *pos, char *buf)
|
||||||
{
|
{
|
||||||
@ -688,14 +682,10 @@ argv_single(struct mdoc *mdoc, int line,
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
|
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
|
||||||
if (ARGS_ERROR == ac)
|
if (ac == ARGS_EOLN)
|
||||||
return(0);
|
return;
|
||||||
if (ARGS_EOLN == ac)
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
v->sz = 1;
|
v->sz = 1;
|
||||||
v->value = mandoc_malloc(sizeof(char *));
|
v->value = mandoc_malloc(sizeof(char *));
|
||||||
v->value[0] = mandoc_strdup(p);
|
v->value[0] = mandoc_strdup(p);
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc_hash.c,v 1.20 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: mdoc_hash.c,v 1.21 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
181
mdoc_html.c
181
mdoc_html.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: mdoc_html.c,v 1.195 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: mdoc_html.c,v 1.213 2014/11/27 22:27:56 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -58,7 +56,6 @@ static void synopsis_pre(struct html *,
|
|||||||
const struct mdoc_node *);
|
const struct mdoc_node *);
|
||||||
|
|
||||||
static void a2width(const char *, struct roffsu *);
|
static void a2width(const char *, struct roffsu *);
|
||||||
static void a2offs(const char *, struct roffsu *);
|
|
||||||
|
|
||||||
static void mdoc_root_post(MDOC_ARGS);
|
static void mdoc_root_post(MDOC_ARGS);
|
||||||
static int mdoc_root_pre(MDOC_ARGS);
|
static int mdoc_root_pre(MDOC_ARGS);
|
||||||
@ -101,6 +98,7 @@ static int mdoc_mt_pre(MDOC_ARGS);
|
|||||||
static int mdoc_ms_pre(MDOC_ARGS);
|
static int mdoc_ms_pre(MDOC_ARGS);
|
||||||
static int mdoc_nd_pre(MDOC_ARGS);
|
static int mdoc_nd_pre(MDOC_ARGS);
|
||||||
static int mdoc_nm_pre(MDOC_ARGS);
|
static int mdoc_nm_pre(MDOC_ARGS);
|
||||||
|
static int mdoc_no_pre(MDOC_ARGS);
|
||||||
static int mdoc_ns_pre(MDOC_ARGS);
|
static int mdoc_ns_pre(MDOC_ARGS);
|
||||||
static int mdoc_pa_pre(MDOC_ARGS);
|
static int mdoc_pa_pre(MDOC_ARGS);
|
||||||
static void mdoc_pf_post(MDOC_ARGS);
|
static void mdoc_pf_post(MDOC_ARGS);
|
||||||
@ -185,7 +183,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
|
|||||||
{mdoc_quote_pre, mdoc_quote_post}, /* Bq */
|
{mdoc_quote_pre, mdoc_quote_post}, /* Bq */
|
||||||
{mdoc_xx_pre, NULL}, /* Bsx */
|
{mdoc_xx_pre, NULL}, /* Bsx */
|
||||||
{mdoc_bx_pre, NULL}, /* Bx */
|
{mdoc_bx_pre, NULL}, /* Bx */
|
||||||
{NULL, NULL}, /* Db */
|
{mdoc_skip_pre, NULL}, /* Db */
|
||||||
{NULL, NULL}, /* Dc */
|
{NULL, NULL}, /* Dc */
|
||||||
{mdoc_quote_pre, mdoc_quote_post}, /* Do */
|
{mdoc_quote_pre, mdoc_quote_post}, /* Do */
|
||||||
{mdoc_quote_pre, mdoc_quote_post}, /* Dq */
|
{mdoc_quote_pre, mdoc_quote_post}, /* Dq */
|
||||||
@ -195,7 +193,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
|
|||||||
{mdoc_quote_pre, mdoc_quote_post}, /* Eo */
|
{mdoc_quote_pre, mdoc_quote_post}, /* Eo */
|
||||||
{mdoc_xx_pre, NULL}, /* Fx */
|
{mdoc_xx_pre, NULL}, /* Fx */
|
||||||
{mdoc_ms_pre, NULL}, /* Ms */
|
{mdoc_ms_pre, NULL}, /* Ms */
|
||||||
{mdoc_igndelim_pre, NULL}, /* No */
|
{mdoc_no_pre, NULL}, /* No */
|
||||||
{mdoc_ns_pre, NULL}, /* Ns */
|
{mdoc_ns_pre, NULL}, /* Ns */
|
||||||
{mdoc_xx_pre, NULL}, /* Nx */
|
{mdoc_xx_pre, NULL}, /* Nx */
|
||||||
{mdoc_xx_pre, NULL}, /* Ox */
|
{mdoc_xx_pre, NULL}, /* Ox */
|
||||||
@ -283,7 +281,7 @@ a2width(const char *p, struct roffsu *su)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if ( ! a2roffsu(p, su, SCALE_MAX)) {
|
if ( ! a2roffsu(p, su, SCALE_MAX)) {
|
||||||
su->unit = SCALE_BU;
|
su->unit = SCALE_EN;
|
||||||
su->scale = html_strlen(p);
|
su->scale = html_strlen(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,11 +314,11 @@ synopsis_pre(struct html *h, const struct mdoc_node *n)
|
|||||||
case MDOC_In:
|
case MDOC_In:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MDOC_Vt:
|
case MDOC_Vt:
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
break;
|
break;
|
||||||
case MDOC_Ft:
|
case MDOC_Ft:
|
||||||
if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
|
if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -330,27 +328,6 @@ synopsis_pre(struct html *h, const struct mdoc_node *n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate the scaling unit passed in an `-offset' argument. This
|
|
||||||
* uses either a native scaling unit (e.g., 1i, 2m), one of a set of
|
|
||||||
* predefined strings (indent, etc.), or the string length of the value.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
a2offs(const char *p, struct roffsu *su)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* FIXME: "right"? */
|
|
||||||
|
|
||||||
if (0 == strcmp(p, "left"))
|
|
||||||
SCALE_HS_INIT(su, 0);
|
|
||||||
else if (0 == strcmp(p, "indent"))
|
|
||||||
SCALE_HS_INIT(su, INDENT);
|
|
||||||
else if (0 == strcmp(p, "indent-two"))
|
|
||||||
SCALE_HS_INIT(su, INDENT * 2);
|
|
||||||
else if ( ! a2roffsu(p, su, SCALE_MAX))
|
|
||||||
SCALE_HS_INIT(su, html_strlen(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_mdoc(MDOC_ARGS)
|
print_mdoc(MDOC_ARGS)
|
||||||
{
|
{
|
||||||
@ -446,13 +423,12 @@ print_mdoc_node(MDOC_ARGS)
|
|||||||
* the "meta" table state. This will be reopened on the
|
* the "meta" table state. This will be reopened on the
|
||||||
* next table element.
|
* next table element.
|
||||||
*/
|
*/
|
||||||
if (h->tblt) {
|
if (h->tblt != NULL) {
|
||||||
print_tblclose(h);
|
print_tblclose(h);
|
||||||
t = h->tags.head;
|
t = h->tags.head;
|
||||||
}
|
}
|
||||||
|
assert(h->tblt == NULL);
|
||||||
assert(NULL == h->tblt);
|
if (mdocs[n->tok].pre && (n->end == ENDBODY_NOT || n->child))
|
||||||
if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
|
|
||||||
child = (*mdocs[n->tok].pre)(meta, n, h);
|
child = (*mdocs[n->tok].pre)(meta, n, h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -477,8 +453,13 @@ print_mdoc_node(MDOC_ARGS)
|
|||||||
case MDOC_EQN:
|
case MDOC_EQN:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
|
if ( ! mdocs[n->tok].post || n->flags & MDOC_ENDED)
|
||||||
(*mdocs[n->tok].post)(meta, n, h);
|
break;
|
||||||
|
(*mdocs[n->tok].post)(meta, n, h);
|
||||||
|
if (n->end != ENDBODY_NOT)
|
||||||
|
n->pending->flags |= MDOC_ENDED;
|
||||||
|
if (n->end == ENDBODY_NOSPACE)
|
||||||
|
h->flags |= HTML_NOSPACE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,29 +467,23 @@ print_mdoc_node(MDOC_ARGS)
|
|||||||
static void
|
static void
|
||||||
mdoc_root_post(MDOC_ARGS)
|
mdoc_root_post(MDOC_ARGS)
|
||||||
{
|
{
|
||||||
struct htmlpair tag[3];
|
struct htmlpair tag;
|
||||||
struct tag *t, *tt;
|
struct tag *t, *tt;
|
||||||
|
|
||||||
PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
|
PAIR_CLASS_INIT(&tag, "foot");
|
||||||
PAIR_CLASS_INIT(&tag[1], "foot");
|
t = print_otag(h, TAG_TABLE, 1, &tag);
|
||||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
|
||||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
|
||||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
|
|
||||||
print_otag(h, TAG_TBODY, 0, NULL);
|
print_otag(h, TAG_TBODY, 0, NULL);
|
||||||
|
|
||||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
PAIR_CLASS_INIT(&tag, "foot-date");
|
||||||
print_otag(h, TAG_TD, 1, tag);
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_text(h, meta->date);
|
print_text(h, meta->date);
|
||||||
print_stagq(h, tt);
|
print_stagq(h, tt);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
PAIR_CLASS_INIT(&tag, "foot-os");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
|
||||||
print_text(h, meta->os);
|
print_text(h, meta->os);
|
||||||
print_tagq(h, t);
|
print_tagq(h, t);
|
||||||
}
|
}
|
||||||
@ -516,7 +491,7 @@ mdoc_root_post(MDOC_ARGS)
|
|||||||
static int
|
static int
|
||||||
mdoc_root_pre(MDOC_ARGS)
|
mdoc_root_pre(MDOC_ARGS)
|
||||||
{
|
{
|
||||||
struct htmlpair tag[3];
|
struct htmlpair tag;
|
||||||
struct tag *t, *tt;
|
struct tag *t, *tt;
|
||||||
char *volume, *title;
|
char *volume, *title;
|
||||||
|
|
||||||
@ -532,33 +507,25 @@ mdoc_root_pre(MDOC_ARGS)
|
|||||||
mandoc_asprintf(&title, "%s(%s)",
|
mandoc_asprintf(&title, "%s(%s)",
|
||||||
meta->title, meta->msec);
|
meta->title, meta->msec);
|
||||||
|
|
||||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
PAIR_CLASS_INIT(&tag, "head");
|
||||||
PAIR_CLASS_INIT(&tag[1], "head");
|
t = print_otag(h, TAG_TABLE, 1, &tag);
|
||||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
|
||||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
|
||||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
print_otag(h, TAG_COL, 1, tag);
|
|
||||||
|
|
||||||
print_otag(h, TAG_TBODY, 0, NULL);
|
print_otag(h, TAG_TBODY, 0, NULL);
|
||||||
|
|
||||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "head-ltitle");
|
PAIR_CLASS_INIT(&tag, "head-ltitle");
|
||||||
print_otag(h, TAG_TD, 1, tag);
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_text(h, title);
|
print_text(h, title);
|
||||||
print_stagq(h, tt);
|
print_stagq(h, tt);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
PAIR_CLASS_INIT(&tag, "head-vol");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
|
||||||
print_text(h, volume);
|
print_text(h, volume);
|
||||||
print_stagq(h, tt);
|
print_stagq(h, tt);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag[0], "head-rtitle");
|
PAIR_CLASS_INIT(&tag, "head-rtitle");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
|
||||||
print_text(h, title);
|
print_text(h, title);
|
||||||
print_tagq(h, t);
|
print_tagq(h, t);
|
||||||
|
|
||||||
@ -572,12 +539,18 @@ mdoc_sh_pre(MDOC_ARGS)
|
|||||||
{
|
{
|
||||||
struct htmlpair tag;
|
struct htmlpair tag;
|
||||||
|
|
||||||
if (MDOC_BLOCK == n->type) {
|
switch (n->type) {
|
||||||
|
case MDOC_BLOCK:
|
||||||
PAIR_CLASS_INIT(&tag, "section");
|
PAIR_CLASS_INIT(&tag, "section");
|
||||||
print_otag(h, TAG_DIV, 1, &tag);
|
print_otag(h, TAG_DIV, 1, &tag);
|
||||||
return(1);
|
return(1);
|
||||||
} else if (MDOC_BODY == n->type)
|
case MDOC_BODY:
|
||||||
|
if (n->sec == SEC_AUTHORS)
|
||||||
|
h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT);
|
||||||
return(1);
|
return(1);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bufinit(h);
|
bufinit(h);
|
||||||
bufcat(h, "x");
|
bufcat(h, "x");
|
||||||
@ -642,9 +615,10 @@ mdoc_fl_pre(MDOC_ARGS)
|
|||||||
|
|
||||||
print_text(h, "\\-");
|
print_text(h, "\\-");
|
||||||
|
|
||||||
if (n->child)
|
if ( ! (n->nchild == 0 &&
|
||||||
h->flags |= HTML_NOSPACE;
|
(n->next == NULL ||
|
||||||
else if (n->next && n->next->line == n->line)
|
n->next->type == MDOC_TEXT ||
|
||||||
|
n->next->flags & MDOC_LINE)))
|
||||||
h->flags |= HTML_NOSPACE;
|
h->flags |= HTML_NOSPACE;
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
@ -1003,7 +977,7 @@ mdoc_bl_pre(MDOC_ARGS)
|
|||||||
/* Set the block's left-hand margin. */
|
/* Set the block's left-hand margin. */
|
||||||
|
|
||||||
if (n->norm->Bl.offs) {
|
if (n->norm->Bl.offs) {
|
||||||
a2offs(n->norm->Bl.offs, &su);
|
a2width(n->norm->Bl.offs, &su);
|
||||||
bufcat_su(h, "margin-left", &su);
|
bufcat_su(h, "margin-left", &su);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,13 +1139,21 @@ mdoc_bd_pre(MDOC_ARGS)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( ! comp)
|
if ( ! comp)
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCALE_HS_INIT(&su, 0);
|
/* Handle the -offset argument. */
|
||||||
if (n->norm->Bd.offs)
|
|
||||||
a2offs(n->norm->Bd.offs, &su);
|
if (n->norm->Bd.offs == NULL ||
|
||||||
|
! strcmp(n->norm->Bd.offs, "left"))
|
||||||
|
SCALE_HS_INIT(&su, 0);
|
||||||
|
else if ( ! strcmp(n->norm->Bd.offs, "indent"))
|
||||||
|
SCALE_HS_INIT(&su, INDENT);
|
||||||
|
else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
|
||||||
|
SCALE_HS_INIT(&su, INDENT * 2);
|
||||||
|
else
|
||||||
|
a2width(n->norm->Bd.offs, &su);
|
||||||
|
|
||||||
bufinit(h);
|
bufinit(h);
|
||||||
bufcat_su(h, "margin-left", &su);
|
bufcat_su(h, "margin-left", &su);
|
||||||
@ -1259,7 +1241,25 @@ mdoc_an_pre(MDOC_ARGS)
|
|||||||
{
|
{
|
||||||
struct htmlpair tag;
|
struct htmlpair tag;
|
||||||
|
|
||||||
/* TODO: -split and -nosplit (see termp_an_pre()). */
|
if (n->norm->An.auth == AUTH_split) {
|
||||||
|
h->flags &= ~HTML_NOSPLIT;
|
||||||
|
h->flags |= HTML_SPLIT;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if (n->norm->An.auth == AUTH_nosplit) {
|
||||||
|
h->flags &= ~HTML_SPLIT;
|
||||||
|
h->flags |= HTML_NOSPLIT;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n->child == NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (h->flags & HTML_SPLIT)
|
||||||
|
print_otag(h, TAG_BR, 0, NULL);
|
||||||
|
|
||||||
|
if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT))
|
||||||
|
h->flags |= HTML_SPLIT;
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag, "author");
|
PAIR_CLASS_INIT(&tag, "author");
|
||||||
print_otag(h, TAG_SPAN, 1, &tag);
|
print_otag(h, TAG_SPAN, 1, &tag);
|
||||||
@ -1553,7 +1553,7 @@ static int
|
|||||||
mdoc_pp_pre(MDOC_ARGS)
|
mdoc_pp_pre(MDOC_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1881,13 +1881,23 @@ mdoc_rs_pre(MDOC_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
|
|
||||||
if (n->prev && SEC_SEE_ALSO == n->sec)
|
if (n->prev && SEC_SEE_ALSO == n->sec)
|
||||||
print_otag(h, TAG_P, 0, NULL);
|
print_paragraph(h);
|
||||||
|
|
||||||
PAIR_CLASS_INIT(&tag, "ref");
|
PAIR_CLASS_INIT(&tag, "ref");
|
||||||
print_otag(h, TAG_SPAN, 1, &tag);
|
print_otag(h, TAG_SPAN, 1, &tag);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mdoc_no_pre(MDOC_ARGS)
|
||||||
|
{
|
||||||
|
struct htmlpair tag;
|
||||||
|
|
||||||
|
PAIR_CLASS_INIT(&tag, "none");
|
||||||
|
print_otag(h, TAG_CODE, 1, &tag);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mdoc_li_pre(MDOC_ARGS)
|
mdoc_li_pre(MDOC_ARGS)
|
||||||
{
|
{
|
||||||
@ -2069,7 +2079,8 @@ mdoc_quote_pre(MDOC_ARGS)
|
|||||||
case MDOC_Ao:
|
case MDOC_Ao:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MDOC_Aq:
|
case MDOC_Aq:
|
||||||
print_text(h, "\\(la");
|
print_text(h, n->parent->prev != NULL &&
|
||||||
|
n->parent->prev->tok == MDOC_An ? "<" : "\\(la");
|
||||||
break;
|
break;
|
||||||
case MDOC_Bro:
|
case MDOC_Bro:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -2135,17 +2146,19 @@ static void
|
|||||||
mdoc_quote_post(MDOC_ARGS)
|
mdoc_quote_post(MDOC_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MDOC_BODY != n->type)
|
if (n->type != MDOC_BODY && n->type != MDOC_ELEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (MDOC_En != n->tok)
|
if ( ! (n->tok == MDOC_En ||
|
||||||
|
(n->tok == MDOC_Eo && n->end == ENDBODY_SPACE)))
|
||||||
h->flags |= HTML_NOSPACE;
|
h->flags |= HTML_NOSPACE;
|
||||||
|
|
||||||
switch (n->tok) {
|
switch (n->tok) {
|
||||||
case MDOC_Ao:
|
case MDOC_Ao:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MDOC_Aq:
|
case MDOC_Aq:
|
||||||
print_text(h, "\\(ra");
|
print_text(h, n->parent->prev != NULL &&
|
||||||
|
n->parent->prev->tok == MDOC_An ? ">" : "\\(ra");
|
||||||
break;
|
break;
|
||||||
case MDOC_Bro:
|
case MDOC_Bro:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
1170
mdoc_macro.c
1170
mdoc_macro.c
File diff suppressed because it is too large
Load Diff
99
mdoc_man.c
99
mdoc_man.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc_man.c,v 1.68 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: mdoc_man.c,v 1.76 2014/11/27 22:27:56 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -46,6 +46,7 @@ static void font_push(char);
|
|||||||
static void font_pop(void);
|
static void font_pop(void);
|
||||||
static void mid_it(void);
|
static void mid_it(void);
|
||||||
static void post__t(DECL_ARGS);
|
static void post__t(DECL_ARGS);
|
||||||
|
static void post_aq(DECL_ARGS);
|
||||||
static void post_bd(DECL_ARGS);
|
static void post_bd(DECL_ARGS);
|
||||||
static void post_bf(DECL_ARGS);
|
static void post_bf(DECL_ARGS);
|
||||||
static void post_bk(DECL_ARGS);
|
static void post_bk(DECL_ARGS);
|
||||||
@ -72,6 +73,7 @@ static void post_vt(DECL_ARGS);
|
|||||||
static int pre__t(DECL_ARGS);
|
static int pre__t(DECL_ARGS);
|
||||||
static int pre_an(DECL_ARGS);
|
static int pre_an(DECL_ARGS);
|
||||||
static int pre_ap(DECL_ARGS);
|
static int pre_ap(DECL_ARGS);
|
||||||
|
static int pre_aq(DECL_ARGS);
|
||||||
static int pre_bd(DECL_ARGS);
|
static int pre_bd(DECL_ARGS);
|
||||||
static int pre_bf(DECL_ARGS);
|
static int pre_bf(DECL_ARGS);
|
||||||
static int pre_bk(DECL_ARGS);
|
static int pre_bk(DECL_ARGS);
|
||||||
@ -82,7 +84,8 @@ static int pre_dl(DECL_ARGS);
|
|||||||
static int pre_en(DECL_ARGS);
|
static int pre_en(DECL_ARGS);
|
||||||
static int pre_enc(DECL_ARGS);
|
static int pre_enc(DECL_ARGS);
|
||||||
static int pre_em(DECL_ARGS);
|
static int pre_em(DECL_ARGS);
|
||||||
static int pre_es(DECL_ARGS);
|
static int pre_skip(DECL_ARGS);
|
||||||
|
static int pre_eo(DECL_ARGS);
|
||||||
static int pre_ex(DECL_ARGS);
|
static int pre_ex(DECL_ARGS);
|
||||||
static int pre_fa(DECL_ARGS);
|
static int pre_fa(DECL_ARGS);
|
||||||
static int pre_fd(DECL_ARGS);
|
static int pre_fd(DECL_ARGS);
|
||||||
@ -112,7 +115,7 @@ static int pre_xr(DECL_ARGS);
|
|||||||
static void print_word(const char *);
|
static void print_word(const char *);
|
||||||
static void print_line(const char *, int);
|
static void print_line(const char *, int);
|
||||||
static void print_block(const char *, int);
|
static void print_block(const char *, int);
|
||||||
static void print_offs(const char *);
|
static void print_offs(const char *, int);
|
||||||
static void print_width(const char *,
|
static void print_width(const char *,
|
||||||
const struct mdoc_node *, size_t);
|
const struct mdoc_node *, size_t);
|
||||||
static void print_count(int *);
|
static void print_count(int *);
|
||||||
@ -172,8 +175,8 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
|||||||
{ NULL, pre__t, post__t, NULL, NULL }, /* %T */
|
{ NULL, pre__t, post__t, NULL, NULL }, /* %T */
|
||||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %V */
|
{ NULL, NULL, post_percent, NULL, NULL }, /* %V */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ac */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Ac */
|
||||||
{ cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
|
{ cond_body, pre_aq, post_aq, NULL, NULL }, /* Ao */
|
||||||
{ cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
|
{ cond_body, pre_aq, post_aq, NULL, NULL }, /* Aq */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* At */
|
{ NULL, NULL, NULL, NULL, NULL }, /* At */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bc */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Bc */
|
||||||
{ NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
|
{ NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
|
||||||
@ -181,14 +184,14 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
|||||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
|
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
|
||||||
{ NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
|
{ NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
|
||||||
{ NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
|
{ NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Db */
|
{ NULL, pre_skip, NULL, NULL, NULL }, /* Db */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
|
||||||
{ cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */
|
{ cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */
|
||||||
{ cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */
|
{ cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ec */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Ec */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
|
||||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
|
{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
|
||||||
{ NULL, NULL, post_eo, NULL, NULL }, /* Eo */
|
{ cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
|
||||||
{ NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
|
{ NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
|
||||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
|
{ NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
|
||||||
{ NULL, pre_no, NULL, NULL, NULL }, /* No */
|
{ NULL, pre_no, NULL, NULL, NULL }, /* No */
|
||||||
@ -233,7 +236,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
|||||||
{ cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
|
{ cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Brc */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Brc */
|
||||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %C */
|
{ NULL, NULL, post_percent, NULL, NULL }, /* %C */
|
||||||
{ NULL, pre_es, NULL, NULL, NULL }, /* Es */
|
{ NULL, pre_skip, NULL, NULL, NULL }, /* Es */
|
||||||
{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
|
{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
|
||||||
{ NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
|
{ NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
|
||||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
|
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
|
||||||
@ -416,7 +419,7 @@ print_block(const char *s, int newflags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_offs(const char *v)
|
print_offs(const char *v, int keywords)
|
||||||
{
|
{
|
||||||
char buf[24];
|
char buf[24];
|
||||||
struct roffsu su;
|
struct roffsu su;
|
||||||
@ -425,11 +428,11 @@ print_offs(const char *v)
|
|||||||
print_line(".RS", MMAN_Bk_susp);
|
print_line(".RS", MMAN_Bk_susp);
|
||||||
|
|
||||||
/* Convert v into a number (of characters). */
|
/* Convert v into a number (of characters). */
|
||||||
if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
|
if (NULL == v || '\0' == *v || (keywords && !strcmp(v, "left")))
|
||||||
sz = 0;
|
sz = 0;
|
||||||
else if (0 == strcmp(v, "indent"))
|
else if (keywords && !strcmp(v, "indent"))
|
||||||
sz = 6;
|
sz = 6;
|
||||||
else if (0 == strcmp(v, "indent-two"))
|
else if (keywords && !strcmp(v, "indent-two"))
|
||||||
sz = 12;
|
sz = 12;
|
||||||
else if (a2roffsu(v, &su, SCALE_MAX)) {
|
else if (a2roffsu(v, &su, SCALE_MAX)) {
|
||||||
if (SCALE_EN == su.unit)
|
if (SCALE_EN == su.unit)
|
||||||
@ -594,15 +597,19 @@ print_node(DECL_ARGS)
|
|||||||
printf("\\&");
|
printf("\\&");
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
}
|
}
|
||||||
|
if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMC))
|
||||||
|
outflags |= MMAN_spc_force;
|
||||||
print_word(n->string);
|
print_word(n->string);
|
||||||
|
if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMO))
|
||||||
|
outflags |= MMAN_spc;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Conditionally run the pre-node action handler for a
|
* Conditionally run the pre-node action handler for a
|
||||||
* node.
|
* node.
|
||||||
*/
|
*/
|
||||||
act = manacts + n->tok;
|
act = manacts + n->tok;
|
||||||
cond = NULL == act->cond || (*act->cond)(meta, n);
|
cond = act->cond == NULL || (*act->cond)(meta, n);
|
||||||
if (cond && act->pre && ENDBODY_NOT == n->end)
|
if (cond && act->pre && (n->end == ENDBODY_NOT || n->nchild))
|
||||||
do_sub = (*act->pre)(meta, n);
|
do_sub = (*act->pre)(meta, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,6 +872,25 @@ pre_ap(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_aq(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
print_word(n->parent->prev != NULL &&
|
||||||
|
n->parent->prev->tok == MDOC_An ? "<" : "\\(la");
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_aq(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
outflags &= ~(MMAN_spc | MMAN_nl);
|
||||||
|
print_word(n->parent->prev != NULL &&
|
||||||
|
n->parent->prev->tok == MDOC_An ? ">" : "\\(ra");
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pre_bd(DECL_ARGS)
|
pre_bd(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -876,7 +902,7 @@ pre_bd(DECL_ARGS)
|
|||||||
print_line(".nf", 0);
|
print_line(".nf", 0);
|
||||||
if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
|
if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
|
||||||
outflags |= MMAN_sp;
|
outflags |= MMAN_sp;
|
||||||
print_offs(n->norm->Bd.offs);
|
print_offs(n->norm->Bd.offs, 1);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -963,7 +989,7 @@ pre_bl(DECL_ARGS)
|
|||||||
* just nest and do not add up their indentation.
|
* just nest and do not add up their indentation.
|
||||||
*/
|
*/
|
||||||
if (n->norm->Bl.offs) {
|
if (n->norm->Bl.offs) {
|
||||||
print_offs(n->norm->Bl.offs);
|
print_offs(n->norm->Bl.offs, 0);
|
||||||
Bl_stack[Bl_stack_len++] = 0;
|
Bl_stack[Bl_stack_len++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1048,7 +1074,7 @@ static int
|
|||||||
pre_dl(DECL_ARGS)
|
pre_dl(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
print_offs("6n");
|
print_offs("6n", 0);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,21 +1124,22 @@ post_en(DECL_ARGS)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_eo(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
outflags &= ~(MMAN_spc | MMAN_nl);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
post_eo(DECL_ARGS)
|
post_eo(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MDOC_HEAD == n->type || MDOC_BODY == n->type)
|
if (n->end != ENDBODY_SPACE)
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
pre_es(DECL_ARGS)
|
|
||||||
{
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pre_fa(DECL_ARGS)
|
pre_fa(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -1166,7 +1193,8 @@ pre_fl(DECL_ARGS)
|
|||||||
|
|
||||||
font_push('B');
|
font_push('B');
|
||||||
print_word("\\-");
|
print_word("\\-");
|
||||||
outflags &= ~MMAN_spc;
|
if (n->nchild)
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1175,8 +1203,10 @@ post_fl(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
font_pop();
|
font_pop();
|
||||||
if (0 == n->nchild && NULL != n->next &&
|
if ( ! (n->nchild ||
|
||||||
n->next->line == n->line)
|
n->next == NULL ||
|
||||||
|
n->next->type == MDOC_TEXT ||
|
||||||
|
n->next->flags & MDOC_LINE))
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1337,7 +1367,7 @@ pre_it(DECL_ARGS)
|
|||||||
outflags |= MMAN_nl;
|
outflags |= MMAN_nl;
|
||||||
font_push('B');
|
font_push('B');
|
||||||
if (LIST_bullet == bln->norm->Bl.type)
|
if (LIST_bullet == bln->norm->Bl.type)
|
||||||
print_word("o");
|
print_word("\\(bu");
|
||||||
else
|
else
|
||||||
print_word("-");
|
print_word("-");
|
||||||
font_pop();
|
font_pop();
|
||||||
@ -1649,6 +1679,13 @@ pre_rv(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_skip(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pre_sm(DECL_ARGS)
|
pre_sm(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
274
mdoc_term.c
274
mdoc_term.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc_term.c,v 1.275 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: mdoc_term.c,v 1.297 2014/11/28 16:54:23 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -16,9 +16,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -53,7 +51,6 @@ struct termact {
|
|||||||
|
|
||||||
static size_t a2width(const struct termp *, const char *);
|
static size_t a2width(const struct termp *, const char *);
|
||||||
static size_t a2height(const struct termp *, const char *);
|
static size_t a2height(const struct termp *, const char *);
|
||||||
static size_t a2offs(const struct termp *, const char *);
|
|
||||||
|
|
||||||
static void print_bvspace(struct termp *,
|
static void print_bvspace(struct termp *,
|
||||||
const struct mdoc_node *,
|
const struct mdoc_node *,
|
||||||
@ -67,7 +64,6 @@ static void synopsis_pre(struct termp *,
|
|||||||
|
|
||||||
static void termp____post(DECL_ARGS);
|
static void termp____post(DECL_ARGS);
|
||||||
static void termp__t_post(DECL_ARGS);
|
static void termp__t_post(DECL_ARGS);
|
||||||
static void termp_an_post(DECL_ARGS);
|
|
||||||
static void termp_bd_post(DECL_ARGS);
|
static void termp_bd_post(DECL_ARGS);
|
||||||
static void termp_bk_post(DECL_ARGS);
|
static void termp_bk_post(DECL_ARGS);
|
||||||
static void termp_bl_post(DECL_ARGS);
|
static void termp_bl_post(DECL_ARGS);
|
||||||
@ -95,7 +91,6 @@ static int termp_bt_pre(DECL_ARGS);
|
|||||||
static int termp_bx_pre(DECL_ARGS);
|
static int termp_bx_pre(DECL_ARGS);
|
||||||
static int termp_cd_pre(DECL_ARGS);
|
static int termp_cd_pre(DECL_ARGS);
|
||||||
static int termp_d1_pre(DECL_ARGS);
|
static int termp_d1_pre(DECL_ARGS);
|
||||||
static int termp_es_pre(DECL_ARGS);
|
|
||||||
static int termp_ex_pre(DECL_ARGS);
|
static int termp_ex_pre(DECL_ARGS);
|
||||||
static int termp_fa_pre(DECL_ARGS);
|
static int termp_fa_pre(DECL_ARGS);
|
||||||
static int termp_fd_pre(DECL_ARGS);
|
static int termp_fd_pre(DECL_ARGS);
|
||||||
@ -115,6 +110,7 @@ static int termp_quote_pre(DECL_ARGS);
|
|||||||
static int termp_rs_pre(DECL_ARGS);
|
static int termp_rs_pre(DECL_ARGS);
|
||||||
static int termp_rv_pre(DECL_ARGS);
|
static int termp_rv_pre(DECL_ARGS);
|
||||||
static int termp_sh_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_sm_pre(DECL_ARGS);
|
||||||
static int termp_sp_pre(DECL_ARGS);
|
static int termp_sp_pre(DECL_ARGS);
|
||||||
static int termp_ss_pre(DECL_ARGS);
|
static int termp_ss_pre(DECL_ARGS);
|
||||||
@ -140,7 +136,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||||||
{ NULL, NULL }, /* El */
|
{ NULL, NULL }, /* El */
|
||||||
{ termp_it_pre, termp_it_post }, /* It */
|
{ termp_it_pre, termp_it_post }, /* It */
|
||||||
{ termp_under_pre, NULL }, /* Ad */
|
{ termp_under_pre, NULL }, /* Ad */
|
||||||
{ termp_an_pre, termp_an_post }, /* An */
|
{ termp_an_pre, NULL }, /* An */
|
||||||
{ termp_under_pre, NULL }, /* Ar */
|
{ termp_under_pre, NULL }, /* Ar */
|
||||||
{ termp_cd_pre, NULL }, /* Cd */
|
{ termp_cd_pre, NULL }, /* Cd */
|
||||||
{ termp_bold_pre, NULL }, /* Cm */
|
{ termp_bold_pre, NULL }, /* Cm */
|
||||||
@ -187,7 +183,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||||||
{ termp_quote_pre, termp_quote_post }, /* Bq */
|
{ termp_quote_pre, termp_quote_post }, /* Bq */
|
||||||
{ termp_xx_pre, NULL }, /* Bsx */
|
{ termp_xx_pre, NULL }, /* Bsx */
|
||||||
{ termp_bx_pre, NULL }, /* Bx */
|
{ termp_bx_pre, NULL }, /* Bx */
|
||||||
{ NULL, NULL }, /* Db */
|
{ termp_skip_pre, NULL }, /* Db */
|
||||||
{ NULL, NULL }, /* Dc */
|
{ NULL, NULL }, /* Dc */
|
||||||
{ termp_quote_pre, termp_quote_post }, /* Do */
|
{ termp_quote_pre, termp_quote_post }, /* Do */
|
||||||
{ termp_quote_pre, termp_quote_post }, /* Dq */
|
{ termp_quote_pre, termp_quote_post }, /* Dq */
|
||||||
@ -197,7 +193,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||||||
{ termp_quote_pre, termp_quote_post }, /* Eo */
|
{ termp_quote_pre, termp_quote_post }, /* Eo */
|
||||||
{ termp_xx_pre, NULL }, /* Fx */
|
{ termp_xx_pre, NULL }, /* Fx */
|
||||||
{ termp_bold_pre, NULL }, /* Ms */
|
{ termp_bold_pre, NULL }, /* Ms */
|
||||||
{ NULL, NULL }, /* No */
|
{ termp_li_pre, NULL }, /* No */
|
||||||
{ termp_ns_pre, NULL }, /* Ns */
|
{ termp_ns_pre, NULL }, /* Ns */
|
||||||
{ termp_xx_pre, NULL }, /* Nx */
|
{ termp_xx_pre, NULL }, /* Nx */
|
||||||
{ termp_xx_pre, NULL }, /* Ox */
|
{ termp_xx_pre, NULL }, /* Ox */
|
||||||
@ -239,7 +235,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||||||
{ termp_quote_pre, termp_quote_post }, /* Bro */
|
{ termp_quote_pre, termp_quote_post }, /* Bro */
|
||||||
{ NULL, NULL }, /* Brc */
|
{ NULL, NULL }, /* Brc */
|
||||||
{ NULL, termp____post }, /* %C */
|
{ NULL, termp____post }, /* %C */
|
||||||
{ termp_es_pre, NULL }, /* Es */
|
{ termp_skip_pre, NULL }, /* Es */
|
||||||
{ termp_quote_pre, termp_quote_post }, /* En */
|
{ termp_quote_pre, termp_quote_post }, /* En */
|
||||||
{ termp_xx_pre, NULL }, /* Dx */
|
{ termp_xx_pre, NULL }, /* Dx */
|
||||||
{ NULL, termp____post }, /* %Q */
|
{ NULL, termp____post }, /* %Q */
|
||||||
@ -254,34 +250,41 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||||||
void
|
void
|
||||||
terminal_mdoc(void *arg, const struct mdoc *mdoc)
|
terminal_mdoc(void *arg, const struct mdoc *mdoc)
|
||||||
{
|
{
|
||||||
const struct mdoc_node *n;
|
|
||||||
const struct mdoc_meta *meta;
|
const struct mdoc_meta *meta;
|
||||||
|
struct mdoc_node *n;
|
||||||
struct termp *p;
|
struct termp *p;
|
||||||
|
|
||||||
p = (struct termp *)arg;
|
p = (struct termp *)arg;
|
||||||
|
|
||||||
if (0 == p->defindent)
|
|
||||||
p->defindent = 5;
|
|
||||||
|
|
||||||
p->overstep = 0;
|
p->overstep = 0;
|
||||||
p->maxrmargin = p->defrmargin;
|
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||||
p->tabwidth = term_len(p, 5);
|
p->tabwidth = term_len(p, 5);
|
||||||
|
|
||||||
if (NULL == p->symtab)
|
n = mdoc_node(mdoc)->child;
|
||||||
p->symtab = mchars_alloc();
|
|
||||||
|
|
||||||
n = mdoc_node(mdoc);
|
|
||||||
meta = mdoc_meta(mdoc);
|
meta = mdoc_meta(mdoc);
|
||||||
|
|
||||||
term_begin(p, print_mdoc_head, print_mdoc_foot, meta);
|
if (p->synopsisonly) {
|
||||||
|
while (n != NULL) {
|
||||||
if (n->child) {
|
if (n->tok == MDOC_Sh && n->sec == SEC_SYNOPSIS) {
|
||||||
if (MDOC_Sh != n->child->tok)
|
if (n->child->next->child != NULL)
|
||||||
term_vspace(p);
|
print_mdoc_nodelist(p, NULL,
|
||||||
print_mdoc_nodelist(p, NULL, meta, n->child);
|
meta, n->child->next->child);
|
||||||
|
term_newln(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n = n->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p->defindent == 0)
|
||||||
|
p->defindent = 5;
|
||||||
|
term_begin(p, print_mdoc_head, print_mdoc_foot, meta);
|
||||||
|
if (n != NULL) {
|
||||||
|
if (n->tok != MDOC_Sh)
|
||||||
|
term_vspace(p);
|
||||||
|
print_mdoc_nodelist(p, NULL, meta, n);
|
||||||
|
}
|
||||||
|
term_end(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
term_end(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -337,13 +340,18 @@ print_mdoc_node(DECL_ARGS)
|
|||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
break;
|
break;
|
||||||
case MDOC_EQN:
|
case MDOC_EQN:
|
||||||
|
if ( ! (n->flags & MDOC_LINE))
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
term_eqn(p, n->eqn);
|
term_eqn(p, n->eqn);
|
||||||
|
if (n->next != NULL && ! (n->next->flags & MDOC_LINE))
|
||||||
|
p->flags |= TERMP_NOSPACE;
|
||||||
break;
|
break;
|
||||||
case MDOC_TBL:
|
case MDOC_TBL:
|
||||||
term_tbl(p, n->span);
|
term_tbl(p, n->span);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
|
if (termacts[n->tok].pre &&
|
||||||
|
(n->end == ENDBODY_NOT || n->nchild))
|
||||||
chld = (*termacts[n->tok].pre)
|
chld = (*termacts[n->tok].pre)
|
||||||
(p, &npair, meta, n);
|
(p, &npair, meta, n);
|
||||||
break;
|
break;
|
||||||
@ -398,6 +406,7 @@ static void
|
|||||||
print_mdoc_foot(struct termp *p, const void *arg)
|
print_mdoc_foot(struct termp *p, const void *arg)
|
||||||
{
|
{
|
||||||
const struct mdoc_meta *meta;
|
const struct mdoc_meta *meta;
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
meta = (const struct mdoc_meta *)arg;
|
meta = (const struct mdoc_meta *)arg;
|
||||||
|
|
||||||
@ -414,8 +423,9 @@ print_mdoc_foot(struct termp *p, const void *arg)
|
|||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
|
|
||||||
p->offset = 0;
|
p->offset = 0;
|
||||||
p->rmargin = (p->maxrmargin -
|
sz = term_strlen(p, meta->date);
|
||||||
term_strlen(p, meta->date) + term_len(p, 1)) / 2;
|
p->rmargin = p->maxrmargin > sz ?
|
||||||
|
(p->maxrmargin + term_len(p, 1) - sz) / 2 : 0;
|
||||||
p->trailspace = 1;
|
p->trailspace = 1;
|
||||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||||
|
|
||||||
@ -423,7 +433,8 @@ print_mdoc_foot(struct termp *p, const void *arg)
|
|||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
|
|
||||||
p->offset = p->rmargin;
|
p->offset = p->rmargin;
|
||||||
p->rmargin = p->maxrmargin - term_strlen(p, meta->os);
|
sz = term_strlen(p, meta->os);
|
||||||
|
p->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0;
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
|
||||||
term_word(p, meta->date);
|
term_word(p, meta->date);
|
||||||
@ -465,9 +476,6 @@ print_mdoc_head(struct termp *p, const void *arg)
|
|||||||
* switches on the manual section.
|
* switches on the manual section.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
p->offset = 0;
|
|
||||||
p->rmargin = p->maxrmargin;
|
|
||||||
|
|
||||||
assert(meta->vol);
|
assert(meta->vol);
|
||||||
if (NULL == meta->arch)
|
if (NULL == meta->arch)
|
||||||
volume = mandoc_strdup(meta->vol);
|
volume = mandoc_strdup(meta->vol);
|
||||||
@ -488,7 +496,7 @@ print_mdoc_head(struct termp *p, const void *arg)
|
|||||||
p->offset = 0;
|
p->offset = 0;
|
||||||
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||||
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
||||||
p->maxrmargin - vollen;
|
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
|
||||||
|
|
||||||
term_word(p, title);
|
term_word(p, title);
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
@ -537,27 +545,10 @@ a2width(const struct termp *p, const char *v)
|
|||||||
struct roffsu su;
|
struct roffsu su;
|
||||||
|
|
||||||
assert(v);
|
assert(v);
|
||||||
if ( ! a2roffsu(v, &su, SCALE_MAX))
|
if ( ! a2roffsu(v, &su, SCALE_MAX)) {
|
||||||
SCALE_HS_INIT(&su, term_strlen(p, v));
|
|
||||||
|
|
||||||
return(term_hspan(p, &su));
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
a2offs(const struct termp *p, const char *v)
|
|
||||||
{
|
|
||||||
struct roffsu su;
|
|
||||||
|
|
||||||
if ('\0' == *v)
|
|
||||||
return(0);
|
|
||||||
else if (0 == strcmp(v, "left"))
|
|
||||||
return(0);
|
|
||||||
else if (0 == strcmp(v, "indent"))
|
|
||||||
return(term_len(p, p->defindent + 1));
|
|
||||||
else if (0 == strcmp(v, "indent-two"))
|
|
||||||
return(term_len(p, (p->defindent + 1) * 2));
|
|
||||||
else if ( ! a2roffsu(v, &su, SCALE_MAX))
|
|
||||||
SCALE_HS_INIT(&su, term_strlen(p, v));
|
SCALE_HS_INIT(&su, term_strlen(p, v));
|
||||||
|
su.scale /= term_strlen(p, "0");
|
||||||
|
}
|
||||||
|
|
||||||
return(term_hspan(p, &su));
|
return(term_hspan(p, &su));
|
||||||
}
|
}
|
||||||
@ -585,16 +576,18 @@ print_bvspace(struct termp *p,
|
|||||||
|
|
||||||
/* Do not vspace directly after Ss/Sh. */
|
/* Do not vspace directly after Ss/Sh. */
|
||||||
|
|
||||||
for (nn = n; nn; nn = nn->parent) {
|
nn = n;
|
||||||
if (MDOC_BLOCK != nn->type)
|
while (nn->prev == NULL) {
|
||||||
continue;
|
do {
|
||||||
if (MDOC_Ss == nn->tok)
|
nn = nn->parent;
|
||||||
|
if (nn->type == MDOC_ROOT)
|
||||||
|
return;
|
||||||
|
} while (nn->type != MDOC_BLOCK);
|
||||||
|
if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss)
|
||||||
return;
|
return;
|
||||||
if (MDOC_Sh == nn->tok)
|
if (nn->tok == MDOC_It &&
|
||||||
return;
|
nn->parent->parent->norm->Bl.type != LIST_item)
|
||||||
if (NULL == nn->prev)
|
break;
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A `-column' does not assert vspace within the list. */
|
/* A `-column' does not assert vspace within the list. */
|
||||||
@ -650,7 +643,7 @@ termp_it_pre(DECL_ARGS)
|
|||||||
width = offset = 0;
|
width = offset = 0;
|
||||||
|
|
||||||
if (bl->norm->Bl.offs)
|
if (bl->norm->Bl.offs)
|
||||||
offset = a2offs(p, bl->norm->Bl.offs);
|
offset = a2width(p, bl->norm->Bl.offs);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LIST_column:
|
case LIST_column:
|
||||||
@ -808,7 +801,8 @@ termp_it_pre(DECL_ARGS)
|
|||||||
* the "overstep" effect in term_flushln() and treat
|
* the "overstep" effect in term_flushln() and treat
|
||||||
* this as a `-ohang' list instead.
|
* this as a `-ohang' list instead.
|
||||||
*/
|
*/
|
||||||
if (n->next->child &&
|
if (NULL != n->next &&
|
||||||
|
NULL != n->next->child &&
|
||||||
(MDOC_Bl == n->next->child->tok ||
|
(MDOC_Bl == n->next->child->tok ||
|
||||||
MDOC_Bd == n->next->child->tok))
|
MDOC_Bd == n->next->child->tok))
|
||||||
break;
|
break;
|
||||||
@ -864,7 +858,9 @@ termp_it_pre(DECL_ARGS)
|
|||||||
* don't want to recalculate rmargin and offsets when
|
* don't want to recalculate rmargin and offsets when
|
||||||
* using `Bd' or `Bl' within `-hang' overstep lists.
|
* using `Bd' or `Bl' within `-hang' overstep lists.
|
||||||
*/
|
*/
|
||||||
if (MDOC_HEAD == n->type && n->next->child &&
|
if (MDOC_HEAD == n->type &&
|
||||||
|
NULL != n->next &&
|
||||||
|
NULL != n->next->child &&
|
||||||
(MDOC_Bl == n->next->child->tok ||
|
(MDOC_Bl == n->next->child->tok ||
|
||||||
MDOC_Bd == n->next->child->tok))
|
MDOC_Bd == n->next->child->tok))
|
||||||
break;
|
break;
|
||||||
@ -881,11 +877,8 @@ termp_it_pre(DECL_ARGS)
|
|||||||
assert(width);
|
assert(width);
|
||||||
if (MDOC_HEAD == n->type)
|
if (MDOC_HEAD == n->type)
|
||||||
p->rmargin = p->offset + width;
|
p->rmargin = p->offset + width;
|
||||||
else {
|
else
|
||||||
p->offset += width;
|
p->offset += width;
|
||||||
if (p->rmargin < p->offset)
|
|
||||||
p->rmargin = p->offset;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case LIST_column:
|
case LIST_column:
|
||||||
assert(width);
|
assert(width);
|
||||||
@ -1002,6 +995,7 @@ termp_it_post(DECL_ARGS)
|
|||||||
static int
|
static int
|
||||||
termp_nm_pre(DECL_ARGS)
|
termp_nm_pre(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
const char *cp;
|
||||||
|
|
||||||
if (MDOC_BLOCK == n->type) {
|
if (MDOC_BLOCK == n->type) {
|
||||||
p->flags |= TERMP_PREKEEP;
|
p->flags |= TERMP_PREKEEP;
|
||||||
@ -1012,14 +1006,15 @@ termp_nm_pre(DECL_ARGS)
|
|||||||
if (NULL == n->child)
|
if (NULL == n->child)
|
||||||
return(0);
|
return(0);
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
p->offset += term_len(p, 1) +
|
cp = NULL;
|
||||||
(NULL == n->prev->child ?
|
if (n->prev->child != NULL)
|
||||||
term_strlen(p, meta->name) :
|
cp = n->prev->child->string;
|
||||||
MDOC_TEXT == n->prev->child->type ?
|
if (cp == NULL)
|
||||||
term_strlen(p, n->prev->child->string) :
|
cp = meta->name;
|
||||||
term_len(p, 5));
|
if (cp == NULL)
|
||||||
if (p->rmargin < p->offset)
|
p->offset += term_len(p, 6);
|
||||||
p->rmargin = p->offset;
|
else
|
||||||
|
p->offset += term_len(p, 1) + term_strlen(p, cp);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,7 +1024,8 @@ termp_nm_pre(DECL_ARGS)
|
|||||||
if (MDOC_HEAD == n->type)
|
if (MDOC_HEAD == n->type)
|
||||||
synopsis_pre(p, n->parent);
|
synopsis_pre(p, n->parent);
|
||||||
|
|
||||||
if (MDOC_HEAD == n->type && n->next->child) {
|
if (MDOC_HEAD == n->type &&
|
||||||
|
NULL != n->next && NULL != n->next->child) {
|
||||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND;
|
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND;
|
||||||
p->trailspace = 1;
|
p->trailspace = 1;
|
||||||
p->rmargin = p->offset + term_len(p, 1);
|
p->rmargin = p->offset + term_len(p, 1);
|
||||||
@ -1057,7 +1053,8 @@ termp_nm_post(DECL_ARGS)
|
|||||||
|
|
||||||
if (MDOC_BLOCK == n->type) {
|
if (MDOC_BLOCK == n->type) {
|
||||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||||
} else if (MDOC_HEAD == n->type && n->next->child) {
|
} else if (MDOC_HEAD == n->type &&
|
||||||
|
NULL != n->next && NULL != n->next->child) {
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
|
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
|
||||||
p->trailspace = 0;
|
p->trailspace = 0;
|
||||||
@ -1072,9 +1069,10 @@ termp_fl_pre(DECL_ARGS)
|
|||||||
term_fontpush(p, TERMFONT_BOLD);
|
term_fontpush(p, TERMFONT_BOLD);
|
||||||
term_word(p, "\\-");
|
term_word(p, "\\-");
|
||||||
|
|
||||||
if (n->child)
|
if ( ! (n->nchild == 0 &&
|
||||||
p->flags |= TERMP_NOSPACE;
|
(n->next == NULL ||
|
||||||
else if (n->next && n->next->line == n->line)
|
n->next->type == MDOC_TEXT ||
|
||||||
|
n->next->flags & MDOC_LINE)))
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
@ -1095,54 +1093,27 @@ static int
|
|||||||
termp_an_pre(DECL_ARGS)
|
termp_an_pre(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (NULL == n->child)
|
if (n->norm->An.auth == AUTH_split) {
|
||||||
return(1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If not in the AUTHORS section, `An -split' will cause
|
|
||||||
* newlines to occur before the author name. If in the AUTHORS
|
|
||||||
* section, by default, the first `An' invocation is nosplit,
|
|
||||||
* then all subsequent ones, regardless of whether interspersed
|
|
||||||
* with other macros/text, are split. -split, in this case,
|
|
||||||
* will override the condition of the implied first -nosplit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (n->sec == SEC_AUTHORS) {
|
|
||||||
if ( ! (TERMP_ANPREC & p->flags)) {
|
|
||||||
if (TERMP_SPLIT & p->flags)
|
|
||||||
term_newln(p);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
if (TERMP_NOSPLIT & p->flags)
|
|
||||||
return(1);
|
|
||||||
term_newln(p);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TERMP_SPLIT & p->flags)
|
|
||||||
term_newln(p);
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
termp_an_post(DECL_ARGS)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (n->child) {
|
|
||||||
if (SEC_AUTHORS == n->sec)
|
|
||||||
p->flags |= TERMP_ANPREC;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AUTH_split == n->norm->An.auth) {
|
|
||||||
p->flags &= ~TERMP_NOSPLIT;
|
p->flags &= ~TERMP_NOSPLIT;
|
||||||
p->flags |= TERMP_SPLIT;
|
p->flags |= TERMP_SPLIT;
|
||||||
} else if (AUTH_nosplit == n->norm->An.auth) {
|
return(0);
|
||||||
|
}
|
||||||
|
if (n->norm->An.auth == AUTH_nosplit) {
|
||||||
p->flags &= ~TERMP_SPLIT;
|
p->flags &= ~TERMP_SPLIT;
|
||||||
p->flags |= TERMP_NOSPLIT;
|
p->flags |= TERMP_NOSPLIT;
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n->child == NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (p->flags & TERMP_SPLIT)
|
||||||
|
term_newln(p);
|
||||||
|
|
||||||
|
if (n->sec == SEC_AUTHORS && ! (p->flags & TERMP_NOSPLIT))
|
||||||
|
p->flags |= TERMP_SPLIT;
|
||||||
|
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1256,14 +1227,8 @@ static int
|
|||||||
termp_nd_pre(DECL_ARGS)
|
termp_nd_pre(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MDOC_BODY != n->type)
|
if (n->type == MDOC_BODY)
|
||||||
return(1);
|
term_word(p, "\\(en");
|
||||||
|
|
||||||
#if defined(__OpenBSD__) || defined(__linux__)
|
|
||||||
term_word(p, "\\(en");
|
|
||||||
#else
|
|
||||||
term_word(p, "\\(em");
|
|
||||||
#endif
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1408,14 +1373,17 @@ static int
|
|||||||
termp_sh_pre(DECL_ARGS)
|
termp_sh_pre(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* No vspace between consecutive `Sh' calls. */
|
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case MDOC_BLOCK:
|
case MDOC_BLOCK:
|
||||||
if (n->prev && MDOC_Sh == n->prev->tok)
|
/*
|
||||||
if (NULL == n->prev->body->child)
|
* Vertical space before sections, except
|
||||||
break;
|
* when the previous section was empty.
|
||||||
term_vspace(p);
|
*/
|
||||||
|
if (n->prev == NULL ||
|
||||||
|
MDOC_Sh != n->prev->tok ||
|
||||||
|
(n->prev->body != NULL &&
|
||||||
|
n->prev->body->child != NULL))
|
||||||
|
term_vspace(p);
|
||||||
break;
|
break;
|
||||||
case MDOC_HEAD:
|
case MDOC_HEAD:
|
||||||
term_fontpush(p, TERMFONT_BOLD);
|
term_fontpush(p, TERMFONT_BOLD);
|
||||||
@ -1593,8 +1561,17 @@ termp_bd_pre(DECL_ARGS)
|
|||||||
} else if (MDOC_HEAD == n->type)
|
} else if (MDOC_HEAD == n->type)
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if (n->norm->Bd.offs)
|
/* Handle the -offset argument. */
|
||||||
p->offset += a2offs(p, n->norm->Bd.offs);
|
|
||||||
|
if (n->norm->Bd.offs == NULL ||
|
||||||
|
! strcmp(n->norm->Bd.offs, "left"))
|
||||||
|
/* nothing */;
|
||||||
|
else if ( ! strcmp(n->norm->Bd.offs, "indent"))
|
||||||
|
p->offset += term_len(p, p->defindent + 1);
|
||||||
|
else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
|
||||||
|
p->offset += term_len(p, (p->defindent + 1) * 2);
|
||||||
|
else
|
||||||
|
p->offset += a2width(p, n->norm->Bd.offs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If -ragged or -filled are specified, the block does nothing
|
* If -ragged or -filled are specified, the block does nothing
|
||||||
@ -1860,7 +1837,7 @@ termp_sp_pre(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
termp_es_pre(DECL_ARGS)
|
termp_skip_pre(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
@ -1877,7 +1854,8 @@ termp_quote_pre(DECL_ARGS)
|
|||||||
case MDOC_Ao:
|
case MDOC_Ao:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MDOC_Aq:
|
case MDOC_Aq:
|
||||||
term_word(p, "<");
|
term_word(p, n->parent->prev != NULL &&
|
||||||
|
n->parent->prev->tok == MDOC_An ? "<" : "\\(la");
|
||||||
break;
|
break;
|
||||||
case MDOC_Bro:
|
case MDOC_Bro:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -1938,17 +1916,19 @@ static void
|
|||||||
termp_quote_post(DECL_ARGS)
|
termp_quote_post(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MDOC_BODY != n->type && MDOC_ELEM != n->type)
|
if (n->type != MDOC_BODY && n->type != MDOC_ELEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (MDOC_En != n->tok)
|
if ( ! (n->tok == MDOC_En ||
|
||||||
|
(n->tok == MDOC_Eo && n->end == ENDBODY_SPACE)))
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
|
|
||||||
switch (n->tok) {
|
switch (n->tok) {
|
||||||
case MDOC_Ao:
|
case MDOC_Ao:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case MDOC_Aq:
|
case MDOC_Aq:
|
||||||
term_word(p, ">");
|
term_word(p, n->parent->prev != NULL &&
|
||||||
|
n->parent->prev->tok == MDOC_An ? ">" : "\\(ra");
|
||||||
break;
|
break;
|
||||||
case MDOC_Bro:
|
case MDOC_Bro:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
835
mdoc_validate.c
835
mdoc_validate.c
File diff suppressed because it is too large
Load Diff
6
msec.c
6
msec.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: msec.c,v 1.11 2014/03/23 11:25:26 schwarze Exp $ */
|
/* $Id: msec.c,v 1.12 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
6
msec.in
6
msec.in
@ -1,4 +1,4 @@
|
|||||||
/* $Id: msec.in,v 1.6 2010/06/19 20:46:28 kristaps Exp $ */
|
/* $Id: msec.in,v 1.7 2014/08/26 11:21:40 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -25,8 +25,8 @@
|
|||||||
LINE("1", "General Commands Manual")
|
LINE("1", "General Commands Manual")
|
||||||
LINE("2", "System Calls Manual")
|
LINE("2", "System Calls Manual")
|
||||||
LINE("3", "Library Functions Manual")
|
LINE("3", "Library Functions Manual")
|
||||||
LINE("3p", "Perl Library Functions Manual")
|
LINE("3p", "Perl Library Manual")
|
||||||
LINE("4", "Kernel Interfaces Manual")
|
LINE("4", "Device Drivers Manual")
|
||||||
LINE("5", "File Formats Manual")
|
LINE("5", "File Formats Manual")
|
||||||
LINE("6", "Games Manual")
|
LINE("6", "Games Manual")
|
||||||
LINE("7", "Miscellaneous Information Manual")
|
LINE("7", "Miscellaneous Information Manual")
|
||||||
|
80
out.c
80
out.c
@ -1,7 +1,7 @@
|
|||||||
/* $Id: out.c,v 1.49 2014/08/01 19:25:52 schwarze Exp $ */
|
/* $Id: out.c,v 1.53 2014/10/14 18:18:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -112,7 +110,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||||||
case '\0':
|
case '\0':
|
||||||
if (SCALE_MAX == def)
|
if (SCALE_MAX == def)
|
||||||
return(0);
|
return(0);
|
||||||
unit = SCALE_BU;
|
unit = SCALE_EN;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
unit = SCALE_BU;
|
unit = SCALE_BU;
|
||||||
@ -141,11 +139,14 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||||||
* used for the actual width calculations.
|
* used for the actual width calculations.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||||
|
size_t totalwidth)
|
||||||
{
|
{
|
||||||
const struct tbl_dat *dp;
|
const struct tbl_dat *dp;
|
||||||
struct roffcol *col;
|
struct roffcol *col;
|
||||||
|
size_t ewidth, xwidth;
|
||||||
int spans;
|
int spans;
|
||||||
|
int icol, maxcol, necol, nxcol;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate the master column specifiers. These will hold the
|
* Allocate the master column specifiers. These will hold the
|
||||||
@ -157,7 +158,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
|||||||
tbl->cols = mandoc_calloc((size_t)sp->opts->cols,
|
tbl->cols = mandoc_calloc((size_t)sp->opts->cols,
|
||||||
sizeof(struct roffcol));
|
sizeof(struct roffcol));
|
||||||
|
|
||||||
for ( ; sp; sp = sp->next) {
|
for (maxcol = -1; sp; sp = sp->next) {
|
||||||
if (TBL_SPAN_DATA != sp->pos)
|
if (TBL_SPAN_DATA != sp->pos)
|
||||||
continue;
|
continue;
|
||||||
spans = 1;
|
spans = 1;
|
||||||
@ -172,11 +173,72 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
|||||||
spans = dp->spans;
|
spans = dp->spans;
|
||||||
if (1 < spans)
|
if (1 < spans)
|
||||||
continue;
|
continue;
|
||||||
assert(dp->layout);
|
icol = dp->layout->head->ident;
|
||||||
col = &tbl->cols[dp->layout->head->ident];
|
if (maxcol < icol)
|
||||||
|
maxcol = icol;
|
||||||
|
col = tbl->cols + icol;
|
||||||
|
col->flags |= dp->layout->flags;
|
||||||
|
if (dp->layout->flags & TBL_CELL_WIGN)
|
||||||
|
continue;
|
||||||
tblcalc_data(tbl, col, sp->opts, dp);
|
tblcalc_data(tbl, col, sp->opts, dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count columns to equalize and columns to maximize.
|
||||||
|
* Find maximum width of the columns to equalize.
|
||||||
|
* Find total width of the columns *not* to maximize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
necol = nxcol = 0;
|
||||||
|
ewidth = xwidth = 0;
|
||||||
|
for (icol = 0; icol <= maxcol; icol++) {
|
||||||
|
col = tbl->cols + icol;
|
||||||
|
if (col->flags & TBL_CELL_EQUAL) {
|
||||||
|
necol++;
|
||||||
|
if (ewidth < col->width)
|
||||||
|
ewidth = col->width;
|
||||||
|
}
|
||||||
|
if (col->flags & TBL_CELL_WMAX)
|
||||||
|
nxcol++;
|
||||||
|
else
|
||||||
|
xwidth += col->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Equalize columns, if requested for any of them.
|
||||||
|
* Update total width of the columns not to maximize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (necol) {
|
||||||
|
for (icol = 0; icol <= maxcol; icol++) {
|
||||||
|
col = tbl->cols + icol;
|
||||||
|
if ( ! (col->flags & TBL_CELL_EQUAL))
|
||||||
|
continue;
|
||||||
|
if (col->width == ewidth)
|
||||||
|
continue;
|
||||||
|
if (nxcol && totalwidth)
|
||||||
|
xwidth += ewidth - col->width;
|
||||||
|
col->width = ewidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there are any columns to maximize, find the total
|
||||||
|
* available width, deducting 3n margins between columns.
|
||||||
|
* Distribute the available width evenly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (nxcol && totalwidth) {
|
||||||
|
xwidth = totalwidth - 3*maxcol - xwidth;
|
||||||
|
for (icol = 0; icol <= maxcol; icol++) {
|
||||||
|
col = tbl->cols + icol;
|
||||||
|
if ( ! (col->flags & TBL_CELL_WMAX))
|
||||||
|
continue;
|
||||||
|
col->width = xwidth / nxcol--;
|
||||||
|
xwidth -= col->width;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
8
out.h
8
out.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: out.h,v 1.22 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: out.h,v 1.24 2014/10/14 02:16:06 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -34,6 +34,7 @@ enum roffscale {
|
|||||||
struct roffcol {
|
struct roffcol {
|
||||||
size_t width; /* width of cell */
|
size_t width; /* width of cell */
|
||||||
size_t decimal; /* decimal position in cell */
|
size_t decimal; /* decimal position in cell */
|
||||||
|
int flags; /* layout flags, see tbl_cell */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct roffsu {
|
struct roffsu {
|
||||||
@ -59,12 +60,13 @@ __BEGIN_DECLS
|
|||||||
while (/* CONSTCOND */ 0)
|
while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
#define SCALE_HS_INIT(p, v) \
|
#define SCALE_HS_INIT(p, v) \
|
||||||
do { (p)->unit = SCALE_BU; \
|
do { (p)->unit = SCALE_EN; \
|
||||||
(p)->scale = (v); } \
|
(p)->scale = (v); } \
|
||||||
while (/* CONSTCOND */ 0)
|
while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
int a2roffsu(const char *, struct roffsu *, enum roffscale);
|
int a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||||
void tblcalc(struct rofftbl *tbl, const struct tbl_span *);
|
void tblcalc(struct rofftbl *tbl,
|
||||||
|
const struct tbl_span *, size_t);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
157
preconv.1
157
preconv.1
@ -1,157 +0,0 @@
|
|||||||
.\" $Id: preconv.1,v 1.7 2013/07/13 19:41:16 schwarze Exp $
|
|
||||||
.\"
|
|
||||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
|
||||||
.\"
|
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
|
||||||
.\" copyright notice and this permission notice appear in all copies.
|
|
||||||
.\"
|
|
||||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
.\"
|
|
||||||
.Dd $Mdocdate: July 13 2013 $
|
|
||||||
.Dt PRECONV 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm preconv
|
|
||||||
.Nd recode multibyte UNIX manuals
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm preconv
|
|
||||||
.Op Fl D Ar enc
|
|
||||||
.Op Fl e Ar enc
|
|
||||||
.Op Ar file
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility recodes multibyte
|
|
||||||
.Ux
|
|
||||||
manual files into
|
|
||||||
.Xr mandoc 1
|
|
||||||
.Po
|
|
||||||
or other troff system supporting the
|
|
||||||
.Sq \e[uNNNN]
|
|
||||||
escape sequence
|
|
||||||
.Pc
|
|
||||||
input.
|
|
||||||
.Pp
|
|
||||||
By default, it parses from standard output, determining encoding as
|
|
||||||
described in
|
|
||||||
.Sx Algorithm .
|
|
||||||
.Pp
|
|
||||||
Its arguments are as follows:
|
|
||||||
.Bl -tag -width Ds
|
|
||||||
.It Fl D Ar enc
|
|
||||||
The default encoding.
|
|
||||||
.It Fl e Ar enc
|
|
||||||
The document's encoding.
|
|
||||||
.It Ar file
|
|
||||||
The input file.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The recoded input is written to standard output: Unicode characters in
|
|
||||||
the ASCII range are printed as regular ASCII characters, while those
|
|
||||||
above this range are printed using the
|
|
||||||
.Sq \e[uNNNN]
|
|
||||||
format documented in
|
|
||||||
.Xr mandoc_char 7 .
|
|
||||||
.Pp
|
|
||||||
If input bytes are improperly formed in the current encoding, they're
|
|
||||||
passed unmodified to standard output.
|
|
||||||
For some encodings, such as UTF-8, unrecoverable input sequences will
|
|
||||||
cause
|
|
||||||
.Nm
|
|
||||||
to stop processing and exit.
|
|
||||||
.Ss Algorithm
|
|
||||||
An encoding is chosen according to the following steps:
|
|
||||||
.Bl -enum
|
|
||||||
.It
|
|
||||||
From the argument passed to
|
|
||||||
.Fl e Ar enc .
|
|
||||||
.It
|
|
||||||
If a BOM exists, UTF\-8 encoding is selected.
|
|
||||||
.It
|
|
||||||
From the coding tags parsed from
|
|
||||||
.Qq File Variables
|
|
||||||
on the first two lines of input.
|
|
||||||
A file variable is an input line of the form
|
|
||||||
.Pp
|
|
||||||
.Dl \%.\e\(dq -*- key: val [; key: val ]* -*-
|
|
||||||
.Pp
|
|
||||||
A coding tag variable is where
|
|
||||||
.Cm key
|
|
||||||
is
|
|
||||||
.Qq coding
|
|
||||||
and
|
|
||||||
.Cm val
|
|
||||||
is the name of the encoding.
|
|
||||||
A typical file variable with a coding tag is
|
|
||||||
.Pp
|
|
||||||
.Dl \%.\e\(dq -*- mode: troff; coding: utf-8 -*-
|
|
||||||
.It
|
|
||||||
From the argument passed to
|
|
||||||
.Fl D Ar enc .
|
|
||||||
.It
|
|
||||||
If all else fails, Latin\-1 is used.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility recognises the UTF\-8, us\-ascii, and latin\-1 encodings as
|
|
||||||
passed to the
|
|
||||||
.Fl e
|
|
||||||
and
|
|
||||||
.Fl D
|
|
||||||
arguments, or as coding tags.
|
|
||||||
Encodings are matched case-insensitively.
|
|
||||||
.\" .Sh IMPLEMENTATION NOTES
|
|
||||||
.\" Not used in OpenBSD.
|
|
||||||
.\" .Sh RETURN VALUES
|
|
||||||
.\" For sections 2, 3, & 9 only.
|
|
||||||
.\" .Sh ENVIRONMENT
|
|
||||||
.\" For sections 1, 6, 7, & 8 only.
|
|
||||||
.\" .Sh FILES
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
.Ex -std
|
|
||||||
.Sh EXAMPLES
|
|
||||||
Explicitly page a UTF\-8 manual
|
|
||||||
.Pa foo.1
|
|
||||||
in the current locale:
|
|
||||||
.Pp
|
|
||||||
.Dl $ preconv \-e utf\-8 foo.1 | mandoc -Tlocale | less
|
|
||||||
.\" .Sh DIAGNOSTICS
|
|
||||||
.\" For sections 1, 4, 6, 7, & 8 only.
|
|
||||||
.\" .Sh ERRORS
|
|
||||||
.\" For sections 2, 3, & 9 only.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr mandoc 1 ,
|
|
||||||
.Xr mandoc_char 7
|
|
||||||
.Sh STANDARDS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility references the US-ASCII character set standard, ANSI_X3.4\-1968;
|
|
||||||
the Latin\-1 character set standard, ISO/IEC 8859\-1:1998; the UTF\-8
|
|
||||||
character set standard; and UCS (Unicode), ISO/IEC 10646.
|
|
||||||
.Sh HISTORY
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility first appeared in the GNU troff
|
|
||||||
.Pq Dq groff
|
|
||||||
system in December 2005, authored by Tomohiro Kubota and Werner
|
|
||||||
Lemberg.
|
|
||||||
The implementation that is part of the
|
|
||||||
.Xr mandoc 1
|
|
||||||
utility appeared in May 2011.
|
|
||||||
.Sh AUTHORS
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
utility was written by
|
|
||||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
|
||||||
.\" .Sh CAVEATS
|
|
||||||
.\" .Sh BUGS
|
|
||||||
.\" .Sh SECURITY CONSIDERATIONS
|
|
||||||
.\" Not used in OpenBSD.
|
|
460
preconv.c
460
preconv.c
@ -1,6 +1,7 @@
|
|||||||
/* $Id: preconv.c,v 1.6 2013/06/02 03:52:21 schwarze Exp $ */
|
/* $Id: preconv.c,v 1.12 2014/11/14 04:24:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -14,325 +15,132 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include "mandoc.h"
|
||||||
|
#include "libmandoc.h"
|
||||||
|
|
||||||
/*
|
int
|
||||||
* The read_whole_file() and resize_buf() functions are copied from
|
preconv_encode(struct buf *ib, size_t *ii, struct buf *ob, size_t *oi,
|
||||||
* read.c, including all dependency code.
|
int *filenc)
|
||||||
*/
|
|
||||||
|
|
||||||
enum enc {
|
|
||||||
ENC_UTF_8, /* UTF-8 */
|
|
||||||
ENC_US_ASCII, /* US-ASCII */
|
|
||||||
ENC_LATIN_1, /* Latin-1 */
|
|
||||||
ENC__MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
struct buf {
|
|
||||||
char *buf; /* binary input buffer */
|
|
||||||
size_t sz; /* size of binary buffer */
|
|
||||||
size_t offs; /* starting buffer offset */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct encode {
|
|
||||||
const char *name;
|
|
||||||
int (*conv)(const struct buf *);
|
|
||||||
};
|
|
||||||
|
|
||||||
static int cue_enc(const struct buf *, size_t *, enum enc *);
|
|
||||||
static int conv_latin_1(const struct buf *);
|
|
||||||
static int conv_us_ascii(const struct buf *);
|
|
||||||
static int conv_utf_8(const struct buf *);
|
|
||||||
static int read_whole_file(const char *, int,
|
|
||||||
struct buf *, int *);
|
|
||||||
static void resize_buf(struct buf *, size_t);
|
|
||||||
static void usage(void);
|
|
||||||
|
|
||||||
static const struct encode encs[ENC__MAX] = {
|
|
||||||
{ "utf-8", conv_utf_8 }, /* ENC_UTF_8 */
|
|
||||||
{ "us-ascii", conv_us_ascii }, /* ENC_US_ASCII */
|
|
||||||
{ "latin-1", conv_latin_1 }, /* ENC_LATIN_1 */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *progname;
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
fprintf(stderr, "usage: %s "
|
|
||||||
"[-D enc] "
|
|
||||||
"[-e ENC] "
|
|
||||||
"[file]\n", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
conv_latin_1(const struct buf *b)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
unsigned char cu;
|
int state;
|
||||||
const char *cp;
|
|
||||||
|
|
||||||
cp = b->buf + (int)b->offs;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Latin-1 falls into the first 256 code-points of Unicode, so
|
|
||||||
* there's no need for any sort of translation. Just make the
|
|
||||||
* 8-bit characters use the Unicode escape.
|
|
||||||
* Note that binary values 128 < v < 160 are passed through
|
|
||||||
* unmodified to mandoc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = b->offs; i < b->sz; i++) {
|
|
||||||
cu = (unsigned char)*cp++;
|
|
||||||
cu < 160U ? putchar(cu) : printf("\\[u%.4X]", cu);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
conv_us_ascii(const struct buf *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* US-ASCII has no conversion since it falls into the first 128
|
|
||||||
* bytes of Unicode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fwrite(b->buf, 1, b->sz, stdout);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
conv_utf_8(const struct buf *b)
|
|
||||||
{
|
|
||||||
int state, be;
|
|
||||||
unsigned int accum;
|
unsigned int accum;
|
||||||
size_t i;
|
|
||||||
unsigned char cu;
|
unsigned char cu;
|
||||||
const char *cp;
|
|
||||||
const long one = 1L;
|
|
||||||
|
|
||||||
cp = b->buf + (int)b->offs;
|
if ( ! (*filenc & MPARSE_UTF8))
|
||||||
|
goto latin;
|
||||||
|
|
||||||
state = 0;
|
state = 0;
|
||||||
accum = 0U;
|
accum = 0U;
|
||||||
be = 0;
|
|
||||||
|
|
||||||
/* Quick test for big-endian value. */
|
for (i = *ii; i < ib->sz; i++) {
|
||||||
|
cu = ib->buf[i];
|
||||||
if ( ! (*((const char *)(&one))))
|
|
||||||
be = 1;
|
|
||||||
|
|
||||||
for (i = b->offs; i < b->sz; i++) {
|
|
||||||
cu = (unsigned char)*cp++;
|
|
||||||
if (state) {
|
if (state) {
|
||||||
if ( ! (cu & 128) || (cu & 64)) {
|
if ( ! (cu & 128) || (cu & 64)) {
|
||||||
/* Bad sequence header. */
|
/* Bad sequence header. */
|
||||||
return(0);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept only legitimate bit patterns. */
|
/* Accept only legitimate bit patterns. */
|
||||||
|
|
||||||
if (cu > 191 || cu < 128) {
|
if (cu > 191 || cu < 128) {
|
||||||
/* Bad in-sequence bits. */
|
/* Bad in-sequence bits. */
|
||||||
return(0);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
accum |= (cu & 63) << --state * 6;
|
accum |= (cu & 63) << --state * 6;
|
||||||
|
|
||||||
/*
|
if (state)
|
||||||
* Accum is held in little-endian order as
|
continue;
|
||||||
* stipulated by the UTF-8 sequence coding. We
|
|
||||||
* need to convert to a native big-endian if our
|
|
||||||
* architecture requires it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (0 == state && be)
|
if (accum < 0x80)
|
||||||
accum = (accum >> 24) |
|
ob->buf[(*oi)++] = accum;
|
||||||
((accum << 8) & 0x00FF0000) |
|
else
|
||||||
((accum >> 8) & 0x0000FF00) |
|
*oi += snprintf(ob->buf + *oi,
|
||||||
(accum << 24);
|
11, "\\[u%.4X]", accum);
|
||||||
|
*ii = i + 1;
|
||||||
if (0 == state) {
|
*filenc &= ~MPARSE_LATIN1;
|
||||||
accum < 128U ? putchar(accum) :
|
return(1);
|
||||||
printf("\\[u%.4X]", accum);
|
} else {
|
||||||
accum = 0U;
|
|
||||||
}
|
|
||||||
} else if (cu & (1 << 7)) {
|
|
||||||
/*
|
/*
|
||||||
* Entering a UTF-8 state: if we encounter a
|
* Entering a UTF-8 state: if we encounter a
|
||||||
* UTF-8 bitmask, calculate the expected UTF-8
|
* UTF-8 bitmask, calculate the expected UTF-8
|
||||||
* state from it.
|
* state from it.
|
||||||
*/
|
*/
|
||||||
for (state = 0; state < 7; state++)
|
for (state = 0; state < 7; state++)
|
||||||
if ( ! (cu & (1 << (7 - state))))
|
if ( ! (cu & (1 << (7 - state))))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Accept only legitimate bit patterns. */
|
/* Accept only legitimate bit patterns. */
|
||||||
|
|
||||||
switch (state) {
|
switch (state--) {
|
||||||
case (4):
|
case (4):
|
||||||
if (cu <= 244 && cu >= 240) {
|
if (cu <= 244 && cu >= 240) {
|
||||||
accum = (cu & 7) << 18;
|
accum = (cu & 7) << 18;
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
/* Bad 4-sequence start bits. */
|
/* Bad 4-sequence start bits. */
|
||||||
return(0);
|
break;
|
||||||
case (3):
|
case (3):
|
||||||
if (cu <= 239 && cu >= 224) {
|
if (cu <= 239 && cu >= 224) {
|
||||||
accum = (cu & 15) << 12;
|
accum = (cu & 15) << 12;
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
/* Bad 3-sequence start bits. */
|
/* Bad 3-sequence start bits. */
|
||||||
return(0);
|
break;
|
||||||
case (2):
|
case (2):
|
||||||
if (cu <= 223 && cu >= 194) {
|
if (cu <= 223 && cu >= 194) {
|
||||||
accum = (cu & 31) << 6;
|
accum = (cu & 31) << 6;
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
/* Bad 2-sequence start bits. */
|
/* Bad 2-sequence start bits. */
|
||||||
return(0);
|
break;
|
||||||
default:
|
default:
|
||||||
/* Bad sequence bit mask. */
|
/* Bad sequence bit mask. */
|
||||||
return(0);
|
break;
|
||||||
}
|
}
|
||||||
state--;
|
break;
|
||||||
} else
|
}
|
||||||
putchar(cu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != state) {
|
/* FALLTHROUGH: Invalid or incomplete UTF-8 sequence. */
|
||||||
/* Bad trailing bits. */
|
|
||||||
|
latin:
|
||||||
|
if ( ! (*filenc & MPARSE_LATIN1))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
|
||||||
|
|
||||||
|
*oi += snprintf(ob->buf + *oi, 11,
|
||||||
|
"\\[u%.4X]", (unsigned char)ib->buf[(*ii)++]);
|
||||||
|
|
||||||
|
*filenc &= ~MPARSE_UTF8;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int
|
||||||
resize_buf(struct buf *buf, size_t initial)
|
preconv_cue(const struct buf *b, size_t offset)
|
||||||
{
|
|
||||||
|
|
||||||
buf->sz = buf->sz > initial / 2 ?
|
|
||||||
2 * buf->sz : initial;
|
|
||||||
|
|
||||||
buf->buf = realloc(buf->buf, buf->sz);
|
|
||||||
if (NULL == buf->buf) {
|
|
||||||
perror(NULL);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
read_whole_file(const char *f, int fd,
|
|
||||||
struct buf *fb, int *with_mmap)
|
|
||||||
{
|
|
||||||
size_t off;
|
|
||||||
ssize_t ssz;
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
struct stat st;
|
|
||||||
if (-1 == fstat(fd, &st)) {
|
|
||||||
perror(f);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're a regular file, try just reading in the whole entry
|
|
||||||
* via mmap(). This is faster than reading it into blocks, and
|
|
||||||
* since each file is only a few bytes to begin with, I'm not
|
|
||||||
* concerned that this is going to tank any machines.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode) && st.st_size >= (1U << 31)) {
|
|
||||||
fprintf(stderr, "%s: input too large\n", f);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode)) {
|
|
||||||
*with_mmap = 1;
|
|
||||||
fb->sz = (size_t)st.st_size;
|
|
||||||
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
|
|
||||||
if (fb->buf != MAP_FAILED)
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this isn't a regular file (like, say, stdin), then we must
|
|
||||||
* go the old way and just read things in bit by bit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
*with_mmap = 0;
|
|
||||||
off = 0;
|
|
||||||
fb->sz = 0;
|
|
||||||
fb->buf = NULL;
|
|
||||||
for (;;) {
|
|
||||||
if (off == fb->sz && fb->sz == (1U << 31)) {
|
|
||||||
fprintf(stderr, "%s: input too large\n", f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (off == fb->sz)
|
|
||||||
resize_buf(fb, 65536);
|
|
||||||
|
|
||||||
ssz = read(fd, fb->buf + (int)off, fb->sz - off);
|
|
||||||
if (ssz == 0) {
|
|
||||||
fb->sz = off;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
if (ssz == -1) {
|
|
||||||
perror(f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
off += (size_t)ssz;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(fb->buf);
|
|
||||||
fb->buf = NULL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
cue_enc(const struct buf *b, size_t *offs, enum enc *enc)
|
|
||||||
{
|
{
|
||||||
const char *ln, *eoln, *eoph;
|
const char *ln, *eoln, *eoph;
|
||||||
size_t sz, phsz, nsz;
|
size_t sz, phsz;
|
||||||
int i;
|
|
||||||
|
|
||||||
ln = b->buf + (int)*offs;
|
ln = b->buf + offset;
|
||||||
sz = b->sz - *offs;
|
sz = b->sz - offset;
|
||||||
|
|
||||||
/* Look for the end-of-line. */
|
/* Look for the end-of-line. */
|
||||||
|
|
||||||
if (NULL == (eoln = memchr(ln, '\n', sz)))
|
if (NULL == (eoln = memchr(ln, '\n', sz)))
|
||||||
return(-1);
|
eoln = ln + sz;
|
||||||
|
|
||||||
/* Set next-line marker. */
|
|
||||||
|
|
||||||
*offs = (size_t)((eoln + 1) - b->buf);
|
|
||||||
|
|
||||||
/* Check if we have the correct header/trailer. */
|
/* Check if we have the correct header/trailer. */
|
||||||
|
|
||||||
if ((sz = (size_t)(eoln - ln)) < 10 ||
|
if ((sz = (size_t)(eoln - ln)) < 10 ||
|
||||||
memcmp(ln, ".\\\" -*-", 7) ||
|
memcmp(ln, ".\\\" -*-", 7) || memcmp(eoln - 3, "-*-", 3))
|
||||||
memcmp(eoln - 3, "-*-", 3))
|
return(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* Move after the header and adjust for the trailer. */
|
/* Move after the header and adjust for the trailer. */
|
||||||
|
|
||||||
@ -356,12 +164,12 @@ cue_enc(const struct buf *b, size_t *offs, enum enc *enc)
|
|||||||
|
|
||||||
/* Only account for the "coding" phrase. */
|
/* Only account for the "coding" phrase. */
|
||||||
|
|
||||||
if ((phsz = (size_t)(eoph - ln)) < 7 ||
|
if ((phsz = eoph - ln) < 7 ||
|
||||||
strncasecmp(ln, "coding:", 7)) {
|
strncasecmp(ln, "coding:", 7)) {
|
||||||
sz -= phsz;
|
sz -= phsz;
|
||||||
ln += phsz;
|
ln += phsz;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sz -= 7;
|
sz -= 7;
|
||||||
ln += 7;
|
ln += 7;
|
||||||
@ -371,153 +179,15 @@ cue_enc(const struct buf *b, size_t *offs, enum enc *enc)
|
|||||||
sz--;
|
sz--;
|
||||||
}
|
}
|
||||||
if (0 == sz)
|
if (0 == sz)
|
||||||
break;
|
return(0);
|
||||||
|
|
||||||
/* Check us against known encodings. */
|
/* Check us against known encodings. */
|
||||||
|
|
||||||
for (i = 0; i < (int)ENC__MAX; i++) {
|
if (phsz > 4 && !strncasecmp(ln, "utf-8", 5))
|
||||||
nsz = strlen(encs[i].name);
|
return(MPARSE_UTF8);
|
||||||
if (phsz < nsz)
|
if (phsz > 10 && !strncasecmp(ln, "iso-latin-1", 11))
|
||||||
continue;
|
return(MPARSE_LATIN1);
|
||||||
if (strncasecmp(ln, encs[i].name, nsz))
|
return(0);
|
||||||
continue;
|
|
||||||
|
|
||||||
*enc = (enum enc)i;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unknown encoding. */
|
|
||||||
|
|
||||||
*enc = ENC__MAX;
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
return(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i, ch, map, fd, rc;
|
|
||||||
struct buf b;
|
|
||||||
const char *fn;
|
|
||||||
enum enc enc, def;
|
|
||||||
unsigned char bom[3] = { 0xEF, 0xBB, 0xBF };
|
|
||||||
size_t offs;
|
|
||||||
extern int optind;
|
|
||||||
extern char *optarg;
|
|
||||||
|
|
||||||
progname = strrchr(argv[0], '/');
|
|
||||||
if (progname == NULL)
|
|
||||||
progname = argv[0];
|
|
||||||
else
|
|
||||||
++progname;
|
|
||||||
|
|
||||||
fn = "<stdin>";
|
|
||||||
fd = STDIN_FILENO;
|
|
||||||
rc = EXIT_FAILURE;
|
|
||||||
enc = def = ENC__MAX;
|
|
||||||
map = 0;
|
|
||||||
|
|
||||||
memset(&b, 0, sizeof(struct buf));
|
|
||||||
|
|
||||||
while (-1 != (ch = getopt(argc, argv, "D:e:rdvh")))
|
|
||||||
switch (ch) {
|
|
||||||
case ('D'):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case ('e'):
|
|
||||||
for (i = 0; i < (int)ENC__MAX; i++) {
|
|
||||||
if (strcasecmp(optarg, encs[i].name))
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i < (int)ENC__MAX) {
|
|
||||||
if ('D' == ch)
|
|
||||||
def = (enum enc)i;
|
|
||||||
else
|
|
||||||
enc = (enum enc)i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "%s: Bad encoding\n", optarg);
|
|
||||||
return(EXIT_FAILURE);
|
|
||||||
case ('r'):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case ('d'):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case ('v'):
|
|
||||||
/* Compatibility with GNU preconv. */
|
|
||||||
break;
|
|
||||||
case ('h'):
|
|
||||||
/* Compatibility with GNU preconv. */
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
return(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open and read the first argument on the command-line.
|
|
||||||
* If we don't have one, we default to stdin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (argc > 0) {
|
|
||||||
fn = *argv;
|
|
||||||
fd = open(fn, O_RDONLY, 0);
|
|
||||||
if (-1 == fd) {
|
|
||||||
perror(fn);
|
|
||||||
return(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! read_whole_file(fn, fd, &b, &map))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Try to read the UTF-8 BOM. */
|
|
||||||
|
|
||||||
if (ENC__MAX == enc)
|
|
||||||
if (b.sz > 3 && 0 == memcmp(b.buf, bom, 3)) {
|
|
||||||
b.offs = 3;
|
|
||||||
enc = ENC_UTF_8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try reading from the "-*-" cue. */
|
|
||||||
|
|
||||||
if (ENC__MAX == enc) {
|
|
||||||
offs = b.offs;
|
|
||||||
ch = cue_enc(&b, &offs, &enc);
|
|
||||||
if (0 == ch)
|
|
||||||
ch = cue_enc(&b, &offs, &enc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* No encoding has been detected.
|
|
||||||
* Thus, we either fall into our default encoder, if specified,
|
|
||||||
* or use Latin-1 if all else fails.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ENC__MAX == enc)
|
|
||||||
enc = ENC__MAX == def ? ENC_LATIN_1 : def;
|
|
||||||
|
|
||||||
if ( ! (*encs[(int)enc].conv)(&b)) {
|
|
||||||
fprintf(stderr, "%s: Bad encoding\n", fn);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = EXIT_SUCCESS;
|
|
||||||
out:
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
if (map)
|
|
||||||
munmap(b.buf, b.sz);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
free(b.buf);
|
|
||||||
|
|
||||||
if (fd > STDIN_FILENO)
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return(rc);
|
|
||||||
}
|
}
|
||||||
|
430
read.c
430
read.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: read.c,v 1.79 2014/08/06 15:09:05 schwarze Exp $ */
|
/* $Id: read.c,v 1.101 2014/11/28 18:09:01 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -16,14 +16,14 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#include <sys/types.h>
|
||||||
# include <sys/stat.h>
|
#if HAVE_MMAP
|
||||||
# include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -45,32 +45,31 @@
|
|||||||
|
|
||||||
#define REPARSE_LIMIT 1000
|
#define REPARSE_LIMIT 1000
|
||||||
|
|
||||||
struct buf {
|
|
||||||
char *buf; /* binary input buffer */
|
|
||||||
size_t sz; /* size of binary buffer */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mparse {
|
struct mparse {
|
||||||
enum mandoclevel file_status; /* status of current parse */
|
|
||||||
enum mandoclevel wlevel; /* ignore messages below this */
|
|
||||||
int line; /* line number in the file */
|
|
||||||
int options; /* parser options */
|
|
||||||
struct man *pman; /* persistent man parser */
|
struct man *pman; /* persistent man parser */
|
||||||
struct mdoc *pmdoc; /* persistent mdoc parser */
|
struct mdoc *pmdoc; /* persistent mdoc parser */
|
||||||
struct man *man; /* man parser */
|
struct man *man; /* man parser */
|
||||||
struct mdoc *mdoc; /* mdoc parser */
|
struct mdoc *mdoc; /* mdoc parser */
|
||||||
struct roff *roff; /* roff parser (!NULL) */
|
struct roff *roff; /* roff parser (!NULL) */
|
||||||
|
const struct mchars *mchars; /* character table */
|
||||||
char *sodest; /* filename pointed to by .so */
|
char *sodest; /* filename pointed to by .so */
|
||||||
int reparse_count; /* finite interp. stack */
|
const char *file; /* filename of current input file */
|
||||||
mandocmsg mmsg; /* warning/error message handler */
|
struct buf *primary; /* buffer currently being parsed */
|
||||||
const char *file;
|
struct buf *secondary; /* preprocessed copy of input */
|
||||||
struct buf *secondary;
|
|
||||||
const char *defos; /* default operating system */
|
const char *defos; /* default operating system */
|
||||||
|
mandocmsg mmsg; /* warning/error message handler */
|
||||||
|
enum mandoclevel file_status; /* status of current parse */
|
||||||
|
enum mandoclevel wlevel; /* ignore messages below this */
|
||||||
|
int options; /* parser options */
|
||||||
|
int filenc; /* encoding of the current file */
|
||||||
|
int reparse_count; /* finite interp. stack */
|
||||||
|
int line; /* line number in the file */
|
||||||
|
pid_t child; /* the gunzip(1) process */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void choose_parser(struct mparse *);
|
||||||
static void resize_buf(struct buf *, size_t);
|
static void resize_buf(struct buf *, size_t);
|
||||||
static void mparse_buf_r(struct mparse *, struct buf, int);
|
static void mparse_buf_r(struct mparse *, struct buf, size_t, int);
|
||||||
static void pset(const char *, int, struct mparse *);
|
|
||||||
static int read_whole_file(struct mparse *, const char *, int,
|
static int read_whole_file(struct mparse *, const char *, int,
|
||||||
struct buf *, int *);
|
struct buf *, int *);
|
||||||
static void mparse_end(struct mparse *);
|
static void mparse_end(struct mparse *);
|
||||||
@ -98,7 +97,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"lower case character in document title",
|
"lower case character in document title",
|
||||||
"missing manual section, using \"\"",
|
"missing manual section, using \"\"",
|
||||||
"unknown manual section",
|
"unknown manual section",
|
||||||
"unknown manual volume or arch",
|
|
||||||
"missing date, using today's date",
|
"missing date, using today's date",
|
||||||
"cannot parse date, using it verbatim",
|
"cannot parse date, using it verbatim",
|
||||||
"missing Os macro, using \"\"",
|
"missing Os macro, using \"\"",
|
||||||
@ -116,6 +114,9 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"sections out of conventional order",
|
"sections out of conventional order",
|
||||||
"duplicate section title",
|
"duplicate section title",
|
||||||
"unexpected section",
|
"unexpected section",
|
||||||
|
"unusual Xr order",
|
||||||
|
"unusual Xr punctuation",
|
||||||
|
"AUTHORS section without An macro",
|
||||||
|
|
||||||
/* related to macros and nesting */
|
/* related to macros and nesting */
|
||||||
"obsolete macro",
|
"obsolete macro",
|
||||||
@ -145,6 +146,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"missing font type, using \\fR",
|
"missing font type, using \\fR",
|
||||||
"unknown font type, using \\fR",
|
"unknown font type, using \\fR",
|
||||||
"missing -std argument, adding it",
|
"missing -std argument, adding it",
|
||||||
|
"missing eqn box, using \"\"",
|
||||||
|
|
||||||
/* related to bad macro arguments */
|
/* related to bad macro arguments */
|
||||||
"unterminated quoted argument",
|
"unterminated quoted argument",
|
||||||
@ -154,6 +156,8 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"skipping duplicate list type",
|
"skipping duplicate list type",
|
||||||
"skipping -width argument",
|
"skipping -width argument",
|
||||||
"unknown AT&T UNIX version",
|
"unknown AT&T UNIX version",
|
||||||
|
"comma in function argument",
|
||||||
|
"parenthesis in function name",
|
||||||
"invalid content in Rs block",
|
"invalid content in Rs block",
|
||||||
"invalid Boolean argument",
|
"invalid Boolean argument",
|
||||||
"unknown font, skipping request",
|
"unknown font, skipping request",
|
||||||
@ -173,7 +177,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"equation scope open on exit",
|
"equation scope open on exit",
|
||||||
"overlapping equation scopes",
|
"overlapping equation scopes",
|
||||||
"unexpected end of equation",
|
"unexpected end of equation",
|
||||||
"equation syntax error",
|
|
||||||
|
|
||||||
/* related to tables */
|
/* related to tables */
|
||||||
"bad table syntax",
|
"bad table syntax",
|
||||||
@ -198,6 +201,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
/* related to request and macro arguments */
|
/* related to request and macro arguments */
|
||||||
"escaped character not allowed in a name",
|
"escaped character not allowed in a name",
|
||||||
"argument count wrong",
|
"argument count wrong",
|
||||||
|
"NOT IMPLEMENTED: Bd -file",
|
||||||
"missing list type, using -item",
|
"missing list type, using -item",
|
||||||
"missing manual name, using \"\"",
|
"missing manual name, using \"\"",
|
||||||
"uname(3) system call failed, using UNKNOWN",
|
"uname(3) system call failed, using UNKNOWN",
|
||||||
@ -205,18 +209,25 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"skipping request without numeric argument",
|
"skipping request without numeric argument",
|
||||||
"skipping all arguments",
|
"skipping all arguments",
|
||||||
"skipping excess arguments",
|
"skipping excess arguments",
|
||||||
|
"divide by zero",
|
||||||
|
|
||||||
"generic fatal error",
|
"generic fatal error",
|
||||||
|
|
||||||
"input too large",
|
"input too large",
|
||||||
"NOT IMPLEMENTED: Bd -file",
|
|
||||||
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
||||||
".so request failed",
|
".so request failed",
|
||||||
|
|
||||||
/* system errors */
|
/* system errors */
|
||||||
|
"cannot dup file descriptor",
|
||||||
|
"cannot exec",
|
||||||
|
"gunzip failed with code",
|
||||||
|
"cannot fork",
|
||||||
NULL,
|
NULL,
|
||||||
"cannot stat file",
|
"cannot open pipe",
|
||||||
"cannot read file",
|
"cannot read file",
|
||||||
|
"gunzip died from signal",
|
||||||
|
"cannot stat file",
|
||||||
|
"wait failed",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
||||||
@ -239,38 +250,40 @@ resize_buf(struct buf *buf, size_t initial)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pset(const char *buf, int pos, struct mparse *curp)
|
choose_parser(struct mparse *curp)
|
||||||
{
|
{
|
||||||
int i;
|
char *cp, *ep;
|
||||||
|
int format;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to intuit which kind of manual parser should be used. If
|
* If neither command line arguments -mdoc or -man select
|
||||||
* passed in by command-line (-man, -mdoc), then use that
|
* a parser nor the roff parser found a .Dd or .TH macro
|
||||||
* explicitly. If passed as -mandoc, then try to guess from the
|
* yet, look ahead in the main input buffer.
|
||||||
* line: either skip dot-lines, use -mdoc when finding `.Dt', or
|
|
||||||
* default to -man, which is more lenient.
|
|
||||||
*
|
|
||||||
* Separate out pmdoc/pman from mdoc/man: the first persists
|
|
||||||
* through all parsers, while the latter is used per-parse.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ('.' == buf[0] || '\'' == buf[0]) {
|
if ((format = roff_getformat(curp->roff)) == 0) {
|
||||||
for (i = 1; buf[i]; i++)
|
cp = curp->primary->buf;
|
||||||
if (' ' != buf[i] && '\t' != buf[i])
|
ep = cp + curp->primary->sz;
|
||||||
|
while (cp < ep) {
|
||||||
|
if (*cp == '.' || *cp == '\'') {
|
||||||
|
cp++;
|
||||||
|
if (cp[0] == 'D' && cp[1] == 'd') {
|
||||||
|
format = MPARSE_MDOC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (cp[0] == 'T' && cp[1] == 'H') {
|
||||||
|
format = MPARSE_MAN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cp = memchr(cp, '\n', ep - cp);
|
||||||
|
if (cp == NULL)
|
||||||
break;
|
break;
|
||||||
if ('\0' == buf[i])
|
cp++;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MPARSE_MDOC & curp->options) {
|
if (format == MPARSE_MDOC) {
|
||||||
curp->mdoc = curp->pmdoc;
|
|
||||||
return;
|
|
||||||
} else if (MPARSE_MAN & curp->options) {
|
|
||||||
curp->man = curp->pman;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
|
|
||||||
if (NULL == curp->pmdoc)
|
if (NULL == curp->pmdoc)
|
||||||
curp->pmdoc = mdoc_alloc(
|
curp->pmdoc = mdoc_alloc(
|
||||||
curp->roff, curp, curp->defos,
|
curp->roff, curp, curp->defos,
|
||||||
@ -280,6 +293,8 @@ pset(const char *buf, int pos, struct mparse *curp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fall back to man(7) as a last resort. */
|
||||||
|
|
||||||
if (NULL == curp->pman)
|
if (NULL == curp->pman)
|
||||||
curp->pman = man_alloc(curp->roff, curp,
|
curp->pman = man_alloc(curp->roff, curp,
|
||||||
MPARSE_QUICK & curp->options ? 1 : 0);
|
MPARSE_QUICK & curp->options ? 1 : 0);
|
||||||
@ -288,36 +303,43 @@ pset(const char *buf, int pos, struct mparse *curp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main parse routine for an opened file. This is called for each
|
* Main parse routine for a buffer.
|
||||||
* opened file and simply loops around the full input file, possibly
|
* It assumes encoding and line numbering are already set up.
|
||||||
* nesting (i.e., with `so').
|
* It can recurse directly (for invocations of user-defined
|
||||||
|
* macros, inline equations, and input line traps)
|
||||||
|
* and indirectly (for .so file inclusion).
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||||
{
|
{
|
||||||
const struct tbl_span *span;
|
const struct tbl_span *span;
|
||||||
struct buf ln;
|
struct buf ln;
|
||||||
|
size_t pos; /* byte number in the ln buffer */
|
||||||
enum rofferr rr;
|
enum rofferr rr;
|
||||||
int i, of, rc;
|
int of;
|
||||||
int pos; /* byte number in the ln buffer */
|
|
||||||
int lnn; /* line number in the real file */
|
int lnn; /* line number in the real file */
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
memset(&ln, 0, sizeof(struct buf));
|
memset(&ln, 0, sizeof(ln));
|
||||||
|
|
||||||
lnn = curp->line;
|
lnn = curp->line;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
|
||||||
for (i = 0; i < (int)blk.sz; ) {
|
while (i < blk.sz) {
|
||||||
if (0 == pos && '\0' == blk.buf[i])
|
if (0 == pos && '\0' == blk.buf[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (start) {
|
if (start) {
|
||||||
curp->line = lnn;
|
curp->line = lnn;
|
||||||
curp->reparse_count = 0;
|
curp->reparse_count = 0;
|
||||||
|
|
||||||
|
if (lnn < 3 &&
|
||||||
|
curp->filenc & MPARSE_UTF8 &&
|
||||||
|
curp->filenc & MPARSE_LATIN1)
|
||||||
|
curp->filenc = preconv_cue(&blk, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {
|
while (i < blk.sz && (start || blk.buf[i] != '\0')) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When finding an unescaped newline character,
|
* When finding an unescaped newline character,
|
||||||
@ -325,7 +347,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
* Skip a preceding carriage return, if any.
|
* Skip a preceding carriage return, if any.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\r' == blk.buf[i] && i + 1 < (int)blk.sz &&
|
if ('\r' == blk.buf[i] && i + 1 < blk.sz &&
|
||||||
'\n' == blk.buf[i + 1])
|
'\n' == blk.buf[i + 1])
|
||||||
++i;
|
++i;
|
||||||
if ('\n' == blk.buf[i]) {
|
if ('\n' == blk.buf[i]) {
|
||||||
@ -335,27 +357,35 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure we have space for at least
|
* Make sure we have space for the worst
|
||||||
* one backslash and one other character
|
* case of 11 bytes: "\\[u10ffff]\0"
|
||||||
* and the trailing NUL byte.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (pos + 2 >= (int)ln.sz)
|
if (pos + 11 > ln.sz)
|
||||||
resize_buf(&ln, 256);
|
resize_buf(&ln, 256);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Warn about bogus characters. If you're using
|
* Encode 8-bit input.
|
||||||
* non-ASCII encoding, you're screwing your
|
|
||||||
* readers. Since I'd rather this not happen,
|
|
||||||
* I'll be helpful and replace these characters
|
|
||||||
* with "?", so we don't display gibberish.
|
|
||||||
* Note to manual writers: use special characters.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
c = (unsigned char) blk.buf[i];
|
c = blk.buf[i];
|
||||||
|
if (c & 0x80) {
|
||||||
|
if ( ! (curp->filenc && preconv_encode(
|
||||||
|
&blk, &i, &ln, &pos, &curp->filenc))) {
|
||||||
|
mandoc_vmsg(MANDOCERR_BADCHAR,
|
||||||
|
curp, curp->line, pos,
|
||||||
|
"0x%x", c);
|
||||||
|
ln.buf[pos++] = '?';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! (isascii(c) &&
|
/*
|
||||||
(isgraph(c) || isblank(c)))) {
|
* Exclude control characters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (c == 0x7f || (c < 0x20 && c != 0x09)) {
|
||||||
mandoc_vmsg(MANDOCERR_BADCHAR, curp,
|
mandoc_vmsg(MANDOCERR_BADCHAR, curp,
|
||||||
curp->line, pos, "0x%x", c);
|
curp->line, pos, "0x%x", c);
|
||||||
i++;
|
i++;
|
||||||
@ -365,7 +395,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
|
|
||||||
/* Trailing backslash = a plain char. */
|
/* Trailing backslash = a plain char. */
|
||||||
|
|
||||||
if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) {
|
if (blk.buf[i] != '\\' || i + 1 == blk.sz) {
|
||||||
ln.buf[pos++] = blk.buf[i++];
|
ln.buf[pos++] = blk.buf[i++];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -377,7 +407,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
* skip that one as well.
|
* skip that one as well.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\r' == blk.buf[i + 1] && i + 2 < (int)blk.sz &&
|
if ('\r' == blk.buf[i + 1] && i + 2 < blk.sz &&
|
||||||
'\n' == blk.buf[i + 2])
|
'\n' == blk.buf[i + 2])
|
||||||
++i;
|
++i;
|
||||||
if ('\n' == blk.buf[i + 1]) {
|
if ('\n' == blk.buf[i + 1]) {
|
||||||
@ -389,7 +419,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
|
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
|
||||||
i += 2;
|
i += 2;
|
||||||
/* Comment, skip to end of line */
|
/* Comment, skip to end of line */
|
||||||
for (; i < (int)blk.sz; ++i) {
|
for (; i < blk.sz; ++i) {
|
||||||
if ('\n' == blk.buf[i]) {
|
if ('\n' == blk.buf[i]) {
|
||||||
++i;
|
++i;
|
||||||
++lnn;
|
++lnn;
|
||||||
@ -426,7 +456,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
ln.buf[pos++] = blk.buf[i++];
|
ln.buf[pos++] = blk.buf[i++];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos >= (int)ln.sz)
|
if (pos >= ln.sz)
|
||||||
resize_buf(&ln, 256);
|
resize_buf(&ln, 256);
|
||||||
|
|
||||||
ln.buf[pos] = '\0';
|
ln.buf[pos] = '\0';
|
||||||
@ -463,20 +493,19 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
[curp->secondary->sz] = '\0';
|
[curp->secondary->sz] = '\0';
|
||||||
}
|
}
|
||||||
rerun:
|
rerun:
|
||||||
rr = roff_parseln(curp->roff, curp->line,
|
rr = roff_parseln(curp->roff, curp->line, &ln, &of);
|
||||||
&ln.buf, &ln.sz, of, &of);
|
|
||||||
|
|
||||||
switch (rr) {
|
switch (rr) {
|
||||||
case ROFF_REPARSE:
|
case ROFF_REPARSE:
|
||||||
if (REPARSE_LIMIT >= ++curp->reparse_count)
|
if (REPARSE_LIMIT >= ++curp->reparse_count)
|
||||||
mparse_buf_r(curp, ln, 0);
|
mparse_buf_r(curp, ln, of, 0);
|
||||||
else
|
else
|
||||||
mandoc_msg(MANDOCERR_ROFFLOOP, curp,
|
mandoc_msg(MANDOCERR_ROFFLOOP, curp,
|
||||||
curp->line, pos, NULL);
|
curp->line, pos, NULL);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
continue;
|
continue;
|
||||||
case ROFF_APPEND:
|
case ROFF_APPEND:
|
||||||
pos = (int)strlen(ln.buf);
|
pos = strlen(ln.buf);
|
||||||
continue;
|
continue;
|
||||||
case ROFF_RERUN:
|
case ROFF_RERUN:
|
||||||
goto rerun;
|
goto rerun;
|
||||||
@ -487,8 +516,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||||
break;
|
break;
|
||||||
case ROFF_SO:
|
case ROFF_SO:
|
||||||
if (0 == (MPARSE_SO & curp->options) &&
|
if ( ! (curp->options & MPARSE_SO) &&
|
||||||
(i >= (int)blk.sz || '\0' == blk.buf[i])) {
|
(i >= blk.sz || blk.buf[i] == '\0')) {
|
||||||
curp->sodest = mandoc_strdup(ln.buf + of);
|
curp->sodest = mandoc_strdup(ln.buf + of);
|
||||||
free(ln.buf);
|
free(ln.buf);
|
||||||
return;
|
return;
|
||||||
@ -529,12 +558,10 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! (curp->man || curp->mdoc))
|
if ( ! (curp->man || curp->mdoc))
|
||||||
pset(ln.buf + of, pos - of, curp);
|
choose_parser(curp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lastly, push down into the parsers themselves. One
|
* Lastly, push down into the parsers themselves.
|
||||||
* of these will have already been set in the pset()
|
|
||||||
* routine.
|
|
||||||
* If libroff returns ROFF_TBL, then add it to the
|
* If libroff returns ROFF_TBL, then add it to the
|
||||||
* currently open parse. Since we only get here if
|
* currently open parse. Since we only get here if
|
||||||
* there does exist data (see tbl_data.c), we're
|
* there does exist data (see tbl_data.c), we're
|
||||||
@ -542,34 +569,21 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
* Do the same for ROFF_EQN.
|
* Do the same for ROFF_EQN.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rc = -1;
|
if (rr == ROFF_TBL) {
|
||||||
|
while ((span = roff_span(curp->roff)) != NULL)
|
||||||
if (ROFF_TBL == rr)
|
if (curp->man == NULL)
|
||||||
while (NULL != (span = roff_span(curp->roff))) {
|
mdoc_addspan(curp->mdoc, span);
|
||||||
rc = curp->man ?
|
else
|
||||||
man_addspan(curp->man, span) :
|
man_addspan(curp->man, span);
|
||||||
mdoc_addspan(curp->mdoc, span);
|
} else if (rr == ROFF_EQN) {
|
||||||
if (0 == rc)
|
if (curp->man == NULL)
|
||||||
break;
|
mdoc_addeqn(curp->mdoc, roff_eqn(curp->roff));
|
||||||
}
|
else
|
||||||
else if (ROFF_EQN == rr)
|
man_addeqn(curp->man, roff_eqn(curp->roff));
|
||||||
rc = curp->mdoc ?
|
} else if ((curp->man == NULL ?
|
||||||
mdoc_addeqn(curp->mdoc,
|
mdoc_parseln(curp->mdoc, curp->line, ln.buf, of) :
|
||||||
roff_eqn(curp->roff)) :
|
man_parseln(curp->man, curp->line, ln.buf, of)) == 2)
|
||||||
man_addeqn(curp->man,
|
break;
|
||||||
roff_eqn(curp->roff));
|
|
||||||
else if (curp->man || curp->mdoc)
|
|
||||||
rc = curp->man ?
|
|
||||||
man_parseln(curp->man,
|
|
||||||
curp->line, ln.buf, of) :
|
|
||||||
mdoc_parseln(curp->mdoc,
|
|
||||||
curp->line, ln.buf, of);
|
|
||||||
|
|
||||||
if (0 == rc) {
|
|
||||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
|
||||||
break;
|
|
||||||
} else if (2 == rc)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Temporary buffers typically are not full. */
|
/* Temporary buffers typically are not full. */
|
||||||
|
|
||||||
@ -591,7 +605,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
|||||||
size_t off;
|
size_t off;
|
||||||
ssize_t ssz;
|
ssize_t ssz;
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#if HAVE_MMAP
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (-1 == fstat(fd, &st)) {
|
if (-1 == fstat(fd, &st)) {
|
||||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
@ -702,7 +716,9 @@ mparse_end(struct mparse *curp)
|
|||||||
static void
|
static void
|
||||||
mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file)
|
mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file)
|
||||||
{
|
{
|
||||||
|
struct buf *svprimary;
|
||||||
const char *svfile;
|
const char *svfile;
|
||||||
|
size_t offset;
|
||||||
static int recursion_depth;
|
static int recursion_depth;
|
||||||
|
|
||||||
if (64 < recursion_depth) {
|
if (64 < recursion_depth) {
|
||||||
@ -713,14 +729,27 @@ mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file)
|
|||||||
/* Line number is per-file. */
|
/* Line number is per-file. */
|
||||||
svfile = curp->file;
|
svfile = curp->file;
|
||||||
curp->file = file;
|
curp->file = file;
|
||||||
|
svprimary = curp->primary;
|
||||||
|
curp->primary = &blk;
|
||||||
curp->line = 1;
|
curp->line = 1;
|
||||||
recursion_depth++;
|
recursion_depth++;
|
||||||
|
|
||||||
mparse_buf_r(curp, blk, 1);
|
/* Skip an UTF-8 byte order mark. */
|
||||||
|
if (curp->filenc & MPARSE_UTF8 && blk.sz > 2 &&
|
||||||
|
(unsigned char)blk.buf[0] == 0xef &&
|
||||||
|
(unsigned char)blk.buf[1] == 0xbb &&
|
||||||
|
(unsigned char)blk.buf[2] == 0xbf) {
|
||||||
|
offset = 3;
|
||||||
|
curp->filenc &= ~MPARSE_LATIN1;
|
||||||
|
} else
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
mparse_buf_r(curp, blk, offset, 1);
|
||||||
|
|
||||||
if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status)
|
if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status)
|
||||||
mparse_end(curp);
|
mparse_end(curp);
|
||||||
|
|
||||||
|
curp->primary = svprimary;
|
||||||
curp->file = svfile;
|
curp->file = svfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,49 +766,159 @@ mparse_readmem(struct mparse *curp, const void *buf, size_t len,
|
|||||||
return(curp->file_status);
|
return(curp->file_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a file descriptor is given, use it and assume it points
|
||||||
|
* to the named file. Otherwise, open the named file.
|
||||||
|
* Read the whole file into memory and call the parsers.
|
||||||
|
* Called recursively when an .so request is encountered.
|
||||||
|
*/
|
||||||
enum mandoclevel
|
enum mandoclevel
|
||||||
mparse_readfd(struct mparse *curp, int fd, const char *file)
|
mparse_readfd(struct mparse *curp, int fd, const char *file)
|
||||||
{
|
{
|
||||||
struct buf blk;
|
struct buf blk;
|
||||||
int with_mmap;
|
int with_mmap;
|
||||||
|
int save_filenc;
|
||||||
|
pid_t save_child;
|
||||||
|
|
||||||
if (-1 == fd && -1 == (fd = open(file, O_RDONLY, 0))) {
|
save_child = curp->child;
|
||||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
if (fd != -1)
|
||||||
if (curp->mmsg)
|
curp->child = 0;
|
||||||
(*curp->mmsg)(MANDOCERR_SYSOPEN,
|
else if (mparse_open(curp, &fd, file) >= MANDOCLEVEL_SYSERR)
|
||||||
curp->file_status,
|
|
||||||
file, 0, 0, strerror(errno));
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (read_whole_file(curp, file, fd, &blk, &with_mmap)) {
|
||||||
|
save_filenc = curp->filenc;
|
||||||
|
curp->filenc = curp->options &
|
||||||
|
(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (fd != STDIN_FILENO && close(fd) == -1)
|
||||||
* Run for each opened file; may be called more than once for
|
|
||||||
* each full parse sequence if the opened file is nested (i.e.,
|
|
||||||
* from `so'). Simply sucks in the whole file and moves into
|
|
||||||
* the parse phase for the file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( ! read_whole_file(curp, file, fd, &blk, &with_mmap))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mparse_parse_buffer(curp, blk, file);
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
if (with_mmap)
|
|
||||||
munmap(blk.buf, blk.sz);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
free(blk.buf);
|
|
||||||
|
|
||||||
if (STDIN_FILENO != fd && -1 == close(fd))
|
|
||||||
perror(file);
|
perror(file);
|
||||||
|
|
||||||
|
mparse_wait(curp);
|
||||||
out:
|
out:
|
||||||
|
curp->child = save_child;
|
||||||
return(curp->file_status);
|
return(curp->file_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mandoclevel
|
||||||
|
mparse_open(struct mparse *curp, int *fd, const char *file)
|
||||||
|
{
|
||||||
|
int pfd[2];
|
||||||
|
int save_errno;
|
||||||
|
char *cp;
|
||||||
|
enum mandocerr err;
|
||||||
|
|
||||||
|
pfd[1] = -1;
|
||||||
|
curp->file = file;
|
||||||
|
|
||||||
|
/* Unless zipped, try to just open the file. */
|
||||||
|
|
||||||
|
if ((cp = strrchr(file, '.')) == NULL ||
|
||||||
|
strcmp(cp + 1, "gz")) {
|
||||||
|
curp->child = 0;
|
||||||
|
if ((*fd = open(file, O_RDONLY)) != -1)
|
||||||
|
return(MANDOCLEVEL_OK);
|
||||||
|
|
||||||
|
/* Open failed; try to append ".gz". */
|
||||||
|
|
||||||
|
mandoc_asprintf(&cp, "%s.gz", file);
|
||||||
|
file = cp;
|
||||||
|
} else
|
||||||
|
cp = NULL;
|
||||||
|
|
||||||
|
/* Before forking, make sure the file can be read. */
|
||||||
|
|
||||||
|
save_errno = errno;
|
||||||
|
if (access(file, R_OK) == -1) {
|
||||||
|
if (cp != NULL)
|
||||||
|
errno = save_errno;
|
||||||
|
err = MANDOCERR_SYSOPEN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run gunzip(1). */
|
||||||
|
|
||||||
|
if (pipe(pfd) == -1) {
|
||||||
|
err = MANDOCERR_SYSPIPE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (curp->child = fork()) {
|
||||||
|
case -1:
|
||||||
|
err = MANDOCERR_SYSFORK;
|
||||||
|
close(pfd[0]);
|
||||||
|
close(pfd[1]);
|
||||||
|
pfd[1] = -1;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
close(pfd[0]);
|
||||||
|
if (dup2(pfd[1], STDOUT_FILENO) == -1) {
|
||||||
|
err = MANDOCERR_SYSDUP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
execlp("gunzip", "gunzip", "-c", file, NULL);
|
||||||
|
err = MANDOCERR_SYSEXEC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
close(pfd[1]);
|
||||||
|
*fd = pfd[0];
|
||||||
|
return(MANDOCLEVEL_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(cp);
|
||||||
|
*fd = -1;
|
||||||
|
curp->child = 0;
|
||||||
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
if (curp->mmsg)
|
||||||
|
(*curp->mmsg)(err, curp->file_status, curp->file,
|
||||||
|
0, 0, strerror(errno));
|
||||||
|
if (pfd[1] != -1)
|
||||||
|
exit(1);
|
||||||
|
return(curp->file_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mandoclevel
|
||||||
|
mparse_wait(struct mparse *curp)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (curp->child == 0)
|
||||||
|
return(MANDOCLEVEL_OK);
|
||||||
|
|
||||||
|
if (waitpid(curp->child, &status, 0) == -1) {
|
||||||
|
mandoc_msg(MANDOCERR_SYSWAIT, curp, 0, 0,
|
||||||
|
strerror(errno));
|
||||||
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
return(curp->file_status);
|
||||||
|
}
|
||||||
|
if (WIFSIGNALED(status)) {
|
||||||
|
mandoc_vmsg(MANDOCERR_SYSSIG, curp, 0, 0,
|
||||||
|
"%d", WTERMSIG(status));
|
||||||
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
return(curp->file_status);
|
||||||
|
}
|
||||||
|
if (WEXITSTATUS(status)) {
|
||||||
|
mandoc_vmsg(MANDOCERR_SYSEXIT, curp, 0, 0,
|
||||||
|
"%d", WEXITSTATUS(status));
|
||||||
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
return(curp->file_status);
|
||||||
|
}
|
||||||
|
return(MANDOCLEVEL_OK);
|
||||||
|
}
|
||||||
|
|
||||||
struct mparse *
|
struct mparse *
|
||||||
mparse_alloc(int options, enum mandoclevel wlevel,
|
mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||||
mandocmsg mmsg, const char *defos)
|
const struct mchars *mchars, const char *defos)
|
||||||
{
|
{
|
||||||
struct mparse *curp;
|
struct mparse *curp;
|
||||||
|
|
||||||
@ -792,7 +931,8 @@ mparse_alloc(int options, enum mandoclevel wlevel,
|
|||||||
curp->mmsg = mmsg;
|
curp->mmsg = mmsg;
|
||||||
curp->defos = defos;
|
curp->defos = defos;
|
||||||
|
|
||||||
curp->roff = roff_alloc(curp, options);
|
curp->mchars = mchars;
|
||||||
|
curp->roff = roff_alloc(curp, curp->mchars, options);
|
||||||
if (curp->options & MPARSE_MDOC)
|
if (curp->options & MPARSE_MDOC)
|
||||||
curp->pmdoc = mdoc_alloc(
|
curp->pmdoc = mdoc_alloc(
|
||||||
curp->roff, curp, curp->defos,
|
curp->roff, curp, curp->defos,
|
||||||
|
27
roff.7
27
roff.7
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: roff.7,v 1.55 2014/07/07 11:35:06 schwarze Exp $
|
.\" $Id: roff.7,v 1.59 2014/11/19 01:20:25 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: July 7 2014 $
|
.Dd $Mdocdate: November 19 2014 $
|
||||||
.Dt ROFF 7
|
.Dt ROFF 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -239,8 +239,9 @@ pica (~1/6 inch)
|
|||||||
.It p
|
.It p
|
||||||
point (~1/72 inch)
|
point (~1/72 inch)
|
||||||
.It f
|
.It f
|
||||||
synonym for
|
scale
|
||||||
.Sq u
|
.Sq u
|
||||||
|
by 65536
|
||||||
.It v
|
.It v
|
||||||
default vertical span
|
default vertical span
|
||||||
.It m
|
.It m
|
||||||
@ -254,7 +255,7 @@ width of rendered
|
|||||||
.Pq en
|
.Pq en
|
||||||
character
|
character
|
||||||
.It u
|
.It u
|
||||||
default horizontal span
|
default horizontal span for the terminal
|
||||||
.It M
|
.It M
|
||||||
mini-em (~1/100 em)
|
mini-em (~1/100 em)
|
||||||
.El
|
.El
|
||||||
@ -262,7 +263,6 @@ mini-em (~1/100 em)
|
|||||||
Using anything other than
|
Using anything other than
|
||||||
.Sq m ,
|
.Sq m ,
|
||||||
.Sq n ,
|
.Sq n ,
|
||||||
.Sq u ,
|
|
||||||
or
|
or
|
||||||
.Sq v
|
.Sq v
|
||||||
is necessarily non-portable across output media.
|
is necessarily non-portable across output media.
|
||||||
@ -747,16 +747,18 @@ If the first character of COND is
|
|||||||
.Pq even page ,
|
.Pq even page ,
|
||||||
.Sq r
|
.Sq r
|
||||||
.Pq register accessed ,
|
.Pq register accessed ,
|
||||||
or
|
|
||||||
.Sq t
|
.Sq t
|
||||||
.Pq troff mode ,
|
.Pq troff mode ,
|
||||||
|
or
|
||||||
|
.Sq v
|
||||||
|
.Pq vroff mode ,
|
||||||
COND evaluates to false.
|
COND evaluates to false.
|
||||||
.It
|
.It
|
||||||
If COND starts with a parenthesis or with an optionally signed
|
If COND starts with a parenthesis or with an optionally signed
|
||||||
integer number, it is evaluated according to the rules of
|
integer number, it is evaluated according to the rules of
|
||||||
.Sx Numerical expressions
|
.Sx Numerical expressions
|
||||||
explained below.
|
explained below.
|
||||||
It evaluates to true if the the result is positive,
|
It evaluates to true if the result is positive,
|
||||||
or to false if the result is zero or negative.
|
or to false if the result is zero or negative.
|
||||||
.It
|
.It
|
||||||
Otherwise, the first character of COND is regarded as a delimiter
|
Otherwise, the first character of COND is regarded as a delimiter
|
||||||
@ -935,6 +937,11 @@ Turn on no-space mode.
|
|||||||
This line-scoped request is intended to take no arguments.
|
This line-scoped request is intended to take no arguments.
|
||||||
Currently, it is ignored including its arguments,
|
Currently, it is ignored including its arguments,
|
||||||
and the number of arguments is not checked.
|
and the number of arguments is not checked.
|
||||||
|
.Ss \&pl
|
||||||
|
Change page length.
|
||||||
|
This line-scoped request is intended to take one height argument.
|
||||||
|
Currently, it is ignored including its arguments,
|
||||||
|
and the number of arguments is not checked.
|
||||||
.Ss \&ps
|
.Ss \&ps
|
||||||
Change point size.
|
Change point size.
|
||||||
This line-scoped request is intended to take one numerical argument.
|
This line-scoped request is intended to take one numerical argument.
|
||||||
@ -1348,6 +1355,12 @@ refers to groff version 1.15.
|
|||||||
.Pp
|
.Pp
|
||||||
.Bl -dash -compact
|
.Bl -dash -compact
|
||||||
.It
|
.It
|
||||||
|
The
|
||||||
|
.Sq u
|
||||||
|
scaling unit is the default terminal unit.
|
||||||
|
In traditional troff systems, this unit would change depending on the
|
||||||
|
output media.
|
||||||
|
.It
|
||||||
In mandoc, the
|
In mandoc, the
|
||||||
.Sx \&EQ ,
|
.Sx \&EQ ,
|
||||||
.Sx \&TE ,
|
.Sx \&TE ,
|
||||||
|
6
st.c
6
st.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: st.c,v 1.10 2014/03/23 11:25:26 schwarze Exp $ */
|
/* $Id: st.c,v 1.11 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
9
st.in
9
st.in
@ -1,4 +1,4 @@
|
|||||||
/* $Id: st.in,v 1.24 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: st.in,v 1.26 2014/11/16 20:46:21 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -42,13 +42,9 @@ LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)")
|
|||||||
LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)")
|
LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)")
|
||||||
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)")
|
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)")
|
||||||
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)")
|
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)")
|
||||||
LINE("-p1003.1j-2000", "IEEE Std 1003.1j-2000 (\\(lqPOSIX.1j\\(rq)")
|
|
||||||
LINE("-p1003.1q-2000", "IEEE Std 1003.1q-2000 (\\(lqPOSIX.1q\\(rq)")
|
|
||||||
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
|
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
|
||||||
LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)")
|
LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)")
|
||||||
LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)")
|
LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)")
|
||||||
LINE("-p1387.2", "IEEE Std 1387.2 (\\(lqPOSIX.7.2\\(rq)")
|
|
||||||
LINE("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)")
|
|
||||||
LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
||||||
LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
||||||
LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO\\~C90, Amendment 1\\(rq)")
|
LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO\\~C90, Amendment 1\\(rq)")
|
||||||
@ -76,8 +72,9 @@ LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\
|
|||||||
LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)")
|
LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)")
|
||||||
LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)")
|
LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)")
|
||||||
LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)")
|
LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)")
|
||||||
LINE("-xns5.2d2.0", "X/Open Networking Services Issue\\~5.2 Draft\\~2.0 (\\(lqXNS5.2D2.0\\(rq)")
|
|
||||||
LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)")
|
LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)")
|
||||||
|
LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(lqSUSv1\\(rq)")
|
||||||
LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(lqSUSv2\\(rq)")
|
LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(lqSUSv2\\(rq)")
|
||||||
LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(lqSUSv3\\(rq)")
|
LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(lqSUSv3\\(rq)")
|
||||||
|
LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(lqSUSv4\\(rq)")
|
||||||
LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
|
LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: style.css,v 1.25 2011/08/26 09:03:17 kristaps Exp $ */
|
/* $Id: style.css,v 1.30 2014/09/27 11:16:24 kristaps Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an example style-sheet provided for mandoc(1) and the -Thtml
|
* This is an example style-sheet provided for mandoc(1) and the -Thtml
|
||||||
@ -20,16 +20,17 @@ blockquote { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1. */
|
|||||||
div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
|
div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
|
||||||
div.subsection { } /* Sub-sections (Ss, SS). */
|
div.subsection { } /* Sub-sections (Ss, SS). */
|
||||||
table.synopsis { } /* SYNOPSIS section table. */
|
table.synopsis { } /* SYNOPSIS section table. */
|
||||||
|
div.spacer { margin: 1em 0; }
|
||||||
|
|
||||||
/* Preamble structure. */
|
/* Preamble structure. */
|
||||||
|
|
||||||
table.foot { font-size: smaller; margin-top: 1em; border-top: 1px dotted #dddddd; } /* Document footer. */
|
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-date { width: 50%; } /* Document footer: date. */
|
||||||
td.foot-os { width: 50%; text-align: right; } /* Document footer: OS/source. */
|
td.foot-os { width: 50%; } /* Document footer: OS/source. */
|
||||||
table.head { font-size: smaller; margin-bottom: 1em; border-bottom: 1px dotted #dddddd; } /* Document header. */
|
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-ltitle { width: 10%; } /* Document header: left-title. */
|
||||||
td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */
|
td.head-vol { width: 80%; } /* Document header: volume. */
|
||||||
td.head-rtitle { width: 10%; text-align: right; } /* Document header: right-title. */
|
td.head-rtitle { width: 10%; } /* Document header: right-title. */
|
||||||
|
|
||||||
/* General font modes. */
|
/* General font modes. */
|
||||||
|
|
||||||
|
62
tbl.7
62
tbl.7
@ -1,6 +1,7 @@
|
|||||||
.\" $Id: tbl.7,v 1.18 2013/09/16 22:39:19 schwarze Exp $
|
.\" $Id: tbl.7,v 1.21 2014/11/26 17:51:55 schwarze Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
.\" Permission to use, copy, modify, and distribute this software for any
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
.\" purpose with or without fee is hereby granted, provided that the above
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -14,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 16 2013 $
|
.Dd $Mdocdate: November 26 2014 $
|
||||||
.Dt TBL 7
|
.Dt TBL 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -134,6 +135,7 @@ in the case of
|
|||||||
.Ss Options
|
.Ss Options
|
||||||
The first line of a table consists of space-separated option keys and
|
The first line of a table consists of space-separated option keys and
|
||||||
modifiers terminated by a semicolon.
|
modifiers terminated by a semicolon.
|
||||||
|
For GNU compatibility, option keys can also be separated by commas.
|
||||||
If the first line does not have a terminating semicolon, it is assumed
|
If the first line does not have a terminating semicolon, it is assumed
|
||||||
that no options are specified and instead a
|
that no options are specified and instead a
|
||||||
.Sx Layout
|
.Sx Layout
|
||||||
@ -195,7 +197,7 @@ Each layout line corresponds to a line of data; the last layout line
|
|||||||
applies to all remaining data lines.
|
applies to all remaining data lines.
|
||||||
Layout lines may also be separated by a comma.
|
Layout lines may also be separated by a comma.
|
||||||
Each layout cell consists of one of the following case-insensitive keys:
|
Each layout cell consists of one of the following case-insensitive keys:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width 2n
|
||||||
.It Cm c
|
.It Cm c
|
||||||
Centre a literal string within its column.
|
Centre a literal string within its column.
|
||||||
.It Cm r
|
.It Cm r
|
||||||
@ -244,35 +246,45 @@ Keys may be followed by a set of modifiers.
|
|||||||
A modifier is either a modifier key or a natural number for specifying
|
A modifier is either a modifier key or a natural number for specifying
|
||||||
the minimum width of a column.
|
the minimum width of a column.
|
||||||
The following case-insensitive modifier keys are available:
|
The following case-insensitive modifier keys are available:
|
||||||
.Cm z ,
|
.Bl -tag -width 2n
|
||||||
.Cm u ,
|
.It Cm b
|
||||||
.Cm e ,
|
Use a bold font for the contents of this column.
|
||||||
.Cm t ,
|
.It Cm e
|
||||||
|
Make this column wider to match the maximum width
|
||||||
|
of any other column also having the
|
||||||
|
.Cm e
|
||||||
|
modifier.
|
||||||
|
.It Cm f
|
||||||
|
The next character selects the font to use for this column.
|
||||||
|
See the
|
||||||
|
.Xr roff 7
|
||||||
|
manual for supported one-character font names.
|
||||||
|
.It Cm i
|
||||||
|
Use an italic font for the contents of this column.
|
||||||
|
.It Cm x
|
||||||
|
After determining the width of all other columns, distribute the
|
||||||
|
rest of the line length among all columns having the
|
||||||
|
.Cm x
|
||||||
|
modifier.
|
||||||
|
.It Cm z
|
||||||
|
Do not use this cell for determining the width of this column.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The modifiers
|
||||||
.Cm d ,
|
.Cm d ,
|
||||||
.Cm b ,
|
.Cm t ,
|
||||||
.Cm i ,
|
.Cm u ,
|
||||||
.Cm r ,
|
|
||||||
and
|
and
|
||||||
.Cm f
|
.Cm w
|
||||||
.Po
|
are ignored by
|
||||||
followed by
|
|
||||||
.Cm b ,
|
|
||||||
.Cm i ,
|
|
||||||
.Cm r ,
|
|
||||||
.Cm 3 ,
|
|
||||||
.Cm 2 ,
|
|
||||||
or
|
|
||||||
.Cm 1
|
|
||||||
.Pc .
|
|
||||||
All of these are ignored by
|
|
||||||
.Xr mandoc 1 .
|
.Xr mandoc 1 .
|
||||||
.Pp
|
.Pp
|
||||||
For example, the following layout specifies a centre-justified column of
|
For example, the following layout specifies a centre-justified column of
|
||||||
minimum width 10, followed by vertical bar, followed by a left-justified
|
minimum width 10, followed by vertical bar, followed by a left-justified
|
||||||
column of minimum width 10, another vertical bar, then a column
|
column of minimum width 10, another vertical bar, then a column using
|
||||||
justified about the decimal point in numbers:
|
bold font justified about the decimal point in numbers:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl c10 | l10 | n
|
.Dl c10 | l10 | nfB
|
||||||
.Ss Data
|
.Ss Data
|
||||||
The data section follows the last layout row.
|
The data section follows the last layout row.
|
||||||
By default, cells in a data section are delimited by a tab.
|
By default, cells in a data section are delimited by a tab.
|
||||||
|
6
tbl.c
6
tbl.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl.c,v 1.29 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: tbl.c,v 1.30 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_data.c,v 1.31 2014/04/23 16:08:33 schwarze Exp $ */
|
/* $Id: tbl_data.c,v 1.32 2014/08/10 23:54:41 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_html.c,v 1.11 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: tbl_html.c,v 1.13 2014/10/14 02:16:06 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -57,7 +57,7 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
|
|||||||
if (TBL_SPAN_FIRST & sp->flags) {
|
if (TBL_SPAN_FIRST & sp->flags) {
|
||||||
h->tbl.len = html_tbl_len;
|
h->tbl.len = html_tbl_len;
|
||||||
h->tbl.slen = html_tbl_strlen;
|
h->tbl.slen = html_tbl_strlen;
|
||||||
tblcalc(&h->tbl, sp);
|
tblcalc(&h->tbl, sp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(NULL == h->tblt);
|
assert(NULL == h->tblt);
|
||||||
|
111
tbl_layout.c
111
tbl_layout.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_layout.c,v 1.26 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: tbl_layout.c,v 1.30 2014/11/25 21:41:47 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -59,7 +59,6 @@ static int mods(struct tbl_node *, struct tbl_cell *,
|
|||||||
int, const char *, int *);
|
int, const char *, int *);
|
||||||
static int cell(struct tbl_node *, struct tbl_row *,
|
static int cell(struct tbl_node *, struct tbl_row *,
|
||||||
int, const char *, int *);
|
int, const char *, int *);
|
||||||
static void row(struct tbl_node *, int, const char *, int *);
|
|
||||||
static struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *,
|
static struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *,
|
||||||
enum tbl_cellt, int vert);
|
enum tbl_cellt, int vert);
|
||||||
|
|
||||||
@ -168,6 +167,9 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
goto mod;
|
goto mod;
|
||||||
case 'w': /* XXX for now, ignore minimal column width */
|
case 'w': /* XXX for now, ignore minimal column width */
|
||||||
goto mod;
|
goto mod;
|
||||||
|
case 'x':
|
||||||
|
cp->flags |= TBL_CELL_WMAX;
|
||||||
|
goto mod;
|
||||||
case 'f':
|
case 'f':
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -201,6 +203,11 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (isalnum((unsigned char)p[*pos - 1])) {
|
||||||
|
mandoc_vmsg(MANDOCERR_FT_BAD, tbl->parse,
|
||||||
|
ln, *pos - 1, "TS f%c", p[*pos - 1]);
|
||||||
|
goto mod;
|
||||||
|
}
|
||||||
|
|
||||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||||
ln, *pos - 1, NULL);
|
ln, *pos - 1, NULL);
|
||||||
@ -292,68 +299,54 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
|||||||
return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos));
|
return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
row(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
|
||||||
{
|
|
||||||
struct tbl_row *rp;
|
|
||||||
|
|
||||||
row: /*
|
|
||||||
* EBNF describing this section:
|
|
||||||
*
|
|
||||||
* row ::= row_list [:space:]* [.]?[\n]
|
|
||||||
* row_list ::= [:space:]* row_elem row_tail
|
|
||||||
* row_tail ::= [:space:]*[,] row_list |
|
|
||||||
* epsilon
|
|
||||||
* row_elem ::= [\t\ ]*[:alpha:]+
|
|
||||||
*/
|
|
||||||
|
|
||||||
rp = mandoc_calloc(1, sizeof(struct tbl_row));
|
|
||||||
if (tbl->last_row)
|
|
||||||
tbl->last_row->next = rp;
|
|
||||||
else
|
|
||||||
tbl->first_row = rp;
|
|
||||||
tbl->last_row = rp;
|
|
||||||
|
|
||||||
cell:
|
|
||||||
while (isspace((unsigned char)p[*pos]))
|
|
||||||
(*pos)++;
|
|
||||||
|
|
||||||
/* Safely exit layout context. */
|
|
||||||
|
|
||||||
if ('.' == p[*pos]) {
|
|
||||||
tbl->part = TBL_PART_DATA;
|
|
||||||
if (NULL == tbl->first_row)
|
|
||||||
mandoc_msg(MANDOCERR_TBLNOLAYOUT,
|
|
||||||
tbl->parse, ln, *pos, NULL);
|
|
||||||
(*pos)++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End (and possibly restart) a row. */
|
|
||||||
|
|
||||||
if (',' == p[*pos]) {
|
|
||||||
(*pos)++;
|
|
||||||
goto row;
|
|
||||||
} else if ('\0' == p[*pos])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( ! cell(tbl, rp, ln, p, pos))
|
|
||||||
return;
|
|
||||||
|
|
||||||
goto cell;
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
tbl_layout(struct tbl_node *tbl, int ln, const char *p)
|
tbl_layout(struct tbl_node *tbl, int ln, const char *p)
|
||||||
{
|
{
|
||||||
|
struct tbl_row *rp;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
row(tbl, ln, p, &pos);
|
rp = NULL;
|
||||||
|
|
||||||
/* Always succeed. */
|
for (;;) {
|
||||||
return(1);
|
/* Skip whitespace before and after each cell. */
|
||||||
|
|
||||||
|
while (isspace((unsigned char)p[pos]))
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
switch (p[pos]) {
|
||||||
|
case ',': /* Next row on this input line. */
|
||||||
|
pos++;
|
||||||
|
rp = NULL;
|
||||||
|
continue;
|
||||||
|
case '\0': /* Next row on next input line. */
|
||||||
|
return(1);
|
||||||
|
case '.': /* End of layout. */
|
||||||
|
pos++;
|
||||||
|
tbl->part = TBL_PART_DATA;
|
||||||
|
if (tbl->first_row != NULL)
|
||||||
|
return(1);
|
||||||
|
mandoc_msg(MANDOCERR_TBLNOLAYOUT,
|
||||||
|
tbl->parse, ln, pos, NULL);
|
||||||
|
rp = mandoc_calloc(1, sizeof(*rp));
|
||||||
|
cell_alloc(tbl, rp, TBL_CELL_LEFT, 0);
|
||||||
|
tbl->first_row = tbl->last_row = rp;
|
||||||
|
return(1);
|
||||||
|
default: /* Cell. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp == NULL) { /* First cell on this line. */
|
||||||
|
rp = mandoc_calloc(1, sizeof(*rp));
|
||||||
|
if (tbl->last_row)
|
||||||
|
tbl->last_row->next = rp;
|
||||||
|
else
|
||||||
|
tbl->first_row = rp;
|
||||||
|
tbl->last_row = rp;
|
||||||
|
}
|
||||||
|
if ( ! cell(tbl, rp, ln, p, &pos))
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tbl_cell *
|
static struct tbl_cell *
|
||||||
|
10
tbl_opts.c
10
tbl_opts.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_opts.c,v 1.13 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: tbl_opts.c,v 1.15 2014/11/26 17:51:55 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -14,9 +14,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -182,7 +182,7 @@ opt(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
|||||||
*
|
*
|
||||||
* options ::= option_list [:space:]* [;][\n]
|
* options ::= option_list [:space:]* [;][\n]
|
||||||
* option_list ::= option option_tail
|
* option_list ::= option option_tail
|
||||||
* option_tail ::= [:space:]+ option_list |
|
* option_tail ::= [,:space:]+ option_list |
|
||||||
* ::= epsilon
|
* ::= epsilon
|
||||||
* option ::= [:alpha:]+ args
|
* option ::= [:alpha:]+ args
|
||||||
* args ::= [:space:]* [(] [:alpha:]+ [)]
|
* args ::= [:space:]* [(] [:alpha:]+ [)]
|
||||||
@ -213,7 +213,7 @@ opt(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
|||||||
|
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
||||||
while (isspace((unsigned char)p[*pos]))
|
while (isspace((unsigned char)p[*pos]) || p[*pos] == ',')
|
||||||
(*pos)++;
|
(*pos)++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
30
tbl_term.c
30
tbl_term.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_term.c,v 1.27 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: tbl_term.c,v 1.31 2014/10/14 18:18:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,9 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -43,6 +43,7 @@ static void tbl_number(struct termp *, const struct tbl_opts *,
|
|||||||
const struct roffcol *);
|
const struct roffcol *);
|
||||||
static void tbl_hrule(struct termp *, const struct tbl_span *);
|
static void tbl_hrule(struct termp *, const struct tbl_span *);
|
||||||
static void tbl_vrule(struct termp *, const struct tbl_head *);
|
static void tbl_vrule(struct termp *, const struct tbl_head *);
|
||||||
|
static void tbl_word(struct termp *, const struct tbl_dat *);
|
||||||
|
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
@ -90,7 +91,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||||||
tp->tbl.slen = term_tbl_strlen;
|
tp->tbl.slen = term_tbl_strlen;
|
||||||
tp->tbl.arg = tp;
|
tp->tbl.arg = tp;
|
||||||
|
|
||||||
tblcalc(&tp->tbl, sp);
|
tblcalc(&tp->tbl, sp, rmargin - tp->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Horizontal frame at the start of boxed tables. */
|
/* Horizontal frame at the start of boxed tables. */
|
||||||
@ -106,7 +107,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||||||
/* Vertical frame at the start of each row. */
|
/* Vertical frame at the start of each row. */
|
||||||
|
|
||||||
if ((TBL_OPT_BOX | TBL_OPT_DBOX) & sp->opts->opts ||
|
if ((TBL_OPT_BOX | TBL_OPT_DBOX) & sp->opts->opts ||
|
||||||
sp->head->vert)
|
(sp->head != NULL && sp->head->vert))
|
||||||
term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
|
term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
|
||||||
TBL_SPAN_DHORIZ == sp->pos ? "+" : "|");
|
TBL_SPAN_DHORIZ == sp->pos ? "+" : "|");
|
||||||
|
|
||||||
@ -378,7 +379,7 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tbl_char(tp, ASCII_NBRSP, padl);
|
tbl_char(tp, ASCII_NBRSP, padl);
|
||||||
term_word(tp, dp->string);
|
tbl_word(tp, dp);
|
||||||
tbl_char(tp, ASCII_NBRSP, padr);
|
tbl_char(tp, ASCII_NBRSP, padr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,8 +420,23 @@ tbl_number(struct termp *tp, const struct tbl_opts *opts,
|
|||||||
padl = col->decimal - d;
|
padl = col->decimal - d;
|
||||||
|
|
||||||
tbl_char(tp, ASCII_NBRSP, padl);
|
tbl_char(tp, ASCII_NBRSP, padl);
|
||||||
term_word(tp, dp->string);
|
tbl_word(tp, dp);
|
||||||
if (col->width > sz + padl)
|
if (col->width > sz + padl)
|
||||||
tbl_char(tp, ASCII_NBRSP, col->width - sz - padl);
|
tbl_char(tp, ASCII_NBRSP, col->width - sz - padl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tbl_word(struct termp *tp, const struct tbl_dat *dp)
|
||||||
|
{
|
||||||
|
const void *prev_font;
|
||||||
|
|
||||||
|
prev_font = term_fontq(tp);
|
||||||
|
if (dp->layout->flags & TBL_CELL_BOLD)
|
||||||
|
term_fontpush(tp, TERMFONT_BOLD);
|
||||||
|
else if (dp->layout->flags & TBL_CELL_ITALIC)
|
||||||
|
term_fontpush(tp, TERMFONT_UNDER);
|
||||||
|
|
||||||
|
term_word(tp, dp->string);
|
||||||
|
|
||||||
|
term_fontpopq(tp, prev_font);
|
||||||
|
}
|
||||||
|
190
term.c
190
term.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: term.c,v 1.226 2014/08/01 19:38:29 schwarze Exp $ */
|
/* $Id: term.c,v 1.236 2014/11/21 01:52:53 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,9 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -44,11 +42,7 @@ void
|
|||||||
term_free(struct termp *p)
|
term_free(struct termp *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (p->buf)
|
free(p->buf);
|
||||||
free(p->buf);
|
|
||||||
if (p->symtab)
|
|
||||||
mchars_free(p->symtab);
|
|
||||||
|
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +100,7 @@ term_flushln(struct termp *p)
|
|||||||
size_t j; /* temporary loop index for p->buf */
|
size_t j; /* temporary loop index for p->buf */
|
||||||
size_t jhy; /* last hyph before overflow w/r/t j */
|
size_t jhy; /* last hyph before overflow w/r/t j */
|
||||||
size_t maxvis; /* output position of visible boundary */
|
size_t maxvis; /* output position of visible boundary */
|
||||||
size_t mmax; /* used in calculating bp */
|
size_t rmargin; /* the rightmost of the two margins */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, establish the maximum columns of "visible" content.
|
* First, establish the maximum columns of "visible" content.
|
||||||
@ -119,13 +113,17 @@ term_flushln(struct termp *p)
|
|||||||
* is negative, it gets sign extended. Subtracting that
|
* is negative, it gets sign extended. Subtracting that
|
||||||
* very large size_t effectively adds a small number to dv.
|
* very large size_t effectively adds a small number to dv.
|
||||||
*/
|
*/
|
||||||
assert (p->rmargin >= p->offset);
|
rmargin = p->rmargin > p->offset ? p->rmargin : p->offset;
|
||||||
dv = p->rmargin - p->offset;
|
dv = p->rmargin - p->offset;
|
||||||
maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
|
maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
|
||||||
dv = p->maxrmargin - p->offset;
|
|
||||||
mmax = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
|
|
||||||
|
|
||||||
bp = TERMP_NOBREAK & p->flags ? mmax : maxvis;
|
if (p->flags & TERMP_NOBREAK) {
|
||||||
|
dv = p->maxrmargin > p->offset ?
|
||||||
|
p->maxrmargin - p->offset : 0;
|
||||||
|
bp = (int)dv > p->overstep ?
|
||||||
|
dv - (size_t)p->overstep : 0;
|
||||||
|
} else
|
||||||
|
bp = maxvis;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the required amount of padding.
|
* Calculate the required amount of padding.
|
||||||
@ -194,8 +192,8 @@ term_flushln(struct termp *p)
|
|||||||
(*p->endline)(p);
|
(*p->endline)(p);
|
||||||
p->viscol = 0;
|
p->viscol = 0;
|
||||||
if (TERMP_BRIND & p->flags) {
|
if (TERMP_BRIND & p->flags) {
|
||||||
vbl = p->rmargin;
|
vbl = rmargin;
|
||||||
vend += p->rmargin - p->offset;
|
vend += rmargin - p->offset;
|
||||||
} else
|
} else
|
||||||
vbl = p->offset;
|
vbl = p->offset;
|
||||||
|
|
||||||
@ -222,7 +220,7 @@ term_flushln(struct termp *p)
|
|||||||
break;
|
break;
|
||||||
if (' ' == p->buf[i]) {
|
if (' ' == p->buf[i]) {
|
||||||
j = i;
|
j = i;
|
||||||
while (' ' == p->buf[i])
|
while (i < p->col && ' ' == p->buf[i])
|
||||||
i++;
|
i++;
|
||||||
dv = (i - j) * (*p->width)(p, ' ');
|
dv = (i - j) * (*p->width)(p, ' ');
|
||||||
vbl += dv;
|
vbl += dv;
|
||||||
@ -260,8 +258,10 @@ term_flushln(struct termp *p)
|
|||||||
* If there was trailing white space, it was not printed;
|
* If there was trailing white space, it was not printed;
|
||||||
* so reset the cursor position accordingly.
|
* so reset the cursor position accordingly.
|
||||||
*/
|
*/
|
||||||
if (vis)
|
if (vis > vbl)
|
||||||
vis -= vbl;
|
vis -= vbl;
|
||||||
|
else
|
||||||
|
vis = 0;
|
||||||
|
|
||||||
p->col = 0;
|
p->col = 0;
|
||||||
p->overstep = 0;
|
p->overstep = 0;
|
||||||
@ -397,7 +397,6 @@ term_word(struct termp *p, const char *word)
|
|||||||
{
|
{
|
||||||
const char nbrsp[2] = { ASCII_NBRSP, 0 };
|
const char nbrsp[2] = { ASCII_NBRSP, 0 };
|
||||||
const char *seq, *cp;
|
const char *seq, *cp;
|
||||||
char c;
|
|
||||||
int sz, uc;
|
int sz, uc;
|
||||||
size_t ssz;
|
size_t ssz;
|
||||||
enum mandoc_esc esc;
|
enum mandoc_esc esc;
|
||||||
@ -446,68 +445,70 @@ term_word(struct termp *p, const char *word)
|
|||||||
if (ESCAPE_ERROR == esc)
|
if (ESCAPE_ERROR == esc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (TERMENC_ASCII != p->enc)
|
|
||||||
switch (esc) {
|
|
||||||
case ESCAPE_UNICODE:
|
|
||||||
uc = mchars_num2uc(seq + 1, sz - 1);
|
|
||||||
if ('\0' == uc)
|
|
||||||
break;
|
|
||||||
encode1(p, uc);
|
|
||||||
continue;
|
|
||||||
case ESCAPE_SPECIAL:
|
|
||||||
uc = mchars_spec2cp(p->symtab, seq, sz);
|
|
||||||
if (uc <= 0)
|
|
||||||
break;
|
|
||||||
encode1(p, uc);
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case ESCAPE_UNICODE:
|
case ESCAPE_UNICODE:
|
||||||
encode1(p, '?');
|
uc = mchars_num2uc(seq + 1, sz - 1);
|
||||||
break;
|
break;
|
||||||
case ESCAPE_NUMBERED:
|
case ESCAPE_NUMBERED:
|
||||||
c = mchars_num2char(seq, sz);
|
uc = mchars_num2char(seq, sz);
|
||||||
if ('\0' != c)
|
if (uc < 0)
|
||||||
encode(p, &c, 1);
|
continue;
|
||||||
break;
|
break;
|
||||||
case ESCAPE_SPECIAL:
|
case ESCAPE_SPECIAL:
|
||||||
cp = mchars_spec2str(p->symtab, seq, sz, &ssz);
|
if (p->enc == TERMENC_ASCII) {
|
||||||
if (NULL != cp)
|
cp = mchars_spec2str(p->symtab,
|
||||||
encode(p, cp, ssz);
|
seq, sz, &ssz);
|
||||||
else if (1 == ssz)
|
if (cp != NULL)
|
||||||
encode(p, seq, sz);
|
encode(p, cp, ssz);
|
||||||
break;
|
} else {
|
||||||
|
uc = mchars_spec2cp(p->symtab, seq, sz);
|
||||||
|
if (uc > 0)
|
||||||
|
encode1(p, uc);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
case ESCAPE_FONTBOLD:
|
case ESCAPE_FONTBOLD:
|
||||||
term_fontrepl(p, TERMFONT_BOLD);
|
term_fontrepl(p, TERMFONT_BOLD);
|
||||||
break;
|
continue;
|
||||||
case ESCAPE_FONTITALIC:
|
case ESCAPE_FONTITALIC:
|
||||||
term_fontrepl(p, TERMFONT_UNDER);
|
term_fontrepl(p, TERMFONT_UNDER);
|
||||||
break;
|
continue;
|
||||||
case ESCAPE_FONTBI:
|
case ESCAPE_FONTBI:
|
||||||
term_fontrepl(p, TERMFONT_BI);
|
term_fontrepl(p, TERMFONT_BI);
|
||||||
break;
|
continue;
|
||||||
case ESCAPE_FONT:
|
case ESCAPE_FONT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ESCAPE_FONTROMAN:
|
case ESCAPE_FONTROMAN:
|
||||||
term_fontrepl(p, TERMFONT_NONE);
|
term_fontrepl(p, TERMFONT_NONE);
|
||||||
break;
|
continue;
|
||||||
case ESCAPE_FONTPREV:
|
case ESCAPE_FONTPREV:
|
||||||
term_fontlast(p);
|
term_fontlast(p);
|
||||||
break;
|
continue;
|
||||||
case ESCAPE_NOSPACE:
|
case ESCAPE_NOSPACE:
|
||||||
if (TERMP_SKIPCHAR & p->flags)
|
if (TERMP_SKIPCHAR & p->flags)
|
||||||
p->flags &= ~TERMP_SKIPCHAR;
|
p->flags &= ~TERMP_SKIPCHAR;
|
||||||
else if ('\0' == *word)
|
else if ('\0' == *word)
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
break;
|
continue;
|
||||||
case ESCAPE_SKIPCHAR:
|
case ESCAPE_SKIPCHAR:
|
||||||
p->flags |= TERMP_SKIPCHAR;
|
p->flags |= TERMP_SKIPCHAR;
|
||||||
break;
|
continue;
|
||||||
default:
|
default:
|
||||||
break;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common handling for Unicode and numbered
|
||||||
|
* character escape sequences.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (p->enc == TERMENC_ASCII) {
|
||||||
|
cp = ascii_uc2str(uc);
|
||||||
|
encode(p, cp, strlen(cp));
|
||||||
|
} else {
|
||||||
|
if ((uc < 0x20 && uc != 0x09) ||
|
||||||
|
(uc > 0x7E && uc < 0xA0))
|
||||||
|
uc = 0xFFFD;
|
||||||
|
encode1(p, uc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->flags &= ~TERMP_NBRWORD;
|
p->flags &= ~TERMP_NBRWORD;
|
||||||
@ -659,7 +660,7 @@ size_t
|
|||||||
term_strlen(const struct termp *p, const char *cp)
|
term_strlen(const struct termp *p, const char *cp)
|
||||||
{
|
{
|
||||||
size_t sz, rsz, i;
|
size_t sz, rsz, i;
|
||||||
int ssz, skip, c;
|
int ssz, skip, uc;
|
||||||
const char *seq, *rhs;
|
const char *seq, *rhs;
|
||||||
enum mandoc_esc esc;
|
enum mandoc_esc esc;
|
||||||
static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH,
|
static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH,
|
||||||
@ -685,62 +686,65 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
if (ESCAPE_ERROR == esc)
|
if (ESCAPE_ERROR == esc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (TERMENC_ASCII != p->enc)
|
|
||||||
switch (esc) {
|
|
||||||
case ESCAPE_UNICODE:
|
|
||||||
c = mchars_num2uc(seq + 1,
|
|
||||||
ssz - 1);
|
|
||||||
if ('\0' == c)
|
|
||||||
break;
|
|
||||||
sz += cond_width(p, c, &skip);
|
|
||||||
continue;
|
|
||||||
case ESCAPE_SPECIAL:
|
|
||||||
c = mchars_spec2cp(p->symtab,
|
|
||||||
seq, ssz);
|
|
||||||
if (c <= 0)
|
|
||||||
break;
|
|
||||||
sz += cond_width(p, c, &skip);
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rhs = NULL;
|
rhs = NULL;
|
||||||
|
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case ESCAPE_UNICODE:
|
case ESCAPE_UNICODE:
|
||||||
sz += cond_width(p, '?', &skip);
|
uc = mchars_num2uc(seq + 1, ssz - 1);
|
||||||
break;
|
break;
|
||||||
case ESCAPE_NUMBERED:
|
case ESCAPE_NUMBERED:
|
||||||
c = mchars_num2char(seq, ssz);
|
uc = mchars_num2char(seq, ssz);
|
||||||
if ('\0' != c)
|
if (uc < 0)
|
||||||
sz += cond_width(p, c, &skip);
|
continue;
|
||||||
break;
|
break;
|
||||||
case ESCAPE_SPECIAL:
|
case ESCAPE_SPECIAL:
|
||||||
rhs = mchars_spec2str(p->symtab,
|
if (p->enc == TERMENC_ASCII) {
|
||||||
seq, ssz, &rsz);
|
rhs = mchars_spec2str(p->symtab,
|
||||||
|
seq, ssz, &rsz);
|
||||||
if (ssz != 1 || rhs)
|
if (rhs != NULL)
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
rhs = seq;
|
uc = mchars_spec2cp(p->symtab,
|
||||||
rsz = ssz;
|
seq, ssz);
|
||||||
break;
|
if (uc > 0)
|
||||||
|
sz += cond_width(p, uc, &skip);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
case ESCAPE_SKIPCHAR:
|
case ESCAPE_SKIPCHAR:
|
||||||
skip = 1;
|
skip = 1;
|
||||||
break;
|
continue;
|
||||||
default:
|
default:
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == rhs)
|
/*
|
||||||
break;
|
* Common handling for Unicode and numbered
|
||||||
|
* character escape sequences.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (rhs == NULL) {
|
||||||
|
if (p->enc == TERMENC_ASCII) {
|
||||||
|
rhs = ascii_uc2str(uc);
|
||||||
|
rsz = strlen(rhs);
|
||||||
|
} else {
|
||||||
|
if ((uc < 0x20 && uc != 0x09) ||
|
||||||
|
(uc > 0x7E && uc < 0xA0))
|
||||||
|
uc = 0xFFFD;
|
||||||
|
sz += cond_width(p, uc, &skip);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (skip) {
|
if (skip) {
|
||||||
skip = 0;
|
skip = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common handling for all escape sequences
|
||||||
|
* printing more than one character.
|
||||||
|
*/
|
||||||
|
|
||||||
for (i = 0; i < rsz; i++)
|
for (i = 0; i < rsz; i++)
|
||||||
sz += (*p->width)(p, *rhs++);
|
sz += (*p->width)(p, *rhs++);
|
||||||
break;
|
break;
|
||||||
|
12
term.h
12
term.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: term.h,v 1.101 2014/04/20 16:46:05 schwarze Exp $ */
|
/* $Id: term.h,v 1.105 2014/10/28 17:36:19 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -54,6 +54,7 @@ struct termp_tbl {
|
|||||||
struct termp {
|
struct termp {
|
||||||
enum termtype type;
|
enum termtype type;
|
||||||
struct rofftbl tbl; /* table configuration */
|
struct rofftbl tbl; /* table configuration */
|
||||||
|
int synopsisonly; /* print the synopsis only */
|
||||||
int mdocstyle; /* imitate mdoc(7) output */
|
int mdocstyle; /* imitate mdoc(7) output */
|
||||||
size_t defindent; /* Default indent for text. */
|
size_t defindent; /* Default indent for text. */
|
||||||
size_t defrmargin; /* Right margin of the device. */
|
size_t defrmargin; /* Right margin of the device. */
|
||||||
@ -80,12 +81,11 @@ struct termp {
|
|||||||
#define TERMP_BRIND (1 << 9) /* See term_flushln(). */
|
#define TERMP_BRIND (1 << 9) /* See term_flushln(). */
|
||||||
#define TERMP_DANGLE (1 << 10) /* See term_flushln(). */
|
#define TERMP_DANGLE (1 << 10) /* See term_flushln(). */
|
||||||
#define TERMP_HANG (1 << 11) /* See term_flushln(). */
|
#define TERMP_HANG (1 << 11) /* See term_flushln(). */
|
||||||
#define TERMP_NOSPLIT (1 << 12) /* See termp_an_pre/post(). */
|
#define TERMP_NOSPLIT (1 << 12) /* Do not break line before .An. */
|
||||||
#define TERMP_SPLIT (1 << 13) /* See termp_an_pre/post(). */
|
#define TERMP_SPLIT (1 << 13) /* Break line before .An. */
|
||||||
#define TERMP_ANPREC (1 << 14) /* See termp_an_pre(). */
|
|
||||||
int *buf; /* Output buffer. */
|
int *buf; /* Output buffer. */
|
||||||
enum termenc enc; /* Type of encoding. */
|
enum termenc enc; /* Type of encoding. */
|
||||||
struct mchars *symtab; /* Encoded-symbol table. */
|
const struct mchars *symtab; /* Character table. */
|
||||||
enum termfont fontl; /* Last font set. */
|
enum termfont fontl; /* Last font set. */
|
||||||
enum termfont fontq[10]; /* Symmetric fonts. */
|
enum termfont fontq[10]; /* Symmetric fonts. */
|
||||||
int fonti; /* Index of font stack. */
|
int fonti; /* Index of font stack. */
|
||||||
@ -104,6 +104,8 @@ struct termp {
|
|||||||
struct termp_ps *ps;
|
struct termp_ps *ps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *ascii_uc2str(int);
|
||||||
|
|
||||||
void term_eqn(struct termp *, const struct eqn *);
|
void term_eqn(struct termp *, const struct eqn *);
|
||||||
void term_tbl(struct termp *, const struct tbl_span *);
|
void term_tbl(struct termp *, const struct tbl_span *);
|
||||||
void term_free(struct termp *);
|
void term_free(struct termp *);
|
||||||
|
171
term_ascii.c
171
term_ascii.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: term_ascii.c,v 1.27 2014/08/01 19:25:52 schwarze Exp $ */
|
/* $Id: term_ascii.c,v 1.40 2014/11/20 13:56:20 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -15,21 +15,20 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
#include <assert.h>
|
||||||
# include <locale.h>
|
#if HAVE_WCHAR
|
||||||
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef USE_WCHAR
|
#if HAVE_WCHAR
|
||||||
# include <wchar.h>
|
#include <wchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
@ -38,18 +37,8 @@
|
|||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
/*
|
static struct termp *ascii_init(enum termenc,
|
||||||
* Sadly, this doesn't seem to be defined on systems even when they
|
const struct mchars *, char *);
|
||||||
* support it. For the time being, remove it and let those compiling
|
|
||||||
* the software decide for themselves what to use.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
#if ! defined(__STDC_ISO_10646__)
|
|
||||||
# undef USE_WCHAR
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct termp *ascii_init(enum termenc, char *);
|
|
||||||
static double ascii_hspan(const struct termp *,
|
static double ascii_hspan(const struct termp *,
|
||||||
const struct roffsu *);
|
const struct roffsu *);
|
||||||
static size_t ascii_width(const struct termp *, int);
|
static size_t ascii_width(const struct termp *, int);
|
||||||
@ -60,7 +49,7 @@ static void ascii_endline(struct termp *);
|
|||||||
static void ascii_letter(struct termp *, int);
|
static void ascii_letter(struct termp *, int);
|
||||||
static void ascii_setwidth(struct termp *, int, size_t);
|
static void ascii_setwidth(struct termp *, int, size_t);
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
#if HAVE_WCHAR
|
||||||
static void locale_advance(struct termp *, size_t);
|
static void locale_advance(struct termp *, size_t);
|
||||||
static void locale_endline(struct termp *);
|
static void locale_endline(struct termp *);
|
||||||
static void locale_letter(struct termp *, int);
|
static void locale_letter(struct termp *, int);
|
||||||
@ -69,14 +58,15 @@ static size_t locale_width(const struct termp *, int);
|
|||||||
|
|
||||||
|
|
||||||
static struct termp *
|
static struct termp *
|
||||||
ascii_init(enum termenc enc, char *outopts)
|
ascii_init(enum termenc enc, const struct mchars *mchars, char *outopts)
|
||||||
{
|
{
|
||||||
const char *toks[4];
|
const char *toks[5];
|
||||||
char *v;
|
char *v;
|
||||||
struct termp *p;
|
struct termp *p;
|
||||||
|
|
||||||
p = mandoc_calloc(1, sizeof(struct termp));
|
p = mandoc_calloc(1, sizeof(struct termp));
|
||||||
|
|
||||||
|
p->symtab = mchars;
|
||||||
p->tabwidth = 5;
|
p->tabwidth = 5;
|
||||||
p->defrmargin = p->lastrmargin = 78;
|
p->defrmargin = p->lastrmargin = 78;
|
||||||
|
|
||||||
@ -92,7 +82,7 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
p->setwidth = ascii_setwidth;
|
p->setwidth = ascii_setwidth;
|
||||||
p->width = ascii_width;
|
p->width = ascii_width;
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
#if HAVE_WCHAR
|
||||||
if (TERMENC_ASCII != enc) {
|
if (TERMENC_ASCII != enc) {
|
||||||
v = TERMENC_LOCALE == enc ?
|
v = TERMENC_LOCALE == enc ?
|
||||||
setlocale(LC_ALL, "") :
|
setlocale(LC_ALL, "") :
|
||||||
@ -110,7 +100,8 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
toks[0] = "indent";
|
toks[0] = "indent";
|
||||||
toks[1] = "width";
|
toks[1] = "width";
|
||||||
toks[2] = "mdoc";
|
toks[2] = "mdoc";
|
||||||
toks[3] = NULL;
|
toks[3] = "synopsis";
|
||||||
|
toks[4] = NULL;
|
||||||
|
|
||||||
while (outopts && *outopts)
|
while (outopts && *outopts)
|
||||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||||
@ -128,6 +119,9 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
p->mdocstyle = 1;
|
p->mdocstyle = 1;
|
||||||
p->defindent = 5;
|
p->defindent = 5;
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
p->synopsisonly = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -140,24 +134,24 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ascii_alloc(char *outopts)
|
ascii_alloc(const struct mchars *mchars, char *outopts)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(ascii_init(TERMENC_ASCII, outopts));
|
return(ascii_init(TERMENC_ASCII, mchars, outopts));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
utf8_alloc(char *outopts)
|
utf8_alloc(const struct mchars *mchars, char *outopts)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(ascii_init(TERMENC_UTF8, outopts));
|
return(ascii_init(TERMENC_UTF8, mchars, outopts));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
locale_alloc(char *outopts)
|
locale_alloc(const struct mchars *mchars, char *outopts)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(ascii_init(TERMENC_LOCALE, outopts));
|
return(ascii_init(TERMENC_LOCALE, mchars, outopts));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -165,12 +159,14 @@ ascii_setwidth(struct termp *p, int iop, size_t width)
|
|||||||
{
|
{
|
||||||
|
|
||||||
p->rmargin = p->defrmargin;
|
p->rmargin = p->defrmargin;
|
||||||
if (0 < iop)
|
if (iop > 0)
|
||||||
p->defrmargin += width;
|
p->defrmargin += width;
|
||||||
else if (0 > iop)
|
else if (iop == 0)
|
||||||
|
p->defrmargin = width ? width : p->lastrmargin;
|
||||||
|
else if (p->defrmargin > width)
|
||||||
p->defrmargin -= width;
|
p->defrmargin -= width;
|
||||||
else
|
else
|
||||||
p->defrmargin = width ? width : p->lastrmargin;
|
p->defrmargin = 0;
|
||||||
p->lastrmargin = p->rmargin;
|
p->lastrmargin = p->rmargin;
|
||||||
p->rmargin = p->maxrmargin = p->defrmargin;
|
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||||
}
|
}
|
||||||
@ -232,38 +228,125 @@ ascii_hspan(const struct termp *p, const struct roffsu *su)
|
|||||||
double r;
|
double r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Approximate based on character width. These are generated
|
* Approximate based on character width.
|
||||||
* entirely by eyeballing the screen, but appear to be correct.
|
* None of these will be actually correct given that an inch on
|
||||||
|
* the screen depends on character size, terminal, etc., etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (su->unit) {
|
switch (su->unit) {
|
||||||
|
case SCALE_BU:
|
||||||
|
r = su->scale * 10.0 / 240.0;
|
||||||
|
break;
|
||||||
case SCALE_CM:
|
case SCALE_CM:
|
||||||
r = su->scale * 4.0;
|
r = su->scale * 10.0 / 2.54;
|
||||||
|
break;
|
||||||
|
case SCALE_FS:
|
||||||
|
r = su->scale * 2730.666;
|
||||||
break;
|
break;
|
||||||
case SCALE_IN:
|
case SCALE_IN:
|
||||||
r = su->scale * 10.0;
|
r = su->scale * 10.0;
|
||||||
break;
|
break;
|
||||||
|
case SCALE_MM:
|
||||||
|
r = su->scale / 100.0;
|
||||||
|
break;
|
||||||
case SCALE_PC:
|
case SCALE_PC:
|
||||||
r = (su->scale * 10.0) / 6.0;
|
r = su->scale * 10.0 / 6.0;
|
||||||
break;
|
break;
|
||||||
case SCALE_PT:
|
case SCALE_PT:
|
||||||
r = (su->scale * 10.0) / 72.0;
|
r = su->scale * 10.0 / 72.0;
|
||||||
break;
|
|
||||||
case SCALE_MM:
|
|
||||||
r = su->scale / 1000.0;
|
|
||||||
break;
|
break;
|
||||||
case SCALE_VS:
|
case SCALE_VS:
|
||||||
r = su->scale * 2.0 - 1.0;
|
r = su->scale * 2.0 - 1.0;
|
||||||
break;
|
break;
|
||||||
default:
|
case SCALE_EN:
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case SCALE_EM:
|
||||||
r = su->scale;
|
r = su->scale;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
const char *
|
||||||
|
ascii_uc2str(int uc)
|
||||||
|
{
|
||||||
|
static const char nbrsp[2] = { ASCII_NBRSP, '\0' };
|
||||||
|
static const char *tab[] = {
|
||||||
|
"<NUL>","<SOH>","<STX>","<ETX>","<EOT>","<ENQ>","<ACK>","<BEL>",
|
||||||
|
"<BS>", "\t", "<LF>", "<VT>", "<FF>", "<CR>", "<SO>", "<SI>",
|
||||||
|
"<DLE>","<DC1>","<DC2>","<DC3>","<DC4>","<NAK>","<SYN>","<ETB>",
|
||||||
|
"<CAN>","<EM>", "<SUB>","<ESC>","<FS>", "<GS>", "<RS>", "<US>",
|
||||||
|
" ", "!", "\"", "#", "$", "%", "&", "'",
|
||||||
|
"(", ")", "*", "+", ",", "-", ".", "/",
|
||||||
|
"0", "1", "2", "3", "4", "5", "6", "7",
|
||||||
|
"8", "9", ":", ";", "<", "=", ">", "?",
|
||||||
|
"@", "A", "B", "C", "D", "E", "F", "G",
|
||||||
|
"H", "I", "J", "K", "L", "M", "N", "O",
|
||||||
|
"P", "Q", "R", "S", "T", "U", "V", "W",
|
||||||
|
"X", "Y", "Z", "[", "\\", "]", "^", "_",
|
||||||
|
"`", "a", "b", "c", "d", "e", "f", "g",
|
||||||
|
"h", "i", "j", "k", "l", "m", "n", "o",
|
||||||
|
"p", "q", "r", "s", "t", "u", "v", "w",
|
||||||
|
"x", "y", "z", "{", "|", "}", "~", "<DEL>",
|
||||||
|
"<80>", "<81>", "<82>", "<83>", "<84>", "<85>", "<86>", "<87>",
|
||||||
|
"<88>", "<89>", "<8A>", "<8B>", "<8C>", "<8D>", "<8E>", "<8F>",
|
||||||
|
"<90>", "<91>", "<92>", "<93>", "<94>", "<95>", "<96>", "<97>",
|
||||||
|
"<99>", "<99>", "<9A>", "<9B>", "<9C>", "<9D>", "<9E>", "<9F>",
|
||||||
|
nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<sec>",
|
||||||
|
"\"", "(C)", "_\ba", "<<", "~", "", "(R)", "-",
|
||||||
|
"<deg>","+-", "2", "3", "'", ",\bu", "<par>",".",
|
||||||
|
",", "1", "_\bo", ">>", "1/4", "1/2", "3/4", "?",
|
||||||
|
"`\bA", "'\bA", "^\bA", "~\bA", "\"\bA","o\bA", "AE", ",\bC",
|
||||||
|
"`\bE", "'\bE", "^\bE", "\"\bE","`\bI", "'\bI", "^\bI", "\"\bI",
|
||||||
|
"-\bD", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x",
|
||||||
|
"/\bO", "`\bU", "'\bU", "^\bU", "\"\bU","'\bY", "Th", "ss",
|
||||||
|
"`\ba", "'\ba", "^\ba", "~\ba", "\"\ba","o\ba", "ae", ",\bc",
|
||||||
|
"`\be", "'\be", "^\be", "\"\be","`\bi", "'\bi", "^\bi", "\"\bi",
|
||||||
|
"d", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","-:-",
|
||||||
|
"/\bo", "`\bu", "'\bu", "^\bu", "\"\bu","'\by", "th", "\"\by",
|
||||||
|
"A", "a", "A", "a", "A", "a", "'\bC", "'\bc",
|
||||||
|
"^\bC", "^\bc", "C", "c", "C", "c", "D", "d",
|
||||||
|
"/\bD", "/\bd", "E", "e", "E", "e", "E", "e",
|
||||||
|
"E", "e", "E", "e", "^\bG", "^\bg", "G", "g",
|
||||||
|
"G", "g", ",\bG", ",\bg", "^\bH", "^\bh", "/\bH", "/\bh",
|
||||||
|
"~\bI", "~\bi", "I", "i", "I", "i", "I", "i",
|
||||||
|
"I", "i", "IJ", "ij", "^\bJ", "^\bj", ",\bK", ",\bk",
|
||||||
|
"q", "'\bL", "'\bl", ",\bL", ",\bl", "L", "l", "L",
|
||||||
|
"l", "/\bL", "/\bl", "'\bN", "'\bn", ",\bN", ",\bn", "N",
|
||||||
|
"n", "'n", "Ng", "ng", "O", "o", "O", "o",
|
||||||
|
"O", "o", "OE", "oe", "'\bR", "'\br", ",\bR", ",\br",
|
||||||
|
"R", "r", "'\bS", "'\bs", "^\bS", "^\bs", ",\bS", ",\bs",
|
||||||
|
"S", "s", ",\bT", ",\bt", "T", "t", "/\bT", "/\bt",
|
||||||
|
"~\bU", "~\bu", "U", "u", "U", "u", "U", "u",
|
||||||
|
"U", "u", "U", "u", "^\bW", "^\bw", "^\bY", "^\by",
|
||||||
|
"\"\bY","'\bZ", "'\bz", "Z", "z", "Z", "z", "s",
|
||||||
|
"b", "B", "B", "b", "6", "6", "O", "C",
|
||||||
|
"c", "D", "D", "D", "d", "d", "3", "@",
|
||||||
|
"E", "F", ",\bf", "G", "G", "hv", "I", "/\bI",
|
||||||
|
"K", "k", "/\bl", "l", "W", "N", "n", "~\bO",
|
||||||
|
"O", "o", "OI", "oi", "P", "p", "YR", "2",
|
||||||
|
"2", "SH", "sh", "t", "T", "t", "T", "U",
|
||||||
|
"u", "Y", "V", "Y", "y", "/\bZ", "/\bz", "ZH",
|
||||||
|
"ZH", "zh", "zh", "/\b2", "5", "5", "ts", "w",
|
||||||
|
"|", "||", "|=", "!", "DZ", "Dz", "dz", "LJ",
|
||||||
|
"Lj", "lj", "NJ", "Nj", "nj", "A", "a", "I",
|
||||||
|
"i", "O", "o", "U", "u", "U", "u", "U",
|
||||||
|
"u", "U", "u", "U", "u", "@", "A", "a",
|
||||||
|
"A", "a", "AE", "ae", "/\bG", "/\bg", "G", "g",
|
||||||
|
"K", "k", "O", "o", "O", "o", "ZH", "zh",
|
||||||
|
"j", "DZ", "Dz", "dz", "'\bG", "'\bg", "HV", "W",
|
||||||
|
"`\bN", "`\bn", "A", "a", "'\bAE","'\bae","O", "o"};
|
||||||
|
|
||||||
|
assert(uc >= 0);
|
||||||
|
if ((size_t)uc < sizeof(tab)/sizeof(tab[0]))
|
||||||
|
return(tab[uc]);
|
||||||
|
return(mchars_uc2str(uc));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_WCHAR
|
||||||
static size_t
|
static size_t
|
||||||
locale_width(const struct termp *p, int c)
|
locale_width(const struct termp *p, int c)
|
||||||
{
|
{
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user