Import mandoc 1.13.2

This commit is contained in:
Baptiste Daroussin 2014-12-25 21:33:25 +00:00
parent 81bffeeaab
commit 2612bc21b4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/mdocml/dist/; revision=276216
svn path=/vendor/mdocml/1.13.2/; revision=276217; tag=vendor/mandoc/1.13.2
51 changed files with 1309 additions and 566 deletions

71
INSTALL
View File

@ -1,13 +1,12 @@
$Id: INSTALL,v 1.5 2014/08/18 13:27:47 kristaps Exp $
$Id: INSTALL,v 1.9 2014/12/11 07:44:46 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).
Since the present version 1.13.2, it includes a man(1) manual viewer
in addition to the apropos(1) manual page search tool.
For general information, see <http://mdocml.bsd.lv/>.
In this document, we describe the installation and deployment of
@ -22,7 +21,7 @@ tech@ mailing list, too.
Enjoy using the mandoc toolset!
Ingo Schwarze, Karlsruhe, August 2014
Ingo Schwarze, Karlsruhe, December 2014
Installation
@ -59,8 +58,8 @@ should work. If the build fails, look at "configure.local.example"
and go back to step 2.
4. Run "make -n install" and check whether everything will be
installed to the intended places. Otherwise, put some *DIR variables
into "configure.local" and go back to step 2.
installed to the intended places. Otherwise, put some *DIR or *NM*
variables into "configure.local" and go back to step 2.
5. Run "sudo make install". If you intend to build a binary
package using some kind of fake root mechanism, you may need a
@ -70,14 +69,14 @@ in the "Makefile" to understand how DESTDIR is used.
6. To set up a man.cgi(8) server, read its manual page.
7. To use mandoc(1) as your man(1) formatter, read the "Deployment"
section below.
sections below.
Understanding mandoc dependencies
---------------------------------
The mandoc(1), preconv(1), and demandoc(1) utilities have no external
dependencies. However, makewhatis(8) and apropos(1) depend on the
following software:
The mandoc(1) and demandoc(1) utilities have no external dependencies.
However, makewhatis(8), apropos(1), and man(1) depend on the following
software:
1. The SQLite database system, see <http://sqlite.org/>.
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
@ -89,14 +88,14 @@ 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.
2. The fts(3) directory traversion functions.
If your system does not have them, the bundled compatibility version
will be used, so you need not worry in that case. But 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>.
If you run into that problem, set "HAVE_FTS=0" in configure.local.
1.3. Marc Espie's ohash(3) library.
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.
@ -145,11 +144,39 @@ in unusual headers. You can also look at the file "config.h" and
check that no "#define HAVE_*" differ from your expectations.
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!
Deployment using the integrated man(1) viewer
---------------------------------------------
This mode of deployment requires database support. In case of
doubt, look at the section "user settings related to database
support" in the file configure.local.example.
Deployment requires the following steps:
1. Build and install mandoc as described above in steps 2 to 5
below "Installation".
2. If your system uses manpath(1), make sure it is configured
correctly, in particular, it returns all directory trees where
manual pages are installed. If your system uses man.conf(5), make
sure it contains a "_whatdb" line for each directory tree, and the
order of these lines meets your wishes.
3. Run the command "sudo makewhatis" to build mandoc.db(5) databases
in all the directory trees configured in step 2.
At this point, your new man(1), apropos(1), and whatis(1) should work.
Otherwise, please look at <http://mdocml.bsd.lv/contact.html>, both
for help and to have these instructions improved.
Whenever installing new manual pages, re-run makewhatis(8) to update
the databases, or man(1) will not find the new pages.
Deployment using your system's native man(1) viewer
---------------------------------------------------
This mode of deployment does not require database support,
so it works even if you don't have SQLite3.
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.
@ -174,15 +201,17 @@ mandoc(1)" to disregard them.
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.
"catpage" instead 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:
instead of groff(1) to format manuals, see the BSDCan and EuroBSDCon
presentations by Ingo Schwarze:
<http://www.openbsd.org/papers/bsdcan11-mandoc-openbsd.html>
<http://www.openbsd.org/papers/bsdcan14-mandoc.pdf>
<http://www.openbsd.org/papers/eurobsdcon2014-mandoc-paper.pdf>

View File

@ -1,17 +1,17 @@
$Id: LICENSE,v 1.4 2014/08/21 00:42:38 schwarze Exp $
$Id: LICENSE,v 1.5 2014/12/11 07:56:24 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) 2008-2012, 2014 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>
Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
See the individual source files for information about who contributed
to which file during which years.

