Update mandoc to 1.13.1
This commit is contained in:
commit
6653664b44
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=274880
187
contrib/mdocml/INSTALL
Normal file
187
contrib/mdocml/INSTALL
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
$Id: INSTALL,v 1.2 2014/08/10 17:22:26 schwarze Exp $
|
||||||
|
|
||||||
|
About mdocml, the portable mandoc distribution
|
||||||
|
----------------------------------------------
|
||||||
|
The mandoc manpage compiler toolset is a suite of tools compiling
|
||||||
|
mdoc(7), the roff(7) macro language of choice for BSD manual pages,
|
||||||
|
and man(7), the predominant historical language for UNIX manuals.
|
||||||
|
The toolset does not yet implement man(1); that is only scheduled
|
||||||
|
for the next release, 1.13.2. It can, however, already serve to
|
||||||
|
translate source manpages to the output displayed by man(1).
|
||||||
|
For general information, see <http://mdocml.bsd.lv/>.
|
||||||
|
|
||||||
|
In this document, we describe the installation and deployment of
|
||||||
|
mandoc(1), first as a simple, standalone formatter, and then as part of
|
||||||
|
the man(1) system.
|
||||||
|
|
||||||
|
In case you have questions or want to provide feedback, read
|
||||||
|
<http://mdocml.bsd.lv/contact.html>. Consider subscribing to the
|
||||||
|
discuss@ mailing list mentioned on that page. If you intend to
|
||||||
|
help with the development of mandoc, consider subscribing to the
|
||||||
|
tech@ mailing list, too.
|
||||||
|
|
||||||
|
Enjoy using the mandoc toolset!
|
||||||
|
|
||||||
|
Ingo Schwarze, Karlsruhe, August 2014
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
Before manually installing mandoc on your system, please check
|
||||||
|
whether the newest version of mandoc is already installed by default
|
||||||
|
or available via a binary package or a ports system. A list of the
|
||||||
|
latest bundled and ported versions of mandoc for various operating
|
||||||
|
systems is maintained at <http://mdocml.bsd.lv/ports.html>.
|
||||||
|
|
||||||
|
If mandoc is installed, you can check the version by running "mandoc -V".
|
||||||
|
The version contained in this distribution tarball is listed near
|
||||||
|
the beginning of the file "Makefile".
|
||||||
|
|
||||||
|
Regarding how packages and ports are maintained for your operating
|
||||||
|
system, please consult your operating system documentation.
|
||||||
|
To install mandoc manually, the following steps are needed:
|
||||||
|
|
||||||
|
1. Decide whether you want to build the base tools mandoc(1),
|
||||||
|
preconv(1) and demandoc(1) only or whether you also want to build the
|
||||||
|
database tools apropos(1) and makewhatis(8). For the latter,
|
||||||
|
the following dependencies are required:
|
||||||
|
|
||||||
|
1.1. The SQLite database system, see <http://sqlite.org/>.
|
||||||
|
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
|
||||||
|
toolset is known to work with version 3.7.5 or newer. Versions
|
||||||
|
older than 3.8.3 may not achieve full performance due to the
|
||||||
|
missing SQLITE_DETERMINISTIC optimization flag. Versions older
|
||||||
|
than 3.8.0 may not show full error information if opening a database
|
||||||
|
fails due to the missing sqlite3_errstr() API. Both are very minor
|
||||||
|
problems, apropos(1) is fully usable with SQLite 3.7.5. Versions
|
||||||
|
older than 3.7.5 may or may not work, they have not been tested.
|
||||||
|
|
||||||
|
1.2. The fts(3) directory traversion functions.
|
||||||
|
A compatibility version will be bundled for 1.13.2 but is not available
|
||||||
|
yet. If you want apropos(1) and makewhatis(8) but do not have fts(3),
|
||||||
|
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,
|
||||||
|
see <https://sourceware.org/bugzilla/show_bug.cgi?id=15838>.
|
||||||
|
|
||||||
|
1.3. Marc Espie's ohash(3) library.
|
||||||
|
If your system does not have it, the bundled compatibility version
|
||||||
|
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
|
||||||
|
----------------------------------
|
||||||
|
If you want to check whether automatic configuration works well
|
||||||
|
on your platform, consider the following:
|
||||||
|
|
||||||
|
The mandoc package intentionally does not use GNU autoconf because
|
||||||
|
we consider that toolset a blatant example of overengineering that
|
||||||
|
is obsolete nowadays, since all modern operating systems are now
|
||||||
|
reasonably close to POSIX and do not need arcane shell magic any
|
||||||
|
longer. If your system does need such magic, consider upgrading
|
||||||
|
to reasonably modern POSIX-compliant tools rather than asking for
|
||||||
|
autoconf-style workarounds.
|
||||||
|
|
||||||
|
As far as mandoc is using any features not mandated by ANSI X3.159-1989
|
||||||
|
("ANSI C") or IEEE Std 1003.1-2008 ("POSIX") that some modern systems
|
||||||
|
do not have, we intend to provide autoconfiguration tests and
|
||||||
|
compat_*.c implementations. Please report any that turn out to be
|
||||||
|
missing. Note that while we do strive to produce portable code,
|
||||||
|
we do not slavishly restrict ourselves to POSIX-only interfaces.
|
||||||
|
For improved security and readability, we do use well-designed,
|
||||||
|
modern interfaces like reallocarray(3) even if they are still rather
|
||||||
|
uncommon, of course bundling compat_*.c implementations as needed.
|
||||||
|
|
||||||
|
Where mandoc is using ANSI C or POSIX features that some systems
|
||||||
|
still lack and that compat_*.c implementations can be provided for
|
||||||
|
without too much hassle, we will consider adding them, too, so
|
||||||
|
please report whatever is missing on your platform.
|
||||||
|
|
||||||
|
The following steps can be used to manually check the automatic
|
||||||
|
configuration on your platform:
|
||||||
|
|
||||||
|
1. Run "make clean".
|
||||||
|
|
||||||
|
2. Run "make config.h"
|
||||||
|
|
||||||
|
3. Read the file "config.log". It shows the compiler commands used
|
||||||
|
to test the libraries installed on your system and the standard
|
||||||
|
output and standard error output these commands produce. Watch out
|
||||||
|
for unexpected failures. Those are most likely to happen if headers
|
||||||
|
or libraries are installed in unusual places or interfaces defined
|
||||||
|
in unusual headers. You can also look at the file "config.h" and
|
||||||
|
check that no expected "#define HAVE_*" lines are missing. The
|
||||||
|
list of tests run can be found in the file "configure".
|
||||||
|
|
||||||
|
|
||||||
|
Deployment
|
||||||
|
----------
|
||||||
|
If you want to integrate the mandoc(1) tools with your existing
|
||||||
|
man(1) system as a formatter, then contact us first: on systems without
|
||||||
|
mandoc(1) as the default, you may have your work cut out for you!
|
||||||
|
Usually, you can have your default installation and mandoc(1) work right
|
||||||
|
alongside each other by using user-specific versions of the files
|
||||||
|
mentioned below.
|
||||||
|
|
||||||
|
0. Back up each file you want to change!
|
||||||
|
|
||||||
|
1. First see whether your system has "/etc/man.conf" or "/etc/manpath.conf"
|
||||||
|
(if it has neither, but man(1) is functional, then let us know) or,
|
||||||
|
if running as your own user, a per-user override file. In either
|
||||||
|
case, find where man(1) is executing nroff(1) or groff(1) to format
|
||||||
|
manuals. Replace these calls with mandoc(1).
|
||||||
|
|
||||||
|
2. Then make sure that man(1) isn't running preprocessors, so you may
|
||||||
|
need to replace tbl(1), eqn(1), and similar references with cat(1).
|
||||||
|
Some man(1) implementations, like that on Mac OSX, let you run "man -d"
|
||||||
|
to see how the formatter is invoked. Use this to test your changes. On
|
||||||
|
Mac OS X, for instance, man(1) will prepend all files with ".ll" and
|
||||||
|
".nr" to set the terminal size, so you need to pass "tail -n+2 |
|
||||||
|
mandoc(1)" to disregard them.
|
||||||
|
|
||||||
|
3. Finally, make sure that mandoc(1) is actually being invoked instead
|
||||||
|
of cached pages being pulled up. You can usually do this by commenting
|
||||||
|
out NOCACHE or similar.
|
||||||
|
|
||||||
|
mandoc(1) still has a long way to go in understanding non-trivial
|
||||||
|
low-level roff(7) markup embedded in some man(7) pages. On the BSD
|
||||||
|
systems using mandoc(1), third-party software is generally vetted
|
||||||
|
on whether it may be formatted with mandoc(1). If not, groff(1)
|
||||||
|
is pulled in as a dependency and used to install a pre-formatted
|
||||||
|
"catpage" intead of directly as manual page source.
|
||||||
|
|
||||||
|
For more background on switching operating systems to use mandoc(1)
|
||||||
|
instead of groff(1) to format manuals, see the two BSDCan presentations
|
||||||
|
by Ingo Schwarze:
|
||||||
|
<http://www.openbsd.org/papers/bsdcan11-mandoc-openbsd.html>
|
||||||
|
<http://www.openbsd.org/papers/bsdcan14-mandoc.pdf>
|
44
contrib/mdocml/LICENSE
Normal file
44
contrib/mdocml/LICENSE
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
$Id: LICENSE,v 1.2 2014/04/23 21:06:41 schwarze Exp $
|
||||||
|
|
||||||
|
With the exceptions noted below, all code and documentation
|
||||||
|
contained in the mdocml toolkit is protected by the Copyright
|
||||||
|
of the following developers:
|
||||||
|
|
||||||
|
Copyright (c) 2008, 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
Copyright (c) 2010, 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||||
|
Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||||
|
Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
|
||||||
|
Copyright (c) 1998, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||||
|
Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||||
|
|
||||||
|
See the individual source files for information about who contributed
|
||||||
|
to which file during which years.
|
||||||
|
|
||||||
|
|
||||||
|
The mdocml distribution as a whole is distributed by its developers
|
||||||
|
under the following license:
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
The following files included from outside sources are protected by
|
||||||
|
other people's Copyright and are distributed under a 3-clause BSD
|
||||||
|
license; see these individual files for details.
|
||||||
|
|
||||||
|
compat_getsubopt.c, compat_strcasestr.c, compat_strsep.c:
|
||||||
|
Copyright (c) 1990, 1993 The Regents of the University of California
|
||||||
|
|
||||||
|
compat_fgetln.c:
|
||||||
|
Copyright (c) 1998 The NetBSD Foundation, Inc.
|
505
contrib/mdocml/Makefile
Normal file
505
contrib/mdocml/Makefile
Normal file
@ -0,0 +1,505 @@
|
|||||||
|
# $Id: Makefile,v 1.435 2014/08/10 02:45:04 schwarze Exp $
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
# Copyright (c) 2011, 2013, 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.
|
||||||
|
|
||||||
|
VERSION = 1.13.1
|
||||||
|
|
||||||
|
# === 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
|
||||||
|
|
||||||
|
DBLIB += -lsqlite3
|
||||||
|
|
||||||
|
TESTSRCS = test-fgetln.c \
|
||||||
|
test-getsubopt.c \
|
||||||
|
test-mmap.c \
|
||||||
|
test-ohash.c \
|
||||||
|
test-reallocarray.c \
|
||||||
|
test-sqlite3_errstr.c \
|
||||||
|
test-strcasestr.c \
|
||||||
|
test-strlcat.c \
|
||||||
|
test-strlcpy.c \
|
||||||
|
test-strptime.c \
|
||||||
|
test-strsep.c
|
||||||
|
|
||||||
|
SRCS = apropos.c \
|
||||||
|
arch.c \
|
||||||
|
att.c \
|
||||||
|
cgi.c \
|
||||||
|
chars.c \
|
||||||
|
compat_fgetln.c \
|
||||||
|
compat_getsubopt.c \
|
||||||
|
compat_ohash.c \
|
||||||
|
compat_reallocarray.c \
|
||||||
|
compat_sqlite3_errstr.c \
|
||||||
|
compat_strcasestr.c \
|
||||||
|
compat_strlcat.c \
|
||||||
|
compat_strlcpy.c \
|
||||||
|
compat_strsep.c \
|
||||||
|
demandoc.c \
|
||||||
|
eqn.c \
|
||||||
|
eqn_html.c \
|
||||||
|
eqn_term.c \
|
||||||
|
html.c \
|
||||||
|
lib.c \
|
||||||
|
main.c \
|
||||||
|
man.c \
|
||||||
|
man_hash.c \
|
||||||
|
man_html.c \
|
||||||
|
man_macro.c \
|
||||||
|
man_term.c \
|
||||||
|
man_validate.c \
|
||||||
|
mandoc.c \
|
||||||
|
mandoc_aux.c \
|
||||||
|
mandocdb.c \
|
||||||
|
manpage.c \
|
||||||
|
manpath.c \
|
||||||
|
mansearch.c \
|
||||||
|
mansearch_const.c \
|
||||||
|
mdoc.c \
|
||||||
|
mdoc_argv.c \
|
||||||
|
mdoc_hash.c \
|
||||||
|
mdoc_html.c \
|
||||||
|
mdoc_macro.c \
|
||||||
|
mdoc_man.c \
|
||||||
|
mdoc_term.c \
|
||||||
|
mdoc_validate.c \
|
||||||
|
msec.c \
|
||||||
|
out.c \
|
||||||
|
preconv.c \
|
||||||
|
read.c \
|
||||||
|
roff.c \
|
||||||
|
st.c \
|
||||||
|
tbl.c \
|
||||||
|
tbl_data.c \
|
||||||
|
tbl_html.c \
|
||||||
|
tbl_layout.c \
|
||||||
|
tbl_opts.c \
|
||||||
|
tbl_term.c \
|
||||||
|
term.c \
|
||||||
|
term_ascii.c \
|
||||||
|
term_ps.c \
|
||||||
|
tree.c \
|
||||||
|
vol.c \
|
||||||
|
$(TESTSRCS)
|
||||||
|
|
||||||
|
DISTFILES = INSTALL \
|
||||||
|
LICENSE \
|
||||||
|
Makefile \
|
||||||
|
Makefile.depend \
|
||||||
|
NEWS \
|
||||||
|
TODO \
|
||||||
|
apropos.1 \
|
||||||
|
arch.in \
|
||||||
|
att.in \
|
||||||
|
cgi.h.example \
|
||||||
|
chars.in \
|
||||||
|
compat_ohash.h \
|
||||||
|
config.h.post \
|
||||||
|
config.h.pre \
|
||||||
|
configure \
|
||||||
|
demandoc.1 \
|
||||||
|
eqn.7 \
|
||||||
|
example.style.css \
|
||||||
|
gmdiff \
|
||||||
|
html.h \
|
||||||
|
lib.in \
|
||||||
|
libman.h \
|
||||||
|
libmandoc.h \
|
||||||
|
libmdoc.h \
|
||||||
|
libroff.h \
|
||||||
|
main.h \
|
||||||
|
makewhatis.8 \
|
||||||
|
man-cgi.css \
|
||||||
|
man.7 \
|
||||||
|
man.cgi.8 \
|
||||||
|
man.h \
|
||||||
|
mandoc.1 \
|
||||||
|
mandoc.3 \
|
||||||
|
mandoc.db.5 \
|
||||||
|
mandoc.h \
|
||||||
|
mandoc_aux.h \
|
||||||
|
mandoc_char.7 \
|
||||||
|
mandoc_escape.3 \
|
||||||
|
mandoc_html.3 \
|
||||||
|
mandoc_malloc.3 \
|
||||||
|
manpath.h \
|
||||||
|
mansearch.3 \
|
||||||
|
mansearch.h \
|
||||||
|
mchars_alloc.3 \
|
||||||
|
mdoc.7 \
|
||||||
|
mdoc.h \
|
||||||
|
msec.in \
|
||||||
|
out.h \
|
||||||
|
preconv.1 \
|
||||||
|
predefs.in \
|
||||||
|
roff.7 \
|
||||||
|
st.in \
|
||||||
|
style.css \
|
||||||
|
tbl.3 \
|
||||||
|
tbl.7 \
|
||||||
|
term.h \
|
||||||
|
vol.in \
|
||||||
|
$(SRCS)
|
||||||
|
|
||||||
|
LIBMAN_OBJS = man.o \
|
||||||
|
man_hash.o \
|
||||||
|
man_macro.o \
|
||||||
|
man_validate.o
|
||||||
|
|
||||||
|
LIBMDOC_OBJS = arch.o \
|
||||||
|
att.o \
|
||||||
|
lib.o \
|
||||||
|
mdoc.o \
|
||||||
|
mdoc_argv.o \
|
||||||
|
mdoc_hash.o \
|
||||||
|
mdoc_macro.o \
|
||||||
|
mdoc_validate.o \
|
||||||
|
st.o \
|
||||||
|
vol.o
|
||||||
|
|
||||||
|
LIBROFF_OBJS = eqn.o \
|
||||||
|
roff.o \
|
||||||
|
tbl.o \
|
||||||
|
tbl_data.o \
|
||||||
|
tbl_layout.o \
|
||||||
|
tbl_opts.o
|
||||||
|
|
||||||
|
LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
||||||
|
$(LIBMDOC_OBJS) \
|
||||||
|
$(LIBROFF_OBJS) \
|
||||||
|
chars.o \
|
||||||
|
mandoc.o \
|
||||||
|
mandoc_aux.o \
|
||||||
|
msec.o \
|
||||||
|
read.o
|
||||||
|
|
||||||
|
COMPAT_OBJS = compat_fgetln.o \
|
||||||
|
compat_getsubopt.o \
|
||||||
|
compat_ohash.o \
|
||||||
|
compat_reallocarray.o \
|
||||||
|
compat_sqlite3_errstr.o \
|
||||||
|
compat_strcasestr.o \
|
||||||
|
compat_strlcat.o \
|
||||||
|
compat_strlcpy.o \
|
||||||
|
compat_strsep.o
|
||||||
|
|
||||||
|
MANDOC_HTML_OBJS = eqn_html.o \
|
||||||
|
html.o \
|
||||||
|
man_html.o \
|
||||||
|
mdoc_html.o \
|
||||||
|
tbl_html.o
|
||||||
|
|
||||||
|
MANDOC_MAN_OBJS = mdoc_man.o
|
||||||
|
|
||||||
|
MANDOC_TERM_OBJS = eqn_term.o \
|
||||||
|
man_term.o \
|
||||||
|
mdoc_term.o \
|
||||||
|
term.o \
|
||||||
|
term_ascii.o \
|
||||||
|
term_ps.o \
|
||||||
|
tbl_term.o
|
||||||
|
|
||||||
|
MANDOC_OBJS = $(MANDOC_HTML_OBJS) \
|
||||||
|
$(MANDOC_MAN_OBJS) \
|
||||||
|
$(MANDOC_TERM_OBJS) \
|
||||||
|
main.o \
|
||||||
|
out.o \
|
||||||
|
tree.o
|
||||||
|
|
||||||
|
MAKEWHATIS_OBJS = mandocdb.o mansearch_const.o manpath.o
|
||||||
|
|
||||||
|
PRECONV_OBJS = preconv.o
|
||||||
|
|
||||||
|
APROPOS_OBJS = apropos.o mansearch.o mansearch_const.o manpath.o
|
||||||
|
|
||||||
|
CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
||||||
|
cgi.o \
|
||||||
|
mansearch.o \
|
||||||
|
mansearch_const.o \
|
||||||
|
out.o
|
||||||
|
|
||||||
|
MANPAGE_OBJS = manpage.o mansearch.o mansearch_const.o manpath.o
|
||||||
|
|
||||||
|
DEMANDOC_OBJS = demandoc.o
|
||||||
|
|
||||||
|
WWW_MANS = apropos.1.html \
|
||||||
|
demandoc.1.html \
|
||||||
|
mandoc.1.html \
|
||||||
|
preconv.1.html \
|
||||||
|
mandoc.3.html \
|
||||||
|
mandoc_escape.3.html \
|
||||||
|
mandoc_html.3.html \
|
||||||
|
mandoc_malloc.3.html \
|
||||||
|
mansearch.3.html \
|
||||||
|
mchars_alloc.3.html \
|
||||||
|
tbl.3.html \
|
||||||
|
mandoc.db.5.html \
|
||||||
|
eqn.7.html \
|
||||||
|
man.7.html \
|
||||||
|
mandoc_char.7.html \
|
||||||
|
mdoc.7.html \
|
||||||
|
roff.7.html \
|
||||||
|
tbl.7.html \
|
||||||
|
makewhatis.8.html \
|
||||||
|
man.cgi.8.html \
|
||||||
|
man.h.html \
|
||||||
|
mandoc.h.html \
|
||||||
|
mandoc_aux.h.html \
|
||||||
|
manpath.h.html \
|
||||||
|
mansearch.h.html \
|
||||||
|
mdoc.h.html
|
||||||
|
|
||||||
|
WWW_OBJS = mdocml.tar.gz \
|
||||||
|
mdocml.sha256
|
||||||
|
|
||||||
|
# === DEPENDENCY HANDLING ==============================================
|
||||||
|
|
||||||
|
all: base-build $(BUILD_TARGETS)
|
||||||
|
|
||||||
|
base-build: $(BASEBIN)
|
||||||
|
|
||||||
|
db-build: $(DBBIN)
|
||||||
|
|
||||||
|
cgi-build: $(CGIBIN)
|
||||||
|
|
||||||
|
install: base-install $(INSTALL_TARGETS)
|
||||||
|
|
||||||
|
www: $(WWW_OBJS) $(WWW_MANS)
|
||||||
|
|
||||||
|
include Makefile.depend
|
||||||
|
|
||||||
|
# === TARGETS CONTAINING SHELL COMMANDS ================================
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f libmandoc.a $(LIBMANDOC_OBJS)
|
||||||
|
rm -f apropos $(APROPOS_OBJS)
|
||||||
|
rm -f makewhatis $(MAKEWHATIS_OBJS)
|
||||||
|
rm -f preconv $(PRECONV_OBJS)
|
||||||
|
rm -f man.cgi $(CGI_OBJS)
|
||||||
|
rm -f manpage $(MANPAGE_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 -rf *.dSYM
|
||||||
|
|
||||||
|
base-install: base-build
|
||||||
|
mkdir -p $(DESTDIR)$(BINDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(EXAMPLEDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(LIBDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man7
|
||||||
|
$(INSTALL_PROGRAM) $(BASEBIN) $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
|
||||||
|
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \
|
||||||
|
$(DESTDIR)$(INCLUDEDIR)
|
||||||
|
$(INSTALL_MAN) mandoc.1 preconv.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
|
||||||
|
mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
|
||||||
|
$(INSTALL_MAN) man.7 mdoc.7 roff.7 eqn.7 tbl.7 mandoc_char.7 \
|
||||||
|
$(DESTDIR)$(MANDIR)/man7
|
||||||
|
$(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR)
|
||||||
|
|
||||||
|
db-install: db-build
|
||||||
|
mkdir -p $(DESTDIR)$(BINDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(SBINDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL_PROGRAM) apropos $(DESTDIR)$(BINDIR)
|
||||||
|
ln -f $(DESTDIR)$(BINDIR)/apropos $(DESTDIR)$(BINDIR)/whatis
|
||||||
|
$(INSTALL_PROGRAM) makewhatis $(DESTDIR)$(SBINDIR)
|
||||||
|
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
ln -f $(DESTDIR)$(MANDIR)/man1/apropos.1 \
|
||||||
|
$(DESTDIR)$(MANDIR)/man1/whatis.1
|
||||||
|
$(INSTALL_MAN) mansearch.3 $(DESTDIR)$(MANDIR)/man3
|
||||||
|
$(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5
|
||||||
|
$(INSTALL_MAN) makewhatis.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
|
|
||||||
|
cgi-install: cgi-build
|
||||||
|
mkdir -p $(DESTDIR)$(CGIBINDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(HTDOCDIR)
|
||||||
|
mkdir -p $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1
|
||||||
|
mkdir -p $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8
|
||||||
|
$(INSTALL_PROGRAM) man.cgi $(DESTDIR)$(CGIBINDIR)
|
||||||
|
$(INSTALL_DATA) example.style.css $(DESTDIR)$(HTDOCDIR)/man.css
|
||||||
|
$(INSTALL_DATA) man-cgi.css $(DESTDIR)$(HTDOCDIR)
|
||||||
|
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1/
|
||||||
|
$(INSTALL_MAN) man.cgi.8 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8/
|
||||||
|
|
||||||
|
www-install: www
|
||||||
|
mkdir -p $(DESTDIR)$(HTDOCDIR)/snapshots
|
||||||
|
$(INSTALL_DATA) $(WWW_MANS) style.css $(DESTDIR)$(HTDOCDIR)
|
||||||
|
$(INSTALL_DATA) $(WWW_OBJS) $(DESTDIR)$(HTDOCDIR)/snapshots
|
||||||
|
$(INSTALL_DATA) mdocml.tar.gz \
|
||||||
|
$(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz
|
||||||
|
$(INSTALL_DATA) mdocml.sha256 \
|
||||||
|
$(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256
|
||||||
|
|
||||||
|
depend: config.h
|
||||||
|
mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
|
||||||
|
perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
|
||||||
|
s|\\\n||g; s| +| |g; print;' Makefile.depend > Makefile.tmp
|
||||||
|
mv Makefile.tmp Makefile.depend
|
||||||
|
|
||||||
|
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||||
|
$(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||||
|
|
||||||
|
mandoc: $(MANDOC_OBJS) libmandoc.a
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(MANDOC_OBJS) libmandoc.a
|
||||||
|
|
||||||
|
makewhatis: $(MAKEWHATIS_OBJS) libmandoc.a
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(MAKEWHATIS_OBJS) libmandoc.a $(DBLIB)
|
||||||
|
|
||||||
|
preconv: $(PRECONV_OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(PRECONV_OBJS)
|
||||||
|
|
||||||
|
manpage: $(MANPAGE_OBJS) libmandoc.a
|
||||||
|
$(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
|
||||||
|
$(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB)
|
||||||
|
|
||||||
|
demandoc: $(DEMANDOC_OBJS) libmandoc.a
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a
|
||||||
|
|
||||||
|
mdocml.sha256: mdocml.tar.gz
|
||||||
|
sha256 mdocml.tar.gz > $@
|
||||||
|
|
||||||
|
mdocml.tar.gz: $(DISTFILES)
|
||||||
|
mkdir -p .dist/mdocml-$(VERSION)/
|
||||||
|
$(INSTALL_SOURCE) $(DISTFILES) .dist/mdocml-$(VERSION)
|
||||||
|
chmod 755 .dist/mdocml-$(VERSION)/configure
|
||||||
|
( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) )
|
||||||
|
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: clean depend
|
||||||
|
.SUFFIXES: .1 .3 .5 .7 .8 .h
|
||||||
|
.SUFFIXES: .1.html .3.html .5.html .7.html .8.html .h.html
|
||||||
|
|
||||||
|
.h.h.html:
|
||||||
|
highlight -I $< > $@
|
||||||
|
|
||||||
|
.1.1.html .3.3.html .5.5.html .7.7.html .8.8.html: mandoc
|
||||||
|
./mandoc -Thtml -Wall,stop \
|
||||||
|
-Ostyle=style.css,man=%N.%S.html,includes=%I.html $< > $@
|
70
contrib/mdocml/Makefile.depend
Normal file
70
contrib/mdocml/Makefile.depend
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
apropos.o: apropos.c config.h manpath.h mansearch.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
|
||||||
|
chars.o: chars.c config.h mandoc.h mandoc_aux.h libmandoc.h chars.in
|
||||||
|
compat_fgetln.o: compat_fgetln.c config.h
|
||||||
|
compat_getsubopt.o: compat_getsubopt.c config.h
|
||||||
|
compat_ohash.o: compat_ohash.c config.h
|
||||||
|
compat_reallocarray.o: compat_reallocarray.c config.h
|
||||||
|
compat_sqlite3_errstr.o: compat_sqlite3_errstr.c config.h
|
||||||
|
compat_strcasestr.o: compat_strcasestr.c config.h
|
||||||
|
compat_strlcat.o: compat_strlcat.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
|
||||||
|
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||||
|
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
|
||||||
|
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
|
||||||
|
html.o: html.c config.h mandoc.h mandoc_aux.h libmandoc.h out.h html.h main.h
|
||||||
|
lib.o: lib.c config.h mdoc.h libmdoc.h lib.in
|
||||||
|
main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h
|
||||||
|
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_html.o: man_html.c config.h mandoc.h mandoc_aux.h out.h html.h man.h main.h
|
||||||
|
man_macro.o: man_macro.c config.h man.h mandoc.h libmandoc.h libman.h
|
||||||
|
man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h
|
||||||
|
man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
|
||||||
|
mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h
|
||||||
|
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||||
|
mandocdb.o: mandocdb.c config.h mdoc.h man.h mandoc.h mandoc_aux.h manpath.h mansearch.h
|
||||||
|
manpage.o: manpage.c config.h manpath.h mansearch.h
|
||||||
|
manpath.o: manpath.c config.h mandoc_aux.h manpath.h
|
||||||
|
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.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_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
||||||
|
mdoc_hash.o: mdoc_hash.c config.h mdoc.h libmdoc.h
|
||||||
|
mdoc_html.o: mdoc_html.c config.h mandoc.h mandoc_aux.h out.h html.h mdoc.h main.h
|
||||||
|
mdoc_macro.o: mdoc_macro.c config.h mdoc.h mandoc.h libmdoc.h libmandoc.h
|
||||||
|
mdoc_man.o: mdoc_man.c config.h mandoc.h mandoc_aux.h out.h man.h mdoc.h main.h
|
||||||
|
mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main.h
|
||||||
|
mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
|
||||||
|
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
||||||
|
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
|
||||||
|
preconv.o: preconv.c config.h
|
||||||
|
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
|
||||||
|
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_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||||
|
tbl_html.o: tbl_html.c config.h mandoc.h out.h html.h
|
||||||
|
tbl_layout.o: tbl_layout.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||||
|
tbl_opts.o: tbl_opts.c config.h mandoc.h libmandoc.h libroff.h
|
||||||
|
tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h
|
||||||
|
term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
||||||
|
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
||||||
|
term_ps.o: term_ps.c config.h mandoc.h mandoc_aux.h out.h main.h term.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-fgetln.o: test-fgetln.c
|
||||||
|
test-getsubopt.o: test-getsubopt.c
|
||||||
|
test-mmap.o: test-mmap.c
|
||||||
|
test-ohash.o: test-ohash.c
|
||||||
|
test-reallocarray.o: test-reallocarray.c
|
||||||
|
test-sqlite3_errstr.o: test-sqlite3_errstr.c
|
||||||
|
test-strcasestr.o: test-strcasestr.c
|
||||||
|
test-strlcat.o: test-strlcat.c
|
||||||
|
test-strlcpy.o: test-strlcpy.c
|
||||||
|
test-strptime.o: test-strptime.c
|
||||||
|
test-strsep.o: test-strsep.c
|
@ -1,7 +1,87 @@
|
|||||||
$Id: NEWS,v 1.3 2013/10/13 16:06:50 schwarze Exp $
|
$Id: NEWS,v 1.5 2014/08/10 16:32:57 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.
|
||||||
|
|
||||||
|
Changes in version 1.13.1, released on August 10, 2014
|
||||||
|
|
||||||
|
--- MAJOR NEW FEATURES ---
|
||||||
|
* A complete apropos(1)/makewhatis(8)/man.cgi(8) suite
|
||||||
|
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
|
||||||
|
of numerical expressions.
|
||||||
|
* Warning and error messages have been improved in many ways.
|
||||||
|
Almost all fatal errors were downgraded to normal errors and some
|
||||||
|
even to warnings. Almost all messages now mention the macro where
|
||||||
|
the issue is detected and many indicate the workaround employed.
|
||||||
|
The mandoc(1) manual now includes a list explaining all messages.
|
||||||
|
--- MINOR NEW FEATURES ---
|
||||||
|
* The roff(7) parser now supports the .ami (append to macro with
|
||||||
|
indirectly specified name), .as (append to user-defined
|
||||||
|
string), .dei (define macro with indirectly specified name),
|
||||||
|
.ll (line length), and .rr (remove register) requests.
|
||||||
|
* The roff(7) parser now supports string comparison and numerical
|
||||||
|
conditionals in the .if and .ie requests.
|
||||||
|
* The roff parser now fully supports the \B (validate numerical
|
||||||
|
expression) and partially supports the \w (measure text width)
|
||||||
|
escape sequences.
|
||||||
|
* The terminal formatter now supports the \: (optional line break)
|
||||||
|
escape sequence.
|
||||||
|
* The roff parser now supports expansion of user-defined strings
|
||||||
|
involving indirect references.
|
||||||
|
* The roff(7) parser now handles some pre-defined read-only
|
||||||
|
number registers that occur in the pod2man(1) preamble.
|
||||||
|
* For backward compatibility, the mdoc(7) parser and formatters
|
||||||
|
now support the obsolete macros .En, .Es, .Fr, and .Ot.
|
||||||
|
* The mdoc(7) formatter non partially supports .Bd -centered.
|
||||||
|
* tbl(7) now handles leading and trailing vertical lines.
|
||||||
|
* The build system now provides fallback versions of strcasestr(3)
|
||||||
|
and strsep(3) for systems lacking them.
|
||||||
|
* The mdoc(7) manual now explains how various standards
|
||||||
|
supported by the .St macro are related to each other.
|
||||||
|
--- BUGFIXES ---
|
||||||
|
* In the roff(7) parser, several bugs were fixed with respect
|
||||||
|
to closing conditional blocks on macro lines.
|
||||||
|
* Parsing of roff(7) identifiers and escape sequences was improved
|
||||||
|
in multiple respects.
|
||||||
|
* In the mdoc(7) parser, the handling of defective document
|
||||||
|
prologues was improved in multiple ways.
|
||||||
|
* The mdoc(7) parser no longer skips content before the first section
|
||||||
|
header, and it no longer deletes non-.% content from .Rs blocks.
|
||||||
|
* In the mdoc(7) parser, a crash was fixed related to weird .Sh headers.
|
||||||
|
* In the mdoc(7) parser, handling of .Sm with missing or invalid
|
||||||
|
arguments was corrected.
|
||||||
|
* In the mdoc(7) parser, trailing punctuation at the end of partial
|
||||||
|
implicit macros no longer triggers end-of-sentence spacing.
|
||||||
|
* In the terminal formatter, two crashes were fixed: one triggered by
|
||||||
|
excessive indentation and another by excessively long .Nm arguments.
|
||||||
|
* In the terminal formatter, a floating point rounding bug was
|
||||||
|
fixed that sometimes caused an off-by-one error in indentation.
|
||||||
|
* In the UTF-8 formatter, rendering of accents, breakable hyphens,
|
||||||
|
and non-breakable spaces was corrected.
|
||||||
|
* In the HTML formatter, encoding of special characters was
|
||||||
|
corrected in multiple respects.
|
||||||
|
* In the mdoc(7) formatter, rendering of .Ex and .Rv was
|
||||||
|
improved for various edge cases.
|
||||||
|
* In the mdoc(7) formatter, handling of empty .Bl -inset item
|
||||||
|
heads was improved.
|
||||||
|
* In the man(7) formatter, some bugs were fixed with respect
|
||||||
|
to same-line detection in the context of .TP and .nf macros,
|
||||||
|
and the indentation of .IP and .TP blocks was improved.
|
||||||
|
* The mandoc(3) library no longer prints to stderr.
|
||||||
|
--- THANKS TO ---
|
||||||
|
Abhinav Upadhyay (NetBSD), Andreas Voegele, Anthony Bentley (OpenBSD),
|
||||||
|
Christian Weisgerber (OpenBSD), Havard Eidnes (NetBSD), Jan Stary,
|
||||||
|
Jason McIntyre (OpenBSD), Jeremie Courreges-Anglas (OpenBSD),
|
||||||
|
Joerg Sonnenberger (NetBSD), Juan Francisco Cantero Hurtado (OpenBSD),
|
||||||
|
Marc Espie (OpenBSD), Matthias Scheler (NetBSD), Pascal Stumpf (OpenBSD),
|
||||||
|
Paul Onyschuk (Alpine Linux), Sebastien Marie, Steffen Nurpmeso,
|
||||||
|
Stuart Henderson (OpenBSD), Ted Unangst (OpenBSD), Theo de Raadt (OpenBSD),
|
||||||
|
Thomas Klausner (NetBSD), and Ulrich Spoerlein (FreeBSD)
|
||||||
|
for reporting bugs and missing features.
|
||||||
|
|
||||||
Changes in version 1.12.3, released on December 31, 2013
|
Changes in version 1.12.3, released on December 31, 2013
|
||||||
|
|
||||||
* In the mdoc(7) SYNOPSIS, line breaks and hanging indentation
|
* In the mdoc(7) SYNOPSIS, line breaks and hanging indentation
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
************************************************************************
|
************************************************************************
|
||||||
* Official mandoc TODO.
|
* Official mandoc TODO.
|
||||||
* $Id: TODO,v 1.162 2013/12/25 14:40:34 schwarze Exp $
|
* $Id: TODO,v 1.176 2014/08/09 14:24:53 schwarze Exp $
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* crashes
|
* crashes
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
None known.
|
- The abort() in bufcat(), html.c, can be triggered via buffmt_includes()
|
||||||
|
by running -Thtml -Oincludes on a file containing a long .In argument.
|
||||||
|
Fixing this will probably require reworking the whole bufcat() concept.
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* missing features
|
* missing features
|
||||||
@ -15,11 +17,6 @@ None known.
|
|||||||
|
|
||||||
--- missing roff features ----------------------------------------------
|
--- missing roff features ----------------------------------------------
|
||||||
|
|
||||||
- roff.c should treat \n(.H>23 and \n(.V>19 in the pod2man(1)
|
|
||||||
preamble as true, see for example AUTHORS in MooseX::Getopt.3p
|
|
||||||
reported by Andreas Voegele <mail at andreasvoegele dot com>
|
|
||||||
Tue, 22 Nov 2011 15:34:47 +0100 on ports@
|
|
||||||
|
|
||||||
- .ad (adjust margins)
|
- .ad (adjust margins)
|
||||||
.ad l -- adjust left margin only (flush left)
|
.ad l -- adjust left margin only (flush left)
|
||||||
.ad r -- adjust right margin only (flush right)
|
.ad r -- adjust right margin only (flush right)
|
||||||
@ -29,20 +26,9 @@ None known.
|
|||||||
.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).
|
||||||
|
|
||||||
- .as (append to string)
|
|
||||||
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
|
||||||
|
|
||||||
- .ce (center N lines)
|
|
||||||
found by naddy@ in xloadimage(1)
|
|
||||||
found by Juan Francisco Cantero Hurtado <iam at juanfra dot info>
|
|
||||||
in lang/racket(1) Thu, 20 Jun 2013 03:19:11 +0200
|
|
||||||
|
|
||||||
- .fc (field control)
|
- .fc (field control)
|
||||||
found by naddy@ in xloadimage(1)
|
found by naddy@ in xloadimage(1)
|
||||||
|
|
||||||
- .ll (line length)
|
|
||||||
found by naddy@ in textproc/enchant(1) Sat, 12 Oct 2013 03:27:10 +0200
|
|
||||||
|
|
||||||
- .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
|
||||||
|
|
||||||
@ -51,6 +37,7 @@ None known.
|
|||||||
|
|
||||||
- .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
|
||||||
|
|
||||||
- .ti (temporary indent)
|
- .ti (temporary indent)
|
||||||
found by naddy@ in xloadimage(1)
|
found by naddy@ in xloadimage(1)
|
||||||
@ -70,6 +57,10 @@ None known.
|
|||||||
- \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
|
||||||
|
|
||||||
|
- \w'' width measurements
|
||||||
|
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
|
||||||
|
|
||||||
- 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
|
||||||
|
|
||||||
@ -96,6 +87,12 @@ None known.
|
|||||||
because libmdoc does not yet use mandoc_getarg().
|
because libmdoc does not yet use mandoc_getarg().
|
||||||
Also check what happens in plain text, it must be identical to \e.
|
Also check what happens in plain text, it must be identical to \e.
|
||||||
|
|
||||||
|
- .Bd -centered implies -filled, not -unfilled, which is not
|
||||||
|
easy to implement; it requires code similar to .ce, which
|
||||||
|
we don't have either.
|
||||||
|
Besides, groff has bug causing text right *before* .Bd -centered
|
||||||
|
to be centered as well.
|
||||||
|
|
||||||
- .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).
|
||||||
@ -129,10 +126,19 @@ None known.
|
|||||||
|
|
||||||
- have a blank `It' head for `Bl -tag' not puke
|
- have a blank `It' head for `Bl -tag' not puke
|
||||||
|
|
||||||
|
- check whether it is correct that `D1' uses INDENT+1;
|
||||||
|
does it need its own constant?
|
||||||
|
|
||||||
- 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)
|
||||||
(mdoc_html.c and mdoc_term.c `Nm' handlers can be slightly simplified)
|
(mdoc_html.c and mdoc_term.c `Nm' handlers can be slightly simplified)
|
||||||
|
|
||||||
|
- support translated section names
|
||||||
|
e.g. x11/scrotwm scrotwm_es.1:21:2: error: NAME section must be first
|
||||||
|
that one uses NOMBRE because it is spanish...
|
||||||
|
deraadt tends to think that section-dependent macro behaviour
|
||||||
|
is a bad idea in the first place, so this may be irrelevant
|
||||||
|
|
||||||
- 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
|
||||||
macro, while mandoc treats it as a block macro and breaks the line.
|
macro, while mandoc treats it as a block macro and breaks the line.
|
||||||
@ -143,18 +149,15 @@ None known.
|
|||||||
|
|
||||||
--- missing man features -----------------------------------------------
|
--- missing man features -----------------------------------------------
|
||||||
|
|
||||||
- groff an-ext.tmac macros (.UR, .UE) occur in xine(5)
|
|
||||||
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
|
||||||
also occur in freeciv-client(6) freeciv-server(6) freeciv-modpack(6)
|
|
||||||
reported by bentley@ Tue, 30 Oct 2012 01:05:57 -0600
|
|
||||||
|
|
||||||
- -T[x]html doesn't stipulate non-collapsing spaces in literal mode
|
- -T[x]html doesn't stipulate non-collapsing spaces in literal mode
|
||||||
|
|
||||||
--- missing tbl features -----------------------------------------------
|
--- missing tbl features -----------------------------------------------
|
||||||
|
|
||||||
- implement basic non-parametric .de to support e.g. sox(1)
|
- look at the POSIX manuals in the books/man-pages-posix port,
|
||||||
reported by naddy@ Sat, 16 Oct 2010 23:51:57 +0200
|
they use some unsupported tbl(7) features.
|
||||||
*** sox(1) still doesn't work, tbl(1) errors need investigation
|
|
||||||
|
- investigate tbl(1) errors in sox(1)
|
||||||
|
see also naddy@ Sat, 16 Oct 2010 23:51:57 +0200
|
||||||
|
|
||||||
- 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
|
||||||
@ -165,14 +168,19 @@ None known.
|
|||||||
- 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
|
||||||
|
|
||||||
- The whatis(1) utility looks for whole words in Nm.
|
- When makewhatis(8) encounters a FATAL parse error,
|
||||||
If the file name of a page does not agree with the contents of any
|
it silently treats the file as formatted, which makes no sense
|
||||||
of its Nm macros (e.g. pool(9)), add the file name as an Nm entry
|
at all for paths like man1/foo.1 - and which also contradicts
|
||||||
to the mandoc.db as well, such that whatis(1) finds it.
|
what the manual says at the end of the description.
|
||||||
If there is a page with a file name that does not appear as a substring
|
The end result will be ENOENT for file names returned
|
||||||
neither in Nm nor in Nd, the same fix would allow finding that page
|
by mansearch() in manpage.file.
|
||||||
with apropos(1) using the file name as a key, as well.
|
|
||||||
Issue reported by tedu@ Fri, 05 Jul 2013 21:15:23 -0400
|
- makewhatis(8) for preformatted pages:
|
||||||
|
parse the section number from the header line
|
||||||
|
and compare to the section number from the directory name
|
||||||
|
|
||||||
|
- Does makewhatis(8) detect missing NAME sections, missing names,
|
||||||
|
and missing descriptions in all the file formats?
|
||||||
|
|
||||||
- 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
|
||||||
@ -181,6 +189,16 @@ None known.
|
|||||||
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
|
||||||
|
|
||||||
|
- kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET)
|
||||||
|
|
||||||
|
--- compatibility checks -----------------------------------------------
|
||||||
|
|
||||||
|
- is .Bk implemented correctly in modern groff?
|
||||||
|
sobrado@ Tue, 19 Apr 2011 22:12:55 +0200
|
||||||
|
|
||||||
|
- compare output to Heirloom roff, Solaris roff, and
|
||||||
|
http://repo.or.cz/w/neatroff.git http://litcave.rudi.ir/
|
||||||
|
|
||||||
- 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.
|
||||||
@ -188,14 +206,24 @@ None known.
|
|||||||
noted by stsp@ Sat, 24 Apr 2010 09:17:55 +0200
|
noted by stsp@ Sat, 24 Apr 2010 09:17:55 +0200
|
||||||
reminded by nicm@ Mon, 3 May 2010 09:52:41 +0100
|
reminded by nicm@ Mon, 3 May 2010 09:52:41 +0100
|
||||||
|
|
||||||
|
- look at pages generated from ronn(1) github.com/rtomayko/ronn
|
||||||
|
(based on markdown)
|
||||||
|
|
||||||
- look at pages generated from Texinfo source by yat2m, e.g. security/gnupg
|
- look at pages generated from Texinfo source by yat2m, e.g. security/gnupg
|
||||||
First impression is not that bad.
|
First impression is not that bad.
|
||||||
|
|
||||||
|
- look at pages generated by pandoc; see
|
||||||
|
https://github.com/jgm/pandoc/blob/master/src/Text/Pandoc/Writers/Man.hs
|
||||||
|
porting planned by kili@ Thu, 19 Jun 2014 19:46:28 +0200
|
||||||
|
|
||||||
- check compatibility with Plan9:
|
- check compatibility with Plan9:
|
||||||
http://swtch.com/usr/local/plan9/tmac/tmac.an
|
http://swtch.com/usr/local/plan9/tmac/tmac.an
|
||||||
http://swtch.com/plan9port/man/man7/man.html
|
http://swtch.com/plan9port/man/man7/man.html
|
||||||
"Anthony J. Bentley" <anthonyjbentley@gmail.com> 28 Dec 2010 21:58:40 -0700
|
"Anthony J. Bentley" <anthonyjbentley@gmail.com> 28 Dec 2010 21:58:40 -0700
|
||||||
|
|
||||||
|
- check compatibility with the man(7) formatter
|
||||||
|
https://raw.githubusercontent.com/rofl0r/hardcore-utils/master/man.c
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* formatting issues: ugly output
|
* formatting issues: ugly output
|
||||||
************************************************************************
|
************************************************************************
|
||||||
@ -227,6 +255,10 @@ None known.
|
|||||||
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
|
||||||
|
|
||||||
|
- global variables in the SYNOPSIS of section 3 pages
|
||||||
|
.Vt vs .Vt/.Va vs .Ft/.Va vs .Ft/.Fa ...
|
||||||
|
from kristaps@ Tue, 08 Jun 2010 11:13:32 +0200
|
||||||
|
|
||||||
- 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
|
||||||
|
|
||||||
@ -234,6 +266,23 @@ None known.
|
|||||||
reveals lots of bugs both in groff and mandoc...
|
reveals lots of bugs both in groff and mandoc...
|
||||||
reported by bentley@ Wed, 22 May 2013 23:49:30 -0600
|
reported by bentley@ Wed, 22 May 2013 23:49:30 -0600
|
||||||
|
|
||||||
|
--- PDF issues ---------------------------------------------------------
|
||||||
|
|
||||||
|
- PDF output doesn't use a monospaced font for .Bd -literal
|
||||||
|
Example: "mandoc -Tpdf afterboot.8 > output.pdf && pdfviewer output.pdf".
|
||||||
|
Search the text "Routing tables".
|
||||||
|
Also check what PostScript mode does when fixing this.
|
||||||
|
reported by juanfra@ Wed, 04 Jun 2014 21:44:58 +0200
|
||||||
|
|
||||||
|
--- HTML issues --------------------------------------------------------
|
||||||
|
|
||||||
|
- <dl><dt><dd> formatting is ugly
|
||||||
|
hints are easy to find on the web, e.g.
|
||||||
|
http://stackoverflow.com/questions/1713048/
|
||||||
|
see also matthew@ Fri, 18 Jul 2014 19:25:12 -0700
|
||||||
|
|
||||||
|
- check https://github.com/trentm/mdocml
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* formatting issues: gratuitous differences
|
* formatting issues: gratuitous differences
|
||||||
************************************************************************
|
************************************************************************
|
||||||
@ -246,6 +295,10 @@ None known.
|
|||||||
is just "o\bo".
|
is just "o\bo".
|
||||||
see for example OpenBSD ksh(1)
|
see for example OpenBSD ksh(1)
|
||||||
|
|
||||||
|
- In .Bl -enum -width 0n, groff continues one the same line after
|
||||||
|
the number, mandoc breaks the line.
|
||||||
|
mail to kristaps@ Mon, 20 Jul 2009 02:21:39 +0200
|
||||||
|
|
||||||
- .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
|
||||||
@ -298,10 +351,58 @@ None known.
|
|||||||
operate in batch mode
|
operate in batch mode
|
||||||
in dig(1).
|
in dig(1).
|
||||||
|
|
||||||
|
************************************************************************
|
||||||
|
* warning issues
|
||||||
|
************************************************************************
|
||||||
|
|
||||||
|
- check that MANDOCERR_BADTAB is thrown in the right cases,
|
||||||
|
i.e. when finding a literal tab character in fill mode,
|
||||||
|
and possibly change the wording of the warning message
|
||||||
|
to refer to fill mode, not literal mode
|
||||||
|
See the mail from Werner LEMBERG on the groff list,
|
||||||
|
Fri, 14 Feb 2014 18:54:42 +0100 (CET)
|
||||||
|
|
||||||
|
- warn about "new sentence, new line"
|
||||||
|
|
||||||
|
- mandoc_special does not really check the escape sequence,
|
||||||
|
but just the overall format
|
||||||
|
|
||||||
|
- integrate mdoclint into mandoc ("end-of-line whitespace" thread)
|
||||||
|
from jmc@ Mon, 13 Jul 2009 17:12:09 +0100
|
||||||
|
from kristaps@ Mon, 13 Jul 2009 18:34:53 +0200
|
||||||
|
from jmc@ Mon, 13 Jul 2009 17:45:37 +0059
|
||||||
|
from kristaps@ Mon, 13 Jul 2009 19:02:03 +0200
|
||||||
|
|
||||||
|
- -Tlint parser errors and warnings to stdout
|
||||||
|
to tech@mdocml, naddy@ Wed, 28 Sep 2011 11:21:46 +0200
|
||||||
|
wait! kristaps@ Sun, 02 Oct 2011 17:12:52 +0200
|
||||||
|
|
||||||
|
- for system errors, use errno/strerror/warn/err
|
||||||
|
|
||||||
|
************************************************************************
|
||||||
|
* documentation issues
|
||||||
|
************************************************************************
|
||||||
|
|
||||||
|
- mention hyphenation rules:
|
||||||
|
breaking at letter-letter in text mode (not macro args)
|
||||||
|
proper hyphenation is unimplemented
|
||||||
|
|
||||||
|
- talk about spacing around delimiters
|
||||||
|
to jmc@, kristaps@ Sat, 23 Apr 2011 17:41:27 +0200
|
||||||
|
|
||||||
|
- mark macros as: page structure domain, manual domain, general text domain
|
||||||
|
is this useful?
|
||||||
|
|
||||||
|
- mention /usr/share/misc/mdoc.template in mdoc(7)?
|
||||||
|
|
||||||
************************************************************************
|
************************************************************************
|
||||||
* performance issues
|
* performance issues
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
|
- Why are we using MAP_SHARED, not MAP_PRIVATE for mmap(2)?
|
||||||
|
How does SQLITE_CONFIG_PAGECACHE actually work? Document it!
|
||||||
|
from kristaps@ Sat, 09 Aug 2014 13:51:36 +0200
|
||||||
|
|
||||||
Several areas can be cleaned up to make mandoc even faster. These are
|
Several areas can be cleaned up to make mandoc even faster. These are
|
||||||
|
|
||||||
- improve hashing mechanism for macros (quite important: performance)
|
- improve hashing mechanism for macros (quite important: performance)
|
||||||
@ -328,3 +429,9 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
|||||||
Decide which formats should be recognized where.
|
Decide which formats should be recognized where.
|
||||||
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
|
||||||
|
|
||||||
|
- Consider creating some views that will make the database more
|
||||||
|
readable from the sqlite3 shell. Consider using them to
|
||||||
|
abstract from the database structure, too.
|
||||||
|
suggested by espie@ Sat, 19 Apr 2014 14:52:57 +0200
|
||||||
|
|
||||||
|
387
contrib/mdocml/apropos.1
Normal file
387
contrib/mdocml/apropos.1
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
.\" $Id: apropos.1,v 1.29 2014/04/24 00:28:19 schwarze Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
.\" Copyright (c) 2011, 2012, 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: April 24 2014 $
|
||||||
|
.Dt APROPOS 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm apropos ,
|
||||||
|
.Nm whatis
|
||||||
|
.Nd search manual page databases
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl C Ar file
|
||||||
|
.Op Fl M Ar path
|
||||||
|
.Op Fl m Ar path
|
||||||
|
.Op Fl O Ar outkey
|
||||||
|
.Op Fl S Ar arch
|
||||||
|
.Op Fl s Ar section
|
||||||
|
.Ar expression ...
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm apropos
|
||||||
|
and
|
||||||
|
.Nm whatis
|
||||||
|
utilities query manual page databases generated by
|
||||||
|
.Xr makewhatis 8 ,
|
||||||
|
evaluating
|
||||||
|
.Ar expression
|
||||||
|
for each file in each database.
|
||||||
|
By default, it displays the names, section numbers, and description lines
|
||||||
|
of all matching manuals.
|
||||||
|
.Pp
|
||||||
|
By default,
|
||||||
|
.Nm
|
||||||
|
searches for
|
||||||
|
.Xr makewhatis 8
|
||||||
|
databases in the default paths stipulated by
|
||||||
|
.Xr man 1
|
||||||
|
and uses case-insensitive substring matching
|
||||||
|
.Pq the Cm = No operator
|
||||||
|
over manual names and descriptions
|
||||||
|
.Pq the Li \&Nm No and Li \&Nd No macro keys .
|
||||||
|
Multiple terms imply pairwise
|
||||||
|
.Fl o .
|
||||||
|
.Nm whatis
|
||||||
|
maps terms only to case-sensitive manual names.
|
||||||
|
.Pp
|
||||||
|
Its arguments are as follows:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Fl C Ar file
|
||||||
|
Specify an alternative configuration
|
||||||
|
.Ar file
|
||||||
|
in
|
||||||
|
.Xr man.conf 5
|
||||||
|
format.
|
||||||
|
.It Fl M Ar path
|
||||||
|
Use the colon-separated path instead of the default list of paths
|
||||||
|
searched for
|
||||||
|
.Xr makewhatis 8
|
||||||
|
databases.
|
||||||
|
Invalid paths, or paths without manual databases, are ignored.
|
||||||
|
.It Fl m Ar path
|
||||||
|
Prepend the colon-separated paths to the list of paths searched
|
||||||
|
for
|
||||||
|
.Xr makewhatis 8
|
||||||
|
databases.
|
||||||
|
Invalid paths, or paths without manual databases, are ignored.
|
||||||
|
.It Fl O Ar outkey
|
||||||
|
Show the values associated with the key
|
||||||
|
.Ar outkey
|
||||||
|
instead of the manual descriptions.
|
||||||
|
.It Fl S Ar arch
|
||||||
|
Restrict the search to pages for the specified
|
||||||
|
.Xr machine 1
|
||||||
|
architecture.
|
||||||
|
.Ar arch
|
||||||
|
is case insensitive.
|
||||||
|
By default, pages for all architectures are shown.
|
||||||
|
.It Fl s Ar section
|
||||||
|
Restrict the search to the specified section of the manual.
|
||||||
|
By default, pages from all sections are shown.
|
||||||
|
See
|
||||||
|
.Xr man 1
|
||||||
|
for a listing of sections.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
An
|
||||||
|
.Ar expression
|
||||||
|
consists of search terms joined by logical operators
|
||||||
|
.Fl a
|
||||||
|
.Pq and
|
||||||
|
and
|
||||||
|
.Fl o
|
||||||
|
.Pq or .
|
||||||
|
The
|
||||||
|
.Fl a
|
||||||
|
operator has precedence over
|
||||||
|
.Fl o
|
||||||
|
and both are evaluated left-to-right.
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It \&( Ar expr No \&)
|
||||||
|
True if the subexpression
|
||||||
|
.Ar expr
|
||||||
|
is true.
|
||||||
|
.It Ar expr1 Fl a Ar expr2
|
||||||
|
True if both
|
||||||
|
.Ar expr1
|
||||||
|
and
|
||||||
|
.Ar expr2
|
||||||
|
are true (logical
|
||||||
|
.Sq and ) .
|
||||||
|
.It Ar expr1 Oo Fl o Oc Ar expr2
|
||||||
|
True if
|
||||||
|
.Ar expr1
|
||||||
|
and/or
|
||||||
|
.Ar expr2
|
||||||
|
evaluate to true (logical
|
||||||
|
.Sq or ) .
|
||||||
|
.It Ar term
|
||||||
|
True if
|
||||||
|
.Ar term
|
||||||
|
is satisfied.
|
||||||
|
This has syntax
|
||||||
|
.Sm off
|
||||||
|
.Oo
|
||||||
|
.Op Ar key Op , Ar key ...
|
||||||
|
.Pq Cm = | ~
|
||||||
|
.Oc
|
||||||
|
.Ar val ,
|
||||||
|
.Sm on
|
||||||
|
where
|
||||||
|
.Ar key
|
||||||
|
is an
|
||||||
|
.Xr mdoc 7
|
||||||
|
macro to query and
|
||||||
|
.Ar val
|
||||||
|
is its value.
|
||||||
|
See
|
||||||
|
.Sx Macro Keys
|
||||||
|
for a list of available keys.
|
||||||
|
Operator
|
||||||
|
.Cm =
|
||||||
|
evaluates a substring, while
|
||||||
|
.Cm ~
|
||||||
|
evaluates a regular expression.
|
||||||
|
.It Fl i Ar term
|
||||||
|
If
|
||||||
|
.Ar term
|
||||||
|
is a regular expression, it
|
||||||
|
is evaluated case-insensitively.
|
||||||
|
Has no effect on substring terms.
|
||||||
|
.El
|
||||||
|
.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
|
||||||
|
.Pp
|
||||||
|
.D1 name[, name...](sec) \- description
|
||||||
|
.Pp
|
||||||
|
Where
|
||||||
|
.Dq name
|
||||||
|
is the manual's name,
|
||||||
|
.Dq sec
|
||||||
|
is the manual section, and
|
||||||
|
.Dq description
|
||||||
|
is the manual's short description.
|
||||||
|
If an architecture is specified for the manual, it is displayed as
|
||||||
|
.Pp
|
||||||
|
.D1 name(sec/arch) \- description
|
||||||
|
.Pp
|
||||||
|
Resulting manuals may be accessed as
|
||||||
|
.Pp
|
||||||
|
.Dl $ man \-s sec name
|
||||||
|
.Pp
|
||||||
|
If an architecture is specified in the output, use
|
||||||
|
.Pp
|
||||||
|
.Dl $ man \-s sec \-S arch name
|
||||||
|
.Ss Macro Keys
|
||||||
|
Queries evaluate over a subset of
|
||||||
|
.Xr mdoc 7
|
||||||
|
macros indexed by
|
||||||
|
.Xr makewhatis 8 .
|
||||||
|
In addition to the macro keys listed below, the special key
|
||||||
|
.Cm any
|
||||||
|
may be used to match any available macro key.
|
||||||
|
.Pp
|
||||||
|
Names and description:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&Nm Ta manual name
|
||||||
|
.It Li \&Nd Ta one-line manual description
|
||||||
|
.It Li arch Ta machine architecture (case-insensitive)
|
||||||
|
.It Li sec Ta manual section number
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Sections and cross references:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&Sh Ta section header (excluding standard sections)
|
||||||
|
.It Li \&Ss Ta subsection header
|
||||||
|
.It Li \&Xr Ta cross reference to another manual page
|
||||||
|
.It Li \&Rs Ta bibliographic reference
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Semantic markup for command line utilities:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&Fl Ta command line options (flags)
|
||||||
|
.It Li \&Cm Ta command modifier
|
||||||
|
.It Li \&Ar Ta command argument
|
||||||
|
.It Li \&Ic Ta internal or interactive command
|
||||||
|
.It Li \&Ev Ta environmental variable
|
||||||
|
.It Li \&Pa Ta file system path
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Semantic markup for function libraries:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&Lb Ta function library name
|
||||||
|
.It Li \&In Ta include file
|
||||||
|
.It Li \&Ft Ta function return type
|
||||||
|
.It Li \&Fn Ta function name
|
||||||
|
.It Li \&Fa Ta function argument type and name
|
||||||
|
.It Li \&Vt Ta variable type
|
||||||
|
.It Li \&Va Ta variable name
|
||||||
|
.It Li \&Dv Ta defined variable or preprocessor constant
|
||||||
|
.It Li \&Er Ta error constant
|
||||||
|
.It Li \&Ev Ta environmental variable
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Various semantic markup:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&An Ta author name
|
||||||
|
.It Li \&Lk Ta hyperlink
|
||||||
|
.It Li \&Mt Ta Do mailto Dc hyperlink
|
||||||
|
.It Li \&Cd Ta kernel configuration declaration
|
||||||
|
.It Li \&Ms Ta mathematical symbol
|
||||||
|
.It Li \&Tn Ta tradename
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Physical markup:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&Em Ta italic font or underline
|
||||||
|
.It Li \&Sy Ta boldface font
|
||||||
|
.It Li \&Li Ta typewriter font
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Text production:
|
||||||
|
.Bl -column "xLix" description -offset indent -compact
|
||||||
|
.It Li \&St Ta reference to a standards document
|
||||||
|
.It Li \&At Ta At No version reference
|
||||||
|
.It Li \&Bx Ta Bx No version reference
|
||||||
|
.It Li \&Bsx Ta Bsx No version reference
|
||||||
|
.It Li \&Nx Ta Nx No version reference
|
||||||
|
.It Li \&Fx Ta Fx No version reference
|
||||||
|
.It Li \&Ox Ta Ox No version reference
|
||||||
|
.It Li \&Dx Ta Dx No version reference
|
||||||
|
.El
|
||||||
|
.Sh ENVIRONMENT
|
||||||
|
.Bl -tag -width MANPATH
|
||||||
|
.It Ev MANPATH
|
||||||
|
The standard search path used by
|
||||||
|
.Xr man 1
|
||||||
|
may be changed by specifying a path in the
|
||||||
|
.Ev MANPATH
|
||||||
|
environment variable.
|
||||||
|
Invalid paths, or paths without manual databases, are ignored.
|
||||||
|
Overridden by
|
||||||
|
.Fl M .
|
||||||
|
If
|
||||||
|
.Ev MANPATH
|
||||||
|
begins with a colon, it is appended to the default list;
|
||||||
|
if it ends with a colon, it is prepended to the default list;
|
||||||
|
or if it contains two adjacent colons,
|
||||||
|
the standard search path is inserted between the colons.
|
||||||
|
If none of these conditions are met, it overrides the
|
||||||
|
standard search path.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width "/etc/man.conf" -compact
|
||||||
|
.It Pa mandoc.db
|
||||||
|
name of the
|
||||||
|
.Xr makewhatis 8
|
||||||
|
keyword database
|
||||||
|
.It Pa /etc/man.conf
|
||||||
|
default
|
||||||
|
.Xr man 1
|
||||||
|
configuration file
|
||||||
|
.El
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
.Ex -std
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Search for
|
||||||
|
.Qq .cf
|
||||||
|
as a substring of manual names and descriptions:
|
||||||
|
.Pp
|
||||||
|
.Dl $ apropos .cf
|
||||||
|
.Pp
|
||||||
|
Include matches for
|
||||||
|
.Qq .cnf
|
||||||
|
and
|
||||||
|
.Qq .conf
|
||||||
|
as well:
|
||||||
|
.Pp
|
||||||
|
.Dl $ apropos .cf .cnf .conf
|
||||||
|
.Pp
|
||||||
|
Search in names and descriptions using a regular expression:
|
||||||
|
.Pp
|
||||||
|
.Dl $ apropos '~set.?[ug]id'
|
||||||
|
.Pp
|
||||||
|
Search for manuals in the library section mentioning both the
|
||||||
|
.Qq optind
|
||||||
|
and the
|
||||||
|
.Qq optarg
|
||||||
|
variables:
|
||||||
|
.Pp
|
||||||
|
.Dl $ apropos \-s 3 Va=optind \-a Va=optarg
|
||||||
|
.Pp
|
||||||
|
Do exactly the same as calling
|
||||||
|
.Xr whatis 1
|
||||||
|
with the argument
|
||||||
|
.Qq ssh :
|
||||||
|
.Pp
|
||||||
|
.Dl $ apropos \-\- \-i 'Nm~[[:<:]]ssh[[:>:]]'
|
||||||
|
.Pp
|
||||||
|
The following two invocations are equivalent:
|
||||||
|
.Pp
|
||||||
|
.D1 Li $ apropos -S Ar arch Li -s Ar section expression
|
||||||
|
.Bd -ragged -offset indent
|
||||||
|
.Li $ apropos \e( Ar expression Li \e)
|
||||||
|
.Li -a arch~^( Ns Ar arch Ns Li |any)$
|
||||||
|
.Li -a sec~^ Ns Ar section Ns Li $
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr man 1 ,
|
||||||
|
.Xr re_format 7 ,
|
||||||
|
.Xr makewhatis 8
|
||||||
|
.Sh HISTORY
|
||||||
|
An
|
||||||
|
.Nm
|
||||||
|
utility first appeared in
|
||||||
|
.Bx 2 .
|
||||||
|
It was rewritten from scratch for
|
||||||
|
.Ox 5.6 .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl M
|
||||||
|
option and the
|
||||||
|
.Ev MANPATH
|
||||||
|
variable first appeared in
|
||||||
|
.Bx 4.3 ;
|
||||||
|
.Fl m
|
||||||
|
in
|
||||||
|
.Bx 4.3 Reno ;
|
||||||
|
.Fl C
|
||||||
|
in
|
||||||
|
.Bx 4.4 Lite1 ;
|
||||||
|
and
|
||||||
|
.Fl S
|
||||||
|
and
|
||||||
|
.Fl s
|
||||||
|
in
|
||||||
|
.Ox 4.5 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
.An Bill Joy
|
||||||
|
wrote the original
|
||||||
|
.Bx
|
||||||
|
.Nm
|
||||||
|
in February 1979.
|
||||||
|
The current version was written by
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
and
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
123
contrib/mdocml/apropos.c
Normal file
123
contrib/mdocml/apropos.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/* $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);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: arch.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
/* $Id: arch.c,v 1.11 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -18,17 +18,15 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.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_a2arch(const char *p)
|
mdoc_a2arch(const char *p)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: arch.in,v 1.14 2013/09/16 22:12:57 schwarze Exp $ */
|
/* $Id: arch.in,v 1.15 2014/04/27 22:42:15 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -65,8 +65,8 @@ LINE("ibmnws", "IBMNWS")
|
|||||||
LINE("iyonix", "Iyonix")
|
LINE("iyonix", "Iyonix")
|
||||||
LINE("landisk", "LANDISK")
|
LINE("landisk", "LANDISK")
|
||||||
LINE("loongson", "Loongson")
|
LINE("loongson", "Loongson")
|
||||||
LINE("luna68k", "Luna68k")
|
LINE("luna68k", "LUNA68K")
|
||||||
LINE("luna88k", "Luna88k")
|
LINE("luna88k", "LUNA88K")
|
||||||
LINE("m68k", "m68k")
|
LINE("m68k", "m68k")
|
||||||
LINE("mac68k", "Mac68k")
|
LINE("mac68k", "Mac68k")
|
||||||
LINE("macppc", "MacPPC")
|
LINE("macppc", "MacPPC")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: att.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
/* $Id: att.c,v 1.11 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -18,17 +18,15 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.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)
|
||||||
{
|
{
|
||||||
|
1150
contrib/mdocml/cgi.c
Normal file
1150
contrib/mdocml/cgi.c
Normal file
File diff suppressed because it is too large
Load Diff
9
contrib/mdocml/cgi.h.example
Normal file
9
contrib/mdocml/cgi.h.example
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* Example compile-time configuration file for man.cgi(8). */
|
||||||
|
|
||||||
|
#define HTTP_HOST "mdocml.bsd.lv"
|
||||||
|
#define MAN_DIR "/var/www/man"
|
||||||
|
#define CSS_DIR ""
|
||||||
|
#define CUSTOMIZE_TITLE "Manual pages with mandoc"
|
||||||
|
#define CUSTOMIZE_BEGIN "<H2>\nManual pages with " \
|
||||||
|
"<A HREF=\"http://mdocml.bsd.lv/\">mandoc</A>\n</H2>"
|
||||||
|
#define COMPAT_OLDURI Yes
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: chars.c,v 1.54 2013/06/20 22:39:30 schwarze Exp $ */
|
/* $Id: chars.c,v 1.58 2014/07/23 15:00:08 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>
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
|
|
||||||
#define PRINT_HI 126
|
#define PRINT_HI 126
|
||||||
@ -37,7 +38,7 @@ struct ln {
|
|||||||
int unicode;
|
int unicode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LINES_MAX 329
|
#define LINES_MAX 330
|
||||||
|
|
||||||
#define CHAR(in, ch, code) \
|
#define CHAR(in, ch, code) \
|
||||||
{ NULL, (in), (ch), (code) },
|
{ NULL, (in), (ch), (code) },
|
||||||
@ -54,6 +55,7 @@ struct mchars {
|
|||||||
static const struct ln *find(const struct mchars *,
|
static const struct ln *find(const struct mchars *,
|
||||||
const char *, size_t);
|
const char *, size_t);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mchars_free(struct mchars *arg)
|
mchars_free(struct mchars *arg)
|
||||||
{
|
{
|
||||||
@ -114,8 +116,8 @@ mchars_num2char(const char *p, size_t sz)
|
|||||||
|
|
||||||
if ((i = mandoc_strntoi(p, sz, 10)) < 0)
|
if ((i = mandoc_strntoi(p, sz, 10)) < 0)
|
||||||
return('\0');
|
return('\0');
|
||||||
return(i > 0 && i < 256 && isprint(i) ?
|
|
||||||
/* LINTED */ i : '\0');
|
return(i > 0 && i < 256 && isprint(i) ? i : '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -125,7 +127,18 @@ mchars_num2uc(const char *p, size_t sz)
|
|||||||
|
|
||||||
if ((i = mandoc_strntoi(p, sz, 16)) < 0)
|
if ((i = mandoc_strntoi(p, sz, 16)) < 0)
|
||||||
return('\0');
|
return('\0');
|
||||||
/* FIXME: make sure we're not in a bogus range. */
|
|
||||||
|
/*
|
||||||
|
* 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');
|
return(i > 0x80 && i <= 0x10FFFF ? i : '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* $Id: chars.in,v 1.43 2013/06/20 22:39:30 schwarze Exp $ */
|
/* $Id: chars.in,v 1.46 2014/04/20 16:46:04 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
|
||||||
@ -27,39 +28,42 @@
|
|||||||
* XXX - update LINES_MAX if adding more!
|
* XXX - update LINES_MAX if adding more!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Non-breaking, non-collapsing space uses unit separator. */
|
/* Special break control characters. */
|
||||||
static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
|
static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
|
||||||
|
static const char ascii_break[2] = { ASCII_BREAK, '\0' };
|
||||||
|
|
||||||
CHAR_TBL_START
|
CHAR_TBL_START
|
||||||
|
|
||||||
/* Spacing. */
|
/* Spacing. */
|
||||||
CHAR("c", "", 0)
|
|
||||||
CHAR("0", " ", 8194)
|
|
||||||
CHAR(" ", ascii_nbrsp, 160)
|
CHAR(" ", ascii_nbrsp, 160)
|
||||||
CHAR("~", ascii_nbrsp, 160)
|
CHAR("~", ascii_nbrsp, 160)
|
||||||
CHAR("%", "", 0)
|
CHAR("0", " ", 8194)
|
||||||
CHAR("&", "", 0)
|
|
||||||
CHAR("^", "", 0)
|
|
||||||
CHAR("|", "", 0)
|
CHAR("|", "", 0)
|
||||||
CHAR("}", "", 0)
|
CHAR("^", "", 0)
|
||||||
|
CHAR("&", "", 0)
|
||||||
|
CHAR("%", "", 0)
|
||||||
|
CHAR(":", ascii_break, 0)
|
||||||
|
/* XXX The following three do not really belong into this file. */
|
||||||
CHAR("t", "", 0)
|
CHAR("t", "", 0)
|
||||||
|
CHAR("c", "", 0)
|
||||||
|
CHAR("}", "", 0)
|
||||||
|
|
||||||
/* Accents. */
|
/* Accents. */
|
||||||
CHAR("a\"", "\"", 779)
|
CHAR("a\"", "\"", 733)
|
||||||
CHAR("a-", "-", 175)
|
CHAR("a-", "-", 175)
|
||||||
CHAR("a.", ".", 729)
|
CHAR("a.", ".", 729)
|
||||||
CHAR("a^", "^", 770)
|
CHAR("a^", "^", 94)
|
||||||
CHAR("\'", "\'", 769)
|
CHAR("\'", "\'", 180)
|
||||||
CHAR("aa", "\'", 769)
|
CHAR("aa", "\'", 180)
|
||||||
CHAR("ga", "`", 768)
|
CHAR("ga", "`", 96)
|
||||||
CHAR("`", "`", 768)
|
CHAR("`", "`", 96)
|
||||||
CHAR("ab", "`", 774)
|
CHAR("ab", "`", 728)
|
||||||
CHAR("ac", ",", 807)
|
CHAR("ac", ",", 184)
|
||||||
CHAR("ad", "\"", 776)
|
CHAR("ad", "\"", 168)
|
||||||
CHAR("ah", "v", 711)
|
CHAR("ah", "v", 711)
|
||||||
CHAR("ao", "o", 730)
|
CHAR("ao", "o", 730)
|
||||||
CHAR("a~", "~", 771)
|
CHAR("a~", "~", 126)
|
||||||
CHAR("ho", ",", 808)
|
CHAR("ho", ",", 731)
|
||||||
CHAR("ha", "^", 94)
|
CHAR("ha", "^", 94)
|
||||||
CHAR("ti", "~", 126)
|
CHAR("ti", "~", 126)
|
||||||
|
|
||||||
|
339
contrib/mdocml/compat_ohash.c
Normal file
339
contrib/mdocml/compat_ohash.c
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_OHASH
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* $OpenBSD: ohash.c,v 1.1 2014/06/02 18:52:03 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "compat_ohash.h"
|
||||||
|
|
||||||
|
struct _ohash_record {
|
||||||
|
uint32_t hv;
|
||||||
|
const char *p;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DELETED ((const char *)h)
|
||||||
|
#define NONE (h->size)
|
||||||
|
|
||||||
|
/* Don't bother changing the hash table if the change is small enough. */
|
||||||
|
#define MINSIZE (1UL << 4)
|
||||||
|
#define MINDELETED 4
|
||||||
|
|
||||||
|
static void ohash_resize(struct ohash *);
|
||||||
|
|
||||||
|
|
||||||
|
/* This handles the common case of variable length keys, where the
|
||||||
|
* key is stored at the end of the record.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
ohash_create_entry(struct ohash_info *i, const char *start, const char **end)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!*end)
|
||||||
|
*end = start + strlen(start);
|
||||||
|
p = (i->alloc)(i->key_offset + (*end - start) + 1, i->data);
|
||||||
|
if (p) {
|
||||||
|
memcpy(p+i->key_offset, start, *end-start);
|
||||||
|
p[i->key_offset + (*end - start)] = '\0';
|
||||||
|
}
|
||||||
|
return (void *)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hash_delete only frees the hash structure. Use hash_first/hash_next
|
||||||
|
* to free entries as well. */
|
||||||
|
void
|
||||||
|
ohash_delete(struct ohash *h)
|
||||||
|
{
|
||||||
|
(h->info.free)(h->t, h->info.data);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
h->t = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ohash_resize(struct ohash *h)
|
||||||
|
{
|
||||||
|
struct _ohash_record *n;
|
||||||
|
size_t ns;
|
||||||
|
unsigned int j;
|
||||||
|
unsigned int i, incr;
|
||||||
|
|
||||||
|
if (4 * h->deleted < h->total) {
|
||||||
|
if (h->size >= (UINT_MAX >> 1U))
|
||||||
|
ns = UINT_MAX;
|
||||||
|
else
|
||||||
|
ns = h->size << 1U;
|
||||||
|
} else if (3 * h->deleted > 2 * h->total)
|
||||||
|
ns = h->size >> 1U;
|
||||||
|
else
|
||||||
|
ns = h->size;
|
||||||
|
if (ns < MINSIZE)
|
||||||
|
ns = MINSIZE;
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_EXPAND++;
|
||||||
|
STAT_HASH_SIZE += ns - h->size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
n = (h->info.calloc)(ns, sizeof(struct _ohash_record), h->info.data);
|
||||||
|
if (!n)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (j = 0; j < h->size; j++) {
|
||||||
|
if (h->t[j].p != NULL && h->t[j].p != DELETED) {
|
||||||
|
i = h->t[j].hv % ns;
|
||||||
|
incr = ((h->t[j].hv % (ns - 2)) & ~1) + 1;
|
||||||
|
while (n[i].p != NULL) {
|
||||||
|
i += incr;
|
||||||
|
if (i >= ns)
|
||||||
|
i -= ns;
|
||||||
|
}
|
||||||
|
n[i].hv = h->t[j].hv;
|
||||||
|
n[i].p = h->t[j].p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(h->info.free)(h->t, h->info.data);
|
||||||
|
h->t = n;
|
||||||
|
h->size = ns;
|
||||||
|
h->total -= h->deleted;
|
||||||
|
h->deleted = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ohash_remove(struct ohash *h, unsigned int i)
|
||||||
|
{
|
||||||
|
void *result = (void *)h->t[i].p;
|
||||||
|
|
||||||
|
if (result == NULL || result == DELETED)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_ENTRIES--;
|
||||||
|
#endif
|
||||||
|
h->t[i].p = DELETED;
|
||||||
|
h->deleted++;
|
||||||
|
if (h->deleted >= MINDELETED && 4 * h->deleted > h->total)
|
||||||
|
ohash_resize(h);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ohash_find(struct ohash *h, unsigned int i)
|
||||||
|
{
|
||||||
|
if (h->t[i].p == DELETED)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return (void *)h->t[i].p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ohash_insert(struct ohash *h, unsigned int i, void *p)
|
||||||
|
{
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_ENTRIES++;
|
||||||
|
#endif
|
||||||
|
if (h->t[i].p == DELETED) {
|
||||||
|
h->deleted--;
|
||||||
|
h->t[i].p = p;
|
||||||
|
} else {
|
||||||
|
h->t[i].p = p;
|
||||||
|
/* Arbitrary resize boundary. Tweak if not efficient enough. */
|
||||||
|
if (++h->total * 4 > h->size * 3)
|
||||||
|
ohash_resize(h);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ohash_entries(struct ohash *h)
|
||||||
|
{
|
||||||
|
return h->total - h->deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ohash_first(struct ohash *h, unsigned int *pos)
|
||||||
|
{
|
||||||
|
*pos = 0;
|
||||||
|
return ohash_next(h, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ohash_next(struct ohash *h, unsigned int *pos)
|
||||||
|
{
|
||||||
|
for (; *pos < h->size; (*pos)++)
|
||||||
|
if (h->t[*pos].p != DELETED && h->t[*pos].p != NULL)
|
||||||
|
return (void *)h->t[(*pos)++].p;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ohash_init(struct ohash *h, unsigned int size, struct ohash_info *info)
|
||||||
|
{
|
||||||
|
h->size = 1UL << size;
|
||||||
|
if (h->size < MINSIZE)
|
||||||
|
h->size = MINSIZE;
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_CREATION++;
|
||||||
|
STAT_HASH_SIZE += h->size;
|
||||||
|
#endif
|
||||||
|
/* Copy info so that caller may free it. */
|
||||||
|
h->info.key_offset = info->key_offset;
|
||||||
|
h->info.calloc = info->calloc;
|
||||||
|
h->info.free = info->free;
|
||||||
|
h->info.alloc = info->alloc;
|
||||||
|
h->info.data = info->data;
|
||||||
|
h->t = (h->info.calloc)(h->size, sizeof(struct _ohash_record),
|
||||||
|
h->info.data);
|
||||||
|
h->total = h->deleted = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ohash_interval(const char *s, const char **e)
|
||||||
|
{
|
||||||
|
uint32_t k;
|
||||||
|
|
||||||
|
if (!*e)
|
||||||
|
*e = s + strlen(s);
|
||||||
|
if (s == *e)
|
||||||
|
k = 0;
|
||||||
|
else
|
||||||
|
k = *s++;
|
||||||
|
while (s != *e)
|
||||||
|
k = ((k << 2) | (k >> 30)) ^ *s++;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ohash_lookup_interval(struct ohash *h, const char *start, const char *end,
|
||||||
|
uint32_t hv)
|
||||||
|
{
|
||||||
|
unsigned int i, incr;
|
||||||
|
unsigned int empty;
|
||||||
|
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_LOOKUP++;
|
||||||
|
#endif
|
||||||
|
empty = NONE;
|
||||||
|
i = hv % h->size;
|
||||||
|
incr = ((hv % (h->size-2)) & ~1) + 1;
|
||||||
|
while (h->t[i].p != NULL) {
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_LENGTH++;
|
||||||
|
#endif
|
||||||
|
if (h->t[i].p == DELETED) {
|
||||||
|
if (empty == NONE)
|
||||||
|
empty = i;
|
||||||
|
} else if (h->t[i].hv == hv &&
|
||||||
|
strncmp(h->t[i].p+h->info.key_offset, start,
|
||||||
|
end - start) == 0 &&
|
||||||
|
(h->t[i].p+h->info.key_offset)[end-start] == '\0') {
|
||||||
|
if (empty != NONE) {
|
||||||
|
h->t[empty].hv = hv;
|
||||||
|
h->t[empty].p = h->t[i].p;
|
||||||
|
h->t[i].p = DELETED;
|
||||||
|
return empty;
|
||||||
|
} else {
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_POSITIVE++;
|
||||||
|
#endif
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += incr;
|
||||||
|
if (i >= h->size)
|
||||||
|
i -= h->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found an empty position. */
|
||||||
|
if (empty != NONE)
|
||||||
|
i = empty;
|
||||||
|
h->t[i].hv = hv;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ohash_lookup_memory(struct ohash *h, const char *k, size_t size, uint32_t hv)
|
||||||
|
{
|
||||||
|
unsigned int i, incr;
|
||||||
|
unsigned int empty;
|
||||||
|
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_LOOKUP++;
|
||||||
|
#endif
|
||||||
|
empty = NONE;
|
||||||
|
i = hv % h->size;
|
||||||
|
incr = ((hv % (h->size-2)) & ~1) + 1;
|
||||||
|
while (h->t[i].p != NULL) {
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_LENGTH++;
|
||||||
|
#endif
|
||||||
|
if (h->t[i].p == DELETED) {
|
||||||
|
if (empty == NONE)
|
||||||
|
empty = i;
|
||||||
|
} else if (h->t[i].hv == hv &&
|
||||||
|
memcmp(h->t[i].p+h->info.key_offset, k, size) == 0) {
|
||||||
|
if (empty != NONE) {
|
||||||
|
h->t[empty].hv = hv;
|
||||||
|
h->t[empty].p = h->t[i].p;
|
||||||
|
h->t[i].p = DELETED;
|
||||||
|
return empty;
|
||||||
|
} else {
|
||||||
|
#ifdef STATS_HASH
|
||||||
|
STAT_HASH_POSITIVE++;
|
||||||
|
#endif
|
||||||
|
} return i;
|
||||||
|
}
|
||||||
|
i += incr;
|
||||||
|
if (i >= h->size)
|
||||||
|
i -= h->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found an empty position. */
|
||||||
|
if (empty != NONE)
|
||||||
|
i = empty;
|
||||||
|
h->t[i].hv = hv;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ohash_qlookup(struct ohash *h, const char *s)
|
||||||
|
{
|
||||||
|
const char *e = NULL;
|
||||||
|
return ohash_qlookupi(h, s, &e);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ohash_qlookupi(struct ohash *h, const char *s, const char **e)
|
||||||
|
{
|
||||||
|
uint32_t hv;
|
||||||
|
|
||||||
|
hv = ohash_interval(s, e);
|
||||||
|
return ohash_lookup_interval(h, s, *e, hv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*!HAVE_OHASH*/
|
73
contrib/mdocml/compat_ohash.h
Normal file
73
contrib/mdocml/compat_ohash.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* $OpenBSD: ohash.h,v 1.2 2014/06/02 18:52:03 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Copyright (c) 1999, 2004 Marc Espie <espie@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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OHASH_H
|
||||||
|
#define OHASH_H
|
||||||
|
|
||||||
|
/* Open hashing support.
|
||||||
|
* Open hashing was chosen because it is much lighter than other hash
|
||||||
|
* techniques, and more efficient in most cases.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* user-visible data structure */
|
||||||
|
struct ohash_info {
|
||||||
|
ptrdiff_t key_offset;
|
||||||
|
void *data; /* user data */
|
||||||
|
void *(*calloc)(size_t, size_t, void *);
|
||||||
|
void (*free)(void *, void *);
|
||||||
|
void *(*alloc)(size_t, void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ohash_record;
|
||||||
|
|
||||||
|
/* private structure. It's there just so you can do a sizeof */
|
||||||
|
struct ohash {
|
||||||
|
struct _ohash_record *t;
|
||||||
|
struct ohash_info info;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int total;
|
||||||
|
unsigned int deleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For this to be tweakable, we use small primitives, and leave part of the
|
||||||
|
* logic to the client application. e.g., hashing is left to the client
|
||||||
|
* application. We also provide a simple table entry lookup that yields
|
||||||
|
* a hashing table index (opaque) to be used in find/insert/remove.
|
||||||
|
* The keys are stored at a known position in the client data.
|
||||||
|
*/
|
||||||
|
__BEGIN_DECLS
|
||||||
|
void ohash_init(struct ohash *, unsigned, struct ohash_info *);
|
||||||
|
void ohash_delete(struct ohash *);
|
||||||
|
|
||||||
|
unsigned int ohash_lookup_interval(struct ohash *, const char *,
|
||||||
|
const char *, uint32_t);
|
||||||
|
unsigned int ohash_lookup_memory(struct ohash *, const char *,
|
||||||
|
size_t, uint32_t);
|
||||||
|
void *ohash_find(struct ohash *, unsigned int);
|
||||||
|
void *ohash_remove(struct ohash *, unsigned int);
|
||||||
|
void *ohash_insert(struct ohash *, unsigned int, void *);
|
||||||
|
void *ohash_first(struct ohash *, unsigned int *);
|
||||||
|
void *ohash_next(struct ohash *, unsigned int *);
|
||||||
|
unsigned int ohash_entries(struct ohash *);
|
||||||
|
|
||||||
|
void *ohash_create_entry(struct ohash_info *, const char *, const char **);
|
||||||
|
uint32_t ohash_interval(const char *, const char **);
|
||||||
|
|
||||||
|
unsigned int ohash_qlookupi(struct ohash *, const char *, const char **);
|
||||||
|
unsigned int ohash_qlookup(struct ohash *, const char *);
|
||||||
|
__END_DECLS
|
||||||
|
#endif
|
45
contrib/mdocml/compat_reallocarray.c
Normal file
45
contrib/mdocml/compat_reallocarray.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_REALLOCARRAY
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* $OpenBSD: malloc.c,v 1.158 2014/04/23 15:07:27 tedu Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
|
||||||
|
|
||||||
|
void *
|
||||||
|
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||||
|
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return realloc(optr, size * nmemb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*!HAVE_REALLOCARRAY*/
|
18
contrib/mdocml/compat_sqlite3_errstr.c
Normal file
18
contrib/mdocml/compat_sqlite3_errstr.c
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SQLITE3_ERRSTR
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
const char *
|
||||||
|
sqlite3_errstr(int rc)
|
||||||
|
{
|
||||||
|
|
||||||
|
return(rc ? "unknown error" : "not an error");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
74
contrib/mdocml/compat_strcasestr.c
Normal file
74
contrib/mdocml/compat_strcasestr.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRCASESTR
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* ($)NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Chris Torek.
|
||||||
|
*
|
||||||
|
* 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/types.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the first occurrence of find in s, ignore case.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strcasestr(const char *s, const char *find)
|
||||||
|
{
|
||||||
|
char c, sc;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if ((c = *find++) != 0) {
|
||||||
|
c = tolower((unsigned char)c);
|
||||||
|
len = strlen(find);
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
if ((sc = *s++) == 0)
|
||||||
|
return (NULL);
|
||||||
|
} while ((char)tolower((unsigned char)sc) != c);
|
||||||
|
} while (strncasecmp(s, find, len) != 0);
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
return __UNCONST(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
80
contrib/mdocml/compat_strsep.c
Normal file
80
contrib/mdocml/compat_strsep.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRSEP
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* ($)OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get next token from string *stringp, where tokens are possibly-empty
|
||||||
|
* strings separated by characters from delim.
|
||||||
|
*
|
||||||
|
* Writes NULs into the string at *stringp to end tokens.
|
||||||
|
* delim need not remain constant from call to call.
|
||||||
|
* On return, *stringp points past the last NUL written (if there might
|
||||||
|
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||||
|
*
|
||||||
|
* If *stringp is NULL, strsep returns NULL.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strsep(char **stringp, const char *delim)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
const char *spanp;
|
||||||
|
int c, sc;
|
||||||
|
char *tok;
|
||||||
|
|
||||||
|
if ((s = *stringp) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
for (tok = s;;) {
|
||||||
|
c = *s++;
|
||||||
|
spanp = delim;
|
||||||
|
do {
|
||||||
|
if ((sc = *spanp++) == c) {
|
||||||
|
if (c == 0)
|
||||||
|
s = NULL;
|
||||||
|
else
|
||||||
|
s[-1] = 0;
|
||||||
|
*stringp = s;
|
||||||
|
return (tok);
|
||||||
|
}
|
||||||
|
} while (sc != 0);
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -2,20 +2,21 @@
|
|||||||
#define MANDOC_CONFIG_H
|
#define MANDOC_CONFIG_H
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__MINT__)
|
#if defined(__linux__) || defined(__MINT__)
|
||||||
# define _GNU_SOURCE /* strptime(), getsubopt() */
|
# define _GNU_SOURCE /* getsubopt(), strcasestr(), strptime() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define VERSION "1.12.3"
|
#define VERSION "1.13.1"
|
||||||
#define HAVE_FGETLN
|
#define HAVE_FGETLN
|
||||||
#define HAVE_STRPTIME
|
|
||||||
#define HAVE_GETSUBOPT
|
#define HAVE_GETSUBOPT
|
||||||
#define HAVE_STRLCAT
|
|
||||||
#define HAVE_MMAP
|
#define HAVE_MMAP
|
||||||
|
#define HAVE_STRCASESTR
|
||||||
|
#define HAVE_STRLCAT
|
||||||
#define HAVE_STRLCPY
|
#define HAVE_STRLCPY
|
||||||
|
#define HAVE_STRPTIME
|
||||||
#include <sys/types.h>
|
#define HAVE_STRSEP
|
||||||
|
|
||||||
#if !defined(__BEGIN_DECLS)
|
#if !defined(__BEGIN_DECLS)
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
@ -32,30 +33,30 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_BETOH64
|
#ifndef HAVE_FGETLN
|
||||||
# if defined(__APPLE__)
|
extern char *fgetln(FILE *, size_t *);
|
||||||
# define betoh64(x) OSSwapBigToHostInt64(x)
|
#endif
|
||||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
#ifndef HAVE_GETSUBOPT
|
||||||
# elif defined(__sun)
|
extern int getsubopt(char **, char * const *, char **);
|
||||||
# define betoh64(x) BE_64(x)
|
extern char *suboptarg;
|
||||||
# define htobe64(x) BE_64(x)
|
#endif
|
||||||
# else
|
#ifndef HAVE_REALLOCARRAY
|
||||||
# define betoh64(x) be64toh(x)
|
extern void *reallocarray(void *, size_t, size_t);
|
||||||
# endif
|
#endif
|
||||||
|
#ifndef HAVE_SQLITE3_ERRSTR
|
||||||
|
extern const char *sqlite3_errstr(int);
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRCASESTR
|
||||||
|
extern char *strcasestr(const char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRLCAT
|
#ifndef HAVE_STRLCAT
|
||||||
extern size_t strlcat(char *, const char *, size_t);
|
extern size_t strlcat(char *, const char *, size_t);
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_STRLCPY
|
#ifndef HAVE_STRLCPY
|
||||||
extern size_t strlcpy(char *, const char *, size_t);
|
extern size_t strlcpy(char *, const char *, size_t);
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GETSUBOPT
|
#ifndef HAVE_STRSEP
|
||||||
extern int getsubopt(char **, char * const *, char **);
|
extern char *strsep(char **, const char *);
|
||||||
extern char *suboptarg;
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_FGETLN
|
|
||||||
extern char *fgetln(FILE *, size_t *);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* MANDOC_CONFIG_H */
|
#endif /* MANDOC_CONFIG_H */
|
||||||
|
42
contrib/mdocml/config.h.post
Normal file
42
contrib/mdocml/config.h.post
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#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 */
|
9
contrib/mdocml/config.h.pre
Normal file
9
contrib/mdocml/config.h.pre
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#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>
|
49
contrib/mdocml/configure
vendored
Executable file
49
contrib/mdocml/configure
vendored
Executable file
@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
echo "/* RUNNING ./CONFIGURE - SHOULD BE USED ONLY VIA MAKE, READ INSTALL */"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
exec > config.h 2> config.log
|
||||||
|
|
||||||
|
CFLAGS="${CFLAGS} -Wno-unused -Werror"
|
||||||
|
|
||||||
|
runtest() {
|
||||||
|
echo ${CC} ${CFLAGS} ${3} -o test-${1} test-${1}.c 1>&2
|
||||||
|
${CC} ${CFLAGS} ${3} -o "test-${1}" "test-${1}.c" 1>&2 || return 0
|
||||||
|
"./test-${1}" && echo "#define HAVE_${2}" \
|
||||||
|
|| echo FAILURE: test-${1} returned $? 1>&2
|
||||||
|
rm "test-${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cat config.h.pre
|
||||||
|
echo
|
||||||
|
echo "#define VERSION \"${VERSION}\""
|
||||||
|
runtest fgetln FGETLN
|
||||||
|
runtest getsubopt GETSUBOPT
|
||||||
|
runtest mmap MMAP
|
||||||
|
runtest ohash OHASH "${DBLIB}"
|
||||||
|
runtest reallocarray REALLOCARRAY
|
||||||
|
runtest sqlite3_errstr SQLITE3_ERRSTR "${DBLIB}"
|
||||||
|
runtest strcasestr STRCASESTR
|
||||||
|
runtest strlcat STRLCAT
|
||||||
|
runtest strlcpy STRLCPY
|
||||||
|
runtest strptime STRPTIME
|
||||||
|
runtest strsep STRSEP
|
||||||
|
echo
|
||||||
|
cat config.h.post
|
||||||
|
|
||||||
|
exit 0
|
257
contrib/mdocml/demandoc.c
Normal file
257
contrib/mdocml/demandoc.c
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/* $Id: demandoc.c,v 1.10 2014/03/19 22:20:43 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.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "man.h"
|
||||||
|
#include "mdoc.h"
|
||||||
|
#include "mandoc.h"
|
||||||
|
|
||||||
|
static void pline(int, int *, int *, int);
|
||||||
|
static void pman(const struct man_node *, int *, int *, int);
|
||||||
|
static void pmandoc(struct mparse *, int, const char *, int);
|
||||||
|
static void pmdoc(const struct mdoc_node *, int *, int *, int);
|
||||||
|
static void pstring(const char *, int, int *, int);
|
||||||
|
static void usage(void);
|
||||||
|
|
||||||
|
static const char *progname;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct mparse *mp;
|
||||||
|
int ch, i, list;
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
progname = strrchr(argv[0], '/');
|
||||||
|
if (progname == NULL)
|
||||||
|
progname = argv[0];
|
||||||
|
else
|
||||||
|
++progname;
|
||||||
|
|
||||||
|
mp = NULL;
|
||||||
|
list = 0;
|
||||||
|
|
||||||
|
while (-1 != (ch = getopt(argc, argv, "ikm:pw")))
|
||||||
|
switch (ch) {
|
||||||
|
case ('i'):
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case ('k'):
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case ('m'):
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case ('p'):
|
||||||
|
break;
|
||||||
|
case ('w'):
|
||||||
|
list = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, NULL);
|
||||||
|
assert(mp);
|
||||||
|
|
||||||
|
if (0 == argc)
|
||||||
|
pmandoc(mp, STDIN_FILENO, "<stdin>", list);
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
mparse_reset(mp);
|
||||||
|
pmandoc(mp, -1, argv[i], list);
|
||||||
|
}
|
||||||
|
|
||||||
|
mparse_free(mp);
|
||||||
|
return((int)MANDOCLEVEL_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stderr, "usage: %s [-w] [files...]\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pmandoc(struct mparse *mp, int fd, const char *fn, int list)
|
||||||
|
{
|
||||||
|
struct mdoc *mdoc;
|
||||||
|
struct man *man;
|
||||||
|
int line, col;
|
||||||
|
|
||||||
|
if (mparse_readfd(mp, fd, fn) >= MANDOCLEVEL_FATAL) {
|
||||||
|
fprintf(stderr, "%s: Parse failure\n", fn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mparse_result(mp, &mdoc, &man, NULL);
|
||||||
|
line = 1;
|
||||||
|
col = 0;
|
||||||
|
|
||||||
|
if (mdoc)
|
||||||
|
pmdoc(mdoc_node(mdoc), &line, &col, list);
|
||||||
|
else if (man)
|
||||||
|
pman(man_node(man), &line, &col, list);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ! list)
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Strip the escapes out of a string, emitting the results.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pstring(const char *p, int col, int *colp, int list)
|
||||||
|
{
|
||||||
|
enum mandoc_esc esc;
|
||||||
|
const char *start, *end;
|
||||||
|
int emit;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print as many column spaces til we achieve parity with the
|
||||||
|
* input document.
|
||||||
|
*/
|
||||||
|
|
||||||
|
again:
|
||||||
|
if (list && '\0' != *p) {
|
||||||
|
while (isspace((unsigned char)*p))
|
||||||
|
p++;
|
||||||
|
|
||||||
|
while ('\'' == *p || '(' == *p || '"' == *p)
|
||||||
|
p++;
|
||||||
|
|
||||||
|
emit = isalpha((unsigned char)p[0]) &&
|
||||||
|
isalpha((unsigned char)p[1]);
|
||||||
|
|
||||||
|
for (start = p; '\0' != *p; p++)
|
||||||
|
if ('\\' == *p) {
|
||||||
|
p++;
|
||||||
|
esc = mandoc_escape(&p, NULL, NULL);
|
||||||
|
if (ESCAPE_ERROR == esc)
|
||||||
|
return;
|
||||||
|
emit = 0;
|
||||||
|
} else if (isspace((unsigned char)*p))
|
||||||
|
break;
|
||||||
|
|
||||||
|
end = p - 1;
|
||||||
|
|
||||||
|
while (end > start)
|
||||||
|
if ('.' == *end || ',' == *end ||
|
||||||
|
'\'' == *end || '"' == *end ||
|
||||||
|
')' == *end || '!' == *end ||
|
||||||
|
'?' == *end || ':' == *end ||
|
||||||
|
';' == *end)
|
||||||
|
end--;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (emit && end - start >= 1) {
|
||||||
|
for ( ; start <= end; start++)
|
||||||
|
if (ASCII_HYPH == *start)
|
||||||
|
putchar('-');
|
||||||
|
else
|
||||||
|
putchar((unsigned char)*start);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isspace((unsigned char)*p))
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*colp < col) {
|
||||||
|
putchar(' ');
|
||||||
|
(*colp)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the input word, skipping any special characters.
|
||||||
|
*/
|
||||||
|
while ('\0' != *p)
|
||||||
|
if ('\\' == *p) {
|
||||||
|
p++;
|
||||||
|
esc = mandoc_escape(&p, NULL, NULL);
|
||||||
|
if (ESCAPE_ERROR == esc)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
putchar((unsigned char )*p++);
|
||||||
|
(*colp)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pline(int line, int *linep, int *col, int list)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print out as many lines as needed to reach parity with the
|
||||||
|
* original input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (*linep < line) {
|
||||||
|
putchar('\n');
|
||||||
|
(*linep)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*col = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pmdoc(const struct mdoc_node *p, int *line, int *col, int list)
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( ; p; p = p->next) {
|
||||||
|
if (MDOC_LINE & p->flags)
|
||||||
|
pline(p->line, line, col, list);
|
||||||
|
if (MDOC_TEXT == p->type)
|
||||||
|
pstring(p->string, p->pos, col, list);
|
||||||
|
if (p->child)
|
||||||
|
pmdoc(p->child, line, col, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pman(const struct man_node *p, int *line, int *col, int list)
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( ; p; p = p->next) {
|
||||||
|
if (MAN_LINE & p->flags)
|
||||||
|
pline(p->line, line, col, list);
|
||||||
|
if (MAN_TEXT == p->type)
|
||||||
|
pstring(p->string, p->pos, col, list);
|
||||||
|
if (p->child)
|
||||||
|
pman(p->child, line, col, list);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: eqn.c,v 1.38 2011/07/25 15:37:00 kristaps Exp $ */
|
/* $Id: eqn.c,v 1.44 2014/07/06 19:09:00 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
#include "libroff.h"
|
#include "libroff.h"
|
||||||
|
|
||||||
@ -137,7 +138,6 @@ struct eqnsym {
|
|||||||
const char *sym;
|
const char *sym;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static enum eqn_rest eqn_box(struct eqn_node *, struct eqn_box *);
|
static enum eqn_rest eqn_box(struct eqn_node *, struct eqn_box *);
|
||||||
static struct eqn_box *eqn_box_alloc(struct eqn_node *,
|
static struct eqn_box *eqn_box_alloc(struct eqn_node *,
|
||||||
struct eqn_box *);
|
struct eqn_box *);
|
||||||
@ -277,7 +277,7 @@ static const struct eqnsym eqnsyms[EQNSYM__MAX] = {
|
|||||||
{ { ">=", 2 }, ">=" }, /* EQNSYM_moreequal */
|
{ { ">=", 2 }, ">=" }, /* EQNSYM_moreequal */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
enum rofferr
|
enum rofferr
|
||||||
eqn_read(struct eqn_node **epp, int ln,
|
eqn_read(struct eqn_node **epp, int ln,
|
||||||
const char *p, int pos, int *offs)
|
const char *p, int pos, int *offs)
|
||||||
@ -300,7 +300,8 @@ eqn_read(struct eqn_node **epp, int ln,
|
|||||||
p++;
|
p++;
|
||||||
if ('\0' == *p)
|
if ('\0' == *p)
|
||||||
return(er);
|
return(er);
|
||||||
mandoc_msg(MANDOCERR_ARGSLOST, ep->parse, ln, pos, NULL);
|
mandoc_vmsg(MANDOCERR_ARG_SKIP, ep->parse,
|
||||||
|
ln, pos, "EN %s", p);
|
||||||
return(er);
|
return(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,11 +414,11 @@ eqn_matrix(struct eqn_node *ep, struct eqn_box *last)
|
|||||||
|
|
||||||
while (EQN_OK == (c = eqn_box(ep, bp)))
|
while (EQN_OK == (c = eqn_box(ep, bp)))
|
||||||
switch (bp->last->pile) {
|
switch (bp->last->pile) {
|
||||||
case (EQNPILE_LCOL):
|
case EQNPILE_LCOL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (EQNPILE_CCOL):
|
case EQNPILE_CCOL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (EQNPILE_RCOL):
|
case EQNPILE_RCOL:
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
||||||
@ -512,8 +513,7 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last)
|
|||||||
for (i = 0; i < (int)EQN__MAX; i++) {
|
for (i = 0; i < (int)EQN__MAX; i++) {
|
||||||
if ( ! EQNSTREQ(&eqnparts[i].str, start, sz))
|
if ( ! EQNSTREQ(&eqnparts[i].str, start, sz))
|
||||||
continue;
|
continue;
|
||||||
return((*eqnparts[i].fp)(ep) ?
|
return((*eqnparts[i].fp)(ep) ? EQN_OK : EQN_ERR);
|
||||||
EQN_OK : EQN_ERR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STRNEQ(start, sz, "{", 1)) {
|
if (STRNEQ(start, sz, "{", 1)) {
|
||||||
@ -629,7 +629,7 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last)
|
|||||||
for (i = 0; i < (int)EQNSYM__MAX; i++)
|
for (i = 0; i < (int)EQNSYM__MAX; i++)
|
||||||
if (EQNSTREQ(&eqnsyms[i].str, start, sz)) {
|
if (EQNSTREQ(&eqnsyms[i].str, start, sz)) {
|
||||||
sym[63] = '\0';
|
sym[63] = '\0';
|
||||||
snprintf(sym, 62, "\\[%s]", eqnsyms[i].sym);
|
(void)snprintf(sym, 62, "\\[%s]", eqnsyms[i].sym);
|
||||||
bp->text = mandoc_strdup(sym);
|
bp->text = mandoc_strdup(sym);
|
||||||
return(EQN_OK);
|
return(EQN_OK);
|
||||||
}
|
}
|
||||||
@ -768,7 +768,7 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
|||||||
ep->cur++;
|
ep->cur++;
|
||||||
} else {
|
} else {
|
||||||
if (q)
|
if (q)
|
||||||
EQN_MSG(MANDOCERR_BADQUOTE, ep);
|
EQN_MSG(MANDOCERR_ARG_QUOTE, ep);
|
||||||
next = strchr(start, '\0');
|
next = strchr(start, '\0');
|
||||||
*sz = (size_t)(next - start);
|
*sz = (size_t)(next - start);
|
||||||
ep->cur += *sz;
|
ep->cur += *sz;
|
||||||
@ -865,15 +865,14 @@ eqn_do_define(struct eqn_node *ep)
|
|||||||
|
|
||||||
if (i == (int)ep->defsz) {
|
if (i == (int)ep->defsz) {
|
||||||
ep->defsz++;
|
ep->defsz++;
|
||||||
ep->defs = mandoc_realloc
|
ep->defs = mandoc_reallocarray(ep->defs,
|
||||||
(ep->defs, ep->defsz *
|
ep->defsz, sizeof(struct eqn_def));
|
||||||
sizeof(struct eqn_def));
|
|
||||||
ep->defs[i].key = ep->defs[i].val = NULL;
|
ep->defs[i].key = ep->defs[i].val = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep->defs[i].keysz = sz;
|
ep->defs[i].keysz = sz;
|
||||||
ep->defs[i].key = mandoc_realloc
|
ep->defs[i].key = mandoc_realloc(
|
||||||
(ep->defs[i].key, sz + 1);
|
ep->defs[i].key, sz + 1);
|
||||||
|
|
||||||
memcpy(ep->defs[i].key, start, sz);
|
memcpy(ep->defs[i].key, start, sz);
|
||||||
ep->defs[i].key[(int)sz] = '\0';
|
ep->defs[i].key[(int)sz] = '\0';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: eqn_html.c,v 1.2 2011/07/24 10:09:03 kristaps Exp $ */
|
/* $Id: eqn_html.c,v 1.3 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -35,9 +35,9 @@ static const enum htmltag fontmap[EQNFONT__MAX] = {
|
|||||||
TAG_I /* EQNFONT_ITALIC */
|
TAG_I /* EQNFONT_ITALIC */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void eqn_box(struct html *, const struct eqn_box *);
|
static void eqn_box(struct html *, const struct eqn_box *);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_eqn(struct html *p, const struct eqn *ep)
|
print_eqn(struct html *p, const struct eqn *ep)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: eqn_term.c,v 1.4 2011/07/24 10:09:03 kristaps Exp $ */
|
/* $Id: eqn_term.c,v 1.5 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -37,6 +37,7 @@ static const enum termfont fontmap[EQNFONT__MAX] = {
|
|||||||
|
|
||||||
static void eqn_box(struct termp *, const struct eqn_box *);
|
static void eqn_box(struct termp *, const struct eqn_box *);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_eqn(struct termp *p, const struct eqn *ep)
|
term_eqn(struct termp *p, const struct eqn *ep)
|
||||||
{
|
{
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 165 B |
38
contrib/mdocml/gmdiff
Normal file
38
contrib/mdocml/gmdiff
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 2013, 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.
|
||||||
|
|
||||||
|
if [ `id -u` -eq 0 ]; then
|
||||||
|
echo "$0: do not run me as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "usage: $0 manual_source_file ..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
file=$1
|
||||||
|
shift
|
||||||
|
echo " ========== $file ========== "
|
||||||
|
tbl $file | groff -mandoc -Tascii -P -c 2> /tmp/groff.err > /tmp/groff.out
|
||||||
|
mandoc -Ios='OpenBSD ports' -Werror $file 2> /tmp/mandoc.err > /tmp/mandoc.out
|
||||||
|
for i in groff mandoc; do
|
||||||
|
[[ -s /tmp/$i.err ]] && echo "$i errors:" && cat /tmp/$i.err
|
||||||
|
done
|
||||||
|
diff -au /tmp/groff.out /tmp/mandoc.out 2>&1
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: html.c,v 1.152 2013/08/08 20:07:47 schwarze Exp $ */
|
/* $Id: html.c,v 1.159 2014/07/23 15:00:08 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 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "html.h"
|
#include "html.h"
|
||||||
@ -109,11 +110,13 @@ static const char *const roffscales[SCALE_MAX] = {
|
|||||||
|
|
||||||
static void bufncat(struct html *, const char *, size_t);
|
static void bufncat(struct html *, const char *, size_t);
|
||||||
static void print_ctag(struct html *, enum htmltag);
|
static void print_ctag(struct html *, enum htmltag);
|
||||||
|
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 *ml_alloc(char *, enum htmltype);
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
ml_alloc(char *outopts, enum htmltype type)
|
ml_alloc(char *outopts, enum htmltype type)
|
||||||
{
|
{
|
||||||
@ -135,16 +138,16 @@ ml_alloc(char *outopts, enum htmltype type)
|
|||||||
|
|
||||||
while (outopts && *outopts)
|
while (outopts && *outopts)
|
||||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||||
case (0):
|
case 0:
|
||||||
h->style = v;
|
h->style = v;
|
||||||
break;
|
break;
|
||||||
case (1):
|
case 1:
|
||||||
h->base_man = v;
|
h->base_man = v;
|
||||||
break;
|
break;
|
||||||
case (2):
|
case 2:
|
||||||
h->base_includes = v;
|
h->base_includes = v;
|
||||||
break;
|
break;
|
||||||
case (3):
|
case 3:
|
||||||
h->oflags |= HTML_FRAGMENT;
|
h->oflags |= HTML_FRAGMENT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -161,7 +164,6 @@ html_alloc(char *outopts)
|
|||||||
return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
|
return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xhtml_alloc(char *outopts)
|
xhtml_alloc(char *outopts)
|
||||||
{
|
{
|
||||||
@ -169,7 +171,6 @@ xhtml_alloc(char *outopts)
|
|||||||
return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
|
return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
html_free(void *p)
|
html_free(void *p)
|
||||||
{
|
{
|
||||||
@ -189,7 +190,6 @@ html_free(void *p)
|
|||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_gen_head(struct html *h)
|
print_gen_head(struct html *h)
|
||||||
{
|
{
|
||||||
@ -226,21 +226,21 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
|||||||
enum htmlfont font;
|
enum htmlfont font;
|
||||||
|
|
||||||
switch (deco) {
|
switch (deco) {
|
||||||
case (ESCAPE_FONTPREV):
|
case ESCAPE_FONTPREV:
|
||||||
font = h->metal;
|
font = h->metal;
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONTITALIC):
|
case ESCAPE_FONTITALIC:
|
||||||
font = HTMLFONT_ITALIC;
|
font = HTMLFONT_ITALIC;
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONTBOLD):
|
case ESCAPE_FONTBOLD:
|
||||||
font = HTMLFONT_BOLD;
|
font = HTMLFONT_BOLD;
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONTBI):
|
case ESCAPE_FONTBI:
|
||||||
font = HTMLFONT_BI;
|
font = HTMLFONT_BI;
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONT):
|
case ESCAPE_FONT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_FONTROMAN):
|
case ESCAPE_FONTROMAN:
|
||||||
font = HTMLFONT_NONE;
|
font = HTMLFONT_NONE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -257,13 +257,13 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
|||||||
h->metac = font;
|
h->metac = font;
|
||||||
|
|
||||||
switch (font) {
|
switch (font) {
|
||||||
case (HTMLFONT_ITALIC):
|
case HTMLFONT_ITALIC:
|
||||||
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
||||||
break;
|
break;
|
||||||
case (HTMLFONT_BOLD):
|
case HTMLFONT_BOLD:
|
||||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||||
break;
|
break;
|
||||||
case (HTMLFONT_BI):
|
case HTMLFONT_BI:
|
||||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||||
print_otag(h, TAG_I, 0, NULL);
|
print_otag(h, TAG_I, 0, NULL);
|
||||||
break;
|
break;
|
||||||
@ -302,19 +302,19 @@ html_strlen(const char *cp)
|
|||||||
break;
|
break;
|
||||||
cp++;
|
cp++;
|
||||||
switch (mandoc_escape(&cp, NULL, NULL)) {
|
switch (mandoc_escape(&cp, NULL, NULL)) {
|
||||||
case (ESCAPE_ERROR):
|
case ESCAPE_ERROR:
|
||||||
return(sz);
|
return(sz);
|
||||||
case (ESCAPE_UNICODE):
|
case ESCAPE_UNICODE:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_NUMBERED):
|
case ESCAPE_NUMBERED:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_SPECIAL):
|
case ESCAPE_SPECIAL:
|
||||||
if (skip)
|
if (skip)
|
||||||
skip = 0;
|
skip = 0;
|
||||||
else
|
else
|
||||||
sz++;
|
sz++;
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_SKIPCHAR):
|
case ESCAPE_SKIPCHAR:
|
||||||
skip = 1;
|
skip = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -324,6 +324,37 @@ html_strlen(const char *cp)
|
|||||||
return(sz);
|
return(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_escape(char c)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '<':
|
||||||
|
printf("<");
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
printf(">");
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
printf("&");
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
printf(""");
|
||||||
|
break;
|
||||||
|
case ASCII_NBRSP:
|
||||||
|
putchar('-');
|
||||||
|
break;
|
||||||
|
case ASCII_HYPH:
|
||||||
|
putchar('-');
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case ASCII_BREAK:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_encode(struct html *h, const char *p, int norecurse)
|
print_encode(struct html *h, const char *p, int norecurse)
|
||||||
{
|
{
|
||||||
@ -331,7 +362,8 @@ print_encode(struct html *h, const char *p, int norecurse)
|
|||||||
int c, len, nospace;
|
int c, len, nospace;
|
||||||
const char *seq;
|
const char *seq;
|
||||||
enum mandoc_esc esc;
|
enum mandoc_esc esc;
|
||||||
static const char rejs[6] = { '\\', '<', '>', '&', ASCII_HYPH, '\0' };
|
static const char rejs[9] = { '\\', '<', '>', '&', '"',
|
||||||
|
ASCII_NBRSP, ASCII_HYPH, ASCII_BREAK, '\0' };
|
||||||
|
|
||||||
nospace = 0;
|
nospace = 0;
|
||||||
|
|
||||||
@ -350,43 +382,29 @@ print_encode(struct html *h, const char *p, int norecurse)
|
|||||||
if ('\0' == *p)
|
if ('\0' == *p)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (*p++) {
|
if (print_escape(*p++))
|
||||||
case ('<'):
|
|
||||||
printf("<");
|
|
||||||
continue;
|
continue;
|
||||||
case ('>'):
|
|
||||||
printf(">");
|
|
||||||
continue;
|
|
||||||
case ('&'):
|
|
||||||
printf("&");
|
|
||||||
continue;
|
|
||||||
case (ASCII_HYPH):
|
|
||||||
putchar('-');
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
esc = mandoc_escape(&p, &seq, &len);
|
esc = mandoc_escape(&p, &seq, &len);
|
||||||
if (ESCAPE_ERROR == esc)
|
if (ESCAPE_ERROR == esc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case (ESCAPE_FONT):
|
case ESCAPE_FONT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_FONTPREV):
|
case ESCAPE_FONTPREV:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_FONTBOLD):
|
case ESCAPE_FONTBOLD:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_FONTITALIC):
|
case ESCAPE_FONTITALIC:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_FONTBI):
|
case ESCAPE_FONTBI:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (ESCAPE_FONTROMAN):
|
case ESCAPE_FONTROMAN:
|
||||||
if (0 == norecurse)
|
if (0 == norecurse)
|
||||||
print_metaf(h, esc);
|
print_metaf(h, esc);
|
||||||
continue;
|
continue;
|
||||||
case (ESCAPE_SKIPCHAR):
|
case ESCAPE_SKIPCHAR:
|
||||||
h->flags |= HTML_SKIPCHAR;
|
h->flags |= HTML_SKIPCHAR;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
@ -399,25 +417,26 @@ print_encode(struct html *h, const char *p, int norecurse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case (ESCAPE_UNICODE):
|
case ESCAPE_UNICODE:
|
||||||
/* Skip passed "u" header. */
|
/* Skip past "u" header. */
|
||||||
c = mchars_num2uc(seq + 1, len - 1);
|
c = mchars_num2uc(seq + 1, len - 1);
|
||||||
if ('\0' != c)
|
if ('\0' != c)
|
||||||
printf("&#x%x;", 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)
|
if ( ! ('\0' == c || print_escape(c)))
|
||||||
putchar(c);
|
putchar(c);
|
||||||
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);
|
printf("&#%d;", c);
|
||||||
else if (-1 == c && 1 == len)
|
else if (-1 == c && 1 == len &&
|
||||||
|
!print_escape(*seq))
|
||||||
putchar((int)*seq);
|
putchar((int)*seq);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_NOSPACE):
|
case ESCAPE_NOSPACE:
|
||||||
if ('\0' == *p)
|
if ('\0' == *p)
|
||||||
nospace = 1;
|
nospace = 1;
|
||||||
break;
|
break;
|
||||||
@ -429,7 +448,6 @@ print_encode(struct html *h, const char *p, int norecurse)
|
|||||||
return(nospace);
|
return(nospace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_attr(struct html *h, const char *key, const char *val)
|
print_attr(struct html *h, const char *key, const char *val)
|
||||||
{
|
{
|
||||||
@ -438,7 +456,6 @@ print_attr(struct html *h, const char *key, const char *val)
|
|||||||
putchar('\"');
|
putchar('\"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct tag *
|
struct tag *
|
||||||
print_otag(struct html *h, enum htmltag tag,
|
print_otag(struct html *h, enum htmltag tag,
|
||||||
int sz, const struct htmlpair *p)
|
int sz, const struct htmlpair *p)
|
||||||
@ -490,7 +507,7 @@ print_otag(struct html *h, enum htmltag tag,
|
|||||||
|
|
||||||
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
||||||
switch (h->type) {
|
switch (h->type) {
|
||||||
case (HTML_XHTML_1_0_STRICT):
|
case HTML_XHTML_1_0_STRICT:
|
||||||
putchar('/');
|
putchar('/');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -507,7 +524,6 @@ print_otag(struct html *h, enum htmltag tag,
|
|||||||
return(t);
|
return(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_ctag(struct html *h, enum htmltag tag)
|
print_ctag(struct html *h, enum htmltag tag)
|
||||||
{
|
{
|
||||||
@ -527,7 +543,7 @@ print_gen_decls(struct html *h)
|
|||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
switch (h->type) {
|
switch (h->type) {
|
||||||
case (HTML_HTML_4_01_STRICT):
|
case HTML_HTML_4_01_STRICT:
|
||||||
name = "HTML";
|
name = "HTML";
|
||||||
doctype = "-//W3C//DTD HTML 4.01//EN";
|
doctype = "-//W3C//DTD HTML 4.01//EN";
|
||||||
dtd = "http://www.w3.org/TR/html4/strict.dtd";
|
dtd = "http://www.w3.org/TR/html4/strict.dtd";
|
||||||
@ -560,13 +576,13 @@ print_text(struct html *h, const char *word)
|
|||||||
|
|
||||||
assert(NULL == h->metaf);
|
assert(NULL == h->metaf);
|
||||||
switch (h->metac) {
|
switch (h->metac) {
|
||||||
case (HTMLFONT_ITALIC):
|
case HTMLFONT_ITALIC:
|
||||||
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
||||||
break;
|
break;
|
||||||
case (HTMLFONT_BOLD):
|
case HTMLFONT_BOLD:
|
||||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||||
break;
|
break;
|
||||||
case (HTMLFONT_BI):
|
case HTMLFONT_BI:
|
||||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||||
print_otag(h, TAG_I, 0, NULL);
|
print_otag(h, TAG_I, 0, NULL);
|
||||||
break;
|
break;
|
||||||
@ -589,7 +605,6 @@ print_text(struct html *h, const char *word)
|
|||||||
h->flags &= ~HTML_IGNDELIM;
|
h->flags &= ~HTML_IGNDELIM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_tagq(struct html *h, const struct tag *until)
|
print_tagq(struct html *h, const struct tag *until)
|
||||||
{
|
{
|
||||||
@ -612,7 +627,6 @@ print_tagq(struct html *h, const struct tag *until)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
print_stagq(struct html *h, const struct tag *suntil)
|
print_stagq(struct html *h, const struct tag *suntil)
|
||||||
{
|
{
|
||||||
@ -657,6 +671,12 @@ void
|
|||||||
bufcat(struct html *h, const char *p)
|
bufcat(struct html *h, const char *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX This is broken and not easy to fix.
|
||||||
|
* When using the -Oincludes option, buffmt_includes()
|
||||||
|
* may pass in strings overrunning BUFSIZ, causing a crash.
|
||||||
|
*/
|
||||||
|
|
||||||
h->buflen = strlcat(h->buf, p, BUFSIZ);
|
h->buflen = strlcat(h->buf, p, BUFSIZ);
|
||||||
assert(h->buflen < BUFSIZ);
|
assert(h->buflen < BUFSIZ);
|
||||||
}
|
}
|
||||||
@ -693,7 +713,7 @@ buffmt_includes(struct html *h, const char *name)
|
|||||||
while (NULL != (p = strchr(pp, '%'))) {
|
while (NULL != (p = strchr(pp, '%'))) {
|
||||||
bufncat(h, pp, (size_t)(p - pp));
|
bufncat(h, pp, (size_t)(p - pp));
|
||||||
switch (*(p + 1)) {
|
switch (*(p + 1)) {
|
||||||
case('I'):
|
case'I':
|
||||||
bufcat(h, name);
|
bufcat(h, name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -707,8 +727,7 @@ buffmt_includes(struct html *h, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
buffmt_man(struct html *h,
|
buffmt_man(struct html *h, const char *name, const char *sec)
|
||||||
const char *name, const char *sec)
|
|
||||||
{
|
{
|
||||||
const char *p, *pp;
|
const char *p, *pp;
|
||||||
|
|
||||||
@ -718,11 +737,11 @@ buffmt_man(struct html *h,
|
|||||||
while (NULL != (p = strchr(pp, '%'))) {
|
while (NULL != (p = strchr(pp, '%'))) {
|
||||||
bufncat(h, pp, (size_t)(p - pp));
|
bufncat(h, pp, (size_t)(p - pp));
|
||||||
switch (*(p + 1)) {
|
switch (*(p + 1)) {
|
||||||
case('S'):
|
case 'S':
|
||||||
bufcat(h, sec ? sec : "1");
|
bufcat(h, sec ? sec : "1");
|
||||||
break;
|
break;
|
||||||
case('N'):
|
case 'N':
|
||||||
bufcat_fmt(h, name);
|
bufcat_fmt(h, "%s", name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bufncat(h, p, 2);
|
bufncat(h, p, 2);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: html.h,v 1.49 2013/08/08 20:07:47 schwarze Exp $ */
|
/* $Id: html.h,v 1.51 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -147,6 +147,9 @@ 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 *);
|
||||||
|
|
||||||
|
#if __GNUC__ - 0 >= 4
|
||||||
|
__attribute__((__format__ (__printf__, 2, 3)))
|
||||||
|
#endif
|
||||||
void bufcat_fmt(struct html *, const char *, ...);
|
void bufcat_fmt(struct html *, const char *, ...);
|
||||||
void bufcat(struct html *, const char *);
|
void bufcat(struct html *, const char *);
|
||||||
void bufcat_id(struct html *, const char *);
|
void bufcat_id(struct html *, const char *);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: lib.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
/* $Id: lib.c,v 1.10 2014/03/23 11:25:26 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -18,12 +18,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.h"
|
|
||||||
#include "libmdoc.h"
|
#include "libmdoc.h"
|
||||||
|
|
||||||
#define LINE(x, y) \
|
#define LINE(x, y) \
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* $Id: lib.in,v 1.17 2013/10/13 15:24:03 schwarze Exp $ */
|
/* $Id: lib.in,v 1.18 2014/01/06 00:53:33 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: libman.h,v 1.56 2012/11/17 00:26:33 schwarze Exp $ */
|
/* $Id: libman.h,v 1.63 2014/08/01 21:24:17 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -24,13 +24,11 @@ enum man_next {
|
|||||||
|
|
||||||
struct man {
|
struct man {
|
||||||
struct mparse *parse; /* parse pointer */
|
struct mparse *parse; /* parse pointer */
|
||||||
|
int quick; /* abort parse early */
|
||||||
int flags; /* parse flags */
|
int flags; /* parse flags */
|
||||||
#define MAN_HALT (1 << 0) /* badness happened: die */
|
|
||||||
#define MAN_ELINE (1 << 1) /* Next-line element scope. */
|
#define MAN_ELINE (1 << 1) /* Next-line element scope. */
|
||||||
#define MAN_BLINE (1 << 2) /* Next-line block scope. */
|
#define MAN_BLINE (1 << 2) /* Next-line block scope. */
|
||||||
#define MAN_ILINE (1 << 3) /* Ignored in next-line scope. */
|
|
||||||
#define MAN_LITERAL (1 << 4) /* Literal input. */
|
#define MAN_LITERAL (1 << 4) /* Literal input. */
|
||||||
#define MAN_BPLINE (1 << 5)
|
|
||||||
#define MAN_NEWLINE (1 << 6) /* first macro/text in a line */
|
#define MAN_NEWLINE (1 << 6) /* first macro/text in a line */
|
||||||
enum man_next next; /* where to put the next node */
|
enum man_next next; /* where to put the next node */
|
||||||
struct man_node *last; /* the last parsed node */
|
struct man_node *last; /* the last parsed node */
|
||||||
@ -61,10 +59,6 @@ extern const struct man_macro *const man_macros;
|
|||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
#define man_pmsg(man, l, p, t) \
|
|
||||||
mandoc_msg((t), (man)->parse, (l), (p), NULL)
|
|
||||||
#define man_nmsg(man, n, t) \
|
|
||||||
mandoc_msg((t), (man)->parse, (n)->line, (n)->pos, NULL)
|
|
||||||
int man_word_alloc(struct man *, int, int, const char *);
|
int man_word_alloc(struct man *, int, int, const char *);
|
||||||
int man_block_alloc(struct man *, int, int, enum mant);
|
int man_block_alloc(struct man *, int, int, enum mant);
|
||||||
int man_head_alloc(struct man *, int, int, enum mant);
|
int man_head_alloc(struct man *, int, int, enum mant);
|
||||||
@ -76,9 +70,7 @@ void man_hash_init(void);
|
|||||||
enum mant man_hash_find(const char *);
|
enum mant man_hash_find(const char *);
|
||||||
int man_macroend(struct man *);
|
int man_macroend(struct man *);
|
||||||
int man_valid_post(struct man *);
|
int man_valid_post(struct man *);
|
||||||
int man_valid_pre(struct man *, struct man_node *);
|
int man_unscope(struct man *, const struct man_node *);
|
||||||
int man_unscope(struct man *,
|
|
||||||
const struct man_node *, enum mandocerr);
|
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: libmandoc.h,v 1.35 2013/12/15 21:23:52 schwarze Exp $ */
|
/* $Id: libmandoc.h,v 1.42 2014/07/09 11:31:43 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 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
|
||||||
@ -38,16 +38,20 @@ struct man;
|
|||||||
|
|
||||||
void mandoc_msg(enum mandocerr, struct mparse *,
|
void mandoc_msg(enum mandocerr, struct mparse *,
|
||||||
int, int, const char *);
|
int, int, const char *);
|
||||||
|
#if __GNUC__ - 0 >= 4
|
||||||
|
__attribute__((__format__ (__printf__, 5, 6)))
|
||||||
|
#endif
|
||||||
void mandoc_vmsg(enum mandocerr, struct mparse *,
|
void mandoc_vmsg(enum mandocerr, struct mparse *,
|
||||||
int, int, const char *, ...);
|
int, int, const char *, ...);
|
||||||
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
||||||
char *mandoc_normdate(struct mparse *, char *, int, int);
|
char *mandoc_normdate(struct mparse *, char *, int, int);
|
||||||
int mandoc_eos(const char *, size_t, int);
|
int mandoc_eos(const char *, size_t);
|
||||||
int mandoc_strntoi(const char *, size_t, int);
|
int mandoc_strntoi(const char *, size_t, int);
|
||||||
const char *mandoc_a2msec(const char*);
|
const char *mandoc_a2msec(const char*);
|
||||||
|
|
||||||
void mdoc_free(struct mdoc *);
|
void mdoc_free(struct mdoc *);
|
||||||
struct mdoc *mdoc_alloc(struct roff *, struct mparse *, char *);
|
struct mdoc *mdoc_alloc(struct roff *, struct mparse *,
|
||||||
|
const char *, int);
|
||||||
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 *);
|
||||||
@ -55,7 +59,7 @@ int mdoc_addspan(struct mdoc *, const struct tbl_span *);
|
|||||||
int mdoc_addeqn(struct mdoc *, const struct eqn *);
|
int 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 *);
|
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 *);
|
||||||
@ -63,7 +67,7 @@ int man_addspan(struct man *, const struct tbl_span *);
|
|||||||
int man_addeqn(struct man *, const struct eqn *);
|
int man_addeqn(struct man *, const struct eqn *);
|
||||||
|
|
||||||
void roff_free(struct roff *);
|
void roff_free(struct roff *);
|
||||||
struct roff *roff_alloc(enum mparset, struct mparse *);
|
struct roff *roff_alloc(struct mparse *, 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,
|
||||||
char **, size_t *, int, int *);
|
char **, size_t *, int, int *);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: libmdoc.h,v 1.82 2013/10/21 23:47:58 schwarze Exp $ */
|
/* $Id: libmdoc.h,v 1.88 2014/08/01 17:40:34 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 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -25,9 +25,9 @@ enum mdoc_next {
|
|||||||
|
|
||||||
struct mdoc {
|
struct mdoc {
|
||||||
struct mparse *parse; /* parse pointer */
|
struct mparse *parse; /* parse pointer */
|
||||||
char *defos; /* default argument for .Os */
|
const char *defos; /* default argument for .Os */
|
||||||
|
int quick; /* abort parse early */
|
||||||
int flags; /* parse flags */
|
int flags; /* parse flags */
|
||||||
#define MDOC_HALT (1 << 0) /* error in parse: halt */
|
|
||||||
#define MDOC_LITERAL (1 << 1) /* in a literal scope */
|
#define MDOC_LITERAL (1 << 1) /* in a literal scope */
|
||||||
#define MDOC_PBODY (1 << 2) /* in the document body */
|
#define MDOC_PBODY (1 << 2) /* in the document body */
|
||||||
#define MDOC_NEWLINE (1 << 3) /* first macro/text in a line */
|
#define MDOC_NEWLINE (1 << 3) /* first macro/text in a line */
|
||||||
@ -40,6 +40,7 @@ struct mdoc {
|
|||||||
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 */
|
||||||
|
struct mdoc_node *last_es; /* the most recent Es node */
|
||||||
struct mdoc_meta meta; /* document meta-data */
|
struct mdoc_meta meta; /* document meta-data */
|
||||||
enum mdoc_sec lastnamed;
|
enum mdoc_sec lastnamed;
|
||||||
enum mdoc_sec lastsec;
|
enum mdoc_sec lastsec;
|
||||||
@ -103,10 +104,6 @@ extern const struct mdoc_macro *const mdoc_macros;
|
|||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
#define mdoc_pmsg(mdoc, l, p, t) \
|
|
||||||
mandoc_msg((t), (mdoc)->parse, (l), (p), NULL)
|
|
||||||
#define mdoc_nmsg(mdoc, n, t) \
|
|
||||||
mandoc_msg((t), (mdoc)->parse, (n)->line, (n)->pos, NULL)
|
|
||||||
int mdoc_macro(MACRO_PROT_ARGS);
|
int mdoc_macro(MACRO_PROT_ARGS);
|
||||||
int mdoc_word_alloc(struct mdoc *,
|
int mdoc_word_alloc(struct mdoc *,
|
||||||
int, int, const char *);
|
int, int, const char *);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: libroff.h,v 1.28 2013/05/31 21:37:17 schwarze Exp $ */
|
/* $Id: libroff.h,v 1.29 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* $Id: main.c,v 1.167 2012/11/19 17:22:26 schwarze Exp $ */
|
/* $Id: main.c,v 1.177 2014/06/21 22:24: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, 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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
|
||||||
@ -27,6 +28,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
@ -66,7 +68,7 @@ struct curparse {
|
|||||||
char outopts[BUFSIZ]; /* buf of output opts */
|
char outopts[BUFSIZ]; /* buf of output opts */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int moptions(enum mparset *, 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,
|
||||||
@ -78,12 +80,13 @@ static int woptions(struct curparse *, char *);
|
|||||||
|
|
||||||
static const char *progname;
|
static const char *progname;
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
struct curparse curp;
|
struct curparse curp;
|
||||||
enum mparset type;
|
int options;
|
||||||
enum mandoclevel rc;
|
enum mandoclevel rc;
|
||||||
char *defos;
|
char *defos;
|
||||||
|
|
||||||
@ -95,44 +98,45 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
memset(&curp, 0, sizeof(struct curparse));
|
memset(&curp, 0, sizeof(struct curparse));
|
||||||
|
|
||||||
type = MPARSE_AUTO;
|
options = MPARSE_SO;
|
||||||
curp.outtype = OUTT_ASCII;
|
curp.outtype = OUTT_ASCII;
|
||||||
curp.wlevel = MANDOCLEVEL_FATAL;
|
curp.wlevel = MANDOCLEVEL_FATAL;
|
||||||
defos = NULL;
|
defos = NULL;
|
||||||
|
|
||||||
/* LINTED */
|
|
||||||
while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:")))
|
while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:")))
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ('I'):
|
case 'I':
|
||||||
if (strncmp(optarg, "os=", 3)) {
|
if (strncmp(optarg, "os=", 3)) {
|
||||||
fprintf(stderr, "-I%s: Bad argument\n",
|
fprintf(stderr,
|
||||||
optarg);
|
"%s: -I%s: Bad argument\n",
|
||||||
|
progname, optarg);
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
}
|
}
|
||||||
if (defos) {
|
if (defos) {
|
||||||
fprintf(stderr, "-I%s: Duplicate argument\n",
|
fprintf(stderr,
|
||||||
optarg);
|
"%s: -I%s: Duplicate argument\n",
|
||||||
|
progname, optarg);
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
}
|
}
|
||||||
defos = mandoc_strdup(optarg + 3);
|
defos = mandoc_strdup(optarg + 3);
|
||||||
break;
|
break;
|
||||||
case ('m'):
|
case 'm':
|
||||||
if ( ! moptions(&type, optarg))
|
if ( ! moptions(&options, optarg))
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
break;
|
break;
|
||||||
case ('O'):
|
case 'O':
|
||||||
(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 ('T'):
|
case 'T':
|
||||||
if ( ! toptions(&curp, optarg))
|
if ( ! toptions(&curp, optarg))
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
break;
|
break;
|
||||||
case ('W'):
|
case 'W':
|
||||||
if ( ! woptions(&curp, optarg))
|
if ( ! woptions(&curp, optarg))
|
||||||
return((int)MANDOCLEVEL_BADARG);
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
break;
|
break;
|
||||||
case ('V'):
|
case 'V':
|
||||||
version();
|
version();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
default:
|
default:
|
||||||
@ -140,7 +144,7 @@ main(int argc, char *argv[])
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp, defos);
|
curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conditionally start up the lookaside buffer before parsing.
|
* Conditionally start up the lookaside buffer before parsing.
|
||||||
@ -198,8 +202,8 @@ usage(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse(struct curparse *curp, int fd,
|
parse(struct curparse *curp, int fd, const char *file,
|
||||||
const char *file, enum mandoclevel *level)
|
enum mandoclevel *level)
|
||||||
{
|
{
|
||||||
enum mandoclevel rc;
|
enum mandoclevel rc;
|
||||||
struct mdoc *mdoc;
|
struct mdoc *mdoc;
|
||||||
@ -229,31 +233,31 @@ parse(struct curparse *curp, int fd,
|
|||||||
|
|
||||||
if ( ! (curp->outman && curp->outmdoc)) {
|
if ( ! (curp->outman && curp->outmdoc)) {
|
||||||
switch (curp->outtype) {
|
switch (curp->outtype) {
|
||||||
case (OUTT_XHTML):
|
case OUTT_XHTML:
|
||||||
curp->outdata = xhtml_alloc(curp->outopts);
|
curp->outdata = xhtml_alloc(curp->outopts);
|
||||||
curp->outfree = html_free;
|
curp->outfree = html_free;
|
||||||
break;
|
break;
|
||||||
case (OUTT_HTML):
|
case OUTT_HTML:
|
||||||
curp->outdata = html_alloc(curp->outopts);
|
curp->outdata = html_alloc(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->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->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->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->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->outopts);
|
||||||
curp->outfree = pspdf_free;
|
curp->outfree = pspdf_free;
|
||||||
break;
|
break;
|
||||||
@ -262,29 +266,29 @@ parse(struct curparse *curp, int fd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (curp->outtype) {
|
switch (curp->outtype) {
|
||||||
case (OUTT_HTML):
|
case OUTT_HTML:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (OUTT_XHTML):
|
case OUTT_XHTML:
|
||||||
curp->outman = html_man;
|
curp->outman = html_man;
|
||||||
curp->outmdoc = html_mdoc;
|
curp->outmdoc = html_mdoc;
|
||||||
break;
|
break;
|
||||||
case (OUTT_TREE):
|
case OUTT_TREE:
|
||||||
curp->outman = tree_man;
|
curp->outman = tree_man;
|
||||||
curp->outmdoc = tree_mdoc;
|
curp->outmdoc = tree_mdoc;
|
||||||
break;
|
break;
|
||||||
case (OUTT_MAN):
|
case OUTT_MAN:
|
||||||
curp->outmdoc = man_mdoc;
|
curp->outmdoc = man_mdoc;
|
||||||
curp->outman = man_man;
|
curp->outman = man_man;
|
||||||
break;
|
break;
|
||||||
case (OUTT_PDF):
|
case OUTT_PDF:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (OUTT_ASCII):
|
case OUTT_ASCII:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (OUTT_UTF8):
|
case OUTT_UTF8:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (OUTT_LOCALE):
|
case OUTT_LOCALE:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (OUTT_PS):
|
case OUTT_PS:
|
||||||
curp->outman = terminal_man;
|
curp->outman = terminal_man;
|
||||||
curp->outmdoc = terminal_mdoc;
|
curp->outmdoc = terminal_mdoc;
|
||||||
break;
|
break;
|
||||||
@ -293,7 +297,7 @@ parse(struct curparse *curp, int fd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mparse_result(curp->mp, &mdoc, &man);
|
mparse_result(curp->mp, &mdoc, &man, NULL);
|
||||||
|
|
||||||
/* Execute the out device, if it exists. */
|
/* Execute the out device, if it exists. */
|
||||||
|
|
||||||
@ -311,17 +315,18 @@ parse(struct curparse *curp, int fd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
moptions(enum mparset *tflags, char *arg)
|
moptions(int *options, char *arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (0 == strcmp(arg, "doc"))
|
if (0 == strcmp(arg, "doc"))
|
||||||
*tflags = MPARSE_MDOC;
|
*options |= MPARSE_MDOC;
|
||||||
else if (0 == strcmp(arg, "andoc"))
|
else if (0 == strcmp(arg, "andoc"))
|
||||||
*tflags = MPARSE_AUTO;
|
/* nothing to do */;
|
||||||
else if (0 == strcmp(arg, "an"))
|
else if (0 == strcmp(arg, "an"))
|
||||||
*tflags = MPARSE_MAN;
|
*options |= MPARSE_MAN;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s: Bad argument\n", arg);
|
fprintf(stderr, "%s: -m%s: Bad argument\n",
|
||||||
|
progname, arg);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +359,8 @@ toptions(struct curparse *curp, char *arg)
|
|||||||
else if (0 == strcmp(arg, "pdf"))
|
else if (0 == strcmp(arg, "pdf"))
|
||||||
curp->outtype = OUTT_PDF;
|
curp->outtype = OUTT_PDF;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s: Bad argument\n", arg);
|
fprintf(stderr, "%s: -T%s: Bad argument\n",
|
||||||
|
progname, arg);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,22 +383,23 @@ woptions(struct curparse *curp, char *arg)
|
|||||||
while (*arg) {
|
while (*arg) {
|
||||||
o = arg;
|
o = arg;
|
||||||
switch (getsubopt(&arg, UNCONST(toks), &v)) {
|
switch (getsubopt(&arg, UNCONST(toks), &v)) {
|
||||||
case (0):
|
case 0:
|
||||||
curp->wstop = 1;
|
curp->wstop = 1;
|
||||||
break;
|
break;
|
||||||
case (1):
|
case 1:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (2):
|
case 2:
|
||||||
curp->wlevel = MANDOCLEVEL_WARNING;
|
curp->wlevel = MANDOCLEVEL_WARNING;
|
||||||
break;
|
break;
|
||||||
case (3):
|
case 3:
|
||||||
curp->wlevel = MANDOCLEVEL_ERROR;
|
curp->wlevel = MANDOCLEVEL_ERROR;
|
||||||
break;
|
break;
|
||||||
case (4):
|
case 4:
|
||||||
curp->wlevel = MANDOCLEVEL_FATAL;
|
curp->wlevel = MANDOCLEVEL_FATAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "-W%s: Bad argument\n", o);
|
fprintf(stderr, "%s: -W%s: Bad argument\n",
|
||||||
|
progname, o);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,11 +411,17 @@ static void
|
|||||||
mmsg(enum mandocerr t, enum mandoclevel lvl,
|
mmsg(enum mandocerr t, enum mandoclevel lvl,
|
||||||
const char *file, int line, int col, const char *msg)
|
const char *file, int line, int col, const char *msg)
|
||||||
{
|
{
|
||||||
|
const char *mparse_msg;
|
||||||
|
|
||||||
fprintf(stderr, "%s:%d:%d: %s: %s",
|
fprintf(stderr, "%s: %s:", progname, file);
|
||||||
file, line, col + 1,
|
|
||||||
mparse_strlevel(lvl),
|
if (line)
|
||||||
mparse_strerror(t));
|
fprintf(stderr, "%d:%d:", line, col + 1);
|
||||||
|
|
||||||
|
fprintf(stderr, " %s", mparse_strlevel(lvl));
|
||||||
|
|
||||||
|
if (NULL != (mparse_msg = mparse_strerror(t)))
|
||||||
|
fprintf(stderr, ": %s", mparse_msg);
|
||||||
|
|
||||||
if (msg)
|
if (msg)
|
||||||
fprintf(stderr, ": %s", msg);
|
fprintf(stderr, ": %s", msg);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: main.h,v 1.15 2011/10/06 22:29:12 kristaps Exp $ */
|
/* $Id: main.h,v 1.16 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
|
217
contrib/mdocml/makewhatis.8
Normal file
217
contrib/mdocml/makewhatis.8
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
.\" $Id: makewhatis.8,v 1.2 2014/04/25 12:13:15 schwarze Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
.\" Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
|
.\" copyright notice and this permission notice appear in all copies.
|
||||||
|
.\"
|
||||||
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: April 25 2014 $
|
||||||
|
.Dt MAKEWHATIS 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm makewhatis
|
||||||
|
.Nd index UNIX manuals
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl aDnpQ
|
||||||
|
.Op Fl T Cm utf8
|
||||||
|
.Op Fl C Ar file
|
||||||
|
.Nm
|
||||||
|
.Op Fl aDnpQ
|
||||||
|
.Op Fl T Cm utf8
|
||||||
|
.Ar dir ...
|
||||||
|
.Nm
|
||||||
|
.Op Fl DnpQ
|
||||||
|
.Op Fl T Cm utf8
|
||||||
|
.Fl d Ar dir
|
||||||
|
.Op Ar
|
||||||
|
.Nm
|
||||||
|
.Op Fl Dnp
|
||||||
|
.Op Fl T Cm utf8
|
||||||
|
.Fl u Ar dir
|
||||||
|
.Op Ar
|
||||||
|
.Nm
|
||||||
|
.Op Fl DQ
|
||||||
|
.Fl t Ar
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility extracts keywords from
|
||||||
|
.Ux
|
||||||
|
manuals and indexes them in a database for fast retrieval by
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
.Xr whatis 1 ,
|
||||||
|
and
|
||||||
|
.Xr man 1 Ns 's
|
||||||
|
.Fl k
|
||||||
|
option.
|
||||||
|
.Pp
|
||||||
|
By default,
|
||||||
|
.Nm
|
||||||
|
creates a database in each
|
||||||
|
.Ar dir
|
||||||
|
using the files
|
||||||
|
.Sm off
|
||||||
|
.Sy man Ar section Li /
|
||||||
|
.Op Ar arch Li /
|
||||||
|
.Ar title . section
|
||||||
|
.Sm on
|
||||||
|
and
|
||||||
|
.Sm off
|
||||||
|
.Sy cat Ar section Li /
|
||||||
|
.Op Ar arch Li /
|
||||||
|
.Ar title . Sy 0
|
||||||
|
.Sm on
|
||||||
|
in that directory.
|
||||||
|
Existing databases are replaced.
|
||||||
|
If
|
||||||
|
.Ar dir
|
||||||
|
is not provided,
|
||||||
|
.Nm
|
||||||
|
uses the default paths stipulated by
|
||||||
|
.Xr manpath 1 ,
|
||||||
|
or
|
||||||
|
.Xr man.conf 5 .
|
||||||
|
.Pp
|
||||||
|
The arguments are as follows:
|
||||||
|
.Bl -tag -width "-C file"
|
||||||
|
.It Fl a
|
||||||
|
Use all directories and files found below
|
||||||
|
.Ar dir ... .
|
||||||
|
.It Fl C Ar file
|
||||||
|
Specify an alternative configuration
|
||||||
|
.Ar file
|
||||||
|
in
|
||||||
|
.Xr man.conf 5
|
||||||
|
format.
|
||||||
|
.It Fl D
|
||||||
|
Display all files added or removed to the index.
|
||||||
|
With a second
|
||||||
|
.Fl D ,
|
||||||
|
also show all keyswords added for each file.
|
||||||
|
.It Fl d Ar dir
|
||||||
|
Merge (remove and re-add)
|
||||||
|
.Ar
|
||||||
|
to the database in
|
||||||
|
.Ar dir .
|
||||||
|
.It Fl n
|
||||||
|
Do not create or modify any database; scan and parse only,
|
||||||
|
and print manual page names and descriptions to standard output.
|
||||||
|
.It Fl p
|
||||||
|
Print warnings about potential problems with manual pages
|
||||||
|
to the standard error output.
|
||||||
|
.It Fl Q
|
||||||
|
Quickly build reduced-size databases
|
||||||
|
by reading only the NAME sections of manuals.
|
||||||
|
The resulting databases will usually contain names and descriptions only.
|
||||||
|
.It Fl T Cm utf8
|
||||||
|
Use UTF-8 encoding instead of ASCII for strings stored in the databases.
|
||||||
|
.It Fl t Ar
|
||||||
|
Check the given
|
||||||
|
.Ar files
|
||||||
|
for potential problems.
|
||||||
|
Implies
|
||||||
|
.Fl a ,
|
||||||
|
.Fl n ,
|
||||||
|
and
|
||||||
|
.Fl p .
|
||||||
|
All diagnostic messages are printed to the standard output;
|
||||||
|
the standard error output is not used.
|
||||||
|
.It Fl u Ar dir
|
||||||
|
Remove
|
||||||
|
.Ar
|
||||||
|
from the database in
|
||||||
|
.Ar dir .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
If fatal parse errors are encountered while parsing, the offending file
|
||||||
|
is printed to stderr, omitted from the index, and the parse continues
|
||||||
|
with the next input file.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Pa mandoc.db
|
||||||
|
A database of manpages relative to the directory of the file.
|
||||||
|
This file is portable across architectures and systems, so long as the
|
||||||
|
manpage hierarchy it indexes does not change.
|
||||||
|
.It Pa /etc/man.conf
|
||||||
|
The default
|
||||||
|
.Xr man 1
|
||||||
|
configuration file.
|
||||||
|
.El
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility exits with one of the following values:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width Ds -compact
|
||||||
|
.It 0
|
||||||
|
No errors occurred.
|
||||||
|
.It 5
|
||||||
|
Invalid command line arguments were specified.
|
||||||
|
No input files have been read.
|
||||||
|
.It 6
|
||||||
|
An operating system error occurred, for example memory exhaustion or an
|
||||||
|
error accessing input files.
|
||||||
|
Such errors cause
|
||||||
|
.Nm
|
||||||
|
to exit at once, possibly in the middle of parsing or formatting a file.
|
||||||
|
The output databases are corrupt and should be removed.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
.Xr man 1 ,
|
||||||
|
.Xr whatis 1 ,
|
||||||
|
.Xr man.conf 5
|
||||||
|
.Sh HISTORY
|
||||||
|
A
|
||||||
|
.Nm
|
||||||
|
utility first appeared in
|
||||||
|
.Bx 2 .
|
||||||
|
It was rewritten in
|
||||||
|
.Xr perl 1
|
||||||
|
for
|
||||||
|
.Ox 2.7
|
||||||
|
and in C for
|
||||||
|
.Ox 5.6 .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar dir
|
||||||
|
argument first appeared in
|
||||||
|
.Nx 1.0 ;
|
||||||
|
the options
|
||||||
|
.Fl dpt
|
||||||
|
in
|
||||||
|
.Ox 2.7 ;
|
||||||
|
the option
|
||||||
|
.Fl u
|
||||||
|
in
|
||||||
|
.Ox 3.4 ;
|
||||||
|
and the options
|
||||||
|
.Fl aCDnQT
|
||||||
|
in
|
||||||
|
.Ox 5.6 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
.An Bill Joy
|
||||||
|
wrote the original
|
||||||
|
.Bx
|
||||||
|
.Nm
|
||||||
|
in February 1979,
|
||||||
|
.An Marc Espie
|
||||||
|
started the Perl version in 2000,
|
||||||
|
and the current version of
|
||||||
|
.Nm
|
||||||
|
was written by
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
and
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
@ -1,7 +1,8 @@
|
|||||||
.\" $Id: man.7,v 1.120 2013/09/16 22:58:57 schwarze Exp $
|
.\" $Id: man.7,v 1.127 2014/06/22 16:39:45 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) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
.\" Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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,7 +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.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 16 2013 $
|
.Dd $Mdocdate: June 22 2014 $
|
||||||
.Dt MAN 7
|
.Dt MAN 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -97,30 +98,32 @@ file for a utility
|
|||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
\&.TH PROGNAME 1 2009-10-10
|
\&.TH PROGNAME 1 2009-10-10
|
||||||
\&.SH NAME
|
\&.SH NAME
|
||||||
\efBprogname\efR \e(en a description goes here
|
\efBprogname\efR \e(en one line about what it does
|
||||||
\&.\e\(dq .SH LIBRARY
|
\&.\e\(dq .SH LIBRARY
|
||||||
\&.\e\(dq For sections 2 & 3 only.
|
\&.\e\(dq For sections 2, 3, and 9 only.
|
||||||
\&.\e\(dq Not used in OpenBSD.
|
\&.\e\(dq Not used in OpenBSD.
|
||||||
\&.SH SYNOPSIS
|
\&.SH SYNOPSIS
|
||||||
\efBprogname\efR [\efB\e-options\efR] arguments...
|
\efBprogname\efR [\efB\e-options\efR] \efIfile ...\efR
|
||||||
\&.SH DESCRIPTION
|
\&.SH DESCRIPTION
|
||||||
The \efBfoo\efR utility processes files...
|
The \efBfoo\efR utility processes files ...
|
||||||
|
\&.\e\(dq .Sh CONTEXT
|
||||||
|
\&.\e\(dq For section 9 functions only.
|
||||||
\&.\e\(dq .SH IMPLEMENTATION NOTES
|
\&.\e\(dq .SH IMPLEMENTATION NOTES
|
||||||
\&.\e\(dq Not used in OpenBSD.
|
\&.\e\(dq Not used in OpenBSD.
|
||||||
\&.\e\(dq .SH RETURN VALUES
|
\&.\e\(dq .SH RETURN VALUES
|
||||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
\&.\e\(dq For sections 2, 3, and 9 function return values only.
|
||||||
\&.\e\(dq .SH ENVIRONMENT
|
\&.\e\(dq .SH ENVIRONMENT
|
||||||
\&.\e\(dq For sections 1, 6, 7, & 8 only.
|
\&.\e\(dq For sections 1, 6, 7, and 8 only.
|
||||||
\&.\e\(dq .SH FILES
|
\&.\e\(dq .SH FILES
|
||||||
\&.\e\(dq .SH EXIT STATUS
|
\&.\e\(dq .SH EXIT STATUS
|
||||||
\&.\e\(dq For sections 1, 6, & 8 only.
|
\&.\e\(dq For sections 1, 6, and 8 only.
|
||||||
\&.\e\(dq .SH EXAMPLES
|
\&.\e\(dq .SH EXAMPLES
|
||||||
\&.\e\(dq .SH DIAGNOSTICS
|
\&.\e\(dq .SH DIAGNOSTICS
|
||||||
\&.\e\(dq For sections 1, 4, 6, 7, & 8 only.
|
\&.\e\(dq For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only.
|
||||||
\&.\e\(dq .SH ERRORS
|
\&.\e\(dq .SH ERRORS
|
||||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
\&.\e\(dq For sections 2, 3, 4, and 9 errno settings only.
|
||||||
\&.\e\(dq .SH SEE ALSO
|
\&.\e\(dq .SH SEE ALSO
|
||||||
\&.\e\(dq .BR foo ( 1 )
|
\&.\e\(dq .BR foobar ( 1 )
|
||||||
\&.\e\(dq .SH STANDARDS
|
\&.\e\(dq .SH STANDARDS
|
||||||
\&.\e\(dq .SH HISTORY
|
\&.\e\(dq .SH HISTORY
|
||||||
\&.\e\(dq .SH AUTHORS
|
\&.\e\(dq .SH AUTHORS
|
||||||
@ -170,6 +173,9 @@ This expands upon the brief, one-line description in
|
|||||||
.Em NAME .
|
.Em NAME .
|
||||||
It usually contains a break-down of the options (if documenting a
|
It usually contains a break-down of the options (if documenting a
|
||||||
command).
|
command).
|
||||||
|
.It Em CONTEXT
|
||||||
|
This section lists the contexts in which functions can be called in section 9.
|
||||||
|
The contexts are autoconf, process, or interrupt.
|
||||||
.It Em IMPLEMENTATION NOTES
|
.It Em IMPLEMENTATION NOTES
|
||||||
Implementation-specific notes should be kept here.
|
Implementation-specific notes should be kept here.
|
||||||
This is useful when implementing standard functions that may have side
|
This is useful when implementing standard functions that may have side
|
||||||
@ -196,13 +202,19 @@ well-tested invocations.
|
|||||||
Make sure that examples work properly!
|
Make sure that examples work properly!
|
||||||
.It Em DIAGNOSTICS
|
.It Em DIAGNOSTICS
|
||||||
Documents error conditions.
|
Documents error conditions.
|
||||||
This is most useful in section 4 manuals.
|
In section 4 and 9 manuals, these are usually messages
|
||||||
|
printed by the kernel to the console and to the kernel log.
|
||||||
|
In section 1, 6, 7, and 8, these are usually messages
|
||||||
|
printed by userland programs to the standard error output.
|
||||||
|
.Pp
|
||||||
Historically, this section was used in place of
|
Historically, this section was used in place of
|
||||||
.Em EXIT STATUS
|
.Em EXIT STATUS
|
||||||
for manuals in sections 1, 6, and 8; however, this practise is
|
for manuals in sections 1, 6, and 8; however, this practise is
|
||||||
discouraged.
|
discouraged.
|
||||||
.It Em ERRORS
|
.It Em ERRORS
|
||||||
Documents error handling in sections 2, 3, and 9.
|
Documents
|
||||||
|
.Xr errno 2
|
||||||
|
settings in sections 2, 3, 4, and 9.
|
||||||
.It Em SEE ALSO
|
.It Em SEE ALSO
|
||||||
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.
|
||||||
@ -280,7 +292,7 @@ For the scoping of individual macros, see
|
|||||||
.Sx MACRO SYNTAX .
|
.Sx MACRO SYNTAX .
|
||||||
.Ss \&AT
|
.Ss \&AT
|
||||||
Sets the volume for the footer for compatibility with man pages from
|
Sets the volume for the footer for compatibility with man pages from
|
||||||
.Tn AT&T UNIX
|
.At
|
||||||
releases.
|
releases.
|
||||||
The optional arguments specify which release it is from.
|
The optional arguments specify which release it is from.
|
||||||
.Ss \&B
|
.Ss \&B
|
||||||
@ -656,6 +668,20 @@ Sets the volume for the footer for compatibility with man pages from
|
|||||||
.Bx
|
.Bx
|
||||||
releases.
|
releases.
|
||||||
The optional first argument specifies which release it is from.
|
The optional first argument specifies which release it is from.
|
||||||
|
.Ss \&UE
|
||||||
|
End a uniform resource identifier block.
|
||||||
|
This is a non-standard GNU extension, included only for compatibility.
|
||||||
|
See
|
||||||
|
.Sx \&UE .
|
||||||
|
.Ss \&UR
|
||||||
|
Begin a uniform resource identifier block.
|
||||||
|
This is a non-standard GNU extension, included only for compatibility.
|
||||||
|
It has the following syntax:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
.Pf \. Sx \&UR Ar uri
|
||||||
|
link description to be shown
|
||||||
|
.Pf \. Sx UE
|
||||||
|
.Ed
|
||||||
.Ss \&br
|
.Ss \&br
|
||||||
Breaks the current line.
|
Breaks the current line.
|
||||||
Consecutive invocations have no further effect.
|
Consecutive invocations have no further effect.
|
||||||
@ -665,11 +691,6 @@ See also
|
|||||||
.Ss \&fi
|
.Ss \&fi
|
||||||
End literal mode begun by
|
End literal mode begun by
|
||||||
.Sx \&nf .
|
.Sx \&nf .
|
||||||
.Ss \&ft
|
|
||||||
Change the current font mode.
|
|
||||||
See
|
|
||||||
.Sx Text Decoration
|
|
||||||
for a listing of available font modes.
|
|
||||||
.Ss \&in
|
.Ss \&in
|
||||||
Indent relative to the current indentation:
|
Indent relative to the current indentation:
|
||||||
.Pp
|
.Pp
|
||||||
@ -750,10 +771,13 @@ The syntax is as follows:
|
|||||||
.It Sx \&BI Ta n Ta current Ta \&
|
.It Sx \&BI Ta n Ta current Ta \&
|
||||||
.It Sx \&BR Ta n Ta current Ta \&
|
.It Sx \&BR Ta n Ta current Ta \&
|
||||||
.It Sx \&DT Ta 0 Ta current Ta \&
|
.It Sx \&DT Ta 0 Ta current Ta \&
|
||||||
|
.It Sx \&EE Ta 0 Ta current Ta compat
|
||||||
|
.It Sx \&EX Ta 0 Ta current Ta compat
|
||||||
.It Sx \&I Ta n Ta next-line Ta \&
|
.It Sx \&I Ta n Ta next-line Ta \&
|
||||||
.It Sx \&IB Ta n Ta current Ta \&
|
.It Sx \&IB Ta n Ta current Ta \&
|
||||||
.It Sx \&IR Ta n Ta current Ta \&
|
.It Sx \&IR Ta n Ta current Ta \&
|
||||||
.It Sx \&OP Ta 0, 1 Ta current Ta compat
|
.It Sx \&OP Ta 0, 1 Ta current Ta compat
|
||||||
|
.It Sx \&PD Ta 1 Ta current Ta \&
|
||||||
.It Sx \&R Ta n Ta next-line Ta \&
|
.It Sx \&R Ta n Ta next-line Ta \&
|
||||||
.It Sx \&RB Ta n Ta current Ta \&
|
.It Sx \&RB Ta n Ta current Ta \&
|
||||||
.It Sx \&RI Ta n Ta current Ta \&
|
.It Sx \&RI Ta n Ta current Ta \&
|
||||||
@ -763,7 +787,6 @@ The syntax is as follows:
|
|||||||
.It Sx \&UC Ta <=1 Ta current Ta \&
|
.It Sx \&UC Ta <=1 Ta current Ta \&
|
||||||
.It Sx \&br Ta 0 Ta current Ta compat
|
.It Sx \&br Ta 0 Ta current Ta compat
|
||||||
.It Sx \&fi Ta 0 Ta current Ta compat
|
.It Sx \&fi Ta 0 Ta current Ta compat
|
||||||
.It Sx \&ft Ta 1 Ta current Ta compat
|
|
||||||
.It Sx \&in Ta 1 Ta current Ta compat
|
.It Sx \&in Ta 1 Ta current Ta compat
|
||||||
.It Sx \&na Ta 0 Ta current Ta compat
|
.It Sx \&na Ta 0 Ta current Ta compat
|
||||||
.It Sx \&nf Ta 0 Ta current Ta compat
|
.It Sx \&nf Ta 0 Ta current Ta compat
|
||||||
@ -823,6 +846,8 @@ implicitly closed, is syntactically incorrect.
|
|||||||
.It Sx \&SH Ta >0 Ta next-line Ta section Ta \&
|
.It Sx \&SH Ta >0 Ta next-line Ta section Ta \&
|
||||||
.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \&
|
.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \&
|
||||||
.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \&
|
.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \&
|
||||||
|
.It Sx \&UE Ta 0 Ta current Ta none Ta compat
|
||||||
|
.It Sx \&UR Ta 1 Ta current Ta part Ta compat
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Macros marked
|
Macros marked
|
||||||
@ -848,10 +873,11 @@ Note that macros like
|
|||||||
.Sx \&BR
|
.Sx \&BR
|
||||||
open and close a font scope for each argument.
|
open and close a font scope for each argument.
|
||||||
.Sh COMPATIBILITY
|
.Sh COMPATIBILITY
|
||||||
This section documents areas of questionable portability between
|
This section mentions some areas of questionable portability between
|
||||||
implementations of the
|
implementations of the
|
||||||
.Nm
|
.Nm
|
||||||
language.
|
language.
|
||||||
|
More incompatibilities exist.
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -dash -compact
|
.Bl -dash -compact
|
||||||
.It
|
.It
|
||||||
@ -863,47 +889,12 @@ to close out a literal context opened with
|
|||||||
.Sx \&nf .
|
.Sx \&nf .
|
||||||
This behaviour may not be portable.
|
This behaviour may not be portable.
|
||||||
.It
|
.It
|
||||||
In quoted literals, GNU troff allowed pair-wise double-quotes to produce
|
|
||||||
a standalone double-quote in formatted output.
|
|
||||||
It is not known whether this behaviour is exhibited by other formatters.
|
|
||||||
.It
|
|
||||||
troff suppresses a newline before
|
troff suppresses a newline before
|
||||||
.Sq \(aq
|
.Sq \(aq
|
||||||
macro output; in mandoc, it is an alias for the standard
|
macro output; in mandoc, it is an alias for the standard
|
||||||
.Sq \&.
|
.Sq \&.
|
||||||
control character.
|
control character.
|
||||||
.It
|
.It
|
||||||
The
|
|
||||||
.Sq \eh
|
|
||||||
.Pq horizontal position ,
|
|
||||||
.Sq \ev
|
|
||||||
.Pq vertical position ,
|
|
||||||
.Sq \em
|
|
||||||
.Pq text colour ,
|
|
||||||
.Sq \eM
|
|
||||||
.Pq text filling colour ,
|
|
||||||
.Sq \ez
|
|
||||||
.Pq zero-length character ,
|
|
||||||
.Sq \ew
|
|
||||||
.Pq string length ,
|
|
||||||
.Sq \ek
|
|
||||||
.Pq horizontal position marker ,
|
|
||||||
.Sq \eo
|
|
||||||
.Pq text overstrike ,
|
|
||||||
and
|
|
||||||
.Sq \es
|
|
||||||
.Pq text size
|
|
||||||
escape sequences are all discarded in mandoc.
|
|
||||||
.It
|
|
||||||
The
|
|
||||||
.Sq \ef
|
|
||||||
scaling unit is accepted by mandoc, but rendered as the default unit.
|
|
||||||
.It
|
|
||||||
The
|
|
||||||
.Sx \&sp
|
|
||||||
macro does not accept negative values in mandoc.
|
|
||||||
In GNU troff, this would result in strange behaviour.
|
|
||||||
.It
|
|
||||||
In page header lines, GNU troff versions up to and including 1.21
|
In page header lines, GNU troff versions up to and including 1.21
|
||||||
only print
|
only print
|
||||||
.Ar volume
|
.Ar volume
|
||||||
@ -919,8 +910,13 @@ is given, like in
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Sx OP
|
.Sx EE ,
|
||||||
macro is part of the extended
|
.Sx EX ,
|
||||||
|
.Sx OP ,
|
||||||
|
.Sx UE ,
|
||||||
|
and
|
||||||
|
.Sx UR
|
||||||
|
macros are part of the GNU extended
|
||||||
.Nm
|
.Nm
|
||||||
macro set, and may not be portable to non-GNU troff implementations.
|
macro set, and may not be portable to non-GNU troff implementations.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* $Id: man.c,v 1.121 2013/11/10 22:54:40 schwarze Exp $ */
|
/* $Id: man.c,v 1.137 2014/08/01 21:24:17 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) 2011 Joerg Sonnenberger <joerg@netbsd.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
|
||||||
@ -21,6 +23,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -28,6 +31,7 @@
|
|||||||
|
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libman.h"
|
#include "libman.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
|
|
||||||
@ -41,7 +45,7 @@ const char *const __man_macronames[MAN_MAX] = {
|
|||||||
"fi", "RE", "RS", "DT",
|
"fi", "RE", "RS", "DT",
|
||||||
"UC", "PD", "AT", "in",
|
"UC", "PD", "AT", "in",
|
||||||
"ft", "OP", "EX", "EE",
|
"ft", "OP", "EX", "EE",
|
||||||
"UR", "UE"
|
"UR", "UE", "ll"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * const *man_macronames = __man_macronames;
|
const char * const *man_macronames = __man_macronames;
|
||||||
@ -64,20 +68,16 @@ const struct man_node *
|
|||||||
man_node(const struct man *man)
|
man_node(const struct man *man)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MAN_HALT & man->flags));
|
|
||||||
return(man->first);
|
return(man->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct man_meta *
|
const struct man_meta *
|
||||||
man_meta(const struct man *man)
|
man_meta(const struct man *man)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MAN_HALT & man->flags));
|
|
||||||
return(&man->meta);
|
return(&man->meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
man_reset(struct man *man)
|
man_reset(struct man *man)
|
||||||
{
|
{
|
||||||
@ -86,7 +86,6 @@ man_reset(struct man *man)
|
|||||||
man_alloc1(man);
|
man_alloc1(man);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
man_free(struct man *man)
|
man_free(struct man *man)
|
||||||
{
|
{
|
||||||
@ -95,9 +94,8 @@ man_free(struct man *man)
|
|||||||
free(man);
|
free(man);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct man *
|
struct man *
|
||||||
man_alloc(struct roff *roff, struct mparse *parse)
|
man_alloc(struct roff *roff, struct mparse *parse, int quick)
|
||||||
{
|
{
|
||||||
struct man *p;
|
struct man *p;
|
||||||
|
|
||||||
@ -105,39 +103,31 @@ man_alloc(struct roff *roff, struct mparse *parse)
|
|||||||
|
|
||||||
man_hash_init();
|
man_hash_init();
|
||||||
p->parse = parse;
|
p->parse = parse;
|
||||||
|
p->quick = quick;
|
||||||
p->roff = roff;
|
p->roff = roff;
|
||||||
|
|
||||||
man_alloc1(p);
|
man_alloc1(p);
|
||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
man_endparse(struct man *man)
|
man_endparse(struct man *man)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MAN_HALT & man->flags));
|
return(man_macroend(man));
|
||||||
if (man_macroend(man))
|
|
||||||
return(1);
|
|
||||||
man->flags |= MAN_HALT;
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
man->flags |= MAN_NEWLINE;
|
||||||
|
|
||||||
assert( ! (MAN_HALT & man->flags));
|
|
||||||
|
|
||||||
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) :
|
||||||
man_ptext(man, ln, buf, offs));
|
man_ptext(man, ln, buf, offs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
man_free1(struct man *man)
|
man_free1(struct man *man)
|
||||||
{
|
{
|
||||||
@ -156,7 +146,6 @@ man_free1(struct man *man)
|
|||||||
free(man->meta.msec);
|
free(man->meta.msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
man_alloc1(struct man *man)
|
man_alloc1(struct man *man)
|
||||||
{
|
{
|
||||||
@ -180,12 +169,12 @@ man_node_append(struct man *man, struct man_node *p)
|
|||||||
assert(MAN_ROOT != p->type);
|
assert(MAN_ROOT != p->type);
|
||||||
|
|
||||||
switch (man->next) {
|
switch (man->next) {
|
||||||
case (MAN_NEXT_SIBLING):
|
case MAN_NEXT_SIBLING:
|
||||||
man->last->next = p;
|
man->last->next = p;
|
||||||
p->prev = man->last;
|
p->prev = man->last;
|
||||||
p->parent = man->last->parent;
|
p->parent = man->last->parent;
|
||||||
break;
|
break;
|
||||||
case (MAN_NEXT_CHILD):
|
case MAN_NEXT_CHILD:
|
||||||
man->last->child = p;
|
man->last->child = p;
|
||||||
p->parent = man->last;
|
p->parent = man->last;
|
||||||
break;
|
break;
|
||||||
@ -197,19 +186,20 @@ man_node_append(struct man *man, struct man_node *p)
|
|||||||
assert(p->parent);
|
assert(p->parent);
|
||||||
p->parent->nchild++;
|
p->parent->nchild++;
|
||||||
|
|
||||||
if ( ! man_valid_pre(man, p))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_BLOCK:
|
||||||
|
if (p->tok == MAN_SH || p->tok == MAN_SS)
|
||||||
|
man->flags &= ~MAN_LITERAL;
|
||||||
|
break;
|
||||||
|
case MAN_HEAD:
|
||||||
assert(MAN_BLOCK == p->parent->type);
|
assert(MAN_BLOCK == p->parent->type);
|
||||||
p->parent->head = p;
|
p->parent->head = p;
|
||||||
break;
|
break;
|
||||||
case (MAN_TAIL):
|
case MAN_TAIL:
|
||||||
assert(MAN_BLOCK == p->parent->type);
|
assert(MAN_BLOCK == p->parent->type);
|
||||||
p->parent->tail = p;
|
p->parent->tail = p;
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
assert(MAN_BLOCK == p->parent->type);
|
assert(MAN_BLOCK == p->parent->type);
|
||||||
p->parent->body = p;
|
p->parent->body = p;
|
||||||
break;
|
break;
|
||||||
@ -220,9 +210,9 @@ man_node_append(struct man *man, struct man_node *p)
|
|||||||
man->last = p;
|
man->last = p;
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case (MAN_TBL):
|
case MAN_TBL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_TEXT):
|
case MAN_TEXT:
|
||||||
if ( ! man_valid_post(man))
|
if ( ! man_valid_post(man))
|
||||||
return(0);
|
return(0);
|
||||||
break;
|
break;
|
||||||
@ -233,7 +223,6 @@ man_node_append(struct man *man, struct man_node *p)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct man_node *
|
static struct man_node *
|
||||||
man_node_alloc(struct man *man, int line, int pos,
|
man_node_alloc(struct man *man, int line, int pos,
|
||||||
enum man_type type, enum mant tok)
|
enum man_type type, enum mant tok)
|
||||||
@ -252,7 +241,6 @@ man_node_alloc(struct man *man, int line, int pos,
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -265,7 +253,6 @@ man_elem_alloc(struct man *man, int line, int pos, enum mant tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
man_tail_alloc(struct man *man, int line, int pos, enum mant tok)
|
man_tail_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||||
{
|
{
|
||||||
@ -278,7 +265,6 @@ man_tail_alloc(struct man *man, int line, int pos, enum mant tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
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)
|
||||||
{
|
{
|
||||||
@ -291,7 +277,6 @@ man_head_alloc(struct man *man, int line, int pos, enum mant tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -304,7 +289,6 @@ man_body_alloc(struct man *man, int line, int pos, enum mant tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -332,7 +316,6 @@ man_word_alloc(struct man *man, int line, int pos, const char *word)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free all of the resources held by a node. This does NOT unlink a
|
* Free all of the resources held by a node. This does NOT unlink a
|
||||||
* node from its context; for that, see man_node_unlink().
|
* node from its context; for that, see man_node_unlink().
|
||||||
@ -346,7 +329,6 @@ man_node_free(struct man_node *p)
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
man_node_delete(struct man *man, struct man_node *p)
|
man_node_delete(struct man *man, struct man_node *p)
|
||||||
{
|
{
|
||||||
@ -363,8 +345,6 @@ man_addeqn(struct man *man, const struct eqn *ep)
|
|||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
assert( ! (MAN_HALT & man->flags));
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -380,8 +360,6 @@ man_addspan(struct man *man, const struct tbl_span *sp)
|
|||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
assert( ! (MAN_HALT & man->flags));
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -403,7 +381,7 @@ man_descope(struct man *man, int line, int offs)
|
|||||||
|
|
||||||
if (MAN_ELINE & man->flags) {
|
if (MAN_ELINE & man->flags) {
|
||||||
man->flags &= ~MAN_ELINE;
|
man->flags &= ~MAN_ELINE;
|
||||||
if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
|
if ( ! man_unscope(man, man->last->parent))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +389,7 @@ man_descope(struct man *man, int line, int offs)
|
|||||||
return(1);
|
return(1);
|
||||||
man->flags &= ~MAN_BLINE;
|
man->flags &= ~MAN_BLINE;
|
||||||
|
|
||||||
if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
|
if ( ! man_unscope(man, man->last->parent))
|
||||||
return(0);
|
return(0);
|
||||||
return(man_body_alloc(man, line, offs, man->last->tok));
|
return(man_body_alloc(man, line, offs, man->last->tok));
|
||||||
}
|
}
|
||||||
@ -458,7 +436,8 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
|
|
||||||
if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
|
if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
|
||||||
if (i > 1 && '\\' != buf[i - 2])
|
if (i > 1 && '\\' != buf[i - 2])
|
||||||
man_pmsg(man, line, i - 1, MANDOCERR_EOLNSPACE);
|
mandoc_msg(MANDOCERR_SPACE_EOL, man->parse,
|
||||||
|
line, i - 1, NULL);
|
||||||
|
|
||||||
for (--i; i && ' ' == buf[i]; i--)
|
for (--i; i && ' ' == buf[i]; i--)
|
||||||
/* Spin back to non-space. */ ;
|
/* Spin back to non-space. */ ;
|
||||||
@ -479,7 +458,7 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
assert(i);
|
assert(i);
|
||||||
if (mandoc_eos(buf, (size_t)i, 0))
|
if (mandoc_eos(buf, (size_t)i))
|
||||||
man->last->flags |= MAN_EOS;
|
man->last->flags |= MAN_EOS;
|
||||||
|
|
||||||
return(man_descope(man, line, offs));
|
return(man_descope(man, line, offs));
|
||||||
@ -488,13 +467,15 @@ man_ptext(struct man *man, int line, char *buf, int offs)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
int i, ppos;
|
|
||||||
enum mant tok;
|
|
||||||
char mac[5];
|
char mac[5];
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
enum mant tok;
|
||||||
|
int i, ppos;
|
||||||
|
int bline;
|
||||||
|
|
||||||
if ('"' == buf[offs]) {
|
if ('"' == buf[offs]) {
|
||||||
man_pmsg(man, ln, offs, MANDOCERR_BADCOMMENT);
|
mandoc_msg(MANDOCERR_COMMENT_BAD, man->parse,
|
||||||
|
ln, offs, NULL);
|
||||||
return(1);
|
return(1);
|
||||||
} else if ('\0' == buf[offs])
|
} else if ('\0' == buf[offs])
|
||||||
return(1);
|
return(1);
|
||||||
@ -507,8 +488,8 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < 4 && '\0' != buf[offs] &&
|
while (i < 4 && '\0' != buf[offs] && ' ' != buf[offs] &&
|
||||||
' ' != buf[offs] && '\t' != buf[offs])
|
'\t' != buf[offs])
|
||||||
mac[i++] = buf[offs++];
|
mac[i++] = buf[offs++];
|
||||||
|
|
||||||
mac[i] = '\0';
|
mac[i] = '\0';
|
||||||
@ -516,8 +497,8 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
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 (MAN_MAX == tok) {
|
||||||
mandoc_vmsg(MANDOCERR_MACRO, man->parse, ln,
|
mandoc_msg(MANDOCERR_MACRO, man->parse,
|
||||||
ppos, "%s", buf + ppos - 1);
|
ln, ppos, buf + ppos - 1);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +513,8 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||||
man_pmsg(man, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
mandoc_msg(MANDOCERR_SPACE_EOL, man->parse,
|
||||||
|
ln, offs - 1, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove prior ELINE macro, as it's being clobbered by a new
|
* Remove prior ELINE macro, as it's being clobbered by a new
|
||||||
@ -550,7 +532,7 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
if (MAN_NSCOPED & man_macros[n->tok].flags)
|
if (MAN_NSCOPED & man_macros[n->tok].flags)
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
|
|
||||||
mandoc_vmsg(MANDOCERR_LINESCOPE, 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],
|
||||||
man_macronames[n->tok]);
|
man_macronames[n->tok]);
|
||||||
|
|
||||||
@ -581,7 +563,7 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
assert(MAN_BLOCK == n->type);
|
assert(MAN_BLOCK == n->type);
|
||||||
assert(MAN_SCOPED & man_macros[n->tok].flags);
|
assert(MAN_SCOPED & man_macros[n->tok].flags);
|
||||||
|
|
||||||
mandoc_vmsg(MANDOCERR_LINESCOPE, 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],
|
||||||
man_macronames[n->tok]);
|
man_macronames[n->tok]);
|
||||||
|
|
||||||
@ -589,63 +571,41 @@ man_pmacro(struct man *man, int ln, char *buf, int offs)
|
|||||||
man->flags &= ~MAN_BLINE;
|
man->flags &= ~MAN_BLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Remember whether we are in next-line scope for a block head. */
|
||||||
* Save the fact that we're in the next-line for a block. In
|
|
||||||
* this way, embedded roff instructions can "remember" state
|
|
||||||
* when they exit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (MAN_BLINE & man->flags)
|
bline = man->flags & MAN_BLINE;
|
||||||
man->flags |= MAN_BPLINE;
|
|
||||||
|
|
||||||
/* 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))
|
if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf))
|
||||||
goto err;
|
return(0);
|
||||||
|
|
||||||
/*
|
/* In quick mode (for mandocdb), abort after the NAME section. */
|
||||||
* We weren't in a block-line scope when entering the
|
|
||||||
* above-parsed macro, so return.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( ! (MAN_BPLINE & man->flags)) {
|
if (man->quick && MAN_SH == tok) {
|
||||||
man->flags &= ~MAN_ILINE;
|
n = man->last;
|
||||||
return(1);
|
if (MAN_BODY == n->type &&
|
||||||
}
|
strcmp(n->prev->child->string, "NAME"))
|
||||||
man->flags &= ~MAN_BPLINE;
|
return(2);
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're in a block scope, then allow this macro to slip by
|
|
||||||
* without closing scope around it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (MAN_ILINE & man->flags) {
|
|
||||||
man->flags &= ~MAN_ILINE;
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we've opened a new next-line element scope, then return
|
* If we are in a next-line scope for a block head,
|
||||||
* now, as the next line will close out the block scope.
|
* close it out now and switch to the body,
|
||||||
|
* unless the next-line scope is allowed to continue.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (MAN_ELINE & man->flags)
|
if ( ! bline || man->flags & MAN_ELINE ||
|
||||||
|
man_macros[tok].flags & MAN_NSCOPED)
|
||||||
return(1);
|
return(1);
|
||||||
|
|
||||||
/* Close out the block scope opened in the prior line. */
|
|
||||||
|
|
||||||
assert(MAN_BLINE & man->flags);
|
assert(MAN_BLINE & man->flags);
|
||||||
man->flags &= ~MAN_BLINE;
|
man->flags &= ~MAN_BLINE;
|
||||||
|
|
||||||
if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
|
if ( ! man_unscope(man, man->last->parent))
|
||||||
return(0);
|
return(0);
|
||||||
return(man_body_alloc(man, ln, ppos, man->last->tok));
|
return(man_body_alloc(man, ln, ppos, man->last->tok));
|
||||||
|
|
||||||
err: /* Error out. */
|
|
||||||
|
|
||||||
man->flags |= MAN_HALT;
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -696,3 +656,49 @@ man_mparse(const struct man *man)
|
|||||||
assert(man && man->parse);
|
assert(man && man->parse);
|
||||||
return(man->parse);
|
return(man->parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
man_deroff(char **dest, const struct man_node *n)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
|
if (MAN_TEXT != n->type) {
|
||||||
|
for (n = n->child; n; n = n->next)
|
||||||
|
man_deroff(dest, n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip leading whitespace and escape sequences. */
|
||||||
|
|
||||||
|
cp = n->string;
|
||||||
|
while ('\0' != *cp) {
|
||||||
|
if ('\\' == *cp) {
|
||||||
|
cp++;
|
||||||
|
mandoc_escape((const char **)&cp, NULL, NULL);
|
||||||
|
} else if (isspace((unsigned char)*cp))
|
||||||
|
cp++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip trailing whitespace. */
|
||||||
|
|
||||||
|
for (sz = strlen(cp); sz; sz--)
|
||||||
|
if (0 == isspace((unsigned char)cp[sz-1]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Skip empty strings. */
|
||||||
|
|
||||||
|
if (0 == sz)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (NULL == *dest) {
|
||||||
|
*dest = mandoc_strndup(cp, sz);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp);
|
||||||
|
free(*dest);
|
||||||
|
*dest = cp;
|
||||||
|
}
|
||||||
|
409
contrib/mdocml/man.cgi.8
Normal file
409
contrib/mdocml/man.cgi.8
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
.\" $Id: man.cgi.8,v 1.9 2014/07/22 18:14:13 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: July 22 2014 $
|
||||||
|
.Dt MAN.CGI 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm man.cgi
|
||||||
|
.Nd CGI program to search and display manual pages
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
CGI program searches for manual pages on a WWW server
|
||||||
|
and displays them to HTTP clients,
|
||||||
|
providing functionality equivalent to the
|
||||||
|
.Xr apropos 1
|
||||||
|
and
|
||||||
|
.Xr man 1
|
||||||
|
utilities.
|
||||||
|
It can use multiple manual trees in parallel.
|
||||||
|
.Ss HTML search interface
|
||||||
|
At the top of each generated HTML page,
|
||||||
|
.Nm
|
||||||
|
displays a search form containing these elements:
|
||||||
|
.Bl -enum
|
||||||
|
.It
|
||||||
|
An input box for search queries, expecting
|
||||||
|
either a name of a manual page or an
|
||||||
|
.Ar expression
|
||||||
|
using the syntax described in the
|
||||||
|
.Xr apropos 1
|
||||||
|
manual; filling this in is required for each search.
|
||||||
|
.It
|
||||||
|
A
|
||||||
|
.Dq Submit
|
||||||
|
button to send a search request from the client to the server.
|
||||||
|
.It
|
||||||
|
A
|
||||||
|
.Dq Reset
|
||||||
|
button to undo any changes to the input boxes and the dropdown menus
|
||||||
|
and reset them to the values contained in the
|
||||||
|
.Ev QUERY_STRING .
|
||||||
|
.It
|
||||||
|
Radio buttons to select pages either by name like in
|
||||||
|
.Xr man 1
|
||||||
|
or using
|
||||||
|
.Xr apropos 1
|
||||||
|
queries.
|
||||||
|
.It
|
||||||
|
A dropdown menu to optionally select a manual section.
|
||||||
|
If one is provided, it has the same effect as the
|
||||||
|
.Xr man 1
|
||||||
|
and
|
||||||
|
.Xr apropos 1
|
||||||
|
.Fl s
|
||||||
|
option.
|
||||||
|
Otherwise, pages from all sections are shown.
|
||||||
|
.It
|
||||||
|
A dropdown menu to optionally select an architecture.
|
||||||
|
If one is provided, it has the same effect as the
|
||||||
|
.Xr man 1
|
||||||
|
and
|
||||||
|
.Xr apropos 1
|
||||||
|
.Fl S
|
||||||
|
option.
|
||||||
|
By default, pages for all architectures are shown.
|
||||||
|
.It
|
||||||
|
A dropdown menu to select a manual tree.
|
||||||
|
If the configuration file
|
||||||
|
.Pa /var/www/man/manpath.conf
|
||||||
|
contains only one manpath, the dropdown menu is not shown.
|
||||||
|
By default, the first manpath given in the file is used.
|
||||||
|
.El
|
||||||
|
.Ss Program output
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
program generates five kinds of output pages:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It The index page.
|
||||||
|
This is returned when calling
|
||||||
|
.Nm
|
||||||
|
without
|
||||||
|
.Ev PATH_INFO
|
||||||
|
and without a
|
||||||
|
.Ev QUERY_STRING .
|
||||||
|
It serves as a starting point for using the program
|
||||||
|
and shows the search form only.
|
||||||
|
.It A list page.
|
||||||
|
Lists are returned when searches match more than one manual page.
|
||||||
|
The first column shows the names and section numbers of manuals
|
||||||
|
as clickable links.
|
||||||
|
The second column shows the one-line descriptions of the manuals.
|
||||||
|
.It A manual page.
|
||||||
|
This output format is used when a search matches exactly one
|
||||||
|
manual page, or when a link on a list page or an
|
||||||
|
.Ic \&Xr
|
||||||
|
link on another manual page is followed.
|
||||||
|
.It A no-result page.
|
||||||
|
This is shown when a search request returns no results -
|
||||||
|
eiher because it violates the query syntax, or because
|
||||||
|
the search does not match any manual pages.
|
||||||
|
.It \&An error page.
|
||||||
|
This cannot happen by merely clicking the
|
||||||
|
.Dq Search
|
||||||
|
button, but only by manually entering an invalid URI.
|
||||||
|
It does not show the search form, but only an error message
|
||||||
|
and a link back to the index page.
|
||||||
|
.El
|
||||||
|
.Ss Setup
|
||||||
|
For each manual tree, create one first-level subdirectory below
|
||||||
|
.Pa /var/www/man .
|
||||||
|
The name of one of these directories is called a
|
||||||
|
.Dq manpath
|
||||||
|
in the context of
|
||||||
|
.Nm .
|
||||||
|
Create a single ASCII text file
|
||||||
|
.Pa /var/www/man/manpath.conf
|
||||||
|
containing the names of these directories, one per line.
|
||||||
|
The directory given first is used as the default manpath.
|
||||||
|
.Pp
|
||||||
|
Inside each of these directories, use the same directory and file
|
||||||
|
structure as found below
|
||||||
|
.Pa /usr/share/man ,
|
||||||
|
that is, second-level subdirectories
|
||||||
|
.Pa /var/www/man/*/man1 , /var/www/man/*/man2
|
||||||
|
etc. containing source
|
||||||
|
.Xr mdoc 7
|
||||||
|
and
|
||||||
|
.Xr man 7
|
||||||
|
manuals with file name extensions matching the section numbers,
|
||||||
|
second-level subdirectories
|
||||||
|
.Pa /var/www/man/*/cat1 , /var/www/man/*/cat2
|
||||||
|
etc. containing preformatted manuals with the file name extension
|
||||||
|
.Sq 0 ,
|
||||||
|
and optional third-level subdirectories for architectures.
|
||||||
|
Use
|
||||||
|
.Xr makewhatis 8
|
||||||
|
to create a
|
||||||
|
.Xr mandoc.db 5
|
||||||
|
database inside each manpath.
|
||||||
|
.Pp
|
||||||
|
Configure your web server to execute CGI programs located in
|
||||||
|
.Pa /cgi-bin .
|
||||||
|
When using
|
||||||
|
.Xr nginx 8 ,
|
||||||
|
the
|
||||||
|
.Xr slowcgi 8
|
||||||
|
proxy daemon is needed to translate FastCGI requests to plain old CGI.
|
||||||
|
.Pp
|
||||||
|
To compile
|
||||||
|
.Nm ,
|
||||||
|
first copy
|
||||||
|
.Pa cgi.h.example
|
||||||
|
to
|
||||||
|
.Pa cgi.h
|
||||||
|
and edit it according to your needs.
|
||||||
|
It contains the following compile-time definitions:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ev COMPAT_OLDURI
|
||||||
|
Only useful for running on www.openbsd.org to deal with old URIs containing
|
||||||
|
.Qq "manpath=OpenBSD "
|
||||||
|
where the blank character has to be translated to a hyphen.
|
||||||
|
When compiling for other sites, this definition can be deleted.
|
||||||
|
.It Ev CSS_DIR
|
||||||
|
An optional path to the directory containing the CSS files,
|
||||||
|
to be specified relative to the server's document root,
|
||||||
|
and to be specified without a trailing slash.
|
||||||
|
When not specified, the CSS files
|
||||||
|
are assumed to be in the document root.
|
||||||
|
This is used in generated HTML code.
|
||||||
|
.It Ev CUSTOMIZE_BEGIN
|
||||||
|
A HTML string to be inserted right after opening the
|
||||||
|
.Aq BODY
|
||||||
|
element.
|
||||||
|
.It Ev CUSTOMIZE_TITLE
|
||||||
|
An ASCII string to be used for the HTML
|
||||||
|
.Aq TITLE
|
||||||
|
element.
|
||||||
|
.It Ev HTTP_HOST
|
||||||
|
The FQDN of the (possibly virtual) host the HTTP server is running on.
|
||||||
|
This is used for
|
||||||
|
.Ic Location:
|
||||||
|
headers in HTTP 303 responses.
|
||||||
|
.It Ev MAN_DIR
|
||||||
|
A path to the
|
||||||
|
.Nm
|
||||||
|
data directory to be used instead of
|
||||||
|
.Pa /var/www/man ,
|
||||||
|
relative to the web server
|
||||||
|
.Xr chroot 2
|
||||||
|
directory, to be specified without a trailing slash.
|
||||||
|
This is prepended to the manpath when opening
|
||||||
|
.Xr mandoc.db 5
|
||||||
|
and manual page files.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
After editing
|
||||||
|
.Pa cgi.h ,
|
||||||
|
run
|
||||||
|
.Pp
|
||||||
|
.Dl make man.cgi
|
||||||
|
.Pp
|
||||||
|
and copy the files to the proper locations.
|
||||||
|
Reading the
|
||||||
|
.Cm installcgi
|
||||||
|
target in the
|
||||||
|
.Pa Makefile
|
||||||
|
can help with that, but do not run it without carefully checking it
|
||||||
|
because the directory layouts of web servers vary greatly.
|
||||||
|
.Ss URI interface
|
||||||
|
.Nm
|
||||||
|
uniform resource identifiers are not needed for interactive use,
|
||||||
|
but can be useful for deep linking.
|
||||||
|
They consist of:
|
||||||
|
.Bl -enum
|
||||||
|
.It
|
||||||
|
The
|
||||||
|
.Cm http://
|
||||||
|
protocol specifier.
|
||||||
|
.It
|
||||||
|
The host name and a following slash.
|
||||||
|
.It
|
||||||
|
The path to the program, normally
|
||||||
|
.Pa cgi-bin/man.cgi/ .
|
||||||
|
.It
|
||||||
|
To show a single page, a slash, the manpath, another slash,
|
||||||
|
and the name of the requested file, for example
|
||||||
|
.Pa /OpenBSD-current/man1/mandoc.1 .
|
||||||
|
.It
|
||||||
|
For searches, a query string starting with a question mark
|
||||||
|
and consisting of
|
||||||
|
.Ar key Ns = Ns Ar value
|
||||||
|
pairs, separated by ampersands, for example
|
||||||
|
.Pa ?manpath=OpenBSD-current&query=mandoc .
|
||||||
|
Supported keys are
|
||||||
|
.Cm manpath ,
|
||||||
|
.Cm query ,
|
||||||
|
.Cm sec ,
|
||||||
|
.Cm arch ,
|
||||||
|
corresponding to
|
||||||
|
.Xr apropos 1
|
||||||
|
.Fl M ,
|
||||||
|
.Ar expression ,
|
||||||
|
.Fl s ,
|
||||||
|
.Fl S ,
|
||||||
|
respectively, and
|
||||||
|
.Cm apropos ,
|
||||||
|
which is a boolean parameter to select or deselect the
|
||||||
|
.Xr apropos 1
|
||||||
|
query mode.
|
||||||
|
For backward compatibility with the traditional
|
||||||
|
.Nm ,
|
||||||
|
.Cm sektion
|
||||||
|
is supported as an alias for
|
||||||
|
.Cm sec .
|
||||||
|
.El
|
||||||
|
.Ss Restricted character set
|
||||||
|
For security reasons, in particular to prevent cross site scripting
|
||||||
|
attacks, some strings used by
|
||||||
|
.Nm
|
||||||
|
can only contain the following characters:
|
||||||
|
.Pp
|
||||||
|
.Bl -dash -compact -offset indent
|
||||||
|
.It
|
||||||
|
lower case and upper case ASCII letters
|
||||||
|
.It
|
||||||
|
the ten decimal digits
|
||||||
|
.It
|
||||||
|
the dash
|
||||||
|
.Pq Sq -
|
||||||
|
.It
|
||||||
|
the dot
|
||||||
|
.Pq Sq \&.
|
||||||
|
.It
|
||||||
|
the slash
|
||||||
|
.Pq Sq /
|
||||||
|
.It
|
||||||
|
the underscore
|
||||||
|
.Pq Sq _
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
In particular, this applies to the
|
||||||
|
.Ev SCRIPT_NAME ,
|
||||||
|
to all manpaths, and to all architecture names.
|
||||||
|
.Sh ENVIRONMENT
|
||||||
|
The web server may pass the following CGI variables to
|
||||||
|
.Nm :
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ev PATH_INFO
|
||||||
|
The final part of the URI path passed from the client to the server,
|
||||||
|
starting after the
|
||||||
|
.Ev SCRIPT_NAME
|
||||||
|
and ending before the
|
||||||
|
.Ev QUERY_STRING .
|
||||||
|
It is used by the
|
||||||
|
.Cm show
|
||||||
|
page to aquire the manpath and filename it needs.
|
||||||
|
.It Ev QUERY_STRING
|
||||||
|
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 used by the
|
||||||
|
.Cm search
|
||||||
|
page to acquire the named parameters it needs.
|
||||||
|
.It Ev SCRIPT_NAME
|
||||||
|
The path to the
|
||||||
|
.Nm
|
||||||
|
binary relative to the server root, usually
|
||||||
|
.Pa /cgi-bin/man.cgi .
|
||||||
|
This is used for generating URIs to be embedded
|
||||||
|
in generated HTML code and HTTP headers.
|
||||||
|
If this contains any character not contained in the
|
||||||
|
.Sx Restricted character set ,
|
||||||
|
.Nm
|
||||||
|
reports an internal server error and exits without doing anything.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Pa /var/www
|
||||||
|
Default web server
|
||||||
|
.Xr chroot 2
|
||||||
|
directory.
|
||||||
|
All the following paths are specified relative to this directory.
|
||||||
|
.It Pa /cgi-bin/man.cgi
|
||||||
|
The path to the
|
||||||
|
.Nm
|
||||||
|
program relative to the server root.
|
||||||
|
Can be overridden by
|
||||||
|
.Ev SCRIPT_NAME .
|
||||||
|
.It Pa /htdocs
|
||||||
|
The path to the server document root relative to the server root.
|
||||||
|
This is part of the web server configuration and not specific to
|
||||||
|
.Nm .
|
||||||
|
.It Pa /htdocs/man-cgi.css
|
||||||
|
A style sheet for general
|
||||||
|
.Nm
|
||||||
|
styling, referenced from each generated HTML page.
|
||||||
|
.It Pa /htdocs/man.css
|
||||||
|
A style sheet for
|
||||||
|
.Xr mandoc 1
|
||||||
|
HTML styling, referenced from each generated HTML page after
|
||||||
|
.Pa man-cgi.css .
|
||||||
|
.It Pa /man
|
||||||
|
Default
|
||||||
|
.Nm
|
||||||
|
data directory containing all the manual trees.
|
||||||
|
Can be overridden by
|
||||||
|
.Ev MAN_DIR .
|
||||||
|
.It Pa /man/mandoc/man1/apropos.1 , /man/mandoc/man8/man.cgi.8
|
||||||
|
Manual pages documenting
|
||||||
|
.Nm
|
||||||
|
itself, linked from the index page.
|
||||||
|
.It Pa /man/manpath.conf
|
||||||
|
The list of available manpaths, one per line.
|
||||||
|
If any of the lines in this file contains a slash
|
||||||
|
.Pq Sq /
|
||||||
|
or any character not contained in the
|
||||||
|
.Sx Restricted character set ,
|
||||||
|
.Nm
|
||||||
|
reports an internal server error and exits without doing anything.
|
||||||
|
.It Pa /man/OpenBSD-current/man1/mandoc.1
|
||||||
|
An example
|
||||||
|
.Xr mdoc 7
|
||||||
|
source file located below the
|
||||||
|
.Dq OpenBSD-current
|
||||||
|
manpath.
|
||||||
|
.El
|
||||||
|
.Sh COMPATIBILITY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
CGI program is call-compatible with queries from the traditional
|
||||||
|
.Pa man.cgi
|
||||||
|
script by Wolfram Schneider.
|
||||||
|
However, the output may not be quite the same.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
.Xr mandoc.db 5 ,
|
||||||
|
.Xr makewhatis 8 ,
|
||||||
|
.Xr slowcgi 8
|
||||||
|
.Sh HISTORY
|
||||||
|
A version of
|
||||||
|
.Nm
|
||||||
|
based on
|
||||||
|
.Xr mandoc 1
|
||||||
|
first appeared in mdocml-1.12.1 (March 2012).
|
||||||
|
The current SQLite3-based version first appeared in
|
||||||
|
.Ox 5.6 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
program was written by
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
and ported to the SQLite3-based
|
||||||
|
.Xr mandoc.db 5
|
||||||
|
backend by
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
@ -1,6 +1,7 @@
|
|||||||
/* $Id: man.h,v 1.62 2013/10/17 20:54:58 schwarze Exp $ */
|
/* $Id: man.h,v 1.65 2014/06/20 23:02:31 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
|
||||||
@ -56,6 +57,7 @@ enum mant {
|
|||||||
MAN_EE,
|
MAN_EE,
|
||||||
MAN_UR,
|
MAN_UR,
|
||||||
MAN_UE,
|
MAN_UE,
|
||||||
|
MAN_ll,
|
||||||
MAN_MAX
|
MAN_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,6 +79,7 @@ struct man_meta {
|
|||||||
char *vol; /* `TH' volume */
|
char *vol; /* `TH' volume */
|
||||||
char *title; /* `TH' title (e.g., FOO) */
|
char *title; /* `TH' title (e.g., FOO) */
|
||||||
char *source; /* `TH' source (e.g., GNU) */
|
char *source; /* `TH' source (e.g., GNU) */
|
||||||
|
int hasbody; /* document is not empty */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct man_node {
|
struct man_node {
|
||||||
@ -111,6 +114,7 @@ struct man;
|
|||||||
const struct man_node *man_node(const struct man *);
|
const struct man_node *man_node(const struct man *);
|
||||||
const struct man_meta *man_meta(const struct man *);
|
const struct man_meta *man_meta(const struct man *);
|
||||||
const struct mparse *man_mparse(const struct man *);
|
const struct mparse *man_mparse(const struct man *);
|
||||||
|
void man_deroff(char **, const struct man_node *);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man_hash.c,v 1.25 2011/07/24 18:15:14 kristaps Exp $ */
|
/* $Id: man_hash.c,v 1.27 2014/04/20 16:46:04 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -23,7 +23,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
@ -49,6 +48,7 @@
|
|||||||
*/
|
*/
|
||||||
static unsigned char table[26 * HASH_DEPTH];
|
static unsigned char table[26 * HASH_DEPTH];
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX - this hash has global scope, so if intended for use as a library
|
* XXX - this hash has global scope, so if intended for use as a library
|
||||||
* with multiple callers, it will need re-invocation protection.
|
* with multiple callers, it will need re-invocation protection.
|
||||||
@ -60,8 +60,7 @@ man_hash_init(void)
|
|||||||
|
|
||||||
memset(table, UCHAR_MAX, sizeof(table));
|
memset(table, UCHAR_MAX, sizeof(table));
|
||||||
|
|
||||||
assert(/* LINTED */
|
assert(MAN_MAX < UCHAR_MAX);
|
||||||
MAN_MAX < UCHAR_MAX);
|
|
||||||
|
|
||||||
for (i = 0; i < (int)MAN_MAX; i++) {
|
for (i = 0; i < (int)MAN_MAX; i++) {
|
||||||
x = man_macronames[i][0];
|
x = man_macronames[i][0];
|
||||||
@ -80,7 +79,6 @@ man_hash_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum mant
|
enum mant
|
||||||
man_hash_find(const char *tmp)
|
man_hash_find(const char *tmp)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: man_html.c,v 1.90 2013/10/17 20:54:58 schwarze Exp $ */
|
/* $Id: man_html.c,v 1.96 2014/08/01 19:25:52 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2012 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
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "html.h"
|
#include "html.h"
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
@ -119,8 +120,10 @@ static const struct htmlman mans[MAN_MAX] = {
|
|||||||
{ man_literal_pre, NULL }, /* EE */
|
{ man_literal_pre, NULL }, /* EE */
|
||||||
{ man_UR_pre, NULL }, /* UR */
|
{ man_UR_pre, NULL }, /* UR */
|
||||||
{ NULL, NULL }, /* UE */
|
{ NULL, NULL }, /* UE */
|
||||||
|
{ man_ign_pre, NULL }, /* ll */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Printing leading vertical space before a block.
|
* Printing leading vertical space before a block.
|
||||||
* This is used for the paragraph macros.
|
* This is used for the paragraph macros.
|
||||||
@ -177,8 +180,6 @@ print_man(MAN_ARGS)
|
|||||||
print_tagq(h, t);
|
print_tagq(h, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
print_man_head(MAN_ARGS)
|
print_man_head(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -191,7 +192,6 @@ print_man_head(MAN_ARGS)
|
|||||||
print_text(h, h->buf);
|
print_text(h, h->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_man_nodelist(MAN_ARGS)
|
print_man_nodelist(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -201,7 +201,6 @@ print_man_nodelist(MAN_ARGS)
|
|||||||
print_man_nodelist(man, n->next, mh, h);
|
print_man_nodelist(man, n->next, mh, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_man_node(MAN_ARGS)
|
print_man_node(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -212,10 +211,10 @@ print_man_node(MAN_ARGS)
|
|||||||
t = h->tags.head;
|
t = h->tags.head;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_ROOT):
|
case MAN_ROOT:
|
||||||
man_root_pre(man, n, mh, h);
|
man_root_pre(man, n, mh, h);
|
||||||
break;
|
break;
|
||||||
case (MAN_TEXT):
|
case MAN_TEXT:
|
||||||
/*
|
/*
|
||||||
* If we have a blank line, output a vertical space.
|
* If we have a blank line, output a vertical space.
|
||||||
* If we have a space as the first character, break
|
* If we have a space as the first character, break
|
||||||
@ -233,10 +232,10 @@ print_man_node(MAN_ARGS)
|
|||||||
|
|
||||||
print_text(h, n->string);
|
print_text(h, n->string);
|
||||||
return;
|
return;
|
||||||
case (MAN_EQN):
|
case MAN_EQN:
|
||||||
print_eqn(h, n->eqn);
|
print_eqn(h, n->eqn);
|
||||||
break;
|
break;
|
||||||
case (MAN_TBL):
|
case MAN_TBL:
|
||||||
/*
|
/*
|
||||||
* This will take care of initialising all of the table
|
* This will take care of initialising all of the table
|
||||||
* state data for the first table, then tearing it down
|
* state data for the first table, then tearing it down
|
||||||
@ -275,10 +274,10 @@ print_man_node(MAN_ARGS)
|
|||||||
print_stagq(h, t);
|
print_stagq(h, t);
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_ROOT):
|
case MAN_ROOT:
|
||||||
man_root_post(man, n, mh, h);
|
man_root_post(man, n, mh, h);
|
||||||
break;
|
break;
|
||||||
case (MAN_EQN):
|
case MAN_EQN:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (mans[n->tok].post)
|
if (mans[n->tok].post)
|
||||||
@ -287,7 +286,6 @@ print_man_node(MAN_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
a2width(const struct man_node *n, struct roffsu *su)
|
a2width(const struct man_node *n, struct roffsu *su)
|
||||||
{
|
{
|
||||||
@ -300,22 +298,16 @@ a2width(const struct man_node *n, struct roffsu *su)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
man_root_pre(MAN_ARGS)
|
man_root_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
struct htmlpair tag[3];
|
struct htmlpair tag[3];
|
||||||
struct tag *t, *tt;
|
struct tag *t, *tt;
|
||||||
char b[BUFSIZ], title[BUFSIZ];
|
char *title;
|
||||||
|
|
||||||
b[0] = 0;
|
|
||||||
if (man->vol)
|
|
||||||
(void)strlcat(b, man->vol, BUFSIZ);
|
|
||||||
|
|
||||||
assert(man->title);
|
assert(man->title);
|
||||||
assert(man->msec);
|
assert(man->msec);
|
||||||
snprintf(title, BUFSIZ - 1, "%s(%s)", man->title, man->msec);
|
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
|
||||||
|
|
||||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
||||||
PAIR_CLASS_INIT(&tag[1], "head");
|
PAIR_CLASS_INIT(&tag[1], "head");
|
||||||
@ -338,7 +330,8 @@ man_root_pre(MAN_ARGS)
|
|||||||
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
||||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
||||||
print_otag(h, TAG_TD, 2, tag);
|
print_otag(h, TAG_TD, 2, tag);
|
||||||
print_text(h, b);
|
if (NULL != 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[0], "head-rtitle");
|
||||||
@ -346,10 +339,9 @@ man_root_pre(MAN_ARGS)
|
|||||||
print_otag(h, TAG_TD, 2, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
man_root_post(MAN_ARGS)
|
man_root_post(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -383,7 +375,6 @@ man_root_post(MAN_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_br_pre(MAN_ARGS)
|
man_br_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -397,7 +388,7 @@ man_br_pre(MAN_ARGS)
|
|||||||
if ( ! a2roffsu(n->string, &su, SCALE_VS))
|
if ( ! a2roffsu(n->string, &su, SCALE_VS))
|
||||||
SCALE_VS_INIT(&su, atoi(n->string));
|
SCALE_VS_INIT(&su, atoi(n->string));
|
||||||
} else
|
} else
|
||||||
su.scale = 0;
|
su.scale = 0.0;
|
||||||
|
|
||||||
bufinit(h);
|
bufinit(h);
|
||||||
bufcat_su(h, "height", &su);
|
bufcat_su(h, "height", &su);
|
||||||
@ -410,7 +401,6 @@ man_br_pre(MAN_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_SH_pre(MAN_ARGS)
|
man_SH_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -428,7 +418,6 @@ man_SH_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_alt_pre(MAN_ARGS)
|
man_alt_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -445,22 +434,22 @@ man_alt_pre(MAN_ARGS)
|
|||||||
for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
|
for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
|
||||||
t = NULL;
|
t = NULL;
|
||||||
switch (n->tok) {
|
switch (n->tok) {
|
||||||
case (MAN_BI):
|
case MAN_BI:
|
||||||
fp = i % 2 ? TAG_I : TAG_B;
|
fp = i % 2 ? TAG_I : TAG_B;
|
||||||
break;
|
break;
|
||||||
case (MAN_IB):
|
case MAN_IB:
|
||||||
fp = i % 2 ? TAG_B : TAG_I;
|
fp = i % 2 ? TAG_B : TAG_I;
|
||||||
break;
|
break;
|
||||||
case (MAN_RI):
|
case MAN_RI:
|
||||||
fp = i % 2 ? TAG_I : TAG_MAX;
|
fp = i % 2 ? TAG_I : TAG_MAX;
|
||||||
break;
|
break;
|
||||||
case (MAN_IR):
|
case MAN_IR:
|
||||||
fp = i % 2 ? TAG_MAX : TAG_I;
|
fp = i % 2 ? TAG_MAX : TAG_I;
|
||||||
break;
|
break;
|
||||||
case (MAN_BR):
|
case MAN_BR:
|
||||||
fp = i % 2 ? TAG_MAX : TAG_B;
|
fp = i % 2 ? TAG_MAX : TAG_B;
|
||||||
break;
|
break;
|
||||||
case (MAN_RB):
|
case MAN_RB:
|
||||||
fp = i % 2 ? TAG_B : TAG_MAX;
|
fp = i % 2 ? TAG_B : TAG_MAX;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -486,7 +475,6 @@ man_alt_pre(MAN_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_SM_pre(MAN_ARGS)
|
man_SM_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -497,7 +485,6 @@ man_SM_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_SS_pre(MAN_ARGS)
|
man_SS_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -515,7 +502,6 @@ man_SS_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_PP_pre(MAN_ARGS)
|
man_PP_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -528,7 +514,6 @@ man_PP_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_IP_pre(MAN_ARGS)
|
man_IP_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -553,15 +538,19 @@ man_IP_pre(MAN_ARGS)
|
|||||||
|
|
||||||
/* For TP, only print next-line header elements. */
|
/* For TP, only print next-line header elements. */
|
||||||
|
|
||||||
if (MAN_TP == n->tok)
|
if (MAN_TP == n->tok) {
|
||||||
for (nn = n->child; nn; nn = nn->next)
|
nn = n->child;
|
||||||
if (nn->line > n->line)
|
while (NULL != nn && 0 == (MAN_LINE & nn->flags))
|
||||||
|
nn = nn->next;
|
||||||
|
while (NULL != nn) {
|
||||||
print_man_node(man, nn, mh, h);
|
print_man_node(man, nn, mh, h);
|
||||||
|
nn = nn->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_HP_pre(MAN_ARGS)
|
man_HP_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -590,7 +579,6 @@ man_HP_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_OP_pre(MAN_ARGS)
|
man_OP_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -620,8 +608,6 @@ man_OP_pre(MAN_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_B_pre(MAN_ARGS)
|
man_B_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -630,7 +616,6 @@ man_B_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_I_pre(MAN_ARGS)
|
man_I_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -639,7 +624,6 @@ man_I_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_literal_pre(MAN_ARGS)
|
man_literal_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -653,7 +637,6 @@ man_literal_pre(MAN_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_in_pre(MAN_ARGS)
|
man_in_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -662,7 +645,6 @@ man_in_pre(MAN_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_ign_pre(MAN_ARGS)
|
man_ign_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -670,7 +652,6 @@ man_ign_pre(MAN_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_RS_pre(MAN_ARGS)
|
man_RS_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
@ -693,7 +674,6 @@ man_RS_pre(MAN_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
man_UR_pre(MAN_ARGS)
|
man_UR_pre(MAN_ARGS)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: man_macro.c,v 1.79 2013/12/25 00:50:05 schwarze Exp $ */
|
/* $Id: man_macro.c,v 1.87 2014/07/30 23:01:39 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 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -49,8 +49,6 @@ static enum rew rew_dohalt(enum mant, enum man_type,
|
|||||||
const struct man_node *);
|
const struct man_node *);
|
||||||
static enum rew rew_block(enum mant, enum man_type,
|
static enum rew rew_block(enum mant, enum man_type,
|
||||||
const struct man_node *);
|
const struct man_node *);
|
||||||
static void rew_warn(struct man *,
|
|
||||||
struct man_node *, enum mandocerr);
|
|
||||||
|
|
||||||
const struct man_macro __man_macros[MAN_MAX] = {
|
const struct man_macro __man_macros[MAN_MAX] = {
|
||||||
{ in_line_eoln, MAN_NSCOPED }, /* br */
|
{ in_line_eoln, MAN_NSCOPED }, /* br */
|
||||||
@ -91,68 +89,64 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
|||||||
{ in_line_eoln, MAN_BSCOPE }, /* EE */
|
{ in_line_eoln, MAN_BSCOPE }, /* EE */
|
||||||
{ blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */
|
{ blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */
|
||||||
{ blk_close, 0 }, /* UE */
|
{ blk_close, 0 }, /* UE */
|
||||||
|
{ in_line_eoln, 0 }, /* ll */
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct man_macro * const man_macros = __man_macros;
|
const struct man_macro * const man_macros = __man_macros;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Warn when "n" is an explicit non-roff macro.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
rew_warn(struct man *man, struct man_node *n, enum mandocerr er)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (er == MANDOCERR_MAX || MAN_BLOCK != n->type)
|
|
||||||
return;
|
|
||||||
if (MAN_VALID & n->flags)
|
|
||||||
return;
|
|
||||||
if ( ! (MAN_EXPLICIT & man_macros[n->tok].flags))
|
|
||||||
return;
|
|
||||||
|
|
||||||
assert(er < MANDOCERR_FATAL);
|
|
||||||
man_nmsg(man, n, er);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Rewind scope. If a code "er" != MANDOCERR_MAX has been provided, it
|
|
||||||
* will be used if an explicit block scope is being closed out.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
man_unscope(struct man *man, const struct man_node *to,
|
man_unscope(struct man *man, const struct man_node *to)
|
||||||
enum mandocerr er)
|
|
||||||
{
|
{
|
||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
|
|
||||||
assert(to);
|
|
||||||
|
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
|
to = to->parent;
|
||||||
|
n = man->last;
|
||||||
|
while (n != to) {
|
||||||
|
|
||||||
/* LINTED */
|
/* Reached the end of the document? */
|
||||||
while (man->last != to) {
|
|
||||||
/*
|
if (to == NULL && ! (n->flags & MAN_VALID)) {
|
||||||
* Save the parent here, because we may delete the
|
if (man->flags & (MAN_BLINE | MAN_ELINE) &&
|
||||||
* man->last node in the post-validation phase and reset
|
man_macros[n->tok].flags & MAN_SCOPED) {
|
||||||
* it to man->last->parent, causing a step in the closing
|
mandoc_vmsg(MANDOCERR_BLK_LINE,
|
||||||
* out to be lost.
|
man->parse, n->line, n->pos,
|
||||||
*/
|
"EOF breaks %s",
|
||||||
n = man->last->parent;
|
man_macronames[n->tok]);
|
||||||
rew_warn(man, man->last, er);
|
if (man->flags & MAN_ELINE)
|
||||||
if ( ! man_valid_post(man))
|
man->flags &= ~MAN_ELINE;
|
||||||
return(0);
|
else {
|
||||||
|
assert(n->type == MAN_HEAD);
|
||||||
|
n = n->parent;
|
||||||
|
man->flags &= ~MAN_BLINE;
|
||||||
|
}
|
||||||
man->last = n;
|
man->last = n;
|
||||||
assert(man->last);
|
n = n->parent;
|
||||||
|
man_node_delete(man, man->last);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (n->type == MAN_BLOCK &&
|
||||||
|
man_macros[n->tok].flags & MAN_EXPLICIT)
|
||||||
|
mandoc_msg(MANDOCERR_BLK_NOEND,
|
||||||
|
man->parse, n->line, n->pos,
|
||||||
|
man_macronames[n->tok]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rew_warn(man, man->last, er);
|
/*
|
||||||
|
* We might delete the man->last node
|
||||||
|
* in the post-validation phase.
|
||||||
|
* Save a pointer to the parent such that
|
||||||
|
* we know where to continue the iteration.
|
||||||
|
*/
|
||||||
|
man->last = n;
|
||||||
|
n = n->parent;
|
||||||
if ( ! man_valid_post(man))
|
if ( ! man_valid_post(man))
|
||||||
return(0);
|
return(0);
|
||||||
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -163,7 +157,6 @@ rew_block(enum mant ntok, enum man_type type, const struct man_node *n)
|
|||||||
return(ntok == n->tok ? REW_HALT : REW_NOHALT);
|
return(ntok == n->tok ? REW_HALT : REW_NOHALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are three scope levels: scoped to the root (all), scoped to the
|
* There are three scope levels: scoped to the root (all), scoped to the
|
||||||
* section (all less sections), and scoped to subsections (all less
|
* section (all less sections), and scoped to subsections (all less
|
||||||
@ -202,14 +195,14 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MAN_SH):
|
case MAN_SH:
|
||||||
break;
|
break;
|
||||||
case (MAN_SS):
|
case MAN_SS:
|
||||||
/* Rewind to a section, if a block. */
|
/* Rewind to a section, if a block. */
|
||||||
if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
|
if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
|
||||||
return(c);
|
return(c);
|
||||||
break;
|
break;
|
||||||
case (MAN_RS):
|
case MAN_RS:
|
||||||
/* Preserve empty paragraphs before RS. */
|
/* Preserve empty paragraphs before RS. */
|
||||||
if (0 == n->nchild && (MAN_P == n->tok ||
|
if (0 == n->nchild && (MAN_P == n->tok ||
|
||||||
MAN_PP == n->tok || MAN_LP == n->tok))
|
MAN_PP == n->tok || MAN_LP == n->tok))
|
||||||
@ -237,7 +230,6 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
|||||||
return(REW_NOHALT);
|
return(REW_NOHALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rewinding entails ascending the parse tree until a coherent point,
|
* Rewinding entails ascending the parse tree until a coherent point,
|
||||||
* for example, the `SH' macro will close out any intervening `SS'
|
* for example, the `SH' macro will close out any intervening `SS'
|
||||||
@ -249,7 +241,6 @@ rew_scope(enum man_type type, struct man *man, enum mant tok)
|
|||||||
struct man_node *n;
|
struct man_node *n;
|
||||||
enum rew c;
|
enum rew c;
|
||||||
|
|
||||||
/* LINTED */
|
|
||||||
for (n = man->last; n; n = n->parent) {
|
for (n = man->last; n; n = n->parent) {
|
||||||
/*
|
/*
|
||||||
* Whether we should stop immediately (REW_HALT), stop
|
* Whether we should stop immediately (REW_HALT), stop
|
||||||
@ -269,14 +260,13 @@ rew_scope(enum man_type type, struct man *man, enum mant tok)
|
|||||||
*/
|
*/
|
||||||
assert(n);
|
assert(n);
|
||||||
|
|
||||||
return(man_unscope(man, n, MANDOCERR_MAX));
|
return(man_unscope(man, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close out a generic explicit macro.
|
* Close out a generic explicit macro.
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
blk_close(MACRO_PROT_ARGS)
|
blk_close(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -284,10 +274,10 @@ blk_close(MACRO_PROT_ARGS)
|
|||||||
const struct man_node *nn;
|
const struct man_node *nn;
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MAN_RE):
|
case MAN_RE:
|
||||||
ntok = MAN_RS;
|
ntok = MAN_RS;
|
||||||
break;
|
break;
|
||||||
case (MAN_UE):
|
case MAN_UE:
|
||||||
ntok = MAN_UR;
|
ntok = MAN_UR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -300,17 +290,16 @@ blk_close(MACRO_PROT_ARGS)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (NULL == nn) {
|
if (NULL == nn) {
|
||||||
man_pmsg(man, line, ppos, MANDOCERR_NOSCOPE);
|
mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse,
|
||||||
|
line, ppos, man_macronames[tok]);
|
||||||
if ( ! rew_scope(MAN_BLOCK, man, MAN_PP))
|
if ( ! rew_scope(MAN_BLOCK, man, MAN_PP))
|
||||||
return(0);
|
return(0);
|
||||||
} else
|
} else
|
||||||
man_unscope(man, nn, MANDOCERR_MAX);
|
man_unscope(man, nn);
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
blk_exp(MACRO_PROT_ARGS)
|
blk_exp(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -343,22 +332,19 @@ blk_exp(MACRO_PROT_ARGS)
|
|||||||
if (n->tok != tok)
|
if (n->tok != tok)
|
||||||
continue;
|
continue;
|
||||||
assert(MAN_HEAD == n->type);
|
assert(MAN_HEAD == n->type);
|
||||||
man_unscope(man, n, MANDOCERR_MAX);
|
man_unscope(man, n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(man_body_alloc(man, line, ppos, tok));
|
return(man_body_alloc(man, line, ppos, tok));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse an implicit-block macro. These contain a MAN_HEAD and a
|
* Parse an implicit-block macro. These contain a MAN_HEAD and a
|
||||||
* MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
|
* MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
blk_imp(MACRO_PROT_ARGS)
|
blk_imp(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -410,8 +396,6 @@ blk_imp(MACRO_PROT_ARGS)
|
|||||||
return(man_body_alloc(man, line, ppos, tok));
|
return(man_body_alloc(man, line, ppos, tok));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
in_line_eoln(MACRO_PROT_ARGS)
|
in_line_eoln(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -438,7 +422,7 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (n != man->last &&
|
if (n != man->last &&
|
||||||
mandoc_eos(man->last->string, strlen(man->last->string), 0))
|
mandoc_eos(man->last->string, strlen(man->last->string)))
|
||||||
man->last->flags |= MAN_EOS;
|
man->last->flags |= MAN_EOS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -453,13 +437,6 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set ignorable context, if applicable. */
|
|
||||||
|
|
||||||
if (MAN_NSCOPED & man_macros[tok].flags) {
|
|
||||||
assert( ! (MAN_SCOPED & man_macros[tok].flags));
|
|
||||||
man->flags |= MAN_ILINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(MAN_ROOT != man->last->type);
|
assert(MAN_ROOT != man->last->type);
|
||||||
man->next = MAN_NEXT_SIBLING;
|
man->next = MAN_NEXT_SIBLING;
|
||||||
|
|
||||||
@ -495,7 +472,7 @@ int
|
|||||||
man_macroend(struct man *man)
|
man_macroend(struct man *man)
|
||||||
{
|
{
|
||||||
|
|
||||||
return(man_unscope(man, man->first, MANDOCERR_SCOPEEXIT));
|
return(man_unscope(man, man->first));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: man_term.c,v 1.139 2013/12/22 23:34:13 schwarze Exp $ */
|
/* $Id: man_term.c,v 1.149 2014/06/20 23:02:31 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010, 2011, 2012, 2013 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
@ -84,6 +85,7 @@ static int pre_ft(DECL_ARGS);
|
|||||||
static int pre_ign(DECL_ARGS);
|
static int pre_ign(DECL_ARGS);
|
||||||
static int pre_in(DECL_ARGS);
|
static int pre_in(DECL_ARGS);
|
||||||
static int pre_literal(DECL_ARGS);
|
static int pre_literal(DECL_ARGS);
|
||||||
|
static int pre_ll(DECL_ARGS);
|
||||||
static int pre_sp(DECL_ARGS);
|
static int pre_sp(DECL_ARGS);
|
||||||
|
|
||||||
static void post_IP(DECL_ARGS);
|
static void post_IP(DECL_ARGS);
|
||||||
@ -133,10 +135,10 @@ static const struct termact termacts[MAN_MAX] = {
|
|||||||
{ pre_literal, NULL, 0 }, /* EE */
|
{ pre_literal, NULL, 0 }, /* EE */
|
||||||
{ pre_UR, post_UR, 0 }, /* UR */
|
{ pre_UR, post_UR, 0 }, /* UR */
|
||||||
{ NULL, NULL, 0 }, /* UE */
|
{ NULL, NULL, 0 }, /* UE */
|
||||||
|
{ pre_ll, NULL, MAN_NOTEXT }, /* ll */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
terminal_man(void *arg, const struct man *man)
|
terminal_man(void *arg, const struct man *man)
|
||||||
{
|
{
|
||||||
@ -187,7 +189,6 @@ a2height(const struct termp *p, const char *cp)
|
|||||||
return(term_vspan(p, &su));
|
return(term_vspan(p, &su));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
a2width(const struct termp *p, const char *cp)
|
a2width(const struct termp *p, const char *cp)
|
||||||
{
|
{
|
||||||
@ -226,7 +227,7 @@ print_bvspace(struct termp *p, const struct man_node *n, int pardist)
|
|||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_ign(DECL_ARGS)
|
pre_ign(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -234,8 +235,14 @@ pre_ign(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_ll(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
term_setwidth(p, n->nchild ? n->child->string : NULL);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_I(DECL_ARGS)
|
pre_I(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -244,8 +251,6 @@ pre_I(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_literal(DECL_ARGS)
|
pre_literal(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -266,14 +271,13 @@ pre_literal(DECL_ARGS)
|
|||||||
p->offset = p->rmargin;
|
p->offset = p->rmargin;
|
||||||
p->rmargin = p->maxrmargin;
|
p->rmargin = p->maxrmargin;
|
||||||
p->trailspace = 0;
|
p->trailspace = 0;
|
||||||
p->flags &= ~TERMP_NOBREAK;
|
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_PD(DECL_ARGS)
|
pre_PD(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -288,7 +292,6 @@ pre_PD(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_alternate(DECL_ARGS)
|
pre_alternate(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -297,27 +300,27 @@ pre_alternate(DECL_ARGS)
|
|||||||
int savelit, i;
|
int savelit, i;
|
||||||
|
|
||||||
switch (n->tok) {
|
switch (n->tok) {
|
||||||
case (MAN_RB):
|
case MAN_RB:
|
||||||
font[0] = TERMFONT_NONE;
|
font[0] = TERMFONT_NONE;
|
||||||
font[1] = TERMFONT_BOLD;
|
font[1] = TERMFONT_BOLD;
|
||||||
break;
|
break;
|
||||||
case (MAN_RI):
|
case MAN_RI:
|
||||||
font[0] = TERMFONT_NONE;
|
font[0] = TERMFONT_NONE;
|
||||||
font[1] = TERMFONT_UNDER;
|
font[1] = TERMFONT_UNDER;
|
||||||
break;
|
break;
|
||||||
case (MAN_BR):
|
case MAN_BR:
|
||||||
font[0] = TERMFONT_BOLD;
|
font[0] = TERMFONT_BOLD;
|
||||||
font[1] = TERMFONT_NONE;
|
font[1] = TERMFONT_NONE;
|
||||||
break;
|
break;
|
||||||
case (MAN_BI):
|
case MAN_BI:
|
||||||
font[0] = TERMFONT_BOLD;
|
font[0] = TERMFONT_BOLD;
|
||||||
font[1] = TERMFONT_UNDER;
|
font[1] = TERMFONT_UNDER;
|
||||||
break;
|
break;
|
||||||
case (MAN_IR):
|
case MAN_IR:
|
||||||
font[0] = TERMFONT_UNDER;
|
font[0] = TERMFONT_UNDER;
|
||||||
font[1] = TERMFONT_NONE;
|
font[1] = TERMFONT_NONE;
|
||||||
break;
|
break;
|
||||||
case (MAN_IB):
|
case MAN_IB:
|
||||||
font[0] = TERMFONT_UNDER;
|
font[0] = TERMFONT_UNDER;
|
||||||
font[1] = TERMFONT_BOLD;
|
font[1] = TERMFONT_BOLD;
|
||||||
break;
|
break;
|
||||||
@ -340,7 +343,6 @@ pre_alternate(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_B(DECL_ARGS)
|
pre_B(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -349,7 +351,6 @@ pre_B(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_OP(DECL_ARGS)
|
pre_OP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -372,7 +373,6 @@ pre_OP(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_ft(DECL_ARGS)
|
pre_ft(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -385,26 +385,26 @@ pre_ft(DECL_ARGS)
|
|||||||
|
|
||||||
cp = n->child->string;
|
cp = n->child->string;
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case ('4'):
|
case '4':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('3'):
|
case '3':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('B'):
|
case 'B':
|
||||||
term_fontrepl(p, TERMFONT_BOLD);
|
term_fontrepl(p, TERMFONT_BOLD);
|
||||||
break;
|
break;
|
||||||
case ('2'):
|
case '2':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('I'):
|
case 'I':
|
||||||
term_fontrepl(p, TERMFONT_UNDER);
|
term_fontrepl(p, TERMFONT_UNDER);
|
||||||
break;
|
break;
|
||||||
case ('P'):
|
case 'P':
|
||||||
term_fontlast(p);
|
term_fontlast(p);
|
||||||
break;
|
break;
|
||||||
case ('1'):
|
case '1':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('C'):
|
case 'C':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('R'):
|
case 'R':
|
||||||
term_fontrepl(p, TERMFONT_NONE);
|
term_fontrepl(p, TERMFONT_NONE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -413,7 +413,6 @@ pre_ft(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_in(DECL_ARGS)
|
pre_in(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -458,8 +457,6 @@ pre_in(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_sp(DECL_ARGS)
|
pre_sp(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -469,15 +466,15 @@ pre_sp(DECL_ARGS)
|
|||||||
|
|
||||||
if ((NULL == n->prev && n->parent)) {
|
if ((NULL == n->prev && n->parent)) {
|
||||||
switch (n->parent->tok) {
|
switch (n->parent->tok) {
|
||||||
case (MAN_SH):
|
case MAN_SH:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_SS):
|
case MAN_SS:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_PP):
|
case MAN_PP:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_LP):
|
case MAN_LP:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_P):
|
case MAN_P:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
return(0);
|
return(0);
|
||||||
default:
|
default:
|
||||||
@ -487,7 +484,7 @@ pre_sp(DECL_ARGS)
|
|||||||
|
|
||||||
neg = 0;
|
neg = 0;
|
||||||
switch (n->tok) {
|
switch (n->tok) {
|
||||||
case (MAN_br):
|
case MAN_br:
|
||||||
len = 0;
|
len = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -515,8 +512,6 @@ pre_sp(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_HP(DECL_ARGS)
|
pre_HP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -525,17 +520,17 @@ pre_HP(DECL_ARGS)
|
|||||||
const struct man_node *nn;
|
const struct man_node *nn;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
print_bvspace(p, n, mt->pardist);
|
print_bvspace(p, n, mt->pardist);
|
||||||
return(1);
|
return(1);
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! (MANT_LITERAL & mt->fl)) {
|
if ( ! (MANT_LITERAL & mt->fl)) {
|
||||||
p->flags |= TERMP_NOBREAK;
|
p->flags |= TERMP_NOBREAK | TERMP_BRIND;
|
||||||
p->trailspace = 2;
|
p->trailspace = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,16 +556,14 @@ pre_HP(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_HP(DECL_ARGS)
|
post_HP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
p->flags &= ~TERMP_NOBREAK;
|
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||||
p->trailspace = 0;
|
p->trailspace = 0;
|
||||||
p->offset = mt->offset;
|
p->offset = mt->offset;
|
||||||
p->rmargin = p->maxrmargin;
|
p->rmargin = p->maxrmargin;
|
||||||
@ -580,14 +573,12 @@ post_HP(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_PP(DECL_ARGS)
|
pre_PP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||||
print_bvspace(p, n, mt->pardist);
|
print_bvspace(p, n, mt->pardist);
|
||||||
break;
|
break;
|
||||||
@ -599,8 +590,6 @@ pre_PP(DECL_ARGS)
|
|||||||
return(MAN_HEAD != n->type);
|
return(MAN_HEAD != n->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_IP(DECL_ARGS)
|
pre_IP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -609,14 +598,14 @@ pre_IP(DECL_ARGS)
|
|||||||
int savelit, ival;
|
int savelit, ival;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
break;
|
break;
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
p->flags |= TERMP_NOBREAK;
|
p->flags |= TERMP_NOBREAK;
|
||||||
p->trailspace = 1;
|
p->trailspace = 1;
|
||||||
break;
|
break;
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
print_bvspace(p, n, mt->pardist);
|
print_bvspace(p, n, mt->pardist);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
@ -633,7 +622,7 @@ pre_IP(DECL_ARGS)
|
|||||||
len = (size_t)ival;
|
len = (size_t)ival;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
/* Handle zero-width lengths. */
|
/* Handle zero-width lengths. */
|
||||||
if (0 == len)
|
if (0 == len)
|
||||||
len = term_len(p, 1);
|
len = term_len(p, 1);
|
||||||
@ -656,9 +645,10 @@ pre_IP(DECL_ARGS)
|
|||||||
mt->fl |= MANT_LITERAL;
|
mt->fl |= MANT_LITERAL;
|
||||||
|
|
||||||
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->rmargin = p->maxrmargin > p->offset ?
|
||||||
|
p->maxrmargin : p->offset;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -667,20 +657,18 @@ pre_IP(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_IP(DECL_ARGS)
|
post_IP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
p->flags &= ~TERMP_NOBREAK;
|
p->flags &= ~TERMP_NOBREAK;
|
||||||
p->trailspace = 0;
|
p->trailspace = 0;
|
||||||
p->rmargin = p->maxrmargin;
|
p->rmargin = p->maxrmargin;
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
p->offset = mt->offset;
|
p->offset = mt->offset;
|
||||||
break;
|
break;
|
||||||
@ -689,8 +677,6 @@ post_IP(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_TP(DECL_ARGS)
|
pre_TP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -699,14 +685,14 @@ pre_TP(DECL_ARGS)
|
|||||||
int savelit, ival;
|
int savelit, ival;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
p->flags |= TERMP_NOBREAK;
|
p->flags |= TERMP_NOBREAK;
|
||||||
p->trailspace = 1;
|
p->trailspace = 1;
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
break;
|
break;
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
print_bvspace(p, n, mt->pardist);
|
print_bvspace(p, n, mt->pardist);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
@ -719,12 +705,12 @@ pre_TP(DECL_ARGS)
|
|||||||
/* Calculate offset. */
|
/* Calculate offset. */
|
||||||
|
|
||||||
if (NULL != (nn = n->parent->head->child))
|
if (NULL != (nn = n->parent->head->child))
|
||||||
if (nn->string && nn->parent->line == nn->line)
|
if (nn->string && 0 == (MAN_LINE & nn->flags))
|
||||||
if ((ival = a2width(p, nn->string)) >= 0)
|
if ((ival = a2width(p, nn->string)) >= 0)
|
||||||
len = (size_t)ival;
|
len = (size_t)ival;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
/* Handle zero-length properly. */
|
/* Handle zero-length properly. */
|
||||||
if (0 == len)
|
if (0 == len)
|
||||||
len = term_len(p, 1);
|
len = term_len(p, 1);
|
||||||
@ -736,9 +722,14 @@ pre_TP(DECL_ARGS)
|
|||||||
mt->fl &= ~MANT_LITERAL;
|
mt->fl &= ~MANT_LITERAL;
|
||||||
|
|
||||||
/* Don't print same-line elements. */
|
/* Don't print same-line elements. */
|
||||||
for (nn = n->child; nn; nn = nn->next)
|
nn = n->child;
|
||||||
if (nn->line > n->line)
|
while (NULL != nn && 0 == (MAN_LINE & nn->flags))
|
||||||
|
nn = nn->next;
|
||||||
|
|
||||||
|
while (NULL != nn) {
|
||||||
print_man_node(p, mt, nn, meta);
|
print_man_node(p, mt, nn, meta);
|
||||||
|
nn = nn->next;
|
||||||
|
}
|
||||||
|
|
||||||
if (savelit)
|
if (savelit)
|
||||||
mt->fl |= MANT_LITERAL;
|
mt->fl |= MANT_LITERAL;
|
||||||
@ -746,9 +737,10 @@ pre_TP(DECL_ARGS)
|
|||||||
mt->lmargin[mt->lmargincur] = (size_t)ival;
|
mt->lmargin[mt->lmargincur] = (size_t)ival;
|
||||||
|
|
||||||
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->rmargin = p->maxrmargin > p->offset ?
|
||||||
|
p->maxrmargin : p->offset;
|
||||||
p->trailspace = 0;
|
p->trailspace = 0;
|
||||||
p->flags &= ~TERMP_NOBREAK;
|
p->flags &= ~TERMP_NOBREAK;
|
||||||
break;
|
break;
|
||||||
@ -759,17 +751,15 @@ pre_TP(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_TP(DECL_ARGS)
|
post_TP(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
p->offset = mt->offset;
|
p->offset = mt->offset;
|
||||||
break;
|
break;
|
||||||
@ -778,15 +768,13 @@ post_TP(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_SS(DECL_ARGS)
|
pre_SS(DECL_ARGS)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
mt->fl &= ~MANT_LITERAL;
|
mt->fl &= ~MANT_LITERAL;
|
||||||
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);
|
||||||
@ -799,11 +787,11 @@ pre_SS(DECL_ARGS)
|
|||||||
for (i = 0; i < mt->pardist; i++)
|
for (i = 0; i < mt->pardist; i++)
|
||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
break;
|
break;
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
term_fontrepl(p, TERMFONT_BOLD);
|
term_fontrepl(p, TERMFONT_BOLD);
|
||||||
p->offset = term_len(p, 3);
|
p->offset = term_len(p, 3);
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
p->offset = mt->offset;
|
p->offset = mt->offset;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -813,17 +801,15 @@ pre_SS(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_SS(DECL_ARGS)
|
post_SS(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -831,15 +817,13 @@ post_SS(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_SH(DECL_ARGS)
|
pre_SH(DECL_ARGS)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
mt->fl &= ~MANT_LITERAL;
|
mt->fl &= ~MANT_LITERAL;
|
||||||
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);
|
||||||
@ -853,11 +837,11 @@ pre_SH(DECL_ARGS)
|
|||||||
for (i = 0; i < mt->pardist; i++)
|
for (i = 0; i < mt->pardist; i++)
|
||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
break;
|
break;
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
term_fontrepl(p, TERMFONT_BOLD);
|
term_fontrepl(p, TERMFONT_BOLD);
|
||||||
p->offset = 0;
|
p->offset = 0;
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
p->offset = mt->offset;
|
p->offset = mt->offset;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -867,17 +851,15 @@ pre_SH(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_SH(DECL_ARGS)
|
post_SH(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -885,7 +867,6 @@ post_SH(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_RS(DECL_ARGS)
|
pre_RS(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -893,10 +874,10 @@ pre_RS(DECL_ARGS)
|
|||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
return(1);
|
return(1);
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
return(0);
|
return(0);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -909,8 +890,9 @@ pre_RS(DECL_ARGS)
|
|||||||
sz = (size_t)ival;
|
sz = (size_t)ival;
|
||||||
|
|
||||||
mt->offset += sz;
|
mt->offset += sz;
|
||||||
p->rmargin = p->maxrmargin;
|
p->offset = mt->offset;
|
||||||
p->offset = mt->offset < p->rmargin ? mt->offset : p->rmargin;
|
p->rmargin = p->maxrmargin > p->offset ?
|
||||||
|
p->maxrmargin : p->offset;
|
||||||
|
|
||||||
if (++mt->lmarginsz < MAXMARGINS)
|
if (++mt->lmarginsz < MAXMARGINS)
|
||||||
mt->lmargincur = mt->lmarginsz;
|
mt->lmargincur = mt->lmarginsz;
|
||||||
@ -919,7 +901,6 @@ pre_RS(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_RS(DECL_ARGS)
|
post_RS(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -927,9 +908,9 @@ post_RS(DECL_ARGS)
|
|||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
return;
|
return;
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
term_newln(p);
|
term_newln(p);
|
||||||
@ -949,7 +930,6 @@ post_RS(DECL_ARGS)
|
|||||||
mt->lmargincur = mt->lmarginsz;
|
mt->lmargincur = mt->lmarginsz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
pre_UR(DECL_ARGS)
|
pre_UR(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -957,7 +937,6 @@ pre_UR(DECL_ARGS)
|
|||||||
return (MAN_HEAD != n->type);
|
return (MAN_HEAD != n->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
post_UR(DECL_ARGS)
|
post_UR(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -982,7 +961,7 @@ print_man_node(DECL_ARGS)
|
|||||||
int c;
|
int c;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case(MAN_TEXT):
|
case MAN_TEXT:
|
||||||
/*
|
/*
|
||||||
* If we have a blank line, output a vertical space.
|
* If we have a blank line, output a vertical space.
|
||||||
* If we have a space as the first character, break
|
* If we have a space as the first character, break
|
||||||
@ -997,10 +976,10 @@ print_man_node(DECL_ARGS)
|
|||||||
term_word(p, n->string);
|
term_word(p, n->string);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
case (MAN_EQN):
|
case MAN_EQN:
|
||||||
term_eqn(p, n->eqn);
|
term_eqn(p, n->eqn);
|
||||||
return;
|
return;
|
||||||
case (MAN_TBL):
|
case MAN_TBL:
|
||||||
/*
|
/*
|
||||||
* Tables are preceded by a newline. Then process a
|
* Tables are preceded by a newline. Then process a
|
||||||
* table line, which will cause line termination,
|
* table line, which will cause line termination,
|
||||||
@ -1037,7 +1016,7 @@ print_man_node(DECL_ARGS)
|
|||||||
* more specific than this.
|
* more specific than this.
|
||||||
*/
|
*/
|
||||||
if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
|
if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
|
||||||
(NULL == n->next || n->next->line > n->line)) {
|
(NULL == n->next || MAN_LINE & n->next->flags)) {
|
||||||
rm = p->rmargin;
|
rm = p->rmargin;
|
||||||
rmax = p->maxrmargin;
|
rmax = p->maxrmargin;
|
||||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||||
@ -1068,13 +1047,12 @@ print_man_nodelist(DECL_ARGS)
|
|||||||
print_man_nodelist(p, mt, n->next, meta);
|
print_man_nodelist(p, mt, n->next, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_man_foot(struct termp *p, const void *arg)
|
print_man_foot(struct termp *p, const void *arg)
|
||||||
{
|
{
|
||||||
char title[BUFSIZ];
|
|
||||||
size_t datelen;
|
|
||||||
const struct man_meta *meta;
|
const struct man_meta *meta;
|
||||||
|
char *title;
|
||||||
|
size_t datelen;
|
||||||
|
|
||||||
meta = (const struct man_meta *)arg;
|
meta = (const struct man_meta *)arg;
|
||||||
assert(meta->title);
|
assert(meta->title);
|
||||||
@ -1083,6 +1061,7 @@ print_man_foot(struct termp *p, const void *arg)
|
|||||||
|
|
||||||
term_fontrepl(p, TERMFONT_NONE);
|
term_fontrepl(p, TERMFONT_NONE);
|
||||||
|
|
||||||
|
if (meta->hasbody)
|
||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1092,13 +1071,16 @@ print_man_foot(struct termp *p, const void *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! p->mdocstyle) {
|
if ( ! p->mdocstyle) {
|
||||||
|
if (meta->hasbody) {
|
||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
|
}
|
||||||
|
mandoc_asprintf(&title, "%s(%s)",
|
||||||
|
meta->title, meta->msec);
|
||||||
} else if (meta->source) {
|
} else if (meta->source) {
|
||||||
strlcpy(title, meta->source, BUFSIZ);
|
title = mandoc_strdup(meta->source);
|
||||||
} else {
|
} else {
|
||||||
title[0] = '\0';
|
title = mandoc_strdup("");
|
||||||
}
|
}
|
||||||
datelen = term_strlen(p, meta->date);
|
datelen = term_strlen(p, meta->date);
|
||||||
|
|
||||||
@ -1134,38 +1116,35 @@ print_man_foot(struct termp *p, const void *arg)
|
|||||||
|
|
||||||
term_word(p, title);
|
term_word(p, title);
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
|
free(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_man_head(struct termp *p, const void *arg)
|
print_man_head(struct termp *p, const void *arg)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZ], title[BUFSIZ];
|
|
||||||
size_t buflen, titlen;
|
|
||||||
const struct man_meta *meta;
|
const struct man_meta *meta;
|
||||||
|
const char *volume;
|
||||||
|
char *title;
|
||||||
|
size_t vollen, titlen;
|
||||||
|
|
||||||
meta = (const struct man_meta *)arg;
|
meta = (const struct man_meta *)arg;
|
||||||
assert(meta->title);
|
assert(meta->title);
|
||||||
assert(meta->msec);
|
assert(meta->msec);
|
||||||
|
|
||||||
if (meta->vol)
|
volume = NULL == meta->vol ? "" : meta->vol;
|
||||||
strlcpy(buf, meta->vol, BUFSIZ);
|
vollen = term_strlen(p, volume);
|
||||||
else
|
|
||||||
buf[0] = '\0';
|
|
||||||
buflen = term_strlen(p, buf);
|
|
||||||
|
|
||||||
/* Top left corner: manual title and section. */
|
/* Top left corner: manual title and section. */
|
||||||
|
|
||||||
snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
|
mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
|
||||||
titlen = term_strlen(p, title);
|
titlen = term_strlen(p, title);
|
||||||
|
|
||||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||||
p->trailspace = 1;
|
p->trailspace = 1;
|
||||||
p->offset = 0;
|
p->offset = 0;
|
||||||
p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
|
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||||
(p->maxrmargin -
|
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
||||||
term_strlen(p, buf) + term_len(p, 1)) / 2 :
|
p->maxrmargin - vollen;
|
||||||
p->maxrmargin - buflen;
|
|
||||||
|
|
||||||
term_word(p, title);
|
term_word(p, title);
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
@ -1174,10 +1153,10 @@ print_man_head(struct termp *p, const void *arg)
|
|||||||
|
|
||||||
p->flags |= TERMP_NOSPACE;
|
p->flags |= TERMP_NOSPACE;
|
||||||
p->offset = p->rmargin;
|
p->offset = p->rmargin;
|
||||||
p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
|
p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
|
||||||
p->maxrmargin - titlen : p->maxrmargin;
|
p->maxrmargin - titlen : p->maxrmargin;
|
||||||
|
|
||||||
term_word(p, buf);
|
term_word(p, volume);
|
||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
|
|
||||||
/* Top right corner: title and section, again. */
|
/* Top right corner: title and section, again. */
|
||||||
@ -1207,4 +1186,5 @@ print_man_head(struct termp *p, const void *arg)
|
|||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
term_vspace(p);
|
term_vspace(p);
|
||||||
}
|
}
|
||||||
|
free(title);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: man_validate.c,v 1.86 2013/10/17 20:54:58 schwarze Exp $ */
|
/* $Id: man_validate.c,v 1.105 2014/08/06 15:09: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 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libman.h"
|
#include "libman.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
|
|
||||||
@ -39,21 +40,14 @@
|
|||||||
|
|
||||||
typedef int (*v_check)(CHKARGS);
|
typedef int (*v_check)(CHKARGS);
|
||||||
|
|
||||||
struct man_valid {
|
|
||||||
v_check *pres;
|
|
||||||
v_check *posts;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int check_eq0(CHKARGS);
|
static int check_eq0(CHKARGS);
|
||||||
static int check_eq2(CHKARGS);
|
static int check_eq2(CHKARGS);
|
||||||
static int check_le1(CHKARGS);
|
static int check_le1(CHKARGS);
|
||||||
static int check_ge2(CHKARGS);
|
|
||||||
static int check_le5(CHKARGS);
|
static int check_le5(CHKARGS);
|
||||||
static int check_head1(CHKARGS);
|
|
||||||
static int check_par(CHKARGS);
|
static int check_par(CHKARGS);
|
||||||
static int check_part(CHKARGS);
|
static int check_part(CHKARGS);
|
||||||
static int check_root(CHKARGS);
|
static int check_root(CHKARGS);
|
||||||
static void check_text(CHKARGS);
|
static int check_text(CHKARGS);
|
||||||
|
|
||||||
static int post_AT(CHKARGS);
|
static int post_AT(CHKARGS);
|
||||||
static int post_IP(CHKARGS);
|
static int post_IP(CHKARGS);
|
||||||
@ -61,174 +55,122 @@ static int post_vs(CHKARGS);
|
|||||||
static int post_fi(CHKARGS);
|
static int post_fi(CHKARGS);
|
||||||
static int post_ft(CHKARGS);
|
static int post_ft(CHKARGS);
|
||||||
static int post_nf(CHKARGS);
|
static int post_nf(CHKARGS);
|
||||||
static int post_sec(CHKARGS);
|
|
||||||
static int post_TH(CHKARGS);
|
static int post_TH(CHKARGS);
|
||||||
static int post_UC(CHKARGS);
|
static int post_UC(CHKARGS);
|
||||||
static int pre_sec(CHKARGS);
|
static int post_UR(CHKARGS);
|
||||||
|
|
||||||
static v_check posts_at[] = { post_AT, NULL };
|
static v_check man_valids[MAN_MAX] = {
|
||||||
static v_check posts_br[] = { post_vs, check_eq0, NULL };
|
post_vs, /* br */
|
||||||
static v_check posts_eq0[] = { check_eq0, NULL };
|
post_TH, /* TH */
|
||||||
static v_check posts_eq2[] = { check_eq2, NULL };
|
NULL, /* SH */
|
||||||
static v_check posts_fi[] = { check_eq0, post_fi, NULL };
|
NULL, /* SS */
|
||||||
static v_check posts_ft[] = { post_ft, NULL };
|
NULL, /* TP */
|
||||||
static v_check posts_ip[] = { post_IP, NULL };
|
check_par, /* LP */
|
||||||
static v_check posts_le1[] = { check_le1, NULL };
|
check_par, /* PP */
|
||||||
static v_check posts_nf[] = { check_eq0, post_nf, NULL };
|
check_par, /* P */
|
||||||
static v_check posts_par[] = { check_par, NULL };
|
post_IP, /* IP */
|
||||||
static v_check posts_part[] = { check_part, NULL };
|
NULL, /* HP */
|
||||||
static v_check posts_sec[] = { post_sec, NULL };
|
NULL, /* SM */
|
||||||
static v_check posts_sp[] = { post_vs, check_le1, NULL };
|
NULL, /* SB */
|
||||||
static v_check posts_th[] = { check_ge2, check_le5, post_TH, NULL };
|
NULL, /* BI */
|
||||||
static v_check posts_uc[] = { post_UC, NULL };
|
NULL, /* IB */
|
||||||
static v_check posts_ur[] = { check_head1, check_part, NULL };
|
NULL, /* BR */
|
||||||
static v_check pres_sec[] = { pre_sec, NULL };
|
NULL, /* RB */
|
||||||
|
NULL, /* R */
|
||||||
static const struct man_valid man_valids[MAN_MAX] = {
|
NULL, /* B */
|
||||||
{ NULL, posts_br }, /* br */
|
NULL, /* I */
|
||||||
{ NULL, posts_th }, /* TH */
|
NULL, /* IR */
|
||||||
{ pres_sec, posts_sec }, /* SH */
|
NULL, /* RI */
|
||||||
{ pres_sec, posts_sec }, /* SS */
|
check_eq0, /* na */
|
||||||
{ NULL, NULL }, /* TP */
|
post_vs, /* sp */
|
||||||
{ NULL, posts_par }, /* LP */
|
post_nf, /* nf */
|
||||||
{ NULL, posts_par }, /* PP */
|
post_fi, /* fi */
|
||||||
{ NULL, posts_par }, /* P */
|
NULL, /* RE */
|
||||||
{ NULL, posts_ip }, /* IP */
|
check_part, /* RS */
|
||||||
{ NULL, NULL }, /* HP */
|
NULL, /* DT */
|
||||||
{ NULL, NULL }, /* SM */
|
post_UC, /* UC */
|
||||||
{ NULL, NULL }, /* SB */
|
check_le1, /* PD */
|
||||||
{ NULL, NULL }, /* BI */
|
post_AT, /* AT */
|
||||||
{ NULL, NULL }, /* IB */
|
NULL, /* in */
|
||||||
{ NULL, NULL }, /* BR */
|
post_ft, /* ft */
|
||||||
{ NULL, NULL }, /* RB */
|
check_eq2, /* OP */
|
||||||
{ NULL, NULL }, /* R */
|
post_nf, /* EX */
|
||||||
{ NULL, NULL }, /* B */
|
post_fi, /* EE */
|
||||||
{ NULL, NULL }, /* I */
|
post_UR, /* UR */
|
||||||
{ NULL, NULL }, /* IR */
|
NULL, /* UE */
|
||||||
{ NULL, NULL }, /* RI */
|
NULL, /* ll */
|
||||||
{ NULL, posts_eq0 }, /* na */
|
|
||||||
{ NULL, posts_sp }, /* sp */
|
|
||||||
{ NULL, posts_nf }, /* nf */
|
|
||||||
{ NULL, posts_fi }, /* fi */
|
|
||||||
{ NULL, NULL }, /* RE */
|
|
||||||
{ NULL, posts_part }, /* RS */
|
|
||||||
{ NULL, NULL }, /* DT */
|
|
||||||
{ NULL, posts_uc }, /* UC */
|
|
||||||
{ NULL, posts_le1 }, /* PD */
|
|
||||||
{ NULL, posts_at }, /* AT */
|
|
||||||
{ NULL, NULL }, /* in */
|
|
||||||
{ NULL, posts_ft }, /* ft */
|
|
||||||
{ NULL, posts_eq2 }, /* OP */
|
|
||||||
{ NULL, posts_nf }, /* EX */
|
|
||||||
{ NULL, posts_fi }, /* EE */
|
|
||||||
{ NULL, posts_ur }, /* UR */
|
|
||||||
{ NULL, NULL }, /* UE */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
man_valid_pre(struct man *man, struct man_node *n)
|
|
||||||
{
|
|
||||||
v_check *cp;
|
|
||||||
|
|
||||||
switch (n->type) {
|
|
||||||
case (MAN_TEXT):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case (MAN_ROOT):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case (MAN_EQN):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case (MAN_TBL):
|
|
||||||
return(1);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == (cp = man_valids[n->tok].pres))
|
|
||||||
return(1);
|
|
||||||
for ( ; *cp; cp++)
|
|
||||||
if ( ! (*cp)(man, n))
|
|
||||||
return(0);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
man_valid_post(struct man *man)
|
man_valid_post(struct man *man)
|
||||||
{
|
{
|
||||||
|
struct man_node *n;
|
||||||
v_check *cp;
|
v_check *cp;
|
||||||
|
|
||||||
if (MAN_VALID & man->last->flags)
|
n = man->last;
|
||||||
|
if (n->flags & MAN_VALID)
|
||||||
return(1);
|
return(1);
|
||||||
man->last->flags |= MAN_VALID;
|
n->flags |= MAN_VALID;
|
||||||
|
|
||||||
switch (man->last->type) {
|
switch (n->type) {
|
||||||
case (MAN_TEXT):
|
case MAN_TEXT:
|
||||||
check_text(man, man->last);
|
return(check_text(man, n));
|
||||||
return(1);
|
case MAN_ROOT:
|
||||||
case (MAN_ROOT):
|
return(check_root(man, n));
|
||||||
return(check_root(man, man->last));
|
case MAN_EQN:
|
||||||
case (MAN_EQN):
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_TBL):
|
case MAN_TBL:
|
||||||
return(1);
|
return(1);
|
||||||
default:
|
default:
|
||||||
break;
|
cp = man_valids + n->tok;
|
||||||
|
return(*cp ? (*cp)(man, n) : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == (cp = man_valids[man->last->tok].posts))
|
|
||||||
return(1);
|
|
||||||
for ( ; *cp; cp++)
|
|
||||||
if ( ! (*cp)(man, man->last))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_root(CHKARGS)
|
check_root(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (MAN_BLINE & man->flags)
|
assert((man->flags & (MAN_BLINE | MAN_ELINE)) == 0);
|
||||||
man_nmsg(man, n, MANDOCERR_SCOPEEXIT);
|
|
||||||
else if (MAN_ELINE & man->flags)
|
|
||||||
man_nmsg(man, n, MANDOCERR_SCOPEEXIT);
|
|
||||||
|
|
||||||
man->flags &= ~MAN_BLINE;
|
if (NULL == man->first->child)
|
||||||
man->flags &= ~MAN_ELINE;
|
mandoc_msg(MANDOCERR_DOC_EMPTY, man->parse,
|
||||||
|
n->line, n->pos, NULL);
|
||||||
|
else
|
||||||
|
man->meta.hasbody = 1;
|
||||||
|
|
||||||
if (NULL == man->first->child) {
|
if (NULL == man->meta.title) {
|
||||||
man_nmsg(man, n, MANDOCERR_NODOCBODY);
|
mandoc_msg(MANDOCERR_TH_NOTITLE, man->parse,
|
||||||
return(0);
|
n->line, n->pos, NULL);
|
||||||
} else if (NULL == man->meta.title) {
|
|
||||||
man_nmsg(man, n, MANDOCERR_NOTITLE);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a title hasn't been set, do so now (by
|
* If a title hasn't been set, do so now (by
|
||||||
* implication, date and section also aren't set).
|
* implication, date and section also aren't set).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
man->meta.title = mandoc_strdup("unknown");
|
man->meta.title = mandoc_strdup("");
|
||||||
man->meta.msec = mandoc_strdup("1");
|
man->meta.msec = mandoc_strdup("");
|
||||||
man->meta.date = mandoc_normdate
|
man->meta.date = man->quick ? mandoc_strdup("") :
|
||||||
(man->parse, NULL, n->line, n->pos);
|
mandoc_normdate(man->parse, NULL, n->line, n->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
check_text(CHKARGS)
|
check_text(CHKARGS)
|
||||||
{
|
{
|
||||||
char *cp, *p;
|
char *cp, *p;
|
||||||
|
|
||||||
if (MAN_LITERAL & man->flags)
|
if (MAN_LITERAL & man->flags)
|
||||||
return;
|
return(1);
|
||||||
|
|
||||||
cp = n->string;
|
cp = n->string;
|
||||||
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
||||||
man_pmsg(man, n->line, (int)(p - cp), MANDOCERR_BADTAB);
|
mandoc_msg(MANDOCERR_FI_TAB, man->parse,
|
||||||
|
n->line, n->pos + (p - cp), NULL);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INEQ_DEFINE(x, ineq, name) \
|
#define INEQ_DEFINE(x, ineq, name) \
|
||||||
@ -246,18 +188,17 @@ check_##name(CHKARGS) \
|
|||||||
INEQ_DEFINE(0, ==, eq0)
|
INEQ_DEFINE(0, ==, eq0)
|
||||||
INEQ_DEFINE(2, ==, eq2)
|
INEQ_DEFINE(2, ==, eq2)
|
||||||
INEQ_DEFINE(1, <=, le1)
|
INEQ_DEFINE(1, <=, le1)
|
||||||
INEQ_DEFINE(2, >=, ge2)
|
|
||||||
INEQ_DEFINE(5, <=, le5)
|
INEQ_DEFINE(5, <=, le5)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_head1(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);
|
||||||
|
|
||||||
return(1);
|
return(check_part(man, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -272,27 +213,27 @@ post_ft(CHKARGS)
|
|||||||
ok = 0;
|
ok = 0;
|
||||||
cp = n->child->string;
|
cp = n->child->string;
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case ('1'):
|
case '1':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('2'):
|
case '2':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('3'):
|
case '3':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('4'):
|
case '4':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('I'):
|
case 'I':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('P'):
|
case 'P':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('R'):
|
case 'R':
|
||||||
if ('\0' == cp[1])
|
if ('\0' == cp[1])
|
||||||
ok = 1;
|
ok = 1;
|
||||||
break;
|
break;
|
||||||
case ('B'):
|
case 'B':
|
||||||
if ('\0' == cp[1] || ('I' == cp[1] && '\0' == cp[2]))
|
if ('\0' == cp[1] || ('I' == cp[1] && '\0' == cp[2]))
|
||||||
ok = 1;
|
ok = 1;
|
||||||
break;
|
break;
|
||||||
case ('C'):
|
case 'C':
|
||||||
if ('W' == cp[1] && '\0' == cp[2])
|
if ('W' == cp[1] && '\0' == cp[2])
|
||||||
ok = 1;
|
ok = 1;
|
||||||
break;
|
break;
|
||||||
@ -301,41 +242,18 @@ post_ft(CHKARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (0 == ok) {
|
if (0 == ok) {
|
||||||
mandoc_vmsg
|
mandoc_vmsg(MANDOCERR_FT_BAD, man->parse,
|
||||||
(MANDOCERR_BADFONT, man->parse,
|
n->line, n->pos, "ft %s", cp);
|
||||||
n->line, n->pos, "%s", cp);
|
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 < n->nchild)
|
if (1 < n->nchild)
|
||||||
mandoc_vmsg
|
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
||||||
(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);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
pre_sec(CHKARGS)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (MAN_BLOCK == n->type)
|
|
||||||
man->flags &= ~MAN_LITERAL;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
post_sec(CHKARGS)
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( ! (MAN_HEAD == n->type && 0 == n->nchild))
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_part(CHKARGS)
|
check_part(CHKARGS)
|
||||||
{
|
{
|
||||||
@ -347,23 +265,28 @@ check_part(CHKARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_par(CHKARGS)
|
check_par(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
if (0 == n->body->nchild)
|
if (0 == n->body->nchild)
|
||||||
man_node_delete(man, n);
|
man_node_delete(man, n);
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
if (0 == n->nchild)
|
if (0 == n->nchild)
|
||||||
man_nmsg(man, n, MANDOCERR_IGNPAR);
|
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||||
|
man->parse, n->line, n->pos,
|
||||||
|
"%s empty", man_macronames[n->tok]);
|
||||||
break;
|
break;
|
||||||
case (MAN_HEAD):
|
case MAN_HEAD:
|
||||||
if (n->nchild)
|
if (n->nchild)
|
||||||
man_nmsg(man, n, MANDOCERR_ARGSLOST);
|
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||||
|
man->parse, n->line, n->pos,
|
||||||
|
"%s %s%s", man_macronames[n->tok],
|
||||||
|
n->child->string,
|
||||||
|
n->nchild > 1 ? " ..." : "");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -377,13 +300,15 @@ post_IP(CHKARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MAN_BLOCK):
|
case MAN_BLOCK:
|
||||||
if (0 == n->head->nchild && 0 == n->body->nchild)
|
if (0 == n->head->nchild && 0 == n->body->nchild)
|
||||||
man_node_delete(man, n);
|
man_node_delete(man, n);
|
||||||
break;
|
break;
|
||||||
case (MAN_BODY):
|
case MAN_BODY:
|
||||||
if (0 == n->parent->head->nchild && 0 == n->nchild)
|
if (0 == n->parent->head->nchild && 0 == n->nchild)
|
||||||
man_nmsg(man, n, MANDOCERR_IGNPAR);
|
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||||
|
man->parse, n->line, n->pos,
|
||||||
|
"%s empty", man_macronames[n->tok]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -394,8 +319,10 @@ post_IP(CHKARGS)
|
|||||||
static int
|
static int
|
||||||
post_TH(CHKARGS)
|
post_TH(CHKARGS)
|
||||||
{
|
{
|
||||||
|
struct man_node *nb;
|
||||||
const char *p;
|
const char *p;
|
||||||
int line, pos;
|
|
||||||
|
check_le5(man, n);
|
||||||
|
|
||||||
free(man->meta.title);
|
free(man->meta.title);
|
||||||
free(man->meta.vol);
|
free(man->meta.vol);
|
||||||
@ -403,11 +330,11 @@ post_TH(CHKARGS)
|
|||||||
free(man->meta.msec);
|
free(man->meta.msec);
|
||||||
free(man->meta.date);
|
free(man->meta.date);
|
||||||
|
|
||||||
line = n->line;
|
|
||||||
pos = n->pos;
|
|
||||||
man->meta.title = man->meta.vol = man->meta.date =
|
man->meta.title = man->meta.vol = man->meta.date =
|
||||||
man->meta.msec = man->meta.source = NULL;
|
man->meta.msec = man->meta.source = NULL;
|
||||||
|
|
||||||
|
nb = n;
|
||||||
|
|
||||||
/* ->TITLE<- MSEC DATE SOURCE VOL */
|
/* ->TITLE<- MSEC DATE SOURCE VOL */
|
||||||
|
|
||||||
n = n->child;
|
n = n->child;
|
||||||
@ -416,13 +343,19 @@ post_TH(CHKARGS)
|
|||||||
/* Only warn about this once... */
|
/* Only warn about this once... */
|
||||||
if (isalpha((unsigned char)*p) &&
|
if (isalpha((unsigned char)*p) &&
|
||||||
! isupper((unsigned char)*p)) {
|
! isupper((unsigned char)*p)) {
|
||||||
man_nmsg(man, n, MANDOCERR_UPPERCASE);
|
mandoc_vmsg(MANDOCERR_TITLE_CASE,
|
||||||
|
man->parse, n->line,
|
||||||
|
n->pos + (p - n->string),
|
||||||
|
"TH %s", n->string);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
man->meta.title = mandoc_strdup(n->string);
|
man->meta.title = mandoc_strdup(n->string);
|
||||||
} else
|
} else {
|
||||||
man->meta.title = mandoc_strdup("");
|
man->meta.title = mandoc_strdup("");
|
||||||
|
mandoc_msg(MANDOCERR_TH_NOTITLE, man->parse,
|
||||||
|
nb->line, nb->pos, "TH");
|
||||||
|
}
|
||||||
|
|
||||||
/* TITLE ->MSEC<- DATE SOURCE VOL */
|
/* TITLE ->MSEC<- DATE SOURCE VOL */
|
||||||
|
|
||||||
@ -430,19 +363,27 @@ post_TH(CHKARGS)
|
|||||||
n = n->next;
|
n = n->next;
|
||||||
if (n && n->string)
|
if (n && n->string)
|
||||||
man->meta.msec = mandoc_strdup(n->string);
|
man->meta.msec = mandoc_strdup(n->string);
|
||||||
else
|
else {
|
||||||
man->meta.msec = mandoc_strdup("");
|
man->meta.msec = mandoc_strdup("");
|
||||||
|
mandoc_vmsg(MANDOCERR_MSEC_MISSING, man->parse,
|
||||||
|
nb->line, nb->pos, "TH %s", man->meta.title);
|
||||||
|
}
|
||||||
|
|
||||||
/* TITLE MSEC ->DATE<- SOURCE VOL */
|
/* TITLE MSEC ->DATE<- SOURCE VOL */
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
n = n->next;
|
n = n->next;
|
||||||
if (n && n->string && '\0' != n->string[0]) {
|
if (n && n->string && '\0' != n->string[0]) {
|
||||||
pos = n->pos;
|
man->meta.date = man->quick ?
|
||||||
man->meta.date = mandoc_normdate
|
mandoc_strdup(n->string) :
|
||||||
(man->parse, n->string, line, pos);
|
mandoc_normdate(man->parse, n->string,
|
||||||
} else
|
n->line, n->pos);
|
||||||
|
} else {
|
||||||
man->meta.date = mandoc_strdup("");
|
man->meta.date = mandoc_strdup("");
|
||||||
|
mandoc_msg(MANDOCERR_DATE_MISSING, man->parse,
|
||||||
|
n ? n->line : nb->line,
|
||||||
|
n ? n->pos : nb->pos, "TH");
|
||||||
|
}
|
||||||
|
|
||||||
/* TITLE MSEC DATE ->SOURCE<- VOL */
|
/* TITLE MSEC DATE ->SOURCE<- VOL */
|
||||||
|
|
||||||
@ -470,8 +411,11 @@ static int
|
|||||||
post_nf(CHKARGS)
|
post_nf(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
check_eq0(man, n);
|
||||||
|
|
||||||
if (MAN_LITERAL & man->flags)
|
if (MAN_LITERAL & man->flags)
|
||||||
man_nmsg(man, n, MANDOCERR_SCOPEREP);
|
mandoc_msg(MANDOCERR_NF_SKIP, man->parse,
|
||||||
|
n->line, n->pos, "nf");
|
||||||
|
|
||||||
man->flags |= MAN_LITERAL;
|
man->flags |= MAN_LITERAL;
|
||||||
return(1);
|
return(1);
|
||||||
@ -481,8 +425,11 @@ static int
|
|||||||
post_fi(CHKARGS)
|
post_fi(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
check_eq0(man, n);
|
||||||
|
|
||||||
if ( ! (MAN_LITERAL & man->flags))
|
if ( ! (MAN_LITERAL & man->flags))
|
||||||
man_nmsg(man, n, MANDOCERR_WNOSCOPE);
|
mandoc_msg(MANDOCERR_FI_SKIP, man->parse,
|
||||||
|
n->line, n->pos, "fi");
|
||||||
|
|
||||||
man->flags &= ~MAN_LITERAL;
|
man->flags &= ~MAN_LITERAL;
|
||||||
return(1);
|
return(1);
|
||||||
@ -568,16 +515,23 @@ static int
|
|||||||
post_vs(CHKARGS)
|
post_vs(CHKARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (n->tok == MAN_br)
|
||||||
|
check_eq0(man, n);
|
||||||
|
else
|
||||||
|
check_le1(man, n);
|
||||||
|
|
||||||
if (NULL != n->prev)
|
if (NULL != n->prev)
|
||||||
return(1);
|
return(1);
|
||||||
|
|
||||||
switch (n->parent->tok) {
|
switch (n->parent->tok) {
|
||||||
case (MAN_SH):
|
case MAN_SH:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_SS):
|
case MAN_SS:
|
||||||
man_nmsg(man, n, MANDOCERR_IGNPAR);
|
mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos,
|
||||||
|
"%s after %s", man_macronames[n->tok],
|
||||||
|
man_macronames[n->parent->tok]);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MAN_MAX):
|
case MAN_MAX:
|
||||||
/*
|
/*
|
||||||
* Don't warn about this because it occurs in pod2man
|
* Don't warn about this because it occurs in pod2man
|
||||||
* and would cause considerable (unfixable) warnage.
|
* and would cause considerable (unfixable) warnage.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\" $Id: mandoc.1,v 1.103 2013/07/13 19:41:16 schwarze Exp $
|
.\" $Id: mandoc.1,v 1.106 2014/08/08 01:50:59 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 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,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: August 8 2014 $
|
||||||
.Dt MANDOC 1
|
.Dt MANDOC 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -496,30 +496,28 @@ parser:
|
|||||||
.Pp
|
.Pp
|
||||||
.Dl $ mandoc \-Tman foo.mdoc \*(Gt foo.man
|
.Dl $ mandoc \-Tman foo.mdoc \*(Gt foo.man
|
||||||
.Sh DIAGNOSTICS
|
.Sh DIAGNOSTICS
|
||||||
Standard error messages reporting parsing errors are prefixed by
|
Messages displayed by
|
||||||
|
.Nm
|
||||||
|
follow this format:
|
||||||
.Pp
|
.Pp
|
||||||
.Sm off
|
.D1 Nm Ns : Ar file : Ns Ar line : Ns Ar column : level : message : macro args
|
||||||
.D1 Ar file : line : column : \ level :
|
|
||||||
.Sm on
|
|
||||||
.Pp
|
.Pp
|
||||||
where the fields have the following meanings:
|
Line and column numbers start at 1.
|
||||||
.Bl -tag -width "column"
|
Both are omitted for messages referring to an input file as a whole.
|
||||||
.It Ar file
|
Macro names and arguments are omitted where meaningless.
|
||||||
The name of the input file causing the message.
|
Fatal messages about invalid command line arguments
|
||||||
.It Ar line
|
or operating system errors, for example when memory is exhausted,
|
||||||
The line number in that input file.
|
may also omit the
|
||||||
Line numbering starts at 1.
|
.Ar file
|
||||||
.It Ar column
|
and
|
||||||
The column number in that input file.
|
.Ar level
|
||||||
Column numbering starts at 1.
|
fields.
|
||||||
If the issue is caused by a word, the column number usually
|
|
||||||
points to the first character of the word.
|
|
||||||
.It Ar level
|
|
||||||
The message level, printed in capital letters.
|
|
||||||
.El
|
|
||||||
.Pp
|
.Pp
|
||||||
Message levels have the following meanings:
|
Message levels have the following meanings:
|
||||||
.Bl -tag -width "warning"
|
.Bl -tag -width "warning"
|
||||||
|
.It Cm syserr
|
||||||
|
Opening or reading an input file failed, so the parser cannot
|
||||||
|
even be started and no output is produced from that input file.
|
||||||
.It Cm fatal
|
.It Cm fatal
|
||||||
The parser is unable to parse a given input file at all.
|
The parser is unable to parse a given input file at all.
|
||||||
No formatted output is produced from that input file.
|
No formatted output is produced from that input file.
|
||||||
@ -551,13 +549,836 @@ levels are hidden unless their level, or a lower level, is requested using a
|
|||||||
option or
|
option or
|
||||||
.Fl T Ns Cm lint
|
.Fl T Ns Cm lint
|
||||||
output mode.
|
output mode.
|
||||||
.Pp
|
.Ss Warnings related to the document prologue
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "missing manual title, using UNTITLED"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Dt
|
||||||
|
macro has no arguments, or there is no
|
||||||
|
.Ic \&Dt
|
||||||
|
macro before the first non-prologue macro.
|
||||||
|
.It Sy "missing manual title, using \(dq\(dq"
|
||||||
|
.Pq man
|
||||||
|
There is no
|
||||||
|
.Ic \&TH
|
||||||
|
macro, or it has no arguments.
|
||||||
|
.It Sy "lower case character in document title"
|
||||||
|
.Pq mdoc , man
|
||||||
|
The title is still used as given in the
|
||||||
|
.Ic \&Dt
|
||||||
|
or
|
||||||
|
.Ic \&TH
|
||||||
|
macro.
|
||||||
|
.It Sy "missing manual section, using \(dq\(dq"
|
||||||
|
.Pq mdoc , man
|
||||||
|
A
|
||||||
|
.Ic \&Dt
|
||||||
|
or
|
||||||
|
.Ic \&TH
|
||||||
|
macro lacks the mandatory section argument.
|
||||||
|
.It Sy "unknown manual section"
|
||||||
|
.Pq mdoc
|
||||||
|
The section number in a
|
||||||
|
.Ic \&Dt
|
||||||
|
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"
|
||||||
|
.Pq mdoc, man
|
||||||
|
The document was parsed as
|
||||||
|
.Xr mdoc 7
|
||||||
|
and it has no
|
||||||
|
.Ic \&Dd
|
||||||
|
macro, or the
|
||||||
|
.Ic \&Dd
|
||||||
|
macro has no arguments or only empty arguments;
|
||||||
|
or the document was parsed as
|
||||||
|
.Xr man 7
|
||||||
|
and it has no
|
||||||
|
.Ic \&TH
|
||||||
|
macro, or the
|
||||||
|
.Ic \&TH
|
||||||
|
macro has less than three arguments or its third argument is empty.
|
||||||
|
.It Sy "cannot parse date, using it verbatim"
|
||||||
|
.Pq mdoc , man
|
||||||
|
The date given in a
|
||||||
|
.Ic \&Dd
|
||||||
|
or
|
||||||
|
.Ic \&TH
|
||||||
|
macro does not follow the conventional format.
|
||||||
|
.It Sy "missing Os macro, using \(dq\(dq"
|
||||||
|
.Pq mdoc
|
||||||
|
The default or current system is not shown in this case.
|
||||||
|
.It Sy "duplicate prologue macro"
|
||||||
|
.Pq mdoc
|
||||||
|
One of the prologue macros occurs more than once.
|
||||||
|
The last instance overrides all previous ones.
|
||||||
|
.It Sy "late prologue macro"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Dd
|
||||||
|
or
|
||||||
|
.Ic \&Os
|
||||||
|
macro occurs after some non-prologue macro, but still takes effect.
|
||||||
|
.It Sy "skipping late title macro"
|
||||||
|
.Pq mdoc
|
||||||
|
The
|
||||||
|
.Ic \&Dt
|
||||||
|
macro can only occur before the first non-prologue macro
|
||||||
|
because traditional formatters write the page header
|
||||||
|
before parsing the document body.
|
||||||
|
Even though this technical restriction does not apply to
|
||||||
|
.Nm ,
|
||||||
|
traditional semantics is preserved.
|
||||||
|
The late macro is discarded including its arguments.
|
||||||
|
.It Sy "prologue macros out of order"
|
||||||
|
.Pq mdoc
|
||||||
|
The prologue macros are not given in the conventional order
|
||||||
|
.Ic \&Dd ,
|
||||||
|
.Ic \&Dt ,
|
||||||
|
.Ic \&Os .
|
||||||
|
All three macros are used even when given in another order.
|
||||||
|
.El
|
||||||
|
.Ss Warnings regarding document structure
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy ".so is fragile, better use ln(1)"
|
||||||
|
.Pq roff
|
||||||
|
Including files only works when the parser program runs with the correct
|
||||||
|
current working directory.
|
||||||
|
.It Sy "no document body"
|
||||||
|
.Pq mdoc , man
|
||||||
|
The document body contains neither text nor macros.
|
||||||
|
An empty document is shown, consisting only of a header and a footer line.
|
||||||
|
.It Sy "content before first section header"
|
||||||
|
.Pq mdoc , man
|
||||||
|
Some macros or text precede the first
|
||||||
|
.Ic \&Sh
|
||||||
|
or
|
||||||
|
.Ic \&SH
|
||||||
|
section header.
|
||||||
|
The offending macros and text are parsed and added to the top level
|
||||||
|
of the syntax tree, outside any section block.
|
||||||
|
.It Sy "first section is not NAME"
|
||||||
|
.Pq mdoc
|
||||||
|
The argument of the first
|
||||||
|
.Ic \&Sh
|
||||||
|
macro is not
|
||||||
|
.Sq NAME .
|
||||||
|
This may confuse
|
||||||
|
.Xr makewhatis 8
|
||||||
|
and
|
||||||
|
.Xr apropos 1 .
|
||||||
|
.It Sy "bad NAME section contents"
|
||||||
|
.Pq mdoc
|
||||||
|
The last node in the NAME section is not an
|
||||||
|
.Ic \&Nd
|
||||||
|
macro, or any preceding macro is not
|
||||||
|
.Ic \&Nm ,
|
||||||
|
or the NAME section is completely empty.
|
||||||
|
This may confuse
|
||||||
|
.Xr makewhatis 8
|
||||||
|
and
|
||||||
|
.Xr apropos 1 .
|
||||||
|
.It Sy "sections out of conventional order"
|
||||||
|
.Pq mdoc
|
||||||
|
A standard section occurs after another section it usually precedes.
|
||||||
|
All section titles are used as given,
|
||||||
|
and the order of sections is not changed.
|
||||||
|
.It Sy "duplicate section title"
|
||||||
|
.Pq mdoc
|
||||||
|
The same standard section title occurs more than once.
|
||||||
|
.It Sy "unexpected section"
|
||||||
|
.Pq mdoc
|
||||||
|
A standard section header occurs in a section of the manual
|
||||||
|
where it normally isn't useful.
|
||||||
|
.El
|
||||||
|
.Ss "Warnings related to macros and nesting"
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "obsolete macro"
|
||||||
|
.Pq mdoc
|
||||||
|
See the
|
||||||
|
.Xr mdoc 7
|
||||||
|
manual for replacements.
|
||||||
|
.It Sy "skipping paragraph macro"
|
||||||
|
In
|
||||||
|
.Xr mdoc 7
|
||||||
|
documents, this happens
|
||||||
|
.Bl -dash -compact
|
||||||
|
.It
|
||||||
|
at the beginning and end of sections and subsections
|
||||||
|
.It
|
||||||
|
right before non-compact lists and displays
|
||||||
|
.It
|
||||||
|
at the end of items in non-column, non-compact lists
|
||||||
|
.It
|
||||||
|
and for multiple consecutive paragraph macros.
|
||||||
|
.El
|
||||||
|
In
|
||||||
|
.Xr man 7
|
||||||
|
documents, it happens
|
||||||
|
.Bl -dash -compact
|
||||||
|
.It
|
||||||
|
for empty
|
||||||
|
.Ic \&P ,
|
||||||
|
.Ic \&PP ,
|
||||||
|
and
|
||||||
|
.Ic \&LP
|
||||||
|
macros
|
||||||
|
.It
|
||||||
|
for
|
||||||
|
.Ic \&IP
|
||||||
|
macros having neither head nor body arguments
|
||||||
|
.It
|
||||||
|
for
|
||||||
|
.Ic \&br
|
||||||
|
or
|
||||||
|
.Ic \&sp
|
||||||
|
right after
|
||||||
|
.Ic \&SH
|
||||||
|
or
|
||||||
|
.Ic \&SS
|
||||||
|
.El
|
||||||
|
.It Sy "moving paragraph macro out of list"
|
||||||
|
.Pq mdoc
|
||||||
|
A list item in a
|
||||||
|
.Ic \&Bl
|
||||||
|
list contains a trailing paragraph macro.
|
||||||
|
The paragraph macro is moved after the end of the list.
|
||||||
|
.It Sy "skipping no-space macro"
|
||||||
|
.Pq mdoc
|
||||||
|
An input line begins with an
|
||||||
|
.Ic \&Ns
|
||||||
|
macro.
|
||||||
|
The macro is ignored.
|
||||||
|
.It Sy "blocks badly nested"
|
||||||
|
.Pq mdoc
|
||||||
|
If two blocks intersect, one should completely contain the other.
|
||||||
|
Otherwise, rendered output is likely to look strange in any output
|
||||||
|
format, and rendering in SGML-based output formats is likely to be
|
||||||
|
outright wrong because such languages do not support badly nested
|
||||||
|
blocks at all.
|
||||||
|
Typical examples of badly nested blocks are
|
||||||
|
.Qq Ic \&Ao \&Bo \&Ac \&Bc
|
||||||
|
and
|
||||||
|
.Qq Ic \&Ao \&Bq \&Ac .
|
||||||
|
In these examples,
|
||||||
|
.Ic \&Ac
|
||||||
|
breaks
|
||||||
|
.Ic \&Bo
|
||||||
|
and
|
||||||
|
.Ic \&Bq ,
|
||||||
|
respectively.
|
||||||
|
.It Sy "nested displays are not portable"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bd ,
|
||||||
|
.Ic \&D1 ,
|
||||||
|
or
|
||||||
|
.Ic \&Dl
|
||||||
|
display occurs nested inside another
|
||||||
|
.Ic \&Bd
|
||||||
|
display.
|
||||||
|
This works with
|
||||||
|
.Nm ,
|
||||||
|
but fails with most other implementations.
|
||||||
|
.It Sy "moving content out of list"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bl
|
||||||
|
list block contains text or macros before the first
|
||||||
|
.Ic \&It
|
||||||
|
macro.
|
||||||
|
The offending children are moved before the beginning of the list.
|
||||||
|
.It Sy ".Vt block has child macro"
|
||||||
|
.Pq mdoc
|
||||||
|
The
|
||||||
|
.Ic \&Vt
|
||||||
|
macro supports plain text arguments only.
|
||||||
|
Formatting may be ugly and semantic searching
|
||||||
|
for the affected content might not work.
|
||||||
|
.It Sy "fill mode already enabled, skipping"
|
||||||
|
.Pq man
|
||||||
|
A
|
||||||
|
.Ic \&fi
|
||||||
|
request occurs even though the document is still in fill mode,
|
||||||
|
or already switched back to fill mode.
|
||||||
|
It has no effect.
|
||||||
|
.It Sy "fill mode already disabled, skipping"
|
||||||
|
.Pq man
|
||||||
|
An
|
||||||
|
.Ic \&nf
|
||||||
|
request occurs even though the document already switched to no-fill mode
|
||||||
|
and did not switch back to fill mode yet.
|
||||||
|
It has no effect.
|
||||||
|
.It Sy "line scope broken"
|
||||||
|
.Pq man
|
||||||
|
While parsing the next-line scope of the previous macro,
|
||||||
|
another macro is found that prematurely terminates the previous one.
|
||||||
|
The previous, interrupted macro is deleted from the parse tree.
|
||||||
|
.El
|
||||||
|
.Ss "Warnings related to missing arguments"
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "skipping empty request"
|
||||||
|
.Pq roff
|
||||||
|
The macro name is missing from a macro definition request.
|
||||||
|
.It Sy "conditional request controls empty scope"
|
||||||
|
.Pq roff
|
||||||
|
A conditional request is only useful if any of the following
|
||||||
|
follows it on the same logical input line:
|
||||||
|
.Bl -dash -compact
|
||||||
|
.It
|
||||||
|
The
|
||||||
|
.Sq \e{
|
||||||
|
keyword to open a multi-line scope.
|
||||||
|
.It
|
||||||
|
A request or macro or some text, resulting in a single-line scope.
|
||||||
|
.It
|
||||||
|
The immediate end of the logical line without any intervening whitespace,
|
||||||
|
resulting in next-line scope.
|
||||||
|
.El
|
||||||
|
Here, a conditional request is followed by trailing whitespace only,
|
||||||
|
and there is no other content on its logical input line.
|
||||||
|
Note that it doesn't matter whether the logical input line is split
|
||||||
|
across multiple physical input lines using
|
||||||
|
.Sq \e
|
||||||
|
line continuation characters.
|
||||||
|
This is one of the rare cases
|
||||||
|
where trailing whitespace is syntactically significant.
|
||||||
|
The conditional request controls a scope containing whitespace only,
|
||||||
|
so it is unlikely to have a significant effect,
|
||||||
|
except that it may control a following
|
||||||
|
.Ic \&el
|
||||||
|
clause.
|
||||||
|
.It Sy "skipping empty macro"
|
||||||
|
.Pq mdoc
|
||||||
|
The indicated macro has no arguments and hence no effect.
|
||||||
|
.It Sy "empty argument, using 0n"
|
||||||
|
.Pq mdoc
|
||||||
|
The required width is missing after
|
||||||
|
.Ic \&Bd
|
||||||
|
or
|
||||||
|
.Ic \&Bl
|
||||||
|
.Fl offset
|
||||||
|
or
|
||||||
|
.Fl width.
|
||||||
|
.It Sy "argument count wrong"
|
||||||
|
.Pq mdoc , man
|
||||||
|
The indicated macro has too few or too many arguments.
|
||||||
|
The syntax tree will contain the wrong number of arguments as given.
|
||||||
|
Formatting behaviour depends on the specific macro in question.
|
||||||
|
Note that the same message may also occur as an ERROR, see below.
|
||||||
|
.It Sy "missing display type, using -ragged"
|
||||||
|
.Pq mdoc
|
||||||
|
The
|
||||||
|
.Ic \&Bd
|
||||||
|
macro is invoked without the required display type.
|
||||||
|
.It Sy "list type is not the first argument"
|
||||||
|
.Pq mdoc
|
||||||
|
In a
|
||||||
|
.Ic \&Bl
|
||||||
|
macro, at least one other argument precedes the type argument.
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
utility may also print messages related to invalid command line arguments
|
utility copes with any argument order, but some other
|
||||||
or operating system errors, for example when memory is exhausted or
|
.Xr mdoc 7
|
||||||
input files cannot be read.
|
implementations do not.
|
||||||
Such messages do not carry the prefix described above.
|
.It Sy "missing -width in -tag list, using 8n"
|
||||||
|
.Pq mdoc
|
||||||
|
Every
|
||||||
|
.Ic \&Bl
|
||||||
|
macro having the
|
||||||
|
.Fl tag
|
||||||
|
argument requires
|
||||||
|
.Fl width ,
|
||||||
|
too.
|
||||||
|
.It Sy "missing utility name, using \(dq\(dq"
|
||||||
|
.Pq mdoc
|
||||||
|
The
|
||||||
|
.Ic \&Ex Fl std
|
||||||
|
macro is called without an argument before
|
||||||
|
.Ic \&Nm
|
||||||
|
has first been called with an argument.
|
||||||
|
.It Sy "empty head in list item"
|
||||||
|
.Pq mdoc
|
||||||
|
In a
|
||||||
|
.Ic \&Bl
|
||||||
|
.Fl diag ,
|
||||||
|
.Fl hang ,
|
||||||
|
.Fl inset ,
|
||||||
|
.Fl ohang ,
|
||||||
|
or
|
||||||
|
.Fl tag
|
||||||
|
list, an
|
||||||
|
.Ic \&It
|
||||||
|
macro lacks the required argument.
|
||||||
|
The item head is left empty.
|
||||||
|
.It Sy "empty list item"
|
||||||
|
.Pq mdoc
|
||||||
|
In a
|
||||||
|
.Ic \&Bl
|
||||||
|
.Fl bullet ,
|
||||||
|
.Fl dash ,
|
||||||
|
.Fl enum ,
|
||||||
|
or
|
||||||
|
.Fl hyphen
|
||||||
|
list, an
|
||||||
|
.Ic \&It
|
||||||
|
block is empty.
|
||||||
|
An empty list item is shown.
|
||||||
|
.It Sy "missing font type"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bf
|
||||||
|
macro has no argument.
|
||||||
|
It switches to the default font,
|
||||||
|
.Cm \efR .
|
||||||
|
.It Sy "unknown font type"
|
||||||
|
.Pq mdoc
|
||||||
|
The
|
||||||
|
.Ic \&Bf
|
||||||
|
argument is invalid.
|
||||||
|
The default font
|
||||||
|
.Cm \efR
|
||||||
|
is used instead.
|
||||||
|
.It Sy "missing -std argument, adding it"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&Ex
|
||||||
|
or
|
||||||
|
.Ic \&Rv
|
||||||
|
macro lacks the required
|
||||||
|
.Fl std
|
||||||
|
argument.
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility assumes
|
||||||
|
.Fl std
|
||||||
|
even when it is not specified, but other implementations may not.
|
||||||
|
.El
|
||||||
|
.Ss "Warnings related to bad macro arguments"
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "unterminated quoted argument"
|
||||||
|
.Pq roff
|
||||||
|
Macro arguments can be enclosed in double quote characters
|
||||||
|
such that space characters and macro names contained in the quoted
|
||||||
|
argument need not be escaped.
|
||||||
|
The closing quote of the last argument of a macro can be omitted.
|
||||||
|
However, omitting it is not recommended because it makes the code
|
||||||
|
harder to read.
|
||||||
|
.It Sy "duplicate argument"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bd
|
||||||
|
or
|
||||||
|
.Ic \&Bl
|
||||||
|
macro has more than one
|
||||||
|
.Fl compact ,
|
||||||
|
more than one
|
||||||
|
.Fl offset ,
|
||||||
|
or more than one
|
||||||
|
.Fl width
|
||||||
|
argument.
|
||||||
|
All but the last instances of these arguments are ignored.
|
||||||
|
.It Sy "skipping duplicate argument"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&An
|
||||||
|
macro has more than one
|
||||||
|
.Fl split
|
||||||
|
or
|
||||||
|
.Fl nosplit
|
||||||
|
argument.
|
||||||
|
All but the first of these arguments are ignored.
|
||||||
|
.It Sy "skipping duplicate display type"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bd
|
||||||
|
macro has more than one type argument; the first one is used.
|
||||||
|
.It Sy "skipping duplicate list type"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bl
|
||||||
|
macro has more than one type argument; the first one is used.
|
||||||
|
.It Sy "skipping -width argument"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bl
|
||||||
|
.Fl column ,
|
||||||
|
.Fl diag ,
|
||||||
|
.Fl ohang ,
|
||||||
|
.Fl inset ,
|
||||||
|
or
|
||||||
|
.Fl item
|
||||||
|
list has a
|
||||||
|
.Fl width
|
||||||
|
argument.
|
||||||
|
That has no effect.
|
||||||
|
.It Sy "unknown AT&T UNIX version"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&At
|
||||||
|
macro has an invalid argument.
|
||||||
|
It is used verbatim, with
|
||||||
|
.Qq "AT&T UNIX "
|
||||||
|
prefixed to it.
|
||||||
|
.It Sy "invalid content in Rs block"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&Rs
|
||||||
|
block contains plain text or non-% macros.
|
||||||
|
The bogus content is left in the syntax tree.
|
||||||
|
Formatting may be poor.
|
||||||
|
.It Sy "invalid Boolean argument"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&Sm
|
||||||
|
macro has an argument other than
|
||||||
|
.Cm on
|
||||||
|
or
|
||||||
|
.Cm off .
|
||||||
|
The invalid argument is moved out of the macro, which leaves the macro
|
||||||
|
empty, causing it to toggle the spacing mode.
|
||||||
|
.It Sy "unknown font, skipping request"
|
||||||
|
.Pq man
|
||||||
|
A
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \&ft
|
||||||
|
request has an invalid argument.
|
||||||
|
.El
|
||||||
|
.Ss "Warnings related to plain text"
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "blank line in fill mode, using .sp"
|
||||||
|
.Pq mdoc
|
||||||
|
The meaning of blank input lines is only well-defined in non-fill mode:
|
||||||
|
In fill mode, line breaks of text input lines are not supposed to be
|
||||||
|
significant.
|
||||||
|
However, for compatibility with groff, blank lines in fill mode
|
||||||
|
are replaced with
|
||||||
|
.Ic \&sp
|
||||||
|
requests.
|
||||||
|
.It Sy "tab in filled text"
|
||||||
|
.Pq mdoc , man
|
||||||
|
The meaning of tab characters is only well-defined in non-fill mode:
|
||||||
|
In fill mode, whitespace is not supposed to be significant
|
||||||
|
on text input lines.
|
||||||
|
As an implementation dependent choice, tab characters on text lines
|
||||||
|
are passed through to the formatters in any case.
|
||||||
|
Given that the text before the tab character will be filled,
|
||||||
|
it is hard to predict which tab stop position the tab will advance to.
|
||||||
|
.It Sy "whitespace at end of input line"
|
||||||
|
.Pq mdoc , man , roff
|
||||||
|
Whitespace at the end of input lines is almost never semantically
|
||||||
|
significant \(em but in the odd case where it might be, it is
|
||||||
|
extremely confusing when reviewing and maintaining documents.
|
||||||
|
.It Sy "bad comment style"
|
||||||
|
.Pq roff
|
||||||
|
Comment lines start with a dot, a backslash, and a double-quote character.
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility treats the line as a comment line even without the backslash,
|
||||||
|
but leaving out the backslash might not be portable.
|
||||||
|
.It Sy "invalid escape sequence"
|
||||||
|
.Pq roff
|
||||||
|
An escape sequence has an invalid opening argument delimiter, lacks the
|
||||||
|
closing argument delimiter, or the argument has too few characters.
|
||||||
|
If the argument is incomplete,
|
||||||
|
.Ic \e*
|
||||||
|
and
|
||||||
|
.Ic \en
|
||||||
|
expand to an empty string,
|
||||||
|
.Ic \eB
|
||||||
|
to the digit
|
||||||
|
.Sq 0 ,
|
||||||
|
and
|
||||||
|
.Ic \ew
|
||||||
|
to the length of the incomplete argument.
|
||||||
|
All other invalid escape sequences are ignored.
|
||||||
|
.It Sy "undefined string, using \(dq\(dq"
|
||||||
|
.Pq roff
|
||||||
|
If a string is used without being defined before,
|
||||||
|
its value is implicitly set to the empty string.
|
||||||
|
However, defining strings explicitly before use
|
||||||
|
keeps the code more readable.
|
||||||
|
.El
|
||||||
|
.Ss "Errors related to equations"
|
||||||
|
.Bl -inset -compact
|
||||||
|
.It "unexpected equation scope closure"
|
||||||
|
.It "equation scope open on exit"
|
||||||
|
.It "overlapping equation scopes"
|
||||||
|
.It "unexpected end of equation"
|
||||||
|
.It "equation syntax error"
|
||||||
|
.El
|
||||||
|
.Ss "Errors related to tables"
|
||||||
|
.Bl -inset -compact
|
||||||
|
.It "bad table syntax"
|
||||||
|
.It "bad table option"
|
||||||
|
.It "bad table layout"
|
||||||
|
.It "no table layout cells specified"
|
||||||
|
.It "no table data cells specified"
|
||||||
|
.It "ignore data in cell"
|
||||||
|
.It "data block still open"
|
||||||
|
.It "ignoring extra data cells"
|
||||||
|
.El
|
||||||
|
.Ss "Errors related to roff, mdoc, and man code"
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "input stack limit exceeded, infinite loop?"
|
||||||
|
.Pq roff
|
||||||
|
Explicit recursion limits are implemented for the following features,
|
||||||
|
in order to prevent infinite loops:
|
||||||
|
.Bl -dash -compact
|
||||||
|
.It
|
||||||
|
expansion of nested escape sequences
|
||||||
|
including expansion of strings and number registers,
|
||||||
|
.It
|
||||||
|
expansion of nested user-defined macros,
|
||||||
|
.It
|
||||||
|
and
|
||||||
|
.Ic \&so
|
||||||
|
file inclusion.
|
||||||
|
.El
|
||||||
|
When a limit is hit, the output is incorrect, typically losing
|
||||||
|
some content, but the parser can continue.
|
||||||
|
.It Sy "skipping bad character"
|
||||||
|
.Pq mdoc , man , roff
|
||||||
|
The input file contains a byte that is not a printable
|
||||||
|
.Xr ascii 7
|
||||||
|
character.
|
||||||
|
The message mentions the character number.
|
||||||
|
The offending byte is replaced with a question mark
|
||||||
|
.Pq Sq \&? .
|
||||||
|
Consider editing the input file to replace the byte with an ASCII
|
||||||
|
transliteration of the intended character.
|
||||||
|
.It Sy "skipping unknown macro"
|
||||||
|
.Pq mdoc , man , roff
|
||||||
|
The first identifier on a request or macro line is neither recognized as a
|
||||||
|
.Xr roff 7
|
||||||
|
request, nor as a user-defined macro, nor, respectively, as an
|
||||||
|
.Xr mdoc 7
|
||||||
|
or
|
||||||
|
.Xr man 7
|
||||||
|
macro.
|
||||||
|
It may be mistyped or unsupported.
|
||||||
|
The request or macro is discarded including its arguments.
|
||||||
|
.It Sy "skipping item outside list"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&It
|
||||||
|
macro occurs outside any
|
||||||
|
.Ic \&Bl
|
||||||
|
list.
|
||||||
|
It is discarded including its arguments.
|
||||||
|
.It Sy "skipping column outside column list"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Ta
|
||||||
|
macro occurs outside any
|
||||||
|
.Ic \&Bl Fl column
|
||||||
|
block.
|
||||||
|
It is discarded including its arguments.
|
||||||
|
.It Sy "skipping end of block that is not open"
|
||||||
|
.Pq mdoc , man , eqn , tbl , roff
|
||||||
|
Various syntax elements can only be used to explicitly close blocks
|
||||||
|
that have previously been opened.
|
||||||
|
An
|
||||||
|
.Xr mdoc 7
|
||||||
|
block closing macro, a
|
||||||
|
.Xr man 7
|
||||||
|
.Ic \&RE
|
||||||
|
or
|
||||||
|
.Ic \&UE
|
||||||
|
macro, or the end of an equation, table, or
|
||||||
|
.Xr roff 7
|
||||||
|
conditional request is encountered but no matching block is open.
|
||||||
|
The offending request or macro is discarded.
|
||||||
|
.It Sy "inserting missing end of block"
|
||||||
|
.Pq mdoc , tbl
|
||||||
|
Various
|
||||||
|
.Xr mdoc 7
|
||||||
|
macros as well as tables require explicit closing by dedicated macros.
|
||||||
|
A block that doesn't support bad nesting
|
||||||
|
ends before all of its children are properly closed.
|
||||||
|
The open child nodes are closed implicitly.
|
||||||
|
.It Sy "scope open on exit"
|
||||||
|
.Pq mdoc , man , eqn , tbl , roff
|
||||||
|
At the end of the document, an explicit
|
||||||
|
.Xr mdoc 7
|
||||||
|
block, a
|
||||||
|
.Xr man 7
|
||||||
|
next-line scope or
|
||||||
|
.Ic \&RS
|
||||||
|
or
|
||||||
|
.Ic \&UR
|
||||||
|
block, an equation, table, or
|
||||||
|
.Xr roff 7
|
||||||
|
conditional or ignore block is still open.
|
||||||
|
The open block is closed implicitly.
|
||||||
|
.It Sy "escaped character not allowed in a name"
|
||||||
|
.Pq roff
|
||||||
|
Macro, string and register identifiers consist of printable,
|
||||||
|
non-whitespace ASCII characters.
|
||||||
|
Escape sequences and characters and strings expressed in terms of them
|
||||||
|
cannot form part of a name.
|
||||||
|
The first argument of an
|
||||||
|
.Ic \&am ,
|
||||||
|
.Ic \&as ,
|
||||||
|
.Ic \&de ,
|
||||||
|
.Ic \&ds ,
|
||||||
|
.Ic \&nr ,
|
||||||
|
or
|
||||||
|
.Ic \&rr
|
||||||
|
request, or any argument of an
|
||||||
|
.Ic \&rm
|
||||||
|
request, or the name of a request or user defined macro being called,
|
||||||
|
is terminated by an escape sequence.
|
||||||
|
In the cases of
|
||||||
|
.Ic \&as ,
|
||||||
|
.Ic \&ds ,
|
||||||
|
and
|
||||||
|
.Ic \&nr ,
|
||||||
|
the request has no effect at all.
|
||||||
|
In the cases of
|
||||||
|
.Ic \&am ,
|
||||||
|
.Ic \&de ,
|
||||||
|
.Ic \&rr ,
|
||||||
|
and
|
||||||
|
.Ic \&rm ,
|
||||||
|
what was parsed up to this point is used as the arguments to the request,
|
||||||
|
and the rest of the input line is discarded including the escape sequence.
|
||||||
|
When parsing for a request or a user-defined macro name to be called,
|
||||||
|
only the escape sequence is discarded.
|
||||||
|
The characters preceding it are used as the request or macro name,
|
||||||
|
the characters following it are used as the arguments to the request or macro.
|
||||||
|
.It Sy "argument count wrong"
|
||||||
|
.Pq mdoc , man , roff
|
||||||
|
The indicated request or macro has too few or too many arguments.
|
||||||
|
The syntax tree will contain the wrong number of arguments as given.
|
||||||
|
Formatting behaviour depends on the specific request or macro in question.
|
||||||
|
Note that the same message may also occur as a WARNING, see above.
|
||||||
|
.It Sy "missing list type, using -item"
|
||||||
|
.Pq mdoc
|
||||||
|
A
|
||||||
|
.Ic \&Bl
|
||||||
|
macro fails to specify the list type.
|
||||||
|
.It Sy "missing manual name, using \(dq\(dq"
|
||||||
|
.Pq mdoc
|
||||||
|
The first call to
|
||||||
|
.Ic \&Nm
|
||||||
|
lacks the required argument.
|
||||||
|
.It Sy "uname(3) system call failed, using UNKNOWN"
|
||||||
|
.Pq mdoc
|
||||||
|
The
|
||||||
|
.Ic \&Os
|
||||||
|
macro is called without arguments, and the
|
||||||
|
.Xr uname 3
|
||||||
|
system call failed.
|
||||||
|
As a workaround,
|
||||||
|
.Nm
|
||||||
|
can be compiled with
|
||||||
|
.Sm off
|
||||||
|
.Fl D Cm OSNAME=\(dq\e\(dq Ar string Cm \e\(dq\(dq .
|
||||||
|
.Sm on
|
||||||
|
.It Sy "unknown standard specifier"
|
||||||
|
.Pq mdoc
|
||||||
|
An
|
||||||
|
.Ic \&St
|
||||||
|
macro has an unknown argument and is discarded.
|
||||||
|
.It Sy "skipping request without numeric argument"
|
||||||
|
.Pq roff
|
||||||
|
An
|
||||||
|
.Ic \&it
|
||||||
|
request has a non-numeric or negative argument or no argument at all.
|
||||||
|
The invalid request is ignored.
|
||||||
|
.It Sy "skipping all arguments"
|
||||||
|
.Pq mdoc , man , eqn , roff
|
||||||
|
An
|
||||||
|
.Xr mdoc 7
|
||||||
|
.Ic \&Bt ,
|
||||||
|
.Ic \&Ed ,
|
||||||
|
.Ic \&Ef ,
|
||||||
|
.Ic \&Ek ,
|
||||||
|
.Ic \&El ,
|
||||||
|
.Ic \&Re ,
|
||||||
|
or
|
||||||
|
.Ic \&Ud
|
||||||
|
macro, an
|
||||||
|
.Ic \&It
|
||||||
|
macro in a list that don't support item heads, a
|
||||||
|
.Xr man 7
|
||||||
|
.Ic \&LP ,
|
||||||
|
.Ic \&P ,
|
||||||
|
or
|
||||||
|
.Ic \&PP
|
||||||
|
macro, an
|
||||||
|
.Xr eqn 7
|
||||||
|
.Ic \&EN
|
||||||
|
macro, or a
|
||||||
|
.Xr roff 7
|
||||||
|
.Sq \&..
|
||||||
|
block closing request is invoked with at least one argument.
|
||||||
|
All arguments are ignored.
|
||||||
|
.It Sy "skipping excess arguments"
|
||||||
|
.Pq mdoc , roff
|
||||||
|
The
|
||||||
|
.Ic \&Bf
|
||||||
|
macro is invoked with more than one argument, or a request of the
|
||||||
|
.Ic \&de
|
||||||
|
family is invoked with more than two arguments.
|
||||||
|
The excess arguments are ignored.
|
||||||
|
.El
|
||||||
|
.Ss FATAL errors
|
||||||
|
.Bl -ohang
|
||||||
|
.It Sy "input too large"
|
||||||
|
.Pq mdoc , man
|
||||||
|
Currently,
|
||||||
|
.Nm
|
||||||
|
cannot handle input files larger than its arbitrary size limit
|
||||||
|
of 2^31 bytes (2 Gigabytes).
|
||||||
|
Since useful manuals are always small, this is not a problem in practice.
|
||||||
|
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"
|
||||||
|
.Pq roff
|
||||||
|
For security reasons,
|
||||||
|
.Nm
|
||||||
|
allows
|
||||||
|
.Ic \&so
|
||||||
|
file inclusion requests only with relative paths
|
||||||
|
and only without ascending to any parent directory.
|
||||||
|
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 ".so request failed"
|
||||||
|
.Pq roff
|
||||||
|
Servicing a
|
||||||
|
.Ic \&so
|
||||||
|
request requires reading an external file.
|
||||||
|
While trying to do so, an
|
||||||
|
.Xr open 2 ,
|
||||||
|
.Xr stat 2 ,
|
||||||
|
or
|
||||||
|
.Xr read 2
|
||||||
|
system call failed.
|
||||||
|
The parser exits immediately.
|
||||||
|
Before showing this message,
|
||||||
|
.Nm
|
||||||
|
always shows another message explaining why the system call failed.
|
||||||
|
.El
|
||||||
.Sh COMPATIBILITY
|
.Sh COMPATIBILITY
|
||||||
This section summarises
|
This section summarises
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mandoc.3,v 1.22 2013/10/06 17:01:52 schwarze Exp $
|
.\" $Id: mandoc.3,v 1.25 2014/08/05 05:48:56 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,21 +15,16 @@
|
|||||||
.\" 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: October 6 2013 $
|
.Dd $Mdocdate: August 5 2014 $
|
||||||
.Dt MANDOC 3
|
.Dt MANDOC 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm mandoc ,
|
.Nm mandoc ,
|
||||||
.Nm mandoc_escape ,
|
.Nm man_deroff ,
|
||||||
.Nm man_meta ,
|
.Nm man_meta ,
|
||||||
.Nm man_mparse ,
|
.Nm man_mparse ,
|
||||||
.Nm man_node ,
|
.Nm man_node ,
|
||||||
.Nm mchars_alloc ,
|
.Nm mdoc_deroff ,
|
||||||
.Nm mchars_free ,
|
|
||||||
.Nm mchars_num2char ,
|
|
||||||
.Nm mchars_num2uc ,
|
|
||||||
.Nm mchars_spec2cp ,
|
|
||||||
.Nm mchars_spec2str ,
|
|
||||||
.Nm mdoc_meta ,
|
.Nm mdoc_meta ,
|
||||||
.Nm mdoc_node ,
|
.Nm mdoc_node ,
|
||||||
.Nm mparse_alloc ,
|
.Nm mparse_alloc ,
|
||||||
@ -45,68 +40,32 @@
|
|||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
.Lb libmandoc
|
.Lb libmandoc
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In man.h
|
.In sys/types.h
|
||||||
.In mdoc.h
|
|
||||||
.In mandoc.h
|
.In mandoc.h
|
||||||
.Ft "enum mandoc_esc"
|
.Fd "#define ASCII_NBRSP"
|
||||||
.Fo mandoc_escape
|
.Fd "#define ASCII_HYPH"
|
||||||
.Fa "const char const **end"
|
.Fd "#define ASCII_BREAK"
|
||||||
.Fa "const char const **start"
|
.Ft struct mparse *
|
||||||
.Fa "int *sz"
|
|
||||||
.Fc
|
|
||||||
.Ft "const struct man_meta *"
|
|
||||||
.Fo man_meta
|
|
||||||
.Fa "const struct man *man"
|
|
||||||
.Fc
|
|
||||||
.Ft "const struct mparse *"
|
|
||||||
.Fo man_mparse
|
|
||||||
.Fa "const struct man *man"
|
|
||||||
.Fc
|
|
||||||
.Ft "const struct man_node *"
|
|
||||||
.Fo man_node
|
|
||||||
.Fa "const struct man *man"
|
|
||||||
.Fc
|
|
||||||
.Ft "struct mchars *"
|
|
||||||
.Fn mchars_alloc "void"
|
|
||||||
.Ft void
|
|
||||||
.Fn mchars_free "struct mchars *p"
|
|
||||||
.Ft char
|
|
||||||
.Fn mchars_num2char "const char *cp" "size_t sz"
|
|
||||||
.Ft int
|
|
||||||
.Fn mchars_num2uc "const char *cp" "size_t sz"
|
|
||||||
.Ft "const char *"
|
|
||||||
.Fo mchars_spec2str
|
|
||||||
.Fa "const struct mchars *p"
|
|
||||||
.Fa "const char *cp"
|
|
||||||
.Fa "size_t sz"
|
|
||||||
.Fa "size_t *rsz"
|
|
||||||
.Fc
|
|
||||||
.Ft int
|
|
||||||
.Fo mchars_spec2cp
|
|
||||||
.Fa "const struct mchars *p"
|
|
||||||
.Fa "const char *cp"
|
|
||||||
.Fa "size_t sz"
|
|
||||||
.Fc
|
|
||||||
.Ft "const struct mdoc_meta *"
|
|
||||||
.Fo mdoc_meta
|
|
||||||
.Fa "const struct mdoc *mdoc"
|
|
||||||
.Fc
|
|
||||||
.Ft "const struct mdoc_node *"
|
|
||||||
.Fo mdoc_node
|
|
||||||
.Fa "const struct mdoc *mdoc"
|
|
||||||
.Fc
|
|
||||||
.Ft void
|
|
||||||
.Fo mparse_alloc
|
.Fo mparse_alloc
|
||||||
.Fa "enum mparset type"
|
.Fa "int options"
|
||||||
.Fa "enum mandoclevel wlevel"
|
.Fa "enum mandoclevel wlevel"
|
||||||
.Fa "mandocmsg msg"
|
.Fa "mandocmsg mmsg"
|
||||||
.Fa "void *msgarg"
|
.Fa "char *defos"
|
||||||
|
.Fc
|
||||||
|
.Ft void
|
||||||
|
.Fo (*mandocmsg)
|
||||||
|
.Fa "enum mandocerr errtype"
|
||||||
|
.Fa "enum mandoclevel level"
|
||||||
|
.Fa "const char *file"
|
||||||
|
.Fa "int line"
|
||||||
|
.Fa "int col"
|
||||||
|
.Fa "const char *msg"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft void
|
.Ft void
|
||||||
.Fo mparse_free
|
.Fo mparse_free
|
||||||
.Fa "struct mparse *parse"
|
.Fa "struct mparse *parse"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft void
|
.Ft const char *
|
||||||
.Fo mparse_getkeep
|
.Fo mparse_getkeep
|
||||||
.Fa "const struct mparse *parse"
|
.Fa "const struct mparse *parse"
|
||||||
.Fc
|
.Fc
|
||||||
@ -129,6 +88,7 @@
|
|||||||
.Fa "struct mparse *parse"
|
.Fa "struct mparse *parse"
|
||||||
.Fa "struct mdoc **mdoc"
|
.Fa "struct mdoc **mdoc"
|
||||||
.Fa "struct man **man"
|
.Fa "struct man **man"
|
||||||
|
.Fa "char **sodest"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft "const char *"
|
.Ft "const char *"
|
||||||
.Fo mparse_strerror
|
.Fo mparse_strerror
|
||||||
@ -138,11 +98,45 @@
|
|||||||
.Fo mparse_strlevel
|
.Fo mparse_strlevel
|
||||||
.Fa "enum mandoclevel"
|
.Fa "enum mandoclevel"
|
||||||
.Fc
|
.Fc
|
||||||
.Vt extern const char * const * man_macronames;
|
.In sys/types.h
|
||||||
|
.In mandoc.h
|
||||||
|
.In mdoc.h
|
||||||
|
.Ft void
|
||||||
|
.Fo mdoc_deroff
|
||||||
|
.Fa "char **dest"
|
||||||
|
.Fa "const struct mdoc_node *node"
|
||||||
|
.Fc
|
||||||
|
.Ft "const struct mdoc_meta *"
|
||||||
|
.Fo mdoc_meta
|
||||||
|
.Fa "const struct mdoc *mdoc"
|
||||||
|
.Fc
|
||||||
|
.Ft "const struct mdoc_node *"
|
||||||
|
.Fo mdoc_node
|
||||||
|
.Fa "const struct mdoc *mdoc"
|
||||||
|
.Fc
|
||||||
.Vt extern const char * const * mdoc_argnames;
|
.Vt extern const char * const * mdoc_argnames;
|
||||||
.Vt extern const char * const * mdoc_macronames;
|
.Vt extern const char * const * mdoc_macronames;
|
||||||
.Fd "#define ASCII_NBRSP"
|
.In sys/types.h
|
||||||
.Fd "#define ASCII_HYPH"
|
.In mandoc.h
|
||||||
|
.In man.h
|
||||||
|
.Ft void
|
||||||
|
.Fo man_deroff
|
||||||
|
.Fa "char **dest"
|
||||||
|
.Fa "const struct man_node *node"
|
||||||
|
.Fc
|
||||||
|
.Ft "const struct man_meta *"
|
||||||
|
.Fo man_meta
|
||||||
|
.Fa "const struct man *man"
|
||||||
|
.Fc
|
||||||
|
.Ft "const struct mparse *"
|
||||||
|
.Fo man_mparse
|
||||||
|
.Fa "const struct man *man"
|
||||||
|
.Fc
|
||||||
|
.Ft "const struct man_node *"
|
||||||
|
.Fo man_node
|
||||||
|
.Fa "const struct man *man"
|
||||||
|
.Fc
|
||||||
|
.Vt extern const char * const * man_macronames;
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Nm mandoc
|
.Nm mandoc
|
||||||
@ -184,37 +178,22 @@ or invoke
|
|||||||
.Fn mparse_reset
|
.Fn mparse_reset
|
||||||
and parse new files.
|
and parse new files.
|
||||||
.El
|
.El
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
library also contains routines for translating character strings into glyphs
|
|
||||||
.Pq see Fn mchars_alloc
|
|
||||||
and parsing escape sequences from strings
|
|
||||||
.Pq see Fn mandoc_escape .
|
|
||||||
.Sh REFERENCE
|
.Sh REFERENCE
|
||||||
This section documents the functions, types, and variables available
|
This section documents the functions, types, and variables available
|
||||||
via
|
via
|
||||||
.In mandoc.h .
|
.In mandoc.h ,
|
||||||
|
with the exception of those documented in
|
||||||
|
.Xr mandoc_escape 3
|
||||||
|
and
|
||||||
|
.Xr mchars_alloc 3 .
|
||||||
.Ss Types
|
.Ss Types
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
.It Vt "enum mandoc_esc"
|
|
||||||
An escape sequence classification.
|
|
||||||
.It Vt "enum mandocerr"
|
.It Vt "enum mandocerr"
|
||||||
A fatal error, error, or warning message during parsing.
|
A fatal error, error, or warning message during parsing.
|
||||||
.It Vt "enum mandoclevel"
|
.It Vt "enum mandoclevel"
|
||||||
A classification of an
|
A classification of an
|
||||||
.Vt "enum mandoclevel"
|
.Vt "enum mandocerr"
|
||||||
as regards system operation.
|
as regards system operation.
|
||||||
.It Vt "struct mchars"
|
|
||||||
An opaque pointer to an object allowing for translation between
|
|
||||||
character strings and glyphs.
|
|
||||||
See
|
|
||||||
.Fn mchars_alloc .
|
|
||||||
.It Vt "enum mparset"
|
|
||||||
The type of parser when reading input.
|
|
||||||
This should usually be
|
|
||||||
.Dv MPARSE_AUTO
|
|
||||||
for auto-detection.
|
|
||||||
.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
|
||||||
@ -230,38 +209,20 @@ messages emitted by the parser.
|
|||||||
.El
|
.El
|
||||||
.Ss Functions
|
.Ss Functions
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
.It Fn mandoc_escape
|
.It Fn man_deroff
|
||||||
Scan an escape sequence, i.e., a character string beginning with
|
Obtain a text-only representation of a
|
||||||
.Sq \e .
|
.Vt struct man_node ,
|
||||||
Pass a pointer to the character after the
|
including text contained in its child nodes.
|
||||||
.Sq \e
|
To be used on children of the pointer returned from
|
||||||
as
|
.Fn man_node .
|
||||||
.Va end ;
|
When it is no longer needed, the pointer returned from
|
||||||
it will be set to the supremum of the parsed escape sequence unless
|
.Fn man_deroff
|
||||||
returning
|
can be passed to
|
||||||
.Dv ESCAPE_ERROR ,
|
.Xr free 3 .
|
||||||
in which case the string is bogus and should be
|
|
||||||
thrown away.
|
|
||||||
If not
|
|
||||||
.Dv ESCAPE_ERROR
|
|
||||||
or
|
|
||||||
.Dv ESCAPE_IGNORE ,
|
|
||||||
.Va start
|
|
||||||
is set to the first relevant character of the substring (font, glyph,
|
|
||||||
whatever) of length
|
|
||||||
.Va sz .
|
|
||||||
Both
|
|
||||||
.Va start
|
|
||||||
and
|
|
||||||
.Va sz
|
|
||||||
may be
|
|
||||||
.Dv NULL .
|
|
||||||
Declared in
|
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa mandoc.c .
|
|
||||||
.It Fn man_meta
|
.It Fn man_meta
|
||||||
Obtain the meta-data of a successful parse.
|
Obtain the meta-data of a successful
|
||||||
|
.Xr man 7
|
||||||
|
parse.
|
||||||
This may only be used on a pointer returned by
|
This may only be used on a pointer returned by
|
||||||
.Fn mparse_result .
|
.Fn mparse_result .
|
||||||
Declared in
|
Declared in
|
||||||
@ -275,67 +236,29 @@ Declared in
|
|||||||
implemented in
|
implemented in
|
||||||
.Pa man.c .
|
.Pa man.c .
|
||||||
.It Fn man_node
|
.It Fn man_node
|
||||||
Obtain the root node of a successful parse.
|
Obtain the root node of a successful
|
||||||
|
.Xr man 7
|
||||||
|
parse.
|
||||||
This may only be used on a pointer returned by
|
This may only be used on a pointer returned by
|
||||||
.Fn mparse_result .
|
.Fn mparse_result .
|
||||||
Declared in
|
Declared in
|
||||||
.In man.h ,
|
.In man.h ,
|
||||||
implemented in
|
implemented in
|
||||||
.Pa man.c .
|
.Pa man.c .
|
||||||
.It Fn mchars_alloc
|
.It Fn mdoc_deroff
|
||||||
Allocate an
|
Obtain a text-only representation of a
|
||||||
.Vt "struct mchars *"
|
.Vt struct mdoc_node ,
|
||||||
object for translating special characters into glyphs.
|
including text contained in its child nodes.
|
||||||
See
|
To be used on children of the pointer returned from
|
||||||
.Xr mandoc_char 7
|
.Fn mdoc_node .
|
||||||
for an overview of special characters.
|
When it is no longer needed, the pointer returned from
|
||||||
The object must be freed with
|
.Fn mdoc_deroff
|
||||||
.Fn mchars_free .
|
can be passed to
|
||||||
Declared in
|
.Xr free 3 .
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa chars.c .
|
|
||||||
.It Fn mchars_free
|
|
||||||
Free an object created with
|
|
||||||
.Fn mchars_alloc .
|
|
||||||
Declared in
|
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa chars.c .
|
|
||||||
.It Fn mchars_num2char
|
|
||||||
Convert a character index (e.g., the \eN\(aq\(aq escape) into a
|
|
||||||
printable ASCII character.
|
|
||||||
Returns \e0 (the nil character) if the input sequence is malformed.
|
|
||||||
Declared in
|
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa chars.c .
|
|
||||||
.It Fn mchars_num2uc
|
|
||||||
Convert a hexadecimal character index (e.g., the \e[uNNNN] escape) into
|
|
||||||
a Unicode codepoint.
|
|
||||||
Returns \e0 (the nil character) if the input sequence is malformed.
|
|
||||||
Declared in
|
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa chars.c .
|
|
||||||
.It Fn mchars_spec2cp
|
|
||||||
Convert a special character into a valid Unicode codepoint.
|
|
||||||
Returns \-1 on failure or a non-zero Unicode codepoint on success.
|
|
||||||
Declared in
|
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa chars.c .
|
|
||||||
.It Fn mchars_spec2str
|
|
||||||
Convert a special character into an ASCII string.
|
|
||||||
Returns
|
|
||||||
.Dv NULL
|
|
||||||
on failure.
|
|
||||||
Declared in
|
|
||||||
.In mandoc.h ,
|
|
||||||
implemented in
|
|
||||||
.Pa chars.c .
|
|
||||||
.It Fn mdoc_meta
|
.It Fn mdoc_meta
|
||||||
Obtain the meta-data of a successful parse.
|
Obtain the meta-data of a successful
|
||||||
|
.Xr mdoc
|
||||||
|
parse.
|
||||||
This may only be used on a pointer returned by
|
This may only be used on a pointer returned by
|
||||||
.Fn mparse_result .
|
.Fn mparse_result .
|
||||||
Declared in
|
Declared in
|
||||||
@ -343,7 +266,9 @@ Declared in
|
|||||||
implemented in
|
implemented in
|
||||||
.Pa mdoc.c .
|
.Pa mdoc.c .
|
||||||
.It Fn mdoc_node
|
.It Fn mdoc_node
|
||||||
Obtain the root node of a successful parse.
|
Obtain the root node of a successful
|
||||||
|
.Xr mdoc
|
||||||
|
parse.
|
||||||
This may only be used on a pointer returned by
|
This may only be used on a pointer returned by
|
||||||
.Fn mparse_result .
|
.Fn mparse_result .
|
||||||
Declared in
|
Declared in
|
||||||
@ -352,6 +277,57 @@ implemented in
|
|||||||
.Pa mdoc.c .
|
.Pa mdoc.c .
|
||||||
.It Fn mparse_alloc
|
.It Fn mparse_alloc
|
||||||
Allocate a parser.
|
Allocate a parser.
|
||||||
|
The arguments have the following effect:
|
||||||
|
.Bl -tag -offset 5n -width inttype
|
||||||
|
.It Ar options
|
||||||
|
When the
|
||||||
|
.Dv MPARSE_MDOC
|
||||||
|
or
|
||||||
|
.Dv MPARSE_MAN
|
||||||
|
bit is set, only that parser is used.
|
||||||
|
Otherwise, the document type is automatically detected.
|
||||||
|
.Pp
|
||||||
|
When the
|
||||||
|
.Dv MPARSE_SO
|
||||||
|
bit is set,
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \&so
|
||||||
|
file inclusion requests are always honoured.
|
||||||
|
Otherwise, if the request is the only content in an input file,
|
||||||
|
only the file name is remembered, to be returned in the
|
||||||
|
.Fa sodest
|
||||||
|
argument of
|
||||||
|
.Fn mparse_result .
|
||||||
|
.Pp
|
||||||
|
When the
|
||||||
|
.Dv MPARSE_QUICK
|
||||||
|
bit is set, parsing is aborted after the NAME section.
|
||||||
|
This is for example useful in
|
||||||
|
.Xr makewhatis 8
|
||||||
|
.Fl Q
|
||||||
|
to quickly build minimal databases.
|
||||||
|
.It Ar wlevel
|
||||||
|
Can be set to
|
||||||
|
.Dv MANDOCLEVEL_FATAL ,
|
||||||
|
.Dv MANDOCLEVEL_ERROR ,
|
||||||
|
or
|
||||||
|
.Dv MANDOCLEVEL_WARNING .
|
||||||
|
Messages below the selected level will be suppressed.
|
||||||
|
.It Ar mmsg
|
||||||
|
A callback function to handle errors and warnings.
|
||||||
|
See
|
||||||
|
.Pa main.c
|
||||||
|
for an example.
|
||||||
|
.It Ar defos
|
||||||
|
A default string for the
|
||||||
|
.Xr mdoc 7
|
||||||
|
.Sq \&Os
|
||||||
|
macro, overriding the
|
||||||
|
.Dv OSNAME
|
||||||
|
preprocessor definition and the results of
|
||||||
|
.Xr uname 3 .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
The same parser may be used for multiple files so long as
|
The same parser may be used for multiple files so long as
|
||||||
.Fn mparse_reset
|
.Fn mparse_reset
|
||||||
is called between parses.
|
is called between parses.
|
||||||
@ -419,7 +395,7 @@ i.e., those where
|
|||||||
.Fn mparse_readfd
|
.Fn mparse_readfd
|
||||||
returned less than MANDOCLEVEL_FATAL
|
returned less than MANDOCLEVEL_FATAL
|
||||||
.Pc
|
.Pc
|
||||||
should invoke this function, in which case one of the two pointers will
|
should invoke this function, in which case one of the three pointers will
|
||||||
be filled in.
|
be filled in.
|
||||||
Declared in
|
Declared in
|
||||||
.In mandoc.h ,
|
.In mandoc.h ,
|
||||||
@ -473,6 +449,8 @@ The following non-printing characters may be embedded in text strings:
|
|||||||
A non-breaking space character.
|
A non-breaking space character.
|
||||||
.It Dv ASCII_HYPH
|
.It Dv ASCII_HYPH
|
||||||
A soft hyphen.
|
A soft hyphen.
|
||||||
|
.It Dv ASCII_BREAK
|
||||||
|
A breakable zero-width space.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Escape characters are also passed verbatim into text strings.
|
Escape characters are also passed verbatim into text strings.
|
||||||
@ -480,11 +458,9 @@ An escape character is a sequence of characters beginning with the
|
|||||||
backslash
|
backslash
|
||||||
.Pq Sq \e .
|
.Pq Sq \e .
|
||||||
To construct human-readable text, these should be intercepted with
|
To construct human-readable text, these should be intercepted with
|
||||||
.Fn mandoc_escape
|
.Xr mandoc_escape 3
|
||||||
and converted with one of
|
and converted with one the functions described in
|
||||||
.Fn mchars_num2char ,
|
.Xr mchars_alloc 3 .
|
||||||
.Fn mchars_spec2str ,
|
|
||||||
and so on.
|
|
||||||
.Ss Man Abstract Syntax Tree
|
.Ss Man Abstract Syntax Tree
|
||||||
This AST is governed by the ontological rules dictated in
|
This AST is governed by the ontological rules dictated in
|
||||||
.Xr man 7
|
.Xr man 7
|
||||||
@ -529,7 +505,7 @@ where capitalised non-terminals represent nodes.
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The only elements capable of nesting other elements are those with
|
The only elements capable of nesting other elements are those with
|
||||||
next-lint scope as documented in
|
next-line scope as documented in
|
||||||
.Xr man 7 .
|
.Xr man 7 .
|
||||||
.Ss Mdoc Abstract Syntax Tree
|
.Ss Mdoc Abstract Syntax Tree
|
||||||
This AST is governed by the ontological
|
This AST is governed by the ontological
|
||||||
@ -669,6 +645,9 @@ consistent across troff implementations, especially when using multiple
|
|||||||
levels of badly-nested blocks.
|
levels of badly-nested blocks.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr mandoc 1 ,
|
.Xr mandoc 1 ,
|
||||||
|
.Xr mandoc_escape 3 ,
|
||||||
|
.Xr mandoc_malloc 3 ,
|
||||||
|
.Xr mchars_alloc 3 ,
|
||||||
.Xr eqn 7 ,
|
.Xr eqn 7 ,
|
||||||
.Xr man 7 ,
|
.Xr man 7 ,
|
||||||
.Xr mandoc_char 7 ,
|
.Xr mandoc_char 7 ,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: mandoc.c,v 1.74 2013/12/30 18:30:32 schwarze Exp $ */
|
/* $Id: mandoc.c,v 1.83 2014/07/06 19:09:00 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 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
|
|
||||||
#define DATESIZE 32
|
#define DATESIZE 32
|
||||||
@ -74,11 +75,11 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
* these, but each eventually returns a substring of the glyph
|
* these, but each eventually returns a substring of the glyph
|
||||||
* name.
|
* name.
|
||||||
*/
|
*/
|
||||||
case ('('):
|
case '(':
|
||||||
gly = ESCAPE_SPECIAL;
|
gly = ESCAPE_SPECIAL;
|
||||||
*sz = 2;
|
*sz = 2;
|
||||||
break;
|
break;
|
||||||
case ('['):
|
case '[':
|
||||||
gly = ESCAPE_SPECIAL;
|
gly = ESCAPE_SPECIAL;
|
||||||
/*
|
/*
|
||||||
* Unicode escapes are defined in groff as \[uXXXX] to
|
* Unicode escapes are defined in groff as \[uXXXX] to
|
||||||
@ -90,7 +91,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
gly = ESCAPE_UNICODE;
|
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;
|
||||||
@ -104,9 +105,9 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
/*
|
/*
|
||||||
* Escapes taking no arguments at all.
|
* Escapes taking no arguments at all.
|
||||||
*/
|
*/
|
||||||
case ('d'):
|
case 'd':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('u'):
|
case 'u':
|
||||||
return(ESCAPE_IGNORE);
|
return(ESCAPE_IGNORE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,39 +116,39 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
* Since we are mostly dealing with terminal mode,
|
* Since we are mostly dealing with terminal mode,
|
||||||
* let us just skip the next character.
|
* let us just skip the next character.
|
||||||
*/
|
*/
|
||||||
case ('z'):
|
case 'z':
|
||||||
return(ESCAPE_SKIPCHAR);
|
return(ESCAPE_SKIPCHAR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
|
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
|
||||||
* 'X' is the trigger. These have opaque sub-strings.
|
* 'X' is the trigger. These have opaque sub-strings.
|
||||||
*/
|
*/
|
||||||
case ('F'):
|
case 'F':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('g'):
|
case 'g':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('k'):
|
case 'k':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('M'):
|
case 'M':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('m'):
|
case 'm':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('n'):
|
case 'n':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('V'):
|
case 'V':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('Y'):
|
case 'Y':
|
||||||
gly = ESCAPE_IGNORE;
|
gly = ESCAPE_IGNORE;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('f'):
|
case 'f':
|
||||||
if (ESCAPE_ERROR == gly)
|
if (ESCAPE_ERROR == gly)
|
||||||
gly = ESCAPE_FONT;
|
gly = ESCAPE_FONT;
|
||||||
switch (**start) {
|
switch (**start) {
|
||||||
case ('('):
|
case '(':
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
*sz = 2;
|
*sz = 2;
|
||||||
break;
|
break;
|
||||||
case ('['):
|
case '[':
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
term = ']';
|
term = ']';
|
||||||
break;
|
break;
|
||||||
@ -160,60 +161,59 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
/*
|
/*
|
||||||
* These escapes are of the form \X'Y', where 'X' is the trigger
|
* These escapes are of the form \X'Y', where 'X' is the trigger
|
||||||
* and 'Y' is any string. These have opaque sub-strings.
|
* and 'Y' is any string. These have opaque sub-strings.
|
||||||
|
* The \B and \w escapes are handled in roff.c, roff_res().
|
||||||
*/
|
*/
|
||||||
case ('A'):
|
case 'A':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('b'):
|
case 'b':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('B'):
|
case 'D':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('D'):
|
case 'o':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('o'):
|
case 'R':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('R'):
|
case 'X':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('w'):
|
case 'Z':
|
||||||
/* FALLTHROUGH */
|
if ('\0' == **start)
|
||||||
case ('X'):
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case ('Z'):
|
|
||||||
if ('\'' != **start)
|
|
||||||
return(ESCAPE_ERROR);
|
return(ESCAPE_ERROR);
|
||||||
gly = ESCAPE_IGNORE;
|
gly = ESCAPE_IGNORE;
|
||||||
|
term = **start;
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
term = '\'';
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These escapes are of the form \X'N', where 'X' is the trigger
|
* These escapes are of the form \X'N', where 'X' is the trigger
|
||||||
* and 'N' resolves to a numerical expression.
|
* and 'N' resolves to a numerical expression.
|
||||||
*/
|
*/
|
||||||
case ('h'):
|
case 'h':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('H'):
|
case 'H':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('L'):
|
case 'L':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('l'):
|
case 'l':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('S'):
|
case 'S':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('v'):
|
case 'v':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('x'):
|
case 'x':
|
||||||
if ('\'' != **start)
|
if (strchr(" %&()*+-./0123456789:<=>", **start)) {
|
||||||
|
++*end;
|
||||||
return(ESCAPE_ERROR);
|
return(ESCAPE_ERROR);
|
||||||
|
}
|
||||||
gly = ESCAPE_IGNORE;
|
gly = ESCAPE_IGNORE;
|
||||||
|
term = **start;
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
term = '\'';
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special handling for the numbered character escape.
|
* Special handling for the numbered character escape.
|
||||||
* XXX Do any other escapes need similar handling?
|
* XXX Do any other escapes need similar handling?
|
||||||
*/
|
*/
|
||||||
case ('N'):
|
case 'N':
|
||||||
if ('\0' == **start)
|
if ('\0' == **start)
|
||||||
return(ESCAPE_ERROR);
|
return(ESCAPE_ERROR);
|
||||||
(*end)++;
|
(*end)++;
|
||||||
@ -232,7 +232,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
/*
|
/*
|
||||||
* Sizes get a special category of their own.
|
* Sizes get a special category of their own.
|
||||||
*/
|
*/
|
||||||
case ('s'):
|
case 's':
|
||||||
gly = ESCAPE_IGNORE;
|
gly = ESCAPE_IGNORE;
|
||||||
|
|
||||||
/* See +/- counts as a sign. */
|
/* See +/- counts as a sign. */
|
||||||
@ -240,15 +240,15 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
(*end)++;
|
(*end)++;
|
||||||
|
|
||||||
switch (**end) {
|
switch (**end) {
|
||||||
case ('('):
|
case '(':
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
*sz = 2;
|
*sz = 2;
|
||||||
break;
|
break;
|
||||||
case ('['):
|
case '[':
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
term = ']';
|
term = ']';
|
||||||
break;
|
break;
|
||||||
case ('\''):
|
case '\'':
|
||||||
*start = ++*end;
|
*start = ++*end;
|
||||||
term = '\'';
|
term = '\'';
|
||||||
break;
|
break;
|
||||||
@ -280,9 +280,9 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
if ('\0' != term) {
|
if ('\0' != term) {
|
||||||
while (**end != term) {
|
while (**end != term) {
|
||||||
switch (**end) {
|
switch (**end) {
|
||||||
case ('\0'):
|
case '\0':
|
||||||
return(ESCAPE_ERROR);
|
return(ESCAPE_ERROR);
|
||||||
case ('\\'):
|
case '\\':
|
||||||
(*end)++;
|
(*end)++;
|
||||||
if (ESCAPE_ERROR ==
|
if (ESCAPE_ERROR ==
|
||||||
mandoc_escape(end, NULL, NULL))
|
mandoc_escape(end, NULL, NULL))
|
||||||
@ -304,7 +304,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
/* Run post-processors. */
|
/* Run post-processors. */
|
||||||
|
|
||||||
switch (gly) {
|
switch (gly) {
|
||||||
case (ESCAPE_FONT):
|
case ESCAPE_FONT:
|
||||||
if (2 == *sz) {
|
if (2 == *sz) {
|
||||||
if ('C' == **start) {
|
if ('C' == **start) {
|
||||||
/*
|
/*
|
||||||
@ -322,27 +322,27 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
switch (**start) {
|
switch (**start) {
|
||||||
case ('3'):
|
case '3':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('B'):
|
case 'B':
|
||||||
gly = ESCAPE_FONTBOLD;
|
gly = ESCAPE_FONTBOLD;
|
||||||
break;
|
break;
|
||||||
case ('2'):
|
case '2':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('I'):
|
case 'I':
|
||||||
gly = ESCAPE_FONTITALIC;
|
gly = ESCAPE_FONTITALIC;
|
||||||
break;
|
break;
|
||||||
case ('P'):
|
case 'P':
|
||||||
gly = ESCAPE_FONTPREV;
|
gly = ESCAPE_FONTPREV;
|
||||||
break;
|
break;
|
||||||
case ('1'):
|
case '1':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('R'):
|
case 'R':
|
||||||
gly = ESCAPE_FONTROMAN;
|
gly = ESCAPE_FONTROMAN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_SPECIAL):
|
case ESCAPE_SPECIAL:
|
||||||
if (1 == *sz && 'c' == **start)
|
if (1 == *sz && 'c' == **start)
|
||||||
gly = ESCAPE_NOSPACE;
|
gly = ESCAPE_NOSPACE;
|
||||||
break;
|
break;
|
||||||
@ -353,74 +353,6 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||||||
return(gly);
|
return(gly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
mandoc_calloc(size_t num, size_t size)
|
|
||||||
{
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
ptr = calloc(num, size);
|
|
||||||
if (NULL == ptr) {
|
|
||||||
perror(NULL);
|
|
||||||
exit((int)MANDOCLEVEL_SYSERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *
|
|
||||||
mandoc_malloc(size_t size)
|
|
||||||
{
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
ptr = malloc(size);
|
|
||||||
if (NULL == ptr) {
|
|
||||||
perror(NULL);
|
|
||||||
exit((int)MANDOCLEVEL_SYSERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *
|
|
||||||
mandoc_realloc(void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
|
|
||||||
ptr = realloc(ptr, size);
|
|
||||||
if (NULL == ptr) {
|
|
||||||
perror(NULL);
|
|
||||||
exit((int)MANDOCLEVEL_SYSERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
mandoc_strndup(const char *ptr, size_t sz)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
p = mandoc_malloc(sz + 1);
|
|
||||||
memcpy(p, ptr, sz);
|
|
||||||
p[(int)sz] = '\0';
|
|
||||||
return(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
mandoc_strdup(const char *ptr)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
p = strdup(ptr);
|
|
||||||
if (NULL == p) {
|
|
||||||
perror(NULL);
|
|
||||||
exit((int)MANDOCLEVEL_SYSERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a quoted or unquoted roff-style request or macro argument.
|
* Parse a quoted or unquoted roff-style request or macro argument.
|
||||||
* Return a pointer to the parsed argument, which is either the original
|
* Return a pointer to the parsed argument, which is either the original
|
||||||
@ -461,14 +393,14 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
|||||||
* backslashes and backslash-t to literal tabs.
|
* backslashes and backslash-t to literal tabs.
|
||||||
*/
|
*/
|
||||||
switch (cp[1]) {
|
switch (cp[1]) {
|
||||||
case ('t'):
|
case 't':
|
||||||
cp[0] = '\t';
|
cp[0] = '\t';
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('\\'):
|
case '\\':
|
||||||
pairs++;
|
pairs++;
|
||||||
cp++;
|
cp++;
|
||||||
break;
|
break;
|
||||||
case (' '):
|
case ' ':
|
||||||
/* Skip escaped blanks. */
|
/* Skip escaped blanks. */
|
||||||
if (0 == quoted)
|
if (0 == quoted)
|
||||||
cp++;
|
cp++;
|
||||||
@ -497,7 +429,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
|||||||
|
|
||||||
/* Quoted argument without a closing quote. */
|
/* Quoted argument without a closing quote. */
|
||||||
if (1 == quoted)
|
if (1 == quoted)
|
||||||
mandoc_msg(MANDOCERR_BADQUOTE, parse, ln, *pos, NULL);
|
mandoc_msg(MANDOCERR_ARG_QUOTE, parse, ln, *pos, NULL);
|
||||||
|
|
||||||
/* NUL-terminate this argument and move to the next one. */
|
/* NUL-terminate this argument and move to the next one. */
|
||||||
if (pairs)
|
if (pairs)
|
||||||
@ -511,7 +443,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
|||||||
*cpp = cp;
|
*cpp = cp;
|
||||||
|
|
||||||
if ('\0' == *cp && (white || ' ' == cp[-1]))
|
if ('\0' == *cp && (white || ' ' == cp[-1]))
|
||||||
mandoc_msg(MANDOCERR_EOLNSPACE, parse, ln, *pos, NULL);
|
mandoc_msg(MANDOCERR_SPACE_EOL, parse, ln, *pos, NULL);
|
||||||
|
|
||||||
return(start);
|
return(start);
|
||||||
}
|
}
|
||||||
@ -579,14 +511,14 @@ mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
|
|||||||
|
|
||||||
if (NULL == in || '\0' == *in ||
|
if (NULL == in || '\0' == *in ||
|
||||||
0 == strcmp(in, "$" "Mdocdate$")) {
|
0 == strcmp(in, "$" "Mdocdate$")) {
|
||||||
mandoc_msg(MANDOCERR_NODATE, parse, ln, pos, NULL);
|
mandoc_msg(MANDOCERR_DATE_MISSING, parse, ln, pos, NULL);
|
||||||
time(&t);
|
time(&t);
|
||||||
}
|
}
|
||||||
else if (a2time(&t, "%Y-%m-%d", in))
|
else if (a2time(&t, "%Y-%m-%d", in))
|
||||||
t = 0;
|
t = 0;
|
||||||
else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) &&
|
else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) &&
|
||||||
!a2time(&t, "%b %d, %Y", in)) {
|
!a2time(&t, "%b %d, %Y", in)) {
|
||||||
mandoc_msg(MANDOCERR_BADDATE, parse, ln, pos, NULL);
|
mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, in);
|
||||||
t = 0;
|
t = 0;
|
||||||
}
|
}
|
||||||
out = t ? time2a(t) : NULL;
|
out = t ? time2a(t) : NULL;
|
||||||
@ -594,10 +526,10 @@ mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mandoc_eos(const char *p, size_t sz, int enclosed)
|
mandoc_eos(const char *p, size_t sz)
|
||||||
{
|
{
|
||||||
const char *q;
|
const char *q;
|
||||||
int found;
|
int enclosed, found;
|
||||||
|
|
||||||
if (0 == sz)
|
if (0 == sz)
|
||||||
return(0);
|
return(0);
|
||||||
@ -608,24 +540,24 @@ mandoc_eos(const char *p, size_t sz, int enclosed)
|
|||||||
* propagate outward.
|
* propagate outward.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
found = 0;
|
enclosed = found = 0;
|
||||||
for (q = p + (int)sz - 1; q >= p; q--) {
|
for (q = p + (int)sz - 1; q >= p; q--) {
|
||||||
switch (*q) {
|
switch (*q) {
|
||||||
case ('\"'):
|
case '\"':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('\''):
|
case '\'':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (']'):
|
case ']':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (')'):
|
case ')':
|
||||||
if (0 == found)
|
if (0 == found)
|
||||||
enclosed = 1;
|
enclosed = 1;
|
||||||
break;
|
break;
|
||||||
case ('.'):
|
case '.':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('!'):
|
case '!':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('?'):
|
case '?':
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
144
contrib/mdocml/mandoc.db.5
Normal file
144
contrib/mdocml/mandoc.db.5
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
.\" $Id: mandoc.db.5,v 1.1 2014/04/15 20:18:26 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: April 15 2014 $
|
||||||
|
.Dt MANDOC.DB 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mandoc.db
|
||||||
|
.Nd manual page database
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
SQLite3 file format is used to store information about installed manual
|
||||||
|
pages to facilitate semantic searching for manuals.
|
||||||
|
Each manual page tree contains its own
|
||||||
|
.Nm
|
||||||
|
file; see
|
||||||
|
.Sx FILES
|
||||||
|
for examples.
|
||||||
|
.Pp
|
||||||
|
Such database files are generated by
|
||||||
|
.Xr makewhatis 8
|
||||||
|
and used by
|
||||||
|
.Xr apropos 1
|
||||||
|
and
|
||||||
|
.Xr whatis 1 .
|
||||||
|
.Pp
|
||||||
|
One line in the following tables describes:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Sy mpages
|
||||||
|
One physical manual page file, no matter how many times and under which
|
||||||
|
names it may appear in the file system.
|
||||||
|
.It Sy mlinks
|
||||||
|
One entry in the file system, no matter which content it points to.
|
||||||
|
.It Sy names
|
||||||
|
One manual page name, no matter whether it appears in a page header,
|
||||||
|
in a NAME or SYNOPSIS section, or as a file name.
|
||||||
|
.It Sy keys
|
||||||
|
One chunk of text from some macro invocation.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Each record in the latter three tables uses its
|
||||||
|
.Va pageid
|
||||||
|
column to point to a record in the
|
||||||
|
.Sy mpages
|
||||||
|
table.
|
||||||
|
.Pp
|
||||||
|
The other columns are as follows; unless stated otherwise, they are
|
||||||
|
of type
|
||||||
|
.Vt TEXT .
|
||||||
|
.Bl -tag -width mpages.desc
|
||||||
|
.It Sy mpages.desc
|
||||||
|
The description line
|
||||||
|
.Pq Sq \&Nd
|
||||||
|
of the page.
|
||||||
|
.It Sy mpages.form
|
||||||
|
The
|
||||||
|
.Vt INTEGER
|
||||||
|
1 if the page is unformatted, i.e. in
|
||||||
|
.Xr mdoc 7
|
||||||
|
or
|
||||||
|
.Xr man 7
|
||||||
|
format, and 2 if it is formatted, i.e. a
|
||||||
|
.Sq cat
|
||||||
|
page.
|
||||||
|
.It Sy mlinks.sec
|
||||||
|
The manual section as found in the subdirectory name.
|
||||||
|
.It Sy mlinks.arch
|
||||||
|
The manual architecture as found in the subdirectory name, or
|
||||||
|
.Qq any .
|
||||||
|
.It Sy mlinks.name
|
||||||
|
The manual name as found in the file name.
|
||||||
|
.It Sy names.bits
|
||||||
|
An
|
||||||
|
.Vt INTEGER
|
||||||
|
bit mask telling whether the name came from a header line, from the
|
||||||
|
NAME or SYNOPSIS section, or from a file name.
|
||||||
|
Bits are defined in
|
||||||
|
.In mansearch.h .
|
||||||
|
.It Sy names.name
|
||||||
|
The name itself.
|
||||||
|
.It Sy keys.bits
|
||||||
|
An
|
||||||
|
.Vt INTEGER
|
||||||
|
bit mask telling which semantic contexts the key was found in;
|
||||||
|
defined in
|
||||||
|
.In mansearch.h ,
|
||||||
|
documented in
|
||||||
|
.Xr apropos 1 .
|
||||||
|
.It Sy keys.key
|
||||||
|
The string found in those contexts.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /usr/share/mandoc.db -compact
|
||||||
|
.It Pa /usr/share/mandoc.db
|
||||||
|
The manual page database for the base system.
|
||||||
|
.It Pa /usr/X11R6/mandoc.db
|
||||||
|
The same for the
|
||||||
|
.Xr X 7
|
||||||
|
Window System.
|
||||||
|
.It Pa /usr/local/mandoc.db
|
||||||
|
The same for
|
||||||
|
.Xr packages 7 .
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
.Xr man 1 ,
|
||||||
|
.Xr sqlite3 1 ,
|
||||||
|
.Xr whatis 1 ,
|
||||||
|
.Xr mansearch 3 ,
|
||||||
|
.Xr makewhatis 8
|
||||||
|
.Sh HISTORY
|
||||||
|
A manual page database
|
||||||
|
.Pa /usr/lib/whatis
|
||||||
|
first appeared in
|
||||||
|
.Bx 2 .
|
||||||
|
The present format first appeared in
|
||||||
|
.Ox 5.6 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
The original version of
|
||||||
|
.Xr makewhatis 8
|
||||||
|
was written by
|
||||||
|
.An Bill Joy
|
||||||
|
in 1979.
|
||||||
|
An SQLite3 version was first implemented by
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
in 2012.
|
||||||
|
The present database format was designed by
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
||||||
|
in 2014.
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: mandoc.h,v 1.112 2013/12/30 18:30:32 schwarze Exp $ */
|
/* $Id: mandoc.h,v 1.152 2014/08/06 15:09:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2012, 2013 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#define ASCII_NBRSP 31 /* non-breaking space */
|
#define ASCII_NBRSP 31 /* non-breaking space */
|
||||||
#define ASCII_HYPH 30 /* breakable hyphen */
|
#define ASCII_HYPH 30 /* breakable hyphen */
|
||||||
|
#define ASCII_BREAK 29 /* breakable zero-width space */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status level. This refers to both internal status (i.e., whilst
|
* Status level. This refers to both internal status (i.e., whilst
|
||||||
@ -48,66 +49,78 @@ enum mandocerr {
|
|||||||
MANDOCERR_WARNING, /* ===== start of warnings ===== */
|
MANDOCERR_WARNING, /* ===== start of warnings ===== */
|
||||||
|
|
||||||
/* related to the prologue */
|
/* related to the prologue */
|
||||||
MANDOCERR_NOTITLE, /* no title in document */
|
MANDOCERR_DT_NOTITLE, /* missing manual title, using UNTITLED: line */
|
||||||
MANDOCERR_UPPERCASE, /* document title should be all caps */
|
MANDOCERR_TH_NOTITLE, /* missing manual title, using "": [macro] */
|
||||||
MANDOCERR_BADMSEC, /* unknown manual section */
|
MANDOCERR_TITLE_CASE, /* lower case character in document title */
|
||||||
MANDOCERR_BADVOLARCH, /* unknown manual volume or arch */
|
MANDOCERR_MSEC_MISSING, /* missing manual section, using "": macro */
|
||||||
MANDOCERR_NODATE, /* date missing, using today's date */
|
MANDOCERR_MSEC_BAD, /* unknown manual section: Dt ... section */
|
||||||
MANDOCERR_BADDATE, /* cannot parse date, using it verbatim */
|
MANDOCERR_ARCH_BAD, /* unknown manual volume or arch: Dt ... volume */
|
||||||
MANDOCERR_PROLOGOOO, /* prologue macros out of order */
|
MANDOCERR_DATE_MISSING, /* missing date, using today's date */
|
||||||
MANDOCERR_PROLOGREP, /* duplicate prologue macro */
|
MANDOCERR_DATE_BAD, /* cannot parse date, using it verbatim: date */
|
||||||
MANDOCERR_BADPROLOG, /* macro not allowed in prologue */
|
MANDOCERR_OS_MISSING, /* missing Os macro, using "" */
|
||||||
MANDOCERR_BADBODY, /* macro not allowed in body */
|
MANDOCERR_PROLOG_REP, /* duplicate prologue macro: macro */
|
||||||
|
MANDOCERR_PROLOG_LATE, /* late prologue macro: macro */
|
||||||
|
MANDOCERR_DT_LATE, /* skipping late title macro: Dt args */
|
||||||
|
MANDOCERR_PROLOG_ORDER, /* prologue macros out of order: macros */
|
||||||
|
|
||||||
/* related to document structure */
|
/* related to document structure */
|
||||||
MANDOCERR_SO, /* .so is fragile, better use ln(1) */
|
MANDOCERR_SO, /* .so is fragile, better use ln(1): so path */
|
||||||
MANDOCERR_NAMESECFIRST, /* NAME section must come first */
|
MANDOCERR_DOC_EMPTY, /* no document body */
|
||||||
MANDOCERR_BADNAMESEC, /* bad NAME section contents */
|
MANDOCERR_SEC_BEFORE, /* content before first section header: macro */
|
||||||
MANDOCERR_SECOOO, /* sections out of conventional order */
|
MANDOCERR_NAMESEC_FIRST, /* first section is not NAME: Sh title */
|
||||||
MANDOCERR_SECREP, /* duplicate section name */
|
MANDOCERR_NAMESEC_BAD, /* bad NAME section contents: macro */
|
||||||
MANDOCERR_SECMSEC, /* section header suited to sections ... */
|
MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
|
||||||
|
MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
|
||||||
|
MANDOCERR_SEC_MSEC, /* unexpected section: Sh title for ... only */
|
||||||
|
|
||||||
/* related to macros and nesting */
|
/* related to macros and nesting */
|
||||||
MANDOCERR_MACROOBS, /* skipping obsolete macro */
|
MANDOCERR_MACRO_OBS, /* obsolete macro: macro */
|
||||||
MANDOCERR_IGNPAR, /* skipping paragraph macro */
|
MANDOCERR_PAR_SKIP, /* skipping paragraph macro: macro ... */
|
||||||
MANDOCERR_MOVEPAR, /* moving paragraph macro out of list */
|
MANDOCERR_PAR_MOVE, /* moving paragraph macro out of list: macro */
|
||||||
MANDOCERR_IGNNS, /* skipping no-space macro */
|
MANDOCERR_NS_SKIP, /* skipping no-space macro */
|
||||||
MANDOCERR_SCOPENEST, /* blocks badly nested */
|
MANDOCERR_BLK_NEST, /* blocks badly nested: macro ... */
|
||||||
MANDOCERR_CHILD, /* child violates parent syntax */
|
MANDOCERR_BD_NEST, /* nested displays are not portable: macro ... */
|
||||||
MANDOCERR_NESTEDDISP, /* nested displays are not portable */
|
MANDOCERR_BL_MOVE, /* moving content out of list: macro */
|
||||||
MANDOCERR_SCOPEREP, /* already in literal mode */
|
MANDOCERR_VT_CHILD, /* .Vt block has child macro: macro */
|
||||||
MANDOCERR_LINESCOPE, /* line scope broken */
|
MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */
|
||||||
|
MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */
|
||||||
|
MANDOCERR_BLK_LINE, /* line scope broken: macro breaks macro */
|
||||||
|
|
||||||
/* related to missing macro arguments */
|
/* related to missing arguments */
|
||||||
MANDOCERR_MACROEMPTY, /* skipping empty macro */
|
MANDOCERR_REQ_EMPTY, /* skipping empty request: request */
|
||||||
|
MANDOCERR_COND_EMPTY, /* conditional request controls empty scope */
|
||||||
|
MANDOCERR_MACRO_EMPTY, /* skipping empty macro: macro */
|
||||||
|
MANDOCERR_ARG_EMPTY, /* empty argument, using 0n: macro arg */
|
||||||
MANDOCERR_ARGCWARN, /* argument count wrong */
|
MANDOCERR_ARGCWARN, /* argument count wrong */
|
||||||
MANDOCERR_DISPTYPE, /* missing display type */
|
MANDOCERR_BD_NOTYPE, /* missing display type, using -ragged: Bd */
|
||||||
MANDOCERR_LISTFIRST, /* list type must come first */
|
MANDOCERR_BL_LATETYPE, /* list type is not the first argument: Bl arg */
|
||||||
MANDOCERR_NOWIDTHARG, /* tag lists require a width argument */
|
MANDOCERR_BL_NOWIDTH, /* missing -width in -tag list, using 8n */
|
||||||
MANDOCERR_FONTTYPE, /* missing font type */
|
MANDOCERR_EX_NONAME, /* missing utility name, using "": Ex */
|
||||||
MANDOCERR_WNOSCOPE, /* skipping end of block that is not open */
|
MANDOCERR_IT_NOHEAD, /* empty head in list item: Bl -type It */
|
||||||
|
MANDOCERR_IT_NOBODY, /* empty list item: Bl -type It */
|
||||||
|
MANDOCERR_BF_NOFONT, /* missing font type, using \fR: Bf */
|
||||||
|
MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */
|
||||||
|
MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
|
||||||
|
|
||||||
/* related to bad macro arguments */
|
/* related to bad arguments */
|
||||||
MANDOCERR_IGNARGV, /* skipping argument */
|
MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */
|
||||||
MANDOCERR_ARGVREP, /* duplicate argument */
|
MANDOCERR_ARG_REP, /* duplicate argument: macro arg */
|
||||||
MANDOCERR_DISPREP, /* duplicate display type */
|
MANDOCERR_AN_REP, /* skipping duplicate argument: An -arg */
|
||||||
MANDOCERR_LISTREP, /* duplicate list type */
|
MANDOCERR_BD_REP, /* skipping duplicate display type: Bd -type */
|
||||||
MANDOCERR_BADATT, /* unknown AT&T UNIX version */
|
MANDOCERR_BL_REP, /* skipping duplicate list type: Bl -type */
|
||||||
MANDOCERR_BADBOOL, /* bad Boolean value */
|
MANDOCERR_BL_SKIPW, /* skipping -width argument: Bl -type */
|
||||||
MANDOCERR_BADFONT, /* unknown font */
|
MANDOCERR_AT_BAD, /* unknown AT&T UNIX version: At version */
|
||||||
MANDOCERR_BADSTANDARD, /* unknown standard specifier */
|
MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */
|
||||||
MANDOCERR_BADWIDTH, /* bad width argument */
|
MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */
|
||||||
|
MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */
|
||||||
|
|
||||||
/* related to plain text */
|
/* related to plain text */
|
||||||
MANDOCERR_NOBLANKLN, /* blank line in non-literal context */
|
MANDOCERR_FI_BLANK, /* blank line in fill mode, using .sp */
|
||||||
MANDOCERR_BADTAB, /* tab in non-literal context */
|
MANDOCERR_FI_TAB, /* tab in filled text */
|
||||||
MANDOCERR_EOLNSPACE, /* end of line whitespace */
|
MANDOCERR_SPACE_EOL, /* whitespace at end of input line */
|
||||||
MANDOCERR_BADCOMMENT, /* bad comment style */
|
MANDOCERR_COMMENT_BAD, /* bad comment style */
|
||||||
MANDOCERR_BADESCAPE, /* unknown escape sequence */
|
MANDOCERR_ESC_BAD, /* invalid escape sequence: esc */
|
||||||
MANDOCERR_BADQUOTE, /* unterminated quoted string */
|
MANDOCERR_STR_UNDEF, /* undefined string, using "": name */
|
||||||
|
|
||||||
/* related to equations */
|
|
||||||
MANDOCERR_EQNQUOTE, /* unexpected literal in equation */
|
|
||||||
|
|
||||||
MANDOCERR_ERROR, /* ===== start of errors ===== */
|
MANDOCERR_ERROR, /* ===== start of errors ===== */
|
||||||
|
|
||||||
@ -128,40 +141,40 @@ enum mandocerr {
|
|||||||
MANDOCERR_TBLBLOCK, /* data block still open */
|
MANDOCERR_TBLBLOCK, /* data block still open */
|
||||||
MANDOCERR_TBLEXTRADAT, /* ignoring extra data cells */
|
MANDOCERR_TBLEXTRADAT, /* ignoring extra data cells */
|
||||||
|
|
||||||
|
/* related to document structure and macros */
|
||||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||||
MANDOCERR_BADCHAR, /* skipping bad character */
|
MANDOCERR_BADCHAR, /* skipping bad character: number */
|
||||||
MANDOCERR_NAMESC, /* escaped character not allowed in a name */
|
MANDOCERR_MACRO, /* skipping unknown macro: macro */
|
||||||
MANDOCERR_NONAME, /* manual name not yet set */
|
MANDOCERR_IT_STRAY, /* skipping item outside list: It ... */
|
||||||
MANDOCERR_NOTEXT, /* skipping text before the first section header */
|
MANDOCERR_TA_STRAY, /* skipping column outside column list: Ta */
|
||||||
MANDOCERR_MACRO, /* skipping unknown macro */
|
MANDOCERR_BLK_NOTOPEN, /* skipping end of block that is not open */
|
||||||
MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */
|
MANDOCERR_BLK_BROKEN, /* inserting missing end of block: macro ... */
|
||||||
|
MANDOCERR_BLK_NOEND, /* appending missing end of block: macro */
|
||||||
|
|
||||||
|
/* related to request and macro arguments */
|
||||||
|
MANDOCERR_NAMESC, /* escaped character not allowed in a name: name */
|
||||||
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
||||||
MANDOCERR_STRAYTA, /* skipping column outside column list */
|
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
|
||||||
MANDOCERR_NOSCOPE, /* skipping end of block that is not open */
|
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
|
||||||
MANDOCERR_SCOPEBROKEN, /* missing end of block */
|
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
|
||||||
MANDOCERR_SCOPEEXIT, /* scope open on exit */
|
MANDOCERR_ST_BAD, /* unknown standard specifier: St standard */
|
||||||
MANDOCERR_UNAME, /* uname(3) system call failed */
|
MANDOCERR_IT_NONUM, /* skipping request without numeric argument */
|
||||||
/* FIXME: merge following with MANDOCERR_ARGCOUNT */
|
MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */
|
||||||
MANDOCERR_NOARGS, /* macro requires line argument(s) */
|
MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */
|
||||||
MANDOCERR_NOBODY, /* macro requires body argument(s) */
|
|
||||||
MANDOCERR_NOARGV, /* macro requires argument(s) */
|
|
||||||
MANDOCERR_NUMERIC, /* request requires a numeric argument */
|
|
||||||
MANDOCERR_LISTTYPE, /* missing list type */
|
|
||||||
MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
|
|
||||||
MANDOCERR_BODYLOST, /* body argument(s) will be lost */
|
|
||||||
|
|
||||||
MANDOCERR_FATAL, /* ===== start of fatal errors ===== */
|
MANDOCERR_FATAL, /* ===== start of fatal errors ===== */
|
||||||
|
|
||||||
MANDOCERR_NOTMANUAL, /* manual isn't really a manual */
|
MANDOCERR_TOOLARGE, /* input too large */
|
||||||
MANDOCERR_COLUMNS, /* column syntax is inconsistent */
|
MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
|
||||||
MANDOCERR_BADDISP, /* NOT IMPLEMENTED: .Bd -file */
|
MANDOCERR_SO_PATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
||||||
MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */
|
MANDOCERR_SO_FAIL, /* .so request failed */
|
||||||
MANDOCERR_SYNTCHILD, /* child violates parent syntax */
|
|
||||||
MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */
|
/* ===== system errors ===== */
|
||||||
MANDOCERR_SOPATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
|
||||||
MANDOCERR_NODOCBODY, /* no document body */
|
MANDOCERR_SYSOPEN, /* cannot open file */
|
||||||
MANDOCERR_NODOCPROLOG, /* no document prologue */
|
MANDOCERR_SYSSTAT, /* cannot stat file */
|
||||||
MANDOCERR_MEM, /* static buffer exhausted */
|
MANDOCERR_SYSREAD, /* cannot read file */
|
||||||
|
|
||||||
MANDOCERR_MAX
|
MANDOCERR_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -231,6 +244,7 @@ struct tbl_row {
|
|||||||
struct tbl_row *next;
|
struct tbl_row *next;
|
||||||
struct tbl_cell *first;
|
struct tbl_cell *first;
|
||||||
struct tbl_cell *last;
|
struct tbl_cell *last;
|
||||||
|
int vert; /* trailing vertical line */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum tbl_datt {
|
enum tbl_datt {
|
||||||
@ -363,15 +377,12 @@ struct eqn {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The type of parse sequence. This value is usually passed via the
|
* Parse options.
|
||||||
* mandoc(1) command line of -man and -mdoc. It's almost exclusively
|
|
||||||
* -mandoc but the others have been retained for compatibility.
|
|
||||||
*/
|
*/
|
||||||
enum mparset {
|
#define MPARSE_MDOC 1 /* assume -mdoc */
|
||||||
MPARSE_AUTO, /* magically determine the document type */
|
#define MPARSE_MAN 2 /* assume -man */
|
||||||
MPARSE_MDOC, /* assume -mdoc */
|
#define MPARSE_SO 4 /* honour .so requests */
|
||||||
MPARSE_MAN /* assume -man */
|
#define MPARSE_QUICK 8 /* abort the parse early */
|
||||||
};
|
|
||||||
|
|
||||||
enum mandoc_esc {
|
enum mandoc_esc {
|
||||||
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
||||||
@ -399,12 +410,7 @@ struct man;
|
|||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
void *mandoc_calloc(size_t, size_t);
|
|
||||||
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
||||||
void *mandoc_malloc(size_t);
|
|
||||||
void *mandoc_realloc(void *, size_t);
|
|
||||||
char *mandoc_strdup(const char *);
|
|
||||||
char *mandoc_strndup(const char *, size_t);
|
|
||||||
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);
|
char mchars_num2char(const char *, size_t);
|
||||||
@ -413,8 +419,8 @@ 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(enum mparset, enum mandoclevel,
|
struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg,
|
||||||
mandocmsg, void *, char *);
|
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_readfd(struct mparse *, int, const char *);
|
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
|
||||||
@ -422,7 +428,7 @@ enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t,
|
|||||||
const char *);
|
const char *);
|
||||||
void mparse_reset(struct mparse *);
|
void mparse_reset(struct mparse *);
|
||||||
void mparse_result(struct mparse *,
|
void mparse_result(struct mparse *,
|
||||||
struct mdoc **, struct man **);
|
struct mdoc **, struct man **, char **);
|
||||||
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);
|
||||||
|
121
contrib/mdocml/mandoc_aux.c
Normal file
121
contrib/mdocml/mandoc_aux.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* $Id: mandoc_aux.c,v 1.3 2014/07/09 08:20:34 schwarze Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
mandoc_asprintf(char **dest, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = vasprintf(dest, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (-1 == ret) {
|
||||||
|
perror(NULL);
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
mandoc_calloc(size_t num, size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = calloc(num, size);
|
||||||
|
if (NULL == ptr) {
|
||||||
|
perror(NULL);
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
mandoc_malloc(size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = malloc(size);
|
||||||
|
if (NULL == ptr) {
|
||||||
|
perror(NULL);
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
mandoc_realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
ptr = realloc(ptr, size);
|
||||||
|
if (NULL == ptr) {
|
||||||
|
perror(NULL);
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
mandoc_reallocarray(void *ptr, size_t num, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
ptr = reallocarray(ptr, num, size);
|
||||||
|
if (NULL == ptr) {
|
||||||
|
perror(NULL);
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
mandoc_strdup(const char *ptr)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = strdup(ptr);
|
||||||
|
if (NULL == p) {
|
||||||
|
perror(NULL);
|
||||||
|
exit((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
mandoc_strndup(const char *ptr, size_t sz)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = mandoc_malloc(sz + 1);
|
||||||
|
memcpy(p, ptr, sz);
|
||||||
|
p[(int)sz] = '\0';
|
||||||
|
return(p);
|
||||||
|
}
|
33
contrib/mdocml/mandoc_aux.h
Normal file
33
contrib/mdocml/mandoc_aux.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* $Id: mandoc_aux.h,v 1.2 2014/04/23 21:06:41 schwarze Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef MANDOC_AUX_H
|
||||||
|
#define MANDOC_AUX_H
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
int mandoc_asprintf(char **, const char *, ...);
|
||||||
|
void *mandoc_calloc(size_t, size_t);
|
||||||
|
void *mandoc_malloc(size_t);
|
||||||
|
void *mandoc_realloc(void *, size_t);
|
||||||
|
void *mandoc_reallocarray(void *, size_t, size_t);
|
||||||
|
char *mandoc_strdup(const char *);
|
||||||
|
char *mandoc_strndup(const char *, size_t);
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /*!MANDOC_AUX_H*/
|
362
contrib/mdocml/mandoc_escape.3
Normal file
362
contrib/mdocml/mandoc_escape.3
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
.\" $Id: mandoc_escape.3,v 1.1 2014/08/05 05:48:56 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: August 5 2014 $
|
||||||
|
.Dt MANDOC_ESCAPE 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mandoc_escape
|
||||||
|
.Nd parse roff escape sequences
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libmandoc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In sys/types.h
|
||||||
|
.In mandoc.h
|
||||||
|
.Ft "enum mandoc_esc"
|
||||||
|
.Fo mandoc_escape
|
||||||
|
.Fa "const char **end"
|
||||||
|
.Fa "const char **start"
|
||||||
|
.Fa "int *sz"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function scans a
|
||||||
|
.Xr roff 7
|
||||||
|
escape sequence.
|
||||||
|
.Pp
|
||||||
|
An escape sequence consists of
|
||||||
|
.Bl -dash -compact -width 2n
|
||||||
|
.It
|
||||||
|
an initial backslash character
|
||||||
|
.Pq Sq \e ,
|
||||||
|
.It
|
||||||
|
a single ASCII character called the escape sequence identifier,
|
||||||
|
.It
|
||||||
|
and, with only a few exceptions, an argument.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Arguments can be given in the following forms; some escape sequence
|
||||||
|
identifiers only accept some of these forms as specified below.
|
||||||
|
The first three forms are called the standard forms.
|
||||||
|
.Bl -tag -width 2n
|
||||||
|
.It \&In brackets: Ic \&[ Ns Ar argument Ns Ic \&]
|
||||||
|
The argument starts after the initial
|
||||||
|
.Sq \&[ ,
|
||||||
|
ends before the final
|
||||||
|
.Sq \&] ,
|
||||||
|
and the escape sequence ends with the final
|
||||||
|
.Sq \&] .
|
||||||
|
.It Two-character argument short form: Ic \&( Ns Ar ar
|
||||||
|
This form can only be used for arguments
|
||||||
|
consisting of exactly two characters.
|
||||||
|
It has the same effect as
|
||||||
|
.Ic \&[ Ns Ar ar Ns Ic \&] .
|
||||||
|
.It One-character argument short form: Ar a
|
||||||
|
This form can only be used for arguments
|
||||||
|
consisting of exactly one character.
|
||||||
|
It has the same effect as
|
||||||
|
.Ic \&[ Ns Ar a Ns Ic \&] .
|
||||||
|
.It Delimited form: Ar C Ns Ar argument Ns Ar C
|
||||||
|
The argument starts after the initial delimiter character
|
||||||
|
.Ar C ,
|
||||||
|
ends before the next occurrence of the delimiter character
|
||||||
|
.Ar C ,
|
||||||
|
and the escape sequence ends with that second
|
||||||
|
.Ar C .
|
||||||
|
Some escape sequences allow arbitrary characters
|
||||||
|
.Ar C
|
||||||
|
as quoting characters, some restrict the range of characters
|
||||||
|
that can be used as quoting characters.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Upon function entry,
|
||||||
|
.Fa end
|
||||||
|
is expected to point to the escape sequence identifier.
|
||||||
|
The values passed in as
|
||||||
|
.Fa start
|
||||||
|
and
|
||||||
|
.Fa sz
|
||||||
|
are ignored and overwritten.
|
||||||
|
.Pp
|
||||||
|
By design, this function cannot handle those
|
||||||
|
.Xr roff 7
|
||||||
|
escape sequences that require in-place expansion, in particular
|
||||||
|
user-defined strings
|
||||||
|
.Ic \e* ,
|
||||||
|
number registers
|
||||||
|
.Ic \en ,
|
||||||
|
width measurements
|
||||||
|
.Ic \ew ,
|
||||||
|
and numerical expression control
|
||||||
|
.Ic \eB .
|
||||||
|
These are handled by
|
||||||
|
.Fn roff_res ,
|
||||||
|
a private preprocessor function called from
|
||||||
|
.Fn roff_parseln ,
|
||||||
|
see the file
|
||||||
|
.Pa roff.c .
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mandoc_escape
|
||||||
|
is used
|
||||||
|
.Bl -dash -compact -width 2n
|
||||||
|
.It
|
||||||
|
recursively by itself, because some escape sequence arguments can
|
||||||
|
in turn contain other escape sequences,
|
||||||
|
.It
|
||||||
|
for error detection internally by the
|
||||||
|
.Xr roff 7
|
||||||
|
parser part of the
|
||||||
|
.Lb libmandoc ,
|
||||||
|
see the file
|
||||||
|
.Pa roff.c ,
|
||||||
|
.It
|
||||||
|
above all externally by the
|
||||||
|
.Xr mandoc
|
||||||
|
formatting modules, in particular
|
||||||
|
.Fl Tascii
|
||||||
|
and
|
||||||
|
.Fl Thtml ,
|
||||||
|
for formatting purposes, see the files
|
||||||
|
.Pa term.c
|
||||||
|
and
|
||||||
|
.Pa html.c ,
|
||||||
|
.It
|
||||||
|
and rarely externally by high-level utilities using the mandoc library,
|
||||||
|
for example
|
||||||
|
.Xr makewhatis 8 ,
|
||||||
|
to purge escape sequences from text.
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Upon function return, the pointer
|
||||||
|
.Fa end
|
||||||
|
is set to the character after the end of the escape sequence,
|
||||||
|
such that the calling higher-level parser can easily continue.
|
||||||
|
.Pp
|
||||||
|
For escape sequences taking an argument, the pointer
|
||||||
|
.Fa start
|
||||||
|
is set to the beginning of the argument and
|
||||||
|
.Fa sz
|
||||||
|
is set to the length of the argument.
|
||||||
|
For escape sequences not taking an argument,
|
||||||
|
.Fa start
|
||||||
|
is set to the character after the end of the sequence and
|
||||||
|
.Fa sz
|
||||||
|
is set to 0.
|
||||||
|
Both
|
||||||
|
.Fa start
|
||||||
|
and
|
||||||
|
.Fa sz
|
||||||
|
may be
|
||||||
|
.Dv NULL ;
|
||||||
|
in that case, the argument and the length are not returned.
|
||||||
|
.Pp
|
||||||
|
For sequences taking an argument, the function
|
||||||
|
.Fn mandoc_escape
|
||||||
|
returns one of the following values:
|
||||||
|
.Bl -tag -width 2n
|
||||||
|
.It Dv ESCAPE_FONT
|
||||||
|
The escape sequence
|
||||||
|
.Ic \ef
|
||||||
|
taking an argument in standard form:
|
||||||
|
.Ic \ef[ , \ef( , \ef Ns Ar a .
|
||||||
|
Two-character arguments starting with the character
|
||||||
|
.Sq C
|
||||||
|
are reduced to one-character arguments by skipping the
|
||||||
|
.Sq C .
|
||||||
|
More specific values are returned for the most commonly used arguments:
|
||||||
|
.Bl -column "argument" "ESCAPE_FONTITALIC"
|
||||||
|
.It argument Ta return value
|
||||||
|
.It Cm R No or Cm 1 Ta Dv ESCAPE_FONTROMAN
|
||||||
|
.It Cm I No or Cm 2 Ta Dv ESCAPE_FONTITALIC
|
||||||
|
.It Cm B No or Cm 3 Ta Dv ESCAPE_FONTBOLD
|
||||||
|
.It Cm P Ta Dv ESCAPE_FONTPREV
|
||||||
|
.It Cm BI Ta Dv ESCAPE_FONTBI
|
||||||
|
.El
|
||||||
|
.It Dv ESCAPE_SPECIAL
|
||||||
|
The escape sequence
|
||||||
|
.Ic \eC
|
||||||
|
taking an argument delimited with the single quote character
|
||||||
|
and, as a special exception, the escape sequences
|
||||||
|
.Em not
|
||||||
|
having an identifier, that is, those where the argument, in standard
|
||||||
|
form, directly follows the initial backslash:
|
||||||
|
.Ic \eC' , \e[ , \e( , \e Ns Ar a .
|
||||||
|
Note that the one-character argument short form can only be used for
|
||||||
|
argument characters that do not clash with escape sequence identifiers.
|
||||||
|
.Pp
|
||||||
|
If the argument consists of more than one character
|
||||||
|
and starts with the character
|
||||||
|
.Sq u ,
|
||||||
|
.Dv ESCAPE_UNICODE
|
||||||
|
is returned as described below.
|
||||||
|
If the argument is just the single character
|
||||||
|
.Sq u ,
|
||||||
|
.Dv ESCAPE_ERROR
|
||||||
|
is returned.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Dv ESCAPE_SPECIAL
|
||||||
|
special character escape sequences can be rendered using the functions
|
||||||
|
.Fn mchars_spec2cp
|
||||||
|
and
|
||||||
|
.Fn mchars_spec2str
|
||||||
|
described in the
|
||||||
|
.Xr mchars_alloc 3
|
||||||
|
manual.
|
||||||
|
.It Dv ESCAPE_UNICODE
|
||||||
|
Escape sequences of the same format as described above under
|
||||||
|
.Dv ESCAPE_SPECIAL ,
|
||||||
|
but with an argument starting with the character
|
||||||
|
.Sq u :
|
||||||
|
.Ic \eC'u , \e[u .
|
||||||
|
As a special exception,
|
||||||
|
.Fa start
|
||||||
|
is set to the character after the
|
||||||
|
.Sq u ,
|
||||||
|
and the
|
||||||
|
.Fa sz
|
||||||
|
return value does not include the
|
||||||
|
.Sq u
|
||||||
|
either.
|
||||||
|
.Pp
|
||||||
|
Such Unicode character escape sequences can be rendered using the function
|
||||||
|
.Fn mchars_num2uc
|
||||||
|
described in the
|
||||||
|
.Xr mchars_alloc 3
|
||||||
|
manual.
|
||||||
|
.It Dv ESCAPE_NUMBERED
|
||||||
|
The escape sequence
|
||||||
|
.Ic \eN
|
||||||
|
followed by a delimited argument.
|
||||||
|
The delimiter character is arbitrary except that digits cannot be used.
|
||||||
|
If a digit is encountered instead of the opening delimiter, that
|
||||||
|
digit is considered to be the argument and the end of the sequence, and
|
||||||
|
.Dv ESCAPE_IGNORE
|
||||||
|
is returned.
|
||||||
|
.Pp
|
||||||
|
Such ASCII character escape sequences can be rendered using the function
|
||||||
|
.Fn mchars_num2char
|
||||||
|
described in the
|
||||||
|
.Xr mchars_alloc 3
|
||||||
|
manual.
|
||||||
|
.It Dv ESCAPE_IGNORE
|
||||||
|
.Bl -bullet -width 2n
|
||||||
|
.It
|
||||||
|
The escape sequence
|
||||||
|
.Ic \es
|
||||||
|
followed by an argument in standard form or by an argument delimited
|
||||||
|
by the single quote character:
|
||||||
|
.Ic \es' , \es[ , \es( , \es Ns Ar a .
|
||||||
|
As a special exception, an optional
|
||||||
|
.Sq +
|
||||||
|
or
|
||||||
|
.Sq \-
|
||||||
|
character is allowed after the
|
||||||
|
.Sq s
|
||||||
|
for all forms.
|
||||||
|
.It
|
||||||
|
The escape sequences
|
||||||
|
.Ic \eF ,
|
||||||
|
.Ic \eg ,
|
||||||
|
.Ic \ek ,
|
||||||
|
.Ic \eM ,
|
||||||
|
.Ic \em ,
|
||||||
|
.Ic \en ,
|
||||||
|
.Ic \eV ,
|
||||||
|
and
|
||||||
|
.Ic \eY
|
||||||
|
followed by an argument in standard form.
|
||||||
|
.It
|
||||||
|
The escape sequences
|
||||||
|
.Ic \eA ,
|
||||||
|
.Ic \eb ,
|
||||||
|
.Ic \eD ,
|
||||||
|
.Ic \eo ,
|
||||||
|
.Ic \eR ,
|
||||||
|
.Ic \eX ,
|
||||||
|
and
|
||||||
|
.Ic \eZ
|
||||||
|
followed by an argument delimited by an arbitrary character.
|
||||||
|
.It
|
||||||
|
The escape sequences
|
||||||
|
.Ic \eH ,
|
||||||
|
.Ic \eh ,
|
||||||
|
.Ic \eL ,
|
||||||
|
.Ic \el ,
|
||||||
|
.Ic \eS ,
|
||||||
|
.Ic \ev ,
|
||||||
|
and
|
||||||
|
.Ic \ex
|
||||||
|
followed by an argument delimited by a character that cannot occur
|
||||||
|
in numerical expressions.
|
||||||
|
However, if any character that can occur in numerical expressions
|
||||||
|
is found instead of a delimiter, the sequence is considered to end
|
||||||
|
with that character, and
|
||||||
|
.Dv ESCAPE_ERROR
|
||||||
|
is returned.
|
||||||
|
.El
|
||||||
|
.It Dv ESCAPE_ERROR
|
||||||
|
Escape sequences taking an argument but not matching any of the above patterns.
|
||||||
|
In particular, that happens if the end of the logical input line
|
||||||
|
is reached before the end of the argument.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
For sequences that do not take an argument, the function
|
||||||
|
.Fn mandoc_escape
|
||||||
|
returns one of the following values:
|
||||||
|
.Bl -tag -width 2n
|
||||||
|
.It Dv ESCAPE_SKIPCHAR
|
||||||
|
The escape sequence
|
||||||
|
.Qq \ez .
|
||||||
|
.It Dv ESCAPE_NOSPACE
|
||||||
|
The escape sequence
|
||||||
|
.Qq \ec .
|
||||||
|
.It Dv ESCAPE_IGNORE
|
||||||
|
The escape sequences
|
||||||
|
.Qq \ed
|
||||||
|
and
|
||||||
|
.Qq \eu .
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
This function is implemented in
|
||||||
|
.Pa mandoc.c .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr mchars_alloc 3 ,
|
||||||
|
.Xr mandoc_char 7 ,
|
||||||
|
.Xr roff 7
|
||||||
|
.Sh HISTORY
|
||||||
|
This function has been available since mandoc 1.11.2.
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
||||||
|
.Sh BUGS
|
||||||
|
The function doesn't cleanly distinguish between sequences that are
|
||||||
|
valid and supported, valid and ignored, valid and unsupported,
|
||||||
|
syntactically invalid, or undefined.
|
||||||
|
For sequences that are ignored or unsupported, it doesn't tell
|
||||||
|
whether that deficiency is likely to cause major formatting problems
|
||||||
|
and/or loss of document content.
|
||||||
|
The function is already rather complicated and still parses some
|
||||||
|
sequences incorrectly.
|
||||||
|
.
|
||||||
|
.ig
|
||||||
|
For these sequences, the list given below specifies a starting string
|
||||||
|
and either the length of the argument or an ending character.
|
||||||
|
The argument starts after the starting string.
|
||||||
|
In the former case, the sequence ends with the end of the argument.
|
||||||
|
In the latter case, the argument ends before the ending character,
|
||||||
|
and the sequence ends with the ending character.
|
||||||
|
..
|
249
contrib/mdocml/mandoc_html.3
Normal file
249
contrib/mdocml/mandoc_html.3
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
.\" $Id: mandoc_html.3,v 1.1 2014/07/23 18:13:09 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: July 23 2014 $
|
||||||
|
.Dt MANDOC_HTML 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mandoc_html
|
||||||
|
.Nd internals of the mandoc HTML formatter
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In "html.h"
|
||||||
|
.Ft void
|
||||||
|
.Fn print_gen_decls "struct html *h"
|
||||||
|
.Ft void
|
||||||
|
.Fn print_gen_head "struct html *h"
|
||||||
|
.Ft struct tag *
|
||||||
|
.Fo print_otag
|
||||||
|
.Fa "struct html *h"
|
||||||
|
.Fa "enum htmltag tag"
|
||||||
|
.Fa "int sz"
|
||||||
|
.Fa "const struct htmlpair *p"
|
||||||
|
.Fc
|
||||||
|
.Ft void
|
||||||
|
.Fo print_tagq
|
||||||
|
.Fa "struct html *h"
|
||||||
|
.Fa "const struct tag *until"
|
||||||
|
.Fc
|
||||||
|
.Ft void
|
||||||
|
.Fo print_stagq
|
||||||
|
.Fa "struct html *h"
|
||||||
|
.Fa "const struct tag *suntil"
|
||||||
|
.Fc
|
||||||
|
.Ft void
|
||||||
|
.Fo print_text
|
||||||
|
.Fa "struct html *h"
|
||||||
|
.Fa "const char *word"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The mandoc HTML formatter is not a formal library.
|
||||||
|
However, as it is compiled into more than one program, in particular
|
||||||
|
.Xr mandoc 1
|
||||||
|
and
|
||||||
|
.Xr man.cgi 8 ,
|
||||||
|
and because it may be security-critical in some contexts,
|
||||||
|
some documentation is useful to help to use it correctly and
|
||||||
|
to prevent XSS vulnerabilities.
|
||||||
|
.Pp
|
||||||
|
The formatter produces HTML output on the standard output.
|
||||||
|
Since proper escaping is usually required and best taken care of
|
||||||
|
at one central place, the language-specific formatters
|
||||||
|
.Po
|
||||||
|
.Pa *_html.c ,
|
||||||
|
see
|
||||||
|
.Sx FILES
|
||||||
|
.Pc
|
||||||
|
are not supposed to print directly to
|
||||||
|
.Dv stdout
|
||||||
|
using functions like
|
||||||
|
.Xr printf 3 ,
|
||||||
|
.Xr putc 3 ,
|
||||||
|
.Xr puts 3 ,
|
||||||
|
or
|
||||||
|
.Xr write 2 .
|
||||||
|
Instead, they are expected to use the output functions declared in
|
||||||
|
.Pa html.h
|
||||||
|
and implemented as part of the main HTML formatting engine in
|
||||||
|
.Pa html.c .
|
||||||
|
.Ss Data structures
|
||||||
|
These structures are declared in
|
||||||
|
.Pa html.h .
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Vt struct html
|
||||||
|
Internal state of the HTML formatter.
|
||||||
|
.It Vt struct htmlpair
|
||||||
|
Holds one HTML attribute.
|
||||||
|
Members are
|
||||||
|
.Fa "enum htmlattr key"
|
||||||
|
and
|
||||||
|
.Fa "const char *val" .
|
||||||
|
Helper macros
|
||||||
|
.Fn PAIR_*
|
||||||
|
are provided to support initialization of such structures.
|
||||||
|
.It Vt struct tag
|
||||||
|
One entry for the LIFO stack of HTML elements.
|
||||||
|
Members are
|
||||||
|
.Fa "enum htmltag tag"
|
||||||
|
and
|
||||||
|
.Fa "struct tag *next" .
|
||||||
|
.El
|
||||||
|
.Ss Private interface functions
|
||||||
|
The function
|
||||||
|
.Fn print_gen_decls
|
||||||
|
prints the opening
|
||||||
|
.Ao Pf \&? Ic xml ? Ac
|
||||||
|
and
|
||||||
|
.Aq Pf \&! Ic DOCTYPE
|
||||||
|
declarations required for the current document type.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn print_gen_head
|
||||||
|
prints the opening
|
||||||
|
.Aq Ic META
|
||||||
|
and
|
||||||
|
.Aq Ic LINK
|
||||||
|
elements for the document
|
||||||
|
.Aq Ic HEAD ,
|
||||||
|
using the
|
||||||
|
.Fa style
|
||||||
|
member of
|
||||||
|
.Fa h
|
||||||
|
unless that is
|
||||||
|
.Dv NULL .
|
||||||
|
It uses
|
||||||
|
.Fn print_otag
|
||||||
|
which takes care of properly encoding attributes,
|
||||||
|
which is relevant for the
|
||||||
|
.Fa style
|
||||||
|
link in particular.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn print_otag
|
||||||
|
prints the start tag of an HTML element with the name
|
||||||
|
.Fa tag ,
|
||||||
|
including the
|
||||||
|
.Fa sz
|
||||||
|
attributes that can optionally be provided in the
|
||||||
|
.Fa p
|
||||||
|
array.
|
||||||
|
It uses the private function
|
||||||
|
.Fn print_attr
|
||||||
|
which in turn uses the private function
|
||||||
|
.Fn print_encode
|
||||||
|
to take care of HTML encoding.
|
||||||
|
If required by the element type, it remembers in
|
||||||
|
.Fa h
|
||||||
|
that the element is open.
|
||||||
|
The function
|
||||||
|
.Fn print_tagq
|
||||||
|
is used to close out all open elements up to and including
|
||||||
|
.Fa until ;
|
||||||
|
.Fn print_stagq
|
||||||
|
is a variant to close out all open elements up to but excluding
|
||||||
|
.Fa suntil .
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn print_text
|
||||||
|
prints HTML element content.
|
||||||
|
It uses the private function
|
||||||
|
.Fn print_encode
|
||||||
|
to take care of HTML encoding.
|
||||||
|
If the document has requested a non-standard font, for example using a
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \ef
|
||||||
|
font escape sequence,
|
||||||
|
.Fn print_text
|
||||||
|
wraps
|
||||||
|
.Fa word
|
||||||
|
in an HTML font selection element using the
|
||||||
|
.Fn print_otag
|
||||||
|
and
|
||||||
|
.Fn print_tagq
|
||||||
|
functions.
|
||||||
|
.Pp
|
||||||
|
The functions
|
||||||
|
.Fn bufinit ,
|
||||||
|
.Fn bufcat* ,
|
||||||
|
and
|
||||||
|
.Fn buffmt*
|
||||||
|
do not directly produce output but buffer text in the
|
||||||
|
.Fa buf
|
||||||
|
member of
|
||||||
|
.Fa h .
|
||||||
|
They are not used internally by
|
||||||
|
.Pa html.c
|
||||||
|
but intended for use by the language-specific formatters
|
||||||
|
to ease preparation of strings for the
|
||||||
|
.Fa p
|
||||||
|
argument of
|
||||||
|
.Fn print_otag
|
||||||
|
and for the
|
||||||
|
.Fa word
|
||||||
|
argument of
|
||||||
|
.Fn print_text .
|
||||||
|
Consequently, these functions do not do any HTML encoding.
|
||||||
|
.Pp
|
||||||
|
The functions
|
||||||
|
.Fn html_strlen ,
|
||||||
|
.Fn print_eqn ,
|
||||||
|
.Fn print_tbl ,
|
||||||
|
and
|
||||||
|
.Fn print_tblclose
|
||||||
|
are not yet documented.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width mandoc_aux.c -compact
|
||||||
|
.It Pa main.h
|
||||||
|
declarations of public functions for use by the main program,
|
||||||
|
not yet documented
|
||||||
|
.It Pa html.h
|
||||||
|
declarations of data types and private functions
|
||||||
|
for use by language-specific HTML formatters
|
||||||
|
.It Pa html.c
|
||||||
|
main HTML formatting engine and utility functions
|
||||||
|
.It Pa mdoc_html.c
|
||||||
|
.Xr mdoc 7
|
||||||
|
HTML formatter
|
||||||
|
.It Pa man_html.c
|
||||||
|
.Xr man 7
|
||||||
|
HTML formatter
|
||||||
|
.It Pa tbl_html.c
|
||||||
|
.Xr tbl 7
|
||||||
|
HTML formatter
|
||||||
|
.It Pa eqn_html.c
|
||||||
|
.Xr eqn 7
|
||||||
|
HTML formatter
|
||||||
|
.It Pa out.h
|
||||||
|
declarations of data types and private functions
|
||||||
|
for shared use by all mandoc formatters,
|
||||||
|
not yet documented
|
||||||
|
.It Pa out.c
|
||||||
|
private functions for shared use by all mandoc formatters
|
||||||
|
.It Pa mandoc_aux.h
|
||||||
|
declarations of common mandoc utility functions, see
|
||||||
|
.Xr mandoc 3
|
||||||
|
.It Pa mandoc_aux.c
|
||||||
|
implementation of common mandoc utility functions
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr mandoc 1 ,
|
||||||
|
.Xr mandoc 3 ,
|
||||||
|
.Xr man.cgi 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
The mandoc HTML formatter was written by
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||||
|
This manual was written by
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
197
contrib/mdocml/mandoc_malloc.3
Normal file
197
contrib/mdocml/mandoc_malloc.3
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
.\" $Id: mandoc_malloc.3,v 1.1 2014/08/05 05:48:56 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: August 5 2014 $
|
||||||
|
.Dt MANDOC_MALLOC 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mandoc_malloc ,
|
||||||
|
.Nm mandoc_realloc ,
|
||||||
|
.Nm mandoc_reallocarray ,
|
||||||
|
.Nm mandoc_calloc ,
|
||||||
|
.Nm mandoc_strdup ,
|
||||||
|
.Nm mandoc_strndup ,
|
||||||
|
.Nm mandoc_asprintf
|
||||||
|
.Nd memory allocation function wrappers used in the mandoc library
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libmandoc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In sys/types.h
|
||||||
|
.In mandoc_aux.h
|
||||||
|
.Ft "void *"
|
||||||
|
.Fo mandoc_malloc
|
||||||
|
.Fa "size_t size"
|
||||||
|
.Fc
|
||||||
|
.Ft "void *"
|
||||||
|
.Fo mandoc_realloc
|
||||||
|
.Fa "void *ptr"
|
||||||
|
.Fa "size_t size"
|
||||||
|
.Fc
|
||||||
|
.Ft "void *"
|
||||||
|
.Fo mandoc_reallocarray
|
||||||
|
.Fa "void *ptr"
|
||||||
|
.Fa "size_t nmemb"
|
||||||
|
.Fa "size_t size"
|
||||||
|
.Fc
|
||||||
|
.Ft "void *"
|
||||||
|
.Fo mandoc_calloc
|
||||||
|
.Fa "size_t nmemb"
|
||||||
|
.Fa "size_t size"
|
||||||
|
.Fc
|
||||||
|
.Ft "char *"
|
||||||
|
.Fo mandoc_strdup
|
||||||
|
.Fa "const char *s"
|
||||||
|
.Fc
|
||||||
|
.Ft "char *"
|
||||||
|
.Fo mandoc_strndup
|
||||||
|
.Fa "const char *s"
|
||||||
|
.Fa "size_t maxlen"
|
||||||
|
.Fc
|
||||||
|
.Ft int
|
||||||
|
.Fo mandoc_asprintf
|
||||||
|
.Fa "char **ret"
|
||||||
|
.Fa "const char *format"
|
||||||
|
.Fa "..."
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These functions call the
|
||||||
|
.Lb libc
|
||||||
|
functions of the same names, passing through their return values when
|
||||||
|
successful.
|
||||||
|
In case of failure, they do not return, but instead call
|
||||||
|
.Xr perror 3
|
||||||
|
and
|
||||||
|
.Xr exit 3 .
|
||||||
|
They can be used both internally by any code in the
|
||||||
|
.Lb libmandoc
|
||||||
|
and externally by programs using that library, for example
|
||||||
|
.Xr mandoc 1 ,
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
and
|
||||||
|
.Xr makewhatis 8 .
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mandoc_malloc
|
||||||
|
allocates one new object, leaving the memory uninitialized.
|
||||||
|
The functions
|
||||||
|
.Fn mandoc_realloc
|
||||||
|
and
|
||||||
|
.Fn mandoc_reallocarray
|
||||||
|
change the size of an existing object or array, possibly moving it.
|
||||||
|
When shrinking the size, existing data is truncated; when growing,
|
||||||
|
the additional memory is not initialized.
|
||||||
|
The function
|
||||||
|
.Fn mandoc_calloc
|
||||||
|
allocates a new array, initializing it to zero.
|
||||||
|
.Pp
|
||||||
|
The argument
|
||||||
|
.Fa size
|
||||||
|
is the size of each object.
|
||||||
|
The argument
|
||||||
|
.Fa nmemb
|
||||||
|
is the new number of objects in the array.
|
||||||
|
The argument
|
||||||
|
.Fa ptr
|
||||||
|
is a pointer to the existing object or array to be resized; if it is
|
||||||
|
.Dv NULL ,
|
||||||
|
a new object or array is allocated.
|
||||||
|
.Pp
|
||||||
|
The functions
|
||||||
|
.Fn mandoc_strdup
|
||||||
|
and
|
||||||
|
.Fn mandoc_strndup
|
||||||
|
copy a string into newly allocated memory.
|
||||||
|
For
|
||||||
|
.Fn mandoc_strdup ,
|
||||||
|
the string pointed to by
|
||||||
|
.Fa s
|
||||||
|
needs to be NUL-terminated.
|
||||||
|
For
|
||||||
|
.Fn mandoc_strndup ,
|
||||||
|
at most
|
||||||
|
.Fa maxlen
|
||||||
|
bytes are copied.
|
||||||
|
The function
|
||||||
|
.Fn mandoc_asprintf
|
||||||
|
writes output formatted according to
|
||||||
|
.Fa format
|
||||||
|
into newly allocated memory and returns a pointer to the result in
|
||||||
|
.Fa ret .
|
||||||
|
For all three string functions, the result is always NUL-terminated.
|
||||||
|
.Pp
|
||||||
|
When the objects and strings are no longer needed,
|
||||||
|
the pointers returned by these functions can be passed to
|
||||||
|
.Xr free 3 .
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The function
|
||||||
|
.Fn mandoc_asprintf
|
||||||
|
always returns the number of characters written, excluding the
|
||||||
|
final NUL byte.
|
||||||
|
It never returns -1.
|
||||||
|
.Pp
|
||||||
|
The other functions always return a valid pointer; they never return
|
||||||
|
.Dv NULL .
|
||||||
|
.Sh FILES
|
||||||
|
These functions are implemented in
|
||||||
|
.Pa mandoc_aux.c .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr asprintf 3 ,
|
||||||
|
.Xr exit 3 ,
|
||||||
|
.Xr malloc 3 ,
|
||||||
|
.Xr perror 3 ,
|
||||||
|
.Xr strdup 3
|
||||||
|
.Sh STANDARDS
|
||||||
|
The functions
|
||||||
|
.Fn malloc ,
|
||||||
|
.Fn realloc ,
|
||||||
|
and
|
||||||
|
.Fn calloc
|
||||||
|
are required by
|
||||||
|
.St -ansiC .
|
||||||
|
The functions
|
||||||
|
.Fn strdup
|
||||||
|
and
|
||||||
|
.Fn strndup
|
||||||
|
are required by
|
||||||
|
.St -p1003.1-2008 .
|
||||||
|
The function
|
||||||
|
.Fn asprintf
|
||||||
|
is a widespread extension that first appeared in the GNU C library.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn reallocarray
|
||||||
|
is an extension that first appeared in
|
||||||
|
.Ox 5.6 .
|
||||||
|
If it is not provided by the operating system, the mandoc build system
|
||||||
|
uses a bundled portable implementation.
|
||||||
|
.Sh HISTORY
|
||||||
|
The functions
|
||||||
|
.Fn mandoc_malloc ,
|
||||||
|
.Fn mandoc_realloc ,
|
||||||
|
.Fn mandoc_calloc ,
|
||||||
|
and
|
||||||
|
.Fn mandoc_strdup
|
||||||
|
have been available since mandoc 1.9.12,
|
||||||
|
.Fn mandoc_strndup
|
||||||
|
since 1.11.5,
|
||||||
|
and
|
||||||
|
.Fn mandoc_asprintf
|
||||||
|
and
|
||||||
|
.Fn mandoc_reallocarray
|
||||||
|
since 1.12.4 and 1.13.0.
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
2491
contrib/mdocml/mandocdb.c
Normal file
2491
contrib/mdocml/mandocdb.c
Normal file
File diff suppressed because it is too large
Load Diff
190
contrib/mdocml/manpage.c
Normal file
190
contrib/mdocml/manpage.c
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/* $Id: manpage.c,v 1.7 2014/01/06 03:02:46 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 <assert.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "manpath.h"
|
||||||
|
#include "mansearch.h"
|
||||||
|
|
||||||
|
static void show(const char *, const char *);
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ch, term;
|
||||||
|
size_t i, sz, len;
|
||||||
|
struct mansearch search;
|
||||||
|
struct manpage *res;
|
||||||
|
char *conf_file, *defpaths, *auxpaths, *cp;
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
const char *cmd;
|
||||||
|
struct manpaths paths;
|
||||||
|
char *progname;
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
term = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO);
|
||||||
|
|
||||||
|
progname = strrchr(argv[0], '/');
|
||||||
|
if (progname == NULL)
|
||||||
|
progname = argv[0];
|
||||||
|
else
|
||||||
|
++progname;
|
||||||
|
|
||||||
|
auxpaths = defpaths = conf_file = NULL;
|
||||||
|
memset(&paths, 0, sizeof(struct manpaths));
|
||||||
|
memset(&search, 0, sizeof(struct mansearch));
|
||||||
|
|
||||||
|
while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
|
||||||
|
switch (ch) {
|
||||||
|
case ('C'):
|
||||||
|
conf_file = optarg;
|
||||||
|
break;
|
||||||
|
case ('M'):
|
||||||
|
defpaths = optarg;
|
||||||
|
break;
|
||||||
|
case ('m'):
|
||||||
|
auxpaths = 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 = TYPE_Nm | TYPE_Nd;
|
||||||
|
|
||||||
|
manpath_parse(&paths, conf_file, defpaths, auxpaths);
|
||||||
|
ch = mansearch(&search, &paths, argc, argv, "Nd", &res, &sz);
|
||||||
|
manpath_free(&paths);
|
||||||
|
|
||||||
|
if (0 == ch)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
if (0 == sz) {
|
||||||
|
free(res);
|
||||||
|
return(EXIT_FAILURE);
|
||||||
|
} else if (1 == sz && term) {
|
||||||
|
i = 1;
|
||||||
|
goto show;
|
||||||
|
} else if (NULL == res)
|
||||||
|
return(EXIT_FAILURE);
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++) {
|
||||||
|
printf("%6zu %s: %s\n",
|
||||||
|
i + 1, res[i].names, res[i].output);
|
||||||
|
free(res[i].names);
|
||||||
|
free(res[i].output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == term) {
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
free(res[i].file);
|
||||||
|
free(res);
|
||||||
|
return(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
printf("Enter a choice [1]: ");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (NULL != (cp = fgetln(stdin, &len)))
|
||||||
|
if ('\n' == cp[--len] && len > 0) {
|
||||||
|
cp[len] = '\0';
|
||||||
|
if ((i = atoi(cp)) < 1 || i > sz)
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == i) {
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
free(res[i].file);
|
||||||
|
free(res);
|
||||||
|
return(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
show:
|
||||||
|
cmd = res[i - 1].form ? "mandoc" : "cat";
|
||||||
|
strlcpy(buf, res[i - 1].file, PATH_MAX);
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
free(res[i].file);
|
||||||
|
free(res);
|
||||||
|
|
||||||
|
show(cmd, buf);
|
||||||
|
/* NOTREACHED */
|
||||||
|
usage:
|
||||||
|
fprintf(stderr, "usage: %s [-C conf] "
|
||||||
|
"[-M paths] "
|
||||||
|
"[-m paths] "
|
||||||
|
"[-S arch] "
|
||||||
|
"[-s section] "
|
||||||
|
"expr ...\n",
|
||||||
|
progname);
|
||||||
|
return(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
show(const char *cmd, const char *file)
|
||||||
|
{
|
||||||
|
int fds[2];
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (-1 == pipe(fds)) {
|
||||||
|
perror(NULL);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == (pid = fork())) {
|
||||||
|
perror(NULL);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
dup2(fds[0], STDIN_FILENO);
|
||||||
|
close(fds[1]);
|
||||||
|
cmd = NULL != getenv("MANPAGER") ?
|
||||||
|
getenv("MANPAGER") :
|
||||||
|
(NULL != getenv("PAGER") ?
|
||||||
|
getenv("PAGER") : "more");
|
||||||
|
execlp(cmd, cmd, (char *)NULL);
|
||||||
|
perror(cmd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
dup2(fds[1], STDOUT_FILENO);
|
||||||
|
close(fds[0]);
|
||||||
|
execlp(cmd, cmd, file, (char *)NULL);
|
||||||
|
perror(cmd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
222
contrib/mdocml/manpath.c
Normal file
222
contrib/mdocml/manpath.c
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/* $Id: manpath.c,v 1.15 2014/04/23 21:06:41 schwarze Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mandoc_aux.h"
|
||||||
|
#include "manpath.h"
|
||||||
|
|
||||||
|
#define MAN_CONF_FILE "/etc/man.conf"
|
||||||
|
#define MAN_CONF_KEY "_whatdb"
|
||||||
|
|
||||||
|
static void manpath_add(struct manpaths *, const char *);
|
||||||
|
static void manpath_parseline(struct manpaths *, char *);
|
||||||
|
|
||||||
|
void
|
||||||
|
manpath_parse(struct manpaths *dirs, const char *file,
|
||||||
|
char *defp, char *auxp)
|
||||||
|
{
|
||||||
|
#ifdef USE_MANPATH
|
||||||
|
char cmd[(PATH_MAX * 3) + 20];
|
||||||
|
FILE *stream;
|
||||||
|
char *buf;
|
||||||
|
size_t sz, bsz;
|
||||||
|
|
||||||
|
strlcpy(cmd, "manpath", sizeof(cmd));
|
||||||
|
if (file) {
|
||||||
|
strlcat(cmd, " -C ", sizeof(cmd));
|
||||||
|
strlcat(cmd, file, sizeof(cmd));
|
||||||
|
}
|
||||||
|
if (auxp) {
|
||||||
|
strlcat(cmd, " -m ", sizeof(cmd));
|
||||||
|
strlcat(cmd, auxp, sizeof(cmd));
|
||||||
|
}
|
||||||
|
if (defp) {
|
||||||
|
strlcat(cmd, " -M ", sizeof(cmd));
|
||||||
|
strlcat(cmd, defp, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open manpath(1). Ignore errors. */
|
||||||
|
|
||||||
|
stream = popen(cmd, "r");
|
||||||
|
if (NULL == stream)
|
||||||
|
return;
|
||||||
|
|
||||||
|
buf = NULL;
|
||||||
|
bsz = 0;
|
||||||
|
|
||||||
|
/* Read in as much output as we can. */
|
||||||
|
|
||||||
|
do {
|
||||||
|
buf = mandoc_realloc(buf, bsz + 1024);
|
||||||
|
sz = fread(buf + bsz, 1, 1024, stream);
|
||||||
|
bsz += sz;
|
||||||
|
} while (sz > 0);
|
||||||
|
|
||||||
|
if ( ! ferror(stream) && feof(stream) &&
|
||||||
|
bsz && '\n' == buf[bsz - 1]) {
|
||||||
|
buf[bsz - 1] = '\0';
|
||||||
|
manpath_parseline(dirs, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
pclose(stream);
|
||||||
|
#else
|
||||||
|
char *insert;
|
||||||
|
|
||||||
|
/* Always prepend -m. */
|
||||||
|
manpath_parseline(dirs, auxp);
|
||||||
|
|
||||||
|
/* If -M is given, it overrides everything else. */
|
||||||
|
if (NULL != defp) {
|
||||||
|
manpath_parseline(dirs, defp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MANPATH and man.conf(5) cooperate. */
|
||||||
|
defp = getenv("MANPATH");
|
||||||
|
if (NULL == file)
|
||||||
|
file = MAN_CONF_FILE;
|
||||||
|
|
||||||
|
/* No MANPATH; use man.conf(5) only. */
|
||||||
|
if (NULL == defp || '\0' == defp[0]) {
|
||||||
|
manpath_manconf(dirs, file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepend man.conf(5) to MANPATH. */
|
||||||
|
if (':' == defp[0]) {
|
||||||
|
manpath_manconf(dirs, file);
|
||||||
|
manpath_parseline(dirs, defp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append man.conf(5) to MANPATH. */
|
||||||
|
if (':' == defp[strlen(defp) - 1]) {
|
||||||
|
manpath_parseline(dirs, defp);
|
||||||
|
manpath_manconf(dirs, file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert man.conf(5) into MANPATH. */
|
||||||
|
insert = strstr(defp, "::");
|
||||||
|
if (NULL != insert) {
|
||||||
|
*insert++ = '\0';
|
||||||
|
manpath_parseline(dirs, defp);
|
||||||
|
manpath_manconf(dirs, file);
|
||||||
|
manpath_parseline(dirs, insert + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MANPATH overrides man.conf(5) completely. */
|
||||||
|
manpath_parseline(dirs, defp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse a FULL pathname from a colon-separated list of arrays.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
manpath_parseline(struct manpaths *dirs, char *path)
|
||||||
|
{
|
||||||
|
char *dir;
|
||||||
|
|
||||||
|
if (NULL == path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
|
||||||
|
manpath_add(dirs, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a directory to the array, ignoring bad directories.
|
||||||
|
* Grow the array one-by-one for simplicity's sake.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
manpath_add(struct manpaths *dirs, const char *dir)
|
||||||
|
{
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
char *cp;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (NULL == (cp = realpath(dir, buf)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < dirs->sz; i++)
|
||||||
|
if (0 == strcmp(dirs->paths[i], dir))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dirs->paths = mandoc_reallocarray(dirs->paths,
|
||||||
|
dirs->sz + 1, sizeof(char *));
|
||||||
|
|
||||||
|
dirs->paths[dirs->sz++] = mandoc_strdup(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
manpath_free(struct manpaths *p)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < p->sz; i++)
|
||||||
|
free(p->paths[i]);
|
||||||
|
|
||||||
|
free(p->paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
manpath_manconf(struct manpaths *dirs, const char *file)
|
||||||
|
{
|
||||||
|
FILE *stream;
|
||||||
|
char *p, *q;
|
||||||
|
size_t len, keysz;
|
||||||
|
|
||||||
|
keysz = strlen(MAN_CONF_KEY);
|
||||||
|
assert(keysz > 0);
|
||||||
|
|
||||||
|
if (NULL == (stream = fopen(file, "r")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (NULL != (p = fgetln(stream, &len))) {
|
||||||
|
if (0 == len || '\n' != p[--len])
|
||||||
|
break;
|
||||||
|
p[len] = '\0';
|
||||||
|
while (isspace((unsigned char)*p))
|
||||||
|
p++;
|
||||||
|
if (strncmp(MAN_CONF_KEY, p, keysz))
|
||||||
|
continue;
|
||||||
|
p += keysz;
|
||||||
|
while (isspace((unsigned char)*p))
|
||||||
|
p++;
|
||||||
|
if ('\0' == *p)
|
||||||
|
continue;
|
||||||
|
if (NULL == (q = strrchr(p, '/')))
|
||||||
|
continue;
|
||||||
|
*q = '\0';
|
||||||
|
manpath_add(dirs, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
}
|
38
contrib/mdocml/manpath.h
Normal file
38
contrib/mdocml/manpath.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* $Id: manpath.h,v 1.6 2012/06/08 10:32:40 kristaps Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef MANPATH_H
|
||||||
|
#define MANPATH_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unsorted list of unique, absolute paths to be searched for manual
|
||||||
|
* databases.
|
||||||
|
*/
|
||||||
|
struct manpaths {
|
||||||
|
size_t sz;
|
||||||
|
char **paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
void manpath_manconf(struct manpaths *, const char *);
|
||||||
|
void manpath_parse(struct manpaths *, const char *, char *, char *);
|
||||||
|
void manpath_free(struct manpaths *);
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /*!MANPATH_H*/
|
228
contrib/mdocml/mansearch.3
Normal file
228
contrib/mdocml/mansearch.3
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
.\" $Id: mansearch.3,v 1.2 2014/08/05 15:29:30 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: August 5 2014 $
|
||||||
|
.Dt MANSEARCH 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mansearch ,
|
||||||
|
.Nm mansearch_setup
|
||||||
|
.Nd search manual page databases
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In stdint.h
|
||||||
|
.In manpath.h
|
||||||
|
.In mansearch.h
|
||||||
|
.Ft int
|
||||||
|
.Fo mansearch_setup
|
||||||
|
.Fa "int start"
|
||||||
|
.Fc
|
||||||
|
.Ft int
|
||||||
|
.Fo mansearch
|
||||||
|
.Fa "const struct mansearch *search"
|
||||||
|
.Fa "const struct manpaths *paths"
|
||||||
|
.Fa "int argc"
|
||||||
|
.Fa "char *argv[]"
|
||||||
|
.Fa "const char *outkey"
|
||||||
|
.Fa "struct manpage **res"
|
||||||
|
.Fa "size_t *sz"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn mansearch
|
||||||
|
function returns information about manuals matching a search query from a
|
||||||
|
.Xr mandoc.db 5
|
||||||
|
SQLite3 database.
|
||||||
|
.Pp
|
||||||
|
The query arguments are as follows:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Fa "const struct mansearch *search"
|
||||||
|
Search options, defined in
|
||||||
|
.In mansearch.h .
|
||||||
|
.It Fa "const struct manpaths *paths"
|
||||||
|
Directories to be searched, defined in
|
||||||
|
.In manpath.h .
|
||||||
|
.It Fa "int argc" , "char *argv[]"
|
||||||
|
Search criteria, usually taken from the command line.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fa "const char *outkey"
|
||||||
|
selects which data to return in the
|
||||||
|
.Va output
|
||||||
|
field of the
|
||||||
|
.Fa res
|
||||||
|
structures.
|
||||||
|
It takes any of the macro keys defined in
|
||||||
|
.Pa mansearch_const.c
|
||||||
|
and described in
|
||||||
|
.Xr apropos 1 .
|
||||||
|
.Pp
|
||||||
|
The output arguments are as follows:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Fa "struct manpage **res"
|
||||||
|
Returns a pointer to an array of result structures defined in
|
||||||
|
.In mansearch.h .
|
||||||
|
The user is expected to call
|
||||||
|
.Xr free 3
|
||||||
|
on the
|
||||||
|
.Va file ,
|
||||||
|
.Va names ,
|
||||||
|
and
|
||||||
|
.Va output
|
||||||
|
fields of all structures, as well as the
|
||||||
|
.Fa res
|
||||||
|
array itself.
|
||||||
|
.It Fa "size_t *sz"
|
||||||
|
Returns the number of result structures contained in
|
||||||
|
.Fa res .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
To speed up searches, the
|
||||||
|
.Fn mansearch_setup
|
||||||
|
function can optionally be called with a
|
||||||
|
.Fa start
|
||||||
|
argument of 1 before
|
||||||
|
.Fn mansearch
|
||||||
|
to set up an SQLite3 pagecache.
|
||||||
|
If it was called, it has to be called again with a
|
||||||
|
.Fa start
|
||||||
|
argument of 0 after the last call to
|
||||||
|
.Fn mansearch
|
||||||
|
to release the memory used for the pagecache.
|
||||||
|
.Sh IMPLEMENTATION NOTES
|
||||||
|
For each manual page tree, the search is done in two steps.
|
||||||
|
In the first step, a list of pages matching the search criteria is built.
|
||||||
|
In the second step, the requested information about these pages is
|
||||||
|
retrieved from the database and assembled into the
|
||||||
|
.Fa res
|
||||||
|
array.
|
||||||
|
.Pp
|
||||||
|
All function mentioned here are defined in the file
|
||||||
|
.Pa mansearch.c .
|
||||||
|
No functions except
|
||||||
|
.Fn mansearch
|
||||||
|
and
|
||||||
|
.Fn sql_statement
|
||||||
|
build any SQL code, and no functions except
|
||||||
|
.Fn mansearch ,
|
||||||
|
.Fn buildnames ,
|
||||||
|
and
|
||||||
|
.Fn buildoutput
|
||||||
|
execute it.
|
||||||
|
.Ss Finding matches
|
||||||
|
The query is built using the following grammar:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
<query> ::= "SELECT * FROM mpages WHERE" <condition>
|
||||||
|
<condition> ::= "(" <condition> ")" |
|
||||||
|
<condition> "OR" <condition> |
|
||||||
|
<condition> "AND" <condition> |
|
||||||
|
"desc" <operator> "?" |
|
||||||
|
"id IN (SELECT pageid FROM" <subquery> ")"
|
||||||
|
<subquery> ::= "names WHERE name" <operator> "?" |
|
||||||
|
"keys WHERE key" <operator> "? AND bits & ?"
|
||||||
|
<operator> ::= "MATCH" | "REGEXP"
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The MATCH and REGEXP operators are implemented by the functions
|
||||||
|
.Fn sql_match
|
||||||
|
and
|
||||||
|
.Fn sql_regexp ,
|
||||||
|
respectively.
|
||||||
|
This is required because SQLite3 natively neither supports
|
||||||
|
case-insensitive substring matching nor regular expression matching,
|
||||||
|
but only string identity, shell globbing, and the weird home-brewed
|
||||||
|
LIKE operator.
|
||||||
|
.Pp
|
||||||
|
Command line parsing is done by the function
|
||||||
|
.Fn exprcomp
|
||||||
|
building a singly linked list of
|
||||||
|
.Vt expr
|
||||||
|
structures, using the helper functions
|
||||||
|
.Fn exprterm
|
||||||
|
and
|
||||||
|
.Fn exprspec .
|
||||||
|
The resulting SQL statement is assembled by the function
|
||||||
|
.Fn sql_statement
|
||||||
|
and evaluated in the main loop of the
|
||||||
|
.Fn mansearch
|
||||||
|
function.
|
||||||
|
.Ss Assembling the results
|
||||||
|
The names, sections, and architectures of the manuals found
|
||||||
|
are assembled into the
|
||||||
|
.Va names
|
||||||
|
field of the result structure by the function
|
||||||
|
.Fn buildnames ,
|
||||||
|
using the following query:
|
||||||
|
.Pp
|
||||||
|
.Dl "SELECT * FROM mlinks WHERE pageid=? ORDER BY sec, arch, name"
|
||||||
|
.Pp
|
||||||
|
If the
|
||||||
|
.Fa outkey
|
||||||
|
differs from
|
||||||
|
.Qq Nd ,
|
||||||
|
the requested output data is assembled into the
|
||||||
|
.Va output
|
||||||
|
field of the result structure by the function
|
||||||
|
.Fn buildoutput ,
|
||||||
|
using the following query:
|
||||||
|
.Pp
|
||||||
|
.Dl "SELECT * FROM keys WHERE pageid=? AND bits & ?"
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width mandoc.db -compact
|
||||||
|
.It Pa mandoc.db
|
||||||
|
The manual page database.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
The simplest invocation
|
||||||
|
.Pp
|
||||||
|
.Dl apropos keyword
|
||||||
|
.Pp
|
||||||
|
results in the following SQL query:
|
||||||
|
.Bd -literal
|
||||||
|
SELECT * FROM mpages WHERE (
|
||||||
|
id IN (SELECT pageid FROM names WHERE name MATCH 'keyword') OR
|
||||||
|
desc MATCH 'keyword'
|
||||||
|
);
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
A more complicated request like
|
||||||
|
.Pp
|
||||||
|
.Dl apropos -s 2 Nm,Xr=getuid
|
||||||
|
.Pp
|
||||||
|
results in:
|
||||||
|
.Bd -literal
|
||||||
|
SELECT * FROM mpages WHERE (
|
||||||
|
id IN (SELECT pageid FROM names WHERE name MATCH 'getuid') OR
|
||||||
|
id IN (SELECT pageid FROM keys WHERE key MATCH 'getuid' AND bits & 4)
|
||||||
|
) AND id IN (SELECT pageid FROM keys WHERE key REGEXP '^2$' AND bits & 2);
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr apropos 1 ,
|
||||||
|
.Xr mandoc.db 5 ,
|
||||||
|
.Xr makewhatis 8
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Fn mansearch
|
||||||
|
subsystem first appeared in
|
||||||
|
.Ox 5.6 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
A module to search manual page databases was first written by
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
in 2011, at first using the Berkeley DB;
|
||||||
|
he rewrote it for SQLite3 in 2012.
|
||||||
|
The current version received major changes from
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
861
contrib/mdocml/mansearch.c
Normal file
861
contrib/mdocml/mansearch.c
Normal file
@ -0,0 +1,861 @@
|
|||||||
|
/* $Id: mansearch.c,v 1.42 2014/08/09 14:24:53 schwarze Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2013, 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.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_OHASH
|
||||||
|
#include <ohash.h>
|
||||||
|
#else
|
||||||
|
#include "compat_ohash.h"
|
||||||
|
#endif
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#ifndef SQLITE_DETERMINISTIC
|
||||||
|
#define SQLITE_DETERMINISTIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
|
#include "manpath.h"
|
||||||
|
#include "mansearch.h"
|
||||||
|
|
||||||
|
extern int mansearch_keymax;
|
||||||
|
extern const char *const mansearch_keynames[];
|
||||||
|
|
||||||
|
#define SQL_BIND_TEXT(_db, _s, _i, _v) \
|
||||||
|
do { if (SQLITE_OK != sqlite3_bind_text \
|
||||||
|
((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \
|
||||||
|
} while (0)
|
||||||
|
#define SQL_BIND_INT64(_db, _s, _i, _v) \
|
||||||
|
do { if (SQLITE_OK != sqlite3_bind_int64 \
|
||||||
|
((_s), (_i)++, (_v))) \
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \
|
||||||
|
} while (0)
|
||||||
|
#define SQL_BIND_BLOB(_db, _s, _i, _v) \
|
||||||
|
do { if (SQLITE_OK != sqlite3_bind_blob \
|
||||||
|
((_s), (_i)++, (&_v), sizeof(_v), SQLITE_STATIC)) \
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
struct expr {
|
||||||
|
regex_t regexp; /* compiled regexp, if applicable */
|
||||||
|
const char *substr; /* to search for, if applicable */
|
||||||
|
struct expr *next; /* next in sequence */
|
||||||
|
uint64_t bits; /* type-mask */
|
||||||
|
int equal; /* equality, not subsring match */
|
||||||
|
int open; /* opening parentheses before */
|
||||||
|
int and; /* logical AND before */
|
||||||
|
int close; /* closing parentheses after */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct match {
|
||||||
|
uint64_t pageid; /* identifier in database */
|
||||||
|
char *desc; /* manual page description */
|
||||||
|
int form; /* 0 == catpage */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void buildnames(struct manpage *, sqlite3 *,
|
||||||
|
sqlite3_stmt *, uint64_t,
|
||||||
|
const char *, int form);
|
||||||
|
static char *buildoutput(sqlite3 *, sqlite3_stmt *,
|
||||||
|
uint64_t, uint64_t);
|
||||||
|
static void *hash_alloc(size_t, void *);
|
||||||
|
static void hash_free(void *, void *);
|
||||||
|
static void *hash_calloc(size_t, size_t, void *);
|
||||||
|
static struct expr *exprcomp(const struct mansearch *,
|
||||||
|
int, char *[]);
|
||||||
|
static void exprfree(struct expr *);
|
||||||
|
static struct expr *exprspec(struct expr *, uint64_t,
|
||||||
|
const char *, const char *);
|
||||||
|
static struct expr *exprterm(const struct mansearch *, char *, int);
|
||||||
|
static int manpage_compare(const void *, const void *);
|
||||||
|
static void sql_append(char **sql, size_t *sz,
|
||||||
|
const char *newstr, int count);
|
||||||
|
static void sql_match(sqlite3_context *context,
|
||||||
|
int argc, sqlite3_value **argv);
|
||||||
|
static void sql_regexp(sqlite3_context *context,
|
||||||
|
int argc, sqlite3_value **argv);
|
||||||
|
static char *sql_statement(const struct expr *);
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
mansearch_setup(int start)
|
||||||
|
{
|
||||||
|
static void *pagecache;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
#define PC_PAGESIZE 1280
|
||||||
|
#define PC_NUMPAGES 256
|
||||||
|
|
||||||
|
if (start) {
|
||||||
|
if (NULL != pagecache) {
|
||||||
|
fprintf(stderr, "pagecache already enabled\n");
|
||||||
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
|
}
|
||||||
|
|
||||||
|
pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_SHARED | MAP_ANON, -1, 0);
|
||||||
|
|
||||||
|
if (MAP_FAILED == pagecache) {
|
||||||
|
perror("mmap");
|
||||||
|
pagecache = NULL;
|
||||||
|
return((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = sqlite3_config(SQLITE_CONFIG_PAGECACHE,
|
||||||
|
pagecache, PC_PAGESIZE, PC_NUMPAGES);
|
||||||
|
|
||||||
|
if (SQLITE_OK == c)
|
||||||
|
return((int)MANDOCLEVEL_OK);
|
||||||
|
|
||||||
|
fprintf(stderr, "pagecache: %s\n", sqlite3_errstr(c));
|
||||||
|
|
||||||
|
} else if (NULL == pagecache) {
|
||||||
|
fprintf(stderr, "pagecache missing\n");
|
||||||
|
return((int)MANDOCLEVEL_BADARG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) {
|
||||||
|
perror("munmap");
|
||||||
|
pagecache = NULL;
|
||||||
|
return((int)MANDOCLEVEL_SYSERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
pagecache = NULL;
|
||||||
|
return((int)MANDOCLEVEL_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mansearch(const struct mansearch *search,
|
||||||
|
const struct manpaths *paths,
|
||||||
|
int argc, char *argv[],
|
||||||
|
const char *outkey,
|
||||||
|
struct manpage **res, size_t *sz)
|
||||||
|
{
|
||||||
|
int fd, rc, c, indexbit;
|
||||||
|
int64_t pageid;
|
||||||
|
uint64_t outbit, iterbit;
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
char *sql;
|
||||||
|
struct manpage *mpage;
|
||||||
|
struct expr *e, *ep;
|
||||||
|
sqlite3 *db;
|
||||||
|
sqlite3_stmt *s, *s2;
|
||||||
|
struct match *mp;
|
||||||
|
struct ohash_info info;
|
||||||
|
struct ohash htab;
|
||||||
|
unsigned int idx;
|
||||||
|
size_t i, j, cur, maxres;
|
||||||
|
|
||||||
|
info.calloc = hash_calloc;
|
||||||
|
info.alloc = hash_alloc;
|
||||||
|
info.free = hash_free;
|
||||||
|
info.key_offset = offsetof(struct match, pageid);
|
||||||
|
|
||||||
|
*sz = cur = maxres = 0;
|
||||||
|
sql = NULL;
|
||||||
|
*res = NULL;
|
||||||
|
fd = -1;
|
||||||
|
e = NULL;
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
if (0 == argc)
|
||||||
|
goto out;
|
||||||
|
if (NULL == (e = exprcomp(search, argc, argv)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
outbit = 0;
|
||||||
|
if (NULL != outkey) {
|
||||||
|
for (indexbit = 0, iterbit = 1;
|
||||||
|
indexbit < mansearch_keymax;
|
||||||
|
indexbit++, iterbit <<= 1) {
|
||||||
|
if (0 == strcasecmp(outkey,
|
||||||
|
mansearch_keynames[indexbit])) {
|
||||||
|
outbit = iterbit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save a descriptor to the current working directory.
|
||||||
|
* Since pathnames in the "paths" variable might be relative,
|
||||||
|
* and we'll be chdir()ing into them, we need to keep a handle
|
||||||
|
* on our current directory from which to start the chdir().
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (NULL == getcwd(buf, PATH_MAX)) {
|
||||||
|
perror("getcwd");
|
||||||
|
goto out;
|
||||||
|
} else if (-1 == (fd = open(buf, O_RDONLY, 0))) {
|
||||||
|
perror(buf);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql_statement(e);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loop over the directories (containing databases) for us to
|
||||||
|
* search.
|
||||||
|
* Don't let missing/bad databases/directories phase us.
|
||||||
|
* In each, try to open the resident database and, if it opens,
|
||||||
|
* scan it for our match expression.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < paths->sz; i++) {
|
||||||
|
if (-1 == fchdir(fd)) {
|
||||||
|
perror(buf);
|
||||||
|
free(*res);
|
||||||
|
break;
|
||||||
|
} else if (-1 == chdir(paths->paths[i])) {
|
||||||
|
perror(paths->paths[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = sqlite3_open_v2(MANDOC_DB, &db,
|
||||||
|
SQLITE_OPEN_READONLY, NULL);
|
||||||
|
|
||||||
|
if (SQLITE_OK != c) {
|
||||||
|
perror(MANDOC_DB);
|
||||||
|
sqlite3_close(db);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the SQL functions for substring
|
||||||
|
* and regular expression matching.
|
||||||
|
*/
|
||||||
|
|
||||||
|
c = sqlite3_create_function(db, "match", 2,
|
||||||
|
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||||
|
NULL, sql_match, NULL, NULL);
|
||||||
|
assert(SQLITE_OK == c);
|
||||||
|
c = sqlite3_create_function(db, "regexp", 2,
|
||||||
|
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||||
|
NULL, sql_regexp, NULL, NULL);
|
||||||
|
assert(SQLITE_OK == c);
|
||||||
|
|
||||||
|
j = 1;
|
||||||
|
c = sqlite3_prepare_v2(db, sql, -1, &s, NULL);
|
||||||
|
if (SQLITE_OK != c)
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
|
|
||||||
|
for (ep = e; NULL != ep; ep = ep->next) {
|
||||||
|
if (NULL == ep->substr) {
|
||||||
|
SQL_BIND_BLOB(db, s, j, ep->regexp);
|
||||||
|
} else
|
||||||
|
SQL_BIND_TEXT(db, s, j, ep->substr);
|
||||||
|
if (0 == ((TYPE_Nd | TYPE_Nm) & ep->bits))
|
||||||
|
SQL_BIND_INT64(db, s, j, ep->bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&htab, 0, sizeof(struct ohash));
|
||||||
|
ohash_init(&htab, 4, &info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hash each entry on its [unique] document identifier.
|
||||||
|
* This is a uint64_t.
|
||||||
|
* Instead of using a hash function, simply convert the
|
||||||
|
* uint64_t to a uint32_t, the hash value's type.
|
||||||
|
* This gives good performance and preserves the
|
||||||
|
* distribution of buckets in the table.
|
||||||
|
*/
|
||||||
|
while (SQLITE_ROW == (c = sqlite3_step(s))) {
|
||||||
|
pageid = sqlite3_column_int64(s, 2);
|
||||||
|
idx = ohash_lookup_memory(&htab,
|
||||||
|
(char *)&pageid, sizeof(uint64_t),
|
||||||
|
(uint32_t)pageid);
|
||||||
|
|
||||||
|
if (NULL != ohash_find(&htab, idx))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mp = mandoc_calloc(1, sizeof(struct match));
|
||||||
|
mp->pageid = pageid;
|
||||||
|
mp->form = sqlite3_column_int(s, 1);
|
||||||
|
if (TYPE_Nd == outbit)
|
||||||
|
mp->desc = mandoc_strdup((const char *)
|
||||||
|
sqlite3_column_text(s, 0));
|
||||||
|
ohash_insert(&htab, idx, mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SQLITE_DONE != c)
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
|
|
||||||
|
sqlite3_finalize(s);
|
||||||
|
|
||||||
|
c = sqlite3_prepare_v2(db,
|
||||||
|
"SELECT sec, arch, name, pageid FROM mlinks "
|
||||||
|
"WHERE pageid=? ORDER BY sec, arch, name",
|
||||||
|
-1, &s, NULL);
|
||||||
|
if (SQLITE_OK != c)
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
|
|
||||||
|
c = sqlite3_prepare_v2(db,
|
||||||
|
"SELECT bits, key, pageid FROM keys "
|
||||||
|
"WHERE pageid=? AND bits & ?",
|
||||||
|
-1, &s2, NULL);
|
||||||
|
if (SQLITE_OK != c)
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
|
|
||||||
|
for (mp = ohash_first(&htab, &idx);
|
||||||
|
NULL != mp;
|
||||||
|
mp = ohash_next(&htab, &idx)) {
|
||||||
|
if (cur + 1 > maxres) {
|
||||||
|
maxres += 1024;
|
||||||
|
*res = mandoc_reallocarray(*res,
|
||||||
|
maxres, sizeof(struct manpage));
|
||||||
|
}
|
||||||
|
mpage = *res + cur;
|
||||||
|
mpage->sec = 10;
|
||||||
|
mpage->form = mp->form;
|
||||||
|
buildnames(mpage, db, s, mp->pageid,
|
||||||
|
paths->paths[i], mp->form);
|
||||||
|
mpage->output = TYPE_Nd & outbit ?
|
||||||
|
mp->desc : outbit ?
|
||||||
|
buildoutput(db, s2, mp->pageid, outbit) : NULL;
|
||||||
|
|
||||||
|
free(mp);
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(s);
|
||||||
|
sqlite3_finalize(s2);
|
||||||
|
sqlite3_close(db);
|
||||||
|
ohash_delete(&htab);
|
||||||
|
}
|
||||||
|
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
|
||||||
|
rc = 1;
|
||||||
|
out:
|
||||||
|
if (-1 != fd) {
|
||||||
|
if (-1 == fchdir(fd))
|
||||||
|
perror(buf);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
exprfree(e);
|
||||||
|
free(sql);
|
||||||
|
*sz = cur;
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
manpage_compare(const void *vp1, const void *vp2)
|
||||||
|
{
|
||||||
|
const struct manpage *mp1, *mp2;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
mp1 = vp1;
|
||||||
|
mp2 = vp2;
|
||||||
|
diff = mp1->sec - mp2->sec;
|
||||||
|
return(diff ? diff : strcasecmp(mp1->names, mp2->names));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
|
||||||
|
uint64_t pageid, const char *path, int form)
|
||||||
|
{
|
||||||
|
char *newnames, *prevsec, *prevarch;
|
||||||
|
const char *oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec;
|
||||||
|
size_t i;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
mpage->file = NULL;
|
||||||
|
mpage->names = NULL;
|
||||||
|
prevsec = prevarch = NULL;
|
||||||
|
i = 1;
|
||||||
|
SQL_BIND_INT64(db, s, i, pageid);
|
||||||
|
while (SQLITE_ROW == (c = sqlite3_step(s))) {
|
||||||
|
|
||||||
|
/* Decide whether we already have some names. */
|
||||||
|
|
||||||
|
if (NULL == mpage->names) {
|
||||||
|
oldnames = "";
|
||||||
|
sep1 = "";
|
||||||
|
} else {
|
||||||
|
oldnames = mpage->names;
|
||||||
|
sep1 = ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch the next name. */
|
||||||
|
|
||||||
|
sec = (const char *)sqlite3_column_text(s, 0);
|
||||||
|
arch = (const char *)sqlite3_column_text(s, 1);
|
||||||
|
name = (const char *)sqlite3_column_text(s, 2);
|
||||||
|
|
||||||
|
/* Remember the first section found. */
|
||||||
|
|
||||||
|
if (9 < mpage->sec && '1' <= *sec && '9' >= *sec)
|
||||||
|
mpage->sec = (*sec - '1') + 1;
|
||||||
|
|
||||||
|
/* If the section changed, append the old one. */
|
||||||
|
|
||||||
|
if (NULL != prevsec &&
|
||||||
|
(strcmp(sec, prevsec) ||
|
||||||
|
strcmp(arch, prevarch))) {
|
||||||
|
sep2 = '\0' == *prevarch ? "" : "/";
|
||||||
|
mandoc_asprintf(&newnames, "%s(%s%s%s)",
|
||||||
|
oldnames, prevsec, sep2, prevarch);
|
||||||
|
free(mpage->names);
|
||||||
|
oldnames = mpage->names = newnames;
|
||||||
|
free(prevsec);
|
||||||
|
free(prevarch);
|
||||||
|
prevsec = prevarch = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the new section, to append it later. */
|
||||||
|
|
||||||
|
if (NULL == prevsec) {
|
||||||
|
prevsec = mandoc_strdup(sec);
|
||||||
|
prevarch = mandoc_strdup(arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append the new name. */
|
||||||
|
|
||||||
|
mandoc_asprintf(&newnames, "%s%s%s",
|
||||||
|
oldnames, sep1, name);
|
||||||
|
free(mpage->names);
|
||||||
|
mpage->names = newnames;
|
||||||
|
|
||||||
|
/* Also save the first file name encountered. */
|
||||||
|
|
||||||
|
if (NULL != mpage->file)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (form) {
|
||||||
|
sep1 = "man";
|
||||||
|
fsec = sec;
|
||||||
|
} else {
|
||||||
|
sep1 = "cat";
|
||||||
|
fsec = "0";
|
||||||
|
}
|
||||||
|
sep2 = '\0' == *arch ? "" : "/";
|
||||||
|
mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
|
||||||
|
path, sep1, sec, sep2, arch, name, fsec);
|
||||||
|
}
|
||||||
|
if (SQLITE_DONE != c)
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
|
sqlite3_reset(s);
|
||||||
|
|
||||||
|
/* Append one final section to the names. */
|
||||||
|
|
||||||
|
if (NULL != prevsec) {
|
||||||
|
sep2 = '\0' == *prevarch ? "" : "/";
|
||||||
|
mandoc_asprintf(&newnames, "%s(%s%s%s)",
|
||||||
|
mpage->names, prevsec, sep2, prevarch);
|
||||||
|
free(mpage->names);
|
||||||
|
mpage->names = newnames;
|
||||||
|
free(prevsec);
|
||||||
|
free(prevarch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
buildoutput(sqlite3 *db, sqlite3_stmt *s, uint64_t pageid, uint64_t outbit)
|
||||||
|
{
|
||||||
|
char *output, *newoutput;
|
||||||
|
const char *oldoutput, *sep1, *data;
|
||||||
|
size_t i;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
output = NULL;
|
||||||
|
i = 1;
|
||||||
|
SQL_BIND_INT64(db, s, i, pageid);
|
||||||
|
SQL_BIND_INT64(db, s, i, outbit);
|
||||||
|
while (SQLITE_ROW == (c = sqlite3_step(s))) {
|
||||||
|
if (NULL == output) {
|
||||||
|
oldoutput = "";
|
||||||
|
sep1 = "";
|
||||||
|
} else {
|
||||||
|
oldoutput = output;
|
||||||
|
sep1 = " # ";
|
||||||
|
}
|
||||||
|
data = (const char *)sqlite3_column_text(s, 1);
|
||||||
|
mandoc_asprintf(&newoutput, "%s%s%s",
|
||||||
|
oldoutput, sep1, data);
|
||||||
|
free(output);
|
||||||
|
output = newoutput;
|
||||||
|
}
|
||||||
|
if (SQLITE_DONE != c)
|
||||||
|
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
|
||||||
|
sqlite3_reset(s);
|
||||||
|
return(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement substring match as an application-defined SQL function.
|
||||||
|
* Using the SQL LIKE or GLOB operators instead would be a bad idea
|
||||||
|
* because that would require escaping metacharacters in the string
|
||||||
|
* being searched for.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sql_match(sqlite3_context *context, int argc, sqlite3_value **argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
assert(2 == argc);
|
||||||
|
sqlite3_result_int(context, NULL != strcasestr(
|
||||||
|
(const char *)sqlite3_value_text(argv[1]),
|
||||||
|
(const char *)sqlite3_value_text(argv[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement regular expression match
|
||||||
|
* as an application-defined SQL function.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sql_regexp(sqlite3_context *context, int argc, sqlite3_value **argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
assert(2 == argc);
|
||||||
|
sqlite3_result_int(context, !regexec(
|
||||||
|
(regex_t *)sqlite3_value_blob(argv[0]),
|
||||||
|
(const char *)sqlite3_value_text(argv[1]),
|
||||||
|
0, NULL, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sql_append(char **sql, size_t *sz, const char *newstr, int count)
|
||||||
|
{
|
||||||
|
size_t newsz;
|
||||||
|
|
||||||
|
newsz = 1 < count ? (size_t)count : strlen(newstr);
|
||||||
|
*sql = mandoc_realloc(*sql, *sz + newsz + 1);
|
||||||
|
if (1 < count)
|
||||||
|
memset(*sql + *sz, *newstr, (size_t)count);
|
||||||
|
else
|
||||||
|
memcpy(*sql + *sz, newstr, newsz);
|
||||||
|
*sz += newsz;
|
||||||
|
(*sql)[*sz] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare the search SQL statement.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
sql_statement(const struct expr *e)
|
||||||
|
{
|
||||||
|
char *sql;
|
||||||
|
size_t sz;
|
||||||
|
int needop;
|
||||||
|
|
||||||
|
sql = mandoc_strdup(
|
||||||
|
"SELECT desc, form, pageid FROM mpages WHERE ");
|
||||||
|
sz = strlen(sql);
|
||||||
|
|
||||||
|
for (needop = 0; NULL != e; e = e->next) {
|
||||||
|
if (e->and)
|
||||||
|
sql_append(&sql, &sz, " AND ", 1);
|
||||||
|
else if (needop)
|
||||||
|
sql_append(&sql, &sz, " OR ", 1);
|
||||||
|
if (e->open)
|
||||||
|
sql_append(&sql, &sz, "(", e->open);
|
||||||
|
sql_append(&sql, &sz,
|
||||||
|
TYPE_Nd & e->bits
|
||||||
|
? (NULL == e->substr
|
||||||
|
? "desc REGEXP ?"
|
||||||
|
: "desc MATCH ?")
|
||||||
|
: TYPE_Nm == e->bits
|
||||||
|
? (NULL == e->substr
|
||||||
|
? "pageid IN (SELECT pageid FROM names "
|
||||||
|
"WHERE name REGEXP ?)"
|
||||||
|
: e->equal
|
||||||
|
? "pageid IN (SELECT pageid FROM names "
|
||||||
|
"WHERE name = ?)"
|
||||||
|
: "pageid IN (SELECT pageid FROM names "
|
||||||
|
"WHERE name MATCH ?)")
|
||||||
|
: (NULL == e->substr
|
||||||
|
? "pageid IN (SELECT pageid FROM keys "
|
||||||
|
"WHERE key REGEXP ? AND bits & ?)"
|
||||||
|
: "pageid IN (SELECT pageid FROM keys "
|
||||||
|
"WHERE key MATCH ? AND bits & ?)"), 1);
|
||||||
|
if (e->close)
|
||||||
|
sql_append(&sql, &sz, ")", e->close);
|
||||||
|
needop = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile a set of string tokens into an expression.
|
||||||
|
* Tokens in "argv" are assumed to be individual expression atoms (e.g.,
|
||||||
|
* "(", "foo=bar", etc.).
|
||||||
|
*/
|
||||||
|
static struct expr *
|
||||||
|
exprcomp(const struct mansearch *search, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
uint64_t mask;
|
||||||
|
int i, toopen, logic, igncase, toclose;
|
||||||
|
struct expr *first, *prev, *cur, *next;
|
||||||
|
|
||||||
|
first = cur = NULL;
|
||||||
|
logic = igncase = toclose = 0;
|
||||||
|
toopen = NULL != search->sec || NULL != search->arch;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
if (0 == strcmp("(", argv[i])) {
|
||||||
|
if (igncase)
|
||||||
|
goto fail;
|
||||||
|
toopen++;
|
||||||
|
toclose++;
|
||||||
|
continue;
|
||||||
|
} else if (0 == strcmp(")", argv[i])) {
|
||||||
|
if (toopen || logic || igncase || NULL == cur)
|
||||||
|
goto fail;
|
||||||
|
cur->close++;
|
||||||
|
if (0 > --toclose)
|
||||||
|
goto fail;
|
||||||
|
continue;
|
||||||
|
} else if (0 == strcmp("-a", argv[i])) {
|
||||||
|
if (toopen || logic || igncase || NULL == cur)
|
||||||
|
goto fail;
|
||||||
|
logic = 1;
|
||||||
|
continue;
|
||||||
|
} else if (0 == strcmp("-o", argv[i])) {
|
||||||
|
if (toopen || logic || igncase || NULL == cur)
|
||||||
|
goto fail;
|
||||||
|
logic = 2;
|
||||||
|
continue;
|
||||||
|
} else if (0 == strcmp("-i", argv[i])) {
|
||||||
|
if (igncase)
|
||||||
|
goto fail;
|
||||||
|
igncase = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
next = exprterm(search, argv[i], !igncase);
|
||||||
|
if (NULL == next)
|
||||||
|
goto fail;
|
||||||
|
if (NULL == first)
|
||||||
|
first = next;
|
||||||
|
else
|
||||||
|
cur->next = next;
|
||||||
|
prev = cur = next;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Searching for descriptions must be split out
|
||||||
|
* because they are stored in the mpages table,
|
||||||
|
* not in the keys table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (mask = TYPE_Nm; mask <= TYPE_Nd; mask <<= 1) {
|
||||||
|
if (mask & cur->bits && ~mask & cur->bits) {
|
||||||
|
next = mandoc_calloc(1,
|
||||||
|
sizeof(struct expr));
|
||||||
|
memcpy(next, cur, sizeof(struct expr));
|
||||||
|
prev->open = 1;
|
||||||
|
cur->bits = mask;
|
||||||
|
cur->next = next;
|
||||||
|
cur = next;
|
||||||
|
cur->bits &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev->and = (1 == logic);
|
||||||
|
prev->open += toopen;
|
||||||
|
if (cur != prev)
|
||||||
|
cur->close = 1;
|
||||||
|
|
||||||
|
toopen = logic = igncase = 0;
|
||||||
|
}
|
||||||
|
if (toopen || logic || igncase || toclose)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (NULL != search->sec || NULL != search->arch)
|
||||||
|
cur->close++;
|
||||||
|
if (NULL != search->arch)
|
||||||
|
cur = exprspec(cur, TYPE_arch, search->arch, "^(%s|any)$");
|
||||||
|
if (NULL != search->sec)
|
||||||
|
exprspec(cur, TYPE_sec, search->sec, "^%s$");
|
||||||
|
|
||||||
|
return(first);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (NULL != first)
|
||||||
|
exprfree(first);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct expr *
|
||||||
|
exprspec(struct expr *cur, uint64_t key, const char *value,
|
||||||
|
const char *format)
|
||||||
|
{
|
||||||
|
char errbuf[BUFSIZ];
|
||||||
|
char *cp;
|
||||||
|
int irc;
|
||||||
|
|
||||||
|
mandoc_asprintf(&cp, format, value);
|
||||||
|
cur->next = mandoc_calloc(1, sizeof(struct expr));
|
||||||
|
cur = cur->next;
|
||||||
|
cur->and = 1;
|
||||||
|
cur->bits = key;
|
||||||
|
if (0 != (irc = regcomp(&cur->regexp, cp,
|
||||||
|
REG_EXTENDED | REG_NOSUB | REG_ICASE))) {
|
||||||
|
regerror(irc, &cur->regexp, errbuf, sizeof(errbuf));
|
||||||
|
fprintf(stderr, "regcomp: %s\n", errbuf);
|
||||||
|
cur->substr = value;
|
||||||
|
}
|
||||||
|
free(cp);
|
||||||
|
return(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct expr *
|
||||||
|
exprterm(const struct mansearch *search, char *buf, int cs)
|
||||||
|
{
|
||||||
|
char errbuf[BUFSIZ];
|
||||||
|
struct expr *e;
|
||||||
|
char *key, *val;
|
||||||
|
uint64_t iterbit;
|
||||||
|
int i, irc;
|
||||||
|
|
||||||
|
if ('\0' == *buf)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
e = mandoc_calloc(1, sizeof(struct expr));
|
||||||
|
|
||||||
|
if (MANSEARCH_MAN & search->flags) {
|
||||||
|
e->bits = search->deftype;
|
||||||
|
e->substr = buf;
|
||||||
|
e->equal = 1;
|
||||||
|
return(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for an '=' or '~' operator,
|
||||||
|
* unless forced to some fixed macro keys.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (MANSEARCH_WHATIS & search->flags)
|
||||||
|
val = NULL;
|
||||||
|
else
|
||||||
|
val = strpbrk(buf, "=~");
|
||||||
|
|
||||||
|
if (NULL == val) {
|
||||||
|
e->bits = search->deftype;
|
||||||
|
e->substr = buf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Found an operator.
|
||||||
|
* Regexp search is requested by !e->substr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (val == buf)
|
||||||
|
e->bits = search->deftype;
|
||||||
|
if ('=' == *val)
|
||||||
|
e->substr = val + 1;
|
||||||
|
*val++ = '\0';
|
||||||
|
if (NULL != strstr(buf, "arch"))
|
||||||
|
cs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compile regular expressions. */
|
||||||
|
|
||||||
|
if (MANSEARCH_WHATIS & search->flags) {
|
||||||
|
e->substr = NULL;
|
||||||
|
mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == e->substr) {
|
||||||
|
irc = regcomp(&e->regexp, val,
|
||||||
|
REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
|
||||||
|
if (MANSEARCH_WHATIS & search->flags)
|
||||||
|
free(val);
|
||||||
|
if (irc) {
|
||||||
|
regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
|
||||||
|
fprintf(stderr, "regcomp: %s\n", errbuf);
|
||||||
|
free(e);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->bits)
|
||||||
|
return(e);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse out all possible fields.
|
||||||
|
* If the field doesn't resolve, bail.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (NULL != (key = strsep(&buf, ","))) {
|
||||||
|
if ('\0' == *key)
|
||||||
|
continue;
|
||||||
|
for (i = 0, iterbit = 1;
|
||||||
|
i < mansearch_keymax;
|
||||||
|
i++, iterbit <<= 1) {
|
||||||
|
if (0 == strcasecmp(key,
|
||||||
|
mansearch_keynames[i])) {
|
||||||
|
e->bits |= iterbit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == mansearch_keymax) {
|
||||||
|
if (strcasecmp(key, "any")) {
|
||||||
|
free(e);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
e->bits |= ~0ULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
exprfree(struct expr *p)
|
||||||
|
{
|
||||||
|
struct expr *pp;
|
||||||
|
|
||||||
|
while (NULL != p) {
|
||||||
|
pp = p->next;
|
||||||
|
free(p);
|
||||||
|
p = pp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
hash_calloc(size_t nmemb, size_t sz, void *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
return(mandoc_calloc(nmemb, sz));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
hash_alloc(size_t sz, void *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
return(mandoc_malloc(sz));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hash_free(void *p, void *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
free(p);
|
||||||
|
}
|
101
contrib/mdocml/mansearch.h
Normal file
101
contrib/mdocml/mansearch.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* $Id: mansearch.h,v 1.15 2014/07/24 20:30:45 schwarze Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
|
* Copyright (c) 2013, 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.
|
||||||
|
*/
|
||||||
|
#ifndef MANSEARCH_H
|
||||||
|
#define MANSEARCH_H
|
||||||
|
|
||||||
|
#define MANDOC_DB "mandoc.db"
|
||||||
|
|
||||||
|
#define TYPE_arch 0x0000000000000001ULL
|
||||||
|
#define TYPE_sec 0x0000000000000002ULL
|
||||||
|
#define TYPE_Xr 0x0000000000000004ULL
|
||||||
|
#define TYPE_Ar 0x0000000000000008ULL
|
||||||
|
#define TYPE_Fa 0x0000000000000010ULL
|
||||||
|
#define TYPE_Fl 0x0000000000000020ULL
|
||||||
|
#define TYPE_Dv 0x0000000000000040ULL
|
||||||
|
#define TYPE_Fn 0x0000000000000080ULL
|
||||||
|
#define TYPE_Ic 0x0000000000000100ULL
|
||||||
|
#define TYPE_Pa 0x0000000000000200ULL
|
||||||
|
#define TYPE_Cm 0x0000000000000400ULL
|
||||||
|
#define TYPE_Li 0x0000000000000800ULL
|
||||||
|
#define TYPE_Em 0x0000000000001000ULL
|
||||||
|
#define TYPE_Cd 0x0000000000002000ULL
|
||||||
|
#define TYPE_Va 0x0000000000004000ULL
|
||||||
|
#define TYPE_Ft 0x0000000000008000ULL
|
||||||
|
#define TYPE_Tn 0x0000000000010000ULL
|
||||||
|
#define TYPE_Er 0x0000000000020000ULL
|
||||||
|
#define TYPE_Ev 0x0000000000040000ULL
|
||||||
|
#define TYPE_Sy 0x0000000000080000ULL
|
||||||
|
#define TYPE_Sh 0x0000000000100000ULL
|
||||||
|
#define TYPE_In 0x0000000000200000ULL
|
||||||
|
#define TYPE_Ss 0x0000000000400000ULL
|
||||||
|
#define TYPE_Ox 0x0000000000800000ULL
|
||||||
|
#define TYPE_An 0x0000000001000000ULL
|
||||||
|
#define TYPE_Mt 0x0000000002000000ULL
|
||||||
|
#define TYPE_St 0x0000000004000000ULL
|
||||||
|
#define TYPE_Bx 0x0000000008000000ULL
|
||||||
|
#define TYPE_At 0x0000000010000000ULL
|
||||||
|
#define TYPE_Nx 0x0000000020000000ULL
|
||||||
|
#define TYPE_Fx 0x0000000040000000ULL
|
||||||
|
#define TYPE_Lk 0x0000000080000000ULL
|
||||||
|
#define TYPE_Ms 0x0000000100000000ULL
|
||||||
|
#define TYPE_Bsx 0x0000000200000000ULL
|
||||||
|
#define TYPE_Dx 0x0000000400000000ULL
|
||||||
|
#define TYPE_Rs 0x0000000800000000ULL
|
||||||
|
#define TYPE_Vt 0x0000001000000000ULL
|
||||||
|
#define TYPE_Lb 0x0000002000000000ULL
|
||||||
|
#define TYPE_Nm 0x0000004000000000ULL
|
||||||
|
#define TYPE_Nd 0x0000008000000000ULL
|
||||||
|
|
||||||
|
#define NAME_SYN 0x0000004000000001ULL
|
||||||
|
#define NAME_FILE 0x0000004000000002ULL
|
||||||
|
#define NAME_TITLE 0x000000400000000cULL
|
||||||
|
#define NAME_FIRST 0x0000004000000008ULL
|
||||||
|
#define NAME_HEAD 0x0000004000000010ULL
|
||||||
|
#define NAME_MASK 0x000000000000001fULL
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
struct manpage {
|
||||||
|
char *file; /* to be prefixed by manpath */
|
||||||
|
char *names; /* a list of names with sections */
|
||||||
|
char *output; /* user-defined additional output */
|
||||||
|
int sec; /* section number, 10 means invalid */
|
||||||
|
int form; /* 0 == catpage */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mansearch {
|
||||||
|
const char *arch; /* architecture/NULL */
|
||||||
|
const char *sec; /* mansection/NULL */
|
||||||
|
uint64_t deftype; /* type if no key */
|
||||||
|
int flags;
|
||||||
|
#define MANSEARCH_WHATIS 0x01 /* whatis(1) mode: whole words, no keys */
|
||||||
|
#define MANSEARCH_MAN 0x02 /* man(1) mode: string equality, no keys */
|
||||||
|
};
|
||||||
|
|
||||||
|
int mansearch_setup(int);
|
||||||
|
int mansearch(const struct mansearch *cfg, /* options */
|
||||||
|
const struct manpaths *paths, /* manpaths */
|
||||||
|
int argc, /* size of argv */
|
||||||
|
char *argv[], /* search terms */
|
||||||
|
const char *outkey, /* name of additional output key */
|
||||||
|
struct manpage **res, /* results */
|
||||||
|
size_t *ressz); /* results returned */
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /*!MANSEARCH_H*/
|
35
contrib/mdocml/mansearch_const.c
Normal file
35
contrib/mdocml/mansearch_const.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* $Id: mansearch_const.c,v 1.5 2014/08/09 14:05:21 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.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "manpath.h"
|
||||||
|
#include "mansearch.h"
|
||||||
|
|
||||||
|
const int mansearch_keymax = 40;
|
||||||
|
|
||||||
|
const char *const mansearch_keynames[40] = {
|
||||||
|
"arch", "sec", "Xr", "Ar", "Fa", "Fl", "Dv", "Fn",
|
||||||
|
"Ic", "Pa", "Cm", "Li", "Em", "Cd", "Va", "Ft",
|
||||||
|
"Tn", "Er", "Ev", "Sy", "Sh", "In", "Ss", "Ox",
|
||||||
|
"An", "Mt", "St", "Bx", "At", "Nx", "Fx", "Lk",
|
||||||
|
"Ms", "Bsx", "Dx", "Rs", "Vt", "Lb", "Nm", "Nd"
|
||||||
|
};
|
224
contrib/mdocml/mchars_alloc.3
Normal file
224
contrib/mdocml/mchars_alloc.3
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
.\" $Id: mchars_alloc.3,v 1.1 2014/08/05 05:48:56 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.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: August 5 2014 $
|
||||||
|
.Dt MCHARS_ALLOC 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mchars_alloc ,
|
||||||
|
.Nm mchars_free ,
|
||||||
|
.Nm mchars_num2char ,
|
||||||
|
.Nm mchars_num2uc ,
|
||||||
|
.Nm mchars_spec2cp ,
|
||||||
|
.Nm mchars_spec2str
|
||||||
|
.Nd character table for mandoc
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libmandoc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In sys/types.h
|
||||||
|
.In mandoc.h
|
||||||
|
.Ft "struct mchars *"
|
||||||
|
.Fn mchars_alloc "void"
|
||||||
|
.Ft void
|
||||||
|
.Fo mchars_free
|
||||||
|
.Fa "struct mchars *table"
|
||||||
|
.Fc
|
||||||
|
.Ft char
|
||||||
|
.Fo mchars_num2char
|
||||||
|
.Fa "const char *decimal"
|
||||||
|
.Fa "size_t sz"
|
||||||
|
.Fc
|
||||||
|
.Ft int
|
||||||
|
.Fo mchars_num2uc
|
||||||
|
.Fa "const char *hexadecimal"
|
||||||
|
.Fa "size_t sz"
|
||||||
|
.Fc
|
||||||
|
.Ft int
|
||||||
|
.Fo mchars_spec2cp
|
||||||
|
.Fa "const struct mchars *table"
|
||||||
|
.Fa "const char *name"
|
||||||
|
.Fa "size_t sz"
|
||||||
|
.Fc
|
||||||
|
.Ft "const char *"
|
||||||
|
.Fo mchars_spec2str
|
||||||
|
.Fa "const struct mchars *table"
|
||||||
|
.Fa "const char *name"
|
||||||
|
.Fa "size_t sz"
|
||||||
|
.Fa "size_t *rsz"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These functions translate Unicode character numbers and
|
||||||
|
.Xr roff 7
|
||||||
|
character names into glyphs.
|
||||||
|
See
|
||||||
|
.Xr mandoc_char 7
|
||||||
|
for a list of
|
||||||
|
.Xr roff 7
|
||||||
|
special characters.
|
||||||
|
These functions are intended for external use by programs formatting
|
||||||
|
.Xr mdoc 7
|
||||||
|
and
|
||||||
|
.Xr man 7
|
||||||
|
pages for output, for example the
|
||||||
|
.Xr mandoc 1
|
||||||
|
output formatter modules and
|
||||||
|
.Xr makewhatis 8 .
|
||||||
|
The
|
||||||
|
.Fa decimal ,
|
||||||
|
.Fa hexadecimal ,
|
||||||
|
.Fa name ,
|
||||||
|
and
|
||||||
|
.Fa size
|
||||||
|
input arguments are usually obtained from the
|
||||||
|
.Xr mandoc_escape 3
|
||||||
|
parser function.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mchars_num2char
|
||||||
|
converts a
|
||||||
|
.Fa decimal
|
||||||
|
string representation of a character number consisting of
|
||||||
|
.Fa sz
|
||||||
|
digits into a printable ASCII character.
|
||||||
|
If the input string is non-numeric or does not represent a printable
|
||||||
|
ASCII character, the NUL character
|
||||||
|
.Pq Sq \e0
|
||||||
|
is returned.
|
||||||
|
For example, the
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl Tascii ,
|
||||||
|
.Fl Tutf8 ,
|
||||||
|
and
|
||||||
|
.Fl Thtml
|
||||||
|
output modules use this function to render
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \eN
|
||||||
|
escape sequences.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mchars_num2uc
|
||||||
|
converts a
|
||||||
|
.Fa hexadecimal
|
||||||
|
string representation of a Unicode codepoint consisting of
|
||||||
|
.Fa sz
|
||||||
|
digits into an integer representation.
|
||||||
|
If the input string is non-numeric or represents an ASCII character,
|
||||||
|
the NUL character
|
||||||
|
.Pq Sq \e0
|
||||||
|
is returned.
|
||||||
|
For example, the
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl Tutf8
|
||||||
|
and
|
||||||
|
.Fl Thtml
|
||||||
|
output modules use this function to render
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \e[u Ns Ar XXXX Ns Ic \&]
|
||||||
|
and
|
||||||
|
.Ic \eC\(aqu Ns Ar XXXX Ns Ic \(aq
|
||||||
|
escape sequences.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mchars_alloc
|
||||||
|
allocates an opaque
|
||||||
|
.Vt "struct mchars *"
|
||||||
|
table object for subsequent use by the following two lookup functions.
|
||||||
|
When no longer needed, this object can be destroyed with
|
||||||
|
.Fn mchars_free .
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mchars_spec2cp
|
||||||
|
looks up a
|
||||||
|
.Xr roff 7
|
||||||
|
special character
|
||||||
|
.Fa name
|
||||||
|
consisting of
|
||||||
|
.Fa sz
|
||||||
|
characters in the
|
||||||
|
.Fa table
|
||||||
|
and returns the corresponding Unicode codepoint.
|
||||||
|
If the
|
||||||
|
.Ar name
|
||||||
|
is not recognized, \-1 is returned.
|
||||||
|
For example, the
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl Tutf8
|
||||||
|
and
|
||||||
|
.Fl Thtml
|
||||||
|
output modules use this function to render
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \e[ Ns Ar name Ns Ic \&]
|
||||||
|
and
|
||||||
|
.Ic \eC\(aq Ns Ar name Ns Ic \(aq
|
||||||
|
escape sequences.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn mchars_spec2str
|
||||||
|
looks up a
|
||||||
|
.Xr roff 7
|
||||||
|
special character
|
||||||
|
.Fa name
|
||||||
|
consisting of
|
||||||
|
.Fa sz
|
||||||
|
characters in the
|
||||||
|
.Fa table
|
||||||
|
and returns an ASCII string representation.
|
||||||
|
The length of the representation is returned in
|
||||||
|
.Fa rsz .
|
||||||
|
In many cases, the meaning of such ASCII representations
|
||||||
|
is not quite obvious, so using
|
||||||
|
.Xr roff 7
|
||||||
|
special characters in documents intended for ASCII rendering
|
||||||
|
is usually a bad idea.
|
||||||
|
If the
|
||||||
|
.Ar name
|
||||||
|
is not recognized,
|
||||||
|
.Dv NULL
|
||||||
|
is returned.
|
||||||
|
For example,
|
||||||
|
.Xr makewhatis 8
|
||||||
|
and the
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl Tascii
|
||||||
|
output module use this function to render
|
||||||
|
.Xr roff 7
|
||||||
|
.Ic \e[ Ns Ar name Ns Ic \&]
|
||||||
|
and
|
||||||
|
.Ic \eC\(aq Ns Ar name Ns Ic \(aq
|
||||||
|
escape sequences.
|
||||||
|
.Sh FILES
|
||||||
|
These funtions are implemented in the file
|
||||||
|
.Pa chars.c .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr mandoc 1 ,
|
||||||
|
.Xr mandoc_escape 3 ,
|
||||||
|
.Xr mandoc_char 7 ,
|
||||||
|
.Xr roff 7
|
||||||
|
.Sh HISTORY
|
||||||
|
These functions and their predecessors have been available since the
|
||||||
|
following mandoc versions:
|
||||||
|
.Bl -column "mchars_num2char()" "1.11.3" "chars_num2char()" "1.10.10"
|
||||||
|
.It Sy function Ta since Ta Sy predecessor Ta since
|
||||||
|
.It Fn mchars_alloc Ta 1.11.3 Ta Fn ascii2htab Ta 1.5.3
|
||||||
|
.It Fn mchars_free Ta 1.11.2 Ta Fn asciifree Ta 1.6.0
|
||||||
|
.It Fn mchars_num2char Ta 1.11.2 Ta Fn chars_num2char Ta 1.10.10
|
||||||
|
.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_spec2str Ta 1.11.2 Ta Fn a2ascii Ta 1.5.3
|
||||||
|
.El
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||||
|
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: mdoc.7,v 1.223 2013/12/25 14:09:32 schwarze Exp $
|
.\" $Id: mdoc.7,v 1.234 2014/08/08 16:38:06 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: December 25 2013 $
|
.Dd $Mdocdate: August 8 2014 $
|
||||||
.Dt MDOC 7
|
.Dt MDOC 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -125,7 +125,7 @@ file for a utility
|
|||||||
\&.Nm progname
|
\&.Nm progname
|
||||||
\&.Nd one line about what it does
|
\&.Nd one line about what it does
|
||||||
\&.\e\(dq .Sh LIBRARY
|
\&.\e\(dq .Sh LIBRARY
|
||||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
\&.\e\(dq For sections 2, 3, and 9 only.
|
||||||
\&.\e\(dq Not used in OpenBSD.
|
\&.\e\(dq Not used in OpenBSD.
|
||||||
\&.Sh SYNOPSIS
|
\&.Sh SYNOPSIS
|
||||||
\&.Nm progname
|
\&.Nm progname
|
||||||
@ -135,20 +135,22 @@ file for a utility
|
|||||||
The
|
The
|
||||||
\&.Nm
|
\&.Nm
|
||||||
utility processes files ...
|
utility processes files ...
|
||||||
|
\&.\e\(dq .Sh CONTEXT
|
||||||
|
\&.\e\(dq For section 9 functions only.
|
||||||
\&.\e\(dq .Sh IMPLEMENTATION NOTES
|
\&.\e\(dq .Sh IMPLEMENTATION NOTES
|
||||||
\&.\e\(dq Not used in OpenBSD.
|
\&.\e\(dq Not used in OpenBSD.
|
||||||
\&.\e\(dq .Sh RETURN VALUES
|
\&.\e\(dq .Sh RETURN VALUES
|
||||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
\&.\e\(dq For sections 2, 3, and 9 function return values only.
|
||||||
\&.\e\(dq .Sh ENVIRONMENT
|
\&.\e\(dq .Sh ENVIRONMENT
|
||||||
\&.\e\(dq For sections 1, 6, 7, & 8 only.
|
\&.\e\(dq For sections 1, 6, 7, and 8 only.
|
||||||
\&.\e\(dq .Sh FILES
|
\&.\e\(dq .Sh FILES
|
||||||
\&.\e\(dq .Sh EXIT STATUS
|
\&.\e\(dq .Sh EXIT STATUS
|
||||||
\&.\e\(dq For sections 1, 6, & 8 only.
|
\&.\e\(dq For sections 1, 6, and 8 only.
|
||||||
\&.\e\(dq .Sh EXAMPLES
|
\&.\e\(dq .Sh EXAMPLES
|
||||||
\&.\e\(dq .Sh DIAGNOSTICS
|
\&.\e\(dq .Sh DIAGNOSTICS
|
||||||
\&.\e\(dq For sections 1, 4, 6, 7, & 8 only.
|
\&.\e\(dq For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only.
|
||||||
\&.\e\(dq .Sh ERRORS
|
\&.\e\(dq .Sh ERRORS
|
||||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
\&.\e\(dq For sections 2, 3, 4, and 9 errno settings only.
|
||||||
\&.\e\(dq .Sh SEE ALSO
|
\&.\e\(dq .Sh SEE ALSO
|
||||||
\&.\e\(dq .Xr foobar 1
|
\&.\e\(dq .Xr foobar 1
|
||||||
\&.\e\(dq .Sh STANDARDS
|
\&.\e\(dq .Sh STANDARDS
|
||||||
@ -318,6 +320,9 @@ macro followed by a non-standard section name, and each having
|
|||||||
several subsections, like in the present
|
several subsections, like in the present
|
||||||
.Nm
|
.Nm
|
||||||
manual.
|
manual.
|
||||||
|
.It Em CONTEXT
|
||||||
|
This section lists the contexts in which functions can be called in section 9.
|
||||||
|
The contexts are autoconf, process, or interrupt.
|
||||||
.It Em IMPLEMENTATION NOTES
|
.It Em IMPLEMENTATION NOTES
|
||||||
Implementation-specific notes should be kept here.
|
Implementation-specific notes should be kept here.
|
||||||
This is useful when implementing standard functions that may have side
|
This is useful when implementing standard functions that may have side
|
||||||
@ -358,8 +363,12 @@ Example usages.
|
|||||||
This often contains snippets of well-formed, well-tested invocations.
|
This often contains snippets of well-formed, well-tested invocations.
|
||||||
Make sure that examples work properly!
|
Make sure that examples work properly!
|
||||||
.It Em DIAGNOSTICS
|
.It Em DIAGNOSTICS
|
||||||
Documents error conditions.
|
Documents error messages.
|
||||||
This is most useful in section 4 manuals.
|
In section 4 and 9 manuals, these are usually messages printed by the
|
||||||
|
kernel to the console and to the kernel log.
|
||||||
|
In section 1, 6, 7, and 8, these are usually messages printed by
|
||||||
|
userland programs to the standard error output.
|
||||||
|
.Pp
|
||||||
Historically, this section was used in place of
|
Historically, this section was used in place of
|
||||||
.Em EXIT STATUS
|
.Em EXIT STATUS
|
||||||
for manuals in sections 1, 6, and 8; however, this practise is
|
for manuals in sections 1, 6, and 8; however, this practise is
|
||||||
@ -369,7 +378,9 @@ See
|
|||||||
.Sx \&Bl
|
.Sx \&Bl
|
||||||
.Fl diag .
|
.Fl diag .
|
||||||
.It Em ERRORS
|
.It Em ERRORS
|
||||||
Documents error handling in sections 2, 3, and 9.
|
Documents
|
||||||
|
.Xr errno 2
|
||||||
|
settings in sections 2, 3, 4, and 9.
|
||||||
.Pp
|
.Pp
|
||||||
See
|
See
|
||||||
.Sx \&Er .
|
.Sx \&Er .
|
||||||
@ -457,7 +468,7 @@ in the alphabetical
|
|||||||
.It Sx \&Pf Ta prefix, no following horizontal space (one argument)
|
.It Sx \&Pf Ta prefix, no following horizontal space (one argument)
|
||||||
.It Sx \&Ns Ta roman font, no preceding horizontal space (no arguments)
|
.It Sx \&Ns Ta roman font, no preceding horizontal space (no arguments)
|
||||||
.It Sx \&Ap Ta apostrophe without surrounding whitespace (no arguments)
|
.It Sx \&Ap Ta apostrophe without surrounding whitespace (no arguments)
|
||||||
.It Sx \&Sm Ta switch horizontal spacing mode: Cm on | off
|
.It Sx \&Sm Ta switch horizontal spacing mode: Op Cm on | off
|
||||||
.It Sx \&Bk , \&Ek Ta keep block: Fl words
|
.It Sx \&Bk , \&Ek Ta keep block: Fl words
|
||||||
.It Sx \&br Ta force output line break in text mode (no arguments)
|
.It Sx \&br Ta force output line break in text mode (no arguments)
|
||||||
.It Sx \&sp Ta force vertical space: Op Ar height
|
.It Sx \&sp Ta force vertical space: Op Ar height
|
||||||
@ -502,7 +513,6 @@ in the alphabetical
|
|||||||
.It Sx \&Cd Ta kernel configuration declaration (>0 arguments)
|
.It Sx \&Cd Ta kernel configuration declaration (>0 arguments)
|
||||||
.It Sx \&Ad Ta memory address (>0 arguments)
|
.It Sx \&Ad Ta memory address (>0 arguments)
|
||||||
.It Sx \&Ms Ta mathematical symbol (>0 arguments)
|
.It Sx \&Ms Ta mathematical symbol (>0 arguments)
|
||||||
.It Sx \&Tn Ta tradename (>0 arguments)
|
|
||||||
.El
|
.El
|
||||||
.Ss Physical markup
|
.Ss Physical markup
|
||||||
.Bl -column "Brq, Bro, Brc" description
|
.Bl -column "Brq, Bro, Brc" description
|
||||||
@ -530,7 +540,6 @@ in the alphabetical
|
|||||||
.It Sx \&Ex Fl std Ta standard command exit values: Op Ar utility ...
|
.It Sx \&Ex Fl std Ta standard command exit values: Op Ar utility ...
|
||||||
.It Sx \&Rv Fl std Ta standard function return values: Op Ar function ...
|
.It Sx \&Rv Fl std Ta standard function return values: Op Ar function ...
|
||||||
.It Sx \&St Ta reference to a standards document (one argument)
|
.It Sx \&St Ta reference to a standards document (one argument)
|
||||||
.It Sx \&Ux Ta Ux
|
|
||||||
.It Sx \&At Ta At
|
.It Sx \&At Ta At
|
||||||
.It Sx \&Bx Ta Bx
|
.It Sx \&Bx Ta Bx
|
||||||
.It Sx \&Bsx Ta Bsx
|
.It Sx \&Bsx Ta Bsx
|
||||||
@ -741,9 +750,8 @@ See also
|
|||||||
.Sx \&Dx ,
|
.Sx \&Dx ,
|
||||||
.Sx \&Fx ,
|
.Sx \&Fx ,
|
||||||
.Sx \&Nx ,
|
.Sx \&Nx ,
|
||||||
.Sx \&Ox ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Ox .
|
||||||
.Ss \&Bc
|
.Ss \&Bc
|
||||||
Close a
|
Close a
|
||||||
.Sx \&Bo
|
.Sx \&Bo
|
||||||
@ -1107,10 +1115,10 @@ See also
|
|||||||
.Sx \&Dx ,
|
.Sx \&Dx ,
|
||||||
.Sx \&Fx ,
|
.Sx \&Fx ,
|
||||||
.Sx \&Nx ,
|
.Sx \&Nx ,
|
||||||
.Sx \&Ox ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Ox .
|
||||||
.Ss \&Bt
|
.Ss \&Bt
|
||||||
|
Supported only for compatibility, do not use this in new manuals.
|
||||||
Prints
|
Prints
|
||||||
.Dq is currently in beta test.
|
.Dq is currently in beta test.
|
||||||
.Ss \&Bx
|
.Ss \&Bx
|
||||||
@ -1130,9 +1138,8 @@ See also
|
|||||||
.Sx \&Dx ,
|
.Sx \&Dx ,
|
||||||
.Sx \&Fx ,
|
.Sx \&Fx ,
|
||||||
.Sx \&Nx ,
|
.Sx \&Nx ,
|
||||||
.Sx \&Ox ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Ox .
|
||||||
.Ss \&Cd
|
.Ss \&Cd
|
||||||
Kernel configuration declaration.
|
Kernel configuration declaration.
|
||||||
This denotes strings accepted by
|
This denotes strings accepted by
|
||||||
@ -1188,7 +1195,7 @@ Close a
|
|||||||
block.
|
block.
|
||||||
Does not have any tail arguments.
|
Does not have any tail arguments.
|
||||||
.Ss \&Dd
|
.Ss \&Dd
|
||||||
Document date.
|
Document date for display in the page footer.
|
||||||
This is the mandatory first macro of any
|
This is the mandatory first macro of any
|
||||||
.Nm
|
.Nm
|
||||||
manual.
|
manual.
|
||||||
@ -1217,8 +1224,11 @@ the special string
|
|||||||
.Dq $\&Mdocdate$
|
.Dq $\&Mdocdate$
|
||||||
can be given as an argument.
|
can be given as an argument.
|
||||||
.It
|
.It
|
||||||
A few alternative date formats are accepted as well
|
The traditional, purely numeric
|
||||||
and converted to the standard form.
|
.Xr man 7
|
||||||
|
format
|
||||||
|
.Ar year Ns \(en Ns Ar month Ns \(en Ns Ar day
|
||||||
|
is accepted, too.
|
||||||
.It
|
.It
|
||||||
If a date string cannot be parsed, it is used verbatim.
|
If a date string cannot be parsed, it is used verbatim.
|
||||||
.It
|
.It
|
||||||
@ -1278,97 +1288,92 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Do .
|
.Sx \&Do .
|
||||||
.Ss \&Dt
|
.Ss \&Dt
|
||||||
Document title.
|
Document title for display in the page header.
|
||||||
This is the mandatory second macro of any
|
This is the mandatory second macro of any
|
||||||
.Nm
|
.Nm
|
||||||
file.
|
file.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Bd -ragged -offset indent
|
.Bd -ragged -offset indent
|
||||||
.Pf \. Sx \&Dt
|
.Pf \. Sx \&Dt
|
||||||
.Oo
|
.Ar TITLE
|
||||||
.Ar title
|
|
||||||
.Oo
|
|
||||||
.Ar section
|
.Ar section
|
||||||
.Op Ar volume
|
.Op Ar volume | arch
|
||||||
.Op Ar arch
|
|
||||||
.Oc
|
|
||||||
.Oc
|
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
Its arguments are as follows:
|
Its arguments are as follows:
|
||||||
.Bl -tag -width Ds -offset Ds
|
.Bl -tag -width section -offset 2n
|
||||||
.It Ar title
|
.It Ar TITLE
|
||||||
The document's title (name), defaulting to
|
The document's title (name), defaulting to
|
||||||
.Dq UNKNOWN
|
.Dq UNTITLED
|
||||||
if unspecified.
|
if unspecified.
|
||||||
It should be capitalised.
|
To achieve a uniform appearance of page header lines,
|
||||||
|
it should by convention be all caps.
|
||||||
.It Ar section
|
.It Ar section
|
||||||
The manual section.
|
The manual section.
|
||||||
This may be one of
|
This may be one of
|
||||||
.Ar 1
|
.Cm 1
|
||||||
.Pq utilities ,
|
.Pq utilities ,
|
||||||
.Ar 2
|
.Cm 2
|
||||||
.Pq system calls ,
|
.Pq system calls ,
|
||||||
.Ar 3
|
.Cm 3
|
||||||
.Pq libraries ,
|
.Pq libraries ,
|
||||||
.Ar 3p
|
.Cm 3p
|
||||||
.Pq Perl libraries ,
|
.Pq Perl libraries ,
|
||||||
.Ar 4
|
.Cm 4
|
||||||
.Pq devices ,
|
.Pq devices ,
|
||||||
.Ar 5
|
.Cm 5
|
||||||
.Pq file formats ,
|
.Pq file formats ,
|
||||||
.Ar 6
|
.Cm 6
|
||||||
.Pq games ,
|
.Pq games ,
|
||||||
.Ar 7
|
.Cm 7
|
||||||
.Pq miscellaneous ,
|
.Pq miscellaneous ,
|
||||||
.Ar 8
|
.Cm 8
|
||||||
.Pq system utilities ,
|
.Pq system utilities ,
|
||||||
.Ar 9
|
.Cm 9
|
||||||
.Pq kernel functions ,
|
.Pq kernel functions ,
|
||||||
.Ar X11
|
.Cm X11
|
||||||
.Pq X Window System ,
|
.Pq X Window System ,
|
||||||
.Ar X11R6
|
.Cm X11R6
|
||||||
.Pq X Window System ,
|
.Pq X Window System ,
|
||||||
.Ar unass
|
.Cm unass
|
||||||
.Pq unassociated ,
|
.Pq unassociated ,
|
||||||
.Ar local
|
.Cm local
|
||||||
.Pq local system ,
|
.Pq local system ,
|
||||||
.Ar draft
|
.Cm draft
|
||||||
.Pq draft manual ,
|
.Pq draft manual ,
|
||||||
or
|
or
|
||||||
.Ar paper
|
.Cm paper
|
||||||
.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
|
||||||
.Dq 1
|
the empty string if unspecified.
|
||||||
if unspecified.
|
|
||||||
.It Ar volume
|
.It Ar volume
|
||||||
This overrides the volume inferred from
|
This overrides the volume inferred from
|
||||||
.Ar section .
|
.Ar section .
|
||||||
This field is optional, and if specified, must be one of
|
This field is optional, and if specified, must be one of
|
||||||
.Ar USD
|
.Cm USD
|
||||||
.Pq users' supplementary documents ,
|
.Pq users' supplementary documents ,
|
||||||
.Ar PS1
|
.Cm PS1
|
||||||
.Pq programmers' supplementary documents ,
|
.Pq programmers' supplementary documents ,
|
||||||
.Ar AMD
|
.Cm AMD
|
||||||
.Pq administrators' supplementary documents ,
|
.Pq administrators' supplementary documents ,
|
||||||
.Ar SMM
|
.Cm SMM
|
||||||
.Pq system managers' manuals ,
|
.Pq system managers' manuals ,
|
||||||
.Ar URM
|
.Cm URM
|
||||||
.Pq users' reference manuals ,
|
.Pq users' reference manuals ,
|
||||||
.Ar PRM
|
.Cm PRM
|
||||||
.Pq programmers' reference manuals ,
|
.Pq programmers' reference manuals ,
|
||||||
.Ar KM
|
.Cm KM
|
||||||
.Pq kernel manuals ,
|
.Pq kernel manuals ,
|
||||||
.Ar IND
|
.Cm IND
|
||||||
.Pq master index ,
|
.Pq master index ,
|
||||||
.Ar MMI
|
.Cm MMI
|
||||||
.Pq master index ,
|
.Pq master index ,
|
||||||
.Ar LOCAL
|
.Cm LOCAL
|
||||||
.Pq local manuals ,
|
.Pq local manuals ,
|
||||||
.Ar LOC
|
.Cm LOC
|
||||||
.Pq local manuals ,
|
.Pq local manuals ,
|
||||||
or
|
or
|
||||||
.Ar CON
|
.Cm CON
|
||||||
.Pq contributed manuals .
|
.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,
|
||||||
@ -1430,9 +1435,8 @@ See also
|
|||||||
.Sx \&Bx ,
|
.Sx \&Bx ,
|
||||||
.Sx \&Fx ,
|
.Sx \&Fx ,
|
||||||
.Sx \&Nx ,
|
.Sx \&Nx ,
|
||||||
.Sx \&Ox ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Ox .
|
||||||
.Ss \&Ec
|
.Ss \&Ec
|
||||||
Close a scope started by
|
Close a scope started by
|
||||||
.Sx \&Eo .
|
.Sx \&Eo .
|
||||||
@ -1481,8 +1485,14 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Sy .
|
.Sx \&Sy .
|
||||||
.Ss \&En
|
.Ss \&En
|
||||||
This macro is obsolete and not implemented in
|
This macro is obsolete.
|
||||||
.Xr mandoc 1 .
|
Use
|
||||||
|
.Sx \&Eo
|
||||||
|
or any of the other enclosure macros.
|
||||||
|
.Pp
|
||||||
|
It encloses its argument in the delimiters specified by the last
|
||||||
|
.Sx \&Es
|
||||||
|
macro.
|
||||||
.Ss \&Eo
|
.Ss \&Eo
|
||||||
An arbitrary enclosure.
|
An arbitrary enclosure.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
@ -1508,7 +1518,14 @@ See also
|
|||||||
.Sx \&Dv
|
.Sx \&Dv
|
||||||
for general constants.
|
for general constants.
|
||||||
.Ss \&Es
|
.Ss \&Es
|
||||||
This macro is obsolete and not implemented.
|
This macro is obsolete.
|
||||||
|
Use
|
||||||
|
.Sx \&Eo
|
||||||
|
or any of the other enclosure macros.
|
||||||
|
.Pp
|
||||||
|
It takes two arguments, defining the delimiters to be used by subsequent
|
||||||
|
.Sx \&En
|
||||||
|
macros.
|
||||||
.Ss \&Ev
|
.Ss \&Ev
|
||||||
Environmental variables such as those specified in
|
Environmental variables such as those specified in
|
||||||
.Xr environ 7 .
|
.Xr environ 7 .
|
||||||
@ -1544,19 +1561,31 @@ Function argument.
|
|||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Bd -ragged -offset indent
|
.Bd -ragged -offset indent
|
||||||
.Pf \. Sx \&Fa
|
.Pf \. Sx \&Fa
|
||||||
.Op Cm argtype
|
.Qo
|
||||||
.Cm argname
|
.Op Ar argtype
|
||||||
|
.Op Ar argname
|
||||||
|
.Qc Ar \&...
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
This may be invoked for names with or without the corresponding type.
|
Each argument may be a name and a type (recommended for the
|
||||||
It is also used to specify the field name of a structure.
|
.Em SYNOPSIS
|
||||||
|
section), a name alone (for function invocations),
|
||||||
|
or a type alone (for function prototypes).
|
||||||
|
If both a type and a name are given or if the type consists of multiple
|
||||||
|
words, all words belonging to the same function argument have to be
|
||||||
|
given in a single argument to the
|
||||||
|
.Sx \&Fa
|
||||||
|
macro.
|
||||||
|
.Pp
|
||||||
|
This macro is also used to specify the field name of a structure.
|
||||||
|
.Pp
|
||||||
Most often, the
|
Most often, the
|
||||||
.Sx \&Fa
|
.Sx \&Fa
|
||||||
macro is used in the
|
macro is used in the
|
||||||
.Em SYNOPSIS
|
.Em SYNOPSIS
|
||||||
within
|
within
|
||||||
.Sx \&Fo
|
.Sx \&Fo
|
||||||
section when documenting multi-line function prototypes.
|
blocks when documenting multi-line function prototypes.
|
||||||
If invoked with multiple arguments, the arguments are separated by a
|
If invoked with multiple arguments, the arguments are separated by a
|
||||||
comma.
|
comma.
|
||||||
Furthermore, if the following macro is another
|
Furthermore, if the following macro is another
|
||||||
@ -1566,7 +1595,7 @@ the last argument will also have a trailing comma.
|
|||||||
Examples:
|
Examples:
|
||||||
.Dl \&.Fa \(dqconst char *p\(dq
|
.Dl \&.Fa \(dqconst char *p\(dq
|
||||||
.Dl \&.Fa \(dqint a\(dq \(dqint b\(dq \(dqint c\(dq
|
.Dl \&.Fa \(dqint a\(dq \(dqint b\(dq \(dqint c\(dq
|
||||||
.Dl \&.Fa foo
|
.Dl \&.Fa \(dqchar *\(dq size_t
|
||||||
.Pp
|
.Pp
|
||||||
See also
|
See also
|
||||||
.Sx \&Fo .
|
.Sx \&Fo .
|
||||||
@ -1669,7 +1698,7 @@ Invocations usually occur in the following context:
|
|||||||
.br
|
.br
|
||||||
.Pf \. Sx \&Fo Ar funcname
|
.Pf \. Sx \&Fo Ar funcname
|
||||||
.br
|
.br
|
||||||
.Pf \. Sx \&Fa Oo Ar argtype Oc Ar argname
|
.Pf \. Sx \&Fa Qq Ar argtype Ar argname
|
||||||
.br
|
.br
|
||||||
\&.\.\.
|
\&.\.\.
|
||||||
.br
|
.br
|
||||||
@ -1688,13 +1717,10 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Ft .
|
.Sx \&Ft .
|
||||||
.Ss \&Fr
|
.Ss \&Fr
|
||||||
This macro is obsolete and not implemented in
|
This macro is obsolete.
|
||||||
.Xr mandoc 1 .
|
No replacement markup is needed.
|
||||||
.Pp
|
.Pp
|
||||||
It was used to show function return values.
|
It was used to show numerical function return values in an italic font.
|
||||||
The syntax was:
|
|
||||||
.Pp
|
|
||||||
.Dl Pf . Sx \&Fr Ar value
|
|
||||||
.Ss \&Ft
|
.Ss \&Ft
|
||||||
A function type.
|
A function type.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
@ -1733,9 +1759,8 @@ See also
|
|||||||
.Sx \&Bx ,
|
.Sx \&Bx ,
|
||||||
.Sx \&Dx ,
|
.Sx \&Dx ,
|
||||||
.Sx \&Nx ,
|
.Sx \&Nx ,
|
||||||
.Sx \&Ox ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Ox .
|
||||||
.Ss \&Hf
|
.Ss \&Hf
|
||||||
This macro is not implemented in
|
This macro is not implemented in
|
||||||
.Xr mandoc 1 .
|
.Xr mandoc 1 .
|
||||||
@ -2053,9 +2078,8 @@ See also
|
|||||||
.Sx \&Bx ,
|
.Sx \&Bx ,
|
||||||
.Sx \&Dx ,
|
.Sx \&Dx ,
|
||||||
.Sx \&Fx ,
|
.Sx \&Fx ,
|
||||||
.Sx \&Ox ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Ox .
|
||||||
.Ss \&Oc
|
.Ss \&Oc
|
||||||
Close multi-line
|
Close multi-line
|
||||||
.Sx \&Oo
|
.Sx \&Oo
|
||||||
@ -2084,7 +2108,7 @@ Examples:
|
|||||||
See also
|
See also
|
||||||
.Sx \&Oo .
|
.Sx \&Oo .
|
||||||
.Ss \&Os
|
.Ss \&Os
|
||||||
Document operating system version.
|
Operating system version for display in the page footer.
|
||||||
This is the mandatory third macro of
|
This is the mandatory third macro of
|
||||||
any
|
any
|
||||||
.Nm
|
.Nm
|
||||||
@ -2109,8 +2133,12 @@ See also
|
|||||||
and
|
and
|
||||||
.Sx \&Dt .
|
.Sx \&Dt .
|
||||||
.Ss \&Ot
|
.Ss \&Ot
|
||||||
This macro is obsolete and not implemented in
|
This macro is obsolete.
|
||||||
.Xr mandoc 1 .
|
Use
|
||||||
|
.Sx \&Ft
|
||||||
|
instead; with
|
||||||
|
.Xr mandoc 1 ,
|
||||||
|
both have the same effect.
|
||||||
.Pp
|
.Pp
|
||||||
Historical
|
Historical
|
||||||
.Nm
|
.Nm
|
||||||
@ -2132,9 +2160,8 @@ See also
|
|||||||
.Sx \&Bx ,
|
.Sx \&Bx ,
|
||||||
.Sx \&Dx ,
|
.Sx \&Dx ,
|
||||||
.Sx \&Fx ,
|
.Sx \&Fx ,
|
||||||
.Sx \&Nx ,
|
|
||||||
and
|
and
|
||||||
.Sx \&Ux .
|
.Sx \&Nx .
|
||||||
.Ss \&Pa
|
.Ss \&Pa
|
||||||
An absolute or relative file system path, or a file or directory name.
|
An absolute or relative file system path, or a file or directory name.
|
||||||
If an argument is not provided, the character
|
If an argument is not provided, the character
|
||||||
@ -2308,7 +2335,7 @@ and
|
|||||||
Switches the spacing mode for output generated from macros.
|
Switches the spacing mode for output generated from macros.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 Pf \. Sx \&Sm Cm on | off
|
.D1 Pf \. Sx \&Sm Op Cm on | off
|
||||||
.Pp
|
.Pp
|
||||||
By default, spacing is
|
By default, spacing is
|
||||||
.Cm on .
|
.Cm on .
|
||||||
@ -2317,6 +2344,11 @@ When switched
|
|||||||
no white space is inserted between macro arguments and between the
|
no white space is inserted between macro arguments and between the
|
||||||
output generated from adjacent macros, but text lines
|
output generated from adjacent macros, but text lines
|
||||||
still get normal spacing between words and sentences.
|
still get normal spacing between words and sentences.
|
||||||
|
.Pp
|
||||||
|
When called without an argument, the
|
||||||
|
.Sx \&Sm
|
||||||
|
macro toggles the spacing mode.
|
||||||
|
Using this is not recommended because it makes the code harder to read.
|
||||||
.Ss \&So
|
.Ss \&So
|
||||||
Multi-line version of
|
Multi-line version of
|
||||||
.Sx \&Sq .
|
.Sx \&Sq .
|
||||||
@ -2354,113 +2386,243 @@ and
|
|||||||
.Sx \&Sx .
|
.Sx \&Sx .
|
||||||
.Ss \&St
|
.Ss \&St
|
||||||
Replace an abbreviation for a standard with the full form.
|
Replace an abbreviation for a standard with the full form.
|
||||||
The following standards are recognised:
|
The following standards are recognised.
|
||||||
|
Where multiple lines are given without a blank line in between,
|
||||||
|
they all refer to the same standard, and using the first form
|
||||||
|
is recommended.
|
||||||
|
.Bl -tag -width 1n
|
||||||
|
.It C language standards
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width "-p1003.1g-2000X" -compact
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
.It \-p1003.1-88
|
|
||||||
.St -p1003.1-88
|
|
||||||
.It \-p1003.1-90
|
|
||||||
.St -p1003.1-90
|
|
||||||
.It \-p1003.1-96
|
|
||||||
.St -p1003.1-96
|
|
||||||
.It \-p1003.1-2001
|
|
||||||
.St -p1003.1-2001
|
|
||||||
.It \-p1003.1-2004
|
|
||||||
.St -p1003.1-2004
|
|
||||||
.It \-p1003.1-2008
|
|
||||||
.St -p1003.1-2008
|
|
||||||
.It \-p1003.1
|
|
||||||
.St -p1003.1
|
|
||||||
.It \-p1003.1b
|
|
||||||
.St -p1003.1b
|
|
||||||
.It \-p1003.1b-93
|
|
||||||
.St -p1003.1b-93
|
|
||||||
.It \-p1003.1c-95
|
|
||||||
.St -p1003.1c-95
|
|
||||||
.It \-p1003.1d-99
|
|
||||||
.St -p1003.1d-99
|
|
||||||
.It \-p1003.1g-2000
|
|
||||||
.St -p1003.1g-2000
|
|
||||||
.It \-p1003.1i-95
|
|
||||||
.St -p1003.1i-95
|
|
||||||
.It \-p1003.1j-2000
|
|
||||||
.St -p1003.1j-2000
|
|
||||||
.It \-p1003.1q-2000
|
|
||||||
.St -p1003.1q-2000
|
|
||||||
.It \-p1003.2
|
|
||||||
.St -p1003.2
|
|
||||||
.It \-p1003.2-92
|
|
||||||
.St -p1003.2-92
|
|
||||||
.It \-p1003.2a-92
|
|
||||||
.St -p1003.2a-92
|
|
||||||
.It \-p1387.2
|
|
||||||
.St -p1387.2
|
|
||||||
.It \-p1387.2-95
|
|
||||||
.St -p1387.2-95
|
|
||||||
.It \-isoC
|
|
||||||
.St -isoC
|
|
||||||
.It \-isoC-90
|
|
||||||
.St -isoC-90
|
|
||||||
.It \-isoC-amd1
|
|
||||||
.St -isoC-amd1
|
|
||||||
.It \-isoC-tcor1
|
|
||||||
.St -isoC-tcor1
|
|
||||||
.It \-isoC-tcor2
|
|
||||||
.St -isoC-tcor2
|
|
||||||
.It \-isoC-99
|
|
||||||
.St -isoC-99
|
|
||||||
.It \-isoC-2011
|
|
||||||
.St -isoC-2011
|
|
||||||
.It \-iso9945-1-90
|
|
||||||
.St -iso9945-1-90
|
|
||||||
.It \-iso9945-1-96
|
|
||||||
.St -iso9945-1-96
|
|
||||||
.It \-iso9945-2-93
|
|
||||||
.St -iso9945-2-93
|
|
||||||
.It \-ansiC
|
.It \-ansiC
|
||||||
.St -ansiC
|
.St -ansiC
|
||||||
.It \-ansiC-89
|
.It \-ansiC-89
|
||||||
.St -ansiC-89
|
.St -ansiC-89
|
||||||
|
.It \-isoC
|
||||||
|
.St -isoC
|
||||||
|
.It \-isoC-90
|
||||||
|
.St -isoC-90
|
||||||
|
.br
|
||||||
|
The original C standard.
|
||||||
|
.Pp
|
||||||
|
.It \-isoC-amd1
|
||||||
|
.St -isoC-amd1
|
||||||
|
.Pp
|
||||||
|
.It \-isoC-tcor1
|
||||||
|
.St -isoC-tcor1
|
||||||
|
.Pp
|
||||||
|
.It \-isoC-tcor2
|
||||||
|
.St -isoC-tcor2
|
||||||
|
.Pp
|
||||||
|
.It \-isoC-99
|
||||||
|
.St -isoC-99
|
||||||
.It \-ansiC-99
|
.It \-ansiC-99
|
||||||
.St -ansiC-99
|
.St -ansiC-99
|
||||||
.It \-ieee754
|
.br
|
||||||
.St -ieee754
|
The second major version of the C language standard.
|
||||||
.It \-iso8802-3
|
.Pp
|
||||||
.St -iso8802-3
|
.It \-isoC-2011
|
||||||
.It \-iso8601
|
.St -isoC-2011
|
||||||
.St -iso8601
|
.br
|
||||||
.It \-ieee1275-94
|
The third major version of the C language standard.
|
||||||
.St -ieee1275-94
|
.El
|
||||||
|
.It POSIX.1 before the Single UNIX Specification
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
|
.It \-p1003.1-88
|
||||||
|
.St -p1003.1-88
|
||||||
|
.It \-p1003.1
|
||||||
|
.St -p1003.1
|
||||||
|
.br
|
||||||
|
The original POSIX standard, based on ANSI C.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1-90
|
||||||
|
.St -p1003.1-90
|
||||||
|
.It \-iso9945-1-90
|
||||||
|
.St -iso9945-1-90
|
||||||
|
.br
|
||||||
|
The first update of POSIX.1.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1b-93
|
||||||
|
.St -p1003.1b-93
|
||||||
|
.It \-p1003.1b
|
||||||
|
.St -p1003.1b
|
||||||
|
.br
|
||||||
|
Real-time extensions.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1c-95
|
||||||
|
.St -p1003.1c-95
|
||||||
|
.br
|
||||||
|
POSIX thread interfaces.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1i-95
|
||||||
|
.St -p1003.1i-95
|
||||||
|
.br
|
||||||
|
Technical Corrigendum.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1-96
|
||||||
|
.St -p1003.1-96
|
||||||
|
.It \-iso9945-1-96
|
||||||
|
.St -iso9945-1-96
|
||||||
|
.br
|
||||||
|
Includes POSIX.1-1990, 1b, 1c, and 1i.
|
||||||
|
.El
|
||||||
|
.It X/Open Portability Guide version 4 and related standards
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
.It \-xpg3
|
.It \-xpg3
|
||||||
.St -xpg3
|
.St -xpg3
|
||||||
|
.br
|
||||||
|
An XPG4 precursor, published in 1989.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.2
|
||||||
|
.St -p1003.2
|
||||||
|
.It \-p1003.2-92
|
||||||
|
.St -p1003.2-92
|
||||||
|
.It \-iso9945-2-93
|
||||||
|
.St -iso9945-2-93
|
||||||
|
.br
|
||||||
|
An XCU4 precursor.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.2a-92
|
||||||
|
.St -p1003.2a-92
|
||||||
|
.br
|
||||||
|
Updates to POSIX.2.
|
||||||
|
.Pp
|
||||||
.It \-xpg4
|
.It \-xpg4
|
||||||
.St -xpg4
|
.St -xpg4
|
||||||
|
.br
|
||||||
|
Based on POSIX.1 and POSIX.2, published in 1992.
|
||||||
|
.El
|
||||||
|
.It Single UNIX Specification version 1 and related standards
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
.It \-xpg4.2
|
.It \-xpg4.2
|
||||||
.St -xpg4.2
|
.St -xpg4.2
|
||||||
.It \-xpg4.3
|
.br
|
||||||
.St -xpg4.3
|
This standard was published in 1994 and is also called SUSv1.
|
||||||
.It \-xbd5
|
It was used as the basis for UNIX 95 certification.
|
||||||
.St -xbd5
|
The following three refer to parts of it.
|
||||||
.It \-xcu5
|
.Pp
|
||||||
.St -xcu5
|
|
||||||
.It \-xsh4.2
|
.It \-xsh4.2
|
||||||
.St -xsh4.2
|
.St -xsh4.2
|
||||||
.It \-xsh5
|
.Pp
|
||||||
.St -xsh5
|
|
||||||
.It \-xns5
|
|
||||||
.St -xns5
|
|
||||||
.It \-xns5.2
|
|
||||||
.St -xns5.2
|
|
||||||
.It \-xns5.2d2.0
|
|
||||||
.St -xns5.2d2.0
|
|
||||||
.It \-xcurses4.2
|
.It \-xcurses4.2
|
||||||
.St -xcurses4.2
|
.St -xcurses4.2
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1g-2000
|
||||||
|
.St -p1003.1g-2000
|
||||||
|
.br
|
||||||
|
Networking APIs, including sockets.
|
||||||
|
.Pp
|
||||||
|
.It \-xpg4.3
|
||||||
|
.St -xpg4.3
|
||||||
|
.Pp
|
||||||
|
.It \-svid4
|
||||||
|
.St -svid4 ,
|
||||||
|
.br
|
||||||
|
Published in 1995.
|
||||||
|
.El
|
||||||
|
.It Single UNIX Specification version 2 and related standards
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
.It \-susv2
|
.It \-susv2
|
||||||
.St -susv2
|
.St -susv2
|
||||||
|
This Standard was published in 1997
|
||||||
|
and is also called X/Open Portability Guide version 5.
|
||||||
|
It was used as the basis for UNIX 98 certification.
|
||||||
|
The following refer to parts of it.
|
||||||
|
.Pp
|
||||||
|
.It \-xbd5
|
||||||
|
.St -xbd5
|
||||||
|
.Pp
|
||||||
|
.It \-xsh5
|
||||||
|
.St -xsh5
|
||||||
|
.Pp
|
||||||
|
.It \-xcu5
|
||||||
|
.St -xcu5
|
||||||
|
.Pp
|
||||||
|
.It \-xns5
|
||||||
|
.St -xns5
|
||||||
|
.It \-xns5.2d2.0
|
||||||
|
.St -xns5.2d2.0
|
||||||
|
.It \-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
|
||||||
|
.It Single UNIX Specification version 3 and related standards
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000X" -compact
|
||||||
|
.It \-p1003.1d-99
|
||||||
|
.St -p1003.1d-99
|
||||||
|
.br
|
||||||
|
Additional real-time extensions.
|
||||||
|
.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
|
||||||
|
.St -p1003.1-2001
|
||||||
.It \-susv3
|
.It \-susv3
|
||||||
.St -susv3
|
.St -susv3
|
||||||
.It \-svid4
|
.br
|
||||||
.St -svid4
|
This standard is based on C99, SUSv2, POSIX.1-1996, 1d, and 1j.
|
||||||
|
It is also called X/Open Portability Guide version 6.
|
||||||
|
It is used as the basis for UNIX 03 certification.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1-2004
|
||||||
|
.St -p1003.1-2004
|
||||||
|
.br
|
||||||
|
The second and last Technical Corrigendum.
|
||||||
|
.El
|
||||||
|
.It Single UNIX Specification version 4
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
|
.It \-p1003.1-2008
|
||||||
|
.St -p1003.1-2008
|
||||||
|
.br
|
||||||
|
This standard is also called SUSv4 and
|
||||||
|
X/Open Portability Guide version 7.
|
||||||
|
.Pp
|
||||||
|
.It \-p1003.1-2013
|
||||||
|
.St -p1003.1-2013
|
||||||
|
.br
|
||||||
|
This is the first Technical Corrigendum.
|
||||||
|
.El
|
||||||
|
.It Other standards
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||||
|
.It \-ieee754
|
||||||
|
.St -ieee754
|
||||||
|
.br
|
||||||
|
Floating-point arithmetic.
|
||||||
|
.Pp
|
||||||
|
.It \-iso8601
|
||||||
|
.St -iso8601
|
||||||
|
.br
|
||||||
|
Representation of dates and times, published in 1988.
|
||||||
|
.Pp
|
||||||
|
.It \-iso8802-3
|
||||||
|
.St -iso8802-3
|
||||||
|
.br
|
||||||
|
Ethernet local area networks.
|
||||||
|
.Pp
|
||||||
|
.It \-ieee1275-94
|
||||||
|
.St -ieee1275-94
|
||||||
|
.El
|
||||||
.El
|
.El
|
||||||
.Ss \&Sx
|
.Ss \&Sx
|
||||||
Reference a section or subsection in the same manual page.
|
Reference a section or subsection in the same manual page.
|
||||||
@ -2492,36 +2654,19 @@ Table cell separator in
|
|||||||
lists; can only be used below
|
lists; can only be used below
|
||||||
.Sx \&It .
|
.Sx \&It .
|
||||||
.Ss \&Tn
|
.Ss \&Tn
|
||||||
Format a tradename.
|
Supported only for compatibility, do not use this in new manuals.
|
||||||
.Pp
|
Even though the macro name
|
||||||
Since this macro is often implemented to use a small caps font,
|
.Pq Dq tradename
|
||||||
it has historically been used for acronyms (like ASCII) as well.
|
suggests a semantic function, historic usage is inconsistent, mostly
|
||||||
Such usage is not recommended because it would use the same macro
|
using it as a presentation-level macro to request a small caps font.
|
||||||
sometimes for semantical annotation, sometimes for physical formatting.
|
|
||||||
.Pp
|
|
||||||
Examples:
|
|
||||||
.Dl \&.Tn IBM
|
|
||||||
.Ss \&Ud
|
.Ss \&Ud
|
||||||
|
Supported only for compatibility, do not use this in new manuals.
|
||||||
Prints out
|
Prints out
|
||||||
.Dq currently under development.
|
.Dq currently under development.
|
||||||
.Ss \&Ux
|
.Ss \&Ux
|
||||||
Format the
|
Supported only for compatibility, do not use this in new manuals.
|
||||||
.Ux
|
Prints out
|
||||||
name.
|
.Dq Ux .
|
||||||
Accepts no argument.
|
|
||||||
.Pp
|
|
||||||
Examples:
|
|
||||||
.Dl \&.Ux
|
|
||||||
.Pp
|
|
||||||
See also
|
|
||||||
.Sx \&At ,
|
|
||||||
.Sx \&Bsx ,
|
|
||||||
.Sx \&Bx ,
|
|
||||||
.Sx \&Dx ,
|
|
||||||
.Sx \&Fx ,
|
|
||||||
.Sx \&Nx ,
|
|
||||||
and
|
|
||||||
.Sx \&Ox .
|
|
||||||
.Ss \&Va
|
.Ss \&Va
|
||||||
A variable name.
|
A variable name.
|
||||||
.Pp
|
.Pp
|
||||||
@ -2773,6 +2918,7 @@ end of the line.
|
|||||||
.It Sx \&D1 Ta \&No Ta \&Yes
|
.It Sx \&D1 Ta \&No Ta \&Yes
|
||||||
.It Sx \&Dl Ta \&No Ta Yes
|
.It Sx \&Dl Ta \&No Ta Yes
|
||||||
.It Sx \&Dq Ta Yes Ta Yes
|
.It Sx \&Dq Ta Yes Ta Yes
|
||||||
|
.It Sx \&En Ta Yes Ta Yes
|
||||||
.It Sx \&Op Ta Yes Ta Yes
|
.It Sx \&Op Ta Yes Ta Yes
|
||||||
.It Sx \&Pq Ta Yes Ta Yes
|
.It Sx \&Pq Ta Yes Ta Yes
|
||||||
.It Sx \&Ql Ta Yes Ta Yes
|
.It Sx \&Ql Ta Yes Ta Yes
|
||||||
@ -2850,16 +2996,15 @@ then the macro accepts an arbitrary number of arguments.
|
|||||||
.It Sx \&Dv Ta Yes Ta Yes Ta >0
|
.It Sx \&Dv Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Dx Ta Yes Ta Yes Ta n
|
.It Sx \&Dx Ta Yes Ta Yes Ta n
|
||||||
.It Sx \&Em Ta Yes Ta Yes Ta >0
|
.It Sx \&Em Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&En Ta \&No Ta \&No Ta 0
|
|
||||||
.It Sx \&Er Ta Yes Ta Yes Ta >0
|
.It Sx \&Er Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Es Ta \&No Ta \&No Ta 0
|
.It Sx \&Es Ta Yes Ta Yes Ta 2
|
||||||
.It Sx \&Ev Ta Yes Ta Yes Ta >0
|
.It Sx \&Ev Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Ex Ta \&No Ta \&No Ta n
|
.It Sx \&Ex Ta \&No Ta \&No Ta n
|
||||||
.It Sx \&Fa Ta Yes Ta Yes Ta >0
|
.It Sx \&Fa Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Fd Ta \&No Ta \&No Ta >0
|
.It Sx \&Fd Ta \&No Ta \&No Ta >0
|
||||||
.It Sx \&Fl Ta Yes Ta Yes Ta n
|
.It Sx \&Fl Ta Yes Ta Yes Ta n
|
||||||
.It Sx \&Fn Ta Yes Ta Yes Ta >0
|
.It Sx \&Fn Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Fr Ta \&No Ta \&No Ta n
|
.It Sx \&Fr Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Ft Ta Yes Ta Yes Ta >0
|
.It Sx \&Ft Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Fx Ta Yes Ta Yes Ta n
|
.It Sx \&Fx Ta Yes Ta Yes Ta n
|
||||||
.It Sx \&Hf Ta \&No Ta \&No Ta n
|
.It Sx \&Hf Ta \&No Ta \&No Ta n
|
||||||
@ -2876,13 +3021,13 @@ then the macro accepts an arbitrary number of arguments.
|
|||||||
.It Sx \&Ns Ta Yes Ta Yes Ta 0
|
.It Sx \&Ns Ta Yes Ta Yes Ta 0
|
||||||
.It Sx \&Nx Ta Yes Ta Yes Ta n
|
.It Sx \&Nx Ta Yes Ta Yes Ta n
|
||||||
.It Sx \&Os Ta \&No Ta \&No Ta n
|
.It Sx \&Os Ta \&No Ta \&No Ta n
|
||||||
.It Sx \&Ot Ta \&No Ta \&No Ta n
|
.It Sx \&Ot Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Ox Ta Yes Ta Yes Ta n
|
.It Sx \&Ox Ta Yes Ta Yes Ta n
|
||||||
.It Sx \&Pa Ta Yes Ta Yes Ta n
|
.It Sx \&Pa Ta Yes Ta Yes Ta n
|
||||||
.It Sx \&Pf Ta Yes Ta Yes Ta 1
|
.It Sx \&Pf Ta Yes Ta Yes Ta 1
|
||||||
.It Sx \&Pp Ta \&No Ta \&No Ta 0
|
.It Sx \&Pp Ta \&No Ta \&No Ta 0
|
||||||
.It Sx \&Rv Ta \&No Ta \&No Ta n
|
.It Sx \&Rv Ta \&No Ta \&No Ta n
|
||||||
.It Sx \&Sm Ta \&No Ta \&No Ta 1
|
.It Sx \&Sm Ta \&No Ta \&No Ta <2
|
||||||
.It Sx \&St Ta \&No Ta Yes Ta 1
|
.It Sx \&St Ta \&No Ta Yes Ta 1
|
||||||
.It Sx \&Sx Ta Yes Ta Yes Ta >0
|
.It Sx \&Sx Ta Yes Ta Yes Ta >0
|
||||||
.It Sx \&Sy Ta Yes Ta Yes Ta >0
|
.It Sx \&Sy Ta Yes Ta Yes Ta >0
|
||||||
@ -2998,8 +3143,9 @@ Manually switching the font using the
|
|||||||
.Ql \ef
|
.Ql \ef
|
||||||
font escape sequences is never required.
|
font escape sequences is never required.
|
||||||
.Sh COMPATIBILITY
|
.Sh COMPATIBILITY
|
||||||
This section documents compatibility between mandoc and other
|
This section provides an incomplete list of compatibility issues
|
||||||
troff implementations, at this time limited to GNU troff
|
between mandoc and other troff implementations, at this time limited
|
||||||
|
to GNU troff
|
||||||
.Pq Qq groff .
|
.Pq Qq groff .
|
||||||
The term
|
The term
|
||||||
.Qq historic groff
|
.Qq historic groff
|
||||||
@ -3108,7 +3254,7 @@ certain list types.
|
|||||||
can only be called by other macros, but not at the beginning of a line.
|
can only be called by other macros, but not at the beginning of a line.
|
||||||
.It
|
.It
|
||||||
.Sx \&%C
|
.Sx \&%C
|
||||||
is not implemented.
|
is not implemented (up to and including groff-1.22.2).
|
||||||
.It
|
.It
|
||||||
Historic groff only allows up to eight or nine arguments per macro input
|
Historic groff only allows up to eight or nine arguments per macro input
|
||||||
line, depending on the exact situation.
|
line, depending on the exact situation.
|
||||||
@ -3126,7 +3272,7 @@ in new groff and mandoc.
|
|||||||
.Sq \ef
|
.Sq \ef
|
||||||
.Pq font face
|
.Pq font face
|
||||||
and
|
and
|
||||||
.Sq \ef
|
.Sq \eF
|
||||||
.Pq font family face
|
.Pq font family face
|
||||||
.Sx Text Decoration
|
.Sx Text Decoration
|
||||||
escapes behave irregularly when specified within line-macro scopes.
|
escapes behave irregularly when specified within line-macro scopes.
|
||||||
@ -3143,41 +3289,11 @@ The following features are unimplemented in mandoc:
|
|||||||
.Fl file Ar file .
|
.Fl file Ar file .
|
||||||
.It
|
.It
|
||||||
.Sx \&Bd
|
.Sx \&Bd
|
||||||
.Fl offset Ar center
|
.Fl offset Cm center
|
||||||
and
|
and
|
||||||
.Fl offset Ar right .
|
.Fl offset Cm right .
|
||||||
Groff does not implement centred and flush-right rendering either,
|
Groff does not implement centred and flush-right rendering either,
|
||||||
but produces large indentations.
|
but produces large indentations.
|
||||||
.It
|
|
||||||
The
|
|
||||||
.Sq \eh
|
|
||||||
.Pq horizontal position ,
|
|
||||||
.Sq \ev
|
|
||||||
.Pq vertical position ,
|
|
||||||
.Sq \em
|
|
||||||
.Pq text colour ,
|
|
||||||
.Sq \eM
|
|
||||||
.Pq text filling colour ,
|
|
||||||
.Sq \ez
|
|
||||||
.Pq zero-length character ,
|
|
||||||
.Sq \ew
|
|
||||||
.Pq string length ,
|
|
||||||
.Sq \ek
|
|
||||||
.Pq horizontal position marker ,
|
|
||||||
.Sq \eo
|
|
||||||
.Pq text overstrike ,
|
|
||||||
and
|
|
||||||
.Sq \es
|
|
||||||
.Pq text size
|
|
||||||
escape sequences are all discarded in mandoc.
|
|
||||||
.It
|
|
||||||
The
|
|
||||||
.Sq \ef
|
|
||||||
scaling unit is accepted by mandoc, but rendered as the default unit.
|
|
||||||
.It
|
|
||||||
In quoted literals, groff allows pairwise double-quotes to produce a
|
|
||||||
standalone double-quote in formatted output.
|
|
||||||
This is not supported by mandoc.
|
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr man 1 ,
|
.Xr man 1 ,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: mdoc.c,v 1.206 2013/12/24 19:11:46 schwarze Exp $ */
|
/* $Id: mdoc.c,v 1.223 2014/08/06 15:09: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 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -30,10 +31,11 @@
|
|||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmdoc.h"
|
#include "libmdoc.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
|
|
||||||
const char *const __mdoc_macronames[MDOC_MAX] = {
|
const char *const __mdoc_macronames[MDOC_MAX + 1] = {
|
||||||
"Ap", "Dd", "Dt", "Os",
|
"Ap", "Dd", "Dt", "Os",
|
||||||
"Sh", "Ss", "Pp", "D1",
|
"Sh", "Ss", "Pp", "D1",
|
||||||
"Dl", "Bd", "Ed", "Bl",
|
"Dl", "Bd", "Ed", "Bl",
|
||||||
@ -44,11 +46,8 @@ const char *const __mdoc_macronames[MDOC_MAX] = {
|
|||||||
"Ic", "In", "Li", "Nd",
|
"Ic", "In", "Li", "Nd",
|
||||||
"Nm", "Op", "Ot", "Pa",
|
"Nm", "Op", "Ot", "Pa",
|
||||||
"Rv", "St", "Va", "Vt",
|
"Rv", "St", "Va", "Vt",
|
||||||
/* LINTED */
|
|
||||||
"Xr", "%A", "%B", "%D",
|
"Xr", "%A", "%B", "%D",
|
||||||
/* LINTED */
|
|
||||||
"%I", "%J", "%N", "%O",
|
"%I", "%J", "%N", "%O",
|
||||||
/* LINTED */
|
|
||||||
"%P", "%R", "%T", "%V",
|
"%P", "%R", "%T", "%V",
|
||||||
"Ac", "Ao", "Aq", "At",
|
"Ac", "Ao", "Aq", "At",
|
||||||
"Bc", "Bf", "Bo", "Bq",
|
"Bc", "Bf", "Bo", "Bq",
|
||||||
@ -65,12 +64,9 @@ const char *const __mdoc_macronames[MDOC_MAX] = {
|
|||||||
"Bk", "Ek", "Bt", "Hf",
|
"Bk", "Ek", "Bt", "Hf",
|
||||||
"Fr", "Ud", "Lb", "Lp",
|
"Fr", "Ud", "Lb", "Lp",
|
||||||
"Lk", "Mt", "Brq", "Bro",
|
"Lk", "Mt", "Brq", "Bro",
|
||||||
/* LINTED */
|
|
||||||
"Brc", "%C", "Es", "En",
|
"Brc", "%C", "Es", "En",
|
||||||
/* LINTED */
|
|
||||||
"Dx", "%Q", "br", "sp",
|
"Dx", "%Q", "br", "sp",
|
||||||
/* LINTED */
|
"%U", "Ta", "ll", "text",
|
||||||
"%U", "Ta"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
|
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
|
||||||
@ -103,24 +99,21 @@ static int mdoc_preptext(struct mdoc *, int, char *, int);
|
|||||||
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);
|
||||||
|
|
||||||
|
|
||||||
const struct mdoc_node *
|
const struct mdoc_node *
|
||||||
mdoc_node(const struct mdoc *mdoc)
|
mdoc_node(const struct mdoc *mdoc)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MDOC_HALT & mdoc->flags));
|
|
||||||
return(mdoc->first);
|
return(mdoc->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct mdoc_meta *
|
const struct mdoc_meta *
|
||||||
mdoc_meta(const struct mdoc *mdoc)
|
mdoc_meta(const struct mdoc *mdoc)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MDOC_HALT & mdoc->flags));
|
|
||||||
return(&mdoc->meta);
|
return(&mdoc->meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frees volatile resources (parse tree, meta-data, fields).
|
* Frees volatile resources (parse tree, meta-data, fields).
|
||||||
*/
|
*/
|
||||||
@ -130,23 +123,15 @@ mdoc_free1(struct mdoc *mdoc)
|
|||||||
|
|
||||||
if (mdoc->first)
|
if (mdoc->first)
|
||||||
mdoc_node_delete(mdoc, mdoc->first);
|
mdoc_node_delete(mdoc, mdoc->first);
|
||||||
if (mdoc->meta.title)
|
|
||||||
free(mdoc->meta.title);
|
|
||||||
if (mdoc->meta.os)
|
|
||||||
free(mdoc->meta.os);
|
|
||||||
if (mdoc->meta.name)
|
|
||||||
free(mdoc->meta.name);
|
|
||||||
if (mdoc->meta.arch)
|
|
||||||
free(mdoc->meta.arch);
|
|
||||||
if (mdoc->meta.vol)
|
|
||||||
free(mdoc->meta.vol);
|
|
||||||
if (mdoc->meta.msec)
|
|
||||||
free(mdoc->meta.msec);
|
free(mdoc->meta.msec);
|
||||||
if (mdoc->meta.date)
|
free(mdoc->meta.vol);
|
||||||
|
free(mdoc->meta.arch);
|
||||||
free(mdoc->meta.date);
|
free(mdoc->meta.date);
|
||||||
|
free(mdoc->meta.title);
|
||||||
|
free(mdoc->meta.os);
|
||||||
|
free(mdoc->meta.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate all volatile resources (parse tree, meta-data, fields).
|
* Allocate all volatile resources (parse tree, meta-data, fields).
|
||||||
*/
|
*/
|
||||||
@ -164,7 +149,6 @@ mdoc_alloc1(struct mdoc *mdoc)
|
|||||||
mdoc->next = MDOC_NEXT_CHILD;
|
mdoc->next = MDOC_NEXT_CHILD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free up volatile resources (see mdoc_free1()) then re-initialises the
|
* Free up volatile resources (see mdoc_free1()) then re-initialises the
|
||||||
* data with mdoc_alloc1(). After invocation, parse data has been reset
|
* data with mdoc_alloc1(). After invocation, parse data has been reset
|
||||||
@ -179,7 +163,6 @@ mdoc_reset(struct mdoc *mdoc)
|
|||||||
mdoc_alloc1(mdoc);
|
mdoc_alloc1(mdoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Completely free up all volatile and non-volatile parse resources.
|
* Completely free up all volatile and non-volatile parse resources.
|
||||||
* After invocation, the pointer is no longer usable.
|
* After invocation, the pointer is no longer usable.
|
||||||
@ -192,12 +175,12 @@ mdoc_free(struct mdoc *mdoc)
|
|||||||
free(mdoc);
|
free(mdoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate volatile and non-volatile parse resources.
|
* Allocate volatile and non-volatile parse resources.
|
||||||
*/
|
*/
|
||||||
struct mdoc *
|
struct mdoc *
|
||||||
mdoc_alloc(struct roff *roff, struct mparse *parse, char *defos)
|
mdoc_alloc(struct roff *roff, struct mparse *parse,
|
||||||
|
const char *defos, int quick)
|
||||||
{
|
{
|
||||||
struct mdoc *p;
|
struct mdoc *p;
|
||||||
|
|
||||||
@ -205,6 +188,7 @@ mdoc_alloc(struct roff *roff, struct mparse *parse, char *defos)
|
|||||||
|
|
||||||
p->parse = parse;
|
p->parse = parse;
|
||||||
p->defos = defos;
|
p->defos = defos;
|
||||||
|
p->quick = quick;
|
||||||
p->roff = roff;
|
p->roff = roff;
|
||||||
|
|
||||||
mdoc_hash_init();
|
mdoc_hash_init();
|
||||||
@ -212,20 +196,11 @@ mdoc_alloc(struct roff *roff, struct mparse *parse, char *defos)
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Climb back up the parse tree, validating open scopes. Mostly calls
|
|
||||||
* through to macro_end() in macro.c.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
mdoc_endparse(struct mdoc *mdoc)
|
mdoc_endparse(struct mdoc *mdoc)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MDOC_HALT & mdoc->flags));
|
return(mdoc_macroend(mdoc));
|
||||||
if (mdoc_macroend(mdoc))
|
|
||||||
return(1);
|
|
||||||
mdoc->flags |= MDOC_HALT;
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -233,15 +208,6 @@ mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep)
|
|||||||
{
|
{
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
|
||||||
assert( ! (MDOC_HALT & mdoc->flags));
|
|
||||||
|
|
||||||
/* No text before an initial macro. */
|
|
||||||
|
|
||||||
if (SEC_NONE == mdoc->lastnamed) {
|
|
||||||
mdoc_pmsg(mdoc, ep->ln, ep->pos, MANDOCERR_NOTEXT);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -257,15 +223,6 @@ mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
|
|||||||
{
|
{
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
|
||||||
assert( ! (MDOC_HALT & mdoc->flags));
|
|
||||||
|
|
||||||
/* No text before an initial macro. */
|
|
||||||
|
|
||||||
if (SEC_NONE == mdoc->lastnamed) {
|
|
||||||
mdoc_pmsg(mdoc, sp->line, 0, MANDOCERR_NOTEXT);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -276,7 +233,6 @@ mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main parse routine. Parses a single line -- really just hands off to
|
* Main parse routine. Parses a single line -- really just hands off to
|
||||||
* the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
|
* the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
|
||||||
@ -285,8 +241,6 @@ int
|
|||||||
mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
|
mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert( ! (MDOC_HALT & mdoc->flags));
|
|
||||||
|
|
||||||
mdoc->flags |= MDOC_NEWLINE;
|
mdoc->flags |= MDOC_NEWLINE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -310,30 +264,22 @@ mdoc_macro(MACRO_PROT_ARGS)
|
|||||||
{
|
{
|
||||||
assert(tok < MDOC_MAX);
|
assert(tok < MDOC_MAX);
|
||||||
|
|
||||||
/* If we're in the body, deny prologue calls. */
|
if (mdoc->flags & MDOC_PBODY) {
|
||||||
|
if (tok == MDOC_Dt) {
|
||||||
if (MDOC_PROLOGUE & mdoc_macros[tok].flags &&
|
mandoc_vmsg(MANDOCERR_DT_LATE,
|
||||||
MDOC_PBODY & mdoc->flags) {
|
mdoc->parse, line, ppos,
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADBODY);
|
"Dt %s", buf + *pos);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
} else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) {
|
||||||
/* If we're in the prologue, deny "body" macros. */
|
if (mdoc->meta.title == NULL) {
|
||||||
|
mandoc_vmsg(MANDOCERR_DT_NOTITLE,
|
||||||
if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
|
mdoc->parse, line, ppos, "%s %s",
|
||||||
! (MDOC_PBODY & mdoc->flags)) {
|
mdoc_macronames[tok], buf + *pos);
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADPROLOG);
|
mdoc->meta.title = mandoc_strdup("UNTITLED");
|
||||||
if (NULL == mdoc->meta.msec)
|
}
|
||||||
mdoc->meta.msec = mandoc_strdup("1");
|
|
||||||
if (NULL == mdoc->meta.title)
|
|
||||||
mdoc->meta.title = mandoc_strdup("UNKNOWN");
|
|
||||||
if (NULL == mdoc->meta.vol)
|
if (NULL == mdoc->meta.vol)
|
||||||
mdoc->meta.vol = mandoc_strdup("LOCAL");
|
mdoc->meta.vol = mandoc_strdup("LOCAL");
|
||||||
if (NULL == mdoc->meta.os)
|
|
||||||
mdoc->meta.os = mandoc_strdup("LOCAL");
|
|
||||||
if (NULL == mdoc->meta.date)
|
|
||||||
mdoc->meta.date = mandoc_normdate
|
|
||||||
(mdoc->parse, NULL, line, ppos);
|
|
||||||
mdoc->flags |= MDOC_PBODY;
|
mdoc->flags |= MDOC_PBODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,12 +296,12 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
assert(MDOC_ROOT != p->type);
|
assert(MDOC_ROOT != p->type);
|
||||||
|
|
||||||
switch (mdoc->next) {
|
switch (mdoc->next) {
|
||||||
case (MDOC_NEXT_SIBLING):
|
case MDOC_NEXT_SIBLING:
|
||||||
mdoc->last->next = p;
|
mdoc->last->next = p;
|
||||||
p->prev = mdoc->last;
|
p->prev = mdoc->last;
|
||||||
p->parent = mdoc->last->parent;
|
p->parent = mdoc->last->parent;
|
||||||
break;
|
break;
|
||||||
case (MDOC_NEXT_CHILD):
|
case MDOC_NEXT_CHILD:
|
||||||
mdoc->last->child = p;
|
mdoc->last->child = p;
|
||||||
p->parent = mdoc->last;
|
p->parent = mdoc->last;
|
||||||
break;
|
break;
|
||||||
@ -372,13 +318,13 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
if (ENDBODY_NOT != p->end)
|
if (ENDBODY_NOT != p->end)
|
||||||
break;
|
break;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_TAIL):
|
case MDOC_TAIL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
p->norm = p->parent->norm;
|
p->norm = p->parent->norm;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -389,15 +335,15 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
assert(MDOC_BLOCK == p->parent->type);
|
assert(MDOC_BLOCK == p->parent->type);
|
||||||
p->parent->head = p;
|
p->parent->head = p;
|
||||||
break;
|
break;
|
||||||
case (MDOC_TAIL):
|
case MDOC_TAIL:
|
||||||
assert(MDOC_BLOCK == p->parent->type);
|
assert(MDOC_BLOCK == p->parent->type);
|
||||||
p->parent->tail = p;
|
p->parent->tail = p;
|
||||||
break;
|
break;
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
if (p->end)
|
if (p->end)
|
||||||
break;
|
break;
|
||||||
assert(MDOC_BLOCK == p->parent->type);
|
assert(MDOC_BLOCK == p->parent->type);
|
||||||
@ -410,9 +356,9 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
mdoc->last = p;
|
mdoc->last = p;
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case (MDOC_TBL):
|
case MDOC_TBL:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_TEXT):
|
case MDOC_TEXT:
|
||||||
if ( ! mdoc_valid_post(mdoc))
|
if ( ! mdoc_valid_post(mdoc))
|
||||||
return(0);
|
return(0);
|
||||||
break;
|
break;
|
||||||
@ -423,7 +369,6 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct mdoc_node *
|
static struct mdoc_node *
|
||||||
node_alloc(struct mdoc *mdoc, int line, int pos,
|
node_alloc(struct mdoc *mdoc, int line, int pos,
|
||||||
enum mdoct tok, enum mdoc_type type)
|
enum mdoct tok, enum mdoc_type type)
|
||||||
@ -451,7 +396,6 @@ node_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -464,7 +408,6 @@ mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -480,7 +423,6 @@ mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -493,7 +435,6 @@ mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
@ -510,7 +451,6 @@ mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
@ -523,13 +463,15 @@ mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
(args->refcnt)++;
|
(args->refcnt)++;
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_Bd):
|
case MDOC_Bd:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Bf):
|
case MDOC_Bf:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Bl):
|
case MDOC_Bl:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Rs):
|
case MDOC_En:
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case MDOC_Rs:
|
||||||
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
|
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -542,7 +484,6 @@ mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
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)
|
||||||
@ -555,7 +496,7 @@ mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
|
|||||||
(args->refcnt)++;
|
(args->refcnt)++;
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_An):
|
case MDOC_An:
|
||||||
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
|
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -591,10 +532,7 @@ mdoc_word_append(struct mdoc *mdoc, const char *p)
|
|||||||
|
|
||||||
n = mdoc->last;
|
n = mdoc->last;
|
||||||
addstr = roff_strdup(mdoc->roff, p);
|
addstr = roff_strdup(mdoc->roff, p);
|
||||||
if (-1 == asprintf(&newstr, "%s %s", n->string, addstr)) {
|
mandoc_asprintf(&newstr, "%s %s", n->string, addstr);
|
||||||
perror(NULL);
|
|
||||||
exit((int)MANDOCLEVEL_SYSERR);
|
|
||||||
}
|
|
||||||
free(addstr);
|
free(addstr);
|
||||||
free(n->string);
|
free(n->string);
|
||||||
n->string = newstr;
|
n->string = newstr;
|
||||||
@ -614,7 +552,6 @@ mdoc_node_free(struct mdoc_node *p)
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n)
|
mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n)
|
||||||
{
|
{
|
||||||
@ -652,7 +589,6 @@ mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n)
|
|||||||
mdoc->first = NULL;
|
mdoc->first = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p)
|
mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p)
|
||||||
{
|
{
|
||||||
@ -739,13 +675,6 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
char *c, *ws, *end;
|
char *c, *ws, *end;
|
||||||
struct mdoc_node *n;
|
struct mdoc_node *n;
|
||||||
|
|
||||||
/* No text before an initial macro. */
|
|
||||||
|
|
||||||
if (SEC_NONE == mdoc->lastnamed) {
|
|
||||||
mdoc_pmsg(mdoc, line, offs, MANDOCERR_NOTEXT);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(mdoc->last);
|
assert(mdoc->last);
|
||||||
n = mdoc->last;
|
n = mdoc->last;
|
||||||
|
|
||||||
@ -814,10 +743,12 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
*end = '\0';
|
*end = '\0';
|
||||||
|
|
||||||
if (ws)
|
if (ws)
|
||||||
mdoc_pmsg(mdoc, line, (int)(ws-buf), MANDOCERR_EOLNSPACE);
|
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||||
|
line, (int)(ws-buf), NULL);
|
||||||
|
|
||||||
if ('\0' == buf[offs] && ! (MDOC_LITERAL & mdoc->flags)) {
|
if ('\0' == buf[offs] && ! (MDOC_LITERAL & mdoc->flags)) {
|
||||||
mdoc_pmsg(mdoc, line, (int)(c-buf), MANDOCERR_NOBLANKLN);
|
mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse,
|
||||||
|
line, (int)(c - buf), NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a `sp' in the case of a blank line. Technically,
|
* Insert a `sp' in the case of a blank line. Technically,
|
||||||
@ -846,13 +777,12 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
|||||||
|
|
||||||
assert(buf < end);
|
assert(buf < end);
|
||||||
|
|
||||||
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs), 0))
|
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs)))
|
||||||
mdoc->last->flags |= MDOC_EOS;
|
mdoc->last->flags |= MDOC_EOS;
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a macro line, that is, a line beginning with the control
|
* Parse a macro line, that is, a line beginning with the control
|
||||||
* character.
|
* character.
|
||||||
@ -868,7 +798,8 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
/* Empty post-control lines are ignored. */
|
/* Empty post-control lines are ignored. */
|
||||||
|
|
||||||
if ('"' == buf[offs]) {
|
if ('"' == buf[offs]) {
|
||||||
mdoc_pmsg(mdoc, ln, offs, MANDOCERR_BADCOMMENT);
|
mandoc_msg(MANDOCERR_COMMENT_BAD, mdoc->parse,
|
||||||
|
ln, offs, NULL);
|
||||||
return(1);
|
return(1);
|
||||||
} else if ('\0' == buf[offs])
|
} else if ('\0' == buf[offs])
|
||||||
return(1);
|
return(1);
|
||||||
@ -881,17 +812,17 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < 4 && '\0' != buf[offs] &&
|
while (i < 4 && '\0' != buf[offs] && ' ' != buf[offs] &&
|
||||||
' ' != buf[offs] && '\t' != buf[offs])
|
'\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 (MDOC_MAX == tok) {
|
||||||
mandoc_vmsg(MANDOCERR_MACRO, mdoc->parse,
|
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
|
||||||
ln, sv, "%s", buf + sv - 1);
|
ln, sv, buf + sv - 1);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,18 +842,16 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||||
mdoc_pmsg(mdoc, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||||
|
ln, offs - 1, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If an initial macro or a list invocation, divert directly
|
* If an initial macro or a list invocation, divert directly
|
||||||
* 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)
|
||||||
if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf))
|
return(mdoc_macro(mdoc, tok, ln, sv, &offs, buf));
|
||||||
goto err;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
n = mdoc->last;
|
n = mdoc->last;
|
||||||
assert(mdoc->last);
|
assert(mdoc->last);
|
||||||
@ -935,9 +864,7 @@ 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;
|
||||||
if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf))
|
return(mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf));
|
||||||
goto err;
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -951,22 +878,21 @@ 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;
|
||||||
if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf))
|
return(mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf));
|
||||||
goto err;
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal processing of a macro. */
|
/* Normal processing of a macro. */
|
||||||
|
|
||||||
if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf))
|
if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf))
|
||||||
goto err;
|
return(0);
|
||||||
|
|
||||||
|
/* In quick mode (for mandocdb), abort after the NAME section. */
|
||||||
|
|
||||||
|
if (mdoc->quick && MDOC_Sh == tok &&
|
||||||
|
SEC_NAME != mdoc->last->sec)
|
||||||
|
return(2);
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
|
|
||||||
err: /* Error out. */
|
|
||||||
|
|
||||||
mdoc->flags |= MDOC_HALT;
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mdelim
|
enum mdelim
|
||||||
@ -978,27 +904,27 @@ mdoc_isdelim(const char *p)
|
|||||||
|
|
||||||
if ('\0' == p[1])
|
if ('\0' == p[1])
|
||||||
switch (p[0]) {
|
switch (p[0]) {
|
||||||
case('('):
|
case '(':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case('['):
|
case '[':
|
||||||
return(DELIM_OPEN);
|
return(DELIM_OPEN);
|
||||||
case('|'):
|
case '|':
|
||||||
return(DELIM_MIDDLE);
|
return(DELIM_MIDDLE);
|
||||||
case('.'):
|
case '.':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case(','):
|
case ',':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case(';'):
|
case ';':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case(':'):
|
case ':':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case('?'):
|
case '?':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case('!'):
|
case '!':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case(')'):
|
case ')':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case(']'):
|
case ']':
|
||||||
return(DELIM_CLOSE);
|
return(DELIM_CLOSE);
|
||||||
default:
|
default:
|
||||||
return(DELIM_NONE);
|
return(DELIM_NONE);
|
||||||
@ -1014,3 +940,42 @@ mdoc_isdelim(const char *p)
|
|||||||
|
|
||||||
return(DELIM_NONE);
|
return(DELIM_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mdoc_deroff(char **dest, const struct mdoc_node *n)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
|
if (MDOC_TEXT != n->type) {
|
||||||
|
for (n = n->child; n; n = n->next)
|
||||||
|
mdoc_deroff(dest, n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip leading whitespace. */
|
||||||
|
|
||||||
|
for (cp = n->string; '\0' != *cp; cp++)
|
||||||
|
if (0 == isspace((unsigned char)*cp))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Skip trailing whitespace. */
|
||||||
|
|
||||||
|
for (sz = strlen(cp); sz; sz--)
|
||||||
|
if (0 == isspace((unsigned char)cp[sz-1]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Skip empty strings. */
|
||||||
|
|
||||||
|
if (0 == sz)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (NULL == *dest) {
|
||||||
|
*dest = mandoc_strndup(cp, sz);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp);
|
||||||
|
free(*dest);
|
||||||
|
*dest = cp;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc.h,v 1.125 2013/12/24 19:11:45 schwarze Exp $ */
|
/* $Id: mdoc.h,v 1.131 2014/07/29 13:58:18 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -140,6 +140,7 @@ enum mdoct {
|
|||||||
MDOC_sp,
|
MDOC_sp,
|
||||||
MDOC__U,
|
MDOC__U,
|
||||||
MDOC_Ta,
|
MDOC_Ta,
|
||||||
|
MDOC_ll,
|
||||||
MDOC_MAX
|
MDOC_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -198,6 +199,7 @@ enum mdoc_sec {
|
|||||||
SEC_LIBRARY, /* LIBRARY */
|
SEC_LIBRARY, /* LIBRARY */
|
||||||
SEC_SYNOPSIS, /* SYNOPSIS */
|
SEC_SYNOPSIS, /* SYNOPSIS */
|
||||||
SEC_DESCRIPTION, /* DESCRIPTION */
|
SEC_DESCRIPTION, /* DESCRIPTION */
|
||||||
|
SEC_CONTEXT, /* CONTEXT */
|
||||||
SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */
|
SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */
|
||||||
SEC_RETURN_VALUES, /* RETURN VALUES */
|
SEC_RETURN_VALUES, /* RETURN VALUES */
|
||||||
SEC_ENVIRONMENT, /* ENVIRONMENT */
|
SEC_ENVIRONMENT, /* ENVIRONMENT */
|
||||||
@ -278,7 +280,7 @@ enum mdoc_list {
|
|||||||
|
|
||||||
enum mdoc_disp {
|
enum mdoc_disp {
|
||||||
DISP__NONE = 0,
|
DISP__NONE = 0,
|
||||||
DISP_centred, /* -centered */
|
DISP_centered, /* -centered */
|
||||||
DISP_ragged, /* -ragged */
|
DISP_ragged, /* -ragged */
|
||||||
DISP_unfilled, /* -unfilled */
|
DISP_unfilled, /* -unfilled */
|
||||||
DISP_filled, /* -filled */
|
DISP_filled, /* -filled */
|
||||||
@ -336,6 +338,7 @@ union mdoc_data {
|
|||||||
struct mdoc_bd Bd;
|
struct mdoc_bd Bd;
|
||||||
struct mdoc_bf Bf;
|
struct mdoc_bf Bf;
|
||||||
struct mdoc_bl Bl;
|
struct mdoc_bl Bl;
|
||||||
|
struct mdoc_node *Es;
|
||||||
struct mdoc_rs Rs;
|
struct mdoc_rs Rs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -389,6 +392,7 @@ struct mdoc;
|
|||||||
|
|
||||||
const struct mdoc_node *mdoc_node(const struct mdoc *);
|
const struct mdoc_node *mdoc_node(const struct mdoc *);
|
||||||
const struct mdoc_meta *mdoc_meta(const struct mdoc *);
|
const struct mdoc_meta *mdoc_meta(const struct mdoc *);
|
||||||
|
void mdoc_deroff(char **, const struct mdoc_node *);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc_argv.c,v 1.89 2013/12/25 00:50:05 schwarze Exp $ */
|
/* $Id: mdoc_argv.c,v 1.95 2014/07/06 19:09:00 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 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmdoc.h"
|
#include "libmdoc.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
|||||||
{ ARGSFL_NONE, NULL }, /* Nd */
|
{ ARGSFL_NONE, NULL }, /* Nd */
|
||||||
{ ARGSFL_DELIM, NULL }, /* Nm */
|
{ ARGSFL_DELIM, NULL }, /* Nm */
|
||||||
{ ARGSFL_DELIM, NULL }, /* Op */
|
{ ARGSFL_DELIM, NULL }, /* Op */
|
||||||
{ ARGSFL_NONE, NULL }, /* Ot */
|
{ ARGSFL_DELIM, NULL }, /* Ot */
|
||||||
{ ARGSFL_DELIM, NULL }, /* Pa */
|
{ ARGSFL_DELIM, NULL }, /* Pa */
|
||||||
{ ARGSFL_NONE, args_Ex }, /* Rv */
|
{ ARGSFL_NONE, args_Ex }, /* Rv */
|
||||||
{ ARGSFL_DELIM, NULL }, /* St */
|
{ ARGSFL_DELIM, NULL }, /* St */
|
||||||
@ -248,7 +249,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
|||||||
{ ARGSFL_NONE, NULL }, /* Ek */
|
{ ARGSFL_NONE, NULL }, /* Ek */
|
||||||
{ ARGSFL_NONE, NULL }, /* Bt */
|
{ ARGSFL_NONE, NULL }, /* Bt */
|
||||||
{ ARGSFL_NONE, NULL }, /* Hf */
|
{ ARGSFL_NONE, NULL }, /* Hf */
|
||||||
{ ARGSFL_NONE, NULL }, /* Fr */
|
{ ARGSFL_DELIM, NULL }, /* Fr */
|
||||||
{ ARGSFL_NONE, NULL }, /* Ud */
|
{ ARGSFL_NONE, NULL }, /* Ud */
|
||||||
{ ARGSFL_DELIM, NULL }, /* Lb */
|
{ ARGSFL_DELIM, NULL }, /* Lb */
|
||||||
{ ARGSFL_NONE, NULL }, /* Lp */
|
{ ARGSFL_NONE, NULL }, /* Lp */
|
||||||
@ -259,13 +260,14 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
|||||||
{ ARGSFL_DELIM, NULL }, /* Brc */
|
{ ARGSFL_DELIM, NULL }, /* Brc */
|
||||||
{ ARGSFL_NONE, NULL }, /* %C */
|
{ ARGSFL_NONE, NULL }, /* %C */
|
||||||
{ ARGSFL_NONE, NULL }, /* Es */
|
{ ARGSFL_NONE, NULL }, /* Es */
|
||||||
{ ARGSFL_NONE, NULL }, /* En */
|
{ ARGSFL_DELIM, NULL }, /* En */
|
||||||
{ ARGSFL_DELIM, NULL }, /* Dx */
|
{ ARGSFL_DELIM, NULL }, /* Dx */
|
||||||
{ ARGSFL_NONE, NULL }, /* %Q */
|
{ ARGSFL_NONE, NULL }, /* %Q */
|
||||||
{ ARGSFL_NONE, NULL }, /* br */
|
{ ARGSFL_NONE, NULL }, /* br */
|
||||||
{ ARGSFL_NONE, NULL }, /* sp */
|
{ ARGSFL_NONE, NULL }, /* sp */
|
||||||
{ ARGSFL_NONE, NULL }, /* %U */
|
{ ARGSFL_NONE, NULL }, /* %U */
|
||||||
{ ARGSFL_NONE, NULL }, /* Ta */
|
{ ARGSFL_NONE, NULL }, /* Ta */
|
||||||
|
{ ARGSFL_NONE, NULL }, /* ll */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -341,15 +343,15 @@ mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
|
|||||||
(*pos)++;
|
(*pos)++;
|
||||||
|
|
||||||
switch (argvflags[tmp.arg]) {
|
switch (argvflags[tmp.arg]) {
|
||||||
case (ARGV_SINGLE):
|
case ARGV_SINGLE:
|
||||||
if ( ! argv_single(mdoc, line, &tmp, pos, buf))
|
if ( ! argv_single(mdoc, line, &tmp, pos, buf))
|
||||||
return(ARGV_ERROR);
|
return(ARGV_ERROR);
|
||||||
break;
|
break;
|
||||||
case (ARGV_MULTI):
|
case ARGV_MULTI:
|
||||||
if ( ! argv_multi(mdoc, line, &tmp, pos, buf))
|
if ( ! argv_multi(mdoc, line, &tmp, pos, buf))
|
||||||
return(ARGV_ERROR);
|
return(ARGV_ERROR);
|
||||||
break;
|
break;
|
||||||
case (ARGV_NONE):
|
case ARGV_NONE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,11 +359,11 @@ mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
|
|||||||
arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
|
arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
|
||||||
|
|
||||||
arg->argc++;
|
arg->argc++;
|
||||||
arg->argv = mandoc_realloc
|
arg->argv = mandoc_reallocarray(arg->argv,
|
||||||
(arg->argv, arg->argc * sizeof(struct mdoc_argv));
|
arg->argc, sizeof(struct mdoc_argv));
|
||||||
|
|
||||||
memcpy(&arg->argv[(int)arg->argc - 1],
|
memcpy(&arg->argv[(int)arg->argc - 1], &tmp,
|
||||||
&tmp, sizeof(struct mdoc_argv));
|
sizeof(struct mdoc_argv));
|
||||||
|
|
||||||
return(ARGV_ARG);
|
return(ARGV_ARG);
|
||||||
}
|
}
|
||||||
@ -459,7 +461,8 @@ args(struct mdoc *mdoc, int line, int *pos,
|
|||||||
* is unterminated.
|
* is unterminated.
|
||||||
*/
|
*/
|
||||||
if (MDOC_PHRASELIT & mdoc->flags)
|
if (MDOC_PHRASELIT & mdoc->flags)
|
||||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE);
|
mandoc_msg(MANDOCERR_ARG_QUOTE,
|
||||||
|
mdoc->parse, line, *pos, NULL);
|
||||||
|
|
||||||
mdoc->flags &= ~MDOC_PHRASELIT;
|
mdoc->flags &= ~MDOC_PHRASELIT;
|
||||||
return(ARGS_EOLN);
|
return(ARGS_EOLN);
|
||||||
@ -518,7 +521,8 @@ args(struct mdoc *mdoc, int line, int *pos,
|
|||||||
|
|
||||||
/* Whitespace check for eoln case... */
|
/* Whitespace check for eoln case... */
|
||||||
if ('\0' == *p && ' ' == *(p - 1))
|
if ('\0' == *p && ' ' == *(p - 1))
|
||||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE);
|
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||||
|
line, *pos, NULL);
|
||||||
|
|
||||||
*pos += (int)(p - *v);
|
*pos += (int)(p - *v);
|
||||||
|
|
||||||
@ -573,7 +577,8 @@ args(struct mdoc *mdoc, int line, int *pos,
|
|||||||
if ('\0' == buf[*pos]) {
|
if ('\0' == buf[*pos]) {
|
||||||
if (MDOC_PPHRASE & mdoc->flags)
|
if (MDOC_PPHRASE & mdoc->flags)
|
||||||
return(ARGS_QWORD);
|
return(ARGS_QWORD);
|
||||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE);
|
mandoc_msg(MANDOCERR_ARG_QUOTE,
|
||||||
|
mdoc->parse, line, *pos, NULL);
|
||||||
return(ARGS_QWORD);
|
return(ARGS_QWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,7 +592,8 @@ args(struct mdoc *mdoc, int line, int *pos,
|
|||||||
(*pos)++;
|
(*pos)++;
|
||||||
|
|
||||||
if ('\0' == buf[*pos])
|
if ('\0' == buf[*pos])
|
||||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE);
|
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||||
|
line, *pos, NULL);
|
||||||
|
|
||||||
return(ARGS_QWORD);
|
return(ARGS_QWORD);
|
||||||
}
|
}
|
||||||
@ -665,8 +671,8 @@ argv_multi(struct mdoc *mdoc, int line,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (0 == v->sz % MULTI_STEP)
|
if (0 == v->sz % MULTI_STEP)
|
||||||
v->value = mandoc_realloc(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);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc_hash.c,v 1.18 2011/07/24 18:15:14 kristaps Exp $ */
|
/* $Id: mdoc_hash.c,v 1.20 2014/04/20 16:46:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -28,11 +28,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.h"
|
|
||||||
#include "libmdoc.h"
|
#include "libmdoc.h"
|
||||||
|
|
||||||
static unsigned char table[27 * 12];
|
static unsigned char table[27 * 12];
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX - this hash has global scope, so if intended for use as a library
|
* XXX - this hash has global scope, so if intended for use as a library
|
||||||
* with multiple callers, it will need re-invocation protection.
|
* with multiple callers, it will need re-invocation protection.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mdoc_macro.c,v 1.125 2013/12/24 20:45:27 schwarze Exp $ */
|
/* $Id: mdoc_macro.c,v 1.139 2014/08/01 17:27:44 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
* Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -48,7 +48,6 @@ static int ctx_synopsis(MACRO_PROT_ARGS);
|
|||||||
static int in_line_eoln(MACRO_PROT_ARGS);
|
static int in_line_eoln(MACRO_PROT_ARGS);
|
||||||
static int in_line_argn(MACRO_PROT_ARGS);
|
static int in_line_argn(MACRO_PROT_ARGS);
|
||||||
static int in_line(MACRO_PROT_ARGS);
|
static int in_line(MACRO_PROT_ARGS);
|
||||||
static int obsolete(MACRO_PROT_ARGS);
|
|
||||||
static int phrase_ta(MACRO_PROT_ARGS);
|
static int phrase_ta(MACRO_PROT_ARGS);
|
||||||
|
|
||||||
static int dword(struct mdoc *, int, int, const char *,
|
static int dword(struct mdoc *, int, int, const char *,
|
||||||
@ -87,7 +86,7 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
|||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* An */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* An */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Cd */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
|
||||||
@ -98,13 +97,13 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
|||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ic */
|
||||||
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
|
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Li */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Li */
|
||||||
{ blk_full, MDOC_JOIN }, /* Nd */
|
{ blk_full, MDOC_JOIN }, /* Nd */
|
||||||
{ ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
|
{ ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
|
||||||
{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
|
{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
|
||||||
{ obsolete, 0 }, /* Ot */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ot */
|
||||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
|
||||||
{ in_line_eoln, 0 }, /* Rv */
|
{ in_line_eoln, 0 }, /* Rv */
|
||||||
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
|
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
|
||||||
@ -191,7 +190,7 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
|||||||
{ blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ek */
|
{ blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ek */
|
||||||
{ in_line_eoln, 0 }, /* Bt */
|
{ in_line_eoln, 0 }, /* Bt */
|
||||||
{ in_line_eoln, 0 }, /* Hf */
|
{ in_line_eoln, 0 }, /* Hf */
|
||||||
{ obsolete, 0 }, /* Fr */
|
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fr */
|
||||||
{ in_line_eoln, 0 }, /* Ud */
|
{ in_line_eoln, 0 }, /* Ud */
|
||||||
{ in_line, 0 }, /* Lb */
|
{ in_line, 0 }, /* Lb */
|
||||||
{ in_line_eoln, 0 }, /* Lp */
|
{ in_line_eoln, 0 }, /* Lp */
|
||||||
@ -203,14 +202,15 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
|||||||
{ blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
|
{ blk_exp_close, MDOC_CALLABLE | MDOC_PARSED |
|
||||||
MDOC_EXPLICIT | MDOC_JOIN }, /* Brc */
|
MDOC_EXPLICIT | MDOC_JOIN }, /* Brc */
|
||||||
{ in_line_eoln, MDOC_JOIN }, /* %C */
|
{ in_line_eoln, MDOC_JOIN }, /* %C */
|
||||||
{ obsolete, 0 }, /* Es */
|
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Es */
|
||||||
{ obsolete, 0 }, /* En */
|
{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* En */
|
||||||
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
|
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
|
||||||
{ in_line_eoln, MDOC_JOIN }, /* %Q */
|
{ in_line_eoln, MDOC_JOIN }, /* %Q */
|
||||||
{ in_line_eoln, 0 }, /* br */
|
{ in_line_eoln, 0 }, /* br */
|
||||||
{ in_line_eoln, 0 }, /* sp */
|
{ in_line_eoln, 0 }, /* sp */
|
||||||
{ in_line_eoln, 0 }, /* %U */
|
{ in_line_eoln, 0 }, /* %U */
|
||||||
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
|
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
|
||||||
|
{ in_line_eoln, 0 }, /* ll */
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
|
const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
|
||||||
@ -234,14 +234,14 @@ mdoc_macroend(struct mdoc *mdoc)
|
|||||||
for ( ; n; n = n->parent)
|
for ( ; n; n = n->parent)
|
||||||
if (MDOC_BLOCK == n->type &&
|
if (MDOC_BLOCK == n->type &&
|
||||||
MDOC_EXPLICIT & mdoc_macros[n->tok].flags)
|
MDOC_EXPLICIT & mdoc_macros[n->tok].flags)
|
||||||
mdoc_nmsg(mdoc, n, MANDOCERR_SCOPEEXIT);
|
mandoc_msg(MANDOCERR_BLK_NOEND, mdoc->parse,
|
||||||
|
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||||
|
|
||||||
/* Rewind to the first. */
|
/* Rewind to the first. */
|
||||||
|
|
||||||
return(rew_last(mdoc, mdoc->first));
|
return(rew_last(mdoc, mdoc->first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up a macro from within a subsequent context.
|
* Look up a macro from within a subsequent context.
|
||||||
*/
|
*/
|
||||||
@ -254,7 +254,6 @@ lookup(enum mdoct from, const char *p)
|
|||||||
return(lookup_raw(p));
|
return(lookup_raw(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup a macro following the initial line macro.
|
* Lookup a macro following the initial line macro.
|
||||||
*/
|
*/
|
||||||
@ -270,7 +269,6 @@ lookup_raw(const char *p)
|
|||||||
return(MDOC_MAX);
|
return(MDOC_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
|
rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
|
||||||
{
|
{
|
||||||
@ -279,7 +277,7 @@ rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
|
|||||||
assert(to);
|
assert(to);
|
||||||
mdoc->next = MDOC_NEXT_SIBLING;
|
mdoc->next = MDOC_NEXT_SIBLING;
|
||||||
|
|
||||||
/* LINTED */
|
|
||||||
while (mdoc->last != to) {
|
while (mdoc->last != to) {
|
||||||
/*
|
/*
|
||||||
* Save the parent here, because we may delete the
|
* Save the parent here, because we may delete the
|
||||||
@ -299,7 +297,6 @@ rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
|
|||||||
return(mdoc_valid_post(mdoc));
|
return(mdoc_valid_post(mdoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For a block closing macro, return the corresponding opening one.
|
* For a block closing macro, return the corresponding opening one.
|
||||||
* Otherwise, return the macro itself.
|
* Otherwise, return the macro itself.
|
||||||
@ -308,37 +305,37 @@ static enum mdoct
|
|||||||
rew_alt(enum mdoct tok)
|
rew_alt(enum mdoct tok)
|
||||||
{
|
{
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_Ac):
|
case MDOC_Ac:
|
||||||
return(MDOC_Ao);
|
return(MDOC_Ao);
|
||||||
case (MDOC_Bc):
|
case MDOC_Bc:
|
||||||
return(MDOC_Bo);
|
return(MDOC_Bo);
|
||||||
case (MDOC_Brc):
|
case MDOC_Brc:
|
||||||
return(MDOC_Bro);
|
return(MDOC_Bro);
|
||||||
case (MDOC_Dc):
|
case MDOC_Dc:
|
||||||
return(MDOC_Do);
|
return(MDOC_Do);
|
||||||
case (MDOC_Ec):
|
case MDOC_Ec:
|
||||||
return(MDOC_Eo);
|
return(MDOC_Eo);
|
||||||
case (MDOC_Ed):
|
case MDOC_Ed:
|
||||||
return(MDOC_Bd);
|
return(MDOC_Bd);
|
||||||
case (MDOC_Ef):
|
case MDOC_Ef:
|
||||||
return(MDOC_Bf);
|
return(MDOC_Bf);
|
||||||
case (MDOC_Ek):
|
case MDOC_Ek:
|
||||||
return(MDOC_Bk);
|
return(MDOC_Bk);
|
||||||
case (MDOC_El):
|
case MDOC_El:
|
||||||
return(MDOC_Bl);
|
return(MDOC_Bl);
|
||||||
case (MDOC_Fc):
|
case MDOC_Fc:
|
||||||
return(MDOC_Fo);
|
return(MDOC_Fo);
|
||||||
case (MDOC_Oc):
|
case MDOC_Oc:
|
||||||
return(MDOC_Oo);
|
return(MDOC_Oo);
|
||||||
case (MDOC_Pc):
|
case MDOC_Pc:
|
||||||
return(MDOC_Po);
|
return(MDOC_Po);
|
||||||
case (MDOC_Qc):
|
case MDOC_Qc:
|
||||||
return(MDOC_Qo);
|
return(MDOC_Qo);
|
||||||
case (MDOC_Re):
|
case MDOC_Re:
|
||||||
return(MDOC_Rs);
|
return(MDOC_Rs);
|
||||||
case (MDOC_Sc):
|
case MDOC_Sc:
|
||||||
return(MDOC_So);
|
return(MDOC_So);
|
||||||
case (MDOC_Xc):
|
case MDOC_Xc:
|
||||||
return(MDOC_Xo);
|
return(MDOC_Xo);
|
||||||
default:
|
default:
|
||||||
return(tok);
|
return(tok);
|
||||||
@ -346,7 +343,6 @@ rew_alt(enum mdoct tok)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rewinding to tok, how do we have to handle *p?
|
* Rewinding to tok, how do we have to handle *p?
|
||||||
* REWIND_NONE: *p would delimit tok, but no tok scope is open
|
* REWIND_NONE: *p would delimit tok, but no tok scope is open
|
||||||
@ -401,11 +397,11 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type,
|
|||||||
* Blocks delimiting our target token get REWIND_NONE.
|
* Blocks delimiting our target token get REWIND_NONE.
|
||||||
*/
|
*/
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_Bl):
|
case MDOC_Bl:
|
||||||
if (MDOC_It == p->tok)
|
if (MDOC_It == p->tok)
|
||||||
return(REWIND_MORE);
|
return(REWIND_MORE);
|
||||||
break;
|
break;
|
||||||
case (MDOC_It):
|
case MDOC_It:
|
||||||
if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
|
if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
|
||||||
return(REWIND_NONE);
|
return(REWIND_NONE);
|
||||||
break;
|
break;
|
||||||
@ -415,19 +411,21 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type,
|
|||||||
* This is an incomplete and extremely ugly workaround,
|
* This is an incomplete and extremely ugly workaround,
|
||||||
* required to let the OpenBSD tree build.
|
* required to let the OpenBSD tree build.
|
||||||
*/
|
*/
|
||||||
case (MDOC_Oo):
|
case MDOC_Oo:
|
||||||
if (MDOC_Op == p->tok)
|
if (MDOC_Op == p->tok)
|
||||||
return(REWIND_MORE);
|
return(REWIND_MORE);
|
||||||
break;
|
break;
|
||||||
case (MDOC_Nm):
|
case MDOC_Nm:
|
||||||
return(REWIND_NONE);
|
return(REWIND_NONE);
|
||||||
case (MDOC_Nd):
|
case MDOC_Nd:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Ss):
|
case MDOC_Ss:
|
||||||
if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
|
if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
|
||||||
return(REWIND_NONE);
|
return(REWIND_NONE);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Sh):
|
case MDOC_Sh:
|
||||||
|
if (MDOC_ROOT == p->parent->type)
|
||||||
|
return(REWIND_THIS);
|
||||||
if (MDOC_Nd == p->tok || MDOC_Ss == p->tok ||
|
if (MDOC_Nd == p->tok || MDOC_Ss == p->tok ||
|
||||||
MDOC_Sh == p->tok)
|
MDOC_Sh == p->tok)
|
||||||
return(REWIND_MORE);
|
return(REWIND_MORE);
|
||||||
@ -456,7 +454,6 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type,
|
|||||||
REWIND_FORCE : REWIND_LATER);
|
REWIND_FORCE : REWIND_LATER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rew_elem(struct mdoc *mdoc, enum mdoct tok)
|
rew_elem(struct mdoc *mdoc, enum mdoct tok)
|
||||||
{
|
{
|
||||||
@ -471,7 +468,6 @@ rew_elem(struct mdoc *mdoc, enum mdoct tok)
|
|||||||
return(rew_last(mdoc, n));
|
return(rew_last(mdoc, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We are trying to close a block identified by tok,
|
* We are trying to close a block identified by tok,
|
||||||
* but the child block *broken is still open.
|
* but the child block *broken is still open.
|
||||||
@ -535,7 +531,7 @@ make_pending(struct mdoc_node *broken, enum mdoct tok,
|
|||||||
taker->pending = broken->pending;
|
taker->pending = broken->pending;
|
||||||
}
|
}
|
||||||
broken->pending = breaker;
|
broken->pending = breaker;
|
||||||
mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos,
|
mandoc_vmsg(MANDOCERR_BLK_NEST, mdoc->parse, line, ppos,
|
||||||
"%s breaks %s", mdoc_macronames[tok],
|
"%s breaks %s", mdoc_macronames[tok],
|
||||||
mdoc_macronames[broken->tok]);
|
mdoc_macronames[broken->tok]);
|
||||||
return(1);
|
return(1);
|
||||||
@ -548,7 +544,6 @@ make_pending(struct mdoc_node *broken, enum mdoct tok,
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rew_sub(enum mdoc_type t, struct mdoc *mdoc,
|
rew_sub(enum mdoc_type t, struct mdoc *mdoc,
|
||||||
enum mdoct tok, int line, int ppos)
|
enum mdoct tok, int line, int ppos)
|
||||||
@ -558,31 +553,33 @@ rew_sub(enum mdoc_type t, struct mdoc *mdoc,
|
|||||||
n = mdoc->last;
|
n = mdoc->last;
|
||||||
while (n) {
|
while (n) {
|
||||||
switch (rew_dohalt(tok, t, n)) {
|
switch (rew_dohalt(tok, t, n)) {
|
||||||
case (REWIND_NONE):
|
case REWIND_NONE:
|
||||||
return(1);
|
return(1);
|
||||||
case (REWIND_THIS):
|
case REWIND_THIS:
|
||||||
n->lastline = line -
|
n->lastline = line -
|
||||||
(MDOC_NEWLINE & mdoc->flags &&
|
(MDOC_NEWLINE & mdoc->flags &&
|
||||||
! (MDOC_EXPLICIT & mdoc_macros[tok].flags));
|
! (MDOC_EXPLICIT & mdoc_macros[tok].flags));
|
||||||
break;
|
break;
|
||||||
case (REWIND_FORCE):
|
case REWIND_FORCE:
|
||||||
mandoc_vmsg(MANDOCERR_SCOPEBROKEN, mdoc->parse,
|
mandoc_vmsg(MANDOCERR_BLK_BROKEN, mdoc->parse,
|
||||||
line, ppos, "%s breaks %s",
|
line, ppos, "%s breaks %s",
|
||||||
mdoc_macronames[tok],
|
mdoc_macronames[tok],
|
||||||
mdoc_macronames[n->tok]);
|
mdoc_macronames[n->tok]);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (REWIND_MORE):
|
case REWIND_MORE:
|
||||||
n->lastline = line -
|
n->lastline = line -
|
||||||
(MDOC_NEWLINE & mdoc->flags ? 1 : 0);
|
(MDOC_NEWLINE & mdoc->flags ? 1 : 0);
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
continue;
|
continue;
|
||||||
case (REWIND_LATER):
|
case REWIND_LATER:
|
||||||
if (make_pending(n, tok, mdoc, line, ppos) ||
|
if (make_pending(n, tok, mdoc, line, ppos) ||
|
||||||
MDOC_BLOCK != t)
|
MDOC_BLOCK != t)
|
||||||
return(1);
|
return(1);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (REWIND_ERROR):
|
case REWIND_ERROR:
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_NOSCOPE);
|
mandoc_msg(MANDOCERR_BLK_NOTOPEN,
|
||||||
|
mdoc->parse, line, ppos,
|
||||||
|
mdoc_macronames[tok]);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -683,14 +680,13 @@ append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
|
|||||||
* knowing which symbols break this behaviour, for
|
* knowing which symbols break this behaviour, for
|
||||||
* example, `. ;' shouldn't propagate the double-space.
|
* example, `. ;' shouldn't propagate the double-space.
|
||||||
*/
|
*/
|
||||||
if (mandoc_eos(p, strlen(p), 0))
|
if (mandoc_eos(p, strlen(p)))
|
||||||
mdoc->last->flags |= MDOC_EOS;
|
mdoc->last->flags |= MDOC_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close out block partial/full explicit.
|
* Close out block partial/full explicit.
|
||||||
*/
|
*/
|
||||||
@ -709,10 +705,10 @@ blk_exp_close(MACRO_PROT_ARGS)
|
|||||||
nl = MDOC_NEWLINE & mdoc->flags;
|
nl = MDOC_NEWLINE & mdoc->flags;
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_Ec):
|
case MDOC_Ec:
|
||||||
maxargs = 1;
|
maxargs = 1;
|
||||||
break;
|
break;
|
||||||
case (MDOC_Ek):
|
case MDOC_Ek:
|
||||||
mdoc->flags &= ~MDOC_KEEP;
|
mdoc->flags &= ~MDOC_KEEP;
|
||||||
default:
|
default:
|
||||||
maxargs = 0;
|
maxargs = 0;
|
||||||
@ -778,11 +774,12 @@ blk_exp_close(MACRO_PROT_ARGS)
|
|||||||
later = n;
|
later = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
|
if ( ! (MDOC_PARSED & mdoc_macros[tok].flags)) {
|
||||||
/* FIXME: do this in validate */
|
if ('\0' != buf[*pos])
|
||||||
if (buf[*pos])
|
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_ARGSLOST);
|
mdoc->parse, line, ppos,
|
||||||
|
"%s %s", mdoc_macronames[tok],
|
||||||
|
buf + *pos);
|
||||||
if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
|
if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
|
||||||
return(0);
|
return(0);
|
||||||
return(rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos));
|
return(rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos));
|
||||||
@ -843,7 +840,6 @@ blk_exp_close(MACRO_PROT_ARGS)
|
|||||||
return(append_delims(mdoc, line, pos, buf));
|
return(append_delims(mdoc, line, pos, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
in_line(MACRO_PROT_ARGS)
|
in_line(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -863,17 +859,17 @@ in_line(MACRO_PROT_ARGS)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_An):
|
case MDOC_An:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Ar):
|
case MDOC_Ar:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Fl):
|
case MDOC_Fl:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Mt):
|
case MDOC_Mt:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Nm):
|
case MDOC_Nm:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Pa):
|
case MDOC_Pa:
|
||||||
nc = 1;
|
nc = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -922,15 +918,16 @@ in_line(MACRO_PROT_ARGS)
|
|||||||
if (scope && ! rew_elem(mdoc, tok))
|
if (scope && ! rew_elem(mdoc, tok))
|
||||||
return(0);
|
return(0);
|
||||||
if (nc && 0 == cnt) {
|
if (nc && 0 == cnt) {
|
||||||
if ( ! mdoc_elem_alloc(mdoc, line,
|
if ( ! mdoc_elem_alloc(mdoc,
|
||||||
ppos, tok, arg))
|
line, ppos, tok, arg))
|
||||||
return(0);
|
return(0);
|
||||||
if ( ! rew_last(mdoc, mdoc->last))
|
if ( ! rew_last(mdoc, mdoc->last))
|
||||||
return(0);
|
return(0);
|
||||||
} else if ( ! nc && 0 == cnt) {
|
} else if ( ! nc && 0 == cnt) {
|
||||||
mdoc_argv_free(arg);
|
mdoc_argv_free(arg);
|
||||||
mdoc_pmsg(mdoc, line, ppos,
|
mandoc_msg(MANDOCERR_MACRO_EMPTY,
|
||||||
MANDOCERR_MACROEMPTY);
|
mdoc->parse, line, ppos,
|
||||||
|
mdoc_macronames[tok]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
|
if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
|
||||||
@ -959,8 +956,8 @@ in_line(MACRO_PROT_ARGS)
|
|||||||
*/
|
*/
|
||||||
if (0 == cnt && (nc || MDOC_Li == tok) &&
|
if (0 == cnt && (nc || MDOC_Li == tok) &&
|
||||||
DELIM_CLOSE == d && ! scope) {
|
DELIM_CLOSE == d && ! scope) {
|
||||||
if ( ! mdoc_elem_alloc(mdoc, line,
|
if ( ! mdoc_elem_alloc(mdoc,
|
||||||
ppos, tok, arg))
|
line, ppos, tok, arg))
|
||||||
return(0);
|
return(0);
|
||||||
if (MDOC_Ar == tok || MDOC_Li == tok ||
|
if (MDOC_Ar == tok || MDOC_Li == tok ||
|
||||||
MDOC_Fl == tok)
|
MDOC_Fl == tok)
|
||||||
@ -1015,7 +1012,8 @@ in_line(MACRO_PROT_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
} else if ( ! nc && 0 == cnt) {
|
} else if ( ! nc && 0 == cnt) {
|
||||||
mdoc_argv_free(arg);
|
mdoc_argv_free(arg);
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROEMPTY);
|
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||||
|
line, ppos, mdoc_macronames[tok]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! nl)
|
if ( ! nl)
|
||||||
@ -1023,7 +1021,6 @@ in_line(MACRO_PROT_ARGS)
|
|||||||
return(append_delims(mdoc, line, pos, buf));
|
return(append_delims(mdoc, line, pos, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
blk_full(MACRO_PROT_ARGS)
|
blk_full(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1040,6 +1037,22 @@ blk_full(MACRO_PROT_ARGS)
|
|||||||
|
|
||||||
nl = MDOC_NEWLINE & mdoc->flags;
|
nl = MDOC_NEWLINE & mdoc->flags;
|
||||||
|
|
||||||
|
/* Skip items outside lists. */
|
||||||
|
|
||||||
|
if (tok == MDOC_It) {
|
||||||
|
for (n = mdoc->last; n; n = n->parent)
|
||||||
|
if (n->tok == MDOC_Bl)
|
||||||
|
break;
|
||||||
|
if (n == NULL) {
|
||||||
|
mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
|
||||||
|
line, ppos, "It %s", buf + *pos);
|
||||||
|
if ( ! mdoc_elem_alloc(mdoc, line, ppos,
|
||||||
|
MDOC_br, NULL))
|
||||||
|
return(0);
|
||||||
|
return(rew_elem(mdoc, MDOC_br));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Close out prior implicit scope. */
|
/* Close out prior implicit scope. */
|
||||||
|
|
||||||
if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
|
if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
|
||||||
@ -1264,7 +1277,6 @@ blk_full(MACRO_PROT_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
blk_part_imp(MACRO_PROT_ARGS)
|
blk_part_imp(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1349,25 +1361,6 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||||||
body = mdoc->last;
|
body = mdoc->last;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = body->child; n && n->next; n = n->next)
|
|
||||||
/* Do nothing. */ ;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* End of sentence spacing: if the last node is a text node and
|
|
||||||
* has a trailing period, then mark it as being end-of-sentence.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (n && MDOC_TEXT == n->type && n->string)
|
|
||||||
if (mandoc_eos(n->string, strlen(n->string), 1))
|
|
||||||
n->flags |= MDOC_EOS;
|
|
||||||
|
|
||||||
/* Up-propagate the end-of-space flag. */
|
|
||||||
|
|
||||||
if (n && (MDOC_EOS & n->flags)) {
|
|
||||||
body->flags |= MDOC_EOS;
|
|
||||||
body->parent->flags |= MDOC_EOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is an open sub-block requiring explicit close-out,
|
* If there is an open sub-block requiring explicit close-out,
|
||||||
* postpone closing out the current block
|
* postpone closing out the current block
|
||||||
@ -1385,18 +1378,9 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(n == body);
|
||||||
|
|
||||||
/*
|
if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
|
||||||
* If we can't rewind to our body, then our scope has already
|
|
||||||
* been closed by another macro (like `Oc' closing `Op'). This
|
|
||||||
* is ugly behaviour nodding its head to OpenBSD's overwhelming
|
|
||||||
* crufty use of `Op' breakage.
|
|
||||||
*/
|
|
||||||
if (n != body)
|
|
||||||
mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos,
|
|
||||||
"%s broken", mdoc_macronames[tok]);
|
|
||||||
|
|
||||||
if (n && ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
/* Standard appending of delimiters. */
|
/* Standard appending of delimiters. */
|
||||||
@ -1406,7 +1390,7 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||||||
|
|
||||||
/* Rewind scope, if applicable. */
|
/* Rewind scope, if applicable. */
|
||||||
|
|
||||||
if (n && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
|
if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
/* Move trailing .Ns out of scope. */
|
/* Move trailing .Ns out of scope. */
|
||||||
@ -1419,7 +1403,6 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
blk_part_exp(MACRO_PROT_ARGS)
|
blk_part_exp(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1527,8 +1510,6 @@ blk_part_exp(MACRO_PROT_ARGS)
|
|||||||
return(append_delims(mdoc, line, pos, buf));
|
return(append_delims(mdoc, line, pos, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
in_line_argn(MACRO_PROT_ARGS)
|
in_line_argn(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1550,18 +1531,20 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case (MDOC_Ap):
|
case MDOC_Ap:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_No):
|
case MDOC_No:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Ns):
|
case MDOC_Ns:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Ux):
|
case MDOC_Ux:
|
||||||
maxargs = 0;
|
maxargs = 0;
|
||||||
break;
|
break;
|
||||||
case (MDOC_Bx):
|
case MDOC_Bx:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Xr):
|
case MDOC_Es:
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case MDOC_Xr:
|
||||||
maxargs = 2;
|
maxargs = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1605,7 +1588,7 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
continue;
|
continue;
|
||||||
} else if (0 == j)
|
} else if (0 == j)
|
||||||
if ( ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
|
if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if (j == maxargs && ! flushed) {
|
if (j == maxargs && ! flushed) {
|
||||||
@ -1641,7 +1624,7 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == j && ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
|
if (0 == j && ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
/* Close out in a consistent state. */
|
/* Close out in a consistent state. */
|
||||||
@ -1653,7 +1636,6 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||||||
return(append_delims(mdoc, line, pos, buf));
|
return(append_delims(mdoc, line, pos, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
in_line_eoln(MACRO_PROT_ARGS)
|
in_line_eoln(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1723,8 +1705,6 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||||||
return(rew_elem(mdoc, tok));
|
return(rew_elem(mdoc, tok));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
ctx_synopsis(MACRO_PROT_ARGS)
|
ctx_synopsis(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1751,17 +1731,6 @@ ctx_synopsis(MACRO_PROT_ARGS)
|
|||||||
return(blk_part_imp(mdoc, tok, line, ppos, pos, buf));
|
return(blk_part_imp(mdoc, tok, line, ppos, pos, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
|
||||||
obsolete(MACRO_PROT_ARGS)
|
|
||||||
{
|
|
||||||
|
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROOBS);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
|
* Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
|
||||||
* They're unusual because they're basically free-form text until a
|
* They're unusual because they're basically free-form text until a
|
||||||
@ -1801,8 +1770,6 @@ phrase(struct mdoc *mdoc, int line, int ppos, char *buf)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static int
|
static int
|
||||||
phrase_ta(MACRO_PROT_ARGS)
|
phrase_ta(MACRO_PROT_ARGS)
|
||||||
{
|
{
|
||||||
@ -1817,7 +1784,8 @@ phrase_ta(MACRO_PROT_ARGS)
|
|||||||
while (NULL != n && MDOC_Bl != n->tok)
|
while (NULL != n && MDOC_Bl != n->tok)
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
if (NULL == n || LIST_column != n->norm->Bl.type) {
|
if (NULL == n || LIST_column != n->norm->Bl.type) {
|
||||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_STRAYTA);
|
mandoc_msg(MANDOCERR_TA_STRAY, mdoc->parse,
|
||||||
|
line, ppos, "Ta");
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* $Id: mdoc_man.c,v 1.57 2013/12/25 22:00:45 schwarze Exp $ */
|
/* $Id: mdoc_man.c,v 1.68 2014/08/06 15:09:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -23,6 +23,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
@ -50,6 +51,7 @@ static void post_bf(DECL_ARGS);
|
|||||||
static void post_bk(DECL_ARGS);
|
static void post_bk(DECL_ARGS);
|
||||||
static void post_bl(DECL_ARGS);
|
static void post_bl(DECL_ARGS);
|
||||||
static void post_dl(DECL_ARGS);
|
static void post_dl(DECL_ARGS);
|
||||||
|
static void post_en(DECL_ARGS);
|
||||||
static void post_enc(DECL_ARGS);
|
static void post_enc(DECL_ARGS);
|
||||||
static void post_eo(DECL_ARGS);
|
static void post_eo(DECL_ARGS);
|
||||||
static void post_fa(DECL_ARGS);
|
static void post_fa(DECL_ARGS);
|
||||||
@ -77,8 +79,11 @@ static int pre_bl(DECL_ARGS);
|
|||||||
static int pre_br(DECL_ARGS);
|
static int pre_br(DECL_ARGS);
|
||||||
static int pre_bx(DECL_ARGS);
|
static int pre_bx(DECL_ARGS);
|
||||||
static int pre_dl(DECL_ARGS);
|
static int pre_dl(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_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);
|
||||||
static int pre_fl(DECL_ARGS);
|
static int pre_fl(DECL_ARGS);
|
||||||
@ -89,11 +94,13 @@ static int pre_in(DECL_ARGS);
|
|||||||
static int pre_it(DECL_ARGS);
|
static int pre_it(DECL_ARGS);
|
||||||
static int pre_lk(DECL_ARGS);
|
static int pre_lk(DECL_ARGS);
|
||||||
static int pre_li(DECL_ARGS);
|
static int pre_li(DECL_ARGS);
|
||||||
|
static int pre_ll(DECL_ARGS);
|
||||||
static int pre_nm(DECL_ARGS);
|
static int pre_nm(DECL_ARGS);
|
||||||
static int pre_no(DECL_ARGS);
|
static int pre_no(DECL_ARGS);
|
||||||
static int pre_ns(DECL_ARGS);
|
static int pre_ns(DECL_ARGS);
|
||||||
static int pre_pp(DECL_ARGS);
|
static int pre_pp(DECL_ARGS);
|
||||||
static int pre_rs(DECL_ARGS);
|
static int pre_rs(DECL_ARGS);
|
||||||
|
static int pre_rv(DECL_ARGS);
|
||||||
static int pre_sm(DECL_ARGS);
|
static int pre_sm(DECL_ARGS);
|
||||||
static int pre_sp(DECL_ARGS);
|
static int pre_sp(DECL_ARGS);
|
||||||
static int pre_sect(DECL_ARGS);
|
static int pre_sect(DECL_ARGS);
|
||||||
@ -134,9 +141,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
|||||||
{ NULL, pre_li, post_font, NULL, NULL }, /* Dv */
|
{ NULL, pre_li, post_font, NULL, NULL }, /* Dv */
|
||||||
{ NULL, pre_li, post_font, NULL, NULL }, /* Er */
|
{ NULL, pre_li, post_font, NULL, NULL }, /* Er */
|
||||||
{ NULL, pre_li, post_font, NULL, NULL }, /* Ev */
|
{ NULL, pre_li, post_font, NULL, NULL }, /* Ev */
|
||||||
{ NULL, pre_enc, post_enc, "The \\fB",
|
{ NULL, pre_ex, NULL, NULL, NULL }, /* Ex */
|
||||||
"\\fP\nutility exits 0 on success, and >0 if an error occurs."
|
|
||||||
}, /* Ex */
|
|
||||||
{ NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */
|
{ NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */
|
||||||
{ NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */
|
{ NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */
|
||||||
{ NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */
|
{ NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */
|
||||||
@ -148,13 +153,9 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
|||||||
{ cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
|
{ cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
|
||||||
{ NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
|
{ NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
|
||||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
|
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ot */
|
{ NULL, pre_ft, post_font, NULL, NULL }, /* Ot */
|
||||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Pa */
|
{ NULL, pre_em, post_font, NULL, NULL }, /* Pa */
|
||||||
{ NULL, pre_enc, post_enc, "The \\fB",
|
{ NULL, pre_rv, NULL, NULL, NULL }, /* Rv */
|
||||||
"\\fP\nfunction returns the value 0 if successful;\n"
|
|
||||||
"otherwise the value -1 is returned and the global\n"
|
|
||||||
"variable \\fIerrno\\fP is set to indicate the error."
|
|
||||||
}, /* Rv */
|
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* St */
|
{ NULL, NULL, NULL, NULL, NULL }, /* St */
|
||||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Va */
|
{ NULL, pre_em, post_font, NULL, NULL }, /* Va */
|
||||||
{ NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
|
{ NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
|
||||||
@ -222,7 +223,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
|||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ek */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Ek */
|
||||||
{ NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
|
{ NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Hf */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Hf */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Fr */
|
{ NULL, pre_em, post_font, NULL, NULL }, /* Fr */
|
||||||
{ NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
|
{ NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
|
||||||
{ NULL, NULL, post_lb, NULL, NULL }, /* Lb */
|
{ NULL, NULL, post_lb, NULL, NULL }, /* Lb */
|
||||||
{ NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
|
{ NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
|
||||||
@ -232,14 +233,15 @@ 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, NULL, NULL, NULL, NULL }, /* Es */
|
{ NULL, pre_es, NULL, NULL, NULL }, /* Es */
|
||||||
{ NULL, NULL, NULL, 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 */
|
||||||
{ NULL, pre_br, NULL, NULL, NULL }, /* br */
|
{ NULL, pre_br, NULL, NULL, NULL }, /* br */
|
||||||
{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
|
{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
|
||||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
|
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
|
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
|
||||||
|
{ NULL, pre_ll, post_sp, NULL, NULL }, /* ll */
|
||||||
{ NULL, NULL, NULL, NULL, NULL }, /* ROOT */
|
{ NULL, NULL, NULL, NULL, NULL }, /* ROOT */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -271,6 +273,7 @@ static struct {
|
|||||||
size_t size;
|
size_t size;
|
||||||
} fontqueue;
|
} fontqueue;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
font_push(char newfont)
|
font_push(char newfont)
|
||||||
{
|
{
|
||||||
@ -359,13 +362,16 @@ print_word(const char *s)
|
|||||||
|
|
||||||
for ( ; *s; s++) {
|
for ( ; *s; s++) {
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case (ASCII_NBRSP):
|
case ASCII_NBRSP:
|
||||||
printf("\\ ");
|
printf("\\ ");
|
||||||
break;
|
break;
|
||||||
case (ASCII_HYPH):
|
case ASCII_HYPH:
|
||||||
putchar('-');
|
putchar('-');
|
||||||
break;
|
break;
|
||||||
case (' '):
|
case ASCII_BREAK:
|
||||||
|
printf("\\:");
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
if (MMAN_nbrword & outflags) {
|
if (MMAN_nbrword & outflags) {
|
||||||
printf("\\ ");
|
printf("\\ ");
|
||||||
break;
|
break;
|
||||||
@ -450,7 +456,7 @@ print_offs(const char *v)
|
|||||||
if (Bl_stack_len)
|
if (Bl_stack_len)
|
||||||
sz += Bl_stack[Bl_stack_len - 1];
|
sz += Bl_stack[Bl_stack_len - 1];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%zun", sz);
|
(void)snprintf(buf, sizeof(buf), "%zun", sz);
|
||||||
print_word(buf);
|
print_word(buf);
|
||||||
outflags |= MMAN_nl;
|
outflags |= MMAN_nl;
|
||||||
}
|
}
|
||||||
@ -458,7 +464,7 @@ print_offs(const char *v)
|
|||||||
/*
|
/*
|
||||||
* Set up the indentation for a list item; used from pre_it().
|
* Set up the indentation for a list item; used from pre_it().
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
print_width(const char *v, const struct mdoc_node *child, size_t defsz)
|
print_width(const char *v, const struct mdoc_node *child, size_t defsz)
|
||||||
{
|
{
|
||||||
char buf[24];
|
char buf[24];
|
||||||
@ -503,19 +509,19 @@ print_width(const char *v, const struct mdoc_node *child, size_t defsz)
|
|||||||
remain = sz + 2;
|
remain = sz + 2;
|
||||||
}
|
}
|
||||||
if (numeric) {
|
if (numeric) {
|
||||||
snprintf(buf, sizeof(buf), "%zun", sz + 2);
|
(void)snprintf(buf, sizeof(buf), "%zun", sz + 2);
|
||||||
print_word(buf);
|
print_word(buf);
|
||||||
} else
|
} else
|
||||||
print_word(v);
|
print_word(v);
|
||||||
TPremain = remain;
|
TPremain = remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
print_count(int *count)
|
print_count(int *count)
|
||||||
{
|
{
|
||||||
char buf[12];
|
char buf[24];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%d.", ++*count);
|
(void)snprintf(buf, sizeof(buf), "%d.", ++*count);
|
||||||
print_word(buf);
|
print_word(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,8 +548,9 @@ man_mdoc(void *arg, const struct mdoc *mdoc)
|
|||||||
n = mdoc_node(mdoc);
|
n = mdoc_node(mdoc);
|
||||||
|
|
||||||
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
|
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
|
||||||
meta->title, meta->msec, meta->date,
|
meta->title,
|
||||||
meta->os, meta->vol);
|
(meta->msec == NULL ? "" : meta->msec),
|
||||||
|
meta->date, meta->os, meta->vol);
|
||||||
|
|
||||||
/* Disable hyphenation and if nroff, disable justification. */
|
/* Disable hyphenation and if nroff, disable justification. */
|
||||||
printf(".nh\n.if n .ad l");
|
printf(".nh\n.if n .ad l");
|
||||||
@ -581,8 +588,8 @@ print_node(DECL_ARGS)
|
|||||||
* Make sure that we don't happen to start with a
|
* Make sure that we don't happen to start with a
|
||||||
* control character at the start of a line.
|
* control character at the start of a line.
|
||||||
*/
|
*/
|
||||||
if (MMAN_nl & outflags && ('.' == *n->string ||
|
if (MMAN_nl & outflags &&
|
||||||
'\'' == *n->string)) {
|
('.' == *n->string || '\'' == *n->string)) {
|
||||||
print_word("");
|
print_word("");
|
||||||
printf("\\&");
|
printf("\\&");
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
@ -595,7 +602,7 @@ print_node(DECL_ARGS)
|
|||||||
*/
|
*/
|
||||||
act = manacts + n->tok;
|
act = manacts + n->tok;
|
||||||
cond = NULL == act->cond || (*act->cond)(meta, n);
|
cond = NULL == act->cond || (*act->cond)(meta, n);
|
||||||
if (cond && act->pre)
|
if (cond && act->pre && ENDBODY_NOT == n->end)
|
||||||
do_sub = (*act->pre)(meta, n);
|
do_sub = (*act->pre)(meta, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,8 +618,17 @@ print_node(DECL_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Lastly, conditionally run the post-node handler.
|
* Lastly, conditionally run the post-node handler.
|
||||||
*/
|
*/
|
||||||
|
if (MDOC_ENDED & n->flags)
|
||||||
|
return;
|
||||||
|
|
||||||
if (cond && act->post)
|
if (cond && act->post)
|
||||||
(*act->post)(meta, n);
|
(*act->post)(meta, n);
|
||||||
|
|
||||||
|
if (ENDBODY_NOT != n->end)
|
||||||
|
n->pending->flags |= MDOC_ENDED;
|
||||||
|
|
||||||
|
if (ENDBODY_NOSPACE == n->end)
|
||||||
|
outflags &= ~(MMAN_spc | MMAN_nl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -650,10 +666,46 @@ post_enc(DECL_ARGS)
|
|||||||
suffix = manacts[n->tok].suffix;
|
suffix = manacts[n->tok].suffix;
|
||||||
if (NULL == suffix)
|
if (NULL == suffix)
|
||||||
return;
|
return;
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~(MMAN_spc | MMAN_nl);
|
||||||
print_word(suffix);
|
print_word(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_ex(DECL_ARGS)
|
||||||
|
{
|
||||||
|
int nchild;
|
||||||
|
|
||||||
|
outflags |= MMAN_br | MMAN_nl;
|
||||||
|
|
||||||
|
print_word("The");
|
||||||
|
|
||||||
|
nchild = n->nchild;
|
||||||
|
for (n = n->child; n; n = n->next) {
|
||||||
|
font_push('B');
|
||||||
|
print_word(n->string);
|
||||||
|
font_pop();
|
||||||
|
|
||||||
|
if (n->next == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nchild > 2) {
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
|
print_word(",");
|
||||||
|
}
|
||||||
|
if (n->next->next == NULL)
|
||||||
|
print_word("and");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nchild > 1)
|
||||||
|
print_word("utilities exit\\~0");
|
||||||
|
else
|
||||||
|
print_word("utility exits\\~0");
|
||||||
|
|
||||||
|
print_word("on success, and\\~>0 if an error occurs.");
|
||||||
|
outflags |= MMAN_nl;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
post_font(DECL_ARGS)
|
post_font(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -757,18 +809,18 @@ pre_syn(const struct mdoc_node *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (n->prev->tok) {
|
switch (n->prev->tok) {
|
||||||
case (MDOC_Fd):
|
case MDOC_Fd:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Fn):
|
case MDOC_Fn:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Fo):
|
case MDOC_Fo:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_In):
|
case MDOC_In:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_Vt):
|
case MDOC_Vt:
|
||||||
outflags |= MMAN_sp;
|
outflags |= MMAN_sp;
|
||||||
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) {
|
||||||
outflags |= MMAN_sp;
|
outflags |= MMAN_sp;
|
||||||
break;
|
break;
|
||||||
@ -785,11 +837,11 @@ pre_an(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->norm->An.auth) {
|
switch (n->norm->An.auth) {
|
||||||
case (AUTH_split):
|
case AUTH_split:
|
||||||
outflags &= ~MMAN_An_nosplit;
|
outflags &= ~MMAN_An_nosplit;
|
||||||
outflags |= MMAN_An_split;
|
outflags |= MMAN_An_split;
|
||||||
return(0);
|
return(0);
|
||||||
case (AUTH_nosplit):
|
case AUTH_nosplit:
|
||||||
outflags &= ~MMAN_An_split;
|
outflags &= ~MMAN_An_split;
|
||||||
outflags |= MMAN_An_nosplit;
|
outflags |= MMAN_An_nosplit;
|
||||||
return(0);
|
return(0);
|
||||||
@ -848,18 +900,18 @@ pre_bf(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_BLOCK):
|
case MDOC_BLOCK:
|
||||||
return(1);
|
return(1);
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
switch (n->norm->Bf.font) {
|
switch (n->norm->Bf.font) {
|
||||||
case (FONT_Em):
|
case FONT_Em:
|
||||||
font_push('I');
|
font_push('I');
|
||||||
break;
|
break;
|
||||||
case (FONT_Sy):
|
case FONT_Sy:
|
||||||
font_push('B');
|
font_push('B');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -882,9 +934,9 @@ pre_bk(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_BLOCK):
|
case MDOC_BLOCK:
|
||||||
return(1);
|
return(1);
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
outflags |= MMAN_Bk;
|
outflags |= MMAN_Bk;
|
||||||
return(1);
|
return(1);
|
||||||
default:
|
default:
|
||||||
@ -916,10 +968,10 @@ pre_bl(DECL_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (n->norm->Bl.type) {
|
switch (n->norm->Bl.type) {
|
||||||
case (LIST_enum):
|
case LIST_enum:
|
||||||
n->norm->Bl.count = 0;
|
n->norm->Bl.count = 0;
|
||||||
return(1);
|
return(1);
|
||||||
case (LIST_column):
|
case LIST_column:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(1);
|
return(1);
|
||||||
@ -938,10 +990,10 @@ post_bl(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->norm->Bl.type) {
|
switch (n->norm->Bl.type) {
|
||||||
case (LIST_column):
|
case LIST_column:
|
||||||
print_line(".TE", 0);
|
print_line(".TE", 0);
|
||||||
break;
|
break;
|
||||||
case (LIST_enum):
|
case LIST_enum:
|
||||||
n->norm->Bl.count = 0;
|
n->norm->Bl.count = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1019,6 +1071,33 @@ pre_em(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_en(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (NULL == n->norm->Es ||
|
||||||
|
NULL == n->norm->Es->child)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
print_word(n->norm->Es->child->string);
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_en(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (NULL == n->norm->Es ||
|
||||||
|
NULL == n->norm->Es->child ||
|
||||||
|
NULL == n->norm->Es->child->next)
|
||||||
|
return;
|
||||||
|
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
|
print_word(n->norm->Es->child->next->string);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
post_eo(DECL_ARGS)
|
post_eo(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -1027,6 +1106,13 @@ post_eo(DECL_ARGS)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
@ -1136,15 +1222,15 @@ pre_fo(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_BLOCK):
|
case MDOC_BLOCK:
|
||||||
pre_syn(n);
|
pre_syn(n);
|
||||||
break;
|
break;
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
if (MDOC_SYNPRETTY & n->flags)
|
if (MDOC_SYNPRETTY & n->flags)
|
||||||
print_block(".HP 4n", MMAN_nl);
|
print_block(".HP 4n", MMAN_nl);
|
||||||
font_push('B');
|
font_push('B');
|
||||||
break;
|
break;
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
print_word("(");
|
print_word("(");
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
@ -1160,10 +1246,10 @@ post_fo(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
font_pop();
|
font_pop();
|
||||||
break;
|
break;
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
post_fn(meta, n);
|
post_fn(meta, n);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1219,7 +1305,7 @@ pre_it(DECL_ARGS)
|
|||||||
const struct mdoc_node *bln;
|
const struct mdoc_node *bln;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
outflags |= MMAN_PP | MMAN_nl;
|
outflags |= MMAN_PP | MMAN_nl;
|
||||||
bln = n->parent->parent;
|
bln = n->parent->parent;
|
||||||
if (0 == bln->norm->Bl.comp ||
|
if (0 == bln->norm->Bl.comp ||
|
||||||
@ -1228,24 +1314,24 @@ pre_it(DECL_ARGS)
|
|||||||
outflags |= MMAN_sp;
|
outflags |= MMAN_sp;
|
||||||
outflags &= ~MMAN_br;
|
outflags &= ~MMAN_br;
|
||||||
switch (bln->norm->Bl.type) {
|
switch (bln->norm->Bl.type) {
|
||||||
case (LIST_item):
|
case LIST_item:
|
||||||
return(0);
|
return(0);
|
||||||
case (LIST_inset):
|
case LIST_inset:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_diag):
|
case LIST_diag:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_ohang):
|
case LIST_ohang:
|
||||||
if (bln->norm->Bl.type == LIST_diag)
|
if (bln->norm->Bl.type == LIST_diag)
|
||||||
print_line(".B \"", 0);
|
print_line(".B \"", 0);
|
||||||
else
|
else
|
||||||
print_line(".R \"", 0);
|
print_line(".R \"", 0);
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
return(1);
|
return(1);
|
||||||
case (LIST_bullet):
|
case LIST_bullet:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_dash):
|
case LIST_dash:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_hyphen):
|
case LIST_hyphen:
|
||||||
print_width(bln->norm->Bl.width, NULL, 0);
|
print_width(bln->norm->Bl.width, NULL, 0);
|
||||||
TPremain = 0;
|
TPremain = 0;
|
||||||
outflags |= MMAN_nl;
|
outflags |= MMAN_nl;
|
||||||
@ -1255,18 +1341,21 @@ pre_it(DECL_ARGS)
|
|||||||
else
|
else
|
||||||
print_word("-");
|
print_word("-");
|
||||||
font_pop();
|
font_pop();
|
||||||
break;
|
outflags |= MMAN_nl;
|
||||||
case (LIST_enum):
|
return(0);
|
||||||
|
case LIST_enum:
|
||||||
print_width(bln->norm->Bl.width, NULL, 0);
|
print_width(bln->norm->Bl.width, NULL, 0);
|
||||||
TPremain = 0;
|
TPremain = 0;
|
||||||
outflags |= MMAN_nl;
|
outflags |= MMAN_nl;
|
||||||
print_count(&bln->norm->Bl.count);
|
print_count(&bln->norm->Bl.count);
|
||||||
break;
|
outflags |= MMAN_nl;
|
||||||
case (LIST_hang):
|
return(0);
|
||||||
|
case LIST_hang:
|
||||||
print_width(bln->norm->Bl.width, n->child, 6);
|
print_width(bln->norm->Bl.width, n->child, 6);
|
||||||
TPremain = 0;
|
TPremain = 0;
|
||||||
break;
|
outflags |= MMAN_nl;
|
||||||
case (LIST_tag):
|
return(1);
|
||||||
|
case LIST_tag:
|
||||||
print_width(bln->norm->Bl.width, n->child, 0);
|
print_width(bln->norm->Bl.width, n->child, 0);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
@ -1274,7 +1363,6 @@ pre_it(DECL_ARGS)
|
|||||||
default:
|
default:
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
outflags |= MMAN_nl;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1300,7 +1388,8 @@ mid_it(void)
|
|||||||
|
|
||||||
/* Restore the indentation of the enclosing list. */
|
/* Restore the indentation of the enclosing list. */
|
||||||
print_line(".RS", MMAN_Bk_susp);
|
print_line(".RS", MMAN_Bk_susp);
|
||||||
snprintf(buf, sizeof(buf), "%zun", Bl_stack[Bl_stack_len - 1]);
|
(void)snprintf(buf, sizeof(buf), "%zun",
|
||||||
|
Bl_stack[Bl_stack_len - 1]);
|
||||||
print_word(buf);
|
print_word(buf);
|
||||||
|
|
||||||
/* Remeber to close out this .RS block later. */
|
/* Remeber to close out this .RS block later. */
|
||||||
@ -1315,32 +1404,32 @@ post_it(DECL_ARGS)
|
|||||||
bln = n->parent->parent;
|
bln = n->parent->parent;
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
switch (bln->norm->Bl.type) {
|
switch (bln->norm->Bl.type) {
|
||||||
case (LIST_diag):
|
case LIST_diag:
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
print_word("\\ ");
|
print_word("\\ ");
|
||||||
break;
|
break;
|
||||||
case (LIST_ohang):
|
case LIST_ohang:
|
||||||
outflags |= MMAN_br;
|
outflags |= MMAN_br;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
switch (bln->norm->Bl.type) {
|
switch (bln->norm->Bl.type) {
|
||||||
case (LIST_bullet):
|
case LIST_bullet:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_dash):
|
case LIST_dash:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_hyphen):
|
case LIST_hyphen:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_enum):
|
case LIST_enum:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_hang):
|
case LIST_hang:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (LIST_tag):
|
case LIST_tag:
|
||||||
assert(Bl_stack_len);
|
assert(Bl_stack_len);
|
||||||
Bl_stack[--Bl_stack_len] = 0;
|
Bl_stack[--Bl_stack_len] = 0;
|
||||||
|
|
||||||
@ -1354,7 +1443,7 @@ post_it(DECL_ARGS)
|
|||||||
Bl_stack_post[Bl_stack_len] = 0;
|
Bl_stack_post[Bl_stack_len] = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (LIST_column):
|
case LIST_column:
|
||||||
if (NULL != n->next) {
|
if (NULL != n->next) {
|
||||||
putchar('\t');
|
putchar('\t');
|
||||||
outflags &= ~MMAN_spc;
|
outflags &= ~MMAN_spc;
|
||||||
@ -1401,6 +1490,14 @@ pre_lk(DECL_ARGS)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_ll(DECL_ARGS)
|
||||||
|
{
|
||||||
|
|
||||||
|
print_line(".ll", 0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pre_li(DECL_ARGS)
|
pre_li(DECL_ARGS)
|
||||||
{
|
{
|
||||||
@ -1441,12 +1538,13 @@ post_nm(DECL_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_BLOCK):
|
case MDOC_BLOCK:
|
||||||
outflags &= ~MMAN_Bk;
|
outflags &= ~MMAN_Bk;
|
||||||
break;
|
break;
|
||||||
case (MDOC_HEAD):
|
case MDOC_HEAD:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (MDOC_ELEM):
|
case MDOC_ELEM:
|
||||||
|
if (n->child != NULL || meta->name != NULL)
|
||||||
font_pop();
|
font_pop();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1499,15 +1597,72 @@ pre_rs(DECL_ARGS)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pre_rv(DECL_ARGS)
|
||||||
|
{
|
||||||
|
int nchild;
|
||||||
|
|
||||||
|
outflags |= MMAN_br | MMAN_nl;
|
||||||
|
|
||||||
|
nchild = n->nchild;
|
||||||
|
if (nchild > 0) {
|
||||||
|
print_word("The");
|
||||||
|
|
||||||
|
for (n = n->child; n; n = n->next) {
|
||||||
|
font_push('B');
|
||||||
|
print_word(n->string);
|
||||||
|
font_pop();
|
||||||
|
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
|
print_word("()");
|
||||||
|
|
||||||
|
if (n->next == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nchild > 2) {
|
||||||
|
outflags &= ~MMAN_spc;
|
||||||
|
print_word(",");
|
||||||
|
}
|
||||||
|
if (n->next->next == NULL)
|
||||||
|
print_word("and");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nchild > 1)
|
||||||
|
print_word("functions return");
|
||||||
|
else
|
||||||
|
print_word("function returns");
|
||||||
|
|
||||||
|
print_word("the value\\~0 if successful;");
|
||||||
|
} else
|
||||||
|
print_word("Upon successful completion, "
|
||||||
|
"the value\\~0 is returned;");
|
||||||
|
|
||||||
|
print_word("otherwise the value\\~\\-1 is returned"
|
||||||
|
" and the global variable");
|
||||||
|
|
||||||
|
font_push('I');
|
||||||
|
print_word("errno");
|
||||||
|
font_pop();
|
||||||
|
|
||||||
|
print_word("is set to indicate the error.");
|
||||||
|
outflags |= MMAN_nl;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pre_sm(DECL_ARGS)
|
pre_sm(DECL_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(n->child && MDOC_TEXT == n->child->type);
|
if (NULL == n->child)
|
||||||
if (0 == strcmp("on", n->child->string))
|
outflags ^= MMAN_Sm;
|
||||||
outflags |= MMAN_Sm | MMAN_spc;
|
else if (0 == strcmp("on", n->child->string))
|
||||||
|
outflags |= MMAN_Sm;
|
||||||
else
|
else
|
||||||
outflags &= ~MMAN_Sm;
|
outflags &= ~MMAN_Sm;
|
||||||
|
|
||||||
|
if (MMAN_Sm & outflags)
|
||||||
|
outflags |= MMAN_spc;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1544,10 +1699,10 @@ pre_vt(DECL_ARGS)
|
|||||||
|
|
||||||
if (MDOC_SYNPRETTY & n->flags) {
|
if (MDOC_SYNPRETTY & n->flags) {
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case (MDOC_BLOCK):
|
case MDOC_BLOCK:
|
||||||
pre_syn(n);
|
pre_syn(n);
|
||||||
return(1);
|
return(1);
|
||||||
case (MDOC_BODY):
|
case MDOC_BODY:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(0);
|
return(0);
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
/* $Id: msec.c,v 1.10 2011/12/02 01:37:14 schwarze Exp $ */
|
/* $Id: msec.c,v 1.11 2014/03/23 11:25:26 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -18,7 +18,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: out.c,v 1.46 2013/10/05 20:30:05 schwarze Exp $ */
|
/* $Id: out.c,v 1.49 2014/08/01 19:25:52 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>
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ static void tblcalc_literal(struct rofftbl *, struct roffcol *,
|
|||||||
static void tblcalc_number(struct rofftbl *, struct roffcol *,
|
static void tblcalc_number(struct rofftbl *, struct roffcol *,
|
||||||
const struct tbl_opts *, const struct tbl_dat *);
|
const struct tbl_opts *, const struct tbl_dat *);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a `scaling unit' to a consistent form, or fail. Scaling
|
* Convert a `scaling unit' to a consistent form, or fail. Scaling
|
||||||
* units are documented in groff.7, mdoc.7, man.7.
|
* units are documented in groff.7, mdoc.7, man.7.
|
||||||
@ -55,10 +57,10 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||||||
i = hasd = 0;
|
i = hasd = 0;
|
||||||
|
|
||||||
switch (*src) {
|
switch (*src) {
|
||||||
case ('+'):
|
case '+':
|
||||||
src++;
|
src++;
|
||||||
break;
|
break;
|
||||||
case ('-'):
|
case '-':
|
||||||
buf[i++] = *src++;
|
buf[i++] = *src++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -86,39 +88,39 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
||||||
switch (*src) {
|
switch (*src) {
|
||||||
case ('c'):
|
case 'c':
|
||||||
unit = SCALE_CM;
|
unit = SCALE_CM;
|
||||||
break;
|
break;
|
||||||
case ('i'):
|
case 'i':
|
||||||
unit = SCALE_IN;
|
unit = SCALE_IN;
|
||||||
break;
|
break;
|
||||||
case ('P'):
|
case 'P':
|
||||||
unit = SCALE_PC;
|
unit = SCALE_PC;
|
||||||
break;
|
break;
|
||||||
case ('p'):
|
case 'p':
|
||||||
unit = SCALE_PT;
|
unit = SCALE_PT;
|
||||||
break;
|
break;
|
||||||
case ('f'):
|
case 'f':
|
||||||
unit = SCALE_FS;
|
unit = SCALE_FS;
|
||||||
break;
|
break;
|
||||||
case ('v'):
|
case 'v':
|
||||||
unit = SCALE_VS;
|
unit = SCALE_VS;
|
||||||
break;
|
break;
|
||||||
case ('m'):
|
case 'm':
|
||||||
unit = SCALE_EM;
|
unit = SCALE_EM;
|
||||||
break;
|
break;
|
||||||
case ('\0'):
|
case '\0':
|
||||||
if (SCALE_MAX == def)
|
if (SCALE_MAX == def)
|
||||||
return(0);
|
return(0);
|
||||||
unit = SCALE_BU;
|
unit = SCALE_BU;
|
||||||
break;
|
break;
|
||||||
case ('u'):
|
case 'u':
|
||||||
unit = SCALE_BU;
|
unit = SCALE_BU;
|
||||||
break;
|
break;
|
||||||
case ('M'):
|
case 'M':
|
||||||
unit = SCALE_MM;
|
unit = SCALE_MM;
|
||||||
break;
|
break;
|
||||||
case ('n'):
|
case 'n':
|
||||||
unit = SCALE_EN;
|
unit = SCALE_EN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -126,8 +128,8 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: do this in the caller. */
|
/* FIXME: do this in the caller. */
|
||||||
if ((dst->scale = atof(buf)) < 0)
|
if ((dst->scale = atof(buf)) < 0.0)
|
||||||
dst->scale = 0;
|
dst->scale = 0.0;
|
||||||
dst->unit = unit;
|
dst->unit = unit;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
@ -152,8 +154,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
assert(NULL == tbl->cols);
|
assert(NULL == tbl->cols);
|
||||||
tbl->cols = mandoc_calloc
|
tbl->cols = mandoc_calloc((size_t)sp->opts->cols,
|
||||||
((size_t)sp->opts->cols, sizeof(struct roffcol));
|
sizeof(struct roffcol));
|
||||||
|
|
||||||
for ( ; sp; sp = sp->next) {
|
for ( ; sp; sp = sp->next) {
|
||||||
if (TBL_SPAN_DATA != sp->pos)
|
if (TBL_SPAN_DATA != sp->pos)
|
||||||
@ -186,26 +188,26 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
|||||||
/* Branch down into data sub-types. */
|
/* Branch down into data sub-types. */
|
||||||
|
|
||||||
switch (dp->layout->pos) {
|
switch (dp->layout->pos) {
|
||||||
case (TBL_CELL_HORIZ):
|
case TBL_CELL_HORIZ:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_DHORIZ):
|
case TBL_CELL_DHORIZ:
|
||||||
sz = (*tbl->len)(1, tbl->arg);
|
sz = (*tbl->len)(1, tbl->arg);
|
||||||
if (col->width < sz)
|
if (col->width < sz)
|
||||||
col->width = sz;
|
col->width = sz;
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_LONG):
|
case TBL_CELL_LONG:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_CENTRE):
|
case TBL_CELL_CENTRE:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_LEFT):
|
case TBL_CELL_LEFT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_RIGHT):
|
case TBL_CELL_RIGHT:
|
||||||
tblcalc_literal(tbl, col, dp);
|
tblcalc_literal(tbl, col, dp);
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_NUMBER):
|
case TBL_CELL_NUMBER:
|
||||||
tblcalc_number(tbl, col, opts, dp);
|
tblcalc_number(tbl, col, opts, dp);
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_DOWN):
|
case TBL_CELL_DOWN:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: out.h,v 1.21 2011/07/17 15:24:25 kristaps Exp $ */
|
/* $Id: out.h,v 1.22 2014/04/20 16:46:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* $Id: read.c,v 1.39 2013/09/16 00:25:07 schwarze Exp $ */
|
/* $Id: read.c,v 1.79 2014/08/06 15:09: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, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
|
* Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* 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
|
||||||
@ -26,6 +27,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -35,6 +37,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "man.h"
|
#include "man.h"
|
||||||
@ -51,24 +54,25 @@ struct mparse {
|
|||||||
enum mandoclevel file_status; /* status of current parse */
|
enum mandoclevel file_status; /* status of current parse */
|
||||||
enum mandoclevel wlevel; /* ignore messages below this */
|
enum mandoclevel wlevel; /* ignore messages below this */
|
||||||
int line; /* line number in the file */
|
int line; /* line number in the file */
|
||||||
enum mparset inttype; /* which parser to use */
|
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) */
|
||||||
|
char *sodest; /* filename pointed to by .so */
|
||||||
int reparse_count; /* finite interp. stack */
|
int reparse_count; /* finite interp. stack */
|
||||||
mandocmsg mmsg; /* warning/error message handler */
|
mandocmsg mmsg; /* warning/error message handler */
|
||||||
void *arg; /* argument to mmsg */
|
|
||||||
const char *file;
|
const char *file;
|
||||||
struct buf *secondary;
|
struct buf *secondary;
|
||||||
char *defos; /* default operating system */
|
const char *defos; /* default operating system */
|
||||||
};
|
};
|
||||||
|
|
||||||
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, int);
|
||||||
static void pset(const char *, int, struct mparse *);
|
static void pset(const char *, int, struct mparse *);
|
||||||
static int read_whole_file(const char *, int, struct buf *, int *);
|
static int read_whole_file(struct mparse *, const char *, int,
|
||||||
|
struct buf *, int *);
|
||||||
static void mparse_end(struct mparse *);
|
static void mparse_end(struct mparse *);
|
||||||
static void mparse_parse_buffer(struct mparse *, struct buf,
|
static void mparse_parse_buffer(struct mparse *, struct buf,
|
||||||
const char *);
|
const char *);
|
||||||
@ -89,66 +93,78 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"generic warning",
|
"generic warning",
|
||||||
|
|
||||||
/* related to the prologue */
|
/* related to the prologue */
|
||||||
"no title in document",
|
"missing manual title, using UNTITLED",
|
||||||
"document title should be all caps",
|
"missing manual title, using \"\"",
|
||||||
|
"lower case character in document title",
|
||||||
|
"missing manual section, using \"\"",
|
||||||
"unknown manual section",
|
"unknown manual section",
|
||||||
"unknown manual volume or arch",
|
"unknown manual volume or arch",
|
||||||
"date missing, using today's date",
|
"missing date, using today's date",
|
||||||
"cannot parse date, using it verbatim",
|
"cannot parse date, using it verbatim",
|
||||||
"prologue macros out of order",
|
"missing Os macro, using \"\"",
|
||||||
"duplicate prologue macro",
|
"duplicate prologue macro",
|
||||||
"macro not allowed in prologue",
|
"late prologue macro",
|
||||||
"macro not allowed in body",
|
"skipping late title macro",
|
||||||
|
"prologue macros out of order",
|
||||||
|
|
||||||
/* related to document structure */
|
/* related to document structure */
|
||||||
".so is fragile, better use ln(1)",
|
".so is fragile, better use ln(1)",
|
||||||
"NAME section must come first",
|
"no document body",
|
||||||
|
"content before first section header",
|
||||||
|
"first section is not \"NAME\"",
|
||||||
"bad NAME section contents",
|
"bad NAME section contents",
|
||||||
"sections out of conventional order",
|
"sections out of conventional order",
|
||||||
"duplicate section name",
|
"duplicate section title",
|
||||||
"section header suited to sections 2, 3, and 9 only",
|
"unexpected section",
|
||||||
|
|
||||||
/* related to macros and nesting */
|
/* related to macros and nesting */
|
||||||
"skipping obsolete macro",
|
"obsolete macro",
|
||||||
"skipping paragraph macro",
|
"skipping paragraph macro",
|
||||||
"moving paragraph macro out of list",
|
"moving paragraph macro out of list",
|
||||||
"skipping no-space macro",
|
"skipping no-space macro",
|
||||||
"blocks badly nested",
|
"blocks badly nested",
|
||||||
"child violates parent syntax",
|
|
||||||
"nested displays are not portable",
|
"nested displays are not portable",
|
||||||
"already in literal mode",
|
"moving content out of list",
|
||||||
|
".Vt block has child macro",
|
||||||
|
"fill mode already enabled, skipping",
|
||||||
|
"fill mode already disabled, skipping",
|
||||||
"line scope broken",
|
"line scope broken",
|
||||||
|
|
||||||
/* related to missing macro arguments */
|
/* related to missing macro arguments */
|
||||||
|
"skipping empty request",
|
||||||
|
"conditional request controls empty scope",
|
||||||
"skipping empty macro",
|
"skipping empty macro",
|
||||||
|
"empty argument, using 0n",
|
||||||
"argument count wrong",
|
"argument count wrong",
|
||||||
"missing display type",
|
"missing display type, using -ragged",
|
||||||
"list type must come first",
|
"list type is not the first argument",
|
||||||
"tag lists require a width argument",
|
"missing -width in -tag list, using 8n",
|
||||||
"missing font type",
|
"missing utility name, using \"\"",
|
||||||
"skipping end of block that is not open",
|
"empty head in list item",
|
||||||
|
"empty list item",
|
||||||
|
"missing font type, using \\fR",
|
||||||
|
"unknown font type, using \\fR",
|
||||||
|
"missing -std argument, adding it",
|
||||||
|
|
||||||
/* related to bad macro arguments */
|
/* related to bad macro arguments */
|
||||||
"skipping argument",
|
"unterminated quoted argument",
|
||||||
"duplicate argument",
|
"duplicate argument",
|
||||||
"duplicate display type",
|
"skipping duplicate argument",
|
||||||
"duplicate list type",
|
"skipping duplicate display type",
|
||||||
|
"skipping duplicate list type",
|
||||||
|
"skipping -width argument",
|
||||||
"unknown AT&T UNIX version",
|
"unknown AT&T UNIX version",
|
||||||
"bad Boolean value",
|
"invalid content in Rs block",
|
||||||
"unknown font",
|
"invalid Boolean argument",
|
||||||
"unknown standard specifier",
|
"unknown font, skipping request",
|
||||||
"bad width argument",
|
|
||||||
|
|
||||||
/* related to plain text */
|
/* related to plain text */
|
||||||
"blank line in non-literal context",
|
"blank line in fill mode, using .sp",
|
||||||
"tab in non-literal context",
|
"tab in filled text",
|
||||||
"end of line whitespace",
|
"whitespace at end of input line",
|
||||||
"bad comment style",
|
"bad comment style",
|
||||||
"bad escape sequence",
|
"invalid escape sequence",
|
||||||
"unterminated quoted string",
|
"undefined string, using \"\"",
|
||||||
|
|
||||||
/* related to equations */
|
|
||||||
"unexpected literal in equation",
|
|
||||||
|
|
||||||
"generic error",
|
"generic error",
|
||||||
|
|
||||||
@ -169,39 +185,38 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
|||||||
"data block still open",
|
"data block still open",
|
||||||
"ignoring extra data cells",
|
"ignoring extra data cells",
|
||||||
|
|
||||||
|
/* related to document structure and macros */
|
||||||
"input stack limit exceeded, infinite loop?",
|
"input stack limit exceeded, infinite loop?",
|
||||||
"skipping bad character",
|
"skipping bad character",
|
||||||
"escaped character not allowed in a name",
|
|
||||||
"manual name not yet set",
|
|
||||||
"skipping text before the first section header",
|
|
||||||
"skipping unknown macro",
|
"skipping unknown macro",
|
||||||
"NOT IMPLEMENTED, please use groff: skipping request",
|
"skipping item outside list",
|
||||||
"argument count wrong",
|
|
||||||
"skipping column outside column list",
|
"skipping column outside column list",
|
||||||
"skipping end of block that is not open",
|
"skipping end of block that is not open",
|
||||||
"missing end of block",
|
"inserting missing end of block",
|
||||||
"scope open on exit",
|
"appending missing end of block",
|
||||||
"uname(3) system call failed",
|
|
||||||
"macro requires line argument(s)",
|
/* related to request and macro arguments */
|
||||||
"macro requires body argument(s)",
|
"escaped character not allowed in a name",
|
||||||
"macro requires argument(s)",
|
"argument count wrong",
|
||||||
"request requires a numeric argument",
|
"missing list type, using -item",
|
||||||
"missing list type",
|
"missing manual name, using \"\"",
|
||||||
"line argument(s) will be lost",
|
"uname(3) system call failed, using UNKNOWN",
|
||||||
"body argument(s) will be lost",
|
"unknown standard specifier",
|
||||||
|
"skipping request without numeric argument",
|
||||||
|
"skipping all arguments",
|
||||||
|
"skipping excess arguments",
|
||||||
|
|
||||||
"generic fatal error",
|
"generic fatal error",
|
||||||
|
|
||||||
"not a manual",
|
"input too large",
|
||||||
"column syntax is inconsistent",
|
"NOT IMPLEMENTED: Bd -file",
|
||||||
"NOT IMPLEMENTED: .Bd -file",
|
|
||||||
"argument count wrong, violates syntax",
|
|
||||||
"child violates parent syntax",
|
|
||||||
"argument count wrong, violates syntax",
|
|
||||||
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
||||||
"no document body",
|
".so request failed",
|
||||||
"no document prologue",
|
|
||||||
"static buffer exhausted",
|
/* system errors */
|
||||||
|
NULL,
|
||||||
|
"cannot stat file",
|
||||||
|
"cannot read file",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
||||||
@ -214,6 +229,7 @@ static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
|||||||
"SYSERR"
|
"SYSERR"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resize_buf(struct buf *buf, size_t initial)
|
resize_buf(struct buf *buf, size_t initial)
|
||||||
{
|
{
|
||||||
@ -246,35 +262,27 @@ pset(const char *buf, int pos, struct mparse *curp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (curp->inttype) {
|
if (MPARSE_MDOC & curp->options) {
|
||||||
case (MPARSE_MDOC):
|
|
||||||
if (NULL == curp->pmdoc)
|
|
||||||
curp->pmdoc = mdoc_alloc(curp->roff, curp,
|
|
||||||
curp->defos);
|
|
||||||
assert(curp->pmdoc);
|
|
||||||
curp->mdoc = curp->pmdoc;
|
curp->mdoc = curp->pmdoc;
|
||||||
return;
|
return;
|
||||||
case (MPARSE_MAN):
|
} else if (MPARSE_MAN & curp->options) {
|
||||||
if (NULL == curp->pman)
|
|
||||||
curp->pman = man_alloc(curp->roff, curp);
|
|
||||||
assert(curp->pman);
|
|
||||||
curp->man = curp->pman;
|
curp->man = curp->pman;
|
||||||
return;
|
return;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
|
if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
|
||||||
if (NULL == curp->pmdoc)
|
if (NULL == curp->pmdoc)
|
||||||
curp->pmdoc = mdoc_alloc(curp->roff, curp,
|
curp->pmdoc = mdoc_alloc(
|
||||||
curp->defos);
|
curp->roff, curp, curp->defos,
|
||||||
|
MPARSE_QUICK & curp->options ? 1 : 0);
|
||||||
assert(curp->pmdoc);
|
assert(curp->pmdoc);
|
||||||
curp->mdoc = curp->pmdoc;
|
curp->mdoc = curp->pmdoc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
assert(curp->pman);
|
assert(curp->pman);
|
||||||
curp->man = curp->pman;
|
curp->man = curp->pman;
|
||||||
}
|
}
|
||||||
@ -348,8 +356,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
|
|
||||||
if ( ! (isascii(c) &&
|
if ( ! (isascii(c) &&
|
||||||
(isgraph(c) || isblank(c)))) {
|
(isgraph(c) || isblank(c)))) {
|
||||||
mandoc_msg(MANDOCERR_BADCHAR, curp,
|
mandoc_vmsg(MANDOCERR_BADCHAR, curp,
|
||||||
curp->line, pos, NULL);
|
curp->line, pos, "0x%x", c);
|
||||||
i++;
|
i++;
|
||||||
ln.buf[pos++] = '?';
|
ln.buf[pos++] = '?';
|
||||||
continue;
|
continue;
|
||||||
@ -405,8 +413,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
|
|
||||||
if ( ! (isascii(c) &&
|
if ( ! (isascii(c) &&
|
||||||
(isgraph(c) || isblank(c)))) {
|
(isgraph(c) || isblank(c)))) {
|
||||||
mandoc_msg(MANDOCERR_BADCHAR, curp,
|
mandoc_vmsg(MANDOCERR_BADCHAR, curp,
|
||||||
curp->line, pos, NULL);
|
curp->line, pos, "0x%x", c);
|
||||||
i += 2;
|
i += 2;
|
||||||
ln.buf[pos++] = '?';
|
ln.buf[pos++] = '?';
|
||||||
continue;
|
continue;
|
||||||
@ -441,9 +449,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (curp->secondary) {
|
if (curp->secondary) {
|
||||||
curp->secondary->buf =
|
curp->secondary->buf = mandoc_realloc(
|
||||||
mandoc_realloc
|
curp->secondary->buf,
|
||||||
(curp->secondary->buf,
|
|
||||||
curp->secondary->sz + pos + 2);
|
curp->secondary->sz + pos + 2);
|
||||||
memcpy(curp->secondary->buf +
|
memcpy(curp->secondary->buf +
|
||||||
curp->secondary->sz,
|
curp->secondary->sz,
|
||||||
@ -456,12 +463,11 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
[curp->secondary->sz] = '\0';
|
[curp->secondary->sz] = '\0';
|
||||||
}
|
}
|
||||||
rerun:
|
rerun:
|
||||||
rr = roff_parseln
|
rr = roff_parseln(curp->roff, curp->line,
|
||||||
(curp->roff, curp->line,
|
|
||||||
&ln.buf, &ln.sz, of, &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, 0);
|
||||||
else
|
else
|
||||||
@ -469,18 +475,24 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
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 = (int)strlen(ln.buf);
|
||||||
continue;
|
continue;
|
||||||
case (ROFF_RERUN):
|
case ROFF_RERUN:
|
||||||
goto rerun;
|
goto rerun;
|
||||||
case (ROFF_IGN):
|
case ROFF_IGN:
|
||||||
pos = 0;
|
pos = 0;
|
||||||
continue;
|
continue;
|
||||||
case (ROFF_ERR):
|
case ROFF_ERR:
|
||||||
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) &&
|
||||||
|
(i >= (int)blk.sz || '\0' == blk.buf[i])) {
|
||||||
|
curp->sodest = mandoc_strdup(ln.buf + of);
|
||||||
|
free(ln.buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* We remove `so' clauses from our lookaside
|
* We remove `so' clauses from our lookaside
|
||||||
* buffer because we're going to descend into
|
* buffer because we're going to descend into
|
||||||
@ -489,8 +501,12 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
if (curp->secondary)
|
if (curp->secondary)
|
||||||
curp->secondary->sz -= pos + 1;
|
curp->secondary->sz -= pos + 1;
|
||||||
mparse_readfd(curp, -1, ln.buf + of);
|
mparse_readfd(curp, -1, ln.buf + of);
|
||||||
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
if (MANDOCLEVEL_FATAL <= curp->file_status) {
|
||||||
|
mandoc_vmsg(MANDOCERR_SO_FAIL,
|
||||||
|
curp, curp->line, pos,
|
||||||
|
".so %s", ln.buf + of);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
pos = 0;
|
pos = 0;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
@ -552,7 +568,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
if (0 == rc) {
|
if (0 == rc) {
|
||||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||||
break;
|
break;
|
||||||
}
|
} else if (2 == rc)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Temporary buffers typically are not full. */
|
/* Temporary buffers typically are not full. */
|
||||||
|
|
||||||
@ -568,7 +585,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||||
|
struct buf *fb, int *with_mmap)
|
||||||
{
|
{
|
||||||
size_t off;
|
size_t off;
|
||||||
ssize_t ssz;
|
ssize_t ssz;
|
||||||
@ -576,7 +594,10 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
|||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (-1 == fstat(fd, &st)) {
|
if (-1 == fstat(fd, &st)) {
|
||||||
perror(file);
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
if (curp->mmsg)
|
||||||
|
(*curp->mmsg)(MANDOCERR_SYSSTAT, curp->file_status,
|
||||||
|
file, 0, 0, strerror(errno));
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,7 +610,10 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
|||||||
|
|
||||||
if (S_ISREG(st.st_mode)) {
|
if (S_ISREG(st.st_mode)) {
|
||||||
if (st.st_size >= (1U << 31)) {
|
if (st.st_size >= (1U << 31)) {
|
||||||
fprintf(stderr, "%s: input too large\n", file);
|
curp->file_status = MANDOCLEVEL_FATAL;
|
||||||
|
if (curp->mmsg)
|
||||||
|
(*curp->mmsg)(MANDOCERR_TOOLARGE,
|
||||||
|
curp->file_status, file, 0, 0, NULL);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
*with_mmap = 1;
|
*with_mmap = 1;
|
||||||
@ -612,7 +636,11 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if (off == fb->sz) {
|
if (off == fb->sz) {
|
||||||
if (fb->sz == (1U << 31)) {
|
if (fb->sz == (1U << 31)) {
|
||||||
fprintf(stderr, "%s: input too large\n", file);
|
curp->file_status = MANDOCLEVEL_FATAL;
|
||||||
|
if (curp->mmsg)
|
||||||
|
(*curp->mmsg)(MANDOCERR_TOOLARGE,
|
||||||
|
curp->file_status,
|
||||||
|
file, 0, 0, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
resize_buf(fb, 65536);
|
resize_buf(fb, 65536);
|
||||||
@ -623,7 +651,11 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
if (ssz == -1) {
|
if (ssz == -1) {
|
||||||
perror(file);
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
if (curp->mmsg)
|
||||||
|
(*curp->mmsg)(MANDOCERR_SYSREAD,
|
||||||
|
curp->file_status, file, 0, 0,
|
||||||
|
strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
off += (size_t)ssz;
|
off += (size_t)ssz;
|
||||||
@ -641,6 +673,19 @@ mparse_end(struct mparse *curp)
|
|||||||
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (curp->mdoc == NULL &&
|
||||||
|
curp->man == NULL &&
|
||||||
|
curp->sodest == NULL) {
|
||||||
|
if (curp->options & MPARSE_MDOC)
|
||||||
|
curp->mdoc = curp->pmdoc;
|
||||||
|
else {
|
||||||
|
if (curp->pman == NULL)
|
||||||
|
curp->pman = man_alloc(curp->roff, curp,
|
||||||
|
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||||
|
curp->man = curp->pman;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (curp->mdoc && ! mdoc_endparse(curp->mdoc)) {
|
if (curp->mdoc && ! mdoc_endparse(curp->mdoc)) {
|
||||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||||
return;
|
return;
|
||||||
@ -651,12 +696,6 @@ mparse_end(struct mparse *curp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! (curp->man || curp->mdoc)) {
|
|
||||||
mandoc_msg(MANDOCERR_NOTMANUAL, curp, 1, 0, NULL);
|
|
||||||
curp->file_status = MANDOCLEVEL_FATAL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
roff_endparse(curp->roff);
|
roff_endparse(curp->roff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,12 +743,15 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
|
|||||||
struct buf blk;
|
struct buf blk;
|
||||||
int with_mmap;
|
int with_mmap;
|
||||||
|
|
||||||
if (-1 == fd)
|
if (-1 == fd && -1 == (fd = open(file, O_RDONLY, 0))) {
|
||||||
if (-1 == (fd = open(file, O_RDONLY, 0))) {
|
|
||||||
perror(file);
|
|
||||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||||
|
if (curp->mmsg)
|
||||||
|
(*curp->mmsg)(MANDOCERR_SYSOPEN,
|
||||||
|
curp->file_status,
|
||||||
|
file, 0, 0, strerror(errno));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run for each opened file; may be called more than once for
|
* Run for each opened file; may be called more than once for
|
||||||
* each full parse sequence if the opened file is nested (i.e.,
|
* each full parse sequence if the opened file is nested (i.e.,
|
||||||
@ -717,10 +759,8 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
|
|||||||
* the parse phase for the file.
|
* the parse phase for the file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! read_whole_file(file, fd, &blk, &with_mmap)) {
|
if ( ! read_whole_file(curp, file, fd, &blk, &with_mmap))
|
||||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
mparse_parse_buffer(curp, blk, file);
|
mparse_parse_buffer(curp, blk, file);
|
||||||
|
|
||||||
@ -738,8 +778,8 @@ mparse_readfd(struct mparse *curp, int fd, const char *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct mparse *
|
struct mparse *
|
||||||
mparse_alloc(enum mparset inttype, enum mandoclevel wlevel,
|
mparse_alloc(int options, enum mandoclevel wlevel,
|
||||||
mandocmsg mmsg, void *arg, char *defos)
|
mandocmsg mmsg, const char *defos)
|
||||||
{
|
{
|
||||||
struct mparse *curp;
|
struct mparse *curp;
|
||||||
|
|
||||||
@ -747,13 +787,20 @@ mparse_alloc(enum mparset inttype, enum mandoclevel wlevel,
|
|||||||
|
|
||||||
curp = mandoc_calloc(1, sizeof(struct mparse));
|
curp = mandoc_calloc(1, sizeof(struct mparse));
|
||||||
|
|
||||||
|
curp->options = options;
|
||||||
curp->wlevel = wlevel;
|
curp->wlevel = wlevel;
|
||||||
curp->mmsg = mmsg;
|
curp->mmsg = mmsg;
|
||||||
curp->arg = arg;
|
|
||||||
curp->inttype = inttype;
|
|
||||||
curp->defos = defos;
|
curp->defos = defos;
|
||||||
|
|
||||||
curp->roff = roff_alloc(inttype, curp);
|
curp->roff = roff_alloc(curp, options);
|
||||||
|
if (curp->options & MPARSE_MDOC)
|
||||||
|
curp->pmdoc = mdoc_alloc(
|
||||||
|
curp->roff, curp, curp->defos,
|
||||||
|
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||||
|
if (curp->options & MPARSE_MAN)
|
||||||
|
curp->pman = man_alloc(curp->roff, curp,
|
||||||
|
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||||
|
|
||||||
return(curp);
|
return(curp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,6 +820,9 @@ mparse_reset(struct mparse *curp)
|
|||||||
curp->file_status = MANDOCLEVEL_OK;
|
curp->file_status = MANDOCLEVEL_OK;
|
||||||
curp->mdoc = NULL;
|
curp->mdoc = NULL;
|
||||||
curp->man = NULL;
|
curp->man = NULL;
|
||||||
|
|
||||||
|
free(curp->sodest);
|
||||||
|
curp->sodest = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -789,13 +839,20 @@ mparse_free(struct mparse *curp)
|
|||||||
free(curp->secondary->buf);
|
free(curp->secondary->buf);
|
||||||
|
|
||||||
free(curp->secondary);
|
free(curp->secondary);
|
||||||
|
free(curp->sodest);
|
||||||
free(curp);
|
free(curp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mparse_result(struct mparse *curp, struct mdoc **mdoc, struct man **man)
|
mparse_result(struct mparse *curp,
|
||||||
|
struct mdoc **mdoc, struct man **man, char **sodest)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (sodest && NULL != (*sodest = curp->sodest)) {
|
||||||
|
*mdoc = NULL;
|
||||||
|
*man = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mdoc)
|
if (mdoc)
|
||||||
*mdoc = curp->mdoc;
|
*mdoc = curp->mdoc;
|
||||||
if (man)
|
if (man)
|
||||||
@ -810,7 +867,7 @@ mandoc_vmsg(enum mandocerr t, struct mparse *m,
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
(void)vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
mandoc_msg(t, m, ln, pos, buf);
|
mandoc_msg(t, m, ln, pos, buf);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\" $Id: roff.7,v 1.46 2013/12/26 02:43:18 schwarze Exp $
|
.\" $Id: roff.7,v 1.55 2014/07/07 11:35:06 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 Ingo Schwarze <schwarze@openbsd.org>
|
.\" Copyright (c) 2010, 2011, 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
|
||||||
@ -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: December 26 2013 $
|
.Dd $Mdocdate: July 7 2014 $
|
||||||
.Dt ROFF 7
|
.Dt ROFF 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -409,24 +409,27 @@ and the number of arguments is not checked.
|
|||||||
Append to a macro definition.
|
Append to a macro definition.
|
||||||
The syntax of this request is the same as that of
|
The syntax of this request is the same as that of
|
||||||
.Sx \&de .
|
.Sx \&de .
|
||||||
It is currently ignored by
|
|
||||||
.Xr mandoc 1 ,
|
|
||||||
as are its children.
|
|
||||||
.Ss \&ami
|
.Ss \&ami
|
||||||
Append to a macro definition, specifying the macro name indirectly.
|
Append to a macro definition, specifying the macro name indirectly.
|
||||||
The syntax of this request is the same as that of
|
The syntax of this request is the same as that of
|
||||||
.Sx \&dei .
|
.Sx \&dei .
|
||||||
It is currently ignored by
|
|
||||||
.Xr mandoc 1 ,
|
|
||||||
as are its children.
|
|
||||||
.Ss \&am1
|
.Ss \&am1
|
||||||
Append to a macro definition, switching roff compatibility mode off
|
Append to a macro definition, switching roff compatibility mode off
|
||||||
during macro execution.
|
during macro execution.
|
||||||
The syntax of this request is the same as that of
|
The syntax of this request is the same as that of
|
||||||
.Sx \&de1 .
|
.Sx \&de1 .
|
||||||
It is currently ignored by
|
Since
|
||||||
.Xr mandoc 1 ,
|
.Xr mandoc 1
|
||||||
as are its children.
|
does not implement
|
||||||
|
.Nm
|
||||||
|
compatibility mode at all, it handles this request as an alias for
|
||||||
|
.Sx \&am .
|
||||||
|
.Ss \&as
|
||||||
|
Append to a user-defined string.
|
||||||
|
The syntax of this request is the same as that of
|
||||||
|
.Sx \&ds .
|
||||||
|
If a user-defined string with the specified name does not yet exist,
|
||||||
|
it is set to the empty string before appending.
|
||||||
.Ss \&cc
|
.Ss \&cc
|
||||||
Changes the control character.
|
Changes the control character.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
@ -439,6 +442,12 @@ If
|
|||||||
is not specified, the control character is reset to
|
is not specified, the control character is reset to
|
||||||
.Sq \&. .
|
.Sq \&. .
|
||||||
Trailing characters are ignored.
|
Trailing characters are ignored.
|
||||||
|
.Ss \&ce
|
||||||
|
Center some lines.
|
||||||
|
This line-scoped request is intended to take one integer argument,
|
||||||
|
specifying how many lines to center.
|
||||||
|
Currently, it is ignored including its arguments, and the number
|
||||||
|
of arguments is not checked.
|
||||||
.Ss \&de
|
.Ss \&de
|
||||||
Define a
|
Define a
|
||||||
.Nm
|
.Nm
|
||||||
@ -542,9 +551,13 @@ Define a
|
|||||||
macro, specifying the macro name indirectly.
|
macro, specifying the macro name indirectly.
|
||||||
The syntax of this request is the same as that of
|
The syntax of this request is the same as that of
|
||||||
.Sx \&de .
|
.Sx \&de .
|
||||||
It is currently ignored by
|
The request
|
||||||
.Xr mandoc 1 ,
|
.Pp
|
||||||
as are its children.
|
.D1 Pf . Cm \&dei Ar name Op Ar end
|
||||||
|
.Pp
|
||||||
|
has the same effect as:
|
||||||
|
.Pp
|
||||||
|
.D1 Pf . Cm \&de No \e* Ns Bo Ar name Bc Op \e* Ns Bq Ar end
|
||||||
.Ss \&de1
|
.Ss \&de1
|
||||||
Define a
|
Define a
|
||||||
.Nm
|
.Nm
|
||||||
@ -647,6 +660,34 @@ This line-scoped request is intended to have one argument specifying
|
|||||||
the font family to be selected.
|
the font family to be selected.
|
||||||
It is a groff extension, and currently, it is ignored including its
|
It is a groff extension, and currently, it is ignored including its
|
||||||
arguments, and the number of arguments is not checked.
|
arguments, and the number of arguments is not checked.
|
||||||
|
.Ss \&ft
|
||||||
|
Change the font.
|
||||||
|
Its syntax is as follows:
|
||||||
|
.Pp
|
||||||
|
.D1 Pf . Cm \&ft Op Ar font
|
||||||
|
.Pp
|
||||||
|
The following
|
||||||
|
.Ar font
|
||||||
|
arguments are supported:
|
||||||
|
.Bl -tag -width 4n -offset indent
|
||||||
|
.It Cm B , BI , 3 , 4
|
||||||
|
switches to
|
||||||
|
.Sy bold
|
||||||
|
font
|
||||||
|
.It Cm I , 2
|
||||||
|
switches to
|
||||||
|
.Em underlined
|
||||||
|
font
|
||||||
|
.It Cm R , CW , 1
|
||||||
|
switches to normal font
|
||||||
|
.It Cm P No "or no argument"
|
||||||
|
switches back to the previous font
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
This request takes effect only locally, may be overridden by macros
|
||||||
|
and escape sequences, and is only supported in
|
||||||
|
.Xr man 7
|
||||||
|
for now.
|
||||||
.Ss \&hw
|
.Ss \&hw
|
||||||
Specify hyphenation points in words.
|
Specify hyphenation points in words.
|
||||||
This line-scoped request is currently ignored.
|
This line-scoped request is currently ignored.
|
||||||
@ -665,10 +706,67 @@ Its syntax is equivalent to
|
|||||||
.Sx \&if .
|
.Sx \&if .
|
||||||
.Ss \&if
|
.Ss \&if
|
||||||
Begins a conditional.
|
Begins a conditional.
|
||||||
Right now, the conditional evaluates to true
|
This request has the following syntax:
|
||||||
if and only if it starts with the letter
|
.Bd -literal -offset indent
|
||||||
.Sy n ,
|
\&.if COND BODY
|
||||||
indicating processing in nroff style as opposed to troff style.
|
.Ed
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
\&.if COND \e{BODY
|
||||||
|
BODY...\e}
|
||||||
|
.Ed
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
\&.if COND \e{\e
|
||||||
|
BODY...
|
||||||
|
\&.\e}
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
COND is a conditional statement.
|
||||||
|
Currently,
|
||||||
|
.Xr mandoc 1
|
||||||
|
supports the following subset of roff conditionals:
|
||||||
|
.Bl -bullet
|
||||||
|
.It
|
||||||
|
If
|
||||||
|
.Sq \&!
|
||||||
|
is prefixed to COND, the condition is logically inverted.
|
||||||
|
.It
|
||||||
|
If the first character of COND is
|
||||||
|
.Sq n
|
||||||
|
.Pq nroff mode
|
||||||
|
or
|
||||||
|
.Sq o
|
||||||
|
.Pq odd page ,
|
||||||
|
COND evaluates to true.
|
||||||
|
.It
|
||||||
|
If the first character of COND is
|
||||||
|
.Sq c
|
||||||
|
.Pq character available ,
|
||||||
|
.Sq d
|
||||||
|
.Pq string defined ,
|
||||||
|
.Sq e
|
||||||
|
.Pq even page ,
|
||||||
|
.Sq r
|
||||||
|
.Pq register accessed ,
|
||||||
|
or
|
||||||
|
.Sq t
|
||||||
|
.Pq troff mode ,
|
||||||
|
COND evaluates to false.
|
||||||
|
.It
|
||||||
|
If COND starts with a parenthesis or with an optionally signed
|
||||||
|
integer number, it is evaluated according to the rules of
|
||||||
|
.Sx Numerical expressions
|
||||||
|
explained below.
|
||||||
|
It evaluates to true if the the result is positive,
|
||||||
|
or to false if the result is zero or negative.
|
||||||
|
.It
|
||||||
|
Otherwise, the first character of COND is regarded as a delimiter
|
||||||
|
and COND evaluates to true if the string extending from its first
|
||||||
|
to its second occurrence is equal to the string extending from its
|
||||||
|
second to its third occurrence.
|
||||||
|
.It
|
||||||
|
If COND cannot be parsed, it evaluates to false.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
If a conditional is false, its children are not processed, but are
|
If a conditional is false, its children are not processed, but are
|
||||||
syntactically interpreted to preserve the integrity of the input
|
syntactically interpreted to preserve the integrity of the input
|
||||||
document.
|
document.
|
||||||
@ -686,44 +784,12 @@ will continue to syntactically interpret to the block close of the final
|
|||||||
conditional.
|
conditional.
|
||||||
Sub-conditionals, in this case, obviously inherit the truth value of
|
Sub-conditionals, in this case, obviously inherit the truth value of
|
||||||
the parent.
|
the parent.
|
||||||
This request has the following syntax:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
\&.if COND \e{\e
|
|
||||||
BODY...
|
|
||||||
\&.\e}
|
|
||||||
.Ed
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
\&.if COND \e{ BODY
|
|
||||||
BODY... \e}
|
|
||||||
.Ed
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
\&.if COND \e{ BODY
|
|
||||||
BODY...
|
|
||||||
\&.\e}
|
|
||||||
.Ed
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
\&.if COND \e
|
|
||||||
BODY
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
COND is a conditional statement.
|
|
||||||
roff allows for complicated conditionals; mandoc is much simpler.
|
|
||||||
At this time, mandoc supports only
|
|
||||||
.Sq n ,
|
|
||||||
evaluating to true;
|
|
||||||
and
|
|
||||||
.Sq t ,
|
|
||||||
.Sq e ,
|
|
||||||
and
|
|
||||||
.Sq o ,
|
|
||||||
evaluating to false.
|
|
||||||
All other invocations are read up to the next end of line or space and
|
|
||||||
evaluate as false.
|
|
||||||
.Pp
|
.Pp
|
||||||
If the BODY section is begun by an escaped brace
|
If the BODY section is begun by an escaped brace
|
||||||
.Sq \e{ ,
|
.Sq \e{ ,
|
||||||
scope continues until a closing-brace escape sequence
|
scope continues until the end of the input line containing the
|
||||||
.Sq \.\e} .
|
matching closing-brace escape sequence
|
||||||
|
.Sq \e} .
|
||||||
If the BODY is not enclosed in braces, scope continues until
|
If the BODY is not enclosed in braces, scope continues until
|
||||||
the end of the line.
|
the end of the line.
|
||||||
If the COND is followed by a BODY on the same line, whether after a
|
If the COND is followed by a BODY on the same line, whether after a
|
||||||
@ -803,6 +869,23 @@ Otherwise, it only terminates the
|
|||||||
and arguments following it or the
|
and arguments following it or the
|
||||||
.Sq \&..
|
.Sq \&..
|
||||||
request are discarded.
|
request are discarded.
|
||||||
|
.Ss \&ll
|
||||||
|
Change the output line length.
|
||||||
|
Its syntax is as follows:
|
||||||
|
.Pp
|
||||||
|
.D1 Pf . Cm \&ll Op Oo +|- Oc Ns Ar width
|
||||||
|
.Pp
|
||||||
|
If the
|
||||||
|
.Ar width
|
||||||
|
argument is omitted, the line length is reset to its previous value.
|
||||||
|
The default setting for terminal output is 78n.
|
||||||
|
If a sign is given, the line length is added to or subtracted from;
|
||||||
|
otherwise, it is set to the provided value.
|
||||||
|
Using this request in new manuals is discouraged for several reasons,
|
||||||
|
among others because it overrides the
|
||||||
|
.Xr mandoc 1
|
||||||
|
.Fl O Cm width
|
||||||
|
command line option.
|
||||||
.Ss \&ne
|
.Ss \&ne
|
||||||
Declare the need for the specified minimum vertical space
|
Declare the need for the specified minimum vertical space
|
||||||
before the next trap or the bottom of the page.
|
before the next trap or the bottom of the page.
|
||||||
@ -810,23 +893,19 @@ This line-scoped request is currently ignored.
|
|||||||
.Ss \&nh
|
.Ss \&nh
|
||||||
Turn off automatic hyphenation mode.
|
Turn off automatic hyphenation mode.
|
||||||
This line-scoped request is currently ignored.
|
This line-scoped request is currently ignored.
|
||||||
.Ss \&rm
|
|
||||||
Remove a request, macro or string.
|
|
||||||
This request is intended to have one argument,
|
|
||||||
the name of the request, macro or string to be undefined.
|
|
||||||
Currently, it is ignored including its arguments,
|
|
||||||
and the number of arguments is not checked.
|
|
||||||
.Ss \&nr
|
.Ss \&nr
|
||||||
Define or change a register.
|
Define or change a register.
|
||||||
A register is an arbitrary string value that defines some sort of state,
|
A register is an arbitrary string value that defines some sort of state,
|
||||||
which influences parsing and/or formatting.
|
which influences parsing and/or formatting.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 Pf \. Cm \&nr Ar name Oo +|- Oc Ns Ar value
|
.D1 Pf \. Cm \&nr Ar name Oo +|- Oc Ns Ar expression
|
||||||
.Pp
|
.Pp
|
||||||
The
|
For the syntax of
|
||||||
.Ar value
|
.Ar expression ,
|
||||||
may, at the moment, only be an integer.
|
see
|
||||||
|
.Sx Numerical expressions
|
||||||
|
below.
|
||||||
If it is prefixed by a sign, the register will be
|
If it is prefixed by a sign, the register will be
|
||||||
incremented or decremented instead of assigned to.
|
incremented or decremented instead of assigned to.
|
||||||
.Pp
|
.Pp
|
||||||
@ -861,6 +940,16 @@ 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.
|
||||||
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 \&rm
|
||||||
|
Remove a request, macro or string.
|
||||||
|
Its syntax is as follows:
|
||||||
|
.Pp
|
||||||
|
.D1 Pf \. Cm \&rm Ar name
|
||||||
|
.Ss \&rr
|
||||||
|
Remove a register.
|
||||||
|
Its syntax is as follows:
|
||||||
|
.Pp
|
||||||
|
.D1 Pf \. Cm \&rr Ar name
|
||||||
.Ss \&so
|
.Ss \&so
|
||||||
Include a source file.
|
Include a source file.
|
||||||
Its syntax is as follows:
|
Its syntax is as follows:
|
||||||
@ -929,6 +1018,73 @@ Begin a table, which formats input in aligned rows and columns.
|
|||||||
See
|
See
|
||||||
.Xr tbl 7
|
.Xr tbl 7
|
||||||
for a description of the tbl language.
|
for a description of the tbl language.
|
||||||
|
.Ss Numerical expressions
|
||||||
|
The
|
||||||
|
.Sx \&nr ,
|
||||||
|
.Sx \&if ,
|
||||||
|
and
|
||||||
|
.Sx \&ie
|
||||||
|
requests accept integer numerical expressions as arguments.
|
||||||
|
These are always evaluated using the C
|
||||||
|
.Vt int
|
||||||
|
type; integer overflow works the same way as in the C language.
|
||||||
|
Numbers consist of an arbitrary number of digits
|
||||||
|
.Sq 0
|
||||||
|
to
|
||||||
|
.Sq 9
|
||||||
|
prefixed by an optional sign
|
||||||
|
.Sq +
|
||||||
|
or
|
||||||
|
.Sq - .
|
||||||
|
.Pp
|
||||||
|
The following binary operators are implemented.
|
||||||
|
Unless otherwise stated, they behave as in the C language:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width 2n -compact
|
||||||
|
.It Ic +
|
||||||
|
addition
|
||||||
|
.It Ic -
|
||||||
|
subtraction
|
||||||
|
.It Ic *
|
||||||
|
multiplication
|
||||||
|
.It Ic /
|
||||||
|
division
|
||||||
|
.It Ic %
|
||||||
|
remainder of division
|
||||||
|
.It Ic <
|
||||||
|
less than
|
||||||
|
.It Ic >
|
||||||
|
greater than
|
||||||
|
.It Ic ==
|
||||||
|
equal to
|
||||||
|
.It Ic =
|
||||||
|
equal to, same effect as
|
||||||
|
.Ic ==
|
||||||
|
(this differs from C)
|
||||||
|
.It Ic <=
|
||||||
|
less than or equal to
|
||||||
|
.It Ic >=
|
||||||
|
greater than or equal to
|
||||||
|
.It Ic <>
|
||||||
|
not equal to (corresponds to C
|
||||||
|
.Ic != ;
|
||||||
|
this one is of limited portability, it is supported by Heirloom roff,
|
||||||
|
but not by groff)
|
||||||
|
.It Ic &
|
||||||
|
logical and (corresponds to C
|
||||||
|
.Ic && )
|
||||||
|
.It Ic \&:
|
||||||
|
logical or (corresponds to C
|
||||||
|
.Ic \&|| )
|
||||||
|
.It Ic <?
|
||||||
|
minimum (not available in C)
|
||||||
|
.It Ic >?
|
||||||
|
maximum (not available in C)
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
There is no concept of precendence; evaluation proceeds from left to right,
|
||||||
|
except when subexpressions are enclosed in parantheses.
|
||||||
|
Inside parentheses, whitespace is ignored.
|
||||||
.Sh ESCAPE SEQUENCE REFERENCE
|
.Sh ESCAPE SEQUENCE REFERENCE
|
||||||
The
|
The
|
||||||
.Xr mandoc 1
|
.Xr mandoc 1
|
||||||
@ -1017,10 +1173,15 @@ Digit width space character.
|
|||||||
Anchor definition; ignored by
|
Anchor definition; ignored by
|
||||||
.Xr mandoc 1 .
|
.Xr mandoc 1 .
|
||||||
.Ss \eB\(aq Ns Ar string Ns \(aq
|
.Ss \eB\(aq Ns Ar string Ns \(aq
|
||||||
Test whether
|
Interpolate
|
||||||
|
.Sq 1
|
||||||
|
if
|
||||||
.Ar string
|
.Ar string
|
||||||
is a numerical expession; ignored by
|
conforms to the syntax of
|
||||||
.Xr mandoc 1 .
|
.Sx Numerical expressions
|
||||||
|
explained above and
|
||||||
|
.Sq 0
|
||||||
|
otherwise.
|
||||||
.Ss \eb\(aq Ns Ar string Ns \(aq
|
.Ss \eb\(aq Ns Ar string Ns \(aq
|
||||||
Bracket building function; ignored by
|
Bracket building function; ignored by
|
||||||
.Xr mandoc 1 .
|
.Xr mandoc 1 .
|
||||||
@ -1144,9 +1305,13 @@ Vertical motion; ignored by
|
|||||||
.Xr mandoc 1 .
|
.Xr mandoc 1 .
|
||||||
.Ss \ew\(aq Ns Ar string Ns \(aq
|
.Ss \ew\(aq Ns Ar string Ns \(aq
|
||||||
Interpolate the width of the
|
Interpolate the width of the
|
||||||
.Ar string ;
|
.Ar string .
|
||||||
ignored by
|
The
|
||||||
.Xr mandoc 1 .
|
.Xr mandoc 1
|
||||||
|
implementation assumes that after expansion of user-defined strings, the
|
||||||
|
.Ar string
|
||||||
|
only contains normal characters, no escape sequences, and that each
|
||||||
|
character has a width of 24 basic units.
|
||||||
.Ss \eX\(aq Ns Ar string Ns \(aq
|
.Ss \eX\(aq Ns Ar string Ns \(aq
|
||||||
Output
|
Output
|
||||||
.Ar string
|
.Ar string
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
/* $Id: st.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
/* $Id: st.c,v 1.10 2014/03/23 11:25:26 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -18,12 +18,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "mdoc.h"
|
#include "mdoc.h"
|
||||||
#include "mandoc.h"
|
|
||||||
#include "libmdoc.h"
|
#include "libmdoc.h"
|
||||||
|
|
||||||
#define LINE(x, y) \
|
#define LINE(x, y) \
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: st.in,v 1.22 2013/12/25 14:09:32 schwarze Exp $ */
|
/* $Id: st.in,v 1.24 2014/04/20 16:46:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -34,6 +34,7 @@ LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
|
|||||||
LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
|
LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
|
||||||
LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
|
LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
|
||||||
LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
|
LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
|
||||||
|
LINE("-p1003.1-2013", "IEEE Std 1003.1-2008/Cor 1-2013 (\\(lqPOSIX.1\\(rq)")
|
||||||
LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
|
LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
|
||||||
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)")
|
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)")
|
||||||
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)")
|
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl.c,v 1.27 2013/05/31 22:08:09 schwarze Exp $ */
|
/* $Id: tbl.c,v 1.29 2014/04/20 16:46: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 Ingo Schwarze <schwarze@openbsd.org>
|
||||||
@ -26,9 +26,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
#include "libroff.h"
|
#include "libroff.h"
|
||||||
|
|
||||||
|
|
||||||
enum rofferr
|
enum rofferr
|
||||||
tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
|
tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
|
||||||
{
|
{
|
||||||
@ -52,11 +54,11 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
|
|||||||
/* Now process each logical section of the table. */
|
/* Now process each logical section of the table. */
|
||||||
|
|
||||||
switch (tbl->part) {
|
switch (tbl->part) {
|
||||||
case (TBL_PART_OPTS):
|
case TBL_PART_OPTS:
|
||||||
return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
|
return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
|
||||||
case (TBL_PART_LAYOUT):
|
case TBL_PART_LAYOUT:
|
||||||
return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
|
return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
|
||||||
case (TBL_PART_CDATA):
|
case TBL_PART_CDATA:
|
||||||
return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
|
return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -172,4 +174,3 @@ tbl_end(struct tbl_node **tblp)
|
|||||||
mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
|
mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
|
||||||
tbl->line, tbl->pos, NULL);
|
tbl->line, tbl->pos, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_data.c,v 1.27 2013/06/01 04:56:50 schwarze Exp $ */
|
/* $Id: tbl_data.c,v 1.31 2014/04/23 16:08:33 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>
|
||||||
@ -26,16 +26,18 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
#include "libroff.h"
|
#include "libroff.h"
|
||||||
|
|
||||||
static int data(struct tbl_node *, struct tbl_span *,
|
static int getdata(struct tbl_node *, struct tbl_span *,
|
||||||
int, const char *, int *);
|
int, const char *, int *);
|
||||||
static struct tbl_span *newspan(struct tbl_node *, int,
|
static struct tbl_span *newspan(struct tbl_node *, int,
|
||||||
struct tbl_row *);
|
struct tbl_row *);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
data(struct tbl_node *tbl, struct tbl_span *dp,
|
getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
||||||
int ln, const char *p, int *pos)
|
int ln, const char *p, int *pos)
|
||||||
{
|
{
|
||||||
struct tbl_dat *dat;
|
struct tbl_dat *dat;
|
||||||
@ -62,8 +64,8 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (NULL == cp) {
|
if (NULL == cp) {
|
||||||
mandoc_msg(MANDOCERR_TBLEXTRADAT,
|
mandoc_msg(MANDOCERR_TBLEXTRADAT, tbl->parse,
|
||||||
tbl->parse, ln, *pos, NULL);
|
ln, *pos, NULL);
|
||||||
/* Skip to the end... */
|
/* Skip to the end... */
|
||||||
while (p[*pos])
|
while (p[*pos])
|
||||||
(*pos)++;
|
(*pos)++;
|
||||||
@ -135,7 +137,6 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
||||||
{
|
{
|
||||||
@ -152,7 +153,7 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
|||||||
if (p[pos] == tbl->opts.tab) {
|
if (p[pos] == tbl->opts.tab) {
|
||||||
tbl->part = TBL_PART_DATA;
|
tbl->part = TBL_PART_DATA;
|
||||||
pos++;
|
pos++;
|
||||||
return(data(tbl, tbl->last_span, ln, p, &pos));
|
return(getdata(tbl, tbl->last_span, ln, p, &pos));
|
||||||
} else if ('\0' == p[pos]) {
|
} else if ('\0' == p[pos]) {
|
||||||
tbl->part = TBL_PART_DATA;
|
tbl->part = TBL_PART_DATA;
|
||||||
return(1);
|
return(1);
|
||||||
@ -166,14 +167,14 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
|||||||
if (dat->string) {
|
if (dat->string) {
|
||||||
sz = strlen(p) + strlen(dat->string) + 2;
|
sz = strlen(p) + strlen(dat->string) + 2;
|
||||||
dat->string = mandoc_realloc(dat->string, sz);
|
dat->string = mandoc_realloc(dat->string, sz);
|
||||||
strlcat(dat->string, " ", sz);
|
(void)strlcat(dat->string, " ", sz);
|
||||||
strlcat(dat->string, p, sz);
|
(void)strlcat(dat->string, p, sz);
|
||||||
} else
|
} else
|
||||||
dat->string = mandoc_strdup(p);
|
dat->string = mandoc_strdup(p);
|
||||||
|
|
||||||
if (TBL_CELL_DOWN == dat->layout->pos)
|
if (TBL_CELL_DOWN == dat->layout->pos)
|
||||||
mandoc_msg(MANDOCERR_TBLIGNDATA,
|
mandoc_msg(MANDOCERR_TBLIGNDATA, tbl->parse,
|
||||||
tbl->parse, ln, pos, NULL);
|
ln, pos, NULL);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -229,11 +230,11 @@ tbl_data(struct tbl_node *tbl, int ln, const char *p)
|
|||||||
for (rp = tbl->last_span->layout->next;
|
for (rp = tbl->last_span->layout->next;
|
||||||
rp && rp->first; rp = rp->next) {
|
rp && rp->first; rp = rp->next) {
|
||||||
switch (rp->first->pos) {
|
switch (rp->first->pos) {
|
||||||
case (TBL_CELL_HORIZ):
|
case TBL_CELL_HORIZ:
|
||||||
dp = newspan(tbl, ln, rp);
|
dp = newspan(tbl, ln, rp);
|
||||||
dp->pos = TBL_SPAN_HORIZ;
|
dp->pos = TBL_SPAN_HORIZ;
|
||||||
continue;
|
continue;
|
||||||
case (TBL_CELL_DHORIZ):
|
case TBL_CELL_DHORIZ:
|
||||||
dp = newspan(tbl, ln, rp);
|
dp = newspan(tbl, ln, rp);
|
||||||
dp->pos = TBL_SPAN_DHORIZ;
|
dp->pos = TBL_SPAN_DHORIZ;
|
||||||
continue;
|
continue;
|
||||||
@ -267,7 +268,7 @@ tbl_data(struct tbl_node *tbl, int ln, const char *p)
|
|||||||
/* This returns 0 when TBL_PART_CDATA is entered. */
|
/* This returns 0 when TBL_PART_CDATA is entered. */
|
||||||
|
|
||||||
while ('\0' != p[pos])
|
while ('\0' != p[pos])
|
||||||
if ( ! data(tbl, dp, ln, p, &pos))
|
if ( ! getdata(tbl, dp, ln, p, &pos))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_html.c,v 1.10 2012/05/27 17:54:54 schwarze Exp $ */
|
/* $Id: tbl_html.c,v 1.11 2014/04/20 16:46:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -31,7 +31,7 @@ static void html_tblopen(struct html *, const struct tbl_span *);
|
|||||||
static size_t html_tbl_len(size_t, void *);
|
static size_t html_tbl_len(size_t, void *);
|
||||||
static size_t html_tbl_strlen(const char *, void *);
|
static size_t html_tbl_strlen(const char *, void *);
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static size_t
|
static size_t
|
||||||
html_tbl_len(size_t sz, void *arg)
|
html_tbl_len(size_t sz, void *arg)
|
||||||
{
|
{
|
||||||
@ -39,7 +39,6 @@ html_tbl_len(size_t sz, void *arg)
|
|||||||
return(sz);
|
return(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static size_t
|
static size_t
|
||||||
html_tbl_strlen(const char *p, void *arg)
|
html_tbl_strlen(const char *p, void *arg)
|
||||||
{
|
{
|
||||||
@ -107,9 +106,9 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
|||||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||||
|
|
||||||
switch (sp->pos) {
|
switch (sp->pos) {
|
||||||
case (TBL_SPAN_HORIZ):
|
case TBL_SPAN_HORIZ:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_SPAN_DHORIZ):
|
case TBL_SPAN_DHORIZ:
|
||||||
PAIR_INIT(&tag, ATTR_COLSPAN, "0");
|
PAIR_INIT(&tag, ATTR_COLSPAN, "0");
|
||||||
print_otag(h, TAG_TD, 1, &tag);
|
print_otag(h, TAG_TD, 1, &tag);
|
||||||
break;
|
break;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: tbl_layout.c,v 1.23 2012/05/27 17:54:54 schwarze Exp $ */
|
/* $Id: tbl_layout.c,v 1.26 2014/04/20 16:46: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) 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
|
||||||
@ -19,13 +19,13 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "libmandoc.h"
|
#include "libmandoc.h"
|
||||||
#include "libroff.h"
|
#include "libroff.h"
|
||||||
|
|
||||||
@ -63,6 +63,7 @@ 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);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||||
int ln, const char *p, int *pos)
|
int ln, const char *p, int *pos)
|
||||||
@ -73,11 +74,11 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
/* Not all types accept modifiers. */
|
/* Not all types accept modifiers. */
|
||||||
|
|
||||||
switch (cp->pos) {
|
switch (cp->pos) {
|
||||||
case (TBL_CELL_DOWN):
|
case TBL_CELL_DOWN:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_HORIZ):
|
case TBL_CELL_HORIZ:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_DHORIZ):
|
case TBL_CELL_DHORIZ:
|
||||||
return(1);
|
return(1);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -91,15 +92,17 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
* this happen.
|
* this happen.
|
||||||
*/
|
*/
|
||||||
switch (p[*pos]) {
|
switch (p[*pos]) {
|
||||||
case ('\0'):
|
case '\0':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (' '):
|
case ' ':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('\t'):
|
case '\t':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (','):
|
case ',':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('.'):
|
case '.':
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case '|':
|
||||||
return(1);
|
return(1);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -115,8 +118,8 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
(*pos)++;
|
(*pos)++;
|
||||||
goto mod;
|
goto mod;
|
||||||
}
|
}
|
||||||
mandoc_msg(MANDOCERR_TBLLAYOUT,
|
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||||
tbl->parse, ln, *pos, NULL);
|
ln, *pos, NULL);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +136,8 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
/* No greater than 4 digits. */
|
/* No greater than 4 digits. */
|
||||||
|
|
||||||
if (4 == i) {
|
if (4 == i) {
|
||||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
mandoc_msg(MANDOCERR_TBLLAYOUT,
|
||||||
ln, *pos, NULL);
|
tbl->parse, ln, *pos, NULL);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,30 +151,30 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
/* TODO: GNU has many more extensions. */
|
/* TODO: GNU has many more extensions. */
|
||||||
|
|
||||||
switch (tolower((unsigned char)p[(*pos)++])) {
|
switch (tolower((unsigned char)p[(*pos)++])) {
|
||||||
case ('z'):
|
case 'z':
|
||||||
cp->flags |= TBL_CELL_WIGN;
|
cp->flags |= TBL_CELL_WIGN;
|
||||||
goto mod;
|
goto mod;
|
||||||
case ('u'):
|
case 'u':
|
||||||
cp->flags |= TBL_CELL_UP;
|
cp->flags |= TBL_CELL_UP;
|
||||||
goto mod;
|
goto mod;
|
||||||
case ('e'):
|
case 'e':
|
||||||
cp->flags |= TBL_CELL_EQUAL;
|
cp->flags |= TBL_CELL_EQUAL;
|
||||||
goto mod;
|
goto mod;
|
||||||
case ('t'):
|
case 't':
|
||||||
cp->flags |= TBL_CELL_TALIGN;
|
cp->flags |= TBL_CELL_TALIGN;
|
||||||
goto mod;
|
goto mod;
|
||||||
case ('d'):
|
case 'd':
|
||||||
cp->flags |= TBL_CELL_BALIGN;
|
cp->flags |= TBL_CELL_BALIGN;
|
||||||
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 ('f'):
|
case 'f':
|
||||||
break;
|
break;
|
||||||
case ('r'):
|
case 'r':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('b'):
|
case 'b':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('i'):
|
case 'i':
|
||||||
(*pos)--;
|
(*pos)--;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -181,19 +184,19 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (tolower((unsigned char)p[(*pos)++])) {
|
switch (tolower((unsigned char)p[(*pos)++])) {
|
||||||
case ('3'):
|
case '3':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('b'):
|
case 'b':
|
||||||
cp->flags |= TBL_CELL_BOLD;
|
cp->flags |= TBL_CELL_BOLD;
|
||||||
goto mod;
|
goto mod;
|
||||||
case ('2'):
|
case '2':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('i'):
|
case 'i':
|
||||||
cp->flags |= TBL_CELL_ITALIC;
|
cp->flags |= TBL_CELL_ITALIC;
|
||||||
goto mod;
|
goto mod;
|
||||||
case ('1'):
|
case '1':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('r'):
|
case 'r':
|
||||||
goto mod;
|
goto mod;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -218,6 +221,13 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
|||||||
while (' ' == p[*pos])
|
while (' ' == p[*pos])
|
||||||
(*pos)++;
|
(*pos)++;
|
||||||
|
|
||||||
|
/* Handle trailing vertical lines */
|
||||||
|
|
||||||
|
if ('.' == p[*pos] || '\0' == p[*pos]) {
|
||||||
|
rp->vert = vert;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the column position (`c', `l', `r', ...). */
|
/* Parse the column position (`c', `l', `r', ...). */
|
||||||
|
|
||||||
for (i = 0; i < KEYS_MAX; i++)
|
for (i = 0; i < KEYS_MAX; i++)
|
||||||
@ -247,10 +257,11 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
|||||||
return(0);
|
return(0);
|
||||||
} else if (rp->last)
|
} else if (rp->last)
|
||||||
switch (rp->last->pos) {
|
switch (rp->last->pos) {
|
||||||
case (TBL_CELL_HORIZ):
|
case TBL_CELL_HORIZ:
|
||||||
case (TBL_CELL_DHORIZ):
|
/* FALLTHROUGH */
|
||||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
case TBL_CELL_DHORIZ:
|
||||||
ln, *pos, NULL);
|
mandoc_msg(MANDOCERR_TBLLAYOUT,
|
||||||
|
tbl->parse, ln, *pos, NULL);
|
||||||
return(0);
|
return(0);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -281,7 +292,6 @@ 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
|
static void
|
||||||
row(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
row(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
||||||
{
|
{
|
||||||
@ -313,8 +323,8 @@ row(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
|||||||
if ('.' == p[*pos]) {
|
if ('.' == p[*pos]) {
|
||||||
tbl->part = TBL_PART_DATA;
|
tbl->part = TBL_PART_DATA;
|
||||||
if (NULL == tbl->first_row)
|
if (NULL == tbl->first_row)
|
||||||
mandoc_msg(MANDOCERR_TBLNOLAYOUT, tbl->parse,
|
mandoc_msg(MANDOCERR_TBLNOLAYOUT,
|
||||||
ln, *pos, NULL);
|
tbl->parse, ln, *pos, NULL);
|
||||||
(*pos)++;
|
(*pos)++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tbl_opts.c,v 1.12 2011/09/18 14:14:15 schwarze Exp $ */
|
/* $Id: tbl_opts.c,v 1.13 2014/04/20 16:46:05 schwarze Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
@ -81,6 +81,7 @@ static int arg(struct tbl_node *, int,
|
|||||||
static void opt(struct tbl_node *, int,
|
static void opt(struct tbl_node *, int,
|
||||||
const char *, int *);
|
const char *, int *);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
||||||
{
|
{
|
||||||
@ -107,7 +108,7 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case (KEY_DELIM):
|
case KEY_DELIM:
|
||||||
if ('\0' == p[(*pos)++]) {
|
if ('\0' == p[(*pos)++]) {
|
||||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||||
ln, *pos - 1, NULL);
|
ln, *pos - 1, NULL);
|
||||||
@ -120,14 +121,14 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (KEY_TAB):
|
case KEY_TAB:
|
||||||
if ('\0' != (tbl->opts.tab = p[(*pos)++]))
|
if ('\0' != (tbl->opts.tab = p[(*pos)++]))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||||
ln, *pos - 1, NULL);
|
ln, *pos - 1, NULL);
|
||||||
return(0);
|
return(0);
|
||||||
case (KEY_LINESIZE):
|
case KEY_LINESIZE:
|
||||||
for (i = 0; i < KEY_MAXNUMSZ && p[*pos]; i++, (*pos)++) {
|
for (i = 0; i < KEY_MAXNUMSZ && p[*pos]; i++, (*pos)++) {
|
||||||
buf[i] = p[*pos];
|
buf[i] = p[*pos];
|
||||||
if ( ! isdigit((unsigned char)buf[i]))
|
if ( ! isdigit((unsigned char)buf[i]))
|
||||||
@ -142,7 +143,7 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||||||
|
|
||||||
mandoc_msg(MANDOCERR_TBL, tbl->parse, ln, *pos, NULL);
|
mandoc_msg(MANDOCERR_TBL, tbl->parse, ln, *pos, NULL);
|
||||||
return(0);
|
return(0);
|
||||||
case (KEY_DPOINT):
|
case KEY_DPOINT:
|
||||||
if ('\0' != (tbl->opts.decimal = p[(*pos)++]))
|
if ('\0' != (tbl->opts.decimal = p[(*pos)++]))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: tbl_term.c,v 1.25 2013/05/31 21:37:17 schwarze Exp $ */
|
/* $Id: tbl_term.c,v 1.27 2014/04/20 16:46: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 Ingo Schwarze <schwarze@openbsd.org>
|
* Copyright (c) 2011, 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
|
||||||
@ -105,7 +105,8 @@ 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 & sp->opts->opts || TBL_OPT_DBOX & sp->opts->opts)
|
if ((TBL_OPT_BOX | TBL_OPT_DBOX) & sp->opts->opts ||
|
||||||
|
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 ? "+" : "|");
|
||||||
|
|
||||||
@ -116,12 +117,12 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (sp->pos) {
|
switch (sp->pos) {
|
||||||
case (TBL_SPAN_HORIZ):
|
case TBL_SPAN_HORIZ:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_SPAN_DHORIZ):
|
case TBL_SPAN_DHORIZ:
|
||||||
tbl_hrule(tp, sp);
|
tbl_hrule(tp, sp);
|
||||||
break;
|
break;
|
||||||
case (TBL_SPAN_DATA):
|
case TBL_SPAN_DATA:
|
||||||
/* Iterate over template headers. */
|
/* Iterate over template headers. */
|
||||||
dp = sp->first;
|
dp = sp->first;
|
||||||
spans = 0;
|
spans = 0;
|
||||||
@ -159,7 +160,8 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||||||
|
|
||||||
/* Vertical frame at the end of each row. */
|
/* Vertical frame at the end of each row. */
|
||||||
|
|
||||||
if (TBL_OPT_BOX & sp->opts->opts || TBL_OPT_DBOX & sp->opts->opts)
|
if ((TBL_OPT_BOX | TBL_OPT_DBOX) & sp->opts->opts ||
|
||||||
|
sp->layout->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 ? "+" : " |");
|
||||||
term_flushln(tp);
|
term_flushln(tp);
|
||||||
@ -266,17 +268,17 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
|
|||||||
assert(dp->layout);
|
assert(dp->layout);
|
||||||
|
|
||||||
switch (dp->pos) {
|
switch (dp->pos) {
|
||||||
case (TBL_DATA_NONE):
|
case TBL_DATA_NONE:
|
||||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||||
return;
|
return;
|
||||||
case (TBL_DATA_HORIZ):
|
case TBL_DATA_HORIZ:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_DATA_NHORIZ):
|
case TBL_DATA_NHORIZ:
|
||||||
tbl_char(tp, '-', col->width);
|
tbl_char(tp, '-', col->width);
|
||||||
return;
|
return;
|
||||||
case (TBL_DATA_NDHORIZ):
|
case TBL_DATA_NDHORIZ:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_DATA_DHORIZ):
|
case TBL_DATA_DHORIZ:
|
||||||
tbl_char(tp, '=', col->width);
|
tbl_char(tp, '=', col->width);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
@ -284,25 +286,25 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (dp->layout->pos) {
|
switch (dp->layout->pos) {
|
||||||
case (TBL_CELL_HORIZ):
|
case TBL_CELL_HORIZ:
|
||||||
tbl_char(tp, '-', col->width);
|
tbl_char(tp, '-', col->width);
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_DHORIZ):
|
case TBL_CELL_DHORIZ:
|
||||||
tbl_char(tp, '=', col->width);
|
tbl_char(tp, '=', col->width);
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_LONG):
|
case TBL_CELL_LONG:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_CENTRE):
|
case TBL_CELL_CENTRE:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_LEFT):
|
case TBL_CELL_LEFT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (TBL_CELL_RIGHT):
|
case TBL_CELL_RIGHT:
|
||||||
tbl_literal(tp, dp, col);
|
tbl_literal(tp, dp, col);
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_NUMBER):
|
case TBL_CELL_NUMBER:
|
||||||
tbl_number(tp, opts, dp, col);
|
tbl_number(tp, opts, dp, col);
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_DOWN):
|
case TBL_CELL_DOWN:
|
||||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -357,17 +359,17 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
|||||||
padl = 0;
|
padl = 0;
|
||||||
|
|
||||||
switch (dp->layout->pos) {
|
switch (dp->layout->pos) {
|
||||||
case (TBL_CELL_LONG):
|
case TBL_CELL_LONG:
|
||||||
padl = term_len(tp, 1);
|
padl = term_len(tp, 1);
|
||||||
padr = padr > padl ? padr - padl : 0;
|
padr = padr > padl ? padr - padl : 0;
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_CENTRE):
|
case TBL_CELL_CENTRE:
|
||||||
if (2 > padr)
|
if (2 > padr)
|
||||||
break;
|
break;
|
||||||
padl = padr / 2;
|
padl = padr / 2;
|
||||||
padr -= padl;
|
padr -= padl;
|
||||||
break;
|
break;
|
||||||
case (TBL_CELL_RIGHT):
|
case TBL_CELL_RIGHT:
|
||||||
padl = padr;
|
padl = padr;
|
||||||
padr = 0;
|
padr = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: term.c,v 1.214 2013/12/25 00:39:31 schwarze Exp $ */
|
/* $Id: term.c,v 1.226 2014/08/01 19:38:29 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, 2011, 2012, 2013 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -23,12 +23,12 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
@ -39,6 +39,7 @@ static void bufferc(struct termp *, char);
|
|||||||
static void encode(struct termp *, const char *, size_t);
|
static void encode(struct termp *, const char *, size_t);
|
||||||
static void encode1(struct termp *, int);
|
static void encode1(struct termp *, int);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_free(struct termp *p)
|
term_free(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -51,7 +52,6 @@ term_free(struct termp *p)
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_begin(struct termp *p, term_margin head,
|
term_begin(struct termp *p, term_margin head,
|
||||||
term_margin foot, const void *arg)
|
term_margin foot, const void *arg)
|
||||||
@ -63,7 +63,6 @@ term_begin(struct termp *p, term_margin head,
|
|||||||
(*p->begin)(p);
|
(*p->begin)(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_end(struct termp *p)
|
term_end(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -72,34 +71,27 @@ term_end(struct termp *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush a line of text. A "line" is loosely defined as being something
|
* Flush a chunk of text. By default, break the output line each time
|
||||||
* that should be followed by a newline, regardless of whether it's
|
* the right margin is reached, and continue output on the next line
|
||||||
* broken apart by newlines getting there. A line can also be a
|
* at the same offset as the chunk itself. By default, also break the
|
||||||
* fragment of a columnar list (`Bl -tag' or `Bl -column'), which does
|
* output line at the end of the chunk.
|
||||||
* not have a trailing newline.
|
|
||||||
*
|
|
||||||
* The following flags may be specified:
|
* The following flags may be specified:
|
||||||
*
|
*
|
||||||
* - TERMP_NOBREAK: this is the most important and is used when making
|
* - TERMP_NOBREAK: Do not break the output line at the right margin,
|
||||||
* columns. In short: don't print a newline and instead expect the
|
* but only at the max right margin. Also, do not break the output
|
||||||
* next call to do the padding up to the start of the next column.
|
* line at the end of the chunk, such that the next call can pad to
|
||||||
* p->trailspace may be set to 0, 1, or 2, depending on how many
|
* the next column. However, if less than p->trailspace blanks,
|
||||||
* space characters are required at the end of the column.
|
* which can be 0, 1, or 2, remain to the right margin, the line
|
||||||
*
|
* will be broken.
|
||||||
* - TERMP_DANGLE: don't newline when TERMP_NOBREAK is specified and
|
* - TERMP_BRIND: If the chunk does not fit and the output line has
|
||||||
* the line is overrun, and don't pad-right if it's underrun.
|
* to be broken, start the next line at the right margin instead
|
||||||
*
|
* of at the offset. Used together with TERMP_NOBREAK for the tags
|
||||||
* - TERMP_HANG: like TERMP_DANGLE, but doesn't newline when
|
* in various kinds of tagged lists.
|
||||||
* overrunning, instead save the position and continue at that point
|
* - TERMP_DANGLE: Do not break the output line at the right margin,
|
||||||
* when the next invocation.
|
* append the next chunk after it even if this one is too long.
|
||||||
*
|
* To be used together with TERMP_NOBREAK.
|
||||||
* In-line line breaking:
|
* - TERMP_HANG: Like TERMP_DANGLE, and also suppress padding before
|
||||||
*
|
* the next chunk if this column is not full.
|
||||||
* If TERMP_NOBREAK is specified and the line overruns the right
|
|
||||||
* margin, it will break and pad-right to the right margin after
|
|
||||||
* writing. If maxrmargin is violated, it will break and continue
|
|
||||||
* writing from the right-margin, which will lead to the above scenario
|
|
||||||
* upon exit. Otherwise, the line will break at the right margin.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
term_flushln(struct termp *p)
|
term_flushln(struct termp *p)
|
||||||
@ -179,9 +171,17 @@ term_flushln(struct termp *p)
|
|||||||
/* Regular word. */
|
/* Regular word. */
|
||||||
/* Break at the hyphen point if we overrun. */
|
/* Break at the hyphen point if we overrun. */
|
||||||
if (vend > vis && vend < bp &&
|
if (vend > vis && vend < bp &&
|
||||||
ASCII_HYPH == p->buf[j])
|
(ASCII_HYPH == p->buf[j] ||
|
||||||
|
ASCII_BREAK == p->buf[j]))
|
||||||
jhy = j;
|
jhy = j;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hyphenation now decided, put back a real
|
||||||
|
* hyphen such that we get the correct width.
|
||||||
|
*/
|
||||||
|
if (ASCII_HYPH == p->buf[j])
|
||||||
|
p->buf[j] = '-';
|
||||||
|
|
||||||
vend += (*p->width)(p, p->buf[j]);
|
vend += (*p->width)(p, p->buf[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ term_flushln(struct termp *p)
|
|||||||
vend -= vis;
|
vend -= vis;
|
||||||
(*p->endline)(p);
|
(*p->endline)(p);
|
||||||
p->viscol = 0;
|
p->viscol = 0;
|
||||||
if (TERMP_NOBREAK & p->flags) {
|
if (TERMP_BRIND & p->flags) {
|
||||||
vbl = p->rmargin;
|
vbl = p->rmargin;
|
||||||
vend += p->rmargin - p->offset;
|
vend += p->rmargin - p->offset;
|
||||||
} else
|
} else
|
||||||
@ -233,6 +233,8 @@ term_flushln(struct termp *p)
|
|||||||
vbl += (*p->width)(p, ' ');
|
vbl += (*p->width)(p, ' ');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (ASCII_BREAK == p->buf[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we definitely know there will be
|
* Now we definitely know there will be
|
||||||
@ -245,12 +247,6 @@ term_flushln(struct termp *p)
|
|||||||
vbl = 0;
|
vbl = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ASCII_HYPH == p->buf[i]) {
|
|
||||||
(*p->letter)(p, '-');
|
|
||||||
p->viscol += (*p->width)(p, '-');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*p->letter)(p, p->buf[i]);
|
(*p->letter)(p, p->buf[i]);
|
||||||
if (8 == p->buf[i])
|
if (8 == p->buf[i])
|
||||||
p->viscol -= (*p->width)(p, p->buf[i-1]);
|
p->viscol -= (*p->width)(p, p->buf[i-1]);
|
||||||
@ -301,7 +297,6 @@ term_flushln(struct termp *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A newline only breaks an existing line; it won't assert vertical
|
* A newline only breaks an existing line; it won't assert vertical
|
||||||
* space. All data in the output buffer is flushed prior to the newline
|
* space. All data in the output buffer is flushed prior to the newline
|
||||||
@ -316,7 +311,6 @@ term_newln(struct termp *p)
|
|||||||
term_flushln(p);
|
term_flushln(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asserts a vertical space (a full, empty line-break between lines).
|
* Asserts a vertical space (a full, empty line-break between lines).
|
||||||
* Note that if used twice, this will cause two blank spaces and so on.
|
* Note that if used twice, this will cause two blank spaces and so on.
|
||||||
@ -345,7 +339,6 @@ term_fontlast(struct termp *p)
|
|||||||
p->fontq[p->fonti] = f;
|
p->fontq[p->fonti] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_fontrepl(struct termp *p, enum termfont f)
|
term_fontrepl(struct termp *p, enum termfont f)
|
||||||
{
|
{
|
||||||
@ -354,7 +347,6 @@ term_fontrepl(struct termp *p, enum termfont f)
|
|||||||
p->fontq[p->fonti] = f;
|
p->fontq[p->fonti] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_fontpush(struct termp *p, enum termfont f)
|
term_fontpush(struct termp *p, enum termfont f)
|
||||||
{
|
{
|
||||||
@ -364,7 +356,6 @@ term_fontpush(struct termp *p, enum termfont f)
|
|||||||
p->fontq[++p->fonti] = f;
|
p->fontq[++p->fonti] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const void *
|
const void *
|
||||||
term_fontq(struct termp *p)
|
term_fontq(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -372,7 +363,6 @@ term_fontq(struct termp *p)
|
|||||||
return(&p->fontq[p->fonti]);
|
return(&p->fontq[p->fonti]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum termfont
|
enum termfont
|
||||||
term_fonttop(struct termp *p)
|
term_fonttop(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -380,7 +370,6 @@ term_fonttop(struct termp *p)
|
|||||||
return(p->fontq[p->fonti]);
|
return(p->fontq[p->fonti]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_fontpopq(struct termp *p, const void *key)
|
term_fontpopq(struct termp *p, const void *key)
|
||||||
{
|
{
|
||||||
@ -390,7 +379,6 @@ term_fontpopq(struct termp *p, const void *key)
|
|||||||
assert(p->fonti >= 0);
|
assert(p->fonti >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
term_fontpop(struct termp *p)
|
term_fontpop(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -456,17 +444,17 @@ term_word(struct termp *p, const char *word)
|
|||||||
word++;
|
word++;
|
||||||
esc = mandoc_escape(&word, &seq, &sz);
|
esc = mandoc_escape(&word, &seq, &sz);
|
||||||
if (ESCAPE_ERROR == esc)
|
if (ESCAPE_ERROR == esc)
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
if (TERMENC_ASCII != p->enc)
|
if (TERMENC_ASCII != p->enc)
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case (ESCAPE_UNICODE):
|
case ESCAPE_UNICODE:
|
||||||
uc = mchars_num2uc(seq + 1, sz - 1);
|
uc = mchars_num2uc(seq + 1, sz - 1);
|
||||||
if ('\0' == uc)
|
if ('\0' == uc)
|
||||||
break;
|
break;
|
||||||
encode1(p, uc);
|
encode1(p, uc);
|
||||||
continue;
|
continue;
|
||||||
case (ESCAPE_SPECIAL):
|
case ESCAPE_SPECIAL:
|
||||||
uc = mchars_spec2cp(p->symtab, seq, sz);
|
uc = mchars_spec2cp(p->symtab, seq, sz);
|
||||||
if (uc <= 0)
|
if (uc <= 0)
|
||||||
break;
|
break;
|
||||||
@ -477,45 +465,45 @@ term_word(struct termp *p, const char *word)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case (ESCAPE_UNICODE):
|
case ESCAPE_UNICODE:
|
||||||
encode1(p, '?');
|
encode1(p, '?');
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_NUMBERED):
|
case ESCAPE_NUMBERED:
|
||||||
c = mchars_num2char(seq, sz);
|
c = mchars_num2char(seq, sz);
|
||||||
if ('\0' != c)
|
if ('\0' != c)
|
||||||
encode(p, &c, 1);
|
encode(p, &c, 1);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_SPECIAL):
|
case ESCAPE_SPECIAL:
|
||||||
cp = mchars_spec2str(p->symtab, seq, sz, &ssz);
|
cp = mchars_spec2str(p->symtab, seq, sz, &ssz);
|
||||||
if (NULL != cp)
|
if (NULL != cp)
|
||||||
encode(p, cp, ssz);
|
encode(p, cp, ssz);
|
||||||
else if (1 == ssz)
|
else if (1 == ssz)
|
||||||
encode(p, seq, sz);
|
encode(p, seq, sz);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONTBOLD):
|
case ESCAPE_FONTBOLD:
|
||||||
term_fontrepl(p, TERMFONT_BOLD);
|
term_fontrepl(p, TERMFONT_BOLD);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONTITALIC):
|
case ESCAPE_FONTITALIC:
|
||||||
term_fontrepl(p, TERMFONT_UNDER);
|
term_fontrepl(p, TERMFONT_UNDER);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_FONTBI):
|
case ESCAPE_FONTBI:
|
||||||
term_fontrepl(p, TERMFONT_BI);
|
term_fontrepl(p, TERMFONT_BI);
|
||||||
break;
|
break;
|
||||||
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;
|
break;
|
||||||
case (ESCAPE_FONTPREV):
|
case ESCAPE_FONTPREV:
|
||||||
term_fontlast(p);
|
term_fontlast(p);
|
||||||
break;
|
break;
|
||||||
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;
|
break;
|
||||||
case (ESCAPE_SKIPCHAR):
|
case ESCAPE_SKIPCHAR:
|
||||||
p->flags |= TERMP_SKIPCHAR;
|
p->flags |= TERMP_SKIPCHAR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -534,7 +522,7 @@ adjbuf(struct termp *p, size_t sz)
|
|||||||
while (sz >= p->maxcols)
|
while (sz >= p->maxcols)
|
||||||
p->maxcols <<= 2;
|
p->maxcols <<= 2;
|
||||||
|
|
||||||
p->buf = mandoc_realloc(p->buf, sizeof(int) * p->maxcols);
|
p->buf = mandoc_reallocarray(p->buf, p->maxcols, sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -619,6 +607,36 @@ encode(struct termp *p, const char *word, size_t sz)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
term_setwidth(struct termp *p, const char *wstr)
|
||||||
|
{
|
||||||
|
struct roffsu su;
|
||||||
|
size_t width;
|
||||||
|
int iop;
|
||||||
|
|
||||||
|
iop = 0;
|
||||||
|
width = 0;
|
||||||
|
if (NULL != wstr) {
|
||||||
|
switch (*wstr) {
|
||||||
|
case '+':
|
||||||
|
iop = 1;
|
||||||
|
wstr++;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
iop = -1;
|
||||||
|
wstr++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (a2roffsu(wstr, &su, SCALE_MAX))
|
||||||
|
width = term_hspan(p, &su);
|
||||||
|
else
|
||||||
|
iop = 0;
|
||||||
|
}
|
||||||
|
(*p->setwidth)(p, iop, width);
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
term_len(const struct termp *p, size_t sz)
|
term_len(const struct termp *p, size_t sz)
|
||||||
{
|
{
|
||||||
@ -644,7 +662,8 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
int ssz, skip, c;
|
int ssz, skip, c;
|
||||||
const char *seq, *rhs;
|
const char *seq, *rhs;
|
||||||
enum mandoc_esc esc;
|
enum mandoc_esc esc;
|
||||||
static const char rej[] = { '\\', ASCII_HYPH, ASCII_NBRSP, '\0' };
|
static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH,
|
||||||
|
ASCII_BREAK, '\0' };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Account for escaped sequences within string length
|
* Account for escaped sequences within string length
|
||||||
@ -659,26 +678,25 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
for (i = 0; i < rsz; i++)
|
for (i = 0; i < rsz; i++)
|
||||||
sz += cond_width(p, *cp++, &skip);
|
sz += cond_width(p, *cp++, &skip);
|
||||||
|
|
||||||
c = 0;
|
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case ('\\'):
|
case '\\':
|
||||||
cp++;
|
cp++;
|
||||||
esc = mandoc_escape(&cp, &seq, &ssz);
|
esc = mandoc_escape(&cp, &seq, &ssz);
|
||||||
if (ESCAPE_ERROR == esc)
|
if (ESCAPE_ERROR == esc)
|
||||||
return(sz);
|
continue;
|
||||||
|
|
||||||
if (TERMENC_ASCII != p->enc)
|
if (TERMENC_ASCII != p->enc)
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case (ESCAPE_UNICODE):
|
case ESCAPE_UNICODE:
|
||||||
c = mchars_num2uc
|
c = mchars_num2uc(seq + 1,
|
||||||
(seq + 1, ssz - 1);
|
ssz - 1);
|
||||||
if ('\0' == c)
|
if ('\0' == c)
|
||||||
break;
|
break;
|
||||||
sz += cond_width(p, c, &skip);
|
sz += cond_width(p, c, &skip);
|
||||||
continue;
|
continue;
|
||||||
case (ESCAPE_SPECIAL):
|
case ESCAPE_SPECIAL:
|
||||||
c = mchars_spec2cp
|
c = mchars_spec2cp(p->symtab,
|
||||||
(p->symtab, seq, ssz);
|
seq, ssz);
|
||||||
if (c <= 0)
|
if (c <= 0)
|
||||||
break;
|
break;
|
||||||
sz += cond_width(p, c, &skip);
|
sz += cond_width(p, c, &skip);
|
||||||
@ -690,17 +708,17 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
rhs = NULL;
|
rhs = NULL;
|
||||||
|
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
case (ESCAPE_UNICODE):
|
case ESCAPE_UNICODE:
|
||||||
sz += cond_width(p, '?', &skip);
|
sz += cond_width(p, '?', &skip);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_NUMBERED):
|
case ESCAPE_NUMBERED:
|
||||||
c = mchars_num2char(seq, ssz);
|
c = mchars_num2char(seq, ssz);
|
||||||
if ('\0' != c)
|
if ('\0' != c)
|
||||||
sz += cond_width(p, c, &skip);
|
sz += cond_width(p, c, &skip);
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_SPECIAL):
|
case ESCAPE_SPECIAL:
|
||||||
rhs = mchars_spec2str
|
rhs = mchars_spec2str(p->symtab,
|
||||||
(p->symtab, seq, ssz, &rsz);
|
seq, ssz, &rsz);
|
||||||
|
|
||||||
if (ssz != 1 || rhs)
|
if (ssz != 1 || rhs)
|
||||||
break;
|
break;
|
||||||
@ -708,7 +726,7 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
rhs = seq;
|
rhs = seq;
|
||||||
rsz = ssz;
|
rsz = ssz;
|
||||||
break;
|
break;
|
||||||
case (ESCAPE_SKIPCHAR):
|
case ESCAPE_SKIPCHAR:
|
||||||
skip = 1;
|
skip = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -726,13 +744,15 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
for (i = 0; i < rsz; i++)
|
for (i = 0; i < rsz; i++)
|
||||||
sz += (*p->width)(p, *rhs++);
|
sz += (*p->width)(p, *rhs++);
|
||||||
break;
|
break;
|
||||||
case (ASCII_NBRSP):
|
case ASCII_NBRSP:
|
||||||
sz += cond_width(p, ' ', &skip);
|
sz += cond_width(p, ' ', &skip);
|
||||||
cp++;
|
cp++;
|
||||||
break;
|
break;
|
||||||
case (ASCII_HYPH):
|
case ASCII_HYPH:
|
||||||
sz += cond_width(p, '-', &skip);
|
sz += cond_width(p, '-', &skip);
|
||||||
cp++;
|
cp++;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case ASCII_BREAK:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -742,40 +762,38 @@ term_strlen(const struct termp *p, const char *cp)
|
|||||||
return(sz);
|
return(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
size_t
|
size_t
|
||||||
term_vspan(const struct termp *p, const struct roffsu *su)
|
term_vspan(const struct termp *p, const struct roffsu *su)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
|
||||||
switch (su->unit) {
|
switch (su->unit) {
|
||||||
case (SCALE_CM):
|
case SCALE_CM:
|
||||||
r = su->scale * 2;
|
r = su->scale * 2.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_IN):
|
case SCALE_IN:
|
||||||
r = su->scale * 6;
|
r = su->scale * 6.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_PC):
|
case SCALE_PC:
|
||||||
r = su->scale;
|
r = su->scale;
|
||||||
break;
|
break;
|
||||||
case (SCALE_PT):
|
case SCALE_PT:
|
||||||
r = su->scale / 8;
|
r = su->scale / 8.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_MM):
|
case SCALE_MM:
|
||||||
r = su->scale / 1000;
|
r = su->scale / 1000.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_VS):
|
case SCALE_VS:
|
||||||
r = su->scale;
|
r = su->scale;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r = su->scale - 1;
|
r = su->scale - 1.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0.0)
|
if (r < 0.0)
|
||||||
r = 0.0;
|
r = 0.0;
|
||||||
return(/* LINTED */(size_t)
|
return((size_t)(r + 0.0005));
|
||||||
r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@ -783,9 +801,8 @@ term_hspan(const struct termp *p, const struct roffsu *su)
|
|||||||
{
|
{
|
||||||
double v;
|
double v;
|
||||||
|
|
||||||
v = ((*p->hspan)(p, su));
|
v = (*p->hspan)(p, su);
|
||||||
if (v < 0.0)
|
if (v < 0.0)
|
||||||
v = 0.0;
|
v = 0.0;
|
||||||
return((size_t) /* LINTED */
|
return((size_t)(v + 0.0005));
|
||||||
v);
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $Id: term.h,v 1.97 2013/12/25 00:39:31 schwarze Exp $ */
|
/* $Id: term.h,v 1.101 2014/04/20 16:46: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) 2011, 2012, 2013 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
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -57,6 +57,7 @@ struct termp {
|
|||||||
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. */
|
||||||
|
size_t lastrmargin; /* Right margin before the last ll. */
|
||||||
size_t rmargin; /* Current right margin. */
|
size_t rmargin; /* Current right margin. */
|
||||||
size_t maxrmargin; /* Max right margin. */
|
size_t maxrmargin; /* Max right margin. */
|
||||||
size_t maxcols; /* Max size of buf. */
|
size_t maxcols; /* Max size of buf. */
|
||||||
@ -76,11 +77,12 @@ struct termp {
|
|||||||
#define TERMP_PREKEEP (1 << 6) /* ...starting with the next one. */
|
#define TERMP_PREKEEP (1 << 6) /* ...starting with the next one. */
|
||||||
#define TERMP_SKIPCHAR (1 << 7) /* Skip the next character. */
|
#define TERMP_SKIPCHAR (1 << 7) /* Skip the next character. */
|
||||||
#define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */
|
#define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */
|
||||||
#define TERMP_DANGLE (1 << 9) /* See term_flushln(). */
|
#define TERMP_BRIND (1 << 9) /* See term_flushln(). */
|
||||||
#define TERMP_HANG (1 << 10) /* See term_flushln(). */
|
#define TERMP_DANGLE (1 << 10) /* See term_flushln(). */
|
||||||
#define TERMP_NOSPLIT (1 << 11) /* See termp_an_pre/post(). */
|
#define TERMP_HANG (1 << 11) /* See term_flushln(). */
|
||||||
#define TERMP_SPLIT (1 << 12) /* See termp_an_pre/post(). */
|
#define TERMP_NOSPLIT (1 << 12) /* See termp_an_pre/post(). */
|
||||||
#define TERMP_ANPREC (1 << 13) /* See termp_an_pre(). */
|
#define TERMP_SPLIT (1 << 13) /* See termp_an_pre/post(). */
|
||||||
|
#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. */
|
struct mchars *symtab; /* Encoded-symbol table. */
|
||||||
@ -94,6 +96,7 @@ struct termp {
|
|||||||
void (*end)(struct termp *);
|
void (*end)(struct termp *);
|
||||||
void (*endline)(struct termp *);
|
void (*endline)(struct termp *);
|
||||||
void (*advance)(struct termp *, size_t);
|
void (*advance)(struct termp *, size_t);
|
||||||
|
void (*setwidth)(struct termp *, int, size_t);
|
||||||
size_t (*width)(const struct termp *, int);
|
size_t (*width)(const struct termp *, int);
|
||||||
double (*hspan)(const struct termp *,
|
double (*hspan)(const struct termp *,
|
||||||
const struct roffsu *);
|
const struct roffsu *);
|
||||||
@ -112,6 +115,7 @@ void term_begin(struct termp *, term_margin,
|
|||||||
term_margin, const void *);
|
term_margin, const void *);
|
||||||
void term_end(struct termp *);
|
void term_end(struct termp *);
|
||||||
|
|
||||||
|
void term_setwidth(struct termp *, const char *);
|
||||||
size_t term_hspan(const struct termp *,
|
size_t term_hspan(const struct termp *,
|
||||||
const struct roffsu *);
|
const struct roffsu *);
|
||||||
size_t term_vspan(const struct termp *,
|
size_t term_vspan(const struct termp *,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* $Id: term_ascii.c,v 1.21 2013/06/01 14:27:20 schwarze Exp $ */
|
/* $Id: term_ascii.c,v 1.27 2014/08/01 19:25:52 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
|
||||||
@ -20,7 +21,6 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#ifdef USE_WCHAR
|
#ifdef USE_WCHAR
|
||||||
# include <locale.h>
|
# include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
@ -33,6 +33,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
@ -57,6 +58,7 @@ static void ascii_begin(struct termp *);
|
|||||||
static void ascii_end(struct termp *);
|
static void ascii_end(struct termp *);
|
||||||
static void ascii_endline(struct termp *);
|
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);
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
#ifdef USE_WCHAR
|
||||||
static void locale_advance(struct termp *, size_t);
|
static void locale_advance(struct termp *, size_t);
|
||||||
@ -65,6 +67,7 @@ static void locale_letter(struct termp *, int);
|
|||||||
static size_t locale_width(const struct termp *, int);
|
static size_t locale_width(const struct termp *, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static struct termp *
|
static struct termp *
|
||||||
ascii_init(enum termenc enc, char *outopts)
|
ascii_init(enum termenc enc, char *outopts)
|
||||||
{
|
{
|
||||||
@ -75,7 +78,7 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
p = mandoc_calloc(1, sizeof(struct termp));
|
p = mandoc_calloc(1, sizeof(struct termp));
|
||||||
|
|
||||||
p->tabwidth = 5;
|
p->tabwidth = 5;
|
||||||
p->defrmargin = 78;
|
p->defrmargin = p->lastrmargin = 78;
|
||||||
|
|
||||||
p->begin = ascii_begin;
|
p->begin = ascii_begin;
|
||||||
p->end = ascii_end;
|
p->end = ascii_end;
|
||||||
@ -86,6 +89,7 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
p->advance = ascii_advance;
|
p->advance = ascii_advance;
|
||||||
p->endline = ascii_endline;
|
p->endline = ascii_endline;
|
||||||
p->letter = ascii_letter;
|
p->letter = ascii_letter;
|
||||||
|
p->setwidth = ascii_setwidth;
|
||||||
p->width = ascii_width;
|
p->width = ascii_width;
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
#ifdef USE_WCHAR
|
||||||
@ -110,13 +114,13 @@ ascii_init(enum termenc enc, char *outopts)
|
|||||||
|
|
||||||
while (outopts && *outopts)
|
while (outopts && *outopts)
|
||||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||||
case (0):
|
case 0:
|
||||||
p->defindent = (size_t)atoi(v);
|
p->defindent = (size_t)atoi(v);
|
||||||
break;
|
break;
|
||||||
case (1):
|
case 1:
|
||||||
p->defrmargin = (size_t)atoi(v);
|
p->defrmargin = (size_t)atoi(v);
|
||||||
break;
|
break;
|
||||||
case (2):
|
case 2:
|
||||||
/*
|
/*
|
||||||
* Temporary, undocumented mode
|
* Temporary, undocumented mode
|
||||||
* to imitate mdoc(7) output style.
|
* to imitate mdoc(7) output style.
|
||||||
@ -149,7 +153,6 @@ utf8_alloc(char *outopts)
|
|||||||
return(ascii_init(TERMENC_UTF8, outopts));
|
return(ascii_init(TERMENC_UTF8, outopts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
locale_alloc(char *outopts)
|
locale_alloc(char *outopts)
|
||||||
{
|
{
|
||||||
@ -157,7 +160,21 @@ locale_alloc(char *outopts)
|
|||||||
return(ascii_init(TERMENC_LOCALE, outopts));
|
return(ascii_init(TERMENC_LOCALE, outopts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
static void
|
||||||
|
ascii_setwidth(struct termp *p, int iop, size_t width)
|
||||||
|
{
|
||||||
|
|
||||||
|
p->rmargin = p->defrmargin;
|
||||||
|
if (0 < iop)
|
||||||
|
p->defrmargin += width;
|
||||||
|
else if (0 > iop)
|
||||||
|
p->defrmargin -= width;
|
||||||
|
else
|
||||||
|
p->defrmargin = width ? width : p->lastrmargin;
|
||||||
|
p->lastrmargin = p->rmargin;
|
||||||
|
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ascii_width(const struct termp *p, int c)
|
ascii_width(const struct termp *p, int c)
|
||||||
{
|
{
|
||||||
@ -172,7 +189,6 @@ ascii_free(void *arg)
|
|||||||
term_free((struct termp *)arg);
|
term_free((struct termp *)arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
ascii_letter(struct termp *p, int c)
|
ascii_letter(struct termp *p, int c)
|
||||||
{
|
{
|
||||||
@ -194,7 +210,6 @@ ascii_end(struct termp *p)
|
|||||||
(*p->footf)(p, p->argf);
|
(*p->footf)(p, p->argf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
ascii_endline(struct termp *p)
|
ascii_endline(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -202,7 +217,6 @@ ascii_endline(struct termp *p)
|
|||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
ascii_advance(struct termp *p, size_t len)
|
ascii_advance(struct termp *p, size_t len)
|
||||||
{
|
{
|
||||||
@ -212,7 +226,6 @@ ascii_advance(struct termp *p, size_t len)
|
|||||||
putchar(' ');
|
putchar(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static double
|
static double
|
||||||
ascii_hspan(const struct termp *p, const struct roffsu *su)
|
ascii_hspan(const struct termp *p, const struct roffsu *su)
|
||||||
{
|
{
|
||||||
@ -224,23 +237,23 @@ ascii_hspan(const struct termp *p, const struct roffsu *su)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (su->unit) {
|
switch (su->unit) {
|
||||||
case (SCALE_CM):
|
case SCALE_CM:
|
||||||
r = 4 * su->scale;
|
r = su->scale * 4.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_IN):
|
case SCALE_IN:
|
||||||
r = 10 * su->scale;
|
r = su->scale * 10.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_PC):
|
case SCALE_PC:
|
||||||
r = (10 * su->scale) / 6;
|
r = (su->scale * 10.0) / 6.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_PT):
|
case SCALE_PT:
|
||||||
r = (10 * su->scale) / 72;
|
r = (su->scale * 10.0) / 72.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_MM):
|
case SCALE_MM:
|
||||||
r = su->scale / 1000;
|
r = su->scale / 1000.0;
|
||||||
break;
|
break;
|
||||||
case (SCALE_VS):
|
case SCALE_VS:
|
||||||
r = su->scale * 2 - 1;
|
r = su->scale * 2.0 - 1.0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r = su->scale;
|
r = su->scale;
|
||||||
@ -251,16 +264,19 @@ ascii_hspan(const struct termp *p, const struct roffsu *su)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WCHAR
|
#ifdef USE_WCHAR
|
||||||
/* ARGSUSED */
|
|
||||||
static size_t
|
static size_t
|
||||||
locale_width(const struct termp *p, int c)
|
locale_width(const struct termp *p, int c)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
return((rc = wcwidth(c)) < 0 ? 0 : rc);
|
if (c == ASCII_NBRSP)
|
||||||
|
c = ' ';
|
||||||
|
rc = wcwidth(c);
|
||||||
|
if (rc < 0)
|
||||||
|
rc = 0;
|
||||||
|
return(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
locale_advance(struct termp *p, size_t len)
|
locale_advance(struct termp *p, size_t len)
|
||||||
{
|
{
|
||||||
@ -270,7 +286,6 @@ locale_advance(struct termp *p, size_t len)
|
|||||||
putwchar(L' ');
|
putwchar(L' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
locale_endline(struct termp *p)
|
locale_endline(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -278,7 +293,6 @@ locale_endline(struct termp *p)
|
|||||||
putwchar(L'\n');
|
putwchar(L'\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
locale_letter(struct termp *p, int c)
|
locale_letter(struct termp *p, int c)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* $Id: term_ps.c,v 1.54 2011/10/16 12:20:34 schwarze Exp $ */
|
/* $Id: term_ps.c,v 1.62 2014/08/01 19:25:52 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
|
||||||
@ -30,6 +31,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "mandoc.h"
|
#include "mandoc.h"
|
||||||
|
#include "mandoc_aux.h"
|
||||||
#include "out.h"
|
#include "out.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
@ -38,11 +40,11 @@
|
|||||||
#define PS_BUFSLOP 128
|
#define PS_BUFSLOP 128
|
||||||
|
|
||||||
/* Convert PostScript point "x" to an AFM unit. */
|
/* Convert PostScript point "x" to an AFM unit. */
|
||||||
#define PNT2AFM(p, x) /* LINTED */ \
|
#define PNT2AFM(p, x) \
|
||||||
(size_t)((double)(x) * (1000.0 / (double)(p)->ps->scale))
|
(size_t)((double)(x) * (1000.0 / (double)(p)->ps->scale))
|
||||||
|
|
||||||
/* Convert an AFM unit "x" to a PostScript points */
|
/* Convert an AFM unit "x" to a PostScript points */
|
||||||
#define AFM2PNT(p, x) /* LINTED */ \
|
#define AFM2PNT(p, x) \
|
||||||
((double)(x) / (1000.0 / (double)(p)->ps->scale))
|
((double)(x) / (1000.0 / (double)(p)->ps->scale))
|
||||||
|
|
||||||
struct glyph {
|
struct glyph {
|
||||||
@ -74,6 +76,7 @@ struct termp_ps {
|
|||||||
size_t bottom; /* body bottom (AFM units) */
|
size_t bottom; /* body bottom (AFM units) */
|
||||||
size_t height; /* page height (AFM units */
|
size_t height; /* page height (AFM units */
|
||||||
size_t width; /* page width (AFM units) */
|
size_t width; /* page width (AFM units) */
|
||||||
|
size_t lastwidth; /* page width before last ll */
|
||||||
size_t left; /* body left (AFM units) */
|
size_t left; /* body left (AFM units) */
|
||||||
size_t header; /* header pos (AFM units) */
|
size_t header; /* header pos (AFM units) */
|
||||||
size_t footer; /* footer pos (AFM units) */
|
size_t footer; /* footer pos (AFM units) */
|
||||||
@ -97,9 +100,13 @@ static void ps_growbuf(struct termp *, size_t);
|
|||||||
static void ps_letter(struct termp *, int);
|
static void ps_letter(struct termp *, int);
|
||||||
static void ps_pclose(struct termp *);
|
static void ps_pclose(struct termp *);
|
||||||
static void ps_pletter(struct termp *, int);
|
static void ps_pletter(struct termp *, int);
|
||||||
|
#if __GNUC__ - 0 >= 4
|
||||||
|
__attribute__((__format__ (__printf__, 2, 3)))
|
||||||
|
#endif
|
||||||
static void ps_printf(struct termp *, const char *, ...);
|
static void ps_printf(struct termp *, const char *, ...);
|
||||||
static void ps_putchar(struct termp *, char);
|
static void ps_putchar(struct termp *, char);
|
||||||
static void ps_setfont(struct termp *, enum termfont);
|
static void ps_setfont(struct termp *, enum termfont);
|
||||||
|
static void ps_setwidth(struct termp *, int, size_t);
|
||||||
static struct termp *pspdf_alloc(char *);
|
static struct termp *pspdf_alloc(char *);
|
||||||
static void pdf_obj(struct termp *, size_t);
|
static void pdf_obj(struct termp *, size_t);
|
||||||
|
|
||||||
@ -445,6 +452,7 @@ pspdf_alloc(char *outopts)
|
|||||||
p->endline = ps_endline;
|
p->endline = ps_endline;
|
||||||
p->hspan = ps_hspan;
|
p->hspan = ps_hspan;
|
||||||
p->letter = ps_letter;
|
p->letter = ps_letter;
|
||||||
|
p->setwidth = ps_setwidth;
|
||||||
p->width = ps_width;
|
p->width = ps_width;
|
||||||
|
|
||||||
toks[0] = "paper";
|
toks[0] = "paper";
|
||||||
@ -454,7 +462,7 @@ pspdf_alloc(char *outopts)
|
|||||||
|
|
||||||
while (outopts && *outopts)
|
while (outopts && *outopts)
|
||||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||||
case (0):
|
case 0:
|
||||||
pp = v;
|
pp = v;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -504,16 +512,14 @@ pspdf_alloc(char *outopts)
|
|||||||
|
|
||||||
/* Margins are 1/9 the page x and y. */
|
/* Margins are 1/9 the page x and y. */
|
||||||
|
|
||||||
marginx = /* LINTED */
|
marginx = (size_t)((double)pagex / 9.0);
|
||||||
(size_t)((double)pagex / 9.0);
|
marginy = (size_t)((double)pagey / 9.0);
|
||||||
marginy = /* LINTED */
|
|
||||||
(size_t)((double)pagey / 9.0);
|
|
||||||
|
|
||||||
/* Line-height is 1.4em. */
|
/* Line-height is 1.4em. */
|
||||||
|
|
||||||
lineheight = PNT2AFM(p, ((double)p->ps->scale * 1.4));
|
lineheight = PNT2AFM(p, ((double)p->ps->scale * 1.4));
|
||||||
|
|
||||||
p->ps->width = (size_t)pagex;
|
p->ps->width = p->ps->lastwidth = (size_t)pagex;
|
||||||
p->ps->height = (size_t)pagey;
|
p->ps->height = (size_t)pagey;
|
||||||
p->ps->header = pagey - (marginy / 2) - (lineheight / 2);
|
p->ps->header = pagey - (marginy / 2) - (lineheight / 2);
|
||||||
p->ps->top = pagey - marginy;
|
p->ps->top = pagey - marginy;
|
||||||
@ -526,6 +532,20 @@ pspdf_alloc(char *outopts)
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ps_setwidth(struct termp *p, int iop, size_t width)
|
||||||
|
{
|
||||||
|
size_t lastwidth;
|
||||||
|
|
||||||
|
lastwidth = p->ps->width;
|
||||||
|
if (0 < iop)
|
||||||
|
p->ps->width += width;
|
||||||
|
else if (0 > iop)
|
||||||
|
p->ps->width -= width;
|
||||||
|
else
|
||||||
|
p->ps->width = width ? width : p->ps->lastwidth;
|
||||||
|
p->ps->lastwidth = lastwidth;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pspdf_free(void *arg)
|
pspdf_free(void *arg)
|
||||||
@ -543,7 +563,6 @@ pspdf_free(void *arg)
|
|||||||
term_free(p);
|
term_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_printf(struct termp *p, const char *fmt, ...)
|
ps_printf(struct termp *p, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -561,8 +580,7 @@ ps_printf(struct termp *p, const char *fmt, ...)
|
|||||||
if ( ! (PS_MARGINS & p->ps->flags)) {
|
if ( ! (PS_MARGINS & p->ps->flags)) {
|
||||||
len = vprintf(fmt, ap);
|
len = vprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
p->ps->pdfbytes += /* LINTED */
|
p->ps->pdfbytes += len < 0 ? 0 : (size_t)len;
|
||||||
len < 0 ? 0 : (size_t)len;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +600,6 @@ ps_printf(struct termp *p, const char *fmt, ...)
|
|||||||
p->ps->psmargcur = strlen(p->ps->psmarg);
|
p->ps->psmargcur = strlen(p->ps->psmarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_putchar(struct termp *p, char c)
|
ps_putchar(struct termp *p, char c)
|
||||||
{
|
{
|
||||||
@ -591,7 +608,6 @@ ps_putchar(struct termp *p, char c)
|
|||||||
/* See ps_printf(). */
|
/* See ps_printf(). */
|
||||||
|
|
||||||
if ( ! (PS_MARGINS & p->ps->flags)) {
|
if ( ! (PS_MARGINS & p->ps->flags)) {
|
||||||
/* LINTED */
|
|
||||||
putchar(c);
|
putchar(c);
|
||||||
p->ps->pdfbytes++;
|
p->ps->pdfbytes++;
|
||||||
return;
|
return;
|
||||||
@ -604,7 +620,6 @@ ps_putchar(struct termp *p, char c)
|
|||||||
p->ps->psmarg[pos] = '\0';
|
p->ps->psmarg[pos] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pdf_obj(struct termp *p, size_t obj)
|
pdf_obj(struct termp *p, size_t obj)
|
||||||
{
|
{
|
||||||
@ -613,20 +628,14 @@ pdf_obj(struct termp *p, size_t obj)
|
|||||||
|
|
||||||
if ((obj - 1) >= p->ps->pdfobjsz) {
|
if ((obj - 1) >= p->ps->pdfobjsz) {
|
||||||
p->ps->pdfobjsz = obj + 128;
|
p->ps->pdfobjsz = obj + 128;
|
||||||
p->ps->pdfobjs = realloc
|
p->ps->pdfobjs = mandoc_reallocarray(p->ps->pdfobjs,
|
||||||
(p->ps->pdfobjs,
|
p->ps->pdfobjsz, sizeof(size_t));
|
||||||
p->ps->pdfobjsz * sizeof(size_t));
|
|
||||||
if (NULL == p->ps->pdfobjs) {
|
|
||||||
perror(NULL);
|
|
||||||
exit((int)MANDOCLEVEL_SYSERR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->ps->pdfobjs[(int)obj - 1] = p->ps->pdfbytes;
|
p->ps->pdfobjs[(int)obj - 1] = p->ps->pdfbytes;
|
||||||
ps_printf(p, "%zu 0 obj\n", obj);
|
ps_printf(p, "%zu 0 obj\n", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_closepage(struct termp *p)
|
ps_closepage(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -680,8 +689,6 @@ ps_closepage(struct termp *p)
|
|||||||
p->ps->flags |= PS_NEWPAGE;
|
p->ps->flags |= PS_NEWPAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
static void
|
||||||
ps_end(struct termp *p)
|
ps_end(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -716,11 +723,9 @@ ps_end(struct termp *p)
|
|||||||
ps_printf(p, "/Kids [");
|
ps_printf(p, "/Kids [");
|
||||||
|
|
||||||
for (i = 0; i < p->ps->pages; i++)
|
for (i = 0; i < p->ps->pages; i++)
|
||||||
ps_printf(p, " %zu 0 R", i * 4 +
|
ps_printf(p, " %zu 0 R", i * 4 + p->ps->pdfbody + 3);
|
||||||
p->ps->pdfbody + 3);
|
|
||||||
|
|
||||||
base = (p->ps->pages - 1) * 4 +
|
base = (p->ps->pages - 1) * 4 + p->ps->pdfbody + 4;
|
||||||
p->ps->pdfbody + 4;
|
|
||||||
|
|
||||||
ps_printf(p, "]\n>>\nendobj\n");
|
ps_printf(p, "]\n>>\nendobj\n");
|
||||||
pdf_obj(p, base);
|
pdf_obj(p, base);
|
||||||
@ -748,7 +753,6 @@ ps_end(struct termp *p)
|
|||||||
ps_printf(p, "%%%%EOF\n");
|
ps_printf(p, "%%%%EOF\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_begin(struct termp *p)
|
ps_begin(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -824,7 +828,7 @@ ps_begin(struct termp *p)
|
|||||||
ps_printf(p, "<<\n");
|
ps_printf(p, "<<\n");
|
||||||
ps_printf(p, "/Type /Font\n");
|
ps_printf(p, "/Type /Font\n");
|
||||||
ps_printf(p, "/Subtype /Type1\n");
|
ps_printf(p, "/Subtype /Type1\n");
|
||||||
ps_printf(p, "/Name /F%zu\n", i);
|
ps_printf(p, "/Name /F%d\n", i);
|
||||||
ps_printf(p, "/BaseFont /%s\n", fonts[i].name);
|
ps_printf(p, "/BaseFont /%s\n", fonts[i].name);
|
||||||
ps_printf(p, ">>\n");
|
ps_printf(p, ">>\n");
|
||||||
}
|
}
|
||||||
@ -837,7 +841,6 @@ ps_begin(struct termp *p)
|
|||||||
ps_setfont(p, TERMFONT_NONE);
|
ps_setfont(p, TERMFONT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_pletter(struct termp *p, int c)
|
ps_pletter(struct termp *p, int c)
|
||||||
{
|
{
|
||||||
@ -851,8 +854,7 @@ ps_pletter(struct termp *p, int c)
|
|||||||
if (PS_NEWPAGE & p->ps->flags) {
|
if (PS_NEWPAGE & p->ps->flags) {
|
||||||
if (TERMTYPE_PS == p->type) {
|
if (TERMTYPE_PS == p->type) {
|
||||||
ps_printf(p, "%%%%Page: %zu %zu\n",
|
ps_printf(p, "%%%%Page: %zu %zu\n",
|
||||||
p->ps->pages + 1,
|
p->ps->pages + 1, p->ps->pages + 1);
|
||||||
p->ps->pages + 1);
|
|
||||||
ps_printf(p, "/%s %zu selectfont\n",
|
ps_printf(p, "/%s %zu selectfont\n",
|
||||||
fonts[(int)p->ps->lastf].name,
|
fonts[(int)p->ps->lastf].name,
|
||||||
p->ps->scale);
|
p->ps->scale);
|
||||||
@ -861,8 +863,7 @@ ps_pletter(struct termp *p, int c)
|
|||||||
p->ps->pages * 4);
|
p->ps->pages * 4);
|
||||||
ps_printf(p, "<<\n");
|
ps_printf(p, "<<\n");
|
||||||
ps_printf(p, "/Length %zu 0 R\n",
|
ps_printf(p, "/Length %zu 0 R\n",
|
||||||
p->ps->pdfbody + 1 +
|
p->ps->pdfbody + 1 + p->ps->pages * 4);
|
||||||
p->ps->pages * 4);
|
|
||||||
ps_printf(p, ">>\nstream\n");
|
ps_printf(p, ">>\nstream\n");
|
||||||
}
|
}
|
||||||
p->ps->pdflastpg = p->ps->pdfbytes;
|
p->ps->pdflastpg = p->ps->pdfbytes;
|
||||||
@ -877,8 +878,7 @@ ps_pletter(struct termp *p, int c)
|
|||||||
if ( ! (PS_INLINE & p->ps->flags)) {
|
if ( ! (PS_INLINE & p->ps->flags)) {
|
||||||
if (TERMTYPE_PS != p->type) {
|
if (TERMTYPE_PS != p->type) {
|
||||||
ps_printf(p, "BT\n/F%d %zu Tf\n",
|
ps_printf(p, "BT\n/F%d %zu Tf\n",
|
||||||
(int)p->ps->lastf,
|
(int)p->ps->lastf, p->ps->scale);
|
||||||
p->ps->scale);
|
|
||||||
ps_printf(p, "%.3f %.3f Td\n(",
|
ps_printf(p, "%.3f %.3f Td\n(",
|
||||||
AFM2PNT(p, p->ps->pscol),
|
AFM2PNT(p, p->ps->pscol),
|
||||||
AFM2PNT(p, p->ps->psrow));
|
AFM2PNT(p, p->ps->psrow));
|
||||||
@ -899,11 +899,11 @@ ps_pletter(struct termp *p, int c)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ('('):
|
case '(':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case (')'):
|
case ')':
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ('\\'):
|
case '\\':
|
||||||
ps_putchar(p, '\\');
|
ps_putchar(p, '\\');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -914,18 +914,14 @@ ps_pletter(struct termp *p, int c)
|
|||||||
|
|
||||||
f = (int)p->ps->lastf;
|
f = (int)p->ps->lastf;
|
||||||
|
|
||||||
if (c <= 32 || (c - 32 >= MAXCHAR)) {
|
if (c <= 32 || c - 32 >= MAXCHAR)
|
||||||
ps_putchar(p, ' ');
|
c = 32;
|
||||||
p->ps->pscol += (size_t)fonts[f].gly[0].wx;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ps_putchar(p, (char)c);
|
ps_putchar(p, (char)c);
|
||||||
c -= 32;
|
c -= 32;
|
||||||
p->ps->pscol += (size_t)fonts[f].gly[c].wx;
|
p->ps->pscol += (size_t)fonts[f].gly[c].wx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_pclose(struct termp *p)
|
ps_pclose(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -947,7 +943,6 @@ ps_pclose(struct termp *p)
|
|||||||
p->ps->flags &= ~PS_INLINE;
|
p->ps->flags &= ~PS_INLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_fclose(struct termp *p)
|
ps_fclose(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -975,13 +970,11 @@ ps_fclose(struct termp *p)
|
|||||||
ps_pclose(p);
|
ps_pclose(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_letter(struct termp *p, int arg)
|
ps_letter(struct termp *p, int arg)
|
||||||
{
|
{
|
||||||
char cc, c;
|
char cc, c;
|
||||||
|
|
||||||
/* LINTED */
|
|
||||||
c = arg >= 128 || arg <= 0 ? '?' : arg;
|
c = arg >= 128 || arg <= 0 ? '?' : arg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1026,7 +1019,6 @@ ps_letter(struct termp *p, int arg)
|
|||||||
ps_pletter(p, c);
|
ps_pletter(p, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_advance(struct termp *p, size_t len)
|
ps_advance(struct termp *p, size_t len)
|
||||||
{
|
{
|
||||||
@ -1042,7 +1034,6 @@ ps_advance(struct termp *p, size_t len)
|
|||||||
p->ps->pscol += len;
|
p->ps->pscol += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_endline(struct termp *p)
|
ps_endline(struct termp *p)
|
||||||
{
|
{
|
||||||
@ -1074,8 +1065,7 @@ ps_endline(struct termp *p)
|
|||||||
* showpage and restart our row.
|
* showpage and restart our row.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (p->ps->psrow >= p->ps->lineheight +
|
if (p->ps->psrow >= p->ps->lineheight + p->ps->bottom) {
|
||||||
p->ps->bottom) {
|
|
||||||
p->ps->psrow -= p->ps->lineheight;
|
p->ps->psrow -= p->ps->lineheight;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1083,7 +1073,6 @@ ps_endline(struct termp *p)
|
|||||||
ps_closepage(p);
|
ps_closepage(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ps_setfont(struct termp *p, enum termfont f)
|
ps_setfont(struct termp *p, enum termfont f)
|
||||||
{
|
{
|
||||||
@ -1101,28 +1090,24 @@ ps_setfont(struct termp *p, enum termfont f)
|
|||||||
|
|
||||||
if (TERMTYPE_PS == p->type)
|
if (TERMTYPE_PS == p->type)
|
||||||
ps_printf(p, "/%s %zu selectfont\n",
|
ps_printf(p, "/%s %zu selectfont\n",
|
||||||
fonts[(int)f].name,
|
fonts[(int)f].name, p->ps->scale);
|
||||||
p->ps->scale);
|
|
||||||
else
|
else
|
||||||
ps_printf(p, "/F%d %zu Tf\n",
|
ps_printf(p, "/F%d %zu Tf\n",
|
||||||
(int)f,
|
(int)f, p->ps->scale);
|
||||||
p->ps->scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static size_t
|
static size_t
|
||||||
ps_width(const struct termp *p, int c)
|
ps_width(const struct termp *p, int c)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (c <= 32 || c - 32 >= MAXCHAR)
|
if (c <= 32 || c - 32 >= MAXCHAR)
|
||||||
return((size_t)fonts[(int)TERMFONT_NONE].gly[0].wx);
|
c = 0;
|
||||||
|
else
|
||||||
c -= 32;
|
c -= 32;
|
||||||
|
|
||||||
return((size_t)fonts[(int)TERMFONT_NONE].gly[c].wx);
|
return((size_t)fonts[(int)TERMFONT_NONE].gly[c].wx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
ps_hspan(const struct termp *p, const struct roffsu *su)
|
ps_hspan(const struct termp *p, const struct roffsu *su)
|
||||||
{
|
{
|
||||||
@ -1134,30 +1119,30 @@ ps_hspan(const struct termp *p, const struct roffsu *su)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (su->unit) {
|
switch (su->unit) {
|
||||||
case (SCALE_CM):
|
case SCALE_CM:
|
||||||
r = PNT2AFM(p, su->scale * 28.34);
|
r = PNT2AFM(p, su->scale * 28.34);
|
||||||
break;
|
break;
|
||||||
case (SCALE_IN):
|
case SCALE_IN:
|
||||||
r = PNT2AFM(p, su->scale * 72);
|
r = PNT2AFM(p, su->scale * 72.0);
|
||||||
break;
|
break;
|
||||||
case (SCALE_PC):
|
case SCALE_PC:
|
||||||
r = PNT2AFM(p, su->scale * 12);
|
r = PNT2AFM(p, su->scale * 12.0);
|
||||||
break;
|
break;
|
||||||
case (SCALE_PT):
|
case SCALE_PT:
|
||||||
r = PNT2AFM(p, su->scale * 100);
|
r = PNT2AFM(p, su->scale * 100.0);
|
||||||
break;
|
break;
|
||||||
case (SCALE_EM):
|
case SCALE_EM:
|
||||||
r = su->scale *
|
r = su->scale *
|
||||||
fonts[(int)TERMFONT_NONE].gly[109 - 32].wx;
|
fonts[(int)TERMFONT_NONE].gly[109 - 32].wx;
|
||||||
break;
|
break;
|
||||||
case (SCALE_MM):
|
case SCALE_MM:
|
||||||
r = PNT2AFM(p, su->scale * 2.834);
|
r = PNT2AFM(p, su->scale * 2.834);
|
||||||
break;
|
break;
|
||||||
case (SCALE_EN):
|
case SCALE_EN:
|
||||||
r = su->scale *
|
r = su->scale *
|
||||||
fonts[(int)TERMFONT_NONE].gly[110 - 32].wx;
|
fonts[(int)TERMFONT_NONE].gly[110 - 32].wx;
|
||||||
break;
|
break;
|
||||||
case (SCALE_VS):
|
case SCALE_VS:
|
||||||
r = su->scale * p->ps->lineheight;
|
r = su->scale * p->ps->lineheight;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1178,8 +1163,5 @@ ps_growbuf(struct termp *p, size_t sz)
|
|||||||
sz = PS_BUFSLOP;
|
sz = PS_BUFSLOP;
|
||||||
|
|
||||||
p->ps->psmargsz += sz;
|
p->ps->psmargsz += sz;
|
||||||
|
p->ps->psmarg = mandoc_realloc(p->ps->psmarg, p->ps->psmargsz);
|
||||||
p->ps->psmarg = mandoc_realloc
|
|
||||||
(p->ps->psmarg, p->ps->psmargsz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
contrib/mdocml/test-fgetln.c
Normal file
11
contrib/mdocml/test-fgetln.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
size_t sz;
|
||||||
|
fclose(stdin);
|
||||||
|
return(NULL != fgetln(stdin, &sz));
|
||||||
|
}
|
19
contrib/mdocml/test-getsubopt.c
Normal file
19
contrib/mdocml/test-getsubopt.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#if defined(__linux__) || defined(__MINT__)
|
||||||
|
# define _GNU_SOURCE /* getsubopt() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern char *suboptarg;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
char buf[] = "k=v";
|
||||||
|
char *options = buf;
|
||||||
|
char token0[] = "k";
|
||||||
|
char *const tokens[] = { token0, NULL };
|
||||||
|
char *value = NULL;
|
||||||
|
return( ! (0 == getsubopt(&options, tokens, &value)
|
||||||
|
&& suboptarg == buf && value == buf+2 && options == buf+3));
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user