113
Makefile
View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.448 2014/11/28 18:57:31 schwarze Exp $
# $Id: Makefile,v 1.453 2014/12/09 09:14:33 schwarze Exp $
#
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
# Copyright (c) 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,9 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
BASEBIN = mandoc demandoc
DBBIN = makewhatis
CGIBIN = man.cgi
# === LIST OF FILES ====================================================
TESTSRCS = test-dirent-namlen.c \
test-fgetln.c \
@ -131,6 +129,7 @@ DISTFILES = INSTALL \
mandoc_aux.h \
mandoc_char.7 \
mandoc_escape.3 \
mandoc_headers.3 \
mandoc_html.3 \
mandoc_malloc.3 \
manpath.h \
@ -208,18 +207,19 @@ MANDOC_TERM_OBJS = eqn_term.o \
term_ps.o \
tbl_term.o
MANDOC_OBJS = $(MANDOC_HTML_OBJS) \
BASE_OBJS = $(MANDOC_HTML_OBJS) \
$(MANDOC_MAN_OBJS) \
$(MANDOC_TERM_OBJS) \
main.o \
out.o \
tree.o
MAN_OBJS = $(MANDOC_OBJS)
MAIN_OBJS = $(BASE_OBJS)
MAKEWHATIS_OBJS = mandocdb.o mansearch_const.o manpath.o
APROPOS_OBJS = mansearch.o mansearch_const.o manpath.o
DB_OBJS = mandocdb.o \
mansearch.o \
mansearch_const.o \
manpath.o
CGI_OBJS = $(MANDOC_HTML_OBJS) \
cgi.o \
@ -237,6 +237,7 @@ WWW_MANS = apropos.1.html \
mandoc.1.html \
mandoc.3.html \
mandoc_escape.3.html \
mandoc_headers.3.html \
mandoc_html.3.html \
mandoc_malloc.3.html \
mansearch.3.html \
@ -261,19 +262,17 @@ WWW_MANS = apropos.1.html \
WWW_OBJS = mdocml.tar.gz \
mdocml.sha256
include Makefile.local
# === USER CONFIGURATION ===============================================
INSTALL_TARGETS = $(BUILD_TARGETS:-build=-install)
include Makefile.local
# === DEPENDENCY HANDLING ==============================================
all: base-build $(BUILD_TARGETS) Makefile.local
base-build: $(BASEBIN)
base-build: mandoc demandoc
db-build: $(DBBIN)
cgi-build: $(CGIBIN)
cgi-build: man.cgi
install: base-install $(INSTALL_TARGETS)
@ -281,6 +280,9 @@ www: $(WWW_OBJS) $(WWW_MANS)
$(WWW_MANS): mandoc
.PHONY: base-install cgi-install db-install install www-install
.PHONY: clean distclean depend
include Makefile.depend
# === TARGETS CONTAINING SHELL COMMANDS ================================
@ -290,8 +292,7 @@ distclean: clean
clean:
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS)
rm -f mandoc $(MANDOC_OBJS) $(APROPOS_OBJS)
rm -f makewhatis $(MAKEWHATIS_OBJS)
rm -f mandoc $(BASE_OBJS) $(DB_OBJS)
rm -f man.cgi $(CGI_OBJS)
rm -f manpage $(MANPAGE_OBJS)
rm -f demandoc $(DEMANDOC_OBJS)
@ -306,34 +307,41 @@ base-install: base-build
mkdir -p $(DESTDIR)$(MANDIR)/man1
mkdir -p $(DESTDIR)$(MANDIR)/man3
mkdir -p $(DESTDIR)$(MANDIR)/man7
$(INSTALL_PROGRAM) $(BASEBIN) $(DESTDIR)$(BINDIR)
$(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR)
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \
$(DESTDIR)$(INCLUDEDIR)
$(INSTALL_MAN) man.1 mandoc.1 demandoc.1 \
$(DESTDIR)$(MANDIR)/man1
$(INSTALL_MAN) mandoc.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_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MAN}.7
$(INSTALL_MAN) mdoc.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MDOC}.7
$(INSTALL_MAN) roff.7 $(DESTDIR)$(MANDIR)/man7/${MANM_ROFF}.7
$(INSTALL_MAN) eqn.7 $(DESTDIR)$(MANDIR)/man7/${MANM_EQN}.7
$(INSTALL_MAN) tbl.7 $(DESTDIR)$(MANDIR)/man7/${MANM_TBL}.7
$(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
$(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR)
db-install: db-build
db-install: base-build
mkdir -p $(DESTDIR)$(BINDIR)
mkdir -p $(DESTDIR)$(SBINDIR)
mkdir -p $(DESTDIR)$(MANDIR)/man1
mkdir -p $(DESTDIR)$(MANDIR)/man3
mkdir -p $(DESTDIR)$(MANDIR)/man5
mkdir -p $(DESTDIR)$(MANDIR)/man8
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/apropos
ln -f $(DESTDIR)$(BINDIR)/mandoc $(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
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS)
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN)
ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS)
ln -f $(DESTDIR)$(BINDIR)/mandoc \
$(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS)
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1
$(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1
ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \
$(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1
$(INSTALL_MAN) mansearch.3 $(DESTDIR)$(MANDIR)/man3
$(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5
$(INSTALL_MAN) makewhatis.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL_MAN) makewhatis.8 \
$(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8
cgi-install: cgi-build
mkdir -p $(DESTDIR)$(CGIBINDIR)
@ -346,34 +354,15 @@ cgi-install: cgi-build
$(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
Makefile.local config.h: configure ${TESTSRCS}
@echo "$@ is out of date; please run ./configure"
@exit 1
depend: config.h
mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
s|\\\n||g; s| +| |g; s| $$||mg; print;' \
Makefile.depend > Makefile.tmp
mv Makefile.tmp Makefile.depend
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
$(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
mandoc: $(MAN_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(MAN_OBJS) libmandoc.a $(DBLIB)
makewhatis: $(MAKEWHATIS_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(MAKEWHATIS_OBJS) libmandoc.a $(DBLIB)
mandoc: $(MAIN_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(MAIN_OBJS) libmandoc.a $(DBLIB)
manpage: $(MANPAGE_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(MANPAGE_OBJS) libmandoc.a $(DBLIB)
@ -384,6 +373,24 @@ man.cgi: $(CGI_OBJS) libmandoc.a
demandoc: $(DEMANDOC_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a
# --- maintainer targets ---
www-install: www
mkdir -p $(HTDOCDIR)/snapshots
$(INSTALL_DATA) $(WWW_MANS) style.css $(HTDOCDIR)/man
$(INSTALL_DATA) $(WWW_OBJS) $(HTDOCDIR)/snapshots
$(INSTALL_DATA) mdocml.tar.gz \
$(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz
$(INSTALL_DATA) mdocml.sha256 \
$(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; s| $$||mg; print;' \
Makefile.depend > Makefile.tmp
mv Makefile.tmp Makefile.depend
mdocml.sha256: mdocml.tar.gz
sha256 mdocml.tar.gz > $@
@ -394,8 +401,8 @@ mdocml.tar.gz: $(DISTFILES)
( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) )
rm -rf .dist/
.PHONY: base-install cgi-install db-install install www-install
.PHONY: clean distclean depend
# === SUFFIX RULES =====================================================
.SUFFIXES: .1 .3 .5 .7 .8 .h
.SUFFIXES: .1.html .3.html .5.html .7.html .8.html .h.html

View File

@ -15,12 +15,12 @@ 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
html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h main.h
lib.o: lib.c config.h mdoc.h libmdoc.h lib.in
main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h manpath.h mansearch.h
man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
man_hash.o: man_hash.c config.h man.h 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_hash.o: man_hash.c config.h man.h libman.h
man_html.o: man_html.c config.h mandoc_aux.h man.h out.h html.h main.h
man_macro.o: man_macro.c config.h man.h mandoc.h libmandoc.h libman.h
man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h
man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
@ -30,19 +30,19 @@ mandocdb.o: mandocdb.c config.h compat_fts.h compat_ohash.h mdoc.h man.h mandoc.
manpage.o: manpage.c config.h manpath.h mansearch.h
manpath.o: manpath.c config.h mandoc_aux.h manpath.h
mansearch.o: mansearch.c config.h compat_ohash.h mandoc.h mandoc_aux.h manpath.h mansearch.h
mansearch_const.o: mansearch_const.c config.h manpath.h mansearch.h
mansearch_const.o: mansearch_const.c config.h mansearch.h
mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
mdoc_hash.o: mdoc_hash.c config.h mdoc.h libmdoc.h
mdoc_html.o: mdoc_html.c config.h mandoc.h mandoc_aux.h out.h html.h mdoc.h main.h
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mdoc.h out.h html.h main.h
mdoc_macro.o: mdoc_macro.c config.h mdoc.h mandoc.h libmdoc.h libmandoc.h
mdoc_man.o: mdoc_man.c config.h mandoc.h mandoc_aux.h out.h man.h mdoc.h main.h
mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main.h
mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
msec.o: msec.c config.h libmandoc.h msec.in
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
preconv.o: preconv.c config.h mandoc.h libmandoc.h
read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h main.h
read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h
roff.o: roff.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h predefs.in
st.o: st.c config.h mdoc.h libmdoc.h st.in
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
@ -53,7 +53,7 @@ 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
term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h main.h
tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h
test-dirent-namlen.o: test-dirent-namlen.c
test-fgetln.o: test-fgetln.c

71
NEWS
View File

@ -1,7 +1,76 @@
$Id: NEWS,v 1.6 2014/08/11 01:39:00 schwarze Exp $
$Id: NEWS,v 1.8 2014/12/13 13:43:47 schwarze Exp $
This file lists the most important changes in the mdocml.bsd.lv distribution.
Changes in version 1.13.2, released on December 13, 2014
--- MAJOR NEW FEATURES ---
* Include an implementation of man(1), the manual page viewer.
* Unified set of command line option, each one supported by all
command names, including new options -a (format all), -c (no
pager), -h (synopsis only), and -w (list filenames).
* Support the MANPAGER and PAGER environment variables.
* Support gzip'ed manuals by the whole toolset, even as .so targets.
* Support UTF-8 and Latin-1 input by the whole toolset, delete preconv(1).
* Switch the default output mode from -Tascii to -Tlocale.
* Improve -Tascii output for Unicode escape sequences.
* Let the -Thtml output mode produce polyglot HTML5.
* Many improvements for eqn(7), in particular in-line equations,
MathML output in -Thtml mode, and much improved terminal formatting.
--- PORTABILITY IMPROVEMENTS ---
* Change the build sequence to the usual ./configure; make; make install.
* Support ./configure.local for build customizations.
* Autodetect wchar, sqlite3, and manpath support.
* Provide a fallback version of fts(3) for systems lacking it.
* Support choosing alternative binary and manual names.
--- MINOR NEW FEATURES ---
* Rudimentary implementation of the e, x, and z tbl(7) layout
modifiers to equalize, maximize, and ignore the width of columns.
* Implement font modifiers in tbl(7) layouts.
* Allow comma-separated options in the tbl(7) options line.
* Parse and ignore the .pl (page length) roff(7) request.
* Implement .An -[no]split for the mdoc(7) -Thtml output mode.
* Support bold italic font in PostScript and PDF output.
* Warn about commas in function arguments and parentheses in function names.
* Warn about botched .Xr ordering and punctuation below SEE ALSO.
* Warn about AUTHORS sections without .An macros.
* Warn about attempts to call non-callable macros.
* New developer documentation manual page mandoc_headers(3).
--- BUGFIXES ---
* Fix read buffer overrun sometimes triggered by trailing whitespace.
* Fix read buffer overrun triggered by certain invalid \H sequences.
* Fix NULL pointer access triggered by .Bl without any arguments.
* Fix NULL pointer access triggered by .It Nm Fo without .Fc.
* Fix NULL pointer access triggered by .Sh Xo .Sh without .Xc.
* Fix NULL pointer access triggered by missing .Nm.
* Fix an assertion triggered by .It right after .El.
* Fix an assertion triggered by .Ec without preceding .Eo.
* Fix an assertion triggered by .Sm or .Db with multiple arguments.
* Fix assertion failures triggered by very large width arguments.
* Fix a division by zero in the roff(7) parser.
* Prevent negative arguments to .ll from causing integer underflow.
* Correctly autodetect source format even when .Dd is preceded by .ll.
* Multiple fixes with respect to .Bd and .Bl -offset and -width.
* Many bugfixes with respect to scaling units.
* Multiple fixes with respect to delimiter handling by in-line macros.
* Multiple fixes with respect to .Pf.
* Make \c work properly in no-fill mode.
* Stricter syntax checking of Unicode character names.
--- THANKS TO ---
* Kristaps Dzonsons for rewriting the eqn(7) parser, implementing
HTML5 and MathML output, and various other code contributions.
* Jonathan Gray (OpenBSD) for extensive testing with afl (the
American Fuzzy Lop security fuzzer) resulting in many bug reports.
* Anthony Bentley (OpenBSD), Baptiste Daroussin (FreeBSD), Daniel
Dickman, Doug Hogan, Jason McIntyre, Theo de Raadt (OpenBSD),
and Martin Natano for source code patches.
* Carsten Kunze (Heirloom troff), Daniel Levai (Slackware),
Garrett D'Amore (illumos), Giovanni Becchis, Matthew Dempsky,
Stuart Henderson, Ted Unangst, Todd Miller (OpenBSD), Thomas
Klausner (NetBSD), Ulrich Spoerlein (FreeBSD), Justin Haynes,
Marcus Merighi, Sebastien Marie, Steffen Nurpmeso and Theo Buehler
for bug reports.
Changes in version 1.13.1, released on August 10, 2014
--- MAJOR NEW FEATURES ---

55
TODO
View File

@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
* $Id: TODO,v 1.189 2014/11/26 21:40:17 schwarze Exp $
* $Id: TODO,v 1.195 2014/12/13 13:14:39 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@ -72,7 +72,8 @@ are mere guesses, and some may be wrong.
- .ta (tab settings) occurs in ircbug(1) and probably gnats(1)
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
loc ** exist *** algo ** size ** imp **
also posix2time(3) Carsten Kunze Mon, 1 Dec 2014 13:03:10 +0100
loc ** exist *** algo ** size ** imp ***
- .ti (temporary indent)
found by naddy@ in xloadimage(1)
@ -83,14 +84,10 @@ are mere guesses, and some may be wrong.
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
loc * exist ** algo ** size ** imp **
- \c (interrupted text) should prevent the line break
even inside .Bd literal; that occurs in chat(8)
also found in cclive(1) - DocBook output
loc ** exist *** algo ** size * imp *
- \h horizontal move
found in cclive(1) DocBook output
Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
found in cclive(1) and nasm(1) asciidoc/DocBook output
bentley@ on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
naddy@ Thu, 4 Dec 2014 16:26:41 +0100
loc ** exist ** algo ** size * imp ** (parser reorg helps a lot)
- \n+ and \n- numerical register increment and decrement
@ -125,13 +122,6 @@ are mere guesses, and some may be wrong.
from jmc@ Wed, 14 Jul 2010 18:10:32 +0100
loc * exist *** algo *** size ** imp **
- \\ is now implemented correctly
* when defining strings and macros using .ds and .de
* when parsing roff(7) and man(7) macro arguments
It does not yet work in mdoc(7) macro arguments
because libmdoc does not yet use mandoc_getarg().
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.
@ -172,12 +162,6 @@ are mere guesses, and some may be wrong.
is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab."
but should give "ab ."
- set a meaningful default if no `Bl' list type is assigned
loc * exist * algo * size * imp ** (already done?)
- have a blank `It' head for `Bl -tag' not puke
loc * exist * algo * size * imp ** (already done?)
- check whether it is correct that `D1' uses INDENT+1;
does it need its own constant?
loc * exist ** algo ** size * imp **
@ -315,9 +299,18 @@ are mere guesses, and some may be wrong.
* formatting issues: ugly output
************************************************************************
- a column list with blank `Ta' cells triggers a spurrious
- revisit empty in-line macros
look at the difference between "Em x Em ." and "Sq x Em ."
Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100
loc *** exist *** algo *** size * imp **
- a column list with blank `Ta' cells triggers a spurious
start-with-whitespace printing of a newline
- In .Bl -column, .It a<tab>"b<tab>c"
shows the quotes in groff, but not in mandoc
loc * exist *** algo ** size * imp **
- In .Bl -column,
.It Em Authentication<tab>Key Length
ought to render "Key Length" with emphasis, too,
@ -403,16 +396,6 @@ are mere guesses, and some may be wrong.
Steffen Nurpmeso Sat, 08 Nov 2014 13:34:59 +0100
loc * exist ** algo ** size * imp **
- .Rv (and probably .Ex) print different text if an `Nm' has been named
or not (run a manual without `Nm blah' to see this). I'm not sure
that this exists in the wild, but it's still an error.
loc * exist * algo * size * imp * (already done?)
- In .Bl -bullet, the groff bullet is "+\b+\bo\bo", the mandoc bullet
is just "o\bo". The problem is to not break ps/pdf when fixing.
see for example OpenBSD ksh(1)
loc ** exist ** algo ** size * imp **
- 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
@ -601,3 +584,9 @@ Several areas can be cleaned up to make mandoc even faster. These are
- Have Mac OSX systems automatically disable -static compilation of the
CGI: -static isn't supported.
************************************************************************
* to improve in the groff_mdoc(7) macros
************************************************************************
- use uname(1) to set doc-default-operating-system at install time
tobimensch Mon, 1 Dec 2014 00:25:07 +0100

View File

@ -6,8 +6,8 @@ int dummy;
#else
/* $Id: compat_fts.c,v 1.4 2014/08/17 20:45:59 schwarze Exp $ */
/* $OpenBSD: fts.c,v 1.46 2014/05/25 17:47:04 tedu Exp $ */
/* $Id: compat_fts.c,v 1.6 2014/12/11 18:20:07 schwarze Exp $ */
/* $OpenBSD: fts.c,v 1.49 2014/11/23 00:14:22 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@ -62,6 +62,10 @@ static unsigned short fts_stat(FTS *, FTSENT *);
static int fts_safe_changedir(FTS *, FTSENT *, int, const char *);
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
#define MAX(a,b) (((a)>(b))?(a):(b))
#ifndef O_DIRECTORY
#define O_DIRECTORY 0
#endif
#define CLR(opt) (sp->fts_options &= ~(opt))
#define ISSET(opt) (sp->fts_options & (opt))
@ -146,7 +150,8 @@ fts_open(char * const *argv, int options, void *dummy)
* and ".." are all fairly nasty problems. Note, if we can't get the
* descriptor we run anyway, just more slowly.
*/
if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
if (!ISSET(FTS_NOCHDIR) &&
(sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0)
SET(FTS_NOCHDIR);
if (nitems == 0)
@ -406,7 +411,7 @@ fts_build(FTS *sp)
DIR *dirp;
void *oldaddr;
size_t dlen, len, maxlen;
int nitems, cderrno, descend, level, nlinks, nostat, doadjust;
int nitems, cderrno, descend, level, doadjust;
int saved_errno;
char *cp;
@ -423,14 +428,6 @@ fts_build(FTS *sp)
return (NULL);
}
/*
* Nlinks is the number of possible entries of type directory in the
* directory if we're cheating on stat calls, 0 if we're not doing
* any stat calls at all, -1 if we're doing stats on everything.
*/
nlinks = -1;
nostat = 0;
/*
* If we're going to need to stat anything or we want to descend
* and stay in the directory, chdir. If this fails we keep going,
@ -448,8 +445,7 @@ fts_build(FTS *sp)
*/
cderrno = 0;
if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
if (nlinks)
cur->fts_errno = errno;
cur->fts_errno = errno;
cur->fts_flags |= FTS_DONTCHDIR;
descend = 0;
cderrno = errno;
@ -544,21 +540,9 @@ mem1: saved_errno = errno;
}
if (cderrno) {
if (nlinks) {
p->fts_info = FTS_NS;
p->fts_errno = cderrno;
} else
p->fts_info = FTS_NSOK;
p->fts_info = FTS_NS;
p->fts_errno = cderrno;
p->fts_accpath = cur->fts_accpath;
} else if (nlinks == 0
#ifdef DT_DIR
|| (nostat &&
dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
#endif
) {
p->fts_accpath =
ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
p->fts_info = FTS_NSOK;
} else {
/* Build a file name for fts_stat to stat. */
if (ISSET(FTS_NOCHDIR)) {
@ -568,11 +552,6 @@ mem1: saved_errno = errno;
p->fts_accpath = p->fts_name;
/* Stat it. */
p->fts_info = fts_stat(sp, p);
/* Decrement link count if applicable. */
if (nlinks > 0 && (p->fts_info == FTS_D ||
p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
--nlinks;
}
/* We walk in directory order so "ls -f" doesn't get upset. */
@ -803,7 +782,7 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
return (-1);
if (fstat(newfd, &sb)) {
ret = -1;

View File

@ -6,7 +6,8 @@ int dummy;
#else
/* $OpenBSD: malloc.c,v 1.158 2014/04/23 15:07:27 tedu Exp $ */
/* $Id: compat_reallocarray.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */
/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
/*
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
*
@ -22,12 +23,17 @@ int dummy;
* 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))
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
reallocarray(void *optr, size_t nmemb, size_t size)

View File

@ -6,7 +6,8 @@ int dummy;
#else
/* ($)NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */
/* $Id: compat_strcasestr.c,v 1.4 2014/12/11 09:19:32 schwarze Exp $ */
/* $NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993

View File

@ -6,7 +6,8 @@ int dummy;
#else
/* ($)OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
/* $Id: compat_strsep.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */
/* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $ */
/*-
* Copyright (c) 1990, 1993

33
configure vendored
View File

@ -31,7 +31,7 @@ echo "config.log: writing..."
# Initialize all variables here,
# such that nothing can leak in from the environment.
VERSION="1.13.1"
VERSION="1.13.2"
echo "VERSION=\"${VERSION}\"" 1>&2
echo "VERSION=\"${VERSION}\"" 1>&3
@ -75,6 +75,16 @@ WWWPREFIX="/var/www"
HTDOCDIR=
CGIBINDIR=
BINM_APROPOS="apropos"
BINM_MAN="man"
BINM_WHATIS="whatis"
BINM_MAKEWHATIS="makewhatis"
MANM_MAN="man"
MANM_MDOC="mdoc"
MANM_ROFF="roff"
MANM_EQN="eqn"
MANM_TBL="tbl"
INSTALL="install"
INSTALL_PROGRAM=
INSTALL_LIB=
@ -285,6 +295,11 @@ cat << __HEREDOC__
#define HAVE_OHASH ${HAVE_OHASH}
#define HAVE_MANPATH ${HAVE_MANPATH}
#define BINM_APROPOS "${BINM_APROPOS}"
#define BINM_MAN "${BINM_MAN}"
#define BINM_WHATIS "${BINM_WHATIS}"
#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}"
#if !defined(__BEGIN_DECLS)
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
@ -358,12 +373,15 @@ if [ ${BUILD_DB} -eq 0 -a ${BUILD_CGI} -gt 0 ]; then
fi
BUILD_TARGETS="base-build"
[ ${BUILD_DB} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} db-build"
[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} cgi-build"
INSTALL_TARGETS="base-install"
[ ${BUILD_DB} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} db-install"
[ ${BUILD_CGI} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} cgi-install"
cat << __HEREDOC__
VERSION = ${VERSION}
BUILD_TARGETS = ${BUILD_TARGETS}
INSTALL_TARGETS = ${INSTALL_TARGETS}
CFLAGS = ${CFLAGS}
DBLIB = ${DBLIB}
STATIC = ${STATIC}
@ -377,6 +395,15 @@ EXAMPLEDIR = ${EXAMPLEDIR}
WWWPREFIX = ${WWWPREFIX}
HTDOCDIR = ${HTDOCDIR}
CGIBINDIR = ${CGIBINDIR}
BINM_APROPOS = ${BINM_APROPOS}
BINM_MAN = ${BINM_MAN}
BINM_WHATIS = ${BINM_WHATIS}
BINM_MAKEWHATIS = ${BINM_MAKEWHATIS}
MANM_MAN = ${MANM_MAN}
MANM_MDOC = ${MANM_MDOC}
MANM_ROFF = ${MANM_ROFF}
MANM_EQN = ${MANM_EQN}
MANM_TBL = ${MANM_TBL}
INSTALL = ${INSTALL}
INSTALL_PROGRAM = ${INSTALL_PROGRAM}
INSTALL_LIB = ${INSTALL_LIB}
@ -385,7 +412,7 @@ INSTALL_DATA = ${INSTALL_DATA}
__HEREDOC__
[ ${BUILD_DB} -gt 0 ] && \
echo "MAN_OBJS = \$(MANDOC_OBJS) \$(APROPOS_OBJS)"
echo "MAIN_OBJS = \$(BASE_OBJS) \$(DB_OBJS)"
echo "Makefile.local: written" 1>&2
echo "Makefile.local: written" 1>&3

View File

@ -1,4 +1,4 @@
# $Id: configure.local.example,v 1.1 2014/08/16 19:00:01 schwarze Exp $
# $Id: configure.local.example,v 1.2 2014/12/09 09:14:33 schwarze Exp $
#
# Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
#
@ -58,7 +58,7 @@ HAVE_WCHAR=0
# If you do not want uname(3) to be called but instead want a fixed
# string to be used, use the following line:
OSNAME="OpenBSD 5.5"
OSNAME="OpenBSD 5.6"
# The following installation directories are used.
# It is possible to set only one or a few of these variables,
@ -74,6 +74,19 @@ LIBDIR="${PREFIX}/lib/mandoc"
MANDIR="${PREFIX}/man"
EXAMPLEDIR="${PREFIX}/share/examples/mandoc"
# Some distributions may want to avoid naming conflicts among manuals.
# If you want to change the names of installed section 7 manual pages,
# the following alternative names are suggested.
# The suffix ".7" will automatically be appended.
# It is possible to set only one or a few of these variables,
# there is no need to copy the whole block.
MANM_MAN="mandoc_man" # default is "man"
MANM_MDOC="mandoc_mdoc" # default is "mdoc"
MANM_ROFF="mandoc_roff" # default is "roff"
MANM_EQN="mandoc_eqn" # default is "eqn"
MANM_TBL="mandoc_tbl" # default is "tbl"
# It is possible to change the utility program used for installation
# and the modes files are installed with. The defaults are:
@ -125,6 +138,21 @@ HAVE_MANPATH=1
HAVE_MANPATH=0
# Some distributions may want to avoid naming conflicts
# with groff, man-db, or other tools.
# If you want to change the names of binary programs,
# the following alternative names are suggested.
# Using other names is possible as well.
# This changes the names of the installed section 1 and section 8
# manual pages as well.
# It is possible to set only one or a few of these variables,
# there is no need to copy the whole block.
BINM_APROPOS=mapropos # default is "apropos"
BINM_MAN=mman # default is "man"
BINM_WHATIS=mwhatis # default is "whatis"
BINM_MAKEWHATIS=mandocdb # default is "makewhatis"
# --- user settings related man.cgi ------------------------------------
# By default, building man.cgi(8) is disabled. To enable it, copy

View File

@ -1,4 +1,4 @@
/* $Id: example.style.css,v 1.53 2014/09/27 11:16:24 kristaps Exp $ */
/* $Id: example.style.css,v 1.54 2014/12/10 22:19:45 schwarze Exp $ */
/*
* This is an example style-sheet provided for mandoc(1) and the -Thtml
* or -Txhtml output mode.
@ -20,11 +20,14 @@ div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */
div.mandoc table.synopsis { } /* SYNOPSIS section table. */
div.mandoc table.foot { } /* Document footer. */
div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */
div.mandoc td.foot-os { width: 50%; } /* Document footer: OS/source. */
div.mandoc td.foot-os { width: 50%;
text-align: right; } /* Document footer: OS/source. */
div.mandoc table.head { } /* Document header. */
div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */
div.mandoc td.head-vol { width: 80%; } /* Document header: volume. */
div.mandoc td.head-rtitle { width: 10%; } /* Document header: right-title. */
div.mandoc td.head-vol { width: 80%;
text-align: center; } /* Document header: volume. */
div.mandoc td.head-rtitle { width: 10%;
text-align: right; } /* Document header: right-title. */
div.mandoc .display { } /* All Bd, D1, Dl. */
div.mandoc .list { } /* All Bl. */
div.mandoc i { } /* Italic: BI, IB, I, (implicit). */

6
html.c
View File

@ -1,4 +1,4 @@
/* $Id: html.c,v 1.181 2014/10/29 00:17:43 schwarze Exp $ */
/* $Id: html.c,v 1.183 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -30,7 +30,6 @@
#include "mandoc.h"
#include "mandoc_aux.h"
#include "libmandoc.h"
#include "out.h"
#include "html.h"
#include "main.h"
@ -563,8 +562,9 @@ print_text(struct html *h, const char *word)
if ( ! print_encode(h, word, 0)) {
if ( ! (h->flags & HTML_NONOSPACE))
h->flags &= ~HTML_NOSPACE;
h->flags &= ~HTML_NONEWLINE;
} else
h->flags |= HTML_NOSPACE;
h->flags |= HTML_NOSPACE | HTML_NONEWLINE;
if (h->metaf) {
print_tagq(h, h->metaf);

14
html.h
View File

@ -1,4 +1,4 @@
/* $Id: html.h,v 1.67 2014/10/28 17:36:19 schwarze Exp $ */
/* $Id: html.h,v 1.70 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -14,10 +14,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HTML_H
#define HTML_H
__BEGIN_DECLS
enum htmltag {
TAG_HTML,
@ -130,6 +126,7 @@ struct html {
#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
#define HTML_NOSPLIT (1 << 7) /* do not break line before .An */
#define HTML_SPLIT (1 << 8) /* break line before .An */
#define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */
struct tagq tags; /* stack of open tags */
struct rofftbl tbl; /* current table */
struct tag *tblt; /* current open table scope */
@ -146,6 +143,11 @@ struct html {
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
};
__BEGIN_DECLS
struct tbl_span;
struct eqn;
void print_gen_decls(struct html *);
void print_gen_head(struct html *);
struct tag *print_otag(struct html *, enum htmltag,
@ -176,5 +178,3 @@ void buffmt_includes(struct html *, const char *);
int html_strlen(const char *);
__END_DECLS
#endif /*!HTML_H*/

View File

@ -1,4 +1,4 @@
/* $Id: libman.h,v 1.65 2014/11/28 05:51:32 schwarze Exp $ */
/* $Id: libman.h,v 1.66 2014/12/01 04:05:31 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef LIBMAN_H
#define LIBMAN_H
enum man_next {
MAN_NEXT_SIBLING = 0,
@ -75,5 +73,3 @@ void man_valid_post(struct man *);
void man_unscope(struct man *, const struct man_node *);
__END_DECLS
#endif /*!LIBMAN_H*/

View File

@ -1,4 +1,4 @@
/* $Id: libmandoc.h,v 1.49 2014/11/28 06:27:05 schwarze Exp $ */
/* $Id: libmandoc.h,v 1.51 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef LIBMANDOC_H
#define LIBMANDOC_H
enum rofferr {
ROFF_CONT, /* continue processing line */
@ -37,6 +35,11 @@ struct buf {
__BEGIN_DECLS
struct mparse;
struct mchars;
enum mandocerr;
struct tbl_span;
struct eqn;
struct roff;
struct mdoc;
struct man;
@ -91,5 +94,3 @@ const struct tbl_span *roff_span(const struct roff *);
const struct eqn *roff_eqn(const struct roff *);
__END_DECLS
#endif /*!LIBMANDOC_H*/

View File

@ -1,4 +1,4 @@
/* $Id: libmdoc.h,v 1.95 2014/11/29 03:37:44 schwarze Exp $ */
/* $Id: libmdoc.h,v 1.96 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef LIBMDOC_H
#define LIBMDOC_H
enum mdoc_next {
MDOC_NEXT_SIBLING = 0,
@ -129,5 +127,3 @@ void mdoc_macroend(struct mdoc *);
enum mdelim mdoc_isdelim(const char *);
__END_DECLS
#endif /*!LIBMDOC_H*/

View File

@ -1,4 +1,4 @@
/* $Id: libroff.h,v 1.31 2014/10/25 14:35:37 schwarze Exp $ */
/* $Id: libroff.h,v 1.33 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,10 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef LIBROFF_H
#define LIBROFF_H
__BEGIN_DECLS
enum tbl_part {
TBL_PART_OPTS, /* in options (first line) */
@ -66,6 +62,8 @@ struct eqn_def {
size_t valsz;
};
__BEGIN_DECLS
struct tbl_node *tbl_alloc(int, int, struct mparse *);
void tbl_restart(int, int, struct tbl_node *);
void tbl_free(struct tbl_node *);
@ -84,5 +82,3 @@ enum rofferr eqn_read(struct eqn_node **, int,
const char *, int, int *);
__END_DECLS
#endif /*LIBROFF_H*/

70
main.c
View File

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.200 2014/11/26 21:40:17 schwarze Exp $ */
/* $Id: main.c,v 1.205 2014/12/11 19:19:35 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -83,12 +83,17 @@ struct curparse {
};
static int koptions(int *, char *);
#if HAVE_SQLITE3
int mandocdb(int, char**);
#endif
static int moptions(int *, char *);
static void mmsg(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
static void parse(struct curparse *, int,
const char *, enum mandoclevel *);
#if HAVE_SQLITE3
static enum mandoclevel passthrough(const char *, int, int);
#endif
static void spawn_pager(void);
static int toptions(struct curparse *, char *);
static void usage(enum argmode) __attribute__((noreturn));
@ -96,6 +101,8 @@ static void version(void) __attribute__((noreturn));
static int woptions(struct curparse *, char *);
static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
static char help_arg[] = "help";
static char *help_argv[] = {help_arg, NULL};
static const char *progname;
@ -105,12 +112,13 @@ main(int argc, char *argv[])
struct curparse curp;
struct mansearch search;
struct manpaths paths;
char *conf_file, *defpaths, *auxpaths;
char *auxpaths;
char *defos;
#if HAVE_SQLITE3
struct manpage *res, *resp;
char *conf_file, *defpaths;
size_t isec, i, sz;
int prio, best_prio;
int prio, best_prio, synopsis_only;
char sec;
#endif
enum mandoclevel rc;
@ -118,7 +126,6 @@ main(int argc, char *argv[])
int fd;
int show_usage;
int use_pager;
int synopsis_only;
int options;
int c;
@ -128,34 +135,46 @@ main(int argc, char *argv[])
else
++progname;
#if HAVE_SQLITE3
if (strcmp(progname, BINM_MAKEWHATIS) == 0)
return(mandocdb(argc, argv));
#endif
/* Search options. */
memset(&paths, 0, sizeof(struct manpaths));
conf_file = defpaths = auxpaths = NULL;
#if HAVE_SQLITE3
conf_file = defpaths = NULL;
#endif
auxpaths = NULL;
memset(&search, 0, sizeof(struct mansearch));
search.outkey = "Nd";
if (strcmp(progname, "man") == 0)
if (strcmp(progname, BINM_MAN) == 0)
search.argmode = ARG_NAME;
else if (strncmp(progname, "apropos", 7) == 0)
else if (strcmp(progname, BINM_APROPOS) == 0)
search.argmode = ARG_EXPR;
else if (strncmp(progname, "whatis", 6) == 0)
else if (strcmp(progname, BINM_WHATIS) == 0)
search.argmode = ARG_WORD;
else if (strncmp(progname, "help", 4) == 0)
search.argmode = ARG_NAME;
else
search.argmode = ARG_FILE;
/* Parser and formatter options. */
memset(&curp, 0, sizeof(struct curparse));
curp.outtype = OUTT_ASCII;
curp.outtype = OUTT_LOCALE;
curp.wlevel = MANDOCLEVEL_FATAL;
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
defos = NULL;
use_pager = 1;
show_usage = 0;
#if HAVE_SQLITE3
synopsis_only = 0;
#endif
outmode = OUTMODE_DEF;
while (-1 != (c = getopt(argc, argv,
@ -165,7 +184,9 @@ main(int argc, char *argv[])
outmode = OUTMODE_ALL;
break;
case 'C':
#if HAVE_SQLITE3
conf_file = optarg;
#endif
break;
case 'c':
use_pager = 0;
@ -175,7 +196,9 @@ main(int argc, char *argv[])
break;
case 'h':
(void)strlcat(curp.outopts, "synopsis,", BUFSIZ);
#if HAVE_SQLITE3
synopsis_only = 1;
#endif
use_pager = 0;
outmode = OUTMODE_ALL;
break;
@ -209,7 +232,9 @@ main(int argc, char *argv[])
outmode = OUTMODE_ALL;
break;
case 'M':
#if HAVE_SQLITE3
defpaths = optarg;
#endif
break;
case 'm':
auxpaths = optarg;
@ -273,15 +298,24 @@ main(int argc, char *argv[])
resp = NULL;
#endif
/* Quirk for a man(1) section argument without -s. */
/*
* Quirks for help(1)
* and for a man(1) section argument without -s.
*/
if (search.argmode == ARG_NAME &&
argv[0] != NULL &&
isdigit((unsigned char)argv[0][0]) &&
(argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) {
search.sec = argv[0];
argv++;
argc--;
if (search.argmode == ARG_NAME) {
if (*progname == 'h') {
if (argc == 0) {
argv = help_argv;
argc = 1;
}
} else if (argv[0] != NULL &&
isdigit((unsigned char)argv[0][0]) &&
(argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) {
search.sec = argv[0];
argv++;
argc--;
}
}
rc = MANDOCLEVEL_OK;
@ -583,6 +617,7 @@ parse(struct curparse *curp, int fd, const char *file,
*level = rc;
}
#if HAVE_SQLITE3
static enum mandoclevel
passthrough(const char *file, int fd, int synopsis_only)
{
@ -646,6 +681,7 @@ passthrough(const char *file, int fd, int synopsis_only)
progname, file, syscall, strerror(errno));
return(MANDOCLEVEL_SYSERR);
}
#endif
static int
koptions(int *options, char *arg)

16
main.h
View File

@ -1,4 +1,4 @@
/* $Id: main.h,v 1.17 2014/10/28 17:36:19 schwarze Exp $ */
/* $Id: main.h,v 1.19 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -14,16 +14,14 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef MAIN_H
#define MAIN_H
__BEGIN_DECLS
struct mdoc;
struct man;
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
__BEGIN_DECLS
struct mchars;
struct mdoc;
struct man;
/*
* Definitions for main.c-visible output device functions, e.g., -Thtml
@ -56,5 +54,3 @@ void terminal_mdoc(void *, const struct mdoc *);
void terminal_man(void *, const struct man *);
__END_DECLS
#endif /*!MAIN_H*/

6
man.h
View File

@ -1,4 +1,4 @@
/* $Id: man.h,v 1.66 2014/11/28 05:51:32 schwarze Exp $ */
/* $Id: man.h,v 1.67 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef MAN_H
#define MAN_H
enum mant {
MAN_br = 0,
@ -116,5 +114,3 @@ const struct mparse *man_mparse(const struct man *);
void man_deroff(char **, const struct man_node *);
__END_DECLS
#endif /*!MAN_H*/

View File

@ -1,4 +1,4 @@
/* $Id: man_hash.c,v 1.28 2014/08/10 23:54:41 schwarze Exp $ */
/* $Id: man_hash.c,v 1.29 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -24,7 +24,6 @@
#include <string.h>
#include "man.h"
#include "mandoc.h"
#include "libman.h"
#define HASH_DEPTH 6

View File

@ -1,4 +1,4 @@
/* $Id: man_html.c,v 1.104 2014/09/27 11:17:19 kristaps Exp $ */
/* $Id: man_html.c,v 1.107 2014/12/04 02:05:42 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -25,11 +25,10 @@
#include <stdlib.h>
#include <string.h>
#include "mandoc.h"
#include "mandoc_aux.h"
#include "man.h"
#include "out.h"
#include "html.h"
#include "man.h"
#include "main.h"
/* TODO: preserve ident widths. */
@ -213,21 +212,14 @@ print_man_node(MAN_ARGS)
man_root_pre(man, n, mh, h);
break;
case MAN_TEXT:
/*
* If we have a blank line, output a vertical space.
* If we have a space as the first character, break
* before printing the line's data.
*/
if ('\0' == *n->string) {
print_paragraph(h);
return;
}
if (' ' == *n->string && MAN_LINE & n->flags)
if (n->flags & MAN_LINE && (*n->string == ' ' ||
(n->prev != NULL && mh->fl & MANH_LITERAL &&
! (h->flags & HTML_NONEWLINE))))
print_otag(h, TAG_BR, 0, NULL);
else if (MANH_LITERAL & mh->fl && n->prev)
print_otag(h, TAG_BR, 0, NULL);
print_text(h, n->string);
return;
case MAN_EQN:
@ -290,7 +282,7 @@ a2width(const struct man_node *n, struct roffsu *su)
if (MAN_TEXT != n->type)
return(0);
if (a2roffsu(n->string, su, SCALE_BU))
if (a2roffsu(n->string, su, SCALE_EN))
return(1);
return(0);

View File

@ -1,4 +1,4 @@
/* $Id: man_term.c,v 1.156 2014/11/21 01:52:53 schwarze Exp $ */
/* $Id: man_term.c,v 1.159 2014/12/04 02:05:42 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@ -123,7 +123,7 @@ static const struct termact termacts[MAN_MAX] = {
{ NULL, NULL, 0 }, /* RE */
{ pre_RS, post_RS, 0 }, /* RS */
{ pre_ign, NULL, 0 }, /* DT */
{ pre_ign, NULL, 0 }, /* UC */
{ pre_ign, NULL, MAN_NOTEXT }, /* UC */
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
{ pre_ign, NULL, 0 }, /* AT */
{ pre_in, NULL, MAN_NOTEXT }, /* in */
@ -201,7 +201,7 @@ a2width(const struct termp *p, const char *cp)
{
struct roffsu su;
if ( ! a2roffsu(cp, &su, SCALE_BU))
if ( ! a2roffsu(cp, &su, SCALE_EN))
return(-1);
return((int)term_hspan(p, &su));
@ -778,12 +778,18 @@ pre_SS(DECL_ARGS)
mt->fl &= ~MANT_LITERAL;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
/* If following a prior empty `SS', no vspace. */
if (n->prev && MAN_SS == n->prev->tok)
if (NULL == n->prev->body->child)
break;
if (NULL == n->prev)
/*
* No vertical space before the first subsection
* and after an empty subsection.
*/
do {
n = n->prev;
} while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT);
if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
break;
for (i = 0; i < mt->pardist; i++)
term_vspace(p);
break;
@ -827,13 +833,18 @@ pre_SH(DECL_ARGS)
mt->fl &= ~MANT_LITERAL;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
/* If following a prior empty `SH', no vspace. */
if (n->prev && MAN_SH == n->prev->tok)
if (NULL == n->prev->body->child)
break;
/* If the first macro, no vspae. */
if (NULL == n->prev)
/*
* No vertical space before the first section
* and after an empty section.
*/
do {
n = n->prev;
} while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT);
if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))
break;
for (i = 0; i < mt->pardist; i++)
term_vspace(p);
break;
@ -1018,13 +1029,14 @@ print_man_node(DECL_ARGS)
* -man doesn't have nested macros, we don't need to be
* more specific than this.
*/
if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
(NULL == n->next || MAN_LINE & n->next->flags)) {
if (mt->fl & MANT_LITERAL &&
! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
(n->next == NULL || n->next->flags & MAN_LINE)) {
rm = p->rmargin;
rmax = p->maxrmargin;
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
if (NULL != n->string && '\0' != *n->string)
if (n->string != NULL && *n->string != '\0')
term_flushln(p);
else
term_newln(p);

View File

@ -1,4 +1,4 @@
.\" $Id: mandoc.1,v 1.125 2014/11/28 18:09:01 schwarze Exp $
.\" $Id: mandoc.1,v 1.128 2014/12/02 11:31:51 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: November 28 2014 $
.Dd $Mdocdate: December 2 2014 $
.Dt MANDOC 1
.Os
.Sh NAME
@ -49,7 +49,7 @@ or
text from stdin, implying
.Fl m Ns Cm andoc ,
and produces
.Fl T Ns Cm ascii
.Fl T Ns Cm locale
output.
.Pp
The options are as follows:
@ -146,7 +146,7 @@ See
.Sx Output Formats
for available formats.
Defaults to
.Fl T Ns Cm ascii .
.Fl T Ns Cm locale .
.It Fl V
Print version and exit.
.It Fl W Ns Ar level
@ -255,7 +255,6 @@ arguments, which correspond to output modes:
.Bl -tag -width "-Tlocale"
.It Fl T Ns Cm ascii
Produce 7-bit ASCII output.
This is the default.
See
.Sx ASCII Output .
.It Fl T Ns Cm html
@ -268,6 +267,7 @@ Implies
.Fl W Ns Cm warning .
.It Fl T Ns Cm locale
Encode output using the current locale.
This is the default.
See
.Sx Locale Output .
.It Fl T Ns Cm man
@ -299,8 +299,8 @@ If multiple input files are specified, these will be processed by the
corresponding filter in-order.
.Ss ASCII Output
Output produced by
.Fl T Ns Cm ascii ,
which is the default, is rendered in standard 7-bit ASCII documented in
.Fl T Ns Cm ascii
is rendered in standard 7-bit ASCII documented in
.Xr ascii 7 .
.Pp
Font styles are applied by using back-spaced encoding such that an
@ -413,6 +413,8 @@ relative URI.
.Ss Locale Output
Locale-depending output encoding is triggered with
.Fl T Ns Cm locale .
This is the default.
.Pp
This option is not available on all systems: systems without locale
support, or those whose internal representation is not natively UCS-4,
will fall back to
@ -803,6 +805,13 @@ Probably, there are author names lacking markup.
See the
.Xr mdoc 7
manual for replacements.
.It Sy "macro neither callable nor escaped"
.Pq mdoc
The name of a macro that is not callable appears on a macro line.
It is printed verbatim.
If the intention is to call it, move it to its own line;
otherwise, escape it by prepending
.Sq \e& .
.It Sy "skipping paragraph macro"
In
.Xr mdoc 7
@ -1047,6 +1056,14 @@ argument is invalid.
The default font
.Cm \efR
is used instead.
.It Sy "nothing follows prefix"
.Pq mdoc
A
.Ic \&Pf
macro has no argument, or only one argument and no macro follows
on the same input line.
This defeats its purpose; in particular, spacing is not suppressed
before the text or macros following on the next input line.
.It Sy "missing -std argument, adding it"
.Pq mdoc
An

View File

@ -1,4 +1,4 @@
/* $Id: mandoc.h,v 1.171 2014/11/28 18:09:01 schwarze Exp $ */
/* $Id: mandoc.h,v 1.176 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef MANDOC_H
#define MANDOC_H
#define ASCII_NBRSP 31 /* non-breaking space */
#define ASCII_HYPH 30 /* breakable hyphen */
@ -77,6 +75,7 @@ enum mandocerr {
/* related to macros and nesting */
MANDOCERR_MACRO_OBS, /* obsolete macro: macro */
MANDOCERR_MACRO_CALL, /* macro neither callable nor escaped: macro */
MANDOCERR_PAR_SKIP, /* skipping paragraph macro: macro ... */
MANDOCERR_PAR_MOVE, /* moving paragraph macro out of list: macro */
MANDOCERR_NS_SKIP, /* skipping no-space macro */
@ -102,6 +101,7 @@ enum mandocerr {
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_PF_SKIP, /* nothing follows prefix: Pf arg */
MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
MANDOCERR_EQN_NOBOX, /* missing eqn box, using "": op */
@ -414,13 +414,13 @@ enum mandoc_esc {
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
__BEGIN_DECLS
struct mparse;
struct mchars;
struct mdoc;
struct man;
__BEGIN_DECLS
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
struct mchars *mchars_alloc(void);
void mchars_free(struct mchars *);
@ -437,7 +437,7 @@ void mparse_free(struct mparse *);
void mparse_keep(struct mparse *);
enum mandoclevel mparse_open(struct mparse *, int *, const char *);
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t,
enum mandoclevel mparse_readmem(struct mparse *, void *, size_t,
const char *);
void mparse_reset(struct mparse *);
void mparse_result(struct mparse *,
@ -448,5 +448,3 @@ const char *mparse_strlevel(enum mandoclevel);
enum mandoclevel mparse_wait(struct mparse *);
__END_DECLS
#endif /*!MANDOC_H*/

View File

@ -1,4 +1,4 @@
/* $Id: mandoc_aux.h,v 1.2 2014/04/23 21:06:41 schwarze Exp $ */
/* $Id: mandoc_aux.h,v 1.3 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* 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
@ -29,5 +27,3 @@ char *mandoc_strdup(const char *);
char *mandoc_strndup(const char *, size_t);
__END_DECLS
#endif /*!MANDOC_AUX_H*/

511
mandoc_headers.3 Normal file
View File

@ -0,0 +1,511 @@
.Dd December 1, 2014
.Dt MANDOC_HEADERS 3
.Os
.Sh NAME
.Nm mandoc_headers
.Nd ordering of mandoc include files
.Sh DESCRIPTION
To support a cleaner coding style, the mandoc header files do not
contain any include directives and do not guard against multiple
inclusion.
The application developer has to make sure that the headers are
included in a proper order, and that no header is included more
than once.
.Pp
The headers and functions form three major groups:
.Sx Parser interface ,
.Sx Parser internals ,
and
.Sx Formatter interface .
.Pp
Various rules are given below prohibiting the inclusion of certain
combinations of headers into the same file.
The intention is to keep the following functional components
separate from each other:
.Pp
.Bl -dash -offset indent -compact
.It
.Xr mdoc 7
parser
.It
.Xr man 7
parser
.It
.Xr roff 7
parser
.It
.Xr tbl 7
parser
.It
.Xr eqn 7
parser
.It
terminal formatters
.It
HTML formatters
.It
search tools
.El
.Pp
Note that mere usage of an opaque type does
.Em not
require inclusion of the header where that type is defined.
.Ss Parser interface
Each of the following headers can be included without including
any other mandoc header.
These headers should be included before any other mandoc headers.
Afterwards, any other mandoc headers can be included as needed.
.Bl -tag -width Ds
.It Qq Pa mandoc_aux.h
Requires
.In sys/types.h
for
.Vt size_t .
Provides the utility functions documented in
.Xr mandoc_malloc 3 .
.It Qq Pa mandoc.h
Requires
.In sys/types.h
for
.Vt size_t .
.Pp
Provides
.Vt enum mandoc_esc ,
.Vt enum mandocerr ,
.Vt enum mandoclevel ,
.Vt enum tbl_cellt ,
.Vt enum tbl_datt ,
.Vt enum tbl_spant ,
.Vt enum eqn_boxt ,
.Vt enum eqn_fontt ,
.Vt enum eqn_pilet ,
.Vt enum eqn_post ,
.Vt struct tbl_opts ,
.Vt struct tbl_head ,
.Vt struct tbl_cell ,
.Vt struct tbl_row ,
.Vt struct tbl_dat ,
.Vt struct tbl_span ,
.Vt struct eqn_box ,
.Vt struct eqn ,
the function prototype typedef
.Fn mandocmsg ,
the function
.Xr mandoc_escape 3 ,
the functions described in
.Xr mchars_alloc 3 ,
and the functions
.Fn mparse_*
described in
.Xr mandoc 3 .
.Pp
Uses the opaque types
.Vt struct mparse
from
.Pa read.c
and
.Vt struct mchars
from
.Pa chars.c
for function prototypes.
Uses the types
.Vt struct mdoc
from
.Pa libmdoc.h
and
.Vt struct man
from
.Pa libman.h
as opaque types for function prototypes.
.It Qq Pa mdoc.h
Requires
.In sys/types.h
for
.Vt size_t .
.Pp
Provides
.Vt enum mdoct ,
.Vt enum mdocargt ,
.Vt enum mdoc_type ,
.Vt enum mdoc_sec ,
.Vt enum mdoc_endbody ,
.Vt enum mdoc_disp ,
.Vt enum mdoc_list ,
.Vt enum mdoc_auth ,
.Vt enum mdoc_font ,
.Vt struct mdoc_meta ,
.Vt struct mdoc_argv ,
.Vt struct mdoc_arg ,
.Vt struct mdoc_bd ,
.Vt struct mdoc_bl ,
.Vt struct mdoc_an ,
.Vt struct mdoc_bf ,
.Vt struct mdoc_rs ,
.Vt struct mdoc_node ,
and the functions
.Fn mdoc_*
described in
.Xr mandoc 3 .
.Pp
Uses the type
.Vt struct mdoc
from
.Pa libmdoc.h
as an opaque type for function prototypes.
Uses pointers to the types
.Vt struct tbl_span
and
.Vt struct eqn
as opaque struct members.
.Pp
When this header is included, the same file should not include
.Pa libman.h
or
.Pa libroff.h .
.It Qq Pa man.h
Provides
.Vt enum mant ,
.Vt enum man_type ,
.Vt struct man_meta ,
.Vt struct man_node ,
and the functions
.Fn man_*
described in
.Xr mandoc 3 .
.Pp
Uses the opaque type
.Vt struct mparse
from
.Pa read.c
for function prototypes.
Uses the type
.Vt struct man
from
.Pa libman.h
as an opaque type for function prototypes.
Uses pointers to the types
.Vt struct tbl_span
and
.Vt struct eqn
as opaque struct members.
.Pp
When this header is included, the same file should not include
.Pa libmdoc.h
or
.Pa libroff.h .
.El
.Ss Parser internals
The following headers require inclusion of a parser interface header
before they can be included. All parser interface headers should
precede all parser internal headers. When any parser internal headers
are included, the same file should not include any formatter headers.
.Bl -tag -width Ds
.It Qq Pa libmandoc.h
Requires
.In sys/types.h
for
.Vt size_t .
.Pp
Provides
.Vt enum rofferr ,
.Vt struct buf ,
utility functions needed by multiple parsers,
and the top-level functions to call the parsers.
.Pp
Uses the opaque types
.Vt struct mparse
from
.Pa read.c
and
.Vt struct roff
from
.Pa roff.c
for function prototypes.
Uses the types
.Vt enum mandocerr ,
.Vt struct tbl_span ,
and
.Vt struct eqn
from
.Pa mandoc.h ,
.Vt struct mdoc
from
.Pa libmdoc.h ,
and
.Vt struct man
from
.Pa libman.h
as opaque types for function prototypes.
.It Qq Pa libmdoc.h
Requires
.Qq Pa mdoc.h
for
.Vt enum mdoct ,
.Vt enum mdoc_* ,
and
.Vt struct mdoc_* .
.Pp
Provides
.Vt enum mdoc_next ,
.Vt enum margserr ,
.Vt enum mdelim ,
.Vt struct mdoc ,
.Vt struct mdoc_macro ,
and many functions internal to the
.Xr mdoc 7
parser.
.Pp
Uses the opaque types
.Vt struct mparse
from
.Pa read.c
and
.Vt struct roff
from
.Pa roff.c .
.Pp
When this header is included, the same file should not include
.Pa man.h ,
.Pa libman.h ,
or
.Pa libroff.h .
.It Qq Pa libman.h
Requires
.Qq Pa man.h
for
.Vt enum mant
and
.Vt struct man_node.
.Pp
Provides
.Vt enum man_next ,
.Vt struct man ,
.Vt struct man_macro ,
and many functions internal to the
.Xr man 7
parser.
.Pp
Uses the opaque types
.Vt struct mparse
from
.Pa read.c
and
.Vt struct roff
from
.Pa roff.c .
.Pp
When this header is included, the same file should not include
.Pa mdoc.h ,
.Pa libmdoc.h ,
or
.Pa libroff.h .
.It Qq Pa libroff.h
Requires
.In sys/types.h
for
.Vt size_t ,
.Qq Pa mandoc.h
for
.Vt struct tbl_*
and
.Vt struct eqn ,
and
.Qq Pa libmandoc.h
for
.Vt enum rofferr .
.Pp
Provides
.Vt enum tbl_part ,
.Vt struct tbl_node ,
.Vt struct eqn_def ,
.Vt struct eqn_node ,
and many functions internal to the
.Xr tbl 7
and
.Xr eqn 7
parsers.
.Pp
Uses the opaque type
.Vt struct mparse
from
.Pa read.c .
.Pp
When this header is included, the same file should not include
.Pa man.h ,
.Pa mdoc.h ,
.Pa libman.h ,
or
.Pa libmdoc.h .
.El
.Ss Formatter interface
These headers should be included after any parser interface headers.
No parser internal headers should be included by the same file.
.Bl -tag -width Ds
.It Qq Pa out.h
Requires
.In sys/types.h
for
.Vt size_t .
.Pp
Provides
.Vt enum roffscale ,
.Vt struct roffcol ,
.Vt struct roffsu ,
.Vt struct rofftbl ,
.Fn a2roffsu ,
and
.Fn tblcalc .
.Pp
Uses
.Vt struct tbl_span
from
.Pa mandoc.h
as an opaque type for function prototypes.
.Pp
When this header is included, the same file should not include
.Pa manpath.h
or
.Pa mansearch.h .
.It Qq Pa term.h
Requires
.In sys/types.h
for
.Vt size_t
and
.Qq Pa out.h
for
.Vt struct roffsu
and
.Vt struct rofftbl .
.Pp
Provides
.Vt enum termenc ,
.Vt enum termfont ,
.Vt enum termtype ,
.Vt struct termp_tbl ,
.Vt struct termp ,
and many terminal formatting functions.
.Pp
Uses the opaque types
.Vt struct mchars
from
.Pa chars.c
and
.Vt struct termp_ps
from
.Pa term_ps.c .
Uses
.Vt struct tbl_span
and
.Vt struct eqn
from
.Pa mandoc.h
as opaque types for function prototypes.
.Pp
When this header is included, the same file should not include
.Pa html.h ,
.Pa manpath.h
or
.Pa mansearch.h .
.It Qq Pa html.h
Requires
.In sys/types.h
for
.Vt size_t ,
.In stdio.h
for
.Dv BUFSIZ ,
and
.Qq Pa out.h
for
.Vt struct roffsu
and
.Vt struct rofftbl .
.Pp
Provides
.Vt enum htmltag ,
.Vt enum htmlattr ,
.Vt enum htmlfont ,
.Vt struct tag ,
.Vt struct tagq ,
.Vt struct htmlpair ,
.Vt struct html ,
and many HTML formatting functions.
.Pp
Uses the opaque type
.Vt struct mchars
from
.Pa chars.c .
.Pp
When this header is included, the same file should not include
.Pa term.h ,
.Pa manpath.h
or
.Pa mansearch.h .
.It Qq Pa main.h
Provides the top level steering functions for all formatters.
.Pp
Uses the opaque type
.Vt struct mchars
from
.Pa chars.c .
Uses the types
.Vt struct mdoc
from
.Pa libmdoc.h
and
.Vt struct man
from
.Pa libman.h
as opaque types for function prototypes.
.It Qq Pa manpath.h
Requires
.In sys/types.h
for
.Vt size_t .
.Pp
Provides
.Vt struct manpaths
and the functions
.Fn manpath_manconf ,
.Fn manpath_parse ,
and
.Fn manpath_free .
.Pp
When this header is included, the same file should not include
.Pa out.h ,
.Pa term.h ,
or
.Pa html.h .
.It Qq Pa mansearch.h
Requires
.In sys/types.h
for
.Vt size_t
and
.In stdint.h
for
.Vt uint64_t .
.Pp
Provides
.Vt enum argmode ,
.Vt struct manpage ,
.Vt struct mansearch ,
and the functions
.Fn mansearch_setup ,
.Fn mansearch ,
and
.Fn mansearch_free .
.Pp
Uses
.Vt struct manpaths
from
.Pa manpath.h
as an opaque type for function prototypes.
.Pp
When this header is included, the same file should not include
.Pa out.h ,
.Pa term.h ,
or
.Pa html.h .
.El

View File

@ -1,4 +1,4 @@
/* $Id: mandocdb.c,v 1.171 2014/11/27 01:58:21 schwarze Exp $ */
/* $Id: mandocdb.c,v 1.179 2014/12/09 07:29:42 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -84,10 +84,9 @@ enum op {
};
struct str {
char *rendered; /* key in UTF-8 or ASCII form */
const struct mpage *mpage; /* if set, the owning parse */
uint64_t mask; /* bitmask in sequence */
char key[]; /* may contain escape sequences */
char key[]; /* rendered text */
};
struct inodev {
@ -104,6 +103,7 @@ struct mpage {
char *desc; /* description from file content */
struct mlink *mlinks; /* singly linked list */
int form; /* format from file content */
int name_head_done;
};
struct mlink {
@ -124,11 +124,13 @@ enum stmt {
STMT_INSERT_PAGE, /* insert mpage */
STMT_INSERT_LINK, /* insert mlink */
STMT_INSERT_NAME, /* insert name */
STMT_SELECT_NAME, /* retrieve existing name flags */
STMT_INSERT_KEY, /* insert parsed key */
STMT__MAX
};
typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_node *);
typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
struct mdoc_handler {
mdoc_fp fp; /* optional handler */
@ -136,7 +138,7 @@ struct mdoc_handler {
};
static void dbclose(int);
static void dbadd(struct mpage *, struct mchars *);
static void dbadd(struct mpage *);
static void dbadd_mlink(const struct mlink *mlink);
static void dbadd_mlink_name(const struct mlink *mlink);
static int dbopen(int);
@ -150,25 +152,37 @@ static void mlink_check(struct mpage *, struct mlink *);
static void mlink_free(struct mlink *);
static void mlinks_undupe(struct mpage *);
static void mpages_free(void);
static void mpages_merge(struct mchars *, struct mparse *);
static void mpages_merge(struct mparse *);
static void names_check(void);
static void parse_cat(struct mpage *, int);
static void parse_man(struct mpage *, const struct man_node *);
static void parse_mdoc(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_body(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_head(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Fd(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Fn(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Nd(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Nm(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Sh(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Xr(struct mpage *, const struct mdoc_node *);
static void parse_man(struct mpage *, const struct man_meta *,
const struct man_node *);
static void parse_mdoc(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_body(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_head(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_Fd(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static void parse_mdoc_fname(struct mpage *, const struct mdoc_node *);
static int parse_mdoc_Fn(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_Fo(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_Nd(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_Nm(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_Sh(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static int parse_mdoc_Xr(struct mpage *, const struct mdoc_meta *,
const struct mdoc_node *);
static void putkey(const struct mpage *, char *, uint64_t);
static void putkeys(const struct mpage *,
const char *, size_t, uint64_t);
static void putkeys(const struct mpage *, char *, size_t, uint64_t);
static void putmdockey(const struct mpage *,
const struct mdoc_node *, uint64_t);
static void render_key(struct mchars *, struct str *);
static int render_string(char **, size_t *);
static void say(const char *, const char *, ...);
static int set_basedir(const char *, int);
static int treescan(void);
@ -185,6 +199,7 @@ static int write_utf8; /* write UTF-8 output; else ASCII */
static int exitcode; /* to be returned by main */
static enum op op; /* operational mode */
static char basedir[PATH_MAX]; /* current base directory */
static struct mchars *mchars; /* table of named characters */
static struct ohash mpages; /* table of distinct manual pages */
static struct ohash mlinks; /* table of directory entries */
static struct ohash names; /* table of all names */
@ -290,7 +305,7 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
{ NULL, 0 }, /* Ux */
{ NULL, 0 }, /* Xc */
{ NULL, 0 }, /* Xo */
{ parse_mdoc_head, 0 }, /* Fo */
{ parse_mdoc_Fo, 0 }, /* Fo */
{ NULL, 0 }, /* Fc */
{ NULL, 0 }, /* Oo */
{ NULL, 0 }, /* Oc */
@ -321,12 +336,11 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
int
main(int argc, char *argv[])
mandocdb(int argc, char *argv[])
{
int ch, i;
size_t j, sz;
const char *path_arg;
struct mchars *mc;
struct manpaths dirs;
struct mparse *mp;
struct ohash_info mpages_info, mlinks_info;
@ -426,9 +440,9 @@ main(int argc, char *argv[])
}
exitcode = (int)MANDOCLEVEL_OK;
mc = mchars_alloc();
mchars = mchars_alloc();
mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL,
mc, NULL);
mchars, NULL);
ohash_init(&mpages, 6, &mpages_info);
ohash_init(&mlinks, 6, &mlinks_info);
@ -464,7 +478,7 @@ main(int argc, char *argv[])
goto out;
}
if (OP_DELETE != op)
mpages_merge(mc, mp);
mpages_merge(mp);
dbclose(OP_DEFAULT == op ? 0 : 1);
} else {
/*
@ -511,7 +525,7 @@ main(int argc, char *argv[])
if (0 == dbopen(0))
continue;
mpages_merge(mc, mp);
mpages_merge(mp);
if (warnings && !nodb &&
! (MPARSE_QUICK & mparse_options))
names_check();
@ -527,7 +541,7 @@ main(int argc, char *argv[])
out:
manpath_free(&dirs);
mparse_free(mp);
mchars_free(mc);
mchars_free(mchars);
mpages_free();
ohash_delete(&mpages);
ohash_delete(&mlinks);
@ -1074,7 +1088,7 @@ mlink_check(struct mpage *mpage, struct mlink *mlink)
* and filename to determine whether the file is parsable or not.
*/
static void
mpages_merge(struct mchars *mc, struct mparse *mp)
mpages_merge(struct mparse *mp)
{
char any[] = "any";
struct ohash_info str_info;
@ -1213,16 +1227,14 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
putkey(mpage, mlink->name, NAME_FILE);
}
assert(NULL == mpage->desc);
if (NULL != mdoc) {
if (NULL != (cp = mdoc_meta(mdoc)->name))
putkey(mpage, cp, NAME_HEAD);
parse_mdoc(mpage, mdoc_node(mdoc));
} else if (NULL != man)
parse_man(mpage, man_node(man));
assert(mpage->desc == NULL);
if (mdoc != NULL)
parse_mdoc(mpage, mdoc_meta(mdoc), mdoc_node(mdoc));
else if (man != NULL)
parse_man(mpage, man_meta(man), man_node(man));
else
parse_cat(mpage, fd);
if (NULL == mpage->desc)
if (mpage->desc == NULL)
mpage->desc = mandoc_strdup(mpage->mlinks->name);
if (warnings && !use_all)
@ -1230,7 +1242,7 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
mlink = mlink->next)
mlink_check(mpage, mlink);
dbadd(mpage, mc);
dbadd(mpage);
nextpage:
if (mparse_wait(mp) != MANDOCLEVEL_OK) {
@ -1427,7 +1439,8 @@ putmdockey(const struct mpage *mpage,
}
static void
parse_man(struct mpage *mpage, const struct man_node *n)
parse_man(struct mpage *mpage, const struct man_meta *meta,
const struct man_node *n)
{
const struct man_node *head, *body;
char *start, *title;
@ -1493,6 +1506,11 @@ parse_man(struct mpage *mpage, const struct man_node *n)
break;
putkey(mpage, start, NAME_TITLE);
if ( ! (mpage->name_head_done ||
strcasecmp(start, meta->title))) {
putkey(mpage, start, NAME_HEAD);
mpage->name_head_done = 1;
}
if (' ' == byte) {
start += sz + 1;
@ -1507,6 +1525,11 @@ parse_man(struct mpage *mpage, const struct man_node *n)
if (start == title) {
putkey(mpage, start, NAME_TITLE);
if ( ! (mpage->name_head_done ||
strcasecmp(start, meta->title))) {
putkey(mpage, start, NAME_HEAD);
mpage->name_head_done = 1;
}
free(title);
return;
}
@ -1537,12 +1560,13 @@ parse_man(struct mpage *mpage, const struct man_node *n)
for (n = n->child; n; n = n->next) {
if (NULL != mpage->desc)
break;
parse_man(mpage, n);
parse_man(mpage, meta, n);
}
}
static void
parse_mdoc(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
assert(NULL != n);
@ -1558,7 +1582,7 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node *n)
/* FALLTHROUGH */
case MDOC_TAIL:
if (NULL != mdocs[n->tok].fp)
if (0 == (*mdocs[n->tok].fp)(mpage, n))
if (0 == (*mdocs[n->tok].fp)(mpage, meta, n))
break;
if (mdocs[n->tok].mask)
putmdockey(mpage, n->child,
@ -1569,14 +1593,15 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node *n)
continue;
}
if (NULL != n->child)
parse_mdoc(mpage, n);
parse_mdoc(mpage, meta, n);
}
}
static int
parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
const char *start, *end;
char *start, *end;
size_t sz;
if (SEC_SYNOPSIS != n->sec ||
@ -1616,41 +1641,61 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n)
return(0);
}
static int
parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_node *n)
static void
parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n)
{
char *cp;
size_t sz;
if (NULL == (n = n->child) || MDOC_TEXT != n->type)
if (n->type != MDOC_TEXT)
return;
/* Skip function pointer punctuation. */
cp = n->string;
while (*cp == '(' || *cp == '*')
cp++;
sz = strcspn(cp, "()");
putkeys(mpage, cp, sz, TYPE_Fn);
if (n->sec == SEC_SYNOPSIS)
putkeys(mpage, cp, sz, NAME_SYN);
}
static int
parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
if (n->child == NULL)
return(0);
/*
* Parse: .Fn "struct type *name" "char *arg".
* First strip away pointer symbol.
* Then store the function name, then type.
* Finally, store the arguments.
*/
parse_mdoc_fname(mpage, n->child);
if (NULL == (cp = strrchr(n->string, ' ')))
cp = n->string;
while ('*' == *cp)
cp++;
putkey(mpage, cp, TYPE_Fn);
if (n->string < cp)
putkeys(mpage, n->string, cp - n->string, TYPE_Ft);
for (n = n->next; NULL != n; n = n->next)
if (MDOC_TEXT == n->type)
for (n = n->child->next; n != NULL; n = n->next)
if (n->type == MDOC_TEXT)
putkey(mpage, n->string, TYPE_Fa);
return(0);
}
static int
parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_Fo(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
if (n->type != MDOC_HEAD)
return(1);
if (n->child != NULL)
parse_mdoc_fname(mpage, n->child);
return(0);
}
static int
parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
char *cp;
@ -1669,7 +1714,8 @@ parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n)
}
static int
parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
if (MDOC_BODY == n->type)
@ -1678,32 +1724,46 @@ parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n)
}
static int
parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
if (SEC_NAME == n->sec)
putmdockey(mpage, n->child, NAME_TITLE);
else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type)
putmdockey(mpage, n->child, NAME_SYN);
else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) {
if (n->child == NULL)
putkey(mpage, meta->name, NAME_SYN);
else
putmdockey(mpage, n->child, NAME_SYN);
}
if ( ! (mpage->name_head_done ||
n->child == NULL || n->child->string == NULL ||
strcasecmp(n->child->string, meta->title))) {
putkey(mpage, n->child->string, NAME_HEAD);
mpage->name_head_done = 1;
}
return(0);
}
static int
parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
return(SEC_CUSTOM == n->sec && MDOC_HEAD == n->type);
}
static int
parse_mdoc_head(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_head(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
return(MDOC_HEAD == n->type);
}
static int
parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n)
parse_mdoc_body(struct mpage *mpage, const struct mdoc_meta *meta,
const struct mdoc_node *n)
{
return(MDOC_BODY == n->type);
@ -1715,18 +1775,19 @@ parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n)
* When we finish the manual, we'll dump the table.
*/
static void
putkeys(const struct mpage *mpage,
const char *cp, size_t sz, uint64_t v)
putkeys(const struct mpage *mpage, char *cp, size_t sz, uint64_t v)
{
struct ohash *htab;
struct str *s;
const char *end;
unsigned int slot;
int i;
int i, mustfree;
if (0 == sz)
return;
mustfree = render_string(&cp, &sz);
if (TYPE_Nm & v) {
htab = &names;
v &= name_mask;
@ -1734,7 +1795,7 @@ putkeys(const struct mpage *mpage,
name_mask &= ~NAME_FIRST;
if (debug > 1)
say(mpage->mlinks->file,
"Adding name %*s", sz, cp);
"Adding name %*s, bits=%d", sz, cp, v);
} else {
htab = &strings;
if (debug > 1)
@ -1759,6 +1820,9 @@ putkeys(const struct mpage *mpage,
}
s->mpage = mpage;
s->mask = v;
if (mustfree)
free(cp);
}
/*
@ -1814,20 +1878,19 @@ utf8(unsigned int cp, char out[7])
}
/*
* Store the rendered version of a key, or alias the pointer
* if the key contains no escape sequences.
* If the string contains escape sequences,
* replace it with an allocated rendering and return 1,
* such that the caller can free it after use.
* Otherwise, do nothing and return 0.
*/
static void
render_key(struct mchars *mc, struct str *key)
static int
render_string(char **public, size_t *psz)
{
size_t sz, bsz, pos;
const char *src, *scp, *addcp, *seq;
char *dst;
size_t ssz, dsz, addsz;
char utfbuf[7], res[6];
char *buf;
const char *seq, *cpp, *val;
int len, u;
enum mandoc_esc esc;
assert(NULL == key->rendered);
int seqlen, unicode;
res[0] = '\\';
res[1] = '\t';
@ -1836,68 +1899,62 @@ render_key(struct mchars *mc, struct str *key)
res[4] = ASCII_BREAK;
res[5] = '\0';
val = key->key;
bsz = strlen(val);
src = scp = *public;
ssz = *psz;
dst = NULL;
dsz = 0;
/*
* Pre-check: if we have no stop-characters, then set the
* pointer as ourselvse and get out of here.
*/
if (strcspn(val, res) == bsz) {
key->rendered = key->key;
return;
}
while (scp < src + *psz) {
/* Pre-allocate by the length of the input */
/* Leave normal characters unchanged. */
buf = mandoc_malloc(++bsz);
pos = 0;
while ('\0' != *val) {
/*
* Halt on the first escape sequence.
* This also halts on the end of string, in which case
* we just copy, fallthrough, and exit the loop.
*/
if ((sz = strcspn(val, res)) > 0) {
memcpy(&buf[pos], val, sz);
pos += sz;
val += sz;
if (strchr(res, *scp) == NULL) {
if (dst != NULL)
dst[dsz++] = *scp;
scp++;
continue;
}
switch (*val) {
case ASCII_HYPH:
buf[pos++] = '-';
val++;
continue;
/*
* Found something that requires replacing,
* make sure we have a destination buffer.
*/
if (dst == NULL) {
dst = mandoc_malloc(ssz + 1);
dsz = scp - src;
memcpy(dst, src, dsz);
}
/* Handle single-char special characters. */
switch (*scp) {
case '\\':
break;
case '\t':
/* FALLTHROUGH */
case ASCII_NBRSP:
buf[pos++] = ' ';
val++;
dst[dsz++] = ' ';
scp++;
continue;
case ASCII_HYPH:
dst[dsz++] = '-';
/* FALLTHROUGH */
case ASCII_BREAK:
scp++;
continue;
default:
break;
abort();
}
if ('\\' != *val)
break;
/* Read past the slash. */
val++;
/*
* Parse the escape sequence and see if it's a
* predefined character or special character.
* Found an escape sequence.
* Read past the slash, then parse it.
* Ignore everything except characters.
*/
esc = mandoc_escape((const char **)&val,
&seq, &len);
if (ESCAPE_ERROR == esc)
break;
if (ESCAPE_SPECIAL != esc)
scp++;
if (mandoc_escape(&scp, &seq, &seqlen) != ESCAPE_SPECIAL)
continue;
/*
@ -1906,32 +1963,44 @@ render_key(struct mchars *mc, struct str *key)
*/
if (write_utf8) {
if ((u = mchars_spec2cp(mc, seq, len)) <= 0)
unicode = mchars_spec2cp(mchars, seq, seqlen);
if (unicode <= 0)
continue;
cpp = utfbuf;
if (0 == (sz = utf8(u, utfbuf)))
addsz = utf8(unicode, utfbuf);
if (addsz == 0)
continue;
sz = strlen(cpp);
addcp = utfbuf;
} else {
cpp = mchars_spec2str(mc, seq, len, &sz);
if (NULL == cpp)
addcp = mchars_spec2str(mchars, seq, seqlen, &addsz);
if (addcp == NULL)
continue;
if (ASCII_NBRSP == *cpp) {
cpp = " ";
sz = 1;
if (*addcp == ASCII_NBRSP) {
addcp = " ";
addsz = 1;
}
}
/* Copy the rendered glyph into the stream. */
bsz += sz;
buf = mandoc_realloc(buf, bsz);
memcpy(&buf[pos], cpp, sz);
pos += sz;
ssz += addsz;
dst = mandoc_realloc(dst, ssz + 1);
memcpy(dst + dsz, addcp, addsz);
dsz += addsz;
}
if (dst != NULL) {
*public = dst;
*psz = dsz;
}
buf[pos] = '\0';
key->rendered = buf;
/* Trim trailing whitespace and NUL-terminate. */
while (*psz > 0 && (*public)[*psz - 1] == ' ')
--*psz;
if (dst != NULL) {
(*public)[*psz] = '\0';
return(1);
} else
return(0);
}
static void
@ -1951,12 +2020,21 @@ dbadd_mlink(const struct mlink *mlink)
static void
dbadd_mlink_name(const struct mlink *mlink)
{
uint64_t bits;
size_t i;
dbadd_mlink(mlink);
i = 1;
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, NAME_FILE & NAME_MASK);
SQL_BIND_INT64(stmts[STMT_SELECT_NAME], i, mlink->mpage->pageid);
bits = NAME_FILE & NAME_MASK;
if (sqlite3_step(stmts[STMT_SELECT_NAME]) == SQLITE_ROW) {
bits |= sqlite3_column_int64(stmts[STMT_SELECT_NAME], 0);
sqlite3_reset(stmts[STMT_SELECT_NAME]);
}
i = 1;
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, bits);
SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, mlink->name);
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mlink->mpage->pageid);
SQL_STEP(stmts[STMT_INSERT_NAME]);
@ -1970,28 +2048,24 @@ dbadd_mlink_name(const struct mlink *mlink)
* Also, handle escape sequences at the last possible moment.
*/
static void
dbadd(struct mpage *mpage, struct mchars *mc)
dbadd(struct mpage *mpage)
{
struct mlink *mlink;
struct str *key;
char *cp;
size_t i;
unsigned int slot;
int mustfree;
mlink = mpage->mlinks;
if (nodb) {
for (key = ohash_first(&names, &slot); NULL != key;
key = ohash_next(&names, &slot)) {
if (key->rendered != key->key)
free(key->rendered);
key = ohash_next(&names, &slot))
free(key);
}
for (key = ohash_first(&strings, &slot); NULL != key;
key = ohash_next(&strings, &slot)) {
if (key->rendered != key->key)
free(key->rendered);
key = ohash_next(&strings, &slot))
free(key);
}
if (0 == debug)
return;
while (NULL != mlink) {
@ -2020,21 +2094,17 @@ dbadd(struct mpage *mpage, struct mchars *mc)
if (debug)
say(mlink->file, "Adding to database");
i = strlen(mpage->desc) + 1;
key = mandoc_calloc(1, sizeof(struct str) + i);
memcpy(key->key, mpage->desc, i);
render_key(mc, key);
cp = mpage->desc;
i = strlen(cp);
mustfree = render_string(&cp, &i);
i = 1;
SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, key->rendered);
SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, cp);
SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, mpage->form);
SQL_STEP(stmts[STMT_INSERT_PAGE]);
mpage->pageid = sqlite3_last_insert_rowid(db);
sqlite3_reset(stmts[STMT_INSERT_PAGE]);
if (key->rendered != key->key)
free(key->rendered);
free(key);
if (mustfree)
free(cp);
while (NULL != mlink) {
dbadd_mlink(mlink);
@ -2045,31 +2115,23 @@ dbadd(struct mpage *mpage, struct mchars *mc)
for (key = ohash_first(&names, &slot); NULL != key;
key = ohash_next(&names, &slot)) {
assert(key->mpage == mpage);
if (NULL == key->rendered)
render_key(mc, key);
i = 1;
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask);
SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->rendered);
SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->key);
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->pageid);
SQL_STEP(stmts[STMT_INSERT_NAME]);
sqlite3_reset(stmts[STMT_INSERT_NAME]);
if (key->rendered != key->key)
free(key->rendered);
free(key);
}
for (key = ohash_first(&strings, &slot); NULL != key;
key = ohash_next(&strings, &slot)) {
assert(key->mpage == mpage);
if (NULL == key->rendered)
render_key(mc, key);
i = 1;
SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask);
SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered);
SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->key);
SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->pageid);
SQL_STEP(stmts[STMT_INSERT_KEY]);
sqlite3_reset(stmts[STMT_INSERT_KEY]);
if (key->rendered != key->key)
free(key->rendered);
free(key);
}
}
@ -2269,7 +2331,8 @@ dbopen(int real)
" \"bits\" INTEGER NOT NULL,\n"
" \"name\" TEXT NOT NULL,\n"
" \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
"ON DELETE CASCADE\n"
"ON DELETE CASCADE,\n"
" UNIQUE (\"name\", \"pageid\") ON CONFLICT REPLACE\n"
");\n"
"\n"
"CREATE TABLE \"keys\" (\n"
@ -2307,6 +2370,8 @@ dbopen(int real)
sql = "INSERT INTO mlinks "
"(sec,arch,name,pageid) VALUES (?,?,?,?)";
sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_LINK], NULL);
sql = "SELECT bits FROM names where pageid = ?";
sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_SELECT_NAME], NULL);
sql = "INSERT INTO names "
"(bits,name,pageid) VALUES (?,?,?)";
sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_NAME], NULL);

View File

@ -1,4 +1,4 @@
/* $Id: manpath.h,v 1.6 2012/06/08 10:32:40 kristaps Exp $ */
/* $Id: manpath.h,v 1.7 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@ -15,8 +15,6 @@
* 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
@ -34,5 +32,3 @@ void manpath_parse(struct manpaths *, const char *, char *, char *);
void manpath_free(struct manpaths *);
__END_DECLS
#endif /*!MANPATH_H*/

View File

@ -1,4 +1,4 @@
.\" $Id: mansearch.3,v 1.2 2014/08/05 15:29:30 schwarze Exp $
.\" $Id: mansearch.3,v 1.3 2014/12/12 21:44:33 schwarze Exp $
.\"
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
.\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: August 5 2014 $
.Dd $Mdocdate: December 12 2014 $
.Dt MANSEARCH 3
.Os
.Sh NAME
@ -172,7 +172,7 @@ using the following query:
If the
.Fa outkey
differs from
.Qq Nd ,
.Qq Ic \&Nd ,
the requested output data is assembled into the
.Va output
field of the result structure by the function

View File

@ -1,4 +1,4 @@
/* $Id: mansearch.c,v 1.51 2014/11/27 01:58:21 schwarze Exp $ */
/* $Id: mansearch.c,v 1.52 2014/12/06 01:23:24 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -21,6 +21,7 @@
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
@ -246,7 +247,8 @@ mansearch(const struct mansearch *search,
SQLITE_OPEN_READONLY, NULL);
if (SQLITE_OK != c) {
perror(MANDOC_DB);
fprintf(stderr, "%s/%s: %s\n",
paths->paths[i], MANDOC_DB, strerror(errno));
sqlite3_close(db);
continue;
}

View File

@ -1,4 +1,4 @@
/* $Id: mansearch.h,v 1.21 2014/11/27 01:58:21 schwarze Exp $ */
/* $Id: mansearch.h,v 1.23 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,8 +15,6 @@
* 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"
@ -99,6 +97,8 @@ struct mansearch {
__BEGIN_DECLS
struct manpaths;
int mansearch_setup(int);
int mansearch(const struct mansearch *cfg, /* options */
const struct manpaths *paths, /* manpaths */
@ -109,5 +109,3 @@ int mansearch(const struct mansearch *cfg, /* options */
void mansearch_free(struct manpage *, size_t);
__END_DECLS
#endif /* MANSEARCH_H */

View File

@ -1,4 +1,4 @@
/* $Id: mansearch_const.c,v 1.6 2014/08/10 23:54:41 schwarze Exp $ */
/* $Id: mansearch_const.c,v 1.7 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
*
@ -20,7 +20,6 @@
#include <stdint.h>
#include "manpath.h"
#include "mansearch.h"
const int mansearch_keymax = 40;

18
mdoc.7
View File

@ -1,4 +1,4 @@
.\" $Id: mdoc.7,v 1.244 2014/11/28 18:36:35 schwarze Exp $
.\" $Id: mdoc.7,v 1.245 2014/11/30 21:56:18 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze <schwarze@openbsd.org>
@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: November 28 2014 $
.Dd $Mdocdate: November 30 2014 $
.Dt MDOC 7
.Os
.Sh NAME
@ -2396,8 +2396,6 @@ The original C standard.
.Pp
.It \-isoC-99
.St -isoC-99
.It \-ansiC-99
.St -ansiC-99
.br
The second major version of the C language standard.
.Pp
@ -2497,9 +2495,6 @@ The following three refer to parts of it.
.br
Networking APIs, including sockets.
.Pp
.It \-xpg4.3
.St -xpg4.3
.Pp
.It \-svid4
.St -svid4 ,
.br
@ -2529,14 +2524,9 @@ The following refer to parts of it.
.It \-xns5.2
.St -xns5.2
.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.
.It Single UNIX Specification version 3
.Pp
.Bl -tag -width "-p1003.1-2001" -compact
.It \-p1003.1-2001
.St -p1003.1-2001
.It \-susv3

6
mdoc.h
View File

@ -1,4 +1,4 @@
/* $Id: mdoc.h,v 1.131 2014/07/29 13:58:18 schwarze Exp $ */
/* $Id: mdoc.h,v 1.132 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -14,8 +14,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef MDOC_H
#define MDOC_H
enum mdoct {
MDOC_Ap = 0,
@ -395,5 +393,3 @@ const struct mdoc_meta *mdoc_meta(const struct mdoc *);
void mdoc_deroff(char **, const struct mdoc_node *);
__END_DECLS
#endif /*!MDOC_H*/

View File

@ -1,4 +1,4 @@
/* $Id: mdoc_html.c,v 1.213 2014/11/27 22:27:56 schwarze Exp $ */
/* $Id: mdoc_html.c,v 1.216 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -26,11 +26,10 @@
#include <string.h>
#include <unistd.h>
#include "mandoc.h"
#include "mandoc_aux.h"
#include "mdoc.h"
#include "out.h"
#include "html.h"
#include "mdoc.h"
#include "main.h"
#define INDENT 5
@ -1202,7 +1201,8 @@ mdoc_bd_pre(MDOC_ARGS)
default:
break;
}
if (nn->next && nn->next->line == nn->line)
if (h->flags & HTML_NONEWLINE ||
(nn->next && ! (nn->next->flags & MDOC_LINE)))
continue;
else if (nn->next)
print_text(h, "\n");
@ -1869,7 +1869,8 @@ static void
mdoc_pf_post(MDOC_ARGS)
{
h->flags |= HTML_NOSPACE;
if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
h->flags |= HTML_NOSPACE;
}
static int

View File

@ -1,4 +1,4 @@
/* $Id: mdoc_macro.c,v 1.154 2014/11/29 04:31:35 schwarze Exp $ */
/* $Id: mdoc_macro.c,v 1.157 2014/12/13 13:14:39 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -53,7 +53,8 @@ static void phrase_ta(MACRO_PROT_ARGS);
static void dword(struct mdoc *, int, int, const char *,
enum mdelim, int);
static void append_delims(struct mdoc *, int, int *, char *);
static enum mdoct lookup(enum mdoct, const char *);
static enum mdoct lookup(struct mdoc *, enum mdoct,
int, int, const char *);
static int macro_or_word(MACRO_PROT_ARGS, int);
static int make_pending(struct mdoc_node *, enum mdoct,
struct mdoc *, int, int);
@ -245,14 +246,19 @@ mdoc_macroend(struct mdoc *mdoc)
* or as a line macro if from == MDOC_MAX.
*/
static enum mdoct
lookup(enum mdoct from, const char *p)
lookup(struct mdoc *mdoc, enum mdoct from, int line, int ppos, const char *p)
{
enum mdoct res;
if (from == MDOC_MAX || mdoc_macros[from].flags & MDOC_PARSED) {
res = mdoc_hash_find(p);
if (res != MDOC_MAX && mdoc_macros[res].flags & MDOC_CALLABLE)
return(res);
if (res != MDOC_MAX) {
if (mdoc_macros[res].flags & MDOC_CALLABLE)
return(res);
if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
mandoc_msg(MANDOCERR_MACRO_CALL,
mdoc->parse, line, ppos, p);
}
}
return(MDOC_MAX);
}
@ -666,12 +672,10 @@ macro_or_word(MACRO_PROT_ARGS, int parsed)
p = buf + ppos;
ntok = MDOC_MAX;
if (mdoc->flags & MDOC_PHRASELIT)
/* nothing */;
else if (*p == '"')
if (*p == '"')
p++;
else if (parsed)
ntok = lookup(tok, p);
else if (parsed && ! (mdoc->flags & MDOC_PHRASELIT))
ntok = lookup(mdoc, tok, line, ppos, p);
if (ntok == MDOC_MAX) {
dword(mdoc, line, ppos, p, DELIM_MAX, tok == MDOC_MAX ||
@ -832,7 +836,8 @@ blk_exp_close(MACRO_PROT_ARGS)
if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
break;
ntok = ac == ARGS_QWORD ? MDOC_MAX : lookup(tok, p);
ntok = ac == ARGS_QWORD ? MDOC_MAX :
lookup(mdoc, tok, line, lastarg, p);
if (ntok == MDOC_MAX) {
dword(mdoc, line, lastarg, p, DELIM_MAX,
@ -933,7 +938,7 @@ in_line(MACRO_PROT_ARGS)
}
ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ?
MDOC_MAX : lookup(tok, p);
MDOC_MAX : lookup(mdoc, tok, line, la, p);
/*
* In this case, we've located a submacro and must
@ -1389,7 +1394,7 @@ in_line_argn(MACRO_PROT_ARGS)
char *p;
enum mdoct ntok;
nl = MDOC_NEWLINE & mdoc->flags;
nl = mdoc->flags & MDOC_NEWLINE;
/*
* A line macro that has a fixed number of arguments (maxargs).
@ -1421,11 +1426,18 @@ in_line_argn(MACRO_PROT_ARGS)
mdoc_argv(mdoc, line, tok, &arg, pos, buf);
for (flushed = j = 0; ; ) {
p = NULL;
flushed = j = 0;
for (;;) {
la = *pos;
ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
if (ac == ARGS_PUNCT || ac == ARGS_EOLN) {
if (j < 2 && tok == MDOC_Pf)
mandoc_vmsg(MANDOCERR_PF_SKIP,
mdoc->parse, line, ppos, "Pf %s",
p == NULL ? "at eol" : p);
break;
}
if ( ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) &&
ac != ARGS_QWORD && j == 0 &&
@ -1440,7 +1452,8 @@ in_line_argn(MACRO_PROT_ARGS)
flushed = 1;
}
ntok = ac == ARGS_QWORD ? MDOC_MAX : lookup(tok, p);
ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && j == 0)) ?
MDOC_MAX : lookup(mdoc, tok, line, la, p);
if (ntok != MDOC_MAX) {
if ( ! flushed)
@ -1463,8 +1476,11 @@ in_line_argn(MACRO_PROT_ARGS)
j++;
}
if (j == 0)
if (j == 0) {
mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
if (ac == ARGS_PUNCT && tok == MDOC_Pf)
append_delims(mdoc, line, pos, buf);
}
if ( ! flushed)
rew_elem(mdoc, tok);
if (nl)

View File

@ -1,4 +1,4 @@
/* $Id: mdoc_man.c,v 1.76 2014/11/27 22:27:56 schwarze Exp $ */
/* $Id: mdoc_man.c,v 1.77 2014/11/30 05:29:00 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
*
@ -1602,7 +1602,8 @@ static void
post_pf(DECL_ARGS)
{
outflags &= ~MMAN_spc;
if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
outflags &= ~MMAN_spc;
}
static int

View File

@ -1,4 +1,4 @@
/* $Id: mdoc_term.c,v 1.297 2014/11/28 16:54:23 schwarze Exp $ */
/* $Id: mdoc_term.c,v 1.299 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -1632,7 +1632,8 @@ termp_bd_pre(DECL_ARGS)
default:
break;
}
if (nn->next && nn->next->line == nn->line)
if (p->flags & TERMP_NONEWLINE ||
(nn->next && ! (nn->next->flags & MDOC_LINE)))
continue;
term_flushln(p);
p->flags |= TERMP_NOSPACE;
@ -1734,7 +1735,8 @@ static void
termp_pf_post(DECL_ARGS)
{
p->flags |= TERMP_NOSPACE;
if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
p->flags |= TERMP_NOSPACE;
}
static int

View File

@ -1,4 +1,4 @@
/* $Id: mdoc_validate.c,v 1.262 2014/11/28 18:36:35 schwarze Exp $ */
/* $Id: mdoc_validate.c,v 1.263 2014/11/30 05:29:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@ -210,7 +210,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, NULL }, /* Nx */
{ NULL, NULL }, /* Ox */
{ NULL, NULL }, /* Pc */
{ NULL, ewarn_eq1 }, /* Pf */
{ NULL, NULL }, /* Pf */
{ NULL, NULL }, /* Po */
{ NULL, NULL }, /* Pq */
{ NULL, NULL }, /* Qc */

3
msec.c
View File

@ -1,4 +1,4 @@
/* $Id: msec.c,v 1.12 2014/08/10 23:54:41 schwarze Exp $ */
/* $Id: msec.c,v 1.13 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -20,7 +20,6 @@
#include <string.h>
#include "mandoc.h"
#include "libmandoc.h"
#define LINE(x, y) \

4
out.c
View File

@ -1,4 +1,4 @@
/* $Id: out.c,v 1.53 2014/10/14 18:18:05 schwarze Exp $ */
/* $Id: out.c,v 1.54 2014/12/04 02:05:42 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -110,7 +110,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
case '\0':
if (SCALE_MAX == def)
return(0);
unit = SCALE_EN;
unit = def;
break;
case 'u':
unit = SCALE_BU;

12
out.h
View File

@ -1,4 +1,4 @@
/* $Id: out.h,v 1.24 2014/10/14 02:16:06 schwarze Exp $ */
/* $Id: out.h,v 1.26 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -14,8 +14,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef OUT_H
#define OUT_H
enum roffscale {
SCALE_CM, /* centimeters (c) */
@ -52,8 +50,6 @@ struct rofftbl {
void *arg; /* passed to slen and len */
};
__BEGIN_DECLS
#define SCALE_VS_INIT(p, v) \
do { (p)->unit = SCALE_VS; \
(p)->scale = (v); } \
@ -64,10 +60,12 @@ __BEGIN_DECLS
(p)->scale = (v); } \
while (/* CONSTCOND */ 0)
__BEGIN_DECLS
struct tbl_span;
int a2roffsu(const char *, struct roffsu *, enum roffscale);
void tblcalc(struct rofftbl *tbl,
const struct tbl_span *, size_t);
__END_DECLS
#endif /*!OUT_H*/

9
read.c
View File

@ -1,4 +1,4 @@
/* $Id: read.c,v 1.101 2014/11/28 18:09:01 schwarze Exp $ */
/* $Id: read.c,v 1.104 2014/12/01 04:14:14 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@ -41,7 +41,6 @@
#include "libmandoc.h"
#include "mdoc.h"
#include "man.h"
#include "main.h"
#define REPARSE_LIMIT 1000
@ -120,6 +119,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
/* related to macros and nesting */
"obsolete macro",
"macro neither callable nor escaped",
"skipping paragraph macro",
"moving paragraph macro out of list",
"skipping no-space macro",
@ -145,6 +145,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"empty list item",
"missing font type, using \\fR",
"unknown font type, using \\fR",
"nothing follows prefix",
"missing -std argument, adding it",
"missing eqn box, using \"\"",
@ -754,12 +755,12 @@ mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file)
}
enum mandoclevel
mparse_readmem(struct mparse *curp, const void *buf, size_t len,
mparse_readmem(struct mparse *curp, void *buf, size_t len,
const char *file)
{
struct buf blk;
blk.buf = UNCONST(buf);
blk.buf = buf;
blk.sz = len;
mparse_parse_buffer(curp, blk, file);

10
roff.7
View File

@ -1,4 +1,4 @@
.\" $Id: roff.7,v 1.59 2014/11/19 01:20:25 schwarze Exp $
.\" $Id: roff.7,v 1.60 2014/12/02 10:08:06 schwarze Exp $
.\"
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: November 19 2014 $
.Dd $Mdocdate: December 2 2014 $
.Dt ROFF 7
.Os
.Sh NAME
@ -1196,8 +1196,10 @@ Bracket building function; ignored by
.Sx Special Characters
with names of arbitrary length.
.Ss \ec
Interrupt text processing to insert requests or macros; ignored by
.Xr mandoc 1 .
When encountered at the end of an input text line,
the next input text line is considered to continue that line,
even if there are request or macro lines in between.
No whitespace is inserted.
.Ss \eD\(aq Ns Ar string Ns \(aq
Draw graphics function; ignored by
.Xr mandoc 1 .

5
st.in
View File

@ -1,4 +1,4 @@
/* $Id: st.in,v 1.26 2014/11/16 20:46:21 schwarze Exp $ */
/* $Id: st.in,v 1.27 2014/11/30 21:56:18 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -39,7 +39,6 @@ LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(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.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)")
LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)")
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)")
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)")
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
@ -57,7 +56,6 @@ LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)")
LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
LINE("-ansiC-99", "ANSI/ISO/IEC 9899-1999 (\\(lqANSI\\~C99\\(rq)")
LINE("-ieee754", "IEEE Std 754-1985")
LINE("-iso8802-3", "ISO 8802-3: 1989")
LINE("-iso8601", "ISO 8601")
@ -65,7 +63,6 @@ LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)")
LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)")
LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)")
LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)")
LINE("-xpg4.3", "X/Open Portability Guide Issue\\~4, Version\\~3 (\\(lqXPG4.3\\(rq)")
LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)")
LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)")
LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)")

6
term.c
View File

@ -1,4 +1,4 @@
/* $Id: term.c,v 1.236 2014/11/21 01:52:53 schwarze Exp $ */
/* $Id: term.c,v 1.237 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@ -417,7 +417,7 @@ term_word(struct termp *p, const char *word)
else
p->flags |= TERMP_NOSPACE;
p->flags &= ~TERMP_SENTENCE;
p->flags &= ~(TERMP_SENTENCE | TERMP_NONEWLINE);
while ('\0' != *word) {
if ('\\' != *word) {
@ -487,7 +487,7 @@ term_word(struct termp *p, const char *word)
if (TERMP_SKIPCHAR & p->flags)
p->flags &= ~TERMP_SKIPCHAR;
else if ('\0' == *word)
p->flags |= TERMP_NOSPACE;
p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE);
continue;
case ESCAPE_SKIPCHAR:
p->flags |= TERMP_SKIPCHAR;

18
term.h
View File

@ -1,4 +1,4 @@
/* $Id: term.h,v 1.105 2014/10/28 17:36:19 schwarze Exp $ */
/* $Id: term.h,v 1.108 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -15,12 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef TERM_H
#define TERM_H
__BEGIN_DECLS
struct termp;
enum termenc {
TERMENC_ASCII,
@ -44,6 +38,8 @@ enum termfont {
#define TERM_MAXMARGIN 100000 /* FIXME */
struct termp;
typedef void (*term_margin)(struct termp *, const void *);
struct termp_tbl {
@ -83,6 +79,7 @@ struct termp {
#define TERMP_HANG (1 << 11) /* See term_flushln(). */
#define TERMP_NOSPLIT (1 << 12) /* Do not break line before .An. */
#define TERMP_SPLIT (1 << 13) /* Break line before .An. */
#define TERMP_NONEWLINE (1 << 14) /* No line break in nofill mode. */
int *buf; /* Output buffer. */
enum termenc enc; /* Type of encoding. */
const struct mchars *symtab; /* Character table. */
@ -104,6 +101,11 @@ struct termp {
struct termp_ps *ps;
};
__BEGIN_DECLS
struct tbl_span;
struct eqn;
const char *ascii_uc2str(int);
void term_eqn(struct termp *, const struct eqn *);
@ -134,5 +136,3 @@ void term_fontrepl(struct termp *, enum termfont);
void term_fontlast(struct termp *);
__END_DECLS
#endif /*!TERM_H*/

View File

@ -1,4 +1,4 @@
/* $Id: term_ps.c,v 1.69 2014/11/20 13:56:20 schwarze Exp $ */
/* $Id: term_ps.c,v 1.70 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@ -27,11 +27,10 @@
#include <string.h>
#include <unistd.h>
#include "mandoc.h"
#include "mandoc_aux.h"
#include "out.h"
#include "main.h"
#include "term.h"
#include "main.h"
/* These work the buffer used by the header and footer. */
#define PS_BUFSLOP 128