Import mandoc 1.14.2
This commit is contained in:
parent
7ad21139cd
commit
75b6c55cb0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/mdocml/dist/; revision=321807 svn path=/vendor/mdocml/1.14.2/; revision=321808; tag=vendor/mandoc/1.14.2
26
INSTALL
26
INSTALL
@ -1,22 +1,24 @@
|
||||
$Id: INSTALL,v 1.18 2017/02/08 12:24:10 schwarze Exp $
|
||||
$Id: INSTALL,v 1.20 2017/07/28 14:57:56 schwarze Exp $
|
||||
|
||||
About the portable mandoc distribution
|
||||
--------------------------------------
|
||||
The mandoc manpage compiler toolset (formerly called "mdocml")
|
||||
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.
|
||||
|
||||
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.
|
||||
It includes a man(1) manual viewer and additional tools.
|
||||
For general information, see <http://mdocml.bsd.lv/>.
|
||||
For general information, see <http://mandoc.bsd.lv/>.
|
||||
|
||||
In case you have questions or want to provide feedback, read
|
||||
<http://mdocml.bsd.lv/contact.html>. Consider subscribing to the
|
||||
<http://mandoc.bsd.lv/contact.html>. Consider subscribing to the
|
||||
discuss@ mailing list mentioned on that page. If you intend to
|
||||
help with the development of mandoc, consider subscribing to the
|
||||
tech@ mailing list, too.
|
||||
|
||||
Enjoy using the mandoc toolset!
|
||||
|
||||
Ingo Schwarze, Karlsruhe, February 2017
|
||||
Ingo Schwarze, Karlsruhe, July 2017
|
||||
|
||||
|
||||
Installation
|
||||
@ -25,7 +27,7 @@ Before manually installing mandoc on your system, please check
|
||||
whether the newest version of mandoc is already installed by default
|
||||
or available via a binary package or a ports system. A list of the
|
||||
latest bundled and ported versions of mandoc for various operating
|
||||
systems is maintained at <http://mdocml.bsd.lv/ports.html>.
|
||||
systems is maintained at <http://mandoc.bsd.lv/ports.html>.
|
||||
|
||||
Regarding how packages and ports are maintained for your operating
|
||||
system, please consult your operating system documentation.
|
||||
@ -35,7 +37,7 @@ To install mandoc manually, the following steps are needed:
|
||||
run the command "echo BUILD_CGI=1 >> configure.local".
|
||||
Then run "cp cgi.h.example cgi.h" and edit cgi.h as desired.
|
||||
|
||||
2. If you also want to build the new catman(8) utility, run the
|
||||
2. If you also want to build the catman(8) utility, run the
|
||||
command "echo BUILD_CATMAN=1 >> configure.local". Note that it
|
||||
is unlikely to be a drop-in replacement providing the same
|
||||
functionality as your system's "catman", if your operating
|
||||
@ -75,7 +77,7 @@ command like "make DESTDIR=... install". Read the *-install targets
|
||||
in the "Makefile" to understand how DESTDIR is used.
|
||||
|
||||
9. Run the command "sudo makewhatis" to build mandoc.db(5) databases
|
||||
in all the directory trees configured in step 6. Whenever installing
|
||||
in all the directory trees configured in step 3. Whenever installing
|
||||
new manual pages, re-run makewhatis(8) to update the databases, or
|
||||
apropos(1) will not find the new pages.
|
||||
|
||||
|
8
LICENSE
8
LICENSE
@ -1,7 +1,7 @@
|
||||
$Id: LICENSE,v 1.15 2017/02/21 00:37:03 schwarze Exp $
|
||||
$Id: LICENSE,v 1.17 2017/06/23 15:58:14 schwarze Exp $
|
||||
|
||||
With the exceptions noted below, all code and documentation
|
||||
contained in the mdocml toolkit is protected by the Copyright
|
||||
contained in the mandoc toolkit is protected by the Copyright
|
||||
of the following developers:
|
||||
|
||||
Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -13,7 +13,7 @@ Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
|
||||
Copyright (c) 1998, 2004, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
|
||||
Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
|
||||
Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
|
||||
Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
|
||||
@ -22,7 +22,7 @@ See the individual source files for information about who contributed
|
||||
to which file during which years.
|
||||
|
||||
|
||||
The mdocml distribution as a whole is distributed by its developers
|
||||
The mandoc distribution as a whole is distributed by its developers
|
||||
under the following license:
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
|
46
Makefile
46
Makefile
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.512 2017/05/07 17:31:45 schwarze Exp $
|
||||
# $Id: Makefile,v 1.516 2017/07/20 16:24:53 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
# Copyright (c) 2011, 2013-2017 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.
|
||||
|
||||
VERSION = 1.14.1
|
||||
VERSION = 1.14.2
|
||||
|
||||
# === LIST OF FILES ====================================================
|
||||
|
||||
@ -38,6 +38,7 @@ TESTSRCS = test-be32toh.c \
|
||||
test-progname.c \
|
||||
test-recvmsg.c \
|
||||
test-reallocarray.c \
|
||||
test-recallocarray.c \
|
||||
test-rewb-bsd.c \
|
||||
test-rewb-sysv.c \
|
||||
test-sandbox_init.c \
|
||||
@ -64,6 +65,7 @@ SRCS = att.c \
|
||||
compat_ohash.c \
|
||||
compat_progname.c \
|
||||
compat_reallocarray.c \
|
||||
compat_recallocarray.c \
|
||||
compat_strcasestr.c \
|
||||
compat_stringlist.c \
|
||||
compat_strlcat.c \
|
||||
@ -92,6 +94,7 @@ SRCS = att.c \
|
||||
mandoc.c \
|
||||
mandoc_aux.c \
|
||||
mandoc_ohash.c \
|
||||
mandoc_xr.c \
|
||||
mandocd.c \
|
||||
mandocdb.c \
|
||||
manpath.c \
|
||||
@ -178,6 +181,7 @@ DISTFILES = INSTALL \
|
||||
mandoc_html.3 \
|
||||
mandoc_malloc.3 \
|
||||
mandoc_ohash.h \
|
||||
mandoc_xr.h \
|
||||
mandocd.8 \
|
||||
mansearch.3 \
|
||||
mansearch.h \
|
||||
@ -227,6 +231,7 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
||||
mandoc.o \
|
||||
mandoc_aux.o \
|
||||
mandoc_ohash.o \
|
||||
mandoc_xr.o \
|
||||
msec.o \
|
||||
preconv.o \
|
||||
read.o
|
||||
@ -240,6 +245,7 @@ COMPAT_OBJS = compat_err.o \
|
||||
compat_ohash.o \
|
||||
compat_progname.o \
|
||||
compat_reallocarray.o \
|
||||
compat_recallocarray.o \
|
||||
compat_strcasestr.o \
|
||||
compat_strlcat.o \
|
||||
compat_strlcpy.o \
|
||||
@ -341,9 +347,6 @@ WWW_MANS = apropos.1.html \
|
||||
mdoc.h.html \
|
||||
roff.h.html
|
||||
|
||||
WWW_OBJS = mdocml.tar.gz \
|
||||
mdocml.sha256
|
||||
|
||||
# === USER CONFIGURATION ===============================================
|
||||
|
||||
include Makefile.local
|
||||
@ -354,7 +357,7 @@ all: mandoc demandoc soelim $(BUILD_TARGETS) Makefile.local
|
||||
|
||||
install: base-install $(INSTALL_TARGETS)
|
||||
|
||||
www: $(WWW_OBJS) $(WWW_MANS)
|
||||
www: $(WWW_MANS)
|
||||
|
||||
$(WWW_MANS): mandoc
|
||||
|
||||
@ -372,10 +375,10 @@ clean:
|
||||
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS)
|
||||
rm -f mandoc $(MAIN_OBJS)
|
||||
rm -f man.cgi $(CGI_OBJS)
|
||||
rm -f mandocd catman $(MANDOCD_OBJS)
|
||||
rm -f mandocd catman catman.o $(MANDOCD_OBJS)
|
||||
rm -f demandoc $(DEMANDOC_OBJS)
|
||||
rm -f soelim $(SOELIM_OBJS)
|
||||
rm -f $(WWW_MANS) $(WWW_OBJS)
|
||||
rm -f $(WWW_MANS) mandoc.tar.gz mandoc.sha256
|
||||
rm -rf *.dSYM
|
||||
|
||||
base-install: mandoc demandoc soelim
|
||||
@ -509,13 +512,7 @@ soelim: $(SOELIM_OBJS)
|
||||
# --- maintainer targets ---
|
||||
|
||||
www-install: www
|
||||
mkdir -p $(HTDOCDIR)/snapshots
|
||||
$(INSTALL_DATA) $(WWW_MANS) mandoc.css $(HTDOCDIR)
|
||||
$(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)
|
||||
@ -542,24 +539,25 @@ regress-distcheck:
|
||||
! -name '*.out_ascii' \
|
||||
! -name '*.out_utf8' \
|
||||
! -name '*.out_html' \
|
||||
! -name '*.out_markdown' \
|
||||
! -name '*.out_lint' \
|
||||
! -path regress/regress.pl \
|
||||
! -path regress/regress.pl.1
|
||||
|
||||
dist: mdocml.sha256
|
||||
dist: mandoc.sha256
|
||||
|
||||
mdocml.sha256: mdocml.tar.gz
|
||||
sha256 mdocml.tar.gz > $@
|
||||
mandoc.sha256: mandoc.tar.gz
|
||||
sha256 mandoc.tar.gz > $@
|
||||
|
||||
mdocml.tar.gz: $(DISTFILES)
|
||||
mandoc.tar.gz: $(DISTFILES)
|
||||
ls regress/*/*/*.mandoc_* && exit 1 || true
|
||||
mkdir -p .dist/mdocml-$(VERSION)/
|
||||
$(INSTALL) -m 0644 $(DISTFILES) .dist/mdocml-$(VERSION)
|
||||
cp -pR regress .dist/mdocml-$(VERSION)
|
||||
find .dist/mdocml-$(VERSION)/regress \
|
||||
mkdir -p .dist/mandoc-$(VERSION)/
|
||||
$(INSTALL) -m 0644 $(DISTFILES) .dist/mandoc-$(VERSION)
|
||||
cp -pR regress .dist/mandoc-$(VERSION)
|
||||
find .dist/mandoc-$(VERSION)/regress \
|
||||
-type d -name CVS -print0 | xargs -0 rm -rf
|
||||
chmod 755 .dist/mdocml-$(VERSION)/configure
|
||||
( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) )
|
||||
chmod 755 .dist/mandoc-$(VERSION)/configure
|
||||
( cd .dist/ && tar zcf ../$@ mandoc-$(VERSION) )
|
||||
rm -rf .dist/
|
||||
|
||||
# === SUFFIX RULES =====================================================
|
||||
|
@ -1,4 +1,4 @@
|
||||
att.o: att.c config.h roff.h mdoc.h libmdoc.h
|
||||
att.o: att.c config.h mandoc.h roff.h mdoc.h libmdoc.h
|
||||
catman.o: catman.c config.h compat_fts.h
|
||||
cgi.o: cgi.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h main.h manconf.h mansearch.h cgi.h
|
||||
chars.o: chars.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h libmandoc.h
|
||||
@ -11,6 +11,7 @@ compat_mkdtemp.o: compat_mkdtemp.c config.h
|
||||
compat_ohash.o: compat_ohash.c config.h compat_ohash.h
|
||||
compat_progname.o: compat_progname.c config.h
|
||||
compat_reallocarray.o: compat_reallocarray.c config.h
|
||||
compat_recallocarray.o: compat_recallocarray.c config.h
|
||||
compat_strcasestr.o: compat_strcasestr.c config.h
|
||||
compat_stringlist.o: compat_stringlist.c config.h compat_stringlist.h
|
||||
compat_strlcat.o: compat_strlcat.c config.h
|
||||
@ -24,44 +25,45 @@ dba_read.o: dba_read.c mandoc_aux.h mansearch.h dba_array.h dba.h dbm.h
|
||||
dba_write.o: dba_write.c config.h dba_write.h
|
||||
dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h
|
||||
dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h
|
||||
demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.h
|
||||
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h
|
||||
eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.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_aux.h mandoc.h roff.h out.h html.h manconf.h main.h
|
||||
lib.o: lib.c config.h roff.h mdoc.h libmdoc.h lib.in
|
||||
main.o: main.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
|
||||
lib.o: lib.c config.h mandoc.h roff.h mdoc.h libmdoc.h lib.in
|
||||
main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
|
||||
man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
man_html.o: man_html.c config.h mandoc_aux.h roff.h man.h out.h html.h main.h
|
||||
man_html.o: man_html.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h html.h main.h
|
||||
man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h main.h
|
||||
man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h
|
||||
mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h
|
||||
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||
mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h
|
||||
mandoc_xr.o: mandoc_xr.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.h
|
||||
mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h main.h manconf.h
|
||||
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h dba_array.h dba.h
|
||||
manpath.o: manpath.c config.h mandoc_aux.h manconf.h
|
||||
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h roff.h mdoc.h out.h html.h main.h
|
||||
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h html.h main.h
|
||||
mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h
|
||||
mdoc_markdown.o: mdoc_markdown.c mandoc_aux.h mandoc.h roff.h mdoc.h main.h
|
||||
mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
|
||||
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h term.h tag.h main.h
|
||||
mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
||||
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
|
||||
preconv.o: preconv.c config.h mandoc.h libmandoc.h
|
||||
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h roff_int.h
|
||||
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h
|
||||
roff.o: roff.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h libmandoc.h roff_int.h libroff.h predefs.in
|
||||
roff_html.o: roff_html.c roff.h out.h html.h
|
||||
roff_term.o: roff_term.c roff.h out.h term.h
|
||||
roff_html.o: roff_html.c mandoc.h roff.h out.h html.h
|
||||
roff_term.o: roff_term.c mandoc.h roff.h out.h term.h
|
||||
roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h
|
||||
soelim.o: soelim.c config.h compat_stringlist.h
|
||||
st.o: st.c config.h roff.h mdoc.h libmdoc.h st.in
|
||||
st.o: st.c config.h mandoc.h roff.h mdoc.h libmdoc.h st.in
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h
|
||||
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
tbl_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
|
98
NEWS
98
NEWS
@ -1,6 +1,92 @@
|
||||
$Id: NEWS,v 1.21 2017/02/21 00:37:03 schwarze Exp $
|
||||
$Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mdocml.bsd.lv distribution.
|
||||
This file lists the most important changes in the mandoc.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.14.2, released on July 28, 2017
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
* New mdoc(7) -Tmarkdown output mode.
|
||||
* For -Thtml, implement internal hyperlinks pointing to authoritative
|
||||
definitions of various syntax elements, similar to the ctags(1)-like
|
||||
less(1) :t internal searching in terminal mode.
|
||||
* Provide a superset of the functionality of the former mdoclint(1)
|
||||
utility and a new -Wstyle message level with several new messages,
|
||||
including validity checking of .Xr cross references.
|
||||
* tbl(7): Implement automatic line breaking inside individual table
|
||||
cells, and several other formatting improvements.
|
||||
* eqn(7): Complete rewrite of the lexer, resulting in several bugfixes.
|
||||
* Continue parser unification, in particular allowing generation
|
||||
of syntax tree nodes on the roff(7) level, allowing implementation
|
||||
of many additional roff requests.
|
||||
--- REMOVED FUNCTIONALITY ---
|
||||
* Delete the manpage(1) utility. It was never enabled in any release.
|
||||
* Delete the -Txhtml command line option. It has been an obsolete
|
||||
alias for the -Thtml output mode for more than two years.
|
||||
--- MINOR NEW FEATURES ---
|
||||
* -Tlint now puts parser messages on stdout instead of stderr,
|
||||
making commands like "man -l -Tlint *.1" useful.
|
||||
* mdoc(7): Various .Lk formatting improvements.
|
||||
* mdoc(7) -Thtml: Better CSS for .Bl lists.
|
||||
* man(7): Implement the .MT/.ME block macro (mailto hyperlink).
|
||||
* man(7): Implement the .DT macro (restore default tab positions).
|
||||
* man(7): Improved support for manuals generated with reStructuredText
|
||||
by partial support for the \n[an-margin] number register.
|
||||
* man(7) -Thtml: Support deep linking to .SH and .SS headers.
|
||||
* tbl(7): Implement the "allbox" table option.
|
||||
* tbl(7): Implement the column spacing and the 'w' (minimum column
|
||||
width) layout modifiers.
|
||||
* tbl(7): Significant improvements of the manual page.
|
||||
* eqn(7): Much improved font selection, including recognition of
|
||||
well-known function names, and a few other formatting improvements.
|
||||
* eqn(7) -Thtml: Use <mn> and <mo> in addition to <mi>.
|
||||
* roff(7): Implement the .ce (centering), .mc (margin character),
|
||||
.rj (right justify), .ta (define tab stops), .ti (temporary indent),
|
||||
.als (macro alias), .ec and .eo (escape character control),
|
||||
.po (page offset), and .rn (macro rename) requests.
|
||||
* roff(7) .am: Implement appending to mdoc(7) and man(7) macros.
|
||||
* roff(7): implement the \h (horizontol motion), \l (horizontal
|
||||
line drawing), and \p (break output line) escape sequences,
|
||||
and also several additional character escape sequences.
|
||||
* roff(7): Implement the 'd' conditional (macro or string defined).
|
||||
* man.cgi(8) now uses pledge(2), too.
|
||||
* regress.pl(1): simpler user interface, better summary output,
|
||||
simpler code, and no more recursion.
|
||||
--- THANKS TO ---
|
||||
* Anthony Bentley (OpenBSD) for the implementation of .MT/.ME,
|
||||
reports of many bugs and missing features, and suggestions
|
||||
for a number of feature and documentation improvements.
|
||||
* Sebastien Marie (OpenBSD) for two source code patches and
|
||||
for some useful discussions.
|
||||
* Florian Obser (OpenBSD) for a bugfix patch and a bug report.
|
||||
* Jonathan Gray (OpenBSD) for several bug reports from afl(1)
|
||||
and several more from static analysis tools.
|
||||
* Theo Buehler (OpenBSD) for several bug reports, most from afl(1).
|
||||
* Jason McIntyre (OpenBSD) for many useful discussions about a
|
||||
wide variety of topics, lots of continuous testing, a number of
|
||||
bug reports, and some suggestions for messages and documentation.
|
||||
* Thomas Klausner (NetBSD) for lots of help while migrating
|
||||
mdoclint(1) functionality to mandoc -Tlint, for suggesting
|
||||
several useful new messages, and for release testing.
|
||||
* Reyk Floeter (OpenBSD) and Vsevolod Stakhov (FreeBSD) for
|
||||
suggesting a markdown output mode.
|
||||
* Thomas Guettler for suggesting -Thtml internal hyperlinks.
|
||||
* Yuri Pankov (Illumos) for inspiring new warning messages and
|
||||
for extensive release testing.
|
||||
* Anton Lindqvist and TJ Townsend (both OpenBSD) and Jan Stary
|
||||
for multiple bug reports.
|
||||
* Leah Neukirchen (Void Linux) for bug reports and release testing.
|
||||
* Michael Stapelberg (Debian) for suggesting feature improvements
|
||||
and for release testing.
|
||||
* Martin Natano and Theo de Raadt (both OpenBSD), Andreas Voegele,
|
||||
Gabriel Guzman, Gonzalo Tornaria, Markus Waldeck, and Raf Czlonka
|
||||
for bug reports.
|
||||
* Antoine Jacoutot (OpenBSD) and Steffen Nurpmeso for suggesting
|
||||
feature improvements.
|
||||
* Dag-Erling Smoergrav (FreeBSD) for inspiring new warning messages.
|
||||
* Ted Unangst and Marc Espie (OpenBSD) for providing useful ideas.
|
||||
* Svyatoslav Mishyn (Crux Linux) for release testing.
|
||||
* Carsten Kunze (Heirloom roff) for help keeping mandoc and groff
|
||||
compatible and for committing some of my patches to groff.
|
||||
|
||||
Changes in version 1.14.1, released on February 21, 2017
|
||||
|
||||
@ -274,11 +360,11 @@ Changes in version 1.13.3, released on March 13, 2015
|
||||
* New -Wunsupp message level.
|
||||
--- POTENTIONALLY SECURITY RELEVANT BUGFIXES ---
|
||||
* Fix a potential write buffer overrun on incomplete string conditionals.
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/roff.c#rev1.241
|
||||
http://mandoc.bsd.lv/cgi-bin/cvsweb/roff.c#rev1.241
|
||||
* Fix a potential write buffer overrun on backslash at EOF in a conditional.
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/roff.c#rev1.247
|
||||
http://mandoc.bsd.lv/cgi-bin/cvsweb/roff.c#rev1.247
|
||||
* Fix a use after free sometimes hit when validation deletes a block.
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_macro.c#rev1.180
|
||||
http://mandoc.bsd.lv/cgi-bin/cvsweb/mdoc_macro.c#rev1.180
|
||||
--- MAJOR FUNCTIONALLY RELEVANT BUGFIXES ---
|
||||
* Let man(1) show manuals for the current architecture by default,
|
||||
and support the MACHINE environment variable.
|
||||
@ -889,4 +975,4 @@ Changes in version 1.9.15, released on February 18, 2010
|
||||
* and column lengths handled correctly.
|
||||
|
||||
For older releases, see the ChangeLog files
|
||||
in http://mdocml.bsd.lv/snapshots/ .
|
||||
in http://mandoc.bsd.lv/snapshots/ .
|
||||
|
110
TODO
110
TODO
@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.237 2017/05/16 19:06:30 schwarze Exp $
|
||||
* $Id: TODO,v 1.246 2017/07/24 11:15:12 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@ -65,21 +65,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 **
|
||||
|
||||
- \h horizontal move
|
||||
#2 most important issue naddy@ Mon, 16 Feb 2015 20:59:17 +0100
|
||||
found in cclive(1) nasm(1) bogofilter(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
|
||||
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
||||
loc * exist * algo * size * imp **
|
||||
|
||||
- \n(.$ macro argument count number register; ocserv(8) by autogen
|
||||
found by sthen@ Thu, 19 Feb 2015 22:03:01 +0000
|
||||
loc * exist ** algo * size * imp **
|
||||
|
||||
- \w'' improve width measurements
|
||||
would not be very useful without an expression parser, see below
|
||||
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
||||
@ -183,22 +172,6 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- missing tbl features -----------------------------------------------
|
||||
|
||||
- horizontal lines in the layout still consume data cells
|
||||
and can be mixed with actual data on the same table line
|
||||
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
|
||||
loc ** exist ** algo ** size ** imp ***
|
||||
|
||||
- break long text into lines inside cells
|
||||
net/lftp(1) from jirib via bentley@ Sep 13, 2016
|
||||
|
||||
- layout l1 for a column of max text width 3 reduces the following
|
||||
inter-column spacing for groff, but not for mandoc
|
||||
net/lftp(1) from jirib via bentley@ Sep 13, 2016
|
||||
|
||||
- the "w" layout option is ignored
|
||||
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
|
||||
loc * exist * algo * size * imp **
|
||||
|
||||
- the "s" layout column specifier is used for placement of data
|
||||
into columns, but ignored during column width calculations
|
||||
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
|
||||
@ -240,6 +213,16 @@ are mere guesses, and some may be wrong.
|
||||
see User's Guide (Second Edition) page 5 section 15.
|
||||
loc ** exist ** algo ** size ** imp **
|
||||
|
||||
- GNU eqn converts some operators to special characters, for example,
|
||||
input HYPHEN-MINUS becomes output \(mi, unless it is part of a
|
||||
quoted word. mandoc(1) only does this when the operator is
|
||||
surrounded by blanks, not when it is part of an unquoted word.
|
||||
Also, check whether there are more such cases (e.g., +?).
|
||||
reported by bentley@ 20 Jun 2017 02:04:29 -0600
|
||||
|
||||
- Primes, opprime, and '
|
||||
bentley@ Thu, 13 Jul 2017 23:14:20 -0600
|
||||
|
||||
--- missing misc features ----------------------------------------------
|
||||
|
||||
- italic correction (\/) in PostScript mode
|
||||
@ -359,6 +342,12 @@ are mere guesses, and some may be wrong.
|
||||
.Vt vs .Vt/.Va vs .Ft/.Va vs .Ft/.Fa ...
|
||||
from kristaps@ Tue, 08 Jun 2010 11:13:32 +0200
|
||||
|
||||
- implicit whitespace around inline equations
|
||||
example code: where '$times$' denotes matrix multiplication
|
||||
must not have an HTML line break, nor a blank, before <math>
|
||||
partial solution: html.c {"math", HTML_NLINSIDE | HTML_INDENT},
|
||||
bentley@ Thu, 13 Jul 2017 19:00:59 -0600
|
||||
|
||||
- in enclosures, mandoc sometimes fancies a bogus end of sentence
|
||||
reminded by jmc@ Thu, 23 Sep 2010 18:13:39 +0059
|
||||
loc * exist ** algo *** size * imp ***
|
||||
@ -421,9 +410,6 @@ are mere guesses, and some may be wrong.
|
||||
Steffen Nurpmeso Sat, 08 Nov 2014 13:34:59 +0100
|
||||
loc * exist ** algo ** size * imp **
|
||||
|
||||
- .Lk formatting for long links with line breaks
|
||||
Franco Fichtner 8 Oct 2013 00:33:42 +0200
|
||||
|
||||
- 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
|
||||
@ -450,16 +436,6 @@ are mere guesses, and some may be wrong.
|
||||
Probably, this should be fixed somewhere in termp_it_pre(), not sure.
|
||||
loc * exist ** algo ** size * imp **
|
||||
|
||||
- .Nx 1.0a
|
||||
should be "NetBSD 1.0A", not "NetBSD 1.0a",
|
||||
see OpenBSD ccdconfig(8).
|
||||
loc * exist * algo * size * imp **
|
||||
|
||||
- In .Bl -tag, if a tag exceeds the right margin and must be continued
|
||||
on the next line, it must be indented by -width, not width+1;
|
||||
see "rule block|pass" in OpenBSD ifconfig(8).
|
||||
loc * exist *** algo ** size * imp **
|
||||
|
||||
- When the -width string contains macros, the macros must be rendered
|
||||
before measuring the width, for example
|
||||
.Bl -tag -width ".Dv message"
|
||||
@ -495,15 +471,24 @@ are mere guesses, and some may be wrong.
|
||||
* warning issues
|
||||
************************************************************************
|
||||
|
||||
- provide a way in mandoc(1) to warn about broken .Xr links;
|
||||
probably cannot be on by default in -Tlint because it needs
|
||||
to access the manpath and mandoc.db(3) after parsing.
|
||||
asked for by jmc@ Fri, 4 Dec 2015 22:39:40 +0000
|
||||
- style message about macros inside .Bd -literal and .Dl, in particular
|
||||
font changing macros like .Cm, .Ar, .Fa (from the mdoclint TODO)
|
||||
|
||||
- style message about mismatches between the section number in the
|
||||
file name (if it is known) and the section number in .Dt
|
||||
(from the mdoclint TODO)
|
||||
|
||||
- style message about NULL without .Dv (from the mdoclint TODO)
|
||||
|
||||
- style message about error constants without .Er (from the mdoclint TODO)
|
||||
|
||||
- warn when .Sh or .Ss contain other macros
|
||||
Steffen Nurpmeso, savannah.gnu.org/bugs/index.php?45034
|
||||
loc * exist * algo * size * imp **
|
||||
|
||||
- style message about violations of the convention
|
||||
.An name Aq Mt localpart@domain in AUTHORS (from the mdoclint TODO)
|
||||
|
||||
- warn about attempts to call non-callable macros
|
||||
Steffen Nurpmeso Tue, 11 Nov 2014 22:55:16 +0100
|
||||
Note that formatting is inconsistent in groff.
|
||||
@ -512,25 +497,25 @@ are mere guesses, and some may be wrong.
|
||||
all over mdoc_macro.c and all subtly different.
|
||||
loc ** exist ** algo ** size ** imp **
|
||||
|
||||
- style message about suspicious uses of - vs. \- vs. \(mi
|
||||
e.g. -1 is likely wrong (from the mdoclint TODO)
|
||||
|
||||
- warn about punctuation - e.g. ',' and ';' - at the beginning
|
||||
of a text line, if it is likely intended to follow the preceding
|
||||
output without intervening whitespace, in particular after a
|
||||
macro line (from the mdoclint TODO)
|
||||
|
||||
- mandoc_special does not really check the escape sequence,
|
||||
but just the overall format
|
||||
loc ** exist ** algo *** size ** imp **
|
||||
|
||||
- integrate mdoclint into mandoc ("end-of-line whitespace" thread)
|
||||
from jmc@ Mon, 13 Jul 2009 17:12:09 +0100
|
||||
from kristaps@ Mon, 13 Jul 2009 18:34:53 +0200
|
||||
from jmc@ Mon, 13 Jul 2009 17:45:37 +0059
|
||||
from kristaps@ Mon, 13 Jul 2009 19:02:03 +0200
|
||||
(mostly done, check what remains)
|
||||
|
||||
- -Tlint parser errors and warnings to stdout
|
||||
to tech@mdocml, naddy@ Wed, 28 Sep 2011 11:21:46 +0200
|
||||
wait! kristaps@ Sun, 02 Oct 2011 17:12:52 +0200
|
||||
|
||||
************************************************************************
|
||||
* documentation issues
|
||||
************************************************************************
|
||||
|
||||
- dashes, hyphens, and minus signs in manual pages
|
||||
jmc@ Fri, 28 Mar 2014 07:19:27 +0000
|
||||
|
||||
- mark macros as: page structure domain, manual domain, general text domain
|
||||
is this useful?
|
||||
|
||||
@ -543,11 +528,6 @@ are mere guesses, and some may be wrong.
|
||||
* performance issues
|
||||
************************************************************************
|
||||
|
||||
- Why are we using MAP_SHARED, not MAP_PRIVATE for mmap(2)?
|
||||
from kristaps@ Sat, 09 Aug 2014 13:51:36 +0200
|
||||
|
||||
Several areas can be cleaned up to make mandoc even faster. These are
|
||||
|
||||
- the PDF file is HUGE: this can be reduced by using relative offsets
|
||||
|
||||
************************************************************************
|
||||
@ -565,13 +545,13 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
||||
same-line from different-line input. That plainly doesn't work
|
||||
with user-defined macros, leading to random breakage.
|
||||
|
||||
- Is it possible to further simplify ENDBODY_SPACE?
|
||||
|
||||
- Find better ways to prevent endless loops
|
||||
in roff(7) macro and string expansion.
|
||||
|
||||
- Finish cleanup of date handling.
|
||||
Decide which formats should be recognized where.
|
||||
Update both mdoc(7) and man(7) documentation.
|
||||
Triggered by Tim van der Molen Tue, 22 Feb 2011 20:30:45 +0100
|
||||
- make buffers for parsing functions const
|
||||
christos@ via wiz@ Fri, 18 Dec 2015 17:10:01 +0100
|
||||
|
||||
- struct mparse refactoring
|
||||
Steffen Nurpmeso Thu, 04 Sep 2014 12:50:00 +0200
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: apropos.1,v 1.45 2017/03/27 18:51:36 schwarze Exp $
|
||||
.\" $Id: apropos.1,v 1.46 2017/07/04 23:40:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: March 27 2017 $
|
||||
.Dd $Mdocdate: July 4 2017 $
|
||||
.Dt APROPOS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -407,7 +407,7 @@ variables:
|
||||
.Dl $ apropos \-s 3 Va=optind \-a Va=optarg
|
||||
.Pp
|
||||
Do exactly the same as calling
|
||||
.Xr whatis 1
|
||||
.Nm whatis
|
||||
with the argument
|
||||
.Qq ssh :
|
||||
.Pp
|
||||
|
3
att.c
3
att.c
@ -1,4 +1,4 @@
|
||||
/* $Id: att.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: att.c,v 1.16 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
12
cgi.c
12
cgi.c
@ -1,4 +1,4 @@
|
||||
/* $Id: cgi.c,v 1.154 2017/04/19 01:00:03 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.156 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@usta.de>
|
||||
@ -140,16 +140,16 @@ html_putchar(char c)
|
||||
{
|
||||
|
||||
switch (c) {
|
||||
case ('"'):
|
||||
case '"':
|
||||
printf(""");
|
||||
break;
|
||||
case ('&'):
|
||||
case '&':
|
||||
printf("&");
|
||||
break;
|
||||
case ('>'):
|
||||
case '>':
|
||||
printf(">");
|
||||
break;
|
||||
case ('<'):
|
||||
case '<':
|
||||
printf("<");
|
||||
break;
|
||||
default:
|
||||
@ -832,7 +832,7 @@ resp_format(const struct req *req, const char *file)
|
||||
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1,
|
||||
MANDOCLEVEL_BADARG, NULL, req->q.manpath);
|
||||
MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, req->q.manpath);
|
||||
mparse_readfd(mp, fd, file);
|
||||
close(fd);
|
||||
|
||||
|
3
chars.c
3
chars.c
@ -1,4 +1,4 @@
|
||||
/* $Id: chars.c,v 1.70 2017/06/02 12:43:52 schwarze Exp $ */
|
||||
/* $Id: chars.c,v 1.71 2017/06/14 20:57:07 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -61,6 +61,7 @@ static struct ln lines[] = {
|
||||
{ "ba", "|", 0x007c },
|
||||
{ "br", "|", 0x2502 },
|
||||
{ "ul", "_", 0x005f },
|
||||
{ "ru", "_", 0x005f },
|
||||
{ "rn", "-", 0x203e },
|
||||
{ "bb", "|", 0x00a6 },
|
||||
{ "sl", "/", 0x002f },
|
||||
|
108
compat_recallocarray.c
Normal file
108
compat_recallocarray.c
Normal file
@ -0,0 +1,108 @@
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_RECALLOCARRAY
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_recallocarray.c,v 1.1 2017/06/12 19:05:47 schwarze Exp $ */
|
||||
/* $OpenBSD: malloc.c,v 1.225 2017/05/13 07:11:29 otto Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* 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))
|
||||
|
||||
/*
|
||||
* Even though specified in POSIX, the PAGESIZE and PAGE_SIZE
|
||||
* macros have very poor portability. Since we only use this
|
||||
* to avoid free() overhead for small shrinking, simply pick
|
||||
* an arbitrary number.
|
||||
*/
|
||||
#define MALLOC_PAGESIZE (1UL << 12)
|
||||
|
||||
|
||||
void *
|
||||
recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
|
||||
{
|
||||
size_t oldsize, newsize;
|
||||
void *newptr;
|
||||
|
||||
if (ptr == NULL)
|
||||
return calloc(newnmemb, size);
|
||||
|
||||
if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
newnmemb > 0 && SIZE_MAX / newnmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
newsize = newnmemb * size;
|
||||
|
||||
if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
oldsize = oldnmemb * size;
|
||||
|
||||
/*
|
||||
* Don't bother too much if we're shrinking just a bit,
|
||||
* we do not shrink for series of small steps, oh well.
|
||||
*/
|
||||
if (newsize <= oldsize) {
|
||||
size_t d = oldsize - newsize;
|
||||
|
||||
if (d < oldsize / 2 && d < MALLOC_PAGESIZE) {
|
||||
memset((char *)ptr + newsize, 0, d);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
newptr = malloc(newsize);
|
||||
if (newptr == NULL)
|
||||
return NULL;
|
||||
|
||||
if (newsize > oldsize) {
|
||||
memcpy(newptr, ptr, oldsize);
|
||||
memset((char *)newptr + oldsize, 0, newsize - oldsize);
|
||||
} else
|
||||
memcpy(newptr, ptr, newsize);
|
||||
|
||||
/*
|
||||
* At this point, the OpenBSD implementation calls
|
||||
* explicit_bzero() on the old memory before it is
|
||||
* freed. Since explicit_bzero() is hard to implement
|
||||
* portably and we don't handle confidential data in
|
||||
* mandoc in the first place, simply free the memory
|
||||
* without clearing it.
|
||||
*/
|
||||
|
||||
free(ptr);
|
||||
|
||||
return newptr;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_RECALLOCARRAY */
|
13
configure
vendored
13
configure
vendored
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.62 2017/03/04 16:36:29 schwarze Exp $
|
||||
# $Id: configure,v 1.64 2017/07/01 09:47:30 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
@ -35,6 +35,7 @@ echo "config.log: writing..."
|
||||
|
||||
SOURCEDIR=`dirname "$0"`
|
||||
|
||||
MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
|
||||
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
OSNAME=
|
||||
UTF8_LOCALE=
|
||||
@ -73,6 +74,7 @@ HAVE_PATH_MAX=
|
||||
HAVE_PLEDGE=
|
||||
HAVE_PROGNAME=
|
||||
HAVE_REALLOCARRAY=
|
||||
HAVE_RECALLOCARRAY=
|
||||
HAVE_RECVMSG=
|
||||
HAVE_REWB_BSD=
|
||||
HAVE_REWB_SYSV=
|
||||
@ -229,6 +231,7 @@ runtest pledge PLEDGE || true
|
||||
runtest sandbox_init SANDBOX_INIT || true
|
||||
runtest progname PROGNAME || true
|
||||
runtest reallocarray REALLOCARRAY || true
|
||||
runtest recallocarray RECALLOCARRAY || true
|
||||
runtest rewb-bsd REWB_BSD || true
|
||||
runtest rewb-sysv REWB_SYSV || true
|
||||
runtest strcasestr STRCASESTR || true
|
||||
@ -348,7 +351,8 @@ cat << __HEREDOC__
|
||||
|
||||
__HEREDOC__
|
||||
|
||||
[ ${HAVE_GETLINE} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \
|
||||
[ ${HAVE_GETLINE} -eq 0 -o \
|
||||
${HAVE_REALLOCARRAY} -eq 0 -o ${HAVE_RECALLOCARRAY} -eq 0 -o \
|
||||
${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \
|
||||
&& echo "#include <sys/types.h>"
|
||||
[ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>"
|
||||
@ -356,6 +360,7 @@ __HEREDOC__
|
||||
|
||||
echo
|
||||
echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\""
|
||||
echo "#define MANPATH_BASE \"${MANPATH_BASE}\""
|
||||
echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
|
||||
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
|
||||
[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\""
|
||||
@ -383,6 +388,7 @@ cat << __HEREDOC__
|
||||
#define HAVE_PLEDGE ${HAVE_PLEDGE}
|
||||
#define HAVE_PROGNAME ${HAVE_PROGNAME}
|
||||
#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY}
|
||||
#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY}
|
||||
#define HAVE_REWB_BSD ${HAVE_REWB_BSD}
|
||||
#define HAVE_REWB_SYSV ${HAVE_REWB_SYSV}
|
||||
#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT}
|
||||
@ -434,6 +440,9 @@ fi
|
||||
[ ${HAVE_REALLOCARRAY} -eq 0 ] && \
|
||||
echo "extern void *reallocarray(void *, size_t, size_t);"
|
||||
|
||||
[ ${HAVE_RECALLOCARRAY} -eq 0 ] && \
|
||||
echo "extern void *recallocarray(void *, size_t, size_t, size_t);"
|
||||
|
||||
[ ${HAVE_STRCASESTR} -eq 0 ] && \
|
||||
echo "extern char *strcasestr(const char *, const char *);"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: configure.local.example,v 1.30 2017/03/04 16:36:29 schwarze Exp $
|
||||
# $Id: configure.local.example,v 1.33 2017/07/20 16:24:53 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
@ -20,7 +20,7 @@
|
||||
# and put any of these settings into it if ./configure autodetection
|
||||
# fails or if you want to make different choices for other reasons.
|
||||
|
||||
# If autodetection fails, please tell <tech@mdocml.bsd.lv>.
|
||||
# If autodetection fails, please tell <tech@mandoc.bsd.lv>.
|
||||
|
||||
# We recommend that you write ./configure.local from scratch and
|
||||
# only put the lines there you need. This file contains examples.
|
||||
@ -62,6 +62,11 @@ UTF8_LOCALE=en_US.UTF-8
|
||||
|
||||
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
|
||||
# Validation of cross references with mandoc -Tlint only looks
|
||||
# for manual pages in the following directories:
|
||||
|
||||
MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
|
||||
|
||||
# In manual pages written in the mdoc(7) language, the operating system
|
||||
# version is displayed in the page footer line. If an operating system
|
||||
# is specified as an argument to the .Os macro, that is always used.
|
||||
@ -292,6 +297,7 @@ HAVE_PATH_MAX=0
|
||||
HAVE_PLEDGE=0
|
||||
HAVE_PROGNAME=0
|
||||
HAVE_REALLOCARRAY=0
|
||||
HAVE_RECALLOCARRAY=0
|
||||
HAVE_REWB_BSD=0
|
||||
HAVE_REWB_SYSV=0
|
||||
HAVE_STRCASESTR=0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: demandoc.c,v 1.28 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/* $Id: demandoc.c,v 1.29 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -25,10 +25,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
|
||||
static void pline(int, int *, int *, int);
|
||||
static void pman(const struct roff_node *, int *, int *, int);
|
||||
@ -78,7 +78,8 @@ main(int argc, char *argv[])
|
||||
argv += optind;
|
||||
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, NULL);
|
||||
mp = mparse_alloc(MPARSE_SO, MANDOCERR_MAX, NULL,
|
||||
MANDOC_OS_OTHER, NULL);
|
||||
assert(mp);
|
||||
|
||||
if (argc < 1)
|
||||
|
6
eqn.7
6
eqn.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: eqn.7,v 1.35 2015/03/30 16:06:14 schwarze Exp $
|
||||
.\" $Id: eqn.7,v 1.36 2017/07/20 11:07:27 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: March 30 2015 $
|
||||
.Dd $Mdocdate: July 20 2017 $
|
||||
.Dt EQN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -125,7 +125,7 @@ int (integral), sum (summation), grad (gradient), del (vector
|
||||
differential), times (multiply), cdot (center-dot), nothing (zero-width
|
||||
space), approx (approximately equals), prime (prime), half (one-half),
|
||||
partial (partial differential), inf (infinity), >> (much greater), <<
|
||||
(much less), \-> (left arrow), <\- (right arrow), +\- (plus-minus), !=
|
||||
(much less), <\- (left arrow), \-> (right arrow), +\- (plus-minus), !=
|
||||
(not equal), == (equivalence), <= (less-than-equal), and >=
|
||||
(more-than-equal).
|
||||
The character escape sequences documented in
|
||||
|
92
eqn_html.c
92
eqn_html.c
@ -1,4 +1,4 @@
|
||||
/* $Id: eqn_html.c,v 1.11 2017/01/17 01:47:51 schwarze Exp $ */
|
||||
/* $Id: eqn_html.c,v 1.17 2017/07/14 13:32:35 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -20,6 +20,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -33,7 +34,10 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
{
|
||||
struct tag *post, *row, *cell, *t;
|
||||
const struct eqn_box *child, *parent;
|
||||
const char *cp;
|
||||
size_t i, j, rows;
|
||||
enum htmltag tag;
|
||||
enum eqn_fontt font;
|
||||
|
||||
if (NULL == bp)
|
||||
return;
|
||||
@ -47,7 +51,8 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
if (EQN_MATRIX == bp->type) {
|
||||
if (NULL == bp->first)
|
||||
goto out;
|
||||
if (EQN_LIST != bp->first->type) {
|
||||
if (bp->first->type != EQN_LIST ||
|
||||
bp->first->expectargs == 1) {
|
||||
eqn_box(p, bp->first);
|
||||
goto out;
|
||||
}
|
||||
@ -87,28 +92,28 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
}
|
||||
|
||||
switch (bp->pos) {
|
||||
case (EQNPOS_TO):
|
||||
case EQNPOS_TO:
|
||||
post = print_otag(p, TAG_MOVER, "");
|
||||
break;
|
||||
case (EQNPOS_SUP):
|
||||
case EQNPOS_SUP:
|
||||
post = print_otag(p, TAG_MSUP, "");
|
||||
break;
|
||||
case (EQNPOS_FROM):
|
||||
case EQNPOS_FROM:
|
||||
post = print_otag(p, TAG_MUNDER, "");
|
||||
break;
|
||||
case (EQNPOS_SUB):
|
||||
case EQNPOS_SUB:
|
||||
post = print_otag(p, TAG_MSUB, "");
|
||||
break;
|
||||
case (EQNPOS_OVER):
|
||||
case EQNPOS_OVER:
|
||||
post = print_otag(p, TAG_MFRAC, "");
|
||||
break;
|
||||
case (EQNPOS_FROMTO):
|
||||
case EQNPOS_FROMTO:
|
||||
post = print_otag(p, TAG_MUNDEROVER, "");
|
||||
break;
|
||||
case (EQNPOS_SUBSUP):
|
||||
case EQNPOS_SUBSUP:
|
||||
post = print_otag(p, TAG_MSUBSUP, "");
|
||||
break;
|
||||
case (EQNPOS_SQRT):
|
||||
case EQNPOS_SQRT:
|
||||
post = print_otag(p, TAG_MSQRT, "");
|
||||
break;
|
||||
default:
|
||||
@ -127,18 +132,68 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
|
||||
if (EQN_PILE == bp->type) {
|
||||
assert(NULL == post);
|
||||
if (bp->first != NULL && bp->first->type == EQN_LIST)
|
||||
if (bp->first != NULL &&
|
||||
bp->first->type == EQN_LIST &&
|
||||
bp->first->expectargs > 1)
|
||||
post = print_otag(p, TAG_MTABLE, "");
|
||||
} else if (bp->type == EQN_LIST &&
|
||||
} else if (bp->type == EQN_LIST && bp->expectargs > 1 &&
|
||||
bp->parent && bp->parent->type == EQN_PILE) {
|
||||
assert(NULL == post);
|
||||
post = print_otag(p, TAG_MTR, "");
|
||||
print_otag(p, TAG_MTD, "");
|
||||
}
|
||||
|
||||
if (NULL != bp->text) {
|
||||
assert(NULL == post);
|
||||
post = print_otag(p, TAG_MI, "");
|
||||
if (bp->text != NULL) {
|
||||
assert(post == NULL);
|
||||
tag = TAG_MI;
|
||||
cp = bp->text;
|
||||
if (isdigit((unsigned char)cp[0]) ||
|
||||
(cp[0] == '.' && isdigit((unsigned char)cp[1]))) {
|
||||
tag = TAG_MN;
|
||||
while (*++cp != '\0') {
|
||||
if (*cp != '.' &&
|
||||
isdigit((unsigned char)*cp) == 0) {
|
||||
tag = TAG_MI;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (*cp != '\0' && isalpha((unsigned char)*cp) == 0) {
|
||||
tag = TAG_MO;
|
||||
while (*cp != '\0') {
|
||||
if (cp[0] == '\\' && cp[1] != '\0') {
|
||||
cp++;
|
||||
mandoc_escape(&cp, NULL, NULL);
|
||||
} else if (isalnum((unsigned char)*cp)) {
|
||||
tag = TAG_MI;
|
||||
break;
|
||||
} else
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
font = bp->font;
|
||||
if (bp->text[0] != '\0' &&
|
||||
(((tag == TAG_MN || tag == TAG_MO) &&
|
||||
font == EQNFONT_ROMAN) ||
|
||||
(tag == TAG_MI && font == (bp->text[1] == '\0' ?
|
||||
EQNFONT_ITALIC : EQNFONT_ROMAN))))
|
||||
font = EQNFONT_NONE;
|
||||
switch (font) {
|
||||
case EQNFONT_NONE:
|
||||
post = print_otag(p, tag, "");
|
||||
break;
|
||||
case EQNFONT_ROMAN:
|
||||
post = print_otag(p, tag, "?", "fontstyle", "normal");
|
||||
break;
|
||||
case EQNFONT_BOLD:
|
||||
case EQNFONT_FAT:
|
||||
post = print_otag(p, tag, "?", "fontweight", "bold");
|
||||
break;
|
||||
case EQNFONT_ITALIC:
|
||||
post = print_otag(p, tag, "?", "fontstyle", "italic");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
print_text(p, bp->text);
|
||||
} else if (NULL == post) {
|
||||
if (NULL != bp->left || NULL != bp->right)
|
||||
@ -172,14 +227,17 @@ eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
}
|
||||
|
||||
void
|
||||
print_eqn(struct html *p, const struct eqn *ep)
|
||||
print_eqn(struct html *p, const struct eqn_box *bp)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
if (bp->first == NULL)
|
||||
return;
|
||||
|
||||
t = print_otag(p, TAG_MATH, "c", "eqn");
|
||||
|
||||
p->flags |= HTML_NONOSPACE;
|
||||
eqn_box(p, ep->root);
|
||||
eqn_box(p, bp);
|
||||
p->flags &= ~HTML_NONOSPACE;
|
||||
|
||||
print_tagq(p, t);
|
||||
|
56
eqn_term.c
56
eqn_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: eqn_term.c,v 1.9 2017/02/12 14:19:01 schwarze Exp $ */
|
||||
/* $Id: eqn_term.c,v 1.13 2017/07/08 14:51:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -40,10 +40,10 @@ static void eqn_box(struct termp *, const struct eqn_box *);
|
||||
|
||||
|
||||
void
|
||||
term_eqn(struct termp *p, const struct eqn *ep)
|
||||
term_eqn(struct termp *p, const struct eqn_box *bp)
|
||||
{
|
||||
|
||||
eqn_box(p, ep->root);
|
||||
eqn_box(p, bp);
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
@ -51,21 +51,40 @@ static void
|
||||
eqn_box(struct termp *p, const struct eqn_box *bp)
|
||||
{
|
||||
const struct eqn_box *child;
|
||||
int delim;
|
||||
|
||||
if (bp->type == EQN_LIST ||
|
||||
/* Delimiters around this box? */
|
||||
|
||||
if ((bp->type == EQN_LIST && bp->expectargs > 1) ||
|
||||
(bp->type == EQN_PILE && (bp->prev || bp->next)) ||
|
||||
(bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) {
|
||||
(bp->parent != NULL && (bp->parent->pos == EQNPOS_SQRT ||
|
||||
/* Diacritic followed by ^ or _. */
|
||||
((bp->top != NULL || bp->bottom != NULL) &&
|
||||
bp->parent->type == EQN_SUBEXPR &&
|
||||
bp->parent->pos != EQNPOS_OVER && bp->next != NULL) ||
|
||||
/* Nested over, sub, sup, from, to. */
|
||||
(bp->type == EQN_SUBEXPR && bp->pos != EQNPOS_SQRT &&
|
||||
((bp->parent->type == EQN_LIST && bp->expectargs == 1) ||
|
||||
(bp->parent->type == EQN_SUBEXPR &&
|
||||
bp->pos != EQNPOS_SQRT)))))) {
|
||||
if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, bp->left != NULL ? bp->left : "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
delim = 1;
|
||||
} else
|
||||
delim = 0;
|
||||
|
||||
/* Handle Fonts and text. */
|
||||
|
||||
if (bp->font != EQNFONT_NONE)
|
||||
term_fontpush(p, fontmap[(int)bp->font]);
|
||||
|
||||
if (bp->text != NULL)
|
||||
term_word(p, bp->text);
|
||||
|
||||
/* Special box types. */
|
||||
|
||||
if (bp->pos == EQNPOS_SQRT) {
|
||||
term_word(p, "sqrt");
|
||||
if (bp->first != NULL) {
|
||||
@ -96,29 +115,25 @@ eqn_box(struct termp *p, const struct eqn_box *bp)
|
||||
} else {
|
||||
child = bp->first;
|
||||
if (bp->type == EQN_MATRIX &&
|
||||
child != NULL && child->type == EQN_LIST)
|
||||
child != NULL &&
|
||||
child->type == EQN_LIST &&
|
||||
child->expectargs > 1)
|
||||
child = child->first;
|
||||
while (child != NULL) {
|
||||
eqn_box(p,
|
||||
bp->type == EQN_PILE &&
|
||||
child->type == EQN_LIST &&
|
||||
child->expectargs > 1 &&
|
||||
child->args == 1 ?
|
||||
child->first : child);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle Fonts and diacritics. */
|
||||
|
||||
if (bp->font != EQNFONT_NONE)
|
||||
term_fontpop(p);
|
||||
if (bp->type == EQN_LIST ||
|
||||
(bp->type == EQN_PILE && (bp->prev || bp->next)) ||
|
||||
(bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, bp->right != NULL ? bp->right : ")");
|
||||
if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
if (bp->top != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, bp->top);
|
||||
@ -127,4 +142,13 @@ eqn_box(struct termp *p, const struct eqn_box *bp)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "_");
|
||||
}
|
||||
|
||||
/* Right delimiter after this box? */
|
||||
|
||||
if (delim) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, bp->right != NULL ? bp->right : ")");
|
||||
if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
}
|
||||
|
2
gmdiff
2
gmdiff
@ -43,7 +43,7 @@ while [ -n "$1" ]; do
|
||||
shift
|
||||
echo " ========== $file ========== "
|
||||
$ROFF -mandoc $file 2> /tmp/roff.err > /tmp/roff.out
|
||||
${MANDOC:=mandoc} -Ios='OpenBSD ports' $MOPT $file \
|
||||
${MANDOC:=mandoc} -Ios=OpenBSD $MOPT $file \
|
||||
2> /tmp/mandoc.err > /tmp/mandoc.out
|
||||
for i in roff mandoc; do
|
||||
[ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err
|
||||
|
80
html.c
80
html.c
@ -1,4 +1,4 @@
|
||||
/* $Id: html.c,v 1.213 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.219 2017/07/15 17:57:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -87,6 +87,7 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"math", HTML_NLALL | HTML_INDENT},
|
||||
{"mrow", 0},
|
||||
{"mi", 0},
|
||||
{"mn", 0},
|
||||
{"mo", 0},
|
||||
{"msup", 0},
|
||||
{"msub", 0},
|
||||
@ -345,16 +346,18 @@ static int
|
||||
print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
{
|
||||
char numbuf[16];
|
||||
size_t sz;
|
||||
int c, len, nospace;
|
||||
struct tag *t;
|
||||
const char *seq;
|
||||
size_t sz;
|
||||
int c, len, breakline, nospace;
|
||||
enum mandoc_esc esc;
|
||||
static const char rejs[9] = { '\\', '<', '>', '&', '"',
|
||||
static const char rejs[10] = { ' ', '\\', '<', '>', '&', '"',
|
||||
ASCII_NBRSP, ASCII_HYPH, ASCII_BREAK, '\0' };
|
||||
|
||||
if (pend == NULL)
|
||||
pend = strchr(p, '\0');
|
||||
|
||||
breakline = 0;
|
||||
nospace = 0;
|
||||
|
||||
while (p < pend) {
|
||||
@ -365,14 +368,28 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
}
|
||||
|
||||
for (sz = strcspn(p, rejs); sz-- && p < pend; p++)
|
||||
if (*p == ' ')
|
||||
print_endword(h);
|
||||
else
|
||||
print_byte(h, *p);
|
||||
print_byte(h, *p);
|
||||
|
||||
if (breakline &&
|
||||
(p >= pend || *p == ' ' || *p == ASCII_NBRSP)) {
|
||||
t = print_otag(h, TAG_DIV, "");
|
||||
print_text(h, "\\~");
|
||||
print_tagq(h, t);
|
||||
breakline = 0;
|
||||
while (p < pend && (*p == ' ' || *p == ASCII_NBRSP))
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p >= pend)
|
||||
break;
|
||||
|
||||
if (*p == ' ') {
|
||||
print_endword(h);
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (print_escape(h, *p++))
|
||||
continue;
|
||||
|
||||
@ -417,6 +434,9 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
if (c <= 0)
|
||||
continue;
|
||||
break;
|
||||
case ESCAPE_BREAK:
|
||||
breakline = 1;
|
||||
continue;
|
||||
case ESCAPE_NOSPACE:
|
||||
if ('\0' == *p)
|
||||
nospace = 1;
|
||||
@ -433,7 +453,7 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
(c > 0x7E && c < 0xA0))
|
||||
c = 0xFFFD;
|
||||
if (c > 0x7E) {
|
||||
(void)snprintf(numbuf, sizeof(numbuf), "&#%d;", c);
|
||||
(void)snprintf(numbuf, sizeof(numbuf), "&#x%.4X;", c);
|
||||
print_word(h, numbuf);
|
||||
} else if (print_escape(h, c) == 0)
|
||||
print_byte(h, c);
|
||||
@ -496,7 +516,7 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
print_indent(h);
|
||||
else if ((h->flags & HTML_NOSPACE) == 0) {
|
||||
if (h->flags & HTML_KEEP)
|
||||
print_word(h, " ");
|
||||
print_word(h, " ");
|
||||
else {
|
||||
if (h->flags & HTML_PREKEEP)
|
||||
h->flags |= HTML_KEEP;
|
||||
@ -603,25 +623,29 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
case 'u':
|
||||
su = va_arg(ap, struct roffsu *);
|
||||
break;
|
||||
case 'v':
|
||||
i = va_arg(ap, int);
|
||||
su = &mysu;
|
||||
SCALE_VS_INIT(su, i);
|
||||
break;
|
||||
case 'w':
|
||||
if ((arg2 = va_arg(ap, char *)) == NULL)
|
||||
break;
|
||||
su = &mysu;
|
||||
a2width(arg2, su);
|
||||
if ((arg2 = va_arg(ap, char *)) != NULL) {
|
||||
su = &mysu;
|
||||
a2width(arg2, su);
|
||||
}
|
||||
if (*fmt == '*') {
|
||||
if (su != NULL && su->unit == SCALE_EN &&
|
||||
su->scale > 5.9 && su->scale < 6.1)
|
||||
su = NULL;
|
||||
fmt++;
|
||||
}
|
||||
if (*fmt == '+') {
|
||||
/* Increase to make even bold text fit. */
|
||||
su->scale *= 1.2;
|
||||
/* Add padding. */
|
||||
su->scale += 3.0;
|
||||
if (su != NULL) {
|
||||
/* Make even bold text fit. */
|
||||
su->scale *= 1.2;
|
||||
/* Add padding. */
|
||||
su->scale += 3.0;
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
if (*fmt == '-') {
|
||||
su->scale *= -1.0;
|
||||
if (su != NULL)
|
||||
su->scale *= -1.0;
|
||||
fmt++;
|
||||
}
|
||||
break;
|
||||
@ -632,9 +656,6 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
/* Second letter: style name. */
|
||||
|
||||
switch (*fmt++) {
|
||||
case 'b':
|
||||
attr = "margin-bottom";
|
||||
break;
|
||||
case 'h':
|
||||
attr = "height";
|
||||
break;
|
||||
@ -644,9 +665,6 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
case 'l':
|
||||
attr = "margin-left";
|
||||
break;
|
||||
case 't':
|
||||
attr = "margin-top";
|
||||
break;
|
||||
case 'w':
|
||||
attr = "width";
|
||||
break;
|
||||
@ -759,7 +777,7 @@ print_text(struct html *h, const char *word)
|
||||
h->flags |= HTML_KEEP;
|
||||
print_endword(h);
|
||||
} else
|
||||
print_word(h, " ");
|
||||
print_word(h, " ");
|
||||
}
|
||||
|
||||
assert(NULL == h->metaf);
|
||||
|
7
html.h
7
html.h
@ -1,4 +1,4 @@
|
||||
/* $Id: html.h,v 1.85 2017/05/04 22:16:09 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.87 2017/07/08 14:51:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -51,6 +51,7 @@ enum htmltag {
|
||||
TAG_MATH,
|
||||
TAG_MROW,
|
||||
TAG_MI,
|
||||
TAG_MN,
|
||||
TAG_MO,
|
||||
TAG_MSUP,
|
||||
TAG_MSUB,
|
||||
@ -114,7 +115,7 @@ struct html {
|
||||
|
||||
struct roff_node;
|
||||
struct tbl_span;
|
||||
struct eqn;
|
||||
struct eqn_box;
|
||||
|
||||
void roff_html_pre(struct html *, const struct roff_node *);
|
||||
|
||||
@ -126,7 +127,7 @@ void print_stagq(struct html *, const struct tag *);
|
||||
void print_text(struct html *, const char *);
|
||||
void print_tblclose(struct html *);
|
||||
void print_tbl(struct html *, const struct tbl_span *);
|
||||
void print_eqn(struct html *, const struct eqn *);
|
||||
void print_eqn(struct html *, const struct eqn_box *);
|
||||
void print_paragraph(struct html *);
|
||||
void print_endline(struct html *);
|
||||
|
||||
|
3
lib.c
3
lib.c
@ -1,4 +1,4 @@
|
||||
/* $Id: lib.c,v 1.13 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: lib.c,v 1.14 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
13
libmandoc.h
13
libmandoc.h
@ -1,7 +1,7 @@
|
||||
/* $Id: libmandoc.h,v 1.67 2017/04/29 12:45:41 schwarze Exp $ */
|
||||
/* $Id: libmandoc.h,v 1.70 2017/07/08 17:52:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -23,8 +23,6 @@ enum rofferr {
|
||||
ROFF_REPARSE, /* re-run main parser on the result */
|
||||
ROFF_SO, /* include another file */
|
||||
ROFF_IGN, /* ignore current line */
|
||||
ROFF_TBL, /* a table row was successfully parsed */
|
||||
ROFF_EQN /* an equation was successfully parsed */
|
||||
};
|
||||
|
||||
struct buf {
|
||||
@ -34,8 +32,6 @@ struct buf {
|
||||
|
||||
|
||||
struct mparse;
|
||||
struct tbl_span;
|
||||
struct eqn;
|
||||
struct roff;
|
||||
struct roff_man;
|
||||
|
||||
@ -45,7 +41,7 @@ void mandoc_vmsg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 5, 6)));
|
||||
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
||||
char *mandoc_normdate(struct mparse *, char *, int, int);
|
||||
char *mandoc_normdate(struct roff_man *, char *, int, int);
|
||||
int mandoc_eos(const char *, size_t);
|
||||
int mandoc_strntoi(const char *, size_t, int);
|
||||
const char *mandoc_a2msec(const char*);
|
||||
@ -75,6 +71,3 @@ char *roff_strdup(const struct roff *, const char *);
|
||||
int roff_getcontrol(const struct roff *,
|
||||
const char *, int *);
|
||||
int roff_getformat(const struct roff *);
|
||||
|
||||
const struct tbl_span *roff_span(const struct roff *);
|
||||
const struct eqn *roff_eqn(const struct roff *);
|
||||
|
27
libroff.h
27
libroff.h
@ -1,7 +1,7 @@
|
||||
/* $Id: libroff.h,v 1.39 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: libroff.h,v 1.42 2017/07/08 17:52:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -38,15 +38,15 @@ struct tbl_node {
|
||||
};
|
||||
|
||||
struct eqn_node {
|
||||
struct eqn eqn; /* syntax tree of this equation */
|
||||
struct mparse *parse; /* main parser, for error reporting */
|
||||
struct eqn_node *next; /* singly linked list of equations */
|
||||
struct roff_node *node; /* syntax tree of this equation */
|
||||
struct eqn_def *defs; /* array of definitions */
|
||||
char *data; /* source code of this equation */
|
||||
char *start; /* first byte of the current token */
|
||||
char *end; /* first byte of the next token */
|
||||
size_t defsz; /* number of definitions */
|
||||
size_t sz; /* length of the source code */
|
||||
size_t cur; /* parse point in the source code */
|
||||
size_t rew; /* beginning of the current token */
|
||||
size_t toksz; /* length of the current token */
|
||||
int gsize; /* default point size */
|
||||
int delim; /* in-line delimiters enabled */
|
||||
char odelim; /* in-line opening delimiter */
|
||||
@ -65,15 +65,16 @@ struct tbl_node *tbl_alloc(int, int, struct mparse *);
|
||||
void tbl_restart(int, int, struct tbl_node *);
|
||||
void tbl_free(struct tbl_node *);
|
||||
void tbl_reset(struct tbl_node *);
|
||||
enum rofferr tbl_read(struct tbl_node *, int, const char *, int);
|
||||
void tbl_read(struct tbl_node *, int, const char *, int);
|
||||
void tbl_option(struct tbl_node *, int, const char *, int *);
|
||||
void tbl_layout(struct tbl_node *, int, const char *, int);
|
||||
void tbl_data(struct tbl_node *, int, const char *, int);
|
||||
int tbl_cdata(struct tbl_node *, int, const char *, int);
|
||||
void tbl_cdata(struct tbl_node *, int, const char *, int);
|
||||
const struct tbl_span *tbl_span(struct tbl_node *);
|
||||
int tbl_end(struct tbl_node **);
|
||||
struct eqn_node *eqn_alloc(int, int, struct mparse *);
|
||||
enum rofferr eqn_end(struct eqn_node **);
|
||||
int tbl_end(struct tbl_node *);
|
||||
struct eqn_node *eqn_alloc(struct mparse *);
|
||||
void eqn_box_free(struct eqn_box *);
|
||||
void eqn_free(struct eqn_node *);
|
||||
enum rofferr eqn_read(struct eqn_node **, int,
|
||||
const char *, int, int *);
|
||||
void eqn_parse(struct eqn_node *);
|
||||
void eqn_read(struct eqn_node *, const char *);
|
||||
void eqn_reset(struct eqn_node *);
|
||||
|
153
main.c
153
main.c
@ -1,4 +1,4 @@
|
||||
/* $Id: main.c,v 1.292 2017/06/03 12:17:25 schwarze Exp $ */
|
||||
/* $Id: main.c,v 1.301 2017/07/26 10:21:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -43,6 +43,7 @@
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_xr.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
@ -74,21 +75,24 @@ enum outt {
|
||||
|
||||
struct curparse {
|
||||
struct mparse *mp;
|
||||
enum mandoclevel wlevel; /* ignore messages below this */
|
||||
int wstop; /* stop after a file with a warning */
|
||||
enum outt outtype; /* which output to use */
|
||||
void *outdata; /* data for output */
|
||||
struct manoutput *outopts; /* output options */
|
||||
void *outdata; /* data for output */
|
||||
char *os_s; /* operating system for display */
|
||||
int wstop; /* stop after a file with a warning */
|
||||
enum mandocerr mmin; /* ignore messages below this */
|
||||
enum mandoc_os os_e; /* check base system conventions */
|
||||
enum outt outtype; /* which output to use */
|
||||
};
|
||||
|
||||
|
||||
int mandocdb(int, char *[]);
|
||||
|
||||
static void check_xr(const char *);
|
||||
static int fs_lookup(const struct manpaths *,
|
||||
size_t ipath, const char *,
|
||||
const char *, const char *,
|
||||
struct manpage **, size_t *);
|
||||
static void fs_search(const struct mansearch *,
|
||||
static int fs_search(const struct mansearch *,
|
||||
const struct manpaths *, int, char**,
|
||||
struct manpage **, size_t *);
|
||||
static int koptions(int *, char *);
|
||||
@ -107,6 +111,7 @@ 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 enum mandoclevel rc;
|
||||
static FILE *mmsg_stream;
|
||||
|
||||
|
||||
int
|
||||
@ -119,7 +124,7 @@ main(int argc, char *argv[])
|
||||
struct manpage *res, *resp;
|
||||
const char *progname, *sec, *thisarg;
|
||||
char *conf_file, *defpaths, *auxpaths;
|
||||
char *defos, *oarg;
|
||||
char *oarg;
|
||||
unsigned char *uc;
|
||||
size_t i, sz;
|
||||
int prio, best_prio;
|
||||
@ -183,10 +188,10 @@ main(int argc, char *argv[])
|
||||
|
||||
memset(&curp, 0, sizeof(struct curparse));
|
||||
curp.outtype = OUTT_LOCALE;
|
||||
curp.wlevel = MANDOCLEVEL_BADARG;
|
||||
curp.mmin = MANDOCERR_MAX;
|
||||
curp.outopts = &conf.output;
|
||||
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
|
||||
defos = NULL;
|
||||
mmsg_stream = stderr;
|
||||
|
||||
use_pager = 1;
|
||||
tag_files = NULL;
|
||||
@ -222,11 +227,11 @@ main(int argc, char *argv[])
|
||||
warnx("-I %s: Bad argument", optarg);
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
}
|
||||
if (defos) {
|
||||
if (curp.os_s != NULL) {
|
||||
warnx("-I %s: Duplicate argument", optarg);
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
}
|
||||
defos = mandoc_strdup(optarg + 3);
|
||||
curp.os_s = mandoc_strdup(optarg + 3);
|
||||
break;
|
||||
case 'K':
|
||||
if ( ! koptions(&options, optarg))
|
||||
@ -446,7 +451,8 @@ main(int argc, char *argv[])
|
||||
moptions(&options, auxpaths);
|
||||
|
||||
mchars_alloc();
|
||||
curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
|
||||
curp.mp = mparse_alloc(options, curp.mmin, mmsg,
|
||||
curp.os_e, curp.os_s);
|
||||
|
||||
/*
|
||||
* Conditionally start up the lookaside buffer before parsing.
|
||||
@ -472,7 +478,7 @@ main(int argc, char *argv[])
|
||||
parse(&curp, fd, *argv);
|
||||
else if (resp->form == FORM_SRC) {
|
||||
/* For .so only; ignore failure. */
|
||||
chdir(conf.manpath.paths[resp->ipath]);
|
||||
(void)chdir(conf.manpath.paths[resp->ipath]);
|
||||
parse(&curp, fd, resp->file);
|
||||
} else
|
||||
passthrough(resp->file, fd,
|
||||
@ -515,6 +521,7 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
mandoc_xr_free();
|
||||
mparse_free(curp.mp);
|
||||
mchars_free();
|
||||
|
||||
@ -524,7 +531,7 @@ main(int argc, char *argv[])
|
||||
mansearch_free(res, sz);
|
||||
}
|
||||
|
||||
free(defos);
|
||||
free(curp.os_s);
|
||||
|
||||
/*
|
||||
* When using a pager, finish writing both temporary files,
|
||||
@ -658,12 +665,23 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
if (globres == 0)
|
||||
file = mandoc_strdup(*globinfo.gl_pathv);
|
||||
globfree(&globinfo);
|
||||
if (globres != 0)
|
||||
if (globres == 0)
|
||||
goto found;
|
||||
if (res != NULL || ipath + 1 != paths->sz)
|
||||
return 0;
|
||||
|
||||
mandoc_asprintf(&file, "%s.%s", name, sec);
|
||||
globres = access(file, R_OK);
|
||||
free(file);
|
||||
return globres != -1;
|
||||
|
||||
found:
|
||||
warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
|
||||
name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
|
||||
if (res == NULL) {
|
||||
free(file);
|
||||
return 1;
|
||||
}
|
||||
*res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
|
||||
page = *res + (*ressz - 1);
|
||||
page->file = file;
|
||||
@ -676,7 +694,7 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
int argc, char **argv, struct manpage **res, size_t *ressz)
|
||||
{
|
||||
@ -688,7 +706,8 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
|
||||
assert(cfg->argmode == ARG_NAME);
|
||||
|
||||
*res = NULL;
|
||||
if (res != NULL)
|
||||
*res = NULL;
|
||||
*ressz = lastsz = 0;
|
||||
while (argc) {
|
||||
for (ipath = 0; ipath < paths->sz; ipath++) {
|
||||
@ -696,19 +715,20 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
if (fs_lookup(paths, ipath, cfg->sec,
|
||||
cfg->arch, *argv, res, ressz) &&
|
||||
cfg->firstmatch)
|
||||
return;
|
||||
return 1;
|
||||
} else for (isec = 0; isec < nsec; isec++)
|
||||
if (fs_lookup(paths, ipath, sections[isec],
|
||||
cfg->arch, *argv, res, ressz) &&
|
||||
cfg->firstmatch)
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if (*ressz == lastsz)
|
||||
if (res != NULL && *ressz == lastsz)
|
||||
warnx("No entry for %s in the manual.", *argv);
|
||||
lastsz = *ressz;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -745,6 +765,7 @@ parse(struct curparse *curp, int fd, const char *file)
|
||||
|
||||
if (man == NULL)
|
||||
return;
|
||||
mandoc_xr_reset();
|
||||
if (man->macroset == MACROSET_MDOC) {
|
||||
if (curp->outtype != OUTT_TREE || !curp->outopts->noval)
|
||||
mdoc_validate(man);
|
||||
@ -796,9 +817,46 @@ parse(struct curparse *curp, int fd, const char *file)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curp->mmin < MANDOCERR_STYLE)
|
||||
check_xr(file);
|
||||
mparse_updaterc(curp->mp, &rc);
|
||||
}
|
||||
|
||||
static void
|
||||
check_xr(const char *file)
|
||||
{
|
||||
static struct manpaths paths;
|
||||
struct mansearch search;
|
||||
struct mandoc_xr *xr;
|
||||
char *cp;
|
||||
size_t sz;
|
||||
|
||||
if (paths.sz == 0)
|
||||
manpath_base(&paths);
|
||||
|
||||
for (xr = mandoc_xr_get(); xr != NULL; xr = xr->next) {
|
||||
if (xr->line == -1)
|
||||
continue;
|
||||
search.arch = NULL;
|
||||
search.sec = xr->sec;
|
||||
search.outkey = NULL;
|
||||
search.argmode = ARG_NAME;
|
||||
search.firstmatch = 1;
|
||||
if (mansearch(&search, &paths, 1, &xr->name, NULL, &sz))
|
||||
continue;
|
||||
if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz))
|
||||
continue;
|
||||
if (xr->count == 1)
|
||||
mandoc_asprintf(&cp, "Xr %s %s", xr->name, xr->sec);
|
||||
else
|
||||
mandoc_asprintf(&cp, "Xr %s %s (%d times)",
|
||||
xr->name, xr->sec, xr->count);
|
||||
mmsg(MANDOCERR_XR_BAD, MANDOCLEVEL_STYLE,
|
||||
file, xr->line, xr->pos + 1, cp);
|
||||
free(cp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
outdata_alloc(struct curparse *curp)
|
||||
{
|
||||
@ -937,7 +995,8 @@ toptions(struct curparse *curp, char *arg)
|
||||
curp->outtype = OUTT_ASCII;
|
||||
else if (0 == strcmp(arg, "lint")) {
|
||||
curp->outtype = OUTT_LINT;
|
||||
curp->wlevel = MANDOCLEVEL_STYLE;
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
mmsg_stream = stdout;
|
||||
} else if (0 == strcmp(arg, "tree"))
|
||||
curp->outtype = OUTT_TREE;
|
||||
else if (0 == strcmp(arg, "man"))
|
||||
@ -966,16 +1025,19 @@ static int
|
||||
woptions(struct curparse *curp, char *arg)
|
||||
{
|
||||
char *v, *o;
|
||||
const char *toks[8];
|
||||
const char *toks[11];
|
||||
|
||||
toks[0] = "stop";
|
||||
toks[1] = "all";
|
||||
toks[2] = "style";
|
||||
toks[3] = "warning";
|
||||
toks[4] = "error";
|
||||
toks[5] = "unsupp";
|
||||
toks[6] = "fatal";
|
||||
toks[7] = NULL;
|
||||
toks[2] = "base";
|
||||
toks[3] = "style";
|
||||
toks[4] = "warning";
|
||||
toks[5] = "error";
|
||||
toks[6] = "unsupp";
|
||||
toks[7] = "fatal";
|
||||
toks[8] = "openbsd";
|
||||
toks[9] = "netbsd";
|
||||
toks[10] = NULL;
|
||||
|
||||
while (*arg) {
|
||||
o = arg;
|
||||
@ -985,19 +1047,30 @@ woptions(struct curparse *curp, char *arg)
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
curp->wlevel = MANDOCLEVEL_STYLE;
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
break;
|
||||
case 3:
|
||||
curp->wlevel = MANDOCLEVEL_WARNING;
|
||||
curp->mmin = MANDOCERR_STYLE;
|
||||
break;
|
||||
case 4:
|
||||
curp->wlevel = MANDOCLEVEL_ERROR;
|
||||
curp->mmin = MANDOCERR_WARNING;
|
||||
break;
|
||||
case 5:
|
||||
curp->wlevel = MANDOCLEVEL_UNSUPP;
|
||||
curp->mmin = MANDOCERR_ERROR;
|
||||
break;
|
||||
case 6:
|
||||
curp->wlevel = MANDOCLEVEL_BADARG;
|
||||
curp->mmin = MANDOCERR_UNSUPP;
|
||||
break;
|
||||
case 7:
|
||||
curp->mmin = MANDOCERR_MAX;
|
||||
break;
|
||||
case 8:
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
curp->os_e = MANDOC_OS_OPENBSD;
|
||||
break;
|
||||
case 9:
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
curp->os_e = MANDOC_OS_NETBSD;
|
||||
break;
|
||||
default:
|
||||
warnx("-W %s: Bad argument", o);
|
||||
@ -1013,21 +1086,21 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
|
||||
{
|
||||
const char *mparse_msg;
|
||||
|
||||
fprintf(stderr, "%s: %s:", getprogname(),
|
||||
fprintf(mmsg_stream, "%s: %s:", getprogname(),
|
||||
file == NULL ? "<stdin>" : file);
|
||||
|
||||
if (line)
|
||||
fprintf(stderr, "%d:%d:", line, col + 1);
|
||||
fprintf(mmsg_stream, "%d:%d:", line, col + 1);
|
||||
|
||||
fprintf(stderr, " %s", mparse_strlevel(lvl));
|
||||
fprintf(mmsg_stream, " %s", mparse_strlevel(lvl));
|
||||
|
||||
if (NULL != (mparse_msg = mparse_strerror(t)))
|
||||
fprintf(stderr, ": %s", mparse_msg);
|
||||
if ((mparse_msg = mparse_strerror(t)) != NULL)
|
||||
fprintf(mmsg_stream, ": %s", mparse_msg);
|
||||
|
||||
if (msg)
|
||||
fprintf(stderr, ": %s", msg);
|
||||
fprintf(mmsg_stream, ": %s", msg);
|
||||
|
||||
fputc('\n', stderr);
|
||||
fputc('\n', mmsg_stream);
|
||||
}
|
||||
|
||||
static pid_t
|
||||
|
18
man.7
18
man.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.7,v 1.135 2017/05/07 21:44:49 schwarze Exp $
|
||||
.\" $Id: man.7,v 1.136 2017/06/25 11:42:02 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 7 2017 $
|
||||
.Dd $Mdocdate: June 25 2017 $
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -466,6 +466,20 @@ See also
|
||||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&ME
|
||||
End a mailto block.
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
See
|
||||
.Sx \&MT .
|
||||
.Ss \&MT
|
||||
Begin a mailto block.
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
It has the following syntax:
|
||||
.Bd -literal -offset indent
|
||||
.Pf \. Sx \&MT Ar address
|
||||
link description to be shown
|
||||
.Pf \. Sx ME
|
||||
.Ed
|
||||
.Ss \&OP
|
||||
Optional command-line argument.
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
|
44
man.c
44
man.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man.c,v 1.174 2017/06/03 15:55:24 schwarze Exp $ */
|
||||
/* $Id: man.c,v 1.176 2017/06/28 12:52:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -76,6 +76,8 @@ static int
|
||||
man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
{
|
||||
int i;
|
||||
const char *cp, *sp;
|
||||
char *ep;
|
||||
|
||||
/* Literal free-form text whitespace is preserved. */
|
||||
|
||||
@ -89,19 +91,36 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
/* Skip leading whitespace. */ ;
|
||||
|
||||
/*
|
||||
* Blank lines are ignored in next line scope and right
|
||||
* after headings but add a single vertical space elsewhere.
|
||||
* Blank lines are ignored in next line scope
|
||||
* and right after headings and cancel preceding \c,
|
||||
* but add a single vertical space elsewhere.
|
||||
*/
|
||||
|
||||
if (buf[i] == '\0') {
|
||||
if (man->flags & (MAN_ELINE | MAN_BLINE))
|
||||
if (man->flags & (MAN_ELINE | MAN_BLINE)) {
|
||||
mandoc_msg(MANDOCERR_BLK_BLANK, man->parse,
|
||||
line, 0, NULL);
|
||||
else if (man->last->tok != MAN_SH &&
|
||||
man->last->tok != MAN_SS) {
|
||||
roff_elem_alloc(man, line, offs, ROFF_sp);
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
return 1;
|
||||
}
|
||||
if (man->last->tok == MAN_SH || man->last->tok == MAN_SS)
|
||||
return 1;
|
||||
switch (man->last->type) {
|
||||
case ROFFT_TEXT:
|
||||
sp = man->last->string;
|
||||
cp = ep = strchr(sp, '\0') - 2;
|
||||
if (cp < sp || cp[0] != '\\' || cp[1] != 'c')
|
||||
break;
|
||||
while (cp > sp && cp[-1] == '\\')
|
||||
cp--;
|
||||
if ((ep - cp) % 2)
|
||||
break;
|
||||
*ep = '\0';
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
roff_elem_alloc(man, line, offs, ROFF_sp);
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -263,8 +282,10 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
if (man->flags & MAN_ELINE && (tok < MAN_TH ||
|
||||
! (man_macros[tok].flags & MAN_NSCOPED))) {
|
||||
n = man->last;
|
||||
assert(n->type != ROFFT_TEXT);
|
||||
if (man_macros[n->tok].flags & MAN_NSCOPED)
|
||||
if (n->type == ROFFT_TEXT)
|
||||
n = n->parent;
|
||||
if (n->tok < MAN_TH ||
|
||||
man_macros[n->tok].flags & MAN_NSCOPED)
|
||||
n = n->parent;
|
||||
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
|
||||
@ -300,7 +321,8 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
n = man->last;
|
||||
if (n->type == ROFFT_TEXT)
|
||||
n = n->parent;
|
||||
if ( ! (man_macros[n->tok].flags & MAN_BSCOPE))
|
||||
if (n->tok < MAN_TH ||
|
||||
(man_macros[n->tok].flags & MAN_BSCOPE) == 0)
|
||||
n = n->parent;
|
||||
|
||||
assert(n->type == ROFFT_HEAD);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.options.1,v 1.6 2017/02/02 20:10:51 schwarze Exp $
|
||||
.\" $Id: man.options.1,v 1.7 2017/07/04 23:40:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2017 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: February 2 2017 $
|
||||
.Dd $Mdocdate: July 4 2017 $
|
||||
.Dt MAN.OPTIONS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1297,11 +1297,17 @@ the Unix Archive of the Unix Heritage Society
|
||||
.It
|
||||
the CSRG Archive CD-ROMs
|
||||
.It
|
||||
the FreeBSD SVN repository
|
||||
the
|
||||
.Fx
|
||||
SVN repository
|
||||
.It
|
||||
the OpenBSD CVS repository
|
||||
the
|
||||
.Ox
|
||||
CVS repository
|
||||
.It
|
||||
the NetBSD CVS repository
|
||||
the
|
||||
.Nx
|
||||
CVS repository
|
||||
.It
|
||||
the GNU roff (groff) git repository
|
||||
.It
|
||||
|
14
man_html.c
14
man_html.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man_html.c,v 1.143 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.145 2017/06/25 11:42:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "out.h"
|
||||
@ -105,6 +106,8 @@ static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL }, /* EE */
|
||||
{ man_UR_pre, NULL }, /* UR */
|
||||
{ NULL, NULL }, /* UE */
|
||||
{ man_UR_pre, NULL }, /* MT */
|
||||
{ NULL, NULL }, /* ME */
|
||||
};
|
||||
static const struct htmlman *const mans = __mans - MAN_TH;
|
||||
|
||||
@ -229,6 +232,7 @@ print_man_node(MAN_ARGS)
|
||||
case MAN_P: /* reopen .nf in the body. */
|
||||
case MAN_RS:
|
||||
case MAN_UR:
|
||||
case MAN_MT:
|
||||
fillmode(h, MAN_fi);
|
||||
break;
|
||||
default:
|
||||
@ -643,11 +647,17 @@ man_RS_pre(MAN_ARGS)
|
||||
static int
|
||||
man_UR_pre(MAN_ARGS)
|
||||
{
|
||||
char *cp;
|
||||
n = n->child;
|
||||
assert(n->type == ROFFT_HEAD);
|
||||
if (n->child != NULL) {
|
||||
assert(n->child->type == ROFFT_TEXT);
|
||||
print_otag(h, TAG_A, "cTh", "Lk", n->child->string);
|
||||
if (n->tok == MAN_MT) {
|
||||
mandoc_asprintf(&cp, "mailto:%s", n->child->string);
|
||||
print_otag(h, TAG_A, "cTh", "Mt", cp);
|
||||
free(cp);
|
||||
} else
|
||||
print_otag(h, TAG_A, "cTh", "Lk", n->child->string);
|
||||
}
|
||||
|
||||
assert(n->next->type == ROFFT_BODY);
|
||||
|
24
man_macro.c
24
man_macro.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man_macro.c,v 1.120 2017/05/05 15:17:32 schwarze Exp $ */
|
||||
/* $Id: man_macro.c,v 1.123 2017/06/25 11:45:37 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -69,12 +69,14 @@ const struct man_macro __man_macros[MAN_MAX - MAN_TH] = {
|
||||
{ in_line_eoln, 0 }, /* UC */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* PD */
|
||||
{ in_line_eoln, 0 }, /* AT */
|
||||
{ in_line_eoln, 0 }, /* in */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* in */
|
||||
{ in_line_eoln, 0 }, /* OP */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EX */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EE */
|
||||
{ blk_exp, MAN_BSCOPE }, /* UR */
|
||||
{ blk_close, MAN_BSCOPE }, /* UE */
|
||||
{ blk_exp, MAN_BSCOPE }, /* MT */
|
||||
{ blk_close, MAN_BSCOPE }, /* ME */
|
||||
};
|
||||
const struct man_macro *const man_macros = __man_macros - MAN_TH;
|
||||
|
||||
@ -217,6 +219,9 @@ blk_close(MACRO_PROT_ARGS)
|
||||
case MAN_UE:
|
||||
ntok = MAN_UR;
|
||||
break;
|
||||
case MAN_ME:
|
||||
ntok = MAN_MT;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
@ -235,6 +240,10 @@ blk_close(MACRO_PROT_ARGS)
|
||||
ntok = man->last->tok;
|
||||
man_unscope(man, nn);
|
||||
|
||||
if (tok == MAN_RE && nn->head->aux > 0)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
nn->head->aux, '-');
|
||||
|
||||
/* Move a trailing paragraph behind the block. */
|
||||
|
||||
if (ntok == MAN_LP || ntok == MAN_PP || ntok == MAN_P) {
|
||||
@ -256,8 +265,17 @@ blk_exp(MACRO_PROT_ARGS)
|
||||
head = roff_head_alloc(man, line, ppos, tok);
|
||||
|
||||
la = *pos;
|
||||
if (man_args(man, line, pos, buf, &p))
|
||||
if (man_args(man, line, pos, buf, &p)) {
|
||||
roff_word_alloc(man, line, la, p);
|
||||
if (tok == MAN_RS) {
|
||||
if (roff_getreg(man->roff, "an-margin") == 0)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
7 * 24, '=');
|
||||
if ((head->aux = strtod(p, NULL) * 24.0) > 0)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
head->aux, '+');
|
||||
}
|
||||
}
|
||||
|
||||
if (buf[*pos] != '\0')
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, line,
|
||||
|
27
man_term.c
27
man_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man_term.c,v 1.204 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.208 2017/06/25 11:42:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -128,6 +128,8 @@ static const struct termact __termacts[MAN_MAX - MAN_TH] = {
|
||||
{ pre_literal, NULL, 0 }, /* EE */
|
||||
{ pre_UR, post_UR, 0 }, /* UR */
|
||||
{ NULL, NULL, 0 }, /* UE */
|
||||
{ pre_UR, post_UR, 0 }, /* MT */
|
||||
{ NULL, NULL, 0 }, /* ME */
|
||||
};
|
||||
static const struct termact *termacts = __termacts - MAN_TH;
|
||||
|
||||
@ -141,6 +143,9 @@ terminal_man(void *arg, const struct roff_man *man)
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
save_defindent = p->defindent;
|
||||
if (p->synopsisonly == 0 && p->defindent == 0)
|
||||
p->defindent = 7;
|
||||
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
@ -167,16 +172,13 @@ terminal_man(void *arg, const struct roff_man *man)
|
||||
n = n->next;
|
||||
}
|
||||
} else {
|
||||
save_defindent = p->defindent;
|
||||
if (p->defindent == 0)
|
||||
p->defindent = 7;
|
||||
term_begin(p, print_man_head, print_man_foot, &man->meta);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (n != NULL)
|
||||
print_man_nodelist(p, &mt, n, &man->meta);
|
||||
term_end(p);
|
||||
p->defindent = save_defindent;
|
||||
}
|
||||
p->defindent = save_defindent;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -377,7 +379,7 @@ pre_in(DECL_ARGS)
|
||||
if (a2roffsu(++cp, &su, SCALE_EN) == NULL)
|
||||
return 0;
|
||||
|
||||
v = (term_hspan(p, &su) + 11) / 24;
|
||||
v = term_hen(p, &su);
|
||||
|
||||
if (less < 0)
|
||||
p->tcol->offset -= p->tcol->offset > v ? v : p->tcol->offset;
|
||||
@ -426,7 +428,7 @@ pre_HP(DECL_ARGS)
|
||||
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
len = term_hen(p, &su);
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
len = -mt->offset;
|
||||
else if (len > SHRT_MAX)
|
||||
@ -511,7 +513,7 @@ pre_IP(DECL_ARGS)
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
(nn = nn->next) != NULL &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
len = term_hen(p, &su);
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
len = -mt->offset;
|
||||
else if (len > SHRT_MAX)
|
||||
@ -593,7 +595,7 @@ pre_TP(DECL_ARGS)
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
nn->string != NULL && ! (NODE_LINE & nn->flags) &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
len = term_hen(p, &su);
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
len = -mt->offset;
|
||||
else if (len > SHRT_MAX)
|
||||
@ -797,7 +799,7 @@ pre_RS(DECL_ARGS)
|
||||
if (n->child == NULL)
|
||||
n->aux = mt->lmargin[mt->lmargincur];
|
||||
else if (a2roffsu(n->child->string, &su, SCALE_EN) != NULL)
|
||||
n->aux = term_hspan(p, &su) / 24;
|
||||
n->aux = term_hen(p, &su);
|
||||
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
|
||||
n->aux = -mt->offset;
|
||||
else if (n->aux > SHRT_MAX)
|
||||
@ -872,7 +874,10 @@ print_man_node(DECL_ARGS)
|
||||
* before printing the line's data.
|
||||
*/
|
||||
if (*n->string == '\0') {
|
||||
term_vspace(p);
|
||||
if (p->flags & TERMP_NONEWLINE)
|
||||
term_newln(p);
|
||||
else
|
||||
term_vspace(p);
|
||||
return;
|
||||
} else if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(p->flags & TERMP_NONEWLINE) == 0)
|
||||
|
@ -47,11 +47,12 @@ static void check_text(CHKARGS);
|
||||
|
||||
static void post_AT(CHKARGS);
|
||||
static void post_IP(CHKARGS);
|
||||
static void post_vs(CHKARGS);
|
||||
static void post_OP(CHKARGS);
|
||||
static void post_TH(CHKARGS);
|
||||
static void post_UC(CHKARGS);
|
||||
static void post_UR(CHKARGS);
|
||||
static void post_in(CHKARGS);
|
||||
static void post_vs(CHKARGS);
|
||||
|
||||
static const v_check __man_valids[MAN_MAX - MAN_TH] = {
|
||||
post_TH, /* TH */
|
||||
@ -82,12 +83,14 @@ static const v_check __man_valids[MAN_MAX - MAN_TH] = {
|
||||
post_UC, /* UC */
|
||||
NULL, /* PD */
|
||||
post_AT, /* AT */
|
||||
NULL, /* in */
|
||||
post_in, /* in */
|
||||
post_OP, /* OP */
|
||||
NULL, /* EX */
|
||||
NULL, /* EE */
|
||||
post_UR, /* UR */
|
||||
NULL, /* UE */
|
||||
post_UR, /* MT */
|
||||
NULL, /* ME */
|
||||
};
|
||||
static const v_check *man_valids = __man_valids - MAN_TH;
|
||||
|
||||
@ -167,8 +170,14 @@ check_root(CHKARGS)
|
||||
man->meta.title = mandoc_strdup("");
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
man->meta.date = man->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(man->parse, NULL, n->line, n->pos);
|
||||
mandoc_normdate(man, NULL, n->line, n->pos);
|
||||
}
|
||||
|
||||
if (man->meta.os_e &&
|
||||
(man->meta.rcsids & (1 << man->meta.os_e)) == 0)
|
||||
mandoc_msg(MANDOCERR_RCS_MISSING, man->parse, 0, 0,
|
||||
man->meta.os_e == MANDOC_OS_OPENBSD ?
|
||||
"(OpenBSD)" : "(NetBSD)");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -202,10 +211,9 @@ post_OP(CHKARGS)
|
||||
static void
|
||||
post_UR(CHKARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_HEAD && n->child == NULL)
|
||||
mandoc_vmsg(MANDOCERR_UR_NOHEAD, man->parse,
|
||||
n->line, n->pos, "UR");
|
||||
mandoc_msg(MANDOCERR_UR_NOHEAD, man->parse,
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
check_part(man, n);
|
||||
}
|
||||
|
||||
@ -323,8 +331,7 @@ post_TH(CHKARGS)
|
||||
if (n && n->string && '\0' != n->string[0]) {
|
||||
man->meta.date = man->quick ?
|
||||
mandoc_strdup(n->string) :
|
||||
mandoc_normdate(man->parse, n->string,
|
||||
n->line, n->pos);
|
||||
mandoc_normdate(man, n->string, n->line, n->pos);
|
||||
} else {
|
||||
man->meta.date = mandoc_strdup("");
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, man->parse,
|
||||
@ -336,8 +343,14 @@ post_TH(CHKARGS)
|
||||
|
||||
if (n && (n = n->next))
|
||||
man->meta.os = mandoc_strdup(n->string);
|
||||
else if (man->defos != NULL)
|
||||
man->meta.os = mandoc_strdup(man->defos);
|
||||
else if (man->os_s != NULL)
|
||||
man->meta.os = mandoc_strdup(man->os_s);
|
||||
if (man->meta.os_e == MANDOC_OS_OTHER && man->meta.os != NULL) {
|
||||
if (strstr(man->meta.os, "OpenBSD") != NULL)
|
||||
man->meta.os_e = MANDOC_OS_OPENBSD;
|
||||
else if (strstr(man->meta.os, "NetBSD") != NULL)
|
||||
man->meta.os_e = MANDOC_OS_NETBSD;
|
||||
}
|
||||
|
||||
/* TITLE MSEC DATE OS ->VOL<- */
|
||||
/* If missing, use the default VOL name for MSEC. */
|
||||
@ -435,6 +448,22 @@ post_AT(CHKARGS)
|
||||
man->meta.os = mandoc_strdup(p);
|
||||
}
|
||||
|
||||
static void
|
||||
post_in(CHKARGS)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (n->parent->tok != MAN_TP ||
|
||||
n->parent->type != ROFFT_HEAD ||
|
||||
n->child == NULL ||
|
||||
*n->child->string == '+' ||
|
||||
*n->child->string == '-')
|
||||
return;
|
||||
mandoc_asprintf(&s, "+%s", n->child->string);
|
||||
free(n->child->string);
|
||||
n->child->string = s;
|
||||
}
|
||||
|
||||
static void
|
||||
post_vs(CHKARGS)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* $OpenBSD$ */
|
||||
/* $Id: manconf.h,v 1.5 2017/07/01 09:47:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -47,3 +47,4 @@ struct manconf {
|
||||
void manconf_parse(struct manconf *, const char *, char *, char *);
|
||||
int manconf_output(struct manoutput *, const char *, int);
|
||||
void manconf_free(struct manconf *);
|
||||
void manpath_base(struct manpaths *);
|
||||
|
392
mandoc.1
392
mandoc.1
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.1,v 1.196 2017/06/08 00:23:30 schwarze Exp $
|
||||
.\" $Id: mandoc.1,v 1.217 2017/07/20 15:26:41 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012, 2014-2017 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: June 8 2017 $
|
||||
.Dd $Mdocdate: July 20 2017 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -75,11 +75,6 @@ and for the
|
||||
.Xr man 7
|
||||
.Ic \&TH
|
||||
macro.
|
||||
This can also be used to perform style checks according to the
|
||||
conventions of one operating system while running on a different
|
||||
operating system; see
|
||||
.Sx Style messages
|
||||
for details.
|
||||
.It Fl K Ar encoding
|
||||
Specify the input encoding.
|
||||
The supported
|
||||
@ -151,14 +146,33 @@ to be reported on the standard error output and to affect the exit status.
|
||||
The
|
||||
.Ar level
|
||||
can be
|
||||
.Cm base ,
|
||||
.Cm style ,
|
||||
.Cm warning ,
|
||||
.Cm error ,
|
||||
or
|
||||
.Cm unsupp ;
|
||||
.Cm unsupp .
|
||||
The
|
||||
.Cm base
|
||||
level automatically derives the operating system from the contents of the
|
||||
.Ic \&Os
|
||||
macro, from the
|
||||
.Fl Ios
|
||||
command line option, or from the
|
||||
.Xr uname 3
|
||||
return value.
|
||||
The levels
|
||||
.Cm openbsd
|
||||
and
|
||||
.Cm netbsd
|
||||
are variants of
|
||||
.Cm base
|
||||
that bypass autodetection and request validation of base system
|
||||
conventions for a particular operating system.
|
||||
The level
|
||||
.Cm all
|
||||
is an alias for
|
||||
.Cm style .
|
||||
.Cm base .
|
||||
By default,
|
||||
.Nm
|
||||
is silent.
|
||||
@ -224,7 +238,9 @@ See
|
||||
.It Fl T Cm lint
|
||||
Parse only: produce no output.
|
||||
Implies
|
||||
.Fl W Cm style .
|
||||
.Fl W Cm all
|
||||
and redirects parser messages, which usually appear
|
||||
on standard error output, to standard output.
|
||||
.It Fl T Cm locale
|
||||
Encode output using the current locale.
|
||||
This is the default.
|
||||
@ -301,8 +317,7 @@ Increasing this is not recommended; it may result in degraded formatting,
|
||||
for example overfull lines or ugly line breaks.
|
||||
.It Cm width Ns = Ns Ar width
|
||||
The output width is set to
|
||||
.Ar width ,
|
||||
which will normalise to \(>=58.
|
||||
.Ar width .
|
||||
.El
|
||||
.Ss HTML Output
|
||||
Output produced by
|
||||
@ -597,19 +612,23 @@ option:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It 0
|
||||
No style suggestions, warnings or errors occurred, or those that
|
||||
did were ignored because they were lower than the requested
|
||||
No base system convention violations, style suggestions, warnings,
|
||||
or errors occurred, or those that did were ignored because they
|
||||
were lower than the requested
|
||||
.Ar level .
|
||||
.It 1
|
||||
At least one style suggestion occurred, but no warning or error, and
|
||||
At least one base system convention violation or style suggestion
|
||||
occurred, but no warning or error, and
|
||||
.Fl W Cm base
|
||||
or
|
||||
.Fl W Cm style
|
||||
was specified.
|
||||
.It 2
|
||||
At least one warning occurred, but no error, and
|
||||
.Fl W Cm warning
|
||||
or
|
||||
.Fl W Cm style
|
||||
was specified.
|
||||
or a lower
|
||||
.Ar level
|
||||
was requested.
|
||||
.It 3
|
||||
At least one parsing error occurred,
|
||||
but no unsupported feature was encountered, and
|
||||
@ -637,7 +656,7 @@ to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
Note that selecting
|
||||
.Fl T Cm lint
|
||||
output mode implies
|
||||
.Fl W Cm style .
|
||||
.Fl W Cm all .
|
||||
.Sh EXAMPLES
|
||||
To page manuals to the terminal:
|
||||
.Pp
|
||||
@ -670,12 +689,19 @@ parser:
|
||||
Messages displayed by
|
||||
.Nm
|
||||
follow this format:
|
||||
.Pp
|
||||
.D1 Nm Ns : Ar file : Ns Ar line : Ns Ar column : level : message : macro args
|
||||
.Bd -ragged -offset indent
|
||||
.Nm :
|
||||
.Ar file : Ns Ar line : Ns Ar column : level : message : macro args
|
||||
.Pq Ar os
|
||||
.Ed
|
||||
.Pp
|
||||
Line and column numbers start at 1.
|
||||
Both are omitted for messages referring to an input file as a whole.
|
||||
Macro names and arguments are omitted where meaningless.
|
||||
The
|
||||
.Ar os
|
||||
operating system specifier is omitted for messages that are relevant
|
||||
for all operating systems.
|
||||
Fatal messages about invalid command line arguments
|
||||
or operating system errors, for example when memory is exhausted,
|
||||
may also omit the
|
||||
@ -695,32 +721,13 @@ so using GNU troff instead of
|
||||
.Nm
|
||||
to process the file may be preferable.
|
||||
.It Cm error
|
||||
An input file contains invalid syntax that cannot be safely interpreted.
|
||||
By discarding part of the input or inserting missing tokens,
|
||||
the parser is able to continue, and the error does not prevent
|
||||
generation of formatted output, but typically, preparing that
|
||||
output involves information loss, broken document structure
|
||||
or unintended formatting, no matter whether
|
||||
.Nm
|
||||
or GNU troff is used.
|
||||
In many cases, the output of
|
||||
.Nm
|
||||
and GNU troff is identical, but in some,
|
||||
.Nm
|
||||
is more resilient than GNU troff with respect to malformed input.
|
||||
.Pp
|
||||
Non-existent or unreadable input files are also reported on the
|
||||
.Cm error
|
||||
level.
|
||||
In that case, the parser cannot even be started and no output
|
||||
is produced from those input files.
|
||||
Indicates a risk of information loss or severe misformatting,
|
||||
in most cases caused by serious syntax errors.
|
||||
.It Cm warning
|
||||
An input file uses obsolete, discouraged or non-portable syntax.
|
||||
All the same, the meaning of the input is unambiguous and a correct
|
||||
rendering can be produced.
|
||||
Documents causing warnings may render poorly when using other
|
||||
formatting tools instead of
|
||||
.Nm .
|
||||
Indicates a risk that the information shown or its formatting
|
||||
may mismatch the author's intent in minor ways.
|
||||
Additionally, syntax errors are classified at least as warnings,
|
||||
even if they do not usually cause misformatting.
|
||||
.It Cm style
|
||||
An input file uses dubious or discouraged style.
|
||||
This is not a complaint about the syntax, and probably neither
|
||||
@ -733,9 +740,21 @@ so it may occasionally issue bogus suggestions.
|
||||
Please use your good judgement to decide whether any particular
|
||||
.Cm style
|
||||
suggestion really justifies a change to the input file.
|
||||
.It Cm base
|
||||
A convertion used in the base system of a specific operating system
|
||||
is not adhered to.
|
||||
These are not markup mistakes, and neither the quality of formatting
|
||||
nor portability are in danger.
|
||||
Messages of the
|
||||
.Cm base
|
||||
level are printed with the more intuitive
|
||||
.Cm style
|
||||
.Ar level
|
||||
tag.
|
||||
.El
|
||||
.Pp
|
||||
Messages of the
|
||||
.Cm base ,
|
||||
.Cm style ,
|
||||
.Cm warning ,
|
||||
.Cm error ,
|
||||
@ -747,9 +766,15 @@ are hidden unless their level, or a lower level, is requested using a
|
||||
option or
|
||||
.Fl T Cm lint
|
||||
output mode.
|
||||
.Ss Style messages
|
||||
As indicated below, some style checks are only performed if a
|
||||
specific operating system name occurs in the arguments of the
|
||||
.Pp
|
||||
As indicated below, all
|
||||
.Cm base
|
||||
and some
|
||||
.Cm style
|
||||
checks are only performed if a specific operating system name occurs
|
||||
in the arguments of the
|
||||
.Fl W
|
||||
command line option, of the
|
||||
.Ic \&Os
|
||||
macro, of the
|
||||
.Fl Ios
|
||||
@ -757,7 +782,98 @@ command line option, or, if neither are present, in the return value
|
||||
of the
|
||||
.Xr uname 3
|
||||
function.
|
||||
.Ss Conventions for base system manuals
|
||||
.Bl -ohang
|
||||
.It Sy "Mdocdate found"
|
||||
.Pq mdoc , Nx
|
||||
The
|
||||
.Ic \&Dd
|
||||
macro uses CVS
|
||||
.Ic Mdocdate
|
||||
keyword substitution, which is not supported by the
|
||||
.Nx
|
||||
base system.
|
||||
Consider using the conventional
|
||||
.Dq "Month dd, yyyy"
|
||||
format instead.
|
||||
.It Sy "Mdocdate missing"
|
||||
.Pq mdoc , Ox
|
||||
The
|
||||
.Ic \&Dd
|
||||
macro does not use CVS
|
||||
.Ic Mdocdate
|
||||
keyword substitution, but using it is conventionally expected in the
|
||||
.Ox
|
||||
base system.
|
||||
.It Sy "unknown architecture"
|
||||
.Pq mdoc , Ox , Nx
|
||||
The third argument of the
|
||||
.Ic \&Dt
|
||||
macro does not match any of the architectures this operating system
|
||||
is running on.
|
||||
.It Sy "operating system explicitly specified"
|
||||
.Pq mdoc , Ox , Nx
|
||||
The
|
||||
.Ic \&Os
|
||||
macro has an argument.
|
||||
In the base system, it is conventionally left blank.
|
||||
.It Sy "RCS id missing"
|
||||
.Pq Ox , Nx
|
||||
The manual page lacks the comment line with the RCS identifier
|
||||
generated by CVS
|
||||
.Ic OpenBSD
|
||||
or
|
||||
.Ic NetBSD
|
||||
keyword substitution as conventionally used in these operating systems.
|
||||
.It Sy "referenced manual not found"
|
||||
.Pq mdoc
|
||||
An
|
||||
.Ic \&Xr
|
||||
macro references a manual page that is not found in the base system.
|
||||
The path to look for base system manuals is configurable at compile
|
||||
time and defaults to
|
||||
.Pa /usr/share/man : /usr/X11R6/man .
|
||||
.El
|
||||
.Ss Style suggestions
|
||||
.Bl -ohang
|
||||
.It Sy "legacy man(7) date format"
|
||||
.Pq mdoc
|
||||
The
|
||||
.Ic \&Dd
|
||||
macro uses the legacy
|
||||
.Xr man 7
|
||||
date format
|
||||
.Dq yyyy-dd-mm .
|
||||
Consider using the conventional
|
||||
.Xr mdoc 7
|
||||
date format
|
||||
.Dq "Month dd, yyyy"
|
||||
instead.
|
||||
.It Sy "lower case character in document title"
|
||||
.Pq mdoc , man
|
||||
The title is still used as given in the
|
||||
.Ic \&Dt
|
||||
or
|
||||
.Ic \&TH
|
||||
macro.
|
||||
.It Sy "duplicate RCS id"
|
||||
A single manual page contains two copies of the RCS identifier for
|
||||
the same operating system.
|
||||
Consider deleting the later instance and moving the first one up
|
||||
to the top of the page.
|
||||
.It Sy "typo in section name"
|
||||
.Pq mdoc
|
||||
Fuzzy string matching revealed that the argument of an
|
||||
.Ic \&Sh
|
||||
macro is similar, but not identical to a standard section name.
|
||||
.It Sy "unterminated quoted argument"
|
||||
.Pq roff
|
||||
Macro arguments can be enclosed in double quote characters
|
||||
such that space characters and macro names contained in the quoted
|
||||
argument need not be escaped.
|
||||
The closing quote of the last argument of a macro can be omitted.
|
||||
However, omitting it is not recommended because it makes the code
|
||||
harder to read.
|
||||
.It Sy "useless macro"
|
||||
.Pq mdoc
|
||||
A
|
||||
@ -793,11 +909,55 @@ list contains two consecutive
|
||||
entries describing the same
|
||||
.Ic \&Er
|
||||
number.
|
||||
.It Sy "description line ends with a full stop"
|
||||
.It Sy "trailing delimiter"
|
||||
.Pq mdoc
|
||||
Do not use punctuation at the end of an
|
||||
.Ic \&Nd
|
||||
block.
|
||||
The last argument of an
|
||||
.Ic \&Ex , \&Fo , \&Nd , \&Nm , \&Os , \&Sh , \&Ss , \&St ,
|
||||
or
|
||||
.Ic \&Sx
|
||||
macro ends with a trailing delimiter.
|
||||
This is usually bad style and often indicates typos.
|
||||
Most likely, the delimiter can be removed.
|
||||
.It Sy "no blank before trailing delimiter"
|
||||
.Pq mdoc
|
||||
The last argument of a macro that supports trailing delimiter
|
||||
arguments is longer than one byte and ends with a trailing delimiter.
|
||||
Consider inserting a blank such that the delimiter becomes a separate
|
||||
argument, thus moving it out of the scope of the macro.
|
||||
.It Sy "fill mode already enabled, skipping"
|
||||
.Pq man
|
||||
A
|
||||
.Ic \&fi
|
||||
request occurs even though the document is still in fill mode,
|
||||
or already switched back to fill mode.
|
||||
It has no effect.
|
||||
.It Sy "fill mode already disabled, skipping"
|
||||
.Pq man
|
||||
An
|
||||
.Ic \&nf
|
||||
request occurs even though the document already switched to no-fill mode
|
||||
and did not switch back to fill mode yet.
|
||||
It has no effect.
|
||||
.It Sy "function name without markup"
|
||||
.Pq mdoc
|
||||
A word followed by an empty pair of parentheses occurs on a text line.
|
||||
Consider using an
|
||||
.Ic \&Fn
|
||||
or
|
||||
.Ic \&Xr
|
||||
macro.
|
||||
.It Sy "whitespace at end of input line"
|
||||
.Pq mdoc , man , roff
|
||||
Whitespace at the end of input lines is almost never semantically
|
||||
significant \(em but in the odd case where it might be, it is
|
||||
extremely confusing when reviewing and maintaining documents.
|
||||
.It Sy "bad comment style"
|
||||
.Pq roff
|
||||
Comment lines start with a dot, a backslash, and a double-quote character.
|
||||
The
|
||||
.Nm
|
||||
utility treats the line as a comment line even without the backslash,
|
||||
but leaving out the backslash might not be portable.
|
||||
.El
|
||||
.Ss Warnings related to the document prologue
|
||||
.Bl -ohang
|
||||
@ -813,13 +973,6 @@ macro before the first non-prologue macro.
|
||||
There is no
|
||||
.Ic \&TH
|
||||
macro, or it has no arguments.
|
||||
.It Sy "lower case character in document title"
|
||||
.Pq mdoc , man
|
||||
The title is still used as given in the
|
||||
.Ic \&Dt
|
||||
or
|
||||
.Ic \&TH
|
||||
macro.
|
||||
.It Sy "missing manual section, using \(dq\(dq"
|
||||
.Pq mdoc , man
|
||||
A
|
||||
@ -855,13 +1008,17 @@ The date given in a
|
||||
or
|
||||
.Ic \&TH
|
||||
macro does not follow the conventional format.
|
||||
.It Sy "date in the future, using it anyway"
|
||||
.Pq mdoc , man
|
||||
The date given in a
|
||||
.Ic \&Dd
|
||||
or
|
||||
.Ic \&TH
|
||||
macro is more than a day ahead of the current system
|
||||
.Xr time 3 .
|
||||
.It Sy "missing Os macro, using \(dq\(dq"
|
||||
.Pq mdoc
|
||||
The default or current system is not shown in this case.
|
||||
.It Sy "duplicate prologue macro"
|
||||
.Pq mdoc
|
||||
One of the prologue macros occurs more than once.
|
||||
The last instance overrides all previous ones.
|
||||
.It Sy "late prologue macro"
|
||||
.Pq mdoc
|
||||
A
|
||||
@ -869,17 +1026,6 @@ A
|
||||
or
|
||||
.Ic \&Os
|
||||
macro occurs after some non-prologue macro, but still takes effect.
|
||||
.It Sy "skipping late title macro"
|
||||
.Pq mdoc
|
||||
The
|
||||
.Ic \&Dt
|
||||
macro appears after the first non-prologue macro.
|
||||
Traditional formatters cannot handle this because
|
||||
they write the page header before parsing the document body.
|
||||
Even though this technical restriction does not apply to
|
||||
.Nm ,
|
||||
traditional semantics is preserved.
|
||||
The late macro is discarded including its arguments.
|
||||
.It Sy "prologue macros out of order"
|
||||
.Pq mdoc
|
||||
The prologue macros are not given in the conventional order
|
||||
@ -971,6 +1117,24 @@ The same standard section title occurs more than once.
|
||||
.Pq mdoc
|
||||
A standard section header occurs in a section of the manual
|
||||
where it normally isn't useful.
|
||||
.It Sy "cross reference to self"
|
||||
.Pq mdoc
|
||||
An
|
||||
.Ic \&Xr
|
||||
macro refers to a name and section matching the section of the present
|
||||
manual page and a name mentioned in an
|
||||
.Ic \&Nm
|
||||
macro in the NAME or SYNOPSIS section, or in an
|
||||
.Ic \&Fn
|
||||
or
|
||||
.Ic \&Fo
|
||||
macro in the SYNOPSIS.
|
||||
Consider using
|
||||
.Ic \&Nm
|
||||
or
|
||||
.Ic \&Fn
|
||||
instead of
|
||||
.Ic \&Xr .
|
||||
.It Sy "unusual Xr order"
|
||||
.Pq mdoc
|
||||
In the SEE ALSO section, an
|
||||
@ -1057,7 +1221,9 @@ The paragraph macro is moved after the end of the list.
|
||||
.Pq mdoc
|
||||
An input line begins with an
|
||||
.Ic \&Ns
|
||||
macro.
|
||||
macro, or the next argument after an
|
||||
.Ic \&Ns
|
||||
macro is an isolated closing delimiter.
|
||||
The macro is ignored.
|
||||
.It Sy "blocks badly nested"
|
||||
.Pq mdoc
|
||||
@ -1098,20 +1264,12 @@ list block contains text or macros before the first
|
||||
.Ic \&It
|
||||
macro.
|
||||
The offending children are moved before the beginning of the list.
|
||||
.It Sy "fill mode already enabled, skipping"
|
||||
.Pq man
|
||||
A
|
||||
.Ic \&fi
|
||||
request occurs even though the document is still in fill mode,
|
||||
or already switched back to fill mode.
|
||||
It has no effect.
|
||||
.It Sy "fill mode already disabled, skipping"
|
||||
.Pq man
|
||||
An
|
||||
.Ic \&nf
|
||||
request occurs even though the document already switched to no-fill mode
|
||||
and did not switch back to fill mode yet.
|
||||
It has no effect.
|
||||
.It Sy "first macro on line"
|
||||
Inside a
|
||||
.Ic \&Bl Fl column
|
||||
list, a
|
||||
.Ic \&Ta
|
||||
macro occurs as the first macro on a line, which is not portable.
|
||||
.It Sy "line scope broken"
|
||||
.Pq man
|
||||
While parsing the next-line scope of the previous macro,
|
||||
@ -1165,6 +1323,7 @@ A
|
||||
.Ic \&Bl ,
|
||||
.Ic \&D1 ,
|
||||
.Ic \&Dl ,
|
||||
.Ic \&MT ,
|
||||
.Ic \&RS ,
|
||||
or
|
||||
.Ic \&UR
|
||||
@ -1242,6 +1401,17 @@ list, an
|
||||
.Ic \&It
|
||||
block is empty.
|
||||
An empty list item is shown.
|
||||
.It Sy "missing argument, using next line"
|
||||
.Pq mdoc
|
||||
An
|
||||
.Ic \&It
|
||||
macro in a
|
||||
.Ic \&Bd Fl column
|
||||
list has no arguments.
|
||||
While
|
||||
.Nm
|
||||
uses the text or macros of the following line, if any, for the cell,
|
||||
other formatters may misformat the list.
|
||||
.It Sy "missing font type, using \efR"
|
||||
.Pq mdoc
|
||||
A
|
||||
@ -1300,6 +1470,8 @@ An empty pair of square brackets is shown.
|
||||
.It Sy "missing resource identifier, using \(dq\(dq"
|
||||
.Pq man
|
||||
The
|
||||
.Ic \&MT
|
||||
or
|
||||
.Ic \&UR
|
||||
macro is invoked without any argument.
|
||||
An empty pair of angle brackets is shown.
|
||||
@ -1311,14 +1483,6 @@ An empty box is inserted.
|
||||
.El
|
||||
.Ss "Warnings related to bad macro arguments"
|
||||
.Bl -ohang
|
||||
.It Sy "unterminated quoted argument"
|
||||
.Pq roff
|
||||
Macro arguments can be enclosed in double quote characters
|
||||
such that space characters and macro names contained in the quoted
|
||||
argument need not be escaped.
|
||||
The closing quote of the last argument of a macro can be omitted.
|
||||
However, omitting it is not recommended because it makes the code
|
||||
harder to read.
|
||||
.It Sy "duplicate argument"
|
||||
.Pq mdoc
|
||||
A
|
||||
@ -1460,22 +1624,10 @@ As an implementation dependent choice, tab characters on text lines
|
||||
are passed through to the formatters in any case.
|
||||
Given that the text before the tab character will be filled,
|
||||
it is hard to predict which tab stop position the tab will advance to.
|
||||
.It Sy "whitespace at end of input line"
|
||||
.Pq mdoc , man , roff
|
||||
Whitespace at the end of input lines is almost never semantically
|
||||
significant \(em but in the odd case where it might be, it is
|
||||
extremely confusing when reviewing and maintaining documents.
|
||||
.It Sy "new sentence, new line"
|
||||
.Pq mdoc
|
||||
A new sentence starts in the middle of a text line.
|
||||
Start it on a new input line to help formatters produce correct spacing.
|
||||
.It Sy "bad comment style"
|
||||
.Pq roff
|
||||
Comment lines start with a dot, a backslash, and a double-quote character.
|
||||
The
|
||||
.Nm
|
||||
utility treats the line as a comment line even without the backslash,
|
||||
but leaving out the backslash might not be portable.
|
||||
.It Sy "invalid escape sequence"
|
||||
.Pq roff
|
||||
An escape sequence has an invalid opening argument delimiter, lacks the
|
||||
@ -1582,6 +1734,21 @@ and any remaining cells stay empty.
|
||||
.El
|
||||
.Ss "Errors related to roff, mdoc, and man code"
|
||||
.Bl -ohang
|
||||
.It Sy "duplicate prologue macro"
|
||||
.Pq mdoc
|
||||
One of the prologue macros occurs more than once.
|
||||
The last instance overrides all previous ones.
|
||||
.It Sy "skipping late title macro"
|
||||
.Pq mdoc
|
||||
The
|
||||
.Ic \&Dt
|
||||
macro appears after the first non-prologue macro.
|
||||
Traditional formatters cannot handle this because
|
||||
they write the page header before parsing the document body.
|
||||
Even though this technical restriction does not apply to
|
||||
.Nm ,
|
||||
traditional semantics is preserved.
|
||||
The late macro is discarded including its arguments.
|
||||
.It Sy "input stack limit exceeded, infinite loop?"
|
||||
.Pq roff
|
||||
Explicit recursion limits are implemented for the following features,
|
||||
@ -1652,7 +1819,7 @@ An
|
||||
.Xr mdoc 7
|
||||
block closing macro, a
|
||||
.Xr man 7
|
||||
.Ic \&RE
|
||||
.Ic \&ME , \&RE
|
||||
or
|
||||
.Ic \&UE
|
||||
macro, an
|
||||
@ -1686,7 +1853,7 @@ At the end of the document, an explicit
|
||||
block, a
|
||||
.Xr man 7
|
||||
next-line scope or
|
||||
.Ic \&RS
|
||||
.Ic \&MT , \&RS
|
||||
or
|
||||
.Ic \&UR
|
||||
block, an equation, table, or
|
||||
@ -1858,6 +2025,7 @@ A macro or request is invoked with too many arguments:
|
||||
.Bl -dash -offset 2n -width 2n -compact
|
||||
.It
|
||||
.Ic \&Fo ,
|
||||
.Ic \&MT ,
|
||||
.Ic \&PD ,
|
||||
.Ic \&RS ,
|
||||
.Ic \&UR ,
|
||||
|
39
mandoc.3
39
mandoc.3
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.3,v 1.39 2017/05/17 23:39:31 schwarze Exp $
|
||||
.\" $Id: mandoc.3,v 1.41 2017/07/04 23:40:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010-2017 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: May 17 2017 $
|
||||
.Dd $Mdocdate: July 4 2017 $
|
||||
.Dt MANDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -35,7 +35,7 @@
|
||||
.Nm mparse_result ,
|
||||
.Nm mparse_strerror ,
|
||||
.Nm mparse_strlevel ,
|
||||
.Nm mparse_updaterc
|
||||
.Nm mparse_updaterc
|
||||
.Nd mandoc macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
@ -47,9 +47,10 @@
|
||||
.Ft struct mparse *
|
||||
.Fo mparse_alloc
|
||||
.Fa "int options"
|
||||
.Fa "enum mandoclevel wlevel"
|
||||
.Fa "enum mandocerr mmin"
|
||||
.Fa "mandocmsg mmsg"
|
||||
.Fa "char *defos"
|
||||
.Fa "enum mandoc_os oe_e"
|
||||
.Fa "char *os_s"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo (*mandocmsg)
|
||||
@ -304,12 +305,15 @@ This is for example useful in
|
||||
.Xr makewhatis 8
|
||||
.Fl Q
|
||||
to quickly build minimal databases.
|
||||
.It Ar wlevel
|
||||
.It Ar mmin
|
||||
Can be set to
|
||||
.Dv MANDOCLEVEL_BADARG ,
|
||||
.Dv MANDOCLEVEL_ERROR ,
|
||||
.Dv MANDOCERR_BASE ,
|
||||
.Dv MANDOCERR_STYLE ,
|
||||
.Dv MANDOCERR_WARNING ,
|
||||
.Dv MANDOCERR_ERROR ,
|
||||
.Dv MANDOCERR_UNSUPP ,
|
||||
or
|
||||
.Dv MANDOCLEVEL_WARNING .
|
||||
.Dv MANDOCERR_MAX .
|
||||
Messages below the selected level will be suppressed.
|
||||
.It Ar mmsg
|
||||
A callback function to handle errors and warnings.
|
||||
@ -319,10 +323,19 @@ for an example.
|
||||
If printing of error messages is not desired,
|
||||
.Dv NULL
|
||||
may be passed.
|
||||
.It Ar defos
|
||||
.It Ar os_e
|
||||
Operating system to check base system conventions for.
|
||||
If
|
||||
.Dv MANDOC_OS_OTHER ,
|
||||
the system is automatically detected from
|
||||
.Ic \&Os ,
|
||||
.Fl Ios ,
|
||||
or
|
||||
.Xr uname 3 .
|
||||
.It Ar os_s
|
||||
A default string for the
|
||||
.Xr mdoc 7
|
||||
.Sq \&Os
|
||||
.Ic \&Os
|
||||
macro, overriding the
|
||||
.Dv OSNAME
|
||||
preprocessor definition and the results of
|
||||
@ -650,10 +663,10 @@ TEXT end
|
||||
.Ed
|
||||
.Pp
|
||||
Here, the formatting of the
|
||||
.Sq \&Ao
|
||||
.Ic \&Ao
|
||||
block extends from TEXT ao to TEXT ac,
|
||||
while the formatting of the
|
||||
.Sq \&Bo
|
||||
.Ic \&Bo
|
||||
block extends from TEXT bo to TEXT bc.
|
||||
It renders as follows in
|
||||
.Fl T Ns Cm ascii
|
||||
|
32
mandoc.c
32
mandoc.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.c,v 1.100 2017/06/02 19:21:23 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.103 2017/07/03 13:40:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -28,8 +28,9 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
static int a2time(time_t *, const char *, const char *);
|
||||
@ -95,6 +96,8 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
case ',':
|
||||
case '/':
|
||||
return ESCAPE_IGNORE;
|
||||
case 'p':
|
||||
return ESCAPE_BREAK;
|
||||
|
||||
/*
|
||||
* The \z escape is supposed to output the following
|
||||
@ -518,27 +521,38 @@ time2a(time_t t)
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
|
||||
mandoc_normdate(struct roff_man *man, char *in, int ln, int pos)
|
||||
{
|
||||
char *cp;
|
||||
time_t t;
|
||||
|
||||
/* No date specified: use today's date. */
|
||||
|
||||
if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0) {
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, parse, ln, pos, NULL);
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, man->parse, ln, pos, NULL);
|
||||
return time2a(time(NULL));
|
||||
}
|
||||
|
||||
/* Valid mdoc(7) date format. */
|
||||
|
||||
if (a2time(&t, "$" "Mdocdate: %b %d %Y $", in) ||
|
||||
a2time(&t, "%b %d, %Y", in))
|
||||
return time2a(t);
|
||||
a2time(&t, "%b %d, %Y", in)) {
|
||||
cp = time2a(t);
|
||||
if (t > time(NULL) + 86400)
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, man->parse,
|
||||
ln, pos, cp);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* Do not warn about the legacy man(7) format. */
|
||||
/* In man(7), do not warn about the legacy format. */
|
||||
|
||||
if ( ! a2time(&t, "%Y-%m-%d", in))
|
||||
mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, in);
|
||||
if (a2time(&t, "%Y-%m-%d", in) == 0)
|
||||
mandoc_msg(MANDOCERR_DATE_BAD, man->parse, ln, pos, in);
|
||||
else if (t > time(NULL) + 86400)
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, man->parse, ln, pos, in);
|
||||
else if (man->macroset == MACROSET_MDOC)
|
||||
mandoc_vmsg(MANDOCERR_DATE_LEGACY, man->parse,
|
||||
ln, pos, "Dd %s", in);
|
||||
|
||||
/* Use any non-mdoc(7) date verbatim. */
|
||||
|
||||
|
25
mandoc.css
25
mandoc.css
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.css,v 1.18 2017/03/13 20:22:18 schwarze Exp $ */
|
||||
/* $Id: mandoc.css,v 1.22 2017/07/16 18:45:00 schwarze Exp $ */
|
||||
/*
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*/
|
||||
@ -18,6 +18,7 @@ a.selflink { border-bottom: thin dotted;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
text-decoration: inherit; }
|
||||
* { clear: both }
|
||||
|
||||
/* Search form and search results. */
|
||||
|
||||
@ -79,39 +80,47 @@ li.It-dash:before {
|
||||
ul.Bl-item { list-style-type: none;
|
||||
padding-left: 0em; }
|
||||
li.It-item { }
|
||||
ul.Bl-compact > li {
|
||||
margin-top: 0ex; }
|
||||
|
||||
ol.Bl-enum { padding-left: 2em; }
|
||||
li.It-enum { }
|
||||
ol.Bl-compact > li {
|
||||
margin-top: 0ex; }
|
||||
|
||||
dl.Bl-diag { }
|
||||
dt.It-diag { }
|
||||
dd.It-diag { }
|
||||
dd.It-diag { margin-left: 0ex; }
|
||||
b.It-diag { font-style: normal; }
|
||||
dl.Bl-hang { }
|
||||
dt.It-hang { }
|
||||
dd.It-hang { }
|
||||
dd.It-hang { margin-left: 10.2ex; }
|
||||
dl.Bl-inset { }
|
||||
dt.It-inset { }
|
||||
dd.It-inset { }
|
||||
dd.It-inset { margin-left: 0ex; }
|
||||
dl.Bl-ohang { }
|
||||
dt.It-ohang { }
|
||||
dd.It-ohang { margin-left: 0ex; }
|
||||
dl.Bl-tag { margin-left: 8ex; }
|
||||
dl.Bl-tag { margin-left: 10.2ex; }
|
||||
dt.It-tag { float: left;
|
||||
clear: both;
|
||||
margin-top: 0ex;
|
||||
margin-left: -8ex;
|
||||
margin-left: -10.2ex;
|
||||
padding-right: 2ex;
|
||||
vertical-align: top; }
|
||||
dd.It-tag { width: 100%;
|
||||
dd.It-tag { clear: right;
|
||||
width: 100%;
|
||||
margin-top: 0ex;
|
||||
margin-left: 0ex;
|
||||
vertical-align: top;
|
||||
overflow: auto; }
|
||||
dl.Bl-compact > dt {
|
||||
margin-top: 0ex; }
|
||||
|
||||
table.Bl-column { }
|
||||
tr.It-column { }
|
||||
td.It-column { margin-top: 1em; }
|
||||
table.Bl-compact > tbody > tr > td {
|
||||
margin-top: 0ex; }
|
||||
|
||||
cite.Rs { font-style: normal;
|
||||
font-weight: normal; }
|
||||
|
61
mandoc.h
61
mandoc.h
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.h,v 1.226 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.245 2017/07/08 14:51:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -44,28 +44,46 @@ enum mandoclevel {
|
||||
enum mandocerr {
|
||||
MANDOCERR_OK,
|
||||
|
||||
MANDOCERR_BASE, /* ===== start of base system conventions ===== */
|
||||
|
||||
MANDOCERR_MDOCDATE, /* Mdocdate found: Dd ... */
|
||||
MANDOCERR_MDOCDATE_MISSING, /* Mdocdate missing: Dd ... */
|
||||
MANDOCERR_ARCH_BAD, /* unknown architecture: Dt ... arch */
|
||||
MANDOCERR_OS_ARG, /* operating system explicitly specified: Os ... */
|
||||
MANDOCERR_RCS_MISSING, /* RCS id missing */
|
||||
MANDOCERR_XR_BAD, /* referenced manual not found: Xr name sec */
|
||||
|
||||
MANDOCERR_STYLE, /* ===== start of style suggestions ===== */
|
||||
|
||||
MANDOCERR_DATE_LEGACY, /* legacy man(7) date format: Dd ... */
|
||||
MANDOCERR_TITLE_CASE, /* lower case character in document title */
|
||||
MANDOCERR_RCS_REP, /* duplicate RCS id: ... */
|
||||
MANDOCERR_SEC_TYPO, /* typo in section name: Sh ... */
|
||||
MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */
|
||||
MANDOCERR_MACRO_USELESS, /* useless macro: macro */
|
||||
MANDOCERR_BX, /* consider using OS macro: macro */
|
||||
MANDOCERR_ER_ORDER, /* errnos out of order: Er ... */
|
||||
MANDOCERR_ER_REP, /* duplicate errno: Er ... */
|
||||
MANDOCERR_ND_DOT, /* description line ends with a full stop */
|
||||
MANDOCERR_DELIM, /* trailing delimiter: macro ... */
|
||||
MANDOCERR_DELIM_NB, /* no blank before trailing delimiter: macro ... */
|
||||
MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */
|
||||
MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */
|
||||
MANDOCERR_FUNC, /* function name without markup: name() */
|
||||
MANDOCERR_SPACE_EOL, /* whitespace at end of input line */
|
||||
MANDOCERR_COMMENT_BAD, /* bad comment style */
|
||||
|
||||
MANDOCERR_WARNING, /* ===== start of warnings ===== */
|
||||
|
||||
/* related to the prologue */
|
||||
MANDOCERR_DT_NOTITLE, /* missing manual title, using UNTITLED: line */
|
||||
MANDOCERR_TH_NOTITLE, /* missing manual title, using "": [macro] */
|
||||
MANDOCERR_TITLE_CASE, /* lower case character in document title */
|
||||
MANDOCERR_MSEC_MISSING, /* missing manual section, using "": macro */
|
||||
MANDOCERR_MSEC_BAD, /* unknown manual section: Dt ... section */
|
||||
MANDOCERR_DATE_MISSING, /* missing date, using today's date */
|
||||
MANDOCERR_DATE_BAD, /* cannot parse date, using it verbatim: date */
|
||||
MANDOCERR_DATE_FUTURE, /* date in the future, using it anyway: date */
|
||||
MANDOCERR_OS_MISSING, /* missing Os macro, using "" */
|
||||
MANDOCERR_PROLOG_REP, /* duplicate prologue macro: macro */
|
||||
MANDOCERR_PROLOG_LATE, /* late prologue macro: macro */
|
||||
MANDOCERR_DT_LATE, /* skipping late title macro: Dt args */
|
||||
MANDOCERR_PROLOG_ORDER, /* prologue macros out of order: macros */
|
||||
|
||||
/* related to document structure */
|
||||
@ -83,6 +101,7 @@ enum mandocerr {
|
||||
MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
|
||||
MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
|
||||
MANDOCERR_SEC_MSEC, /* unexpected section: Sh title for ... only */
|
||||
MANDOCERR_XR_SELF, /* cross reference to self: Xr name sec */
|
||||
MANDOCERR_XR_ORDER, /* unusual Xr order: ... after ... */
|
||||
MANDOCERR_XR_PUNCT, /* unusual Xr punctuation: ... after ... */
|
||||
MANDOCERR_AN_MISSING, /* AUTHORS section without An macro */
|
||||
@ -96,8 +115,7 @@ enum mandocerr {
|
||||
MANDOCERR_BLK_NEST, /* blocks badly nested: macro ... */
|
||||
MANDOCERR_BD_NEST, /* nested displays are not portable: macro ... */
|
||||
MANDOCERR_BL_MOVE, /* moving content out of list: macro */
|
||||
MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */
|
||||
MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */
|
||||
MANDOCERR_TA_LINE, /* first macro on line: Ta */
|
||||
MANDOCERR_BLK_LINE, /* line scope broken: macro breaks macro */
|
||||
MANDOCERR_BLK_BLANK, /* skipping blank line in line scope */
|
||||
|
||||
@ -114,6 +132,7 @@ enum mandocerr {
|
||||
MANDOCERR_FO_NOHEAD, /* missing function name, using "": Fo */
|
||||
MANDOCERR_IT_NOHEAD, /* empty head in list item: Bl -type It */
|
||||
MANDOCERR_IT_NOBODY, /* empty list item: Bl -type It */
|
||||
MANDOCERR_IT_NOARG, /* missing argument, using next line: Bl -c 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 */
|
||||
@ -125,7 +144,6 @@ enum mandocerr {
|
||||
MANDOCERR_EQN_NOBOX, /* missing eqn box, using "": op */
|
||||
|
||||
/* related to bad arguments */
|
||||
MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */
|
||||
MANDOCERR_ARG_REP, /* duplicate argument: macro arg */
|
||||
MANDOCERR_AN_REP, /* skipping duplicate argument: An -arg */
|
||||
MANDOCERR_BD_REP, /* skipping duplicate display type: Bd -type */
|
||||
@ -144,9 +162,7 @@ enum mandocerr {
|
||||
/* related to plain text */
|
||||
MANDOCERR_FI_BLANK, /* blank line in fill mode, using .sp */
|
||||
MANDOCERR_FI_TAB, /* tab in filled text */
|
||||
MANDOCERR_SPACE_EOL, /* whitespace at end of input line */
|
||||
MANDOCERR_EOS, /* new sentence, new line */
|
||||
MANDOCERR_COMMENT_BAD, /* bad comment style */
|
||||
MANDOCERR_ESC_BAD, /* invalid escape sequence: esc */
|
||||
MANDOCERR_STR_UNDEF, /* undefined string, using "": name */
|
||||
|
||||
@ -172,6 +188,8 @@ enum mandocerr {
|
||||
|
||||
/* related to document structure and macros */
|
||||
MANDOCERR_FILE, /* cannot open file */
|
||||
MANDOCERR_PROLOG_REP, /* duplicate prologue macro: macro */
|
||||
MANDOCERR_DT_LATE, /* skipping late title macro: Dt args */
|
||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||
MANDOCERR_CHAR_BAD, /* skipping bad character: number */
|
||||
MANDOCERR_MACRO, /* skipping unknown macro: macro */
|
||||
@ -316,11 +334,9 @@ struct tbl_span {
|
||||
};
|
||||
|
||||
enum eqn_boxt {
|
||||
EQN_ROOT, /* root of parse tree */
|
||||
EQN_TEXT, /* text (number, variable, whatever) */
|
||||
EQN_SUBEXPR, /* nested `eqn' subexpression */
|
||||
EQN_LIST, /* list (braces, etc.) */
|
||||
EQN_LISTONE, /* singleton list */
|
||||
EQN_PILE, /* vertical pile */
|
||||
EQN_MATRIX /* pile of piles */
|
||||
};
|
||||
@ -385,17 +401,6 @@ struct eqn_box {
|
||||
enum eqn_pilet pile; /* equation piling */
|
||||
};
|
||||
|
||||
/*
|
||||
* An equation consists of a tree of expressions starting at a given
|
||||
* line and position.
|
||||
*/
|
||||
struct eqn {
|
||||
char *name; /* identifier (or NULL) */
|
||||
struct eqn_box *root; /* root mathematical expression */
|
||||
int ln; /* invocation line */
|
||||
int pos; /* invocation position */
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse options.
|
||||
*/
|
||||
@ -406,6 +411,12 @@ struct eqn {
|
||||
#define MPARSE_UTF8 16 /* accept UTF-8 input */
|
||||
#define MPARSE_LATIN1 32 /* accept ISO-LATIN-1 input */
|
||||
|
||||
enum mandoc_os {
|
||||
MANDOC_OS_OTHER = 0,
|
||||
MANDOC_OS_NETBSD,
|
||||
MANDOC_OS_OPENBSD
|
||||
};
|
||||
|
||||
enum mandoc_esc {
|
||||
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
||||
ESCAPE_IGNORE, /* escape to be ignored */
|
||||
@ -418,6 +429,7 @@ enum mandoc_esc {
|
||||
ESCAPE_FONTPREV, /* previous font mode */
|
||||
ESCAPE_NUMBERED, /* a numbered glyph */
|
||||
ESCAPE_UNICODE, /* a unicode codepoint */
|
||||
ESCAPE_BREAK, /* break the output line */
|
||||
ESCAPE_NOSPACE, /* suppress space if the last on a line */
|
||||
ESCAPE_HORIZ, /* horizontal movement */
|
||||
ESCAPE_HLINE, /* horizontal line drawing */
|
||||
@ -440,7 +452,8 @@ const char *mchars_uc2str(int);
|
||||
int mchars_num2uc(const char *, size_t);
|
||||
int mchars_spec2cp(const char *, size_t);
|
||||
const char *mchars_spec2str(const char *, size_t, size_t *);
|
||||
struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg, const char *);
|
||||
struct mparse *mparse_alloc(int, enum mandocerr, mandocmsg,
|
||||
enum mandoc_os, const char *);
|
||||
void mparse_free(struct mparse *);
|
||||
void mparse_keep(struct mparse *);
|
||||
int mparse_open(struct mparse *, const char *);
|
||||
|
15
mandoc_aux.c
15
mandoc_aux.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc_aux.c,v 1.9 2015/11/07 14:22:29 schwarze Exp $ */
|
||||
/* $Id: mandoc_aux.c,v 1.10 2017/06/12 19:05:47 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -71,7 +71,6 @@ mandoc_malloc(size_t size)
|
||||
void *
|
||||
mandoc_realloc(void *ptr, size_t size)
|
||||
{
|
||||
|
||||
ptr = realloc(ptr, size);
|
||||
if (ptr == NULL)
|
||||
err((int)MANDOCLEVEL_SYSERR, NULL);
|
||||
@ -81,13 +80,21 @@ mandoc_realloc(void *ptr, size_t size)
|
||||
void *
|
||||
mandoc_reallocarray(void *ptr, size_t num, size_t size)
|
||||
{
|
||||
|
||||
ptr = reallocarray(ptr, num, size);
|
||||
if (ptr == NULL)
|
||||
err((int)MANDOCLEVEL_SYSERR, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_recallocarray(void *ptr, size_t oldnum, size_t num, size_t size)
|
||||
{
|
||||
ptr = recallocarray(ptr, oldnum, num, size);
|
||||
if (ptr == NULL)
|
||||
err((int)MANDOCLEVEL_SYSERR, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_strdup(const char *ptr)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc_aux.h,v 1.6 2017/02/17 14:31:52 schwarze Exp $ */
|
||||
/* $Id: mandoc_aux.h,v 1.7 2017/06/12 19:05:47 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -22,5 +22,6 @@ void *mandoc_calloc(size_t, size_t);
|
||||
void *mandoc_malloc(size_t);
|
||||
void *mandoc_realloc(void *, size_t);
|
||||
void *mandoc_reallocarray(void *, size_t, size_t);
|
||||
void *mandoc_recallocarray(void *, size_t, size_t, size_t);
|
||||
char *mandoc_strdup(const char *);
|
||||
char *mandoc_strndup(const char *, size_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_char.7,v 1.66 2017/06/02 12:43:52 schwarze Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.67 2017/06/14 20:57:07 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: June 2 2017 $
|
||||
.Dd $Mdocdate: June 14 2017 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -260,6 +260,7 @@ Lines:
|
||||
.It \e(ba Ta \(ba Ta bar
|
||||
.It \e(br Ta \(br Ta box rule
|
||||
.It \e(ul Ta \(ul Ta underscore
|
||||
.It \e(ru Ta \(ru Ta underscore (width 0.5m)
|
||||
.It \e(rn Ta \(rn Ta overline
|
||||
.It \e(bb Ta \(bb Ta broken bar
|
||||
.It \e(sl Ta \(sl Ta forward slash
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_escape.3,v 1.3 2015/01/21 20:33:25 schwarze Exp $
|
||||
.\" $Id: mandoc_escape.3,v 1.4 2017/07/04 23:40:01 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: January 21 2015 $
|
||||
.Dd $Mdocdate: July 4 2017 $
|
||||
.Dt MANDOC_ESCAPE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -122,7 +122,7 @@ library, see the file
|
||||
.Pa roff.c ,
|
||||
.It
|
||||
above all externally by the
|
||||
.Xr mandoc
|
||||
.Xr mandoc 1
|
||||
formatting modules, in particular
|
||||
.Fl Tascii
|
||||
and
|
||||
|
@ -1,4 +1,4 @@
|
||||
.Dd December 1, 2014
|
||||
.Dd $Mdocdate: July 8 2017 $
|
||||
.Dt MANDOC_HEADERS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -87,6 +87,7 @@ Provides
|
||||
.Vt enum mandoc_esc ,
|
||||
.Vt enum mandocerr ,
|
||||
.Vt enum mandoclevel ,
|
||||
.Vt enum mandoc_os ,
|
||||
.Vt enum tbl_cellt ,
|
||||
.Vt enum tbl_datt ,
|
||||
.Vt enum tbl_spant ,
|
||||
@ -100,7 +101,6 @@ Provides
|
||||
.Vt struct tbl_dat ,
|
||||
.Vt struct tbl_span ,
|
||||
.Vt struct eqn_box ,
|
||||
.Vt struct eqn ,
|
||||
the function prototype typedef
|
||||
.Fn mandocmsg ,
|
||||
the function
|
||||
@ -122,11 +122,24 @@ Uses the type
|
||||
from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa mandoc_xr.h
|
||||
Provides
|
||||
.Vt struct mandoc_xr
|
||||
and the functions
|
||||
.Fn mandoc_xr_reset ,
|
||||
.Fn mandoc_xr_add ,
|
||||
.Fn mandoc_xr_get ,
|
||||
and
|
||||
.Fn mandoc_xr_free .
|
||||
.It Qq Pa roff.h
|
||||
Requires
|
||||
.Qq Pa mandoc_ohash.h
|
||||
for
|
||||
.Vt struct ohash .
|
||||
.Vt struct ohash
|
||||
and
|
||||
.Qq Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandoc_os .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum mdoc_endbody ,
|
||||
@ -251,17 +264,11 @@ and
|
||||
from
|
||||
.Pa roff.c
|
||||
for function prototypes.
|
||||
Uses the types
|
||||
.Vt struct tbl_span
|
||||
and
|
||||
.Vt struct eqn
|
||||
from
|
||||
.Pa mandoc.h
|
||||
and
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff.h
|
||||
as opaque types for function prototypes.
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa roff_int.h
|
||||
Requires
|
||||
.Qq Pa roff.h
|
||||
@ -278,16 +285,11 @@ because the latter two are needed by
|
||||
.Qq Pa roff.c .
|
||||
.Pp
|
||||
Uses the types
|
||||
.Vt struct eqn
|
||||
and
|
||||
.Vt struct tbl_span
|
||||
from
|
||||
.Pa mandoc.h ,
|
||||
.Vt struct roff_man
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h ,
|
||||
.Pa roff.h
|
||||
and
|
||||
.Vt struct mdoc_arg
|
||||
from
|
||||
@ -359,16 +361,13 @@ or
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t ,
|
||||
.Vt size_t
|
||||
and
|
||||
.Qq Pa mandoc.h
|
||||
for
|
||||
.Vt struct tbl_*
|
||||
and
|
||||
.Vt struct eqn ,
|
||||
and
|
||||
.Qq Pa libmandoc.h
|
||||
for
|
||||
.Vt enum rofferr .
|
||||
.Vt struct eqn_box .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum tbl_part ,
|
||||
@ -448,7 +447,7 @@ from
|
||||
Uses
|
||||
.Vt struct tbl_span
|
||||
and
|
||||
.Vt struct eqn
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa mandoc.h
|
||||
and
|
||||
@ -489,7 +488,7 @@ and many HTML formatting functions.
|
||||
Uses
|
||||
.Vt struct tbl_span
|
||||
and
|
||||
.Vt struct eqn
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa mandoc.h
|
||||
and
|
||||
@ -535,8 +534,9 @@ Provides
|
||||
and the functions
|
||||
.Fn manconf_parse ,
|
||||
.Fn manconf_output ,
|
||||
.Fn manconf_free ,
|
||||
and
|
||||
.Fn manconf_free .
|
||||
.Fn manpath_base .
|
||||
.It Qq Pa mansearch.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_html.3,v 1.8 2017/05/12 17:58:21 schwarze Exp $
|
||||
.\" $Id: mandoc_html.3,v 1.10 2017/07/15 17:57:51 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2017 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: May 12 2017 $
|
||||
.Dd $Mdocdate: July 15 2017 $
|
||||
.Dt MANDOC_HTML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -219,11 +219,6 @@ argument, used as a style value.
|
||||
Requires one
|
||||
.Vt struct roffsu *
|
||||
argument, used as a length.
|
||||
.It Cm v
|
||||
Requires one
|
||||
.Vt int
|
||||
argument, interpreted as a vertical length in units of
|
||||
.Dv SCALE_VS .
|
||||
.It Cm w
|
||||
Requires one
|
||||
.Vt char *
|
||||
@ -236,12 +231,15 @@ nothing is printed for this pair.
|
||||
.Pp
|
||||
The
|
||||
.Cm w
|
||||
argument type letter can optionally be followed by one or two
|
||||
argument type letter can optionally be followed by one, two, or three
|
||||
modifier letters.
|
||||
The modifier
|
||||
.Cm *
|
||||
suppresses printing of the pair if the argument matches 6n.
|
||||
The modifier
|
||||
.Cm +
|
||||
increases the width by 10% to make even bold text fit
|
||||
and adds two units for padding between columns.
|
||||
increases the width by 20% to make even bold text fit
|
||||
and adds three units for padding between columns.
|
||||
The modifier
|
||||
.Cm \-
|
||||
makes the width negative by multiplying it with \-1.
|
||||
@ -249,10 +247,6 @@ makes the width negative by multiplying it with \-1.
|
||||
.Pp
|
||||
Style name letters decide what to do with the preceding argument:
|
||||
.Bl -tag -width 1n -offset indent
|
||||
.It Cm b
|
||||
Set
|
||||
.Cm margin-bottom
|
||||
to the given length.
|
||||
.It Cm h
|
||||
Set
|
||||
.Cm height
|
||||
@ -265,10 +259,6 @@ to the given length.
|
||||
Set
|
||||
.Cm margin-left
|
||||
to the given length.
|
||||
.It Cm t
|
||||
Set
|
||||
.Cm margin-top
|
||||
to the given length.
|
||||
.It Cm w
|
||||
Set
|
||||
.Cm width
|
||||
|
121
mandoc_xr.c
Normal file
121
mandoc_xr.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* $Id: mandoc_xr.c,v 1.3 2017/07/02 21:18:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "mandoc_xr.h"
|
||||
|
||||
static struct ohash *xr_hash = NULL;
|
||||
static struct mandoc_xr *xr_first = NULL;
|
||||
static struct mandoc_xr *xr_last = NULL;
|
||||
|
||||
static void mandoc_xr_clear(void);
|
||||
|
||||
|
||||
static void
|
||||
mandoc_xr_clear(void)
|
||||
{
|
||||
struct mandoc_xr *xr;
|
||||
unsigned int slot;
|
||||
|
||||
if (xr_hash == NULL)
|
||||
return;
|
||||
for (xr = ohash_first(xr_hash, &slot); xr != NULL;
|
||||
xr = ohash_next(xr_hash, &slot))
|
||||
free(xr);
|
||||
ohash_delete(xr_hash);
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_xr_reset(void)
|
||||
{
|
||||
if (xr_hash == NULL)
|
||||
xr_hash = mandoc_malloc(sizeof(*xr_hash));
|
||||
else
|
||||
mandoc_xr_clear();
|
||||
mandoc_ohash_init(xr_hash, 5,
|
||||
offsetof(struct mandoc_xr, hashkey));
|
||||
xr_first = xr_last = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
mandoc_xr_add(const char *sec, const char *name, int line, int pos)
|
||||
{
|
||||
struct mandoc_xr *xr, *oxr;
|
||||
const char *pend;
|
||||
size_t ssz, nsz, tsz;
|
||||
unsigned int slot;
|
||||
int ret;
|
||||
uint32_t hv;
|
||||
|
||||
if (xr_hash == NULL)
|
||||
return 0;
|
||||
|
||||
ssz = strlen(sec) + 1;
|
||||
nsz = strlen(name) + 1;
|
||||
tsz = ssz + nsz;
|
||||
xr = mandoc_malloc(sizeof(*xr) + tsz);
|
||||
xr->next = NULL;
|
||||
xr->sec = xr->hashkey;
|
||||
xr->name = xr->hashkey + ssz;
|
||||
xr->line = line;
|
||||
xr->pos = pos;
|
||||
xr->count = 1;
|
||||
memcpy(xr->sec, sec, ssz);
|
||||
memcpy(xr->name, name, nsz);
|
||||
|
||||
pend = xr->hashkey + tsz;
|
||||
hv = ohash_interval(xr->hashkey, &pend);
|
||||
slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
|
||||
if ((oxr = ohash_find(xr_hash, slot)) == NULL) {
|
||||
ohash_insert(xr_hash, slot, xr);
|
||||
if (xr_first == NULL)
|
||||
xr_first = xr;
|
||||
else
|
||||
xr_last->next = xr;
|
||||
xr_last = xr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
oxr->count++;
|
||||
ret = (oxr->line == -1) ^ (xr->line == -1);
|
||||
if (xr->line == -1)
|
||||
oxr->line = -1;
|
||||
free(xr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct mandoc_xr *
|
||||
mandoc_xr_get(void)
|
||||
{
|
||||
return xr_first;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_xr_free(void)
|
||||
{
|
||||
mandoc_xr_clear();
|
||||
free(xr_hash);
|
||||
xr_hash = NULL;
|
||||
}
|
31
mandoc_xr.h
Normal file
31
mandoc_xr.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* $Id: mandoc_xr.h,v 1.3 2017/07/02 21:18:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct mandoc_xr {
|
||||
struct mandoc_xr *next;
|
||||
char *sec;
|
||||
char *name;
|
||||
int line; /* Or -1 for this page's own names. */
|
||||
int pos;
|
||||
int count;
|
||||
char hashkey[];
|
||||
};
|
||||
|
||||
void mandoc_xr_reset(void);
|
||||
int mandoc_xr_add(const char *, const char *, int, int);
|
||||
struct mandoc_xr *mandoc_xr_get(void);
|
||||
void mandoc_xr_free(void);
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandocd.c,v 1.5 2017/02/17 14:31:52 schwarze Exp $ */
|
||||
/* $Id: mandocd.c,v 1.6 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -171,7 +171,7 @@ main(int argc, char *argv[])
|
||||
|
||||
mchars_alloc();
|
||||
parser = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1,
|
||||
MANDOCLEVEL_BADARG, NULL, defos);
|
||||
MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, defos);
|
||||
|
||||
memset(&options, 0, sizeof(options));
|
||||
switch (outtype) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandocdb.c,v 1.250 2017/05/17 22:27:12 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.253 2017/07/28 14:48:25 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -420,7 +420,8 @@ mandocdb(int argc, char *argv[])
|
||||
|
||||
exitcode = (int)MANDOCLEVEL_OK;
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL, NULL);
|
||||
mp = mparse_alloc(mparse_options, MANDOCERR_MAX, NULL,
|
||||
MANDOC_OS_OTHER, NULL);
|
||||
mandoc_ohash_init(&mpages, 6, offsetof(struct mpage, inodev));
|
||||
mandoc_ohash_init(&mlinks, 6, offsetof(struct mlink, file));
|
||||
|
||||
@ -2129,7 +2130,7 @@ dbwrite(struct dba *dba)
|
||||
|
||||
dba_array_start(dba->pages);
|
||||
if (dba_array_next(dba->pages) == NULL) {
|
||||
if (unlink(MANDOC_DB) == -1)
|
||||
if (unlink(MANDOC_DB) == -1 && errno != ENOENT)
|
||||
say(MANDOC_DB, "&unlink");
|
||||
return;
|
||||
}
|
||||
|
11
manpath.c
11
manpath.c
@ -1,4 +1,4 @@
|
||||
/* $Id: manpath.c,v 1.33 2017/02/10 15:45:28 schwarze Exp $ */
|
||||
/* $Id: manpath.c,v 1.35 2017/07/01 09:47:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -91,6 +91,13 @@ manconf_parse(struct manconf *conf, const char *file,
|
||||
manpath_parseline(&conf->manpath, defp, 0);
|
||||
}
|
||||
|
||||
void
|
||||
manpath_base(struct manpaths *dirs)
|
||||
{
|
||||
char path_base[] = MANPATH_BASE;
|
||||
manpath_parseline(dirs, path_base, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a FULL pathname from a colon-separated list of arrays.
|
||||
*/
|
||||
@ -299,7 +306,7 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
mandoc_asprintf(&oldval, "%zu", conf->width);
|
||||
break;
|
||||
}
|
||||
conf->width = strtonum(cp, 58, 1000, &errstr);
|
||||
conf->width = strtonum(cp, 1, 1000, &errstr);
|
||||
if (errstr == NULL)
|
||||
return 0;
|
||||
warnx("-O width=%s is %s", cp, errstr);
|
||||
|
34
mansearch.c
34
mansearch.c
@ -104,7 +104,8 @@ mansearch(const struct mansearch *search,
|
||||
}
|
||||
|
||||
cur = maxres = 0;
|
||||
*res = NULL;
|
||||
if (res != NULL)
|
||||
*res = NULL;
|
||||
|
||||
outkey = KEY_Nd;
|
||||
if (search->outkey != NULL)
|
||||
@ -173,6 +174,10 @@ mansearch(const struct mansearch *search,
|
||||
lstmatch(search->arch, page->arch) == 0)
|
||||
continue;
|
||||
|
||||
if (res == NULL) {
|
||||
cur = 1;
|
||||
break;
|
||||
}
|
||||
if (cur + 1 > maxres) {
|
||||
maxres += 1024;
|
||||
*res = mandoc_reallocarray(*res,
|
||||
@ -204,12 +209,13 @@ mansearch(const struct mansearch *search,
|
||||
if (cur && search->firstmatch)
|
||||
break;
|
||||
}
|
||||
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
|
||||
if (res != NULL)
|
||||
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
|
||||
if (chdir_status && getcwd_status && chdir(buf) == -1)
|
||||
warn("%s", buf);
|
||||
exprfree(e);
|
||||
*sz = cur;
|
||||
return 1;
|
||||
return res != NULL || cur;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -388,13 +394,29 @@ static int
|
||||
manpage_compare(const void *vp1, const void *vp2)
|
||||
{
|
||||
const struct manpage *mp1, *mp2;
|
||||
const char *cp1, *cp2;
|
||||
size_t sz1, sz2;
|
||||
int diff;
|
||||
|
||||
mp1 = vp1;
|
||||
mp2 = vp2;
|
||||
return (diff = mp2->bits - mp1->bits) ? diff :
|
||||
(diff = mp1->sec - mp2->sec) ? diff :
|
||||
strcasecmp(mp1->names, mp2->names);
|
||||
if ((diff = mp2->bits - mp1->bits) ||
|
||||
(diff = mp1->sec - mp2->sec))
|
||||
return diff;
|
||||
|
||||
/* Fall back to alphabetic ordering of names. */
|
||||
sz1 = strcspn(mp1->names, "(");
|
||||
sz2 = strcspn(mp2->names, "(");
|
||||
if (sz1 < sz2)
|
||||
sz1 = sz2;
|
||||
if ((diff = strncasecmp(mp1->names, mp2->names, sz1)))
|
||||
return diff;
|
||||
|
||||
/* For identical names and sections, prefer arch-dependent. */
|
||||
cp1 = strchr(mp1->names + sz1, '/');
|
||||
cp2 = strchr(mp2->names + sz2, '/');
|
||||
return cp1 != NULL && cp2 != NULL ? strcasecmp(cp1, cp2) :
|
||||
cp1 != NULL ? -1 : cp2 != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
|
25
mdoc.7
25
mdoc.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: mdoc.7,v 1.264 2017/05/05 15:54:59 schwarze Exp $
|
||||
.\" $Id: mdoc.7,v 1.269 2017/07/20 16:24:53 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2017 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: May 5 2017 $
|
||||
.Dd $Mdocdate: July 20 2017 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -477,7 +477,7 @@ in the alphabetical
|
||||
.It Sx \&Sm Ta switch horizontal spacing mode: Op Cm on | off
|
||||
.It Sx \&Bk , \&Ek Ta keep block: Fl words
|
||||
.El
|
||||
.Ss Semantic markup for command line utilities:
|
||||
.Ss Semantic markup for command line utilities
|
||||
.Bl -column "Brq, Bro, Brc" description
|
||||
.It Sx \&Nm Ta start a SYNOPSIS block with the name of a utility
|
||||
.It Sx \&Fl Ta command line options (flags) (>=0 arguments)
|
||||
@ -488,7 +488,7 @@ in the alphabetical
|
||||
.It Sx \&Ev Ta environmental variable (>0 arguments)
|
||||
.It Sx \&Pa Ta file system path (>=0 arguments)
|
||||
.El
|
||||
.Ss Semantic markup for function libraries:
|
||||
.Ss Semantic markup for function libraries
|
||||
.Bl -column "Brq, Bro, Brc" description
|
||||
.It Sx \&Lb Ta function library (one argument)
|
||||
.It Sx \&In Ta include file (one argument)
|
||||
@ -509,7 +509,7 @@ in the alphabetical
|
||||
.It Sx \&Er Ta error constant (>0 arguments)
|
||||
.It Sx \&Ev Ta environmental variable (>0 arguments)
|
||||
.El
|
||||
.Ss Various semantic markup:
|
||||
.Ss Various semantic markup
|
||||
.Bl -column "Brq, Bro, Brc" description
|
||||
.It Sx \&An Ta author name (>0 arguments)
|
||||
.It Sx \&Lk Ta hyperlink: Ar uri Op Ar name
|
||||
@ -735,7 +735,7 @@ A version of
|
||||
.At .
|
||||
.It Cm III
|
||||
.At III .
|
||||
.It Cm V[.[1-4]]?
|
||||
.It Cm V | V.[1-4]
|
||||
A version of
|
||||
.At V .
|
||||
.El
|
||||
@ -1850,10 +1850,10 @@ The tab cell delimiter may only be used within the
|
||||
.Sx \&It
|
||||
line itself; on following lines, only the
|
||||
.Sx \&Ta
|
||||
macro can be used to delimit cells, and
|
||||
macro can be used to delimit cells, and portability requires that
|
||||
.Sx \&Ta
|
||||
is only recognised as a macro when called by other macros,
|
||||
not as the first macro on a line.
|
||||
is called by other macros: some parsers do not recognize it when
|
||||
it appears as the first macro on a line.
|
||||
.Pp
|
||||
Note that quoted strings may span tab-delimited cells on an
|
||||
.Sx \&It
|
||||
@ -2575,11 +2575,6 @@ The second and last Technical Corrigendum.
|
||||
.br
|
||||
This standard is also called
|
||||
X/Open Portability Guide version 7.
|
||||
.Pp
|
||||
.It \-p1003.1-2013
|
||||
.St -p1003.1-2013
|
||||
.br
|
||||
This is the first Technical Corrigendum.
|
||||
.El
|
||||
.It Other standards
|
||||
.Pp
|
||||
@ -3203,7 +3198,7 @@ but produces large indentations.
|
||||
.Xr tbl 7
|
||||
.Pp
|
||||
The web page
|
||||
.Lk http://mdocml.bsd.lv/mdoc/ "extended documentation for the mdoc language"
|
||||
.Lk http://mandoc.bsd.lv/mdoc/ "extended documentation for the mdoc language"
|
||||
provides a few tutorial-style pages for beginners, an extensive style
|
||||
guide for advanced authors, and an alphabetic index helping to choose
|
||||
the best macros for various kinds of content.
|
||||
|
30
mdoc.c
30
mdoc.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc.c,v 1.266 2017/06/07 20:58:49 schwarze Exp $ */
|
||||
/* $Id: mdoc.c,v 1.267 2017/06/17 13:06:16 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -179,6 +179,7 @@ static int
|
||||
mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *cp, *sp;
|
||||
char *c, *ws, *end;
|
||||
|
||||
n = mdoc->last;
|
||||
@ -244,15 +245,30 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||
line, (int)(ws-buf), NULL);
|
||||
|
||||
/*
|
||||
* Blank lines are allowed in no-fill mode
|
||||
* and cancel preceding \c,
|
||||
* but add a single vertical space elsewhere.
|
||||
*/
|
||||
|
||||
if (buf[offs] == '\0' && ! (mdoc->flags & MDOC_LITERAL)) {
|
||||
switch (mdoc->last->type) {
|
||||
case ROFFT_TEXT:
|
||||
sp = mdoc->last->string;
|
||||
cp = end = strchr(sp, '\0') - 2;
|
||||
if (cp < sp || cp[0] != '\\' || cp[1] != 'c')
|
||||
break;
|
||||
while (cp > sp && cp[-1] == '\\')
|
||||
cp--;
|
||||
if ((end - cp) % 2)
|
||||
break;
|
||||
*end = '\0';
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse,
|
||||
line, (int)(c - buf), NULL);
|
||||
|
||||
/*
|
||||
* Insert a `sp' in the case of a blank line. Technically,
|
||||
* blank lines aren't allowed, but enough manuals assume this
|
||||
* behaviour that we want to work around it.
|
||||
*/
|
||||
roff_elem_alloc(mdoc, line, offs, ROFF_sp);
|
||||
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
|
60
mdoc_html.c
60
mdoc_html.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_html.c,v 1.289 2017/05/30 16:31:29 schwarze Exp $ */
|
||||
/* $Id: mdoc_html.c,v 1.294 2017/07/15 17:57:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -27,6 +27,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "out.h"
|
||||
@ -714,10 +715,7 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
if (bl->norm->Bl.comp)
|
||||
print_otag(h, TAG_LI, "csvt", cattr, 0);
|
||||
else
|
||||
print_otag(h, TAG_LI, "c", cattr);
|
||||
print_otag(h, TAG_LI, "c", cattr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -729,15 +727,12 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
case LIST_ohang:
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
if (bl->norm->Bl.comp)
|
||||
print_otag(h, TAG_DT, "csvt", cattr, 0);
|
||||
else
|
||||
print_otag(h, TAG_DT, "c", cattr);
|
||||
print_otag(h, TAG_DT, "c", cattr);
|
||||
if (type == LIST_diag)
|
||||
print_otag(h, TAG_B, "c", cattr);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, TAG_DD, "cswl", cattr,
|
||||
print_otag(h, TAG_DD, "csw*+l", cattr,
|
||||
bl->norm->Bl.width);
|
||||
break;
|
||||
default:
|
||||
@ -751,7 +746,7 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
(n->parent->prev == NULL ||
|
||||
n->parent->prev->body == NULL ||
|
||||
n->parent->prev->body->child != NULL)) {
|
||||
t = print_otag(h, TAG_DT, "csw+-l",
|
||||
t = print_otag(h, TAG_DT, "csw*+-l",
|
||||
cattr, bl->norm->Bl.width);
|
||||
print_text(h, "\\ ");
|
||||
print_tagq(h, t);
|
||||
@ -759,7 +754,7 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
print_text(h, "\\ ");
|
||||
print_tagq(h, t);
|
||||
}
|
||||
print_otag(h, TAG_DT, "csw+-l", cattr,
|
||||
print_otag(h, TAG_DT, "csw*+-l", cattr,
|
||||
bl->norm->Bl.width);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
@ -779,10 +774,7 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
case ROFFT_HEAD:
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (bl->norm->Bl.comp)
|
||||
print_otag(h, TAG_TD, "csvt", cattr, 0);
|
||||
else
|
||||
print_otag(h, TAG_TD, "c", cattr);
|
||||
print_otag(h, TAG_TD, "c", cattr);
|
||||
break;
|
||||
default:
|
||||
print_otag(h, TAG_TR, "c", cattr);
|
||||
@ -797,9 +789,9 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_bl_pre(MDOC_ARGS)
|
||||
{
|
||||
char cattr[21];
|
||||
struct tag *t;
|
||||
struct mdoc_bl *bl;
|
||||
const char *cattr;
|
||||
size_t i;
|
||||
enum htmltag elemtype;
|
||||
|
||||
@ -834,50 +826,52 @@ mdoc_bl_pre(MDOC_ARGS)
|
||||
switch (bl->type) {
|
||||
case LIST_bullet:
|
||||
elemtype = TAG_UL;
|
||||
cattr = "Bl-bullet";
|
||||
(void)strlcpy(cattr, "Bl-bullet", sizeof(cattr));
|
||||
break;
|
||||
case LIST_dash:
|
||||
case LIST_hyphen:
|
||||
elemtype = TAG_UL;
|
||||
cattr = "Bl-dash";
|
||||
(void)strlcpy(cattr, "Bl-dash", sizeof(cattr));
|
||||
break;
|
||||
case LIST_item:
|
||||
elemtype = TAG_UL;
|
||||
cattr = "Bl-item";
|
||||
(void)strlcpy(cattr, "Bl-item", sizeof(cattr));
|
||||
break;
|
||||
case LIST_enum:
|
||||
elemtype = TAG_OL;
|
||||
cattr = "Bl-enum";
|
||||
(void)strlcpy(cattr, "Bl-enum", sizeof(cattr));
|
||||
break;
|
||||
case LIST_diag:
|
||||
elemtype = TAG_DL;
|
||||
cattr = "Bl-diag";
|
||||
(void)strlcpy(cattr, "Bl-diag", sizeof(cattr));
|
||||
break;
|
||||
case LIST_hang:
|
||||
elemtype = TAG_DL;
|
||||
cattr = "Bl-hang";
|
||||
(void)strlcpy(cattr, "Bl-hang", sizeof(cattr));
|
||||
break;
|
||||
case LIST_inset:
|
||||
elemtype = TAG_DL;
|
||||
cattr = "Bl-inset";
|
||||
(void)strlcpy(cattr, "Bl-inset", sizeof(cattr));
|
||||
break;
|
||||
case LIST_ohang:
|
||||
elemtype = TAG_DL;
|
||||
cattr = "Bl-ohang";
|
||||
(void)strlcpy(cattr, "Bl-ohang", sizeof(cattr));
|
||||
break;
|
||||
case LIST_tag:
|
||||
cattr = "Bl-tag";
|
||||
if (bl->offs)
|
||||
print_otag(h, TAG_DIV, "cswl", cattr, bl->offs);
|
||||
print_otag(h, TAG_DL, "csw+l", cattr, bl->width);
|
||||
print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs);
|
||||
print_otag(h, TAG_DL, "csw*+l", bl->comp ?
|
||||
"Bl-tag Bl-compact" : "Bl-tag", bl->width);
|
||||
return 1;
|
||||
case LIST_column:
|
||||
elemtype = TAG_TABLE;
|
||||
cattr = "Bl-column";
|
||||
(void)strlcpy(cattr, "Bl-column", sizeof(cattr));
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
if (bl->comp)
|
||||
(void)strlcat(cattr, " Bl-compact", sizeof(cattr));
|
||||
print_otag(h, elemtype, "cswl", cattr, bl->offs);
|
||||
return 1;
|
||||
}
|
||||
@ -1322,12 +1316,16 @@ mdoc_lk_pre(MDOC_ARGS)
|
||||
punct = punct->next;
|
||||
|
||||
/* Link target and link text. */
|
||||
descr = link->next;
|
||||
if (descr == punct)
|
||||
descr = link; /* no text */
|
||||
t = print_otag(h, TAG_A, "cTh", "Lk", link->string);
|
||||
for (descr = link->next; descr != punct; descr = descr->next) {
|
||||
do {
|
||||
if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, descr->string);
|
||||
}
|
||||
descr = descr->next;
|
||||
} while (descr != punct);
|
||||
print_tagq(h, t);
|
||||
|
||||
/* Trailing punctuation. */
|
||||
|
47
mdoc_man.c
47
mdoc_man.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_man.c,v 1.119 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: mdoc_man.c,v 1.122 2017/06/14 22:51:25 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -125,14 +125,16 @@ static void print_count(int *);
|
||||
static void print_node(DECL_ARGS);
|
||||
|
||||
static const void_fp roff_manacts[ROFF_MAX] = {
|
||||
pre_br,
|
||||
pre_onearg,
|
||||
pre_ft,
|
||||
pre_onearg,
|
||||
pre_onearg,
|
||||
pre_sp,
|
||||
pre_ta,
|
||||
pre_onearg,
|
||||
pre_br, /* br */
|
||||
pre_onearg, /* ce */
|
||||
pre_ft, /* ft */
|
||||
pre_onearg, /* ll */
|
||||
pre_onearg, /* mc */
|
||||
pre_onearg, /* po */
|
||||
pre_onearg, /* rj */
|
||||
pre_sp, /* sp */
|
||||
pre_ta, /* ta */
|
||||
pre_onearg, /* ti */
|
||||
};
|
||||
|
||||
static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = {
|
||||
@ -196,8 +198,8 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bsx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bx */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Bsx */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Bx */
|
||||
{ NULL, pre_skip, NULL, NULL, NULL }, /* Db */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
|
||||
{ cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */
|
||||
@ -206,12 +208,12 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
|
||||
{ cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Fx */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Fx */
|
||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
|
||||
{ NULL, pre_no, NULL, NULL, NULL }, /* No */
|
||||
{ NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Nx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ox */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Nx */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Ox */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Pc */
|
||||
{ NULL, NULL, post_pf, NULL, NULL }, /* Pf */
|
||||
{ cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
|
||||
@ -252,7 +254,7 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %C */
|
||||
{ NULL, pre_skip, NULL, NULL, NULL }, /* Es */
|
||||
{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dx */
|
||||
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Dx */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
|
||||
@ -990,11 +992,11 @@ post_bf(DECL_ARGS)
|
||||
static int
|
||||
pre_bk(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
return 1;
|
||||
case ROFFT_BODY:
|
||||
case ROFFT_ELEM:
|
||||
outflags |= MMAN_Bk;
|
||||
return 1;
|
||||
default:
|
||||
@ -1005,9 +1007,18 @@ pre_bk(DECL_ARGS)
|
||||
static void
|
||||
post_bk(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BODY)
|
||||
switch (n->type) {
|
||||
case ROFFT_ELEM:
|
||||
while ((n = n->parent) != NULL)
|
||||
if (n->tok == MDOC_Bk)
|
||||
return;
|
||||
/* FALLTHROUGH */
|
||||
case ROFFT_BODY:
|
||||
outflags &= ~MMAN_Bk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_markdown.c,v 1.22 2017/05/30 16:31:29 schwarze Exp $ */
|
||||
/* $Id: mdoc_markdown.c,v 1.23 2017/06/14 01:31:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -493,7 +493,7 @@ md_word(const char *s)
|
||||
{
|
||||
const char *seq, *prevfont, *currfont, *nextfont;
|
||||
char c;
|
||||
int bs, sz, uc;
|
||||
int bs, sz, uc, breakline;
|
||||
|
||||
/* No spacing before closing delimiters. */
|
||||
if (s[0] != '\0' && s[1] == '\0' &&
|
||||
@ -510,6 +510,7 @@ md_word(const char *s)
|
||||
if ((s[0] == '(' || s[0] == '[') && s[1] == '\0')
|
||||
outflags &= ~MD_spc;
|
||||
|
||||
breakline = 0;
|
||||
prevfont = currfont = "";
|
||||
while ((c = *s++) != '\0') {
|
||||
bs = 0;
|
||||
@ -595,6 +596,9 @@ md_word(const char *s)
|
||||
case ESCAPE_FONTPREV:
|
||||
nextfont = prevfont;
|
||||
break;
|
||||
case ESCAPE_BREAK:
|
||||
breakline = 1;
|
||||
break;
|
||||
case ESCAPE_NOSPACE:
|
||||
case ESCAPE_SKIPCHAR:
|
||||
case ESCAPE_OVERSTRIKE:
|
||||
@ -642,6 +646,13 @@ md_word(const char *s)
|
||||
if (bs)
|
||||
putchar('\\');
|
||||
md_char(c);
|
||||
if (breakline &&
|
||||
(*s == '\0' || *s == ' ' || *s == ASCII_NBRSP)) {
|
||||
printf(" \n");
|
||||
breakline = 0;
|
||||
while (*s == ' ' || *s == ASCII_NBRSP)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (*currfont != '\0') {
|
||||
outflags &= ~MD_spc;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_term.c,v 1.363 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.364 2017/06/14 17:51:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -540,7 +540,7 @@ a2width(const struct termp *p, const char *v)
|
||||
SCALE_HS_INIT(&su, term_strlen(p, v));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
}
|
||||
return term_hspan(p, &su) / 24;
|
||||
return term_hen(p, &su);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -686,7 +686,7 @@ termp_it_pre(DECL_ARGS)
|
||||
SCALE_HS_INIT(&su,
|
||||
term_strlen(p, bl->norm->Bl.cols[i]));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
offset += term_hspan(p, &su) / 24 + dcol;
|
||||
offset += term_hen(p, &su) + dcol;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -704,7 +704,7 @@ termp_it_pre(DECL_ARGS)
|
||||
*/
|
||||
SCALE_HS_INIT(&su, term_strlen(p, bl->norm->Bl.cols[i]));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
width = term_hspan(p, &su) / 24 + dcol;
|
||||
width = term_hen(p, &su) + dcol;
|
||||
break;
|
||||
default:
|
||||
if (NULL == bl->norm->Bl.width)
|
||||
|
514
mdoc_validate.c
514
mdoc_validate.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_validate.c,v 1.332 2017/06/08 00:23:30 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.350 2017/07/20 12:54:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_xr.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmandoc.h"
|
||||
@ -53,13 +54,14 @@ typedef void (*v_post)(POST_ARGS);
|
||||
|
||||
static int build_list(struct roff_man *, int);
|
||||
static void check_text(struct roff_man *, int, int, char *);
|
||||
static void check_bsd(struct roff_man *, int, int, char *);
|
||||
static void check_argv(struct roff_man *,
|
||||
struct roff_node *, struct mdoc_argv *);
|
||||
static void check_args(struct roff_man *, struct roff_node *);
|
||||
static void check_toptext(struct roff_man *, int, int, const char *);
|
||||
static int child_an(const struct roff_node *);
|
||||
static size_t macro2len(enum roff_tok);
|
||||
static void rewrite_macro2len(struct roff_man *, char **);
|
||||
static int similar(const char *, const char *);
|
||||
|
||||
static void post_an(POST_ARGS);
|
||||
static void post_an_norm(POST_ARGS);
|
||||
@ -75,6 +77,8 @@ static void post_bx(POST_ARGS);
|
||||
static void post_defaults(POST_ARGS);
|
||||
static void post_display(POST_ARGS);
|
||||
static void post_dd(POST_ARGS);
|
||||
static void post_delim(POST_ARGS);
|
||||
static void post_delim_nb(POST_ARGS);
|
||||
static void post_dt(POST_ARGS);
|
||||
static void post_en(POST_ARGS);
|
||||
static void post_es(POST_ARGS);
|
||||
@ -106,6 +110,7 @@ static void post_sh_authors(POST_ARGS);
|
||||
static void post_sm(POST_ARGS);
|
||||
static void post_st(POST_ARGS);
|
||||
static void post_std(POST_ARGS);
|
||||
static void post_sx(POST_ARGS);
|
||||
static void post_useless(POST_ARGS);
|
||||
static void post_xr(POST_ARGS);
|
||||
static void post_xx(POST_ARGS);
|
||||
@ -124,33 +129,33 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
||||
post_bl, /* Bl */
|
||||
NULL, /* El */
|
||||
post_it, /* It */
|
||||
NULL, /* Ad */
|
||||
post_delim_nb, /* Ad */
|
||||
post_an, /* An */
|
||||
NULL, /* Ap */
|
||||
post_defaults, /* Ar */
|
||||
NULL, /* Cd */
|
||||
NULL, /* Cm */
|
||||
NULL, /* Dv */
|
||||
NULL, /* Er */
|
||||
NULL, /* Ev */
|
||||
post_delim_nb, /* Cm */
|
||||
post_delim_nb, /* Dv */
|
||||
post_delim_nb, /* Er */
|
||||
post_delim_nb, /* Ev */
|
||||
post_ex, /* Ex */
|
||||
post_fa, /* Fa */
|
||||
NULL, /* Fd */
|
||||
NULL, /* Fl */
|
||||
post_delim_nb, /* Fl */
|
||||
post_fn, /* Fn */
|
||||
NULL, /* Ft */
|
||||
NULL, /* Ic */
|
||||
NULL, /* In */
|
||||
post_delim_nb, /* Ft */
|
||||
post_delim_nb, /* Ic */
|
||||
post_delim_nb, /* In */
|
||||
post_defaults, /* Li */
|
||||
post_nd, /* Nd */
|
||||
post_nm, /* Nm */
|
||||
NULL, /* Op */
|
||||
post_delim_nb, /* Op */
|
||||
post_obsolete, /* Ot */
|
||||
post_defaults, /* Pa */
|
||||
post_rv, /* Rv */
|
||||
post_st, /* St */
|
||||
NULL, /* Va */
|
||||
NULL, /* Vt */
|
||||
post_delim_nb, /* Va */
|
||||
post_delim_nb, /* Vt */
|
||||
post_xr, /* Xr */
|
||||
NULL, /* %A */
|
||||
post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */
|
||||
@ -164,12 +169,12 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
||||
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */
|
||||
NULL, /* %V */
|
||||
NULL, /* Ac */
|
||||
NULL, /* Ao */
|
||||
NULL, /* Aq */
|
||||
post_delim_nb, /* Ao */
|
||||
post_delim_nb, /* Aq */
|
||||
post_at, /* At */
|
||||
NULL, /* Bc */
|
||||
post_bf, /* Bf */
|
||||
NULL, /* Bo */
|
||||
post_delim_nb, /* Bo */
|
||||
NULL, /* Bq */
|
||||
post_xx, /* Bsx */
|
||||
post_bx, /* Bx */
|
||||
@ -179,50 +184,50 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
||||
NULL, /* Dq */
|
||||
NULL, /* Ec */
|
||||
NULL, /* Ef */
|
||||
NULL, /* Em */
|
||||
post_delim_nb, /* Em */
|
||||
NULL, /* Eo */
|
||||
post_xx, /* Fx */
|
||||
NULL, /* Ms */
|
||||
post_delim_nb, /* Ms */
|
||||
NULL, /* No */
|
||||
post_ns, /* Ns */
|
||||
post_xx, /* Nx */
|
||||
post_xx, /* Ox */
|
||||
NULL, /* Pc */
|
||||
NULL, /* Pf */
|
||||
NULL, /* Po */
|
||||
NULL, /* Pq */
|
||||
post_delim_nb, /* Po */
|
||||
post_delim_nb, /* Pq */
|
||||
NULL, /* Qc */
|
||||
NULL, /* Ql */
|
||||
NULL, /* Qo */
|
||||
NULL, /* Qq */
|
||||
post_delim_nb, /* Ql */
|
||||
post_delim_nb, /* Qo */
|
||||
post_delim_nb, /* Qq */
|
||||
NULL, /* Re */
|
||||
post_rs, /* Rs */
|
||||
NULL, /* Sc */
|
||||
NULL, /* So */
|
||||
NULL, /* Sq */
|
||||
post_delim_nb, /* So */
|
||||
post_delim_nb, /* Sq */
|
||||
post_sm, /* Sm */
|
||||
post_hyph, /* Sx */
|
||||
NULL, /* Sy */
|
||||
post_sx, /* Sx */
|
||||
post_delim_nb, /* Sy */
|
||||
post_useless, /* Tn */
|
||||
post_xx, /* Ux */
|
||||
NULL, /* Xc */
|
||||
NULL, /* Xo */
|
||||
post_fo, /* Fo */
|
||||
NULL, /* Fc */
|
||||
NULL, /* Oo */
|
||||
post_delim_nb, /* Oo */
|
||||
NULL, /* Oc */
|
||||
post_bk, /* Bk */
|
||||
NULL, /* Ek */
|
||||
post_eoln, /* Bt */
|
||||
NULL, /* Hf */
|
||||
post_obsolete, /* Hf */
|
||||
post_obsolete, /* Fr */
|
||||
post_eoln, /* Ud */
|
||||
post_lb, /* Lb */
|
||||
post_par, /* Lp */
|
||||
NULL, /* Lk */
|
||||
post_delim_nb, /* Lk */
|
||||
post_defaults, /* Mt */
|
||||
NULL, /* Brq */
|
||||
NULL, /* Bro */
|
||||
post_delim_nb, /* Brq */
|
||||
post_delim_nb, /* Bro */
|
||||
NULL, /* Brc */
|
||||
NULL, /* %C */
|
||||
post_es, /* Es */
|
||||
@ -303,10 +308,11 @@ mdoc_node_validate(struct roff_man *mdoc)
|
||||
if (n->sec != SEC_SYNOPSIS ||
|
||||
(n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
|
||||
check_text(mdoc, n->line, n->pos, n->string);
|
||||
if (n->parent->tok == MDOC_Sh ||
|
||||
n->parent->tok == MDOC_Ss ||
|
||||
n->parent->tok == MDOC_It)
|
||||
check_bsd(mdoc, n->line, n->pos, n->string);
|
||||
if (n->parent->tok == MDOC_It ||
|
||||
(n->parent->type == ROFFT_BODY &&
|
||||
(n->parent->tok == MDOC_Sh ||
|
||||
n->parent->tok == MDOC_Ss)))
|
||||
check_toptext(mdoc, n->line, n->pos, n->string);
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
case ROFFT_TBL:
|
||||
@ -389,9 +395,12 @@ check_text(struct roff_man *mdoc, int ln, int pos, char *p)
|
||||
}
|
||||
|
||||
static void
|
||||
check_bsd(struct roff_man *mdoc, int ln, int pos, char *p)
|
||||
check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p)
|
||||
{
|
||||
const char *cp;
|
||||
const char *cp, *cpr;
|
||||
|
||||
if (*p == '\0')
|
||||
return;
|
||||
|
||||
if ((cp = strstr(p, "OpenBSD")) != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
@ -405,6 +414,142 @@ check_bsd(struct roff_man *mdoc, int ln, int pos, char *p)
|
||||
if ((cp = strstr(p, "DragonFly")) != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
ln, pos + (cp - p), "Dx");
|
||||
|
||||
cp = p;
|
||||
while ((cp = strstr(cp + 1, "()")) != NULL) {
|
||||
for (cpr = cp - 1; cpr >= p; cpr--)
|
||||
if (*cpr != '_' && !isalnum((unsigned char)*cpr))
|
||||
break;
|
||||
if ((cpr < p || *cpr == ' ') && cpr + 1 < cp) {
|
||||
cpr++;
|
||||
mandoc_vmsg(MANDOCERR_FUNC, mdoc->parse,
|
||||
ln, pos + (cpr - p),
|
||||
"%.*s()", (int)(cp - cpr), cpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_delim(POST_ARGS)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
const char *lc;
|
||||
enum mdelim delim;
|
||||
enum roff_tok tok;
|
||||
|
||||
tok = mdoc->last->tok;
|
||||
nch = mdoc->last->last;
|
||||
if (nch == NULL || nch->type != ROFFT_TEXT)
|
||||
return;
|
||||
lc = strchr(nch->string, '\0') - 1;
|
||||
if (lc < nch->string)
|
||||
return;
|
||||
delim = mdoc_isdelim(lc);
|
||||
if (delim == DELIM_NONE || delim == DELIM_OPEN)
|
||||
return;
|
||||
if (*lc == ')' && (tok == MDOC_Nd || tok == MDOC_Sh ||
|
||||
tok == MDOC_Ss || tok == MDOC_Fo))
|
||||
return;
|
||||
|
||||
mandoc_vmsg(MANDOCERR_DELIM, mdoc->parse,
|
||||
nch->line, nch->pos + (lc - nch->string),
|
||||
"%s%s %s", roff_name[tok],
|
||||
nch == mdoc->last->child ? "" : " ...", nch->string);
|
||||
}
|
||||
|
||||
static void
|
||||
post_delim_nb(POST_ARGS)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
const char *lc, *cp;
|
||||
int nw;
|
||||
enum mdelim delim;
|
||||
enum roff_tok tok;
|
||||
|
||||
/*
|
||||
* Find candidates: at least two bytes,
|
||||
* the last one a closing or middle delimiter.
|
||||
*/
|
||||
|
||||
tok = mdoc->last->tok;
|
||||
nch = mdoc->last->last;
|
||||
if (nch == NULL || nch->type != ROFFT_TEXT)
|
||||
return;
|
||||
lc = strchr(nch->string, '\0') - 1;
|
||||
if (lc <= nch->string)
|
||||
return;
|
||||
delim = mdoc_isdelim(lc);
|
||||
if (delim == DELIM_NONE || delim == DELIM_OPEN)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Reduce false positives by allowing various cases.
|
||||
*/
|
||||
|
||||
/* Escaped delimiters. */
|
||||
if (lc > nch->string + 1 && lc[-2] == '\\' &&
|
||||
(lc[-1] == '&' || lc[-1] == 'e'))
|
||||
return;
|
||||
|
||||
/* Specific byte sequences. */
|
||||
switch (*lc) {
|
||||
case ')':
|
||||
for (cp = lc; cp >= nch->string; cp--)
|
||||
if (*cp == '(')
|
||||
return;
|
||||
break;
|
||||
case '.':
|
||||
if (lc > nch->string + 1 && lc[-2] == '.' && lc[-1] == '.')
|
||||
return;
|
||||
if (lc[-1] == '.')
|
||||
return;
|
||||
break;
|
||||
case ';':
|
||||
if (tok == MDOC_Vt)
|
||||
return;
|
||||
break;
|
||||
case '?':
|
||||
if (lc[-1] == '?')
|
||||
return;
|
||||
break;
|
||||
case ']':
|
||||
for (cp = lc; cp >= nch->string; cp--)
|
||||
if (*cp == '[')
|
||||
return;
|
||||
break;
|
||||
case '|':
|
||||
if (lc == nch->string + 1 && lc[-1] == '|')
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Exactly two non-alphanumeric bytes. */
|
||||
if (lc == nch->string + 1 && !isalnum((unsigned char)lc[-1]))
|
||||
return;
|
||||
|
||||
/* At least three alphabetic words with a sentence ending. */
|
||||
if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em ||
|
||||
tok == MDOC_Li || tok == MDOC_Po || tok == MDOC_Pq ||
|
||||
tok == MDOC_Sy)) {
|
||||
nw = 0;
|
||||
for (cp = lc - 1; cp >= nch->string; cp--) {
|
||||
if (*cp == ' ') {
|
||||
nw++;
|
||||
if (cp > nch->string && cp[-1] == ',')
|
||||
cp--;
|
||||
} else if (isalpha((unsigned int)*cp)) {
|
||||
if (nw > 1)
|
||||
return;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mandoc_vmsg(MANDOCERR_DELIM_NB, mdoc->parse,
|
||||
nch->line, nch->pos + (lc - nch->string),
|
||||
"%s%s %s", roff_name[tok],
|
||||
nch == mdoc->last->child ? "" : " ...", nch->string);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -555,7 +700,7 @@ post_bl_norm(POST_ARGS)
|
||||
|
||||
switch (n->norm->Bl.type) {
|
||||
case LIST_tag:
|
||||
if (NULL == n->norm->Bl.width)
|
||||
if (n->norm->Bl.width == NULL)
|
||||
mandoc_msg(MANDOCERR_BL_NOWIDTH, mdoc->parse,
|
||||
n->line, n->pos, "Bl -tag");
|
||||
break;
|
||||
@ -564,19 +709,20 @@ post_bl_norm(POST_ARGS)
|
||||
case LIST_ohang:
|
||||
case LIST_inset:
|
||||
case LIST_item:
|
||||
if (n->norm->Bl.width)
|
||||
if (n->norm->Bl.width != NULL)
|
||||
mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse,
|
||||
wa->line, wa->pos, "Bl -%s",
|
||||
mdoc_argnames[mdoclt]);
|
||||
n->norm->Bl.width = NULL;
|
||||
break;
|
||||
case LIST_bullet:
|
||||
case LIST_dash:
|
||||
case LIST_hyphen:
|
||||
if (NULL == n->norm->Bl.width)
|
||||
if (n->norm->Bl.width == NULL)
|
||||
n->norm->Bl.width = "2n";
|
||||
break;
|
||||
case LIST_enum:
|
||||
if (NULL == n->norm->Bl.width)
|
||||
if (n->norm->Bl.width == NULL)
|
||||
n->norm->Bl.width = "3n";
|
||||
break;
|
||||
default:
|
||||
@ -782,6 +928,8 @@ post_lb(POST_ARGS)
|
||||
struct roff_node *n;
|
||||
const char *p;
|
||||
|
||||
post_delim_nb(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
assert(n->child->type == ROFFT_TEXT);
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
@ -851,6 +999,8 @@ post_std(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
post_delim(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->args && n->args->argc == 1)
|
||||
if (n->args->argv[0].arg == MDOC_Std)
|
||||
@ -987,6 +1137,8 @@ post_fname(POST_ARGS)
|
||||
if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*')))
|
||||
mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse,
|
||||
n->line, n->pos + pos, n->string);
|
||||
if (n->sec == SEC_SYNOPSIS && mdoc->meta.msec != NULL)
|
||||
mandoc_xr_add(mdoc->meta.msec, n->string, -1, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1018,7 +1170,8 @@ post_fo(POST_ARGS)
|
||||
"Fo ... %s", n->child->next->string);
|
||||
while (n->child != n->last)
|
||||
roff_node_delete(mdoc, n->last);
|
||||
}
|
||||
} else
|
||||
post_delim(mdoc);
|
||||
|
||||
post_fname(mdoc);
|
||||
}
|
||||
@ -1042,6 +1195,7 @@ post_fa(POST_ARGS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
post_delim_nb(mdoc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1051,6 +1205,11 @@ post_nm(POST_ARGS)
|
||||
|
||||
n = mdoc->last;
|
||||
|
||||
if ((n->sec == SEC_NAME || n->sec == SEC_SYNOPSIS) &&
|
||||
n->child != NULL && n->child->type == ROFFT_TEXT &&
|
||||
mdoc->meta.msec != NULL)
|
||||
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1);
|
||||
|
||||
if (n->last != NULL &&
|
||||
(n->last->tok == MDOC_Pp ||
|
||||
n->last->tok == MDOC_Lp))
|
||||
@ -1064,8 +1223,18 @@ post_nm(POST_ARGS)
|
||||
mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,
|
||||
n->line, n->pos, "Nm");
|
||||
|
||||
if ((n->type != ROFFT_ELEM && n->type != ROFFT_HEAD) ||
|
||||
(n->child != NULL && n->child->type == ROFFT_TEXT) ||
|
||||
switch (n->type) {
|
||||
case ROFFT_ELEM:
|
||||
post_delim_nb(mdoc);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
post_delim(mdoc);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if ((n->child != NULL && n->child->type == ROFFT_TEXT) ||
|
||||
mdoc->meta.name == NULL)
|
||||
return;
|
||||
|
||||
@ -1079,7 +1248,6 @@ static void
|
||||
post_nd(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
size_t sz;
|
||||
|
||||
n = mdoc->last;
|
||||
|
||||
@ -1093,11 +1261,8 @@ post_nd(POST_ARGS)
|
||||
if (n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse,
|
||||
n->line, n->pos, "Nd");
|
||||
else if (n->last->type == ROFFT_TEXT &&
|
||||
(sz = strlen(n->last->string)) != 0 &&
|
||||
n->last->string[sz - 1] == '.')
|
||||
mandoc_msg(MANDOCERR_ND_DOT, mdoc->parse,
|
||||
n->last->line, n->last->pos + sz - 1, NULL);
|
||||
else
|
||||
post_delim(mdoc);
|
||||
|
||||
post_hyph(mdoc);
|
||||
}
|
||||
@ -1154,17 +1319,18 @@ post_defaults(POST_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
if (mdoc->last->child != NULL) {
|
||||
post_delim_nb(mdoc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The `Ar' defaults to "file ..." if no value is provided as an
|
||||
* argument; the `Mt' and `Pa' macros use "~"; the `Li' just
|
||||
* gets an empty string.
|
||||
*/
|
||||
|
||||
if (mdoc->last->child != NULL)
|
||||
return;
|
||||
|
||||
nn = mdoc->last;
|
||||
|
||||
switch (nn->tok) {
|
||||
case MDOC_Ar:
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
@ -1228,6 +1394,8 @@ post_an(POST_ARGS)
|
||||
if (nch == NULL)
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||
np->line, np->pos, "An");
|
||||
else
|
||||
post_delim_nb(mdoc);
|
||||
} else if (nch != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
|
||||
nch->line, nch->pos, "An ... %s", nch->string);
|
||||
@ -1255,6 +1423,9 @@ post_xx(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *os;
|
||||
char *v;
|
||||
|
||||
post_delim_nb(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
switch (n->tok) {
|
||||
@ -1269,6 +1440,20 @@ post_xx(POST_ARGS)
|
||||
break;
|
||||
case MDOC_Nx:
|
||||
os = "NetBSD";
|
||||
if (n->child == NULL)
|
||||
break;
|
||||
v = n->child->string;
|
||||
if ((v[0] != '0' && v[0] != '1') || v[1] != '.' ||
|
||||
v[2] < '0' || v[2] > '9' ||
|
||||
v[3] < 'a' || v[3] > 'z' || v[4] != '\0')
|
||||
break;
|
||||
n->child->flags |= NODE_NOPRT;
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, n->child->line, n->child->pos, v);
|
||||
v = mdoc->last->string;
|
||||
v[3] = toupper((unsigned char)v[3]);
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
break;
|
||||
case MDOC_Ox:
|
||||
os = "OpenBSD";
|
||||
@ -1335,15 +1520,30 @@ post_it(POST_ARGS)
|
||||
|
||||
assert(nit->head->child == NULL);
|
||||
|
||||
i = 0;
|
||||
for (nch = nit->child; nch != NULL; nch = nch->next)
|
||||
if (nch->type == ROFFT_BODY)
|
||||
i++;
|
||||
if (nit->head->next->child == NULL &&
|
||||
nit->head->next->next == NULL) {
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||
nit->line, nit->pos, "It");
|
||||
roff_node_delete(mdoc, nit);
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (nch = nit->child; nch != NULL; nch = nch->next) {
|
||||
if (nch->type != ROFFT_BODY)
|
||||
continue;
|
||||
if (i++ && nch->flags & NODE_LINE)
|
||||
mandoc_msg(MANDOCERR_TA_LINE, mdoc->parse,
|
||||
nch->line, nch->pos, "Ta");
|
||||
}
|
||||
if (i < cols || i > cols + 1)
|
||||
mandoc_vmsg(MANDOCERR_BL_COL,
|
||||
mdoc->parse, nit->line, nit->pos,
|
||||
"%d columns, %d cells", cols, i);
|
||||
else if (nit->head->next->child != NULL &&
|
||||
nit->head->next->child->line > nit->line)
|
||||
mandoc_msg(MANDOCERR_IT_NOARG, mdoc->parse,
|
||||
nit->line, nit->pos, "Bl -column It");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -1585,7 +1785,7 @@ post_bl(POST_ARGS)
|
||||
nchild = nnext;
|
||||
}
|
||||
|
||||
if (mdoc->meta.os_e != MDOC_OS_NETBSD)
|
||||
if (mdoc->meta.os_e != MANDOC_OS_NETBSD)
|
||||
return;
|
||||
|
||||
prev_Er = NULL;
|
||||
@ -1604,11 +1804,12 @@ post_bl(POST_ARGS)
|
||||
if (order > 0)
|
||||
mandoc_vmsg(MANDOCERR_ER_ORDER,
|
||||
mdoc->parse, nnext->line, nnext->pos,
|
||||
"Er %s %s", prev_Er, nnext->string);
|
||||
"Er %s %s (NetBSD)",
|
||||
prev_Er, nnext->string);
|
||||
else if (order == 0)
|
||||
mandoc_vmsg(MANDOCERR_ER_REP,
|
||||
mdoc->parse, nnext->line, nnext->pos,
|
||||
"Er %s", prev_Er);
|
||||
"Er %s (NetBSD)", prev_Er);
|
||||
}
|
||||
prev_Er = nnext->string;
|
||||
}
|
||||
@ -1661,14 +1862,35 @@ post_sm(POST_ARGS)
|
||||
static void
|
||||
post_root(POST_ARGS)
|
||||
{
|
||||
const char *openbsd_arch[] = {
|
||||
"alpha", "amd64", "arm64", "armv7", "hppa", "i386",
|
||||
"landisk", "loongson", "luna88k", "macppc", "mips64",
|
||||
"octeon", "sgi", "socppc", "sparc64", NULL
|
||||
};
|
||||
const char *netbsd_arch[] = {
|
||||
"acorn26", "acorn32", "algor", "alpha", "amiga",
|
||||
"arc", "atari",
|
||||
"bebox", "cats", "cesfic", "cobalt", "dreamcast",
|
||||
"emips", "evbarm", "evbmips", "evbppc", "evbsh3", "evbsh5",
|
||||
"hp300", "hpcarm", "hpcmips", "hpcsh", "hppa",
|
||||
"i386", "ibmnws", "luna68k",
|
||||
"mac68k", "macppc", "mipsco", "mmeye", "mvme68k", "mvmeppc",
|
||||
"netwinder", "news68k", "newsmips", "next68k",
|
||||
"pc532", "playstation2", "pmax", "pmppc", "prep",
|
||||
"sandpoint", "sbmips", "sgimips", "shark",
|
||||
"sparc", "sparc64", "sun2", "sun3",
|
||||
"vax", "walnut", "x68k", "x86", "x86_64", "xen", NULL
|
||||
};
|
||||
const char **arches[] = { NULL, netbsd_arch, openbsd_arch };
|
||||
|
||||
struct roff_node *n;
|
||||
const char **arch;
|
||||
|
||||
/* Add missing prologue data. */
|
||||
|
||||
if (mdoc->meta.date == NULL)
|
||||
mdoc->meta.date = mdoc->quick ?
|
||||
mandoc_strdup("") :
|
||||
mandoc_normdate(mdoc->parse, NULL, 0, 0);
|
||||
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(mdoc, NULL, 0, 0);
|
||||
|
||||
if (mdoc->meta.title == NULL) {
|
||||
mandoc_msg(MANDOCERR_DT_NOTITLE,
|
||||
@ -1683,6 +1905,27 @@ post_root(POST_ARGS)
|
||||
mandoc_msg(MANDOCERR_OS_MISSING,
|
||||
mdoc->parse, 0, 0, NULL);
|
||||
mdoc->meta.os = mandoc_strdup("");
|
||||
} else if (mdoc->meta.os_e &&
|
||||
(mdoc->meta.rcsids & (1 << mdoc->meta.os_e)) == 0)
|
||||
mandoc_msg(MANDOCERR_RCS_MISSING, mdoc->parse, 0, 0,
|
||||
mdoc->meta.os_e == MANDOC_OS_OPENBSD ?
|
||||
"(OpenBSD)" : "(NetBSD)");
|
||||
|
||||
if (mdoc->meta.arch != NULL &&
|
||||
(arch = arches[mdoc->meta.os_e]) != NULL) {
|
||||
while (*arch != NULL && strcmp(*arch, mdoc->meta.arch))
|
||||
arch++;
|
||||
if (*arch == NULL) {
|
||||
n = mdoc->first->child;
|
||||
while (n->tok != MDOC_Dt)
|
||||
n = n->next;
|
||||
n = n->child->next->next;
|
||||
mandoc_vmsg(MANDOCERR_ARCH_BAD,
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"Dt ... %s %s", mdoc->meta.arch,
|
||||
mdoc->meta.os_e == MANDOC_OS_OPENBSD ?
|
||||
"(OpenBSD)" : "(NetBSD)");
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that we begin with a proper `Sh'. */
|
||||
@ -1815,10 +2058,20 @@ post_hyph(POST_ARGS)
|
||||
static void
|
||||
post_ns(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
if (mdoc->last->flags & NODE_LINE)
|
||||
n = mdoc->last;
|
||||
if (n->flags & NODE_LINE ||
|
||||
(n->next != NULL && n->next->flags & NODE_DELIMC))
|
||||
mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse,
|
||||
mdoc->last->line, mdoc->last->pos, NULL);
|
||||
n->line, n->pos, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
post_sx(POST_ARGS)
|
||||
{
|
||||
post_delim(mdoc);
|
||||
post_hyph(mdoc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1981,11 +2234,54 @@ post_sh_authors(POST_ARGS)
|
||||
mdoc->last->line, mdoc->last->pos, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return an upper bound for the string distance (allowing
|
||||
* transpositions). Not a full Levenshtein implementation
|
||||
* because Levenshtein is quadratic in the string length
|
||||
* and this function is called for every standard name,
|
||||
* so the check for each custom name would be cubic.
|
||||
* The following crude heuristics is linear, resulting
|
||||
* in quadratic behaviour for checking one custom name,
|
||||
* which does not cause measurable slowdown.
|
||||
*/
|
||||
static int
|
||||
similar(const char *s1, const char *s2)
|
||||
{
|
||||
const int maxdist = 3;
|
||||
int dist = 0;
|
||||
|
||||
while (s1[0] != '\0' && s2[0] != '\0') {
|
||||
if (s1[0] == s2[0]) {
|
||||
s1++;
|
||||
s2++;
|
||||
continue;
|
||||
}
|
||||
if (++dist > maxdist)
|
||||
return INT_MAX;
|
||||
if (s1[1] == s2[1]) { /* replacement */
|
||||
s1++;
|
||||
s2++;
|
||||
} else if (s1[0] == s2[1] && s1[1] == s2[0]) {
|
||||
s1 += 2; /* transposition */
|
||||
s2 += 2;
|
||||
} else if (s1[0] == s2[1]) /* insertion */
|
||||
s2++;
|
||||
else if (s1[1] == s2[0]) /* deletion */
|
||||
s1++;
|
||||
else
|
||||
return INT_MAX;
|
||||
}
|
||||
dist += strlen(s1) + strlen(s2);
|
||||
return dist > maxdist ? INT_MAX : dist;
|
||||
}
|
||||
|
||||
static void
|
||||
post_sh_head(POST_ARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
const char *goodsec;
|
||||
const char *const *testsec;
|
||||
int dist, mindist;
|
||||
enum roff_sec sec;
|
||||
|
||||
/*
|
||||
@ -2023,8 +2319,25 @@ post_sh_head(POST_ARGS)
|
||||
|
||||
/* We don't care about custom sections after this. */
|
||||
|
||||
if (sec == SEC_CUSTOM)
|
||||
if (sec == SEC_CUSTOM) {
|
||||
if ((nch = mdoc->last->child) == NULL ||
|
||||
nch->type != ROFFT_TEXT || nch->next != NULL)
|
||||
return;
|
||||
goodsec = NULL;
|
||||
mindist = INT_MAX;
|
||||
for (testsec = secnames + 1; *testsec != NULL; testsec++) {
|
||||
dist = similar(nch->string, *testsec);
|
||||
if (dist < mindist) {
|
||||
goodsec = *testsec;
|
||||
mindist = dist;
|
||||
}
|
||||
}
|
||||
if (goodsec != NULL)
|
||||
mandoc_vmsg(MANDOCERR_SEC_TYPO, mdoc->parse,
|
||||
nch->line, nch->pos, "Sh %s instead of %s",
|
||||
nch->string, goodsec);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether our non-custom section is being repeated or is
|
||||
@ -2090,9 +2403,15 @@ post_xr(POST_ARGS)
|
||||
if (nch->next == NULL) {
|
||||
mandoc_vmsg(MANDOCERR_XR_NOSEC, mdoc->parse,
|
||||
n->line, n->pos, "Xr %s", nch->string);
|
||||
return;
|
||||
} else {
|
||||
assert(nch->next == n->last);
|
||||
if(mandoc_xr_add(nch->next->string, nch->string,
|
||||
nch->line, nch->pos))
|
||||
mandoc_vmsg(MANDOCERR_XR_SELF, mdoc->parse,
|
||||
nch->line, nch->pos, "Xr %s %s",
|
||||
nch->string, nch->next->string);
|
||||
}
|
||||
assert(nch->next == n->last);
|
||||
post_delim_nb(mdoc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2105,6 +2424,7 @@ post_ignpar(POST_ARGS)
|
||||
post_prevpar(mdoc);
|
||||
return;
|
||||
case ROFFT_HEAD:
|
||||
post_delim(mdoc);
|
||||
post_hyph(mdoc);
|
||||
return;
|
||||
case ROFFT_BODY:
|
||||
@ -2224,7 +2544,7 @@ post_dd(POST_ARGS)
|
||||
|
||||
if (n->child == NULL || n->child->string[0] == '\0') {
|
||||
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
|
||||
mandoc_normdate(mdoc, NULL, n->line, n->pos);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2233,7 +2553,7 @@ post_dd(POST_ARGS)
|
||||
if (mdoc->quick)
|
||||
mdoc->meta.date = datestr;
|
||||
else {
|
||||
mdoc->meta.date = mandoc_normdate(mdoc->parse,
|
||||
mdoc->meta.date = mandoc_normdate(mdoc,
|
||||
datestr, n->line, n->pos);
|
||||
free(datestr);
|
||||
}
|
||||
@ -2341,6 +2661,8 @@ post_bx(POST_ARGS)
|
||||
struct roff_node *n, *nch;
|
||||
const char *macro;
|
||||
|
||||
post_delim_nb(mdoc);
|
||||
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
|
||||
@ -2405,6 +2727,8 @@ post_os(POST_ARGS)
|
||||
mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
|
||||
n->line, n->pos, "Os");
|
||||
|
||||
post_delim(mdoc);
|
||||
|
||||
/*
|
||||
* Set the operating system by way of the `Os' macro.
|
||||
* The order of precedence is:
|
||||
@ -2420,8 +2744,8 @@ post_os(POST_ARGS)
|
||||
if (mdoc->meta.os)
|
||||
goto out;
|
||||
|
||||
if (mdoc->defos) {
|
||||
mdoc->meta.os = mandoc_strdup(mdoc->defos);
|
||||
if (mdoc->os_s != NULL) {
|
||||
mdoc->meta.os = mandoc_strdup(mdoc->os_s);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2440,9 +2764,43 @@ post_os(POST_ARGS)
|
||||
mdoc->meta.os = mandoc_strdup(defbuf);
|
||||
#endif /*!OSNAME*/
|
||||
|
||||
out: mdoc->meta.os_e = strstr(mdoc->meta.os, "OpenBSD") != NULL ?
|
||||
MDOC_OS_OPENBSD : strstr(mdoc->meta.os, "NetBSD") != NULL ?
|
||||
MDOC_OS_NETBSD : MDOC_OS_OTHER;
|
||||
out:
|
||||
if (mdoc->meta.os_e == MANDOC_OS_OTHER) {
|
||||
if (strstr(mdoc->meta.os, "OpenBSD") != NULL)
|
||||
mdoc->meta.os_e = MANDOC_OS_OPENBSD;
|
||||
else if (strstr(mdoc->meta.os, "NetBSD") != NULL)
|
||||
mdoc->meta.os_e = MANDOC_OS_NETBSD;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the earliest point where we can check
|
||||
* Mdocdate conventions because we don't know
|
||||
* the operating system earlier.
|
||||
*/
|
||||
|
||||
if (n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_OS_ARG, mdoc->parse,
|
||||
n->child->line, n->child->pos,
|
||||
"Os %s (%s)", n->child->string,
|
||||
mdoc->meta.os_e == MANDOC_OS_OPENBSD ?
|
||||
"OpenBSD" : "NetBSD");
|
||||
|
||||
while (n->tok != MDOC_Dd)
|
||||
if ((n = n->prev) == NULL)
|
||||
return;
|
||||
if ((n = n->child) == NULL)
|
||||
return;
|
||||
if (strncmp(n->string, "$" "Mdocdate", 9)) {
|
||||
if (mdoc->meta.os_e == MANDOC_OS_OPENBSD)
|
||||
mandoc_vmsg(MANDOCERR_MDOCDATE_MISSING,
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"Dd %s (OpenBSD)", n->string);
|
||||
} else {
|
||||
if (mdoc->meta.os_e == MANDOC_OS_NETBSD)
|
||||
mandoc_vmsg(MANDOCERR_MDOCDATE,
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"Dd %s (NetBSD)", n->string);
|
||||
}
|
||||
}
|
||||
|
||||
enum roff_sec
|
||||
|
8
msec.in
8
msec.in
@ -1,4 +1,4 @@
|
||||
/* $Id: msec.in,v 1.7 2014/08/26 11:21:40 schwarze Exp $ */
|
||||
/* $Id: msec.in,v 1.8 2017/06/24 17:37:06 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -32,9 +32,3 @@ LINE("6", "Games Manual")
|
||||
LINE("7", "Miscellaneous Information Manual")
|
||||
LINE("8", "System Manager\'s Manual")
|
||||
LINE("9", "Kernel Developer\'s Manual")
|
||||
LINE("X11", "X11 Developer\'s Manual")
|
||||
LINE("X11R6", "X11 Developer\'s Manual")
|
||||
LINE("unass", "Unassociated")
|
||||
LINE("local", "Local")
|
||||
LINE("draft", "Draft")
|
||||
LINE("paper", "Paper")
|
||||
|
48
out.c
48
out.c
@ -1,4 +1,4 @@
|
||||
/* $Id: out.c,v 1.65 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.70 2017/06/27 18:25:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -20,6 +20,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -85,10 +86,8 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
case 'v':
|
||||
dst->unit = SCALE_VS;
|
||||
break;
|
||||
case '\0':
|
||||
endptr--;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
endptr--;
|
||||
if (SCALE_MAX == def)
|
||||
return NULL;
|
||||
dst->unit = def;
|
||||
@ -105,7 +104,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
*/
|
||||
void
|
||||
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
size_t totalwidth)
|
||||
size_t offset, size_t rmargin)
|
||||
{
|
||||
struct roffsu su;
|
||||
const struct tbl_opts *opts;
|
||||
@ -142,8 +141,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
if (1 < spans)
|
||||
continue;
|
||||
icol = dp->layout->col;
|
||||
if (maxcol < icol)
|
||||
maxcol = icol;
|
||||
while (maxcol < icol)
|
||||
tbl->cols[++maxcol].spacing = SIZE_MAX;
|
||||
col = tbl->cols + icol;
|
||||
col->flags |= dp->layout->flags;
|
||||
if (dp->layout->flags & TBL_CELL_WIGN)
|
||||
@ -156,8 +155,15 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
(*tbl->sulen)(&su, tbl->arg);
|
||||
if (col->width < dp->layout->width)
|
||||
col->width = dp->layout->width;
|
||||
tblcalc_data(tbl, col, opts, dp, dp->block ?
|
||||
totalwidth / (sp->opts->cols + 1) : 0);
|
||||
if (dp->layout->spacing != SIZE_MAX &&
|
||||
(col->spacing == SIZE_MAX ||
|
||||
col->spacing < dp->layout->spacing))
|
||||
col->spacing = dp->layout->spacing;
|
||||
tblcalc_data(tbl, col, opts, dp,
|
||||
dp->block == 0 ? 0 :
|
||||
dp->layout->width ? dp->layout->width :
|
||||
rmargin ? (rmargin + sp->opts->cols / 2)
|
||||
/ (sp->opts->cols + 1) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,6 +177,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
ewidth = xwidth = 0;
|
||||
for (icol = 0; icol <= maxcol; icol++) {
|
||||
col = tbl->cols + icol;
|
||||
if (col->spacing == SIZE_MAX || icol == maxcol)
|
||||
col->spacing = 3;
|
||||
if (col->flags & TBL_CELL_EQUAL) {
|
||||
necol++;
|
||||
if (ewidth < col->width)
|
||||
@ -194,7 +202,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
continue;
|
||||
if (col->width == ewidth)
|
||||
continue;
|
||||
if (nxcol && totalwidth)
|
||||
if (nxcol && rmargin)
|
||||
xwidth += ewidth - col->width;
|
||||
col->width = ewidth;
|
||||
}
|
||||
@ -206,13 +214,13 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
* Distribute the available width evenly.
|
||||
*/
|
||||
|
||||
if (nxcol && totalwidth) {
|
||||
if (nxcol && rmargin) {
|
||||
xwidth += 3*maxcol +
|
||||
(opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ?
|
||||
2 : !!opts->lvert + !!opts->rvert);
|
||||
if (xwidth >= totalwidth)
|
||||
if (rmargin <= offset + xwidth)
|
||||
return;
|
||||
xwidth = totalwidth - xwidth;
|
||||
xwidth = rmargin - offset - xwidth;
|
||||
|
||||
/*
|
||||
* Emulate a bug in GNU tbl width calculation that
|
||||
@ -281,11 +289,13 @@ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
|
||||
const char *str; /* Beginning of the first line. */
|
||||
const char *beg; /* Beginning of the current line. */
|
||||
char *end; /* End of the current line. */
|
||||
size_t sz; /* Length of the current line. */
|
||||
size_t lsz; /* Length of the current line. */
|
||||
size_t wsz; /* Length of the current word. */
|
||||
|
||||
if (dp->string == NULL || *dp->string == '\0')
|
||||
return;
|
||||
str = mw ? mandoc_strdup(dp->string) : dp->string;
|
||||
lsz = 0;
|
||||
for (beg = str; beg != NULL && *beg != '\0'; beg = end) {
|
||||
end = mw ? strchr(beg, ' ') : NULL;
|
||||
if (end != NULL) {
|
||||
@ -293,9 +303,13 @@ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
|
||||
while (*end == ' ')
|
||||
end++;
|
||||
}
|
||||
sz = (*tbl->slen)(beg, tbl->arg);
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
wsz = (*tbl->slen)(beg, tbl->arg);
|
||||
if (mw && lsz && lsz + 1 + wsz <= mw)
|
||||
lsz += 1 + wsz;
|
||||
else
|
||||
lsz = wsz;
|
||||
if (col->width < lsz)
|
||||
col->width = lsz;
|
||||
}
|
||||
if (mw)
|
||||
free((void *)str);
|
||||
|
5
out.h
5
out.h
@ -1,4 +1,4 @@
|
||||
/* $Id: out.h,v 1.29 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: out.h,v 1.31 2017/06/27 18:25:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -33,6 +33,7 @@ enum roffscale {
|
||||
struct roffcol {
|
||||
size_t width; /* width of cell */
|
||||
size_t decimal; /* decimal position in cell */
|
||||
size_t spacing; /* spacing after the column */
|
||||
int flags; /* layout flags, see tbl_cell */
|
||||
};
|
||||
|
||||
@ -68,4 +69,4 @@ struct tbl_span;
|
||||
|
||||
const char *a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
void tblcalc(struct rofftbl *tbl,
|
||||
const struct tbl_span *, size_t);
|
||||
const struct tbl_span *, size_t, size_t);
|
||||
|
103
read.c
103
read.c
@ -1,4 +1,4 @@
|
||||
/* $Id: read.c,v 1.173 2017/06/08 00:23:30 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.192 2017/07/20 14:36:36 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -24,9 +24,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
@ -42,7 +39,6 @@
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
|
||||
#define REPARSE_LIMIT 1000
|
||||
|
||||
@ -53,10 +49,10 @@ struct mparse {
|
||||
const char *file; /* filename of current input file */
|
||||
struct buf *primary; /* buffer currently being parsed */
|
||||
struct buf *secondary; /* preprocessed copy of input */
|
||||
const char *defos; /* default operating system */
|
||||
const char *os_s; /* default operating system */
|
||||
mandocmsg mmsg; /* warning/error message handler */
|
||||
enum mandoclevel file_status; /* status of current parse */
|
||||
enum mandoclevel wlevel; /* ignore messages below this */
|
||||
enum mandocerr mmin; /* ignore messages below this */
|
||||
int options; /* parser options */
|
||||
int gzip; /* current input file is gzipped */
|
||||
int filenc; /* encoding of the current file */
|
||||
@ -75,7 +71,7 @@ static void mparse_parse_buffer(struct mparse *, struct buf,
|
||||
|
||||
static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = {
|
||||
MANDOCERR_OK,
|
||||
MANDOCERR_STYLE,
|
||||
MANDOCERR_OK,
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_ERROR,
|
||||
MANDOCERR_UNSUPP,
|
||||
@ -86,28 +82,46 @@ static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = {
|
||||
static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"ok",
|
||||
|
||||
"base system convention",
|
||||
|
||||
"Mdocdate found",
|
||||
"Mdocdate missing",
|
||||
"unknown architecture",
|
||||
"operating system explicitly specified",
|
||||
"RCS id missing",
|
||||
"referenced manual not found",
|
||||
|
||||
"generic style suggestion",
|
||||
|
||||
"legacy man(7) date format",
|
||||
"lower case character in document title",
|
||||
"duplicate RCS id",
|
||||
"typo in section name",
|
||||
"unterminated quoted argument",
|
||||
"useless macro",
|
||||
"consider using OS macro",
|
||||
"errnos out of order",
|
||||
"duplicate errno",
|
||||
"description line ends with a full stop",
|
||||
"trailing delimiter",
|
||||
"no blank before trailing delimiter",
|
||||
"fill mode already enabled, skipping",
|
||||
"fill mode already disabled, skipping",
|
||||
"function name without markup",
|
||||
"whitespace at end of input line",
|
||||
"bad comment style",
|
||||
|
||||
"generic warning",
|
||||
|
||||
/* related to the prologue */
|
||||
"missing manual title, using UNTITLED",
|
||||
"missing manual title, using \"\"",
|
||||
"lower case character in document title",
|
||||
"missing manual section, using \"\"",
|
||||
"unknown manual section",
|
||||
"missing date, using today's date",
|
||||
"cannot parse date, using it verbatim",
|
||||
"date in the future, using it anyway",
|
||||
"missing Os macro, using \"\"",
|
||||
"duplicate prologue macro",
|
||||
"late prologue macro",
|
||||
"skipping late title macro",
|
||||
"prologue macros out of order",
|
||||
|
||||
/* related to document structure */
|
||||
@ -125,6 +139,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"sections out of conventional order",
|
||||
"duplicate section title",
|
||||
"unexpected section",
|
||||
"cross reference to self",
|
||||
"unusual Xr order",
|
||||
"unusual Xr punctuation",
|
||||
"AUTHORS section without An macro",
|
||||
@ -138,8 +153,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"blocks badly nested",
|
||||
"nested displays are not portable",
|
||||
"moving content out of list",
|
||||
"fill mode already enabled, skipping",
|
||||
"fill mode already disabled, skipping",
|
||||
"first macro on line",
|
||||
"line scope broken",
|
||||
"skipping blank line in line scope",
|
||||
|
||||
@ -156,6 +170,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"missing function name, using \"\"",
|
||||
"empty head in list item",
|
||||
"empty list item",
|
||||
"missing argument, using next line",
|
||||
"missing font type, using \\fR",
|
||||
"unknown font type, using \\fR",
|
||||
"nothing follows prefix",
|
||||
@ -167,7 +182,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"missing eqn box, using \"\"",
|
||||
|
||||
/* related to bad macro arguments */
|
||||
"unterminated quoted argument",
|
||||
"duplicate argument",
|
||||
"skipping duplicate argument",
|
||||
"skipping duplicate display type",
|
||||
@ -186,9 +200,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
/* related to plain text */
|
||||
"blank line in fill mode, using .sp",
|
||||
"tab in filled text",
|
||||
"whitespace at end of input line",
|
||||
"new sentence, new line",
|
||||
"bad comment style",
|
||||
"invalid escape sequence",
|
||||
"undefined string, using \"\"",
|
||||
|
||||
@ -214,6 +226,8 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
|
||||
/* related to document structure and macros */
|
||||
NULL,
|
||||
"duplicate prologue macro",
|
||||
"skipping late title macro",
|
||||
"input stack limit exceeded, infinite loop?",
|
||||
"skipping bad character",
|
||||
"skipping unknown macro",
|
||||
@ -325,7 +339,6 @@ choose_parser(struct mparse *curp)
|
||||
static int
|
||||
mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
{
|
||||
const struct tbl_span *span;
|
||||
struct buf ln;
|
||||
const char *save_file;
|
||||
char *cp;
|
||||
@ -516,21 +529,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
if (curp->man->macroset == MACROSET_NONE)
|
||||
choose_parser(curp);
|
||||
|
||||
/*
|
||||
* Lastly, push down into the parsers themselves.
|
||||
* If libroff returns ROFF_TBL, then add it to the
|
||||
* currently open parse. Since we only get here if
|
||||
* there does exist data (see tbl_data.c), we're
|
||||
* guaranteed that something's been allocated.
|
||||
* Do the same for ROFF_EQN.
|
||||
*/
|
||||
|
||||
if (rr == ROFF_TBL)
|
||||
while ((span = roff_span(curp->roff)) != NULL)
|
||||
roff_addtbl(curp->man, span);
|
||||
else if (rr == ROFF_EQN)
|
||||
roff_addeqn(curp->man, roff_eqn(curp->roff));
|
||||
else if ((curp->man->macroset == MACROSET_MDOC ?
|
||||
if ((curp->man->macroset == MACROSET_MDOC ?
|
||||
mdoc_parseln(curp->man, curp->line, ln.buf, of) :
|
||||
man_parseln(curp->man, curp->line, ln.buf, of)) == 2)
|
||||
break;
|
||||
@ -558,8 +557,11 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
size_t off;
|
||||
ssize_t ssz;
|
||||
|
||||
if (fstat(fd, &st) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", file);
|
||||
if (fstat(fd, &st) == -1) {
|
||||
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
|
||||
"fstat: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're a regular file, try just reading in the whole entry
|
||||
@ -581,8 +583,11 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
}
|
||||
|
||||
if (curp->gzip) {
|
||||
if ((gz = gzdopen(fd, "rb")) == NULL)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", file);
|
||||
if ((gz = gzdopen(fd, "rb")) == NULL) {
|
||||
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
|
||||
"gzdopen: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
gz = NULL;
|
||||
|
||||
@ -611,8 +616,11 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
fb->sz = off;
|
||||
return 1;
|
||||
}
|
||||
if (ssz == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", file);
|
||||
if (ssz == -1) {
|
||||
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
|
||||
"read: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
off += (size_t)ssz;
|
||||
}
|
||||
|
||||
@ -748,20 +756,20 @@ mparse_open(struct mparse *curp, const char *file)
|
||||
}
|
||||
|
||||
struct mparse *
|
||||
mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||
const char *defos)
|
||||
mparse_alloc(int options, enum mandocerr mmin, mandocmsg mmsg,
|
||||
enum mandoc_os os_e, const char *os_s)
|
||||
{
|
||||
struct mparse *curp;
|
||||
|
||||
curp = mandoc_calloc(1, sizeof(struct mparse));
|
||||
|
||||
curp->options = options;
|
||||
curp->wlevel = wlevel;
|
||||
curp->mmin = mmin;
|
||||
curp->mmsg = mmsg;
|
||||
curp->defos = defos;
|
||||
curp->os_s = os_s;
|
||||
|
||||
curp->roff = roff_alloc(curp, options);
|
||||
curp->man = roff_man_alloc( curp->roff, curp, curp->defos,
|
||||
curp->man = roff_man_alloc(curp->roff, curp, curp->os_s,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
if (curp->options & MPARSE_MDOC) {
|
||||
curp->man->macroset = MACROSET_MDOC;
|
||||
@ -773,6 +781,7 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||
curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX);
|
||||
}
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
curp->man->meta.os_e = os_e;
|
||||
return curp;
|
||||
}
|
||||
|
||||
@ -848,13 +857,13 @@ mandoc_msg(enum mandocerr er, struct mparse *m,
|
||||
{
|
||||
enum mandoclevel level;
|
||||
|
||||
if (er < m->mmin && er != MANDOCERR_FILE)
|
||||
return;
|
||||
|
||||
level = MANDOCLEVEL_UNSUPP;
|
||||
while (er < mandoclimits[level])
|
||||
level--;
|
||||
|
||||
if (level < m->wlevel && er != MANDOCERR_FILE)
|
||||
return;
|
||||
|
||||
if (m->mmsg)
|
||||
(*m->mmsg)(er, level, m->file, ln, col, msg);
|
||||
|
||||
|
70
roff.7
70
roff.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: roff.7,v 1.86 2017/06/07 00:50:34 schwarze Exp $
|
||||
.\" $Id: roff.7,v 1.94 2017/07/05 12:25:17 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010,2011,2013-2015,2017 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: June 7 2017 $
|
||||
.Dd $Mdocdate: July 5 2017 $
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -180,7 +180,7 @@ single-character
|
||||
two-character
|
||||
.Sq \e*(XX ,
|
||||
and N-character
|
||||
.Sq \e*[N] .
|
||||
.Sq \e* Ns Bq N .
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
@ -412,7 +412,6 @@ Create an alias for a number register.
|
||||
Currently unsupported.
|
||||
.It Ic \&als Ar newname oldname
|
||||
Create an alias for a request, string, macro, or diversion.
|
||||
Currently unsupported.
|
||||
.It Ic \&am Ar macroname Op Ar endmacro
|
||||
Append to a macro definition.
|
||||
The syntax of this request is the same as that of
|
||||
@ -1045,8 +1044,6 @@ If the first character of
|
||||
is
|
||||
.Sq c
|
||||
.Pq character available ,
|
||||
.Sq d
|
||||
.Pq string defined ,
|
||||
.Sq e
|
||||
.Pq even page ,
|
||||
.Sq t
|
||||
@ -1059,6 +1056,15 @@ it evaluates to false.
|
||||
If the first character of
|
||||
.Ar condition
|
||||
is
|
||||
.Sq d ,
|
||||
it evaluates to true if the rest of
|
||||
.Ar condition
|
||||
is the name of an existing user defined macro or string;
|
||||
otherwise, it evaluates to false.
|
||||
.It
|
||||
If the first character of
|
||||
.Ar condition
|
||||
is
|
||||
.Sq r ,
|
||||
it evaluates to true if the rest of
|
||||
.Ar condition
|
||||
@ -1435,8 +1441,15 @@ Currently ignored.
|
||||
Print all number registers on standard error output.
|
||||
Currently ignored.
|
||||
.It Ic \&po Op Oo Cm + Ns | Ns Cm - Oc Ns Ar offset
|
||||
Set horizontal page offset.
|
||||
Currently ignored.
|
||||
Set a horizontal page offset.
|
||||
If no argument is specified, the page offset is reverted to its
|
||||
previous value.
|
||||
If a sign is specified, the new page offset is calculated relative
|
||||
to the current one; otherwise, it is absolute.
|
||||
The argument follows the syntax of
|
||||
.Sx Scaling Widths
|
||||
and the default scaling unit is
|
||||
.Cm m .
|
||||
.It Ic \&ps Op Oo Cm + Ns | Ns Cm - Oc Ns size
|
||||
Change point size.
|
||||
Currently ignored.
|
||||
@ -1477,7 +1490,9 @@ This is a Heirloom extension and currently ignored.
|
||||
Justify the next
|
||||
.Ar N
|
||||
input lines to the right margin without filling.
|
||||
Currently ignored.
|
||||
.Ar N
|
||||
defaults to 1.
|
||||
An argument of 0 or less ends right adjustment.
|
||||
.It Ic \&rm Ar macroname
|
||||
Remove a request, macro or string.
|
||||
.It Ic \&rn Ar oldname newname
|
||||
@ -1783,7 +1798,7 @@ logical and (corresponds to C
|
||||
.Ic && )
|
||||
.It Ic \&:
|
||||
logical or (corresponds to C
|
||||
.Ic \&|| )
|
||||
.Ic || )
|
||||
.It Ic <?
|
||||
minimum (not available in C)
|
||||
.It Ic >?
|
||||
@ -1839,7 +1854,7 @@ instead.
|
||||
.Sx Special Characters
|
||||
with two-letter names, see
|
||||
.Xr mandoc_char 7 .
|
||||
.Ss \e*[ Ns Ar name ]
|
||||
.Ss \e* Ns Bq Ar name
|
||||
Interpolate the string with the
|
||||
.Ar name ;
|
||||
see
|
||||
@ -1859,7 +1874,7 @@ Special character
|
||||
.Ss \e/
|
||||
Right italic correction (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \e[ Ns Ar name ]
|
||||
.Ss \e Ns Bq Ar name
|
||||
.Sx Special Characters
|
||||
with names of arbitrary length, see
|
||||
.Xr mandoc_char 7 .
|
||||
@ -1915,14 +1930,14 @@ Move down by half a line; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ee
|
||||
Backslash special character.
|
||||
.Ss \eF[ Ns Ar name ]
|
||||
.Ss \eF Ns Bq Ar name
|
||||
Switch font family (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eF Ns Ar c
|
||||
and
|
||||
.No \eF( Ns Ar cc .
|
||||
.Ss \ef[ Ns Ar name ]
|
||||
.Ss \ef Ns Bq Ar name
|
||||
Switch to the font
|
||||
.Ar name ,
|
||||
see
|
||||
@ -1931,7 +1946,7 @@ For short names, there are variants
|
||||
.No \ef Ns Ar c
|
||||
and
|
||||
.No \ef( Ns Ar cc .
|
||||
.Ss \eg[ Ns Ar name ]
|
||||
.Ss \eg Ns Bq Ar name
|
||||
Interpolate the format of a number register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
@ -1941,11 +1956,14 @@ and
|
||||
.Ss \eH\(aq Ns Oo +|- Oc Ns Ar number Ns \(aq
|
||||
Set the height of the current font; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eh\(aq Ns Ar width Ns \(aq
|
||||
Horizontal motion relative to the current position.
|
||||
.Ss \eh\(aq Ns Oo Cm \&| Oc Ns Ar width Ns \(aq
|
||||
Horizontal motion.
|
||||
If the vertical bar is given, the motion is relative to the current
|
||||
indentation.
|
||||
Otherwise, it is relative to the current position.
|
||||
The default scaling unit is
|
||||
.Cm m .
|
||||
.Ss \ek[ Ns Ar name ]
|
||||
.Ss \ek Ns Bq Ar name
|
||||
Mark horizontal input place in register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
@ -1960,14 +1978,14 @@ Draw a horizontal line of
|
||||
.Ar width
|
||||
using the glyph
|
||||
.Ar c .
|
||||
.Ss \eM[ Ns Ar name ]
|
||||
.Ss \eM Ns Bq Ar name
|
||||
Set fill (background) color (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eM Ns Ar c
|
||||
and
|
||||
.No \eM( Ns Ar cc .
|
||||
.Ss \em[ Ns Ar name ]
|
||||
.Ss \em Ns Bq Ar name
|
||||
Set glyph drawing color (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
@ -1978,7 +1996,7 @@ and
|
||||
Character
|
||||
.Ar number
|
||||
on the current font.
|
||||
.Ss \en[ Ns Ar name ]
|
||||
.Ss \en Ns Bq Ar name
|
||||
Interpolate the number register
|
||||
.Ar name .
|
||||
For short names, there are variants
|
||||
@ -1991,6 +2009,8 @@ Overstrike, writing all the characters contained in the
|
||||
to the same output position.
|
||||
In terminal and HTML output modes,
|
||||
only the last one of the characters is visible.
|
||||
.Ss \ep
|
||||
Break the output line at the end of the current word.
|
||||
.Ss \eR\(aq Ns Ar name Oo +|- Oc Ns Ar number Ns \(aq
|
||||
Set number register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
@ -2003,9 +2023,9 @@ Change point size; ignored by
|
||||
Alternative forms
|
||||
.No \es Ns Oo +|- Oc Ns Ar n ,
|
||||
.No \es Ns Oo +|- Oc Ns \(aq Ns Ar number Ns \(aq ,
|
||||
.No \es Ns [ Oo +|- Oc Ns Ar number ] ,
|
||||
.No \es Ns Bq Oo +|- Oc Ns Ar number ,
|
||||
and
|
||||
.No \es Ns Oo +|- Oc Ns [ Ar number Ns ]
|
||||
.No \es Ns Oo +|- Oc Ns Bq Ar number
|
||||
are also parsed and ignored.
|
||||
.Ss \et
|
||||
Horizontal tab; ignored by
|
||||
@ -2013,7 +2033,7 @@ Horizontal tab; ignored by
|
||||
.Ss \eu
|
||||
Move up by half a line; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eV[ Ns Ar name ]
|
||||
.Ss \eV Ns Bq Ar name
|
||||
Interpolate an environment variable; ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
@ -2040,7 +2060,7 @@ as device control function; ignored in nroff mode and by
|
||||
.Ss \ex\(aq Ns Ar number Ns \(aq
|
||||
Extra line space function; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eY[ Ns Ar name ]
|
||||
.Ss \eY Ns Bq Ar name
|
||||
Output a string as a device control function; ignored in nroff mode and by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
|
21
roff.h
21
roff.h
@ -1,4 +1,4 @@
|
||||
/* $Id: roff.h,v 1.52 2017/06/07 23:29:49 schwarze Exp $ */
|
||||
/* $Id: roff.h,v 1.58 2017/07/08 14:51:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -26,12 +26,6 @@ enum roff_macroset {
|
||||
MACROSET_MAN
|
||||
};
|
||||
|
||||
enum mdoc_os {
|
||||
MDOC_OS_OTHER = 0,
|
||||
MDOC_OS_NETBSD,
|
||||
MDOC_OS_OPENBSD
|
||||
};
|
||||
|
||||
enum roff_sec {
|
||||
SEC_NONE = 0,
|
||||
SEC_NAME,
|
||||
@ -77,6 +71,8 @@ enum roff_tok {
|
||||
ROFF_ft,
|
||||
ROFF_ll,
|
||||
ROFF_mc,
|
||||
ROFF_po,
|
||||
ROFF_rj,
|
||||
ROFF_sp,
|
||||
ROFF_ta,
|
||||
ROFF_ti,
|
||||
@ -244,7 +240,6 @@ enum roff_tok {
|
||||
ROFF_pm,
|
||||
ROFF_pn,
|
||||
ROFF_pnr,
|
||||
ROFF_po,
|
||||
ROFF_ps,
|
||||
ROFF_psbb,
|
||||
ROFF_pshape,
|
||||
@ -257,7 +252,6 @@ enum roff_tok {
|
||||
ROFF_return,
|
||||
ROFF_rfschar,
|
||||
ROFF_rhang,
|
||||
ROFF_rj,
|
||||
ROFF_rm,
|
||||
ROFF_rn,
|
||||
ROFF_rnn,
|
||||
@ -473,6 +467,8 @@ enum roff_tok {
|
||||
MAN_EE,
|
||||
MAN_UR,
|
||||
MAN_UE,
|
||||
MAN_MT,
|
||||
MAN_ME,
|
||||
MAN_MAX
|
||||
};
|
||||
|
||||
@ -503,7 +499,7 @@ struct roff_node {
|
||||
union mdoc_data *norm; /* Normalized arguments. */
|
||||
char *string; /* TEXT */
|
||||
const struct tbl_span *span; /* TBL */
|
||||
const struct eqn *eqn; /* EQN */
|
||||
struct eqn_box *eqn; /* EQN */
|
||||
int line; /* Input file line number. */
|
||||
int pos; /* Input file column number. */
|
||||
int flags;
|
||||
@ -534,7 +530,8 @@ struct roff_meta {
|
||||
char *name; /* Leading manual name. */
|
||||
char *date; /* Normalized date. */
|
||||
int hasbody; /* Document is not empty. */
|
||||
enum mdoc_os os_e; /* Operating system. */
|
||||
int rcsids; /* Bits indexed by enum mandoc_os. */
|
||||
enum mandoc_os os_e; /* Operating system. */
|
||||
};
|
||||
|
||||
struct roff_man {
|
||||
@ -543,7 +540,7 @@ struct roff_man {
|
||||
struct roff *roff; /* Roff parser state data. */
|
||||
struct ohash *mdocmac; /* Mdoc macro lookup table. */
|
||||
struct ohash *manmac; /* Man macro lookup table. */
|
||||
const char *defos; /* Default operating system. */
|
||||
const char *os_s; /* Default operating system. */
|
||||
struct roff_node *first; /* The first node parsed. */
|
||||
struct roff_node *last; /* The last node parsed. */
|
||||
struct roff_node *last_es; /* The most recent Es node. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: roff_html.c,v 1.8 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: roff_html.c,v 1.11 2017/06/24 14:38:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -20,6 +20,7 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
@ -38,6 +39,8 @@ static const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = {
|
||||
NULL, /* ft */
|
||||
NULL, /* ll */
|
||||
NULL, /* mc */
|
||||
NULL, /* po */
|
||||
roff_html_pre_ce, /* rj */
|
||||
roff_html_pre_sp, /* sp */
|
||||
NULL, /* ta */
|
||||
NULL, /* ti */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: roff_int.h,v 1.7 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: roff_int.h,v 1.9 2017/07/08 17:52:50 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -25,8 +25,6 @@ void roff_elem_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *roff_block_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *roff_head_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *roff_body_alloc(struct roff_man *, int, int, int);
|
||||
void roff_addeqn(struct roff_man *, const struct eqn *);
|
||||
void roff_addtbl(struct roff_man *, const struct tbl_span *);
|
||||
void roff_node_unlink(struct roff_man *, struct roff_node *);
|
||||
void roff_node_free(struct roff_node *);
|
||||
void roff_node_delete(struct roff_man *, struct roff_node *);
|
||||
|
59
roff_term.c
59
roff_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: roff_term.c,v 1.10 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: roff_term.c,v 1.14 2017/06/24 14:38:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -19,6 +19,7 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
@ -32,6 +33,7 @@ static void roff_term_pre_ce(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ft(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ll(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_mc(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_po(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_sp(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ta(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ti(ROFF_TERM_ARGS);
|
||||
@ -42,6 +44,8 @@ static const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = {
|
||||
roff_term_pre_ft, /* ft */
|
||||
roff_term_pre_ll, /* ll */
|
||||
roff_term_pre_mc, /* mc */
|
||||
roff_term_pre_po, /* po */
|
||||
roff_term_pre_ce, /* rj */
|
||||
roff_term_pre_sp, /* sp */
|
||||
roff_term_pre_ta, /* ta */
|
||||
roff_term_pre_ti, /* ti */
|
||||
@ -69,33 +73,34 @@ roff_term_pre_br(ROFF_TERM_ARGS)
|
||||
static void
|
||||
roff_term_pre_ce(ROFF_TERM_ARGS)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
const struct roff_node *nc1, *nc2;
|
||||
size_t len, lm;
|
||||
|
||||
roff_term_pre_br(p, n);
|
||||
lm = p->tcol->offset;
|
||||
n = n->child->next;
|
||||
while (n != NULL) {
|
||||
nch = n;
|
||||
nc1 = n->child->next;
|
||||
while (nc1 != NULL) {
|
||||
nc2 = nc1;
|
||||
len = 0;
|
||||
do {
|
||||
if (n->type == ROFFT_TEXT) {
|
||||
if (nc2->type == ROFFT_TEXT) {
|
||||
if (len)
|
||||
len++;
|
||||
len += term_strlen(p, nch->string);
|
||||
len += term_strlen(p, nc2->string);
|
||||
}
|
||||
nch = nch->next;
|
||||
} while (nch != NULL && (n->type != ROFFT_TEXT ||
|
||||
(n->flags & NODE_LINE) == 0));
|
||||
nc2 = nc2->next;
|
||||
} while (nc2 != NULL && (nc2->type != ROFFT_TEXT ||
|
||||
(nc2->flags & NODE_LINE) == 0));
|
||||
p->tcol->offset = len >= p->tcol->rmargin ? 0 :
|
||||
lm + len >= p->tcol->rmargin ? p->tcol->rmargin - len :
|
||||
n->tok == ROFF_rj ? p->tcol->rmargin - len :
|
||||
(lm + p->tcol->rmargin - len) / 2;
|
||||
while (n != nch) {
|
||||
if (n->type == ROFFT_TEXT)
|
||||
term_word(p, n->string);
|
||||
while (nc1 != nc2) {
|
||||
if (nc1->type == ROFFT_TEXT)
|
||||
term_word(p, nc1->string);
|
||||
else
|
||||
roff_term_pre(p, n);
|
||||
n = n->next;
|
||||
roff_term_pre(p, nc1);
|
||||
nc1 = nc1->next;
|
||||
}
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_flushln(p);
|
||||
@ -150,6 +155,28 @@ roff_term_pre_mc(ROFF_TERM_ARGS)
|
||||
p->flags |= TERMP_ENDMC;
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_po(ROFF_TERM_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
static int po, polast;
|
||||
int ponew;
|
||||
|
||||
if (n->child != NULL &&
|
||||
a2roffsu(n->child->string, &su, SCALE_EM) != NULL) {
|
||||
ponew = term_hen(p, &su);
|
||||
if (*n->child->string == '+' ||
|
||||
*n->child->string == '-')
|
||||
ponew += po;
|
||||
} else
|
||||
ponew = polast;
|
||||
polast = po;
|
||||
po = ponew;
|
||||
|
||||
ponew = po - polast + (int)p->tcol->offset;
|
||||
p->tcol->offset = ponew > 0 ? ponew : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_sp(ROFF_TERM_ARGS)
|
||||
{
|
||||
@ -203,7 +230,7 @@ roff_term_pre_ti(ROFF_TERM_ARGS)
|
||||
|
||||
if (a2roffsu(cp, &su, SCALE_EM) == NULL)
|
||||
return;
|
||||
len = term_hspan(p, &su) / 24;
|
||||
len = term_hen(p, &su);
|
||||
|
||||
if (sign == 0) {
|
||||
p->ti = len - p->tcol->offset;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: roff_validate.c,v 1.7 2017/06/06 15:01:04 schwarze Exp $ */
|
||||
/* $Id: roff_validate.c,v 1.9 2017/06/14 22:51:25 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -36,6 +36,8 @@ static const roff_valid_fp roff_valids[ROFF_MAX] = {
|
||||
roff_valid_ft, /* ft */
|
||||
NULL, /* ll */
|
||||
NULL, /* mc */
|
||||
NULL, /* po */
|
||||
NULL, /* rj */
|
||||
NULL, /* sp */
|
||||
NULL, /* ta */
|
||||
NULL, /* ti */
|
||||
|
10
soelim.1
10
soelim.1
@ -1,4 +1,4 @@
|
||||
.\" $Id: soelim.1,v 1.4 2017/03/18 19:56:01 schwarze Exp $
|
||||
.\" $Id: soelim.1,v 1.5 2017/07/04 23:40:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
.\" All rights reserved.
|
||||
@ -24,7 +24,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: March 18 2017 $
|
||||
.Dd $Mdocdate: July 4 2017 $
|
||||
.Dt SOELIM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -53,15 +53,15 @@ Recognise
|
||||
when not followed by a space character.
|
||||
.It Fl r
|
||||
Compatibility with GNU groff's
|
||||
.Xr soelim 1
|
||||
.Nm soelim
|
||||
(does nothing).
|
||||
.It Fl t
|
||||
Compatibility with GNU groff's
|
||||
.Xr soelim 1
|
||||
.Nm soelim
|
||||
(does nothing).
|
||||
.It Fl v
|
||||
Compatibility with GNU groff's
|
||||
.Xr soelim 1
|
||||
.Nm soelim
|
||||
(does nothing).
|
||||
.It Fl I Ar dir
|
||||
This option specify directories where
|
||||
|
3
st.c
3
st.c
@ -1,4 +1,4 @@
|
||||
/* $Id: st.c,v 1.13 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/* $Id: st.c,v 1.14 2017/06/24 14:38:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
3
st.in
3
st.in
@ -1,4 +1,4 @@
|
||||
/* $Id: st.in,v 1.28 2015/02/17 20:37:17 schwarze Exp $ */
|
||||
/* $Id: st.in,v 1.29 2017/06/24 13:49:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -34,7 +34,6 @@ LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1-2013", "IEEE Std 1003.1-2008/Cor 1-2013 (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1", "IEEE Std 1003.1 (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(LqPOSIX.1b\\(Rq)")
|
||||
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(LqPOSIX.1b\\(Rq)")
|
||||
|
440
tbl.7
440
tbl.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: tbl.7,v 1.27 2017/06/08 18:11:22 schwarze Exp $
|
||||
.\" $Id: tbl.7,v 1.28 2017/06/28 00:59:57 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2014, 2015, 2017 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: June 8 2017 $
|
||||
.Dd $Mdocdate: June 28 2017 $
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -24,128 +24,43 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm tbl
|
||||
language is a table-formatting language.
|
||||
language formats tables.
|
||||
It is used within
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
.Ux
|
||||
manual pages.
|
||||
pages.
|
||||
This manual describes the subset of the
|
||||
.Nm
|
||||
language accepted by the
|
||||
.Xr mandoc 1
|
||||
utility.
|
||||
.Pp
|
||||
Tables within
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
are enclosed by the
|
||||
.Sq TS
|
||||
and
|
||||
.Sq TE
|
||||
macro tags, whose precise syntax is documented in
|
||||
.Xr roff 7 .
|
||||
Tables consist of a series of options on a single line, followed by the
|
||||
table layout, followed by data.
|
||||
.Pp
|
||||
For example, the following creates a boxed table with digits centered in
|
||||
the cells.
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
tab(:) box;
|
||||
c5 c5 c5.
|
||||
1:2:3
|
||||
4:5:6
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
When formatted, the following output is produced:
|
||||
.Bd -filled -offset indent -compact
|
||||
.TS
|
||||
tab(:) box;
|
||||
c5 c5 c5.
|
||||
1:2:3
|
||||
4:5:6
|
||||
.TE
|
||||
.Ed
|
||||
.Sh TABLE STRUCTURE
|
||||
Tables are enclosed by the
|
||||
.Sq TS
|
||||
and
|
||||
.Sq TE
|
||||
Each table is started with a
|
||||
.Xr roff 7
|
||||
macros.
|
||||
A table consists of an optional single line of table
|
||||
.Sx Options
|
||||
terminated by a semicolon, followed by one or more lines of
|
||||
.Ic \&TS
|
||||
macro, consist of at most one line of
|
||||
.Sx Options ,
|
||||
one or more
|
||||
.Sx Layout
|
||||
specifications terminated by a period, then
|
||||
.Sx Data .
|
||||
lines, one or more
|
||||
.Sx Data
|
||||
lines, and ends with a
|
||||
.Ic \&TE
|
||||
macro.
|
||||
All input must be 7-bit ASCII.
|
||||
Example:
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
box tab(:);
|
||||
c | c
|
||||
| c | c.
|
||||
1:2
|
||||
3:4
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
Table data is
|
||||
.Em pre-processed ,
|
||||
that is, data rows are parsed then inserted into the underlying stream
|
||||
of input data.
|
||||
This allows data rows to be interspersed by arbitrary
|
||||
.Xr roff 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
and
|
||||
.Xr man 7
|
||||
macros such as
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
tab(:);
|
||||
c c c.
|
||||
1:2:3
|
||||
\&.Ao
|
||||
3:2:1
|
||||
\&.Ac
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
in the case of
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
tab(:);
|
||||
c c c.
|
||||
\&.ds ab 2
|
||||
1:\e*(ab:3
|
||||
\&.I
|
||||
3:2:1
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
in the case of
|
||||
.Xr man 7 .
|
||||
.Ss Options
|
||||
The first line of a table may contain options separated by spaces, tabs,
|
||||
or commas and terminated by a semicolon.
|
||||
If the first line does not have a terminating semicolon, it is assumed
|
||||
that no options are specified and instead a
|
||||
If the first input line of a table ends with a semicolon, it contains
|
||||
case-insensitive options separated by spaces, tabs, or commas.
|
||||
Otherwise, it is interpreted as the first
|
||||
.Sx Layout
|
||||
is processed.
|
||||
Some options require arguments enclosed by parentheses.
|
||||
The following case-insensitive options are available:
|
||||
line.
|
||||
.Pp
|
||||
The following options are available.
|
||||
Some of them require arguments enclosed in parentheses:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm allbox
|
||||
Draw a single-line box around each table cell.
|
||||
Currently treated as a synonym for
|
||||
.Cm box .
|
||||
.It Cm box
|
||||
Draw a single-line box around the table.
|
||||
For GNU compatibility, this may also be invoked with
|
||||
@ -185,73 +100,77 @@ Suppress warnings about tables exceeding the current line length.
|
||||
This is a GNU extension and currently ignored.
|
||||
.It Cm tab
|
||||
Use the single-character argument as a delimiter between data cells.
|
||||
By default, the tab character is used.
|
||||
By default, the horizontal tabulator character is used.
|
||||
.El
|
||||
.Ss Layout
|
||||
The table layout follows
|
||||
The table layout follows an
|
||||
.Sx Options
|
||||
or a
|
||||
.Sq \&T&
|
||||
macro invocation.
|
||||
Layout specifies how data rows are displayed on output.
|
||||
Each layout line corresponds to a line of data; the last layout line
|
||||
applies to all remaining data lines.
|
||||
Layout lines may also be separated by a comma.
|
||||
Each layout cell consists of one of the following case-insensitive keys:
|
||||
line or a
|
||||
.Xr roff 7
|
||||
.Ic \&TS
|
||||
or
|
||||
.Ic \&T&
|
||||
macro.
|
||||
Each layout line specifies how one line of
|
||||
.Sx Data
|
||||
is formatted.
|
||||
The last layout line ends with a full stop.
|
||||
It also applies to all remaining data lines.
|
||||
Multiple layout lines can be joined by commas on a single physical
|
||||
input line.
|
||||
.Pp
|
||||
Each layout line consists of one or more layout cell specifications,
|
||||
optionally separated by whitespace.
|
||||
The following case-insensitive key characters start a new cell
|
||||
specification:
|
||||
.Bl -tag -width 2n
|
||||
.It Cm c
|
||||
Center a literal string within its column.
|
||||
Center the string in this cell.
|
||||
.It Cm r
|
||||
Right-justify a literal string within its column.
|
||||
Right-justify the string in this cell.
|
||||
.It Cm l
|
||||
Left-justify a literal string within its column.
|
||||
Left-justify the string in this cell.
|
||||
.It Cm n
|
||||
Justify a number around its last decimal point.
|
||||
If the decimal point is not found on the number, it's assumed to trail
|
||||
the number.
|
||||
If no decimal point is found in the number,
|
||||
it is assumed to trail the number.
|
||||
.It Cm s
|
||||
Horizontally span columns from the last
|
||||
.No non- Ns Cm s
|
||||
data cell.
|
||||
It is an error if spanning columns follow a
|
||||
.Cm \-
|
||||
.Pf non- Cm s
|
||||
layout cell.
|
||||
It is an error if a column span follows a
|
||||
.Cm _
|
||||
or
|
||||
.Cm \(ba
|
||||
cell, or come first.
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.Cm =
|
||||
cell, or comes first on a layout line.
|
||||
The combined cell as a whole consumes only one cell
|
||||
of the corresponding data line.
|
||||
.It Cm a
|
||||
Left-justify a literal string and pad with one space.
|
||||
Left-justify a string and pad with one space.
|
||||
.It Cm ^
|
||||
Vertically span rows from the last
|
||||
.No non- Ns Cm ^
|
||||
data cell.
|
||||
It is an error to invoke a vertical span on the first layout row.
|
||||
Unlike a horizontal spanner, you must specify an empty cell (if it not
|
||||
empty, the data is discarded) in the corresponding data cell.
|
||||
.It Cm \-
|
||||
Replace the data cell (its contents will be lost) with a single
|
||||
horizontal line.
|
||||
This may also be invoked with
|
||||
.Cm _ .
|
||||
.Pf non- Cm ^
|
||||
layout cell.
|
||||
It is an error to invoke a vertical span on the first layout line.
|
||||
Unlike a horizontal span, a vertical span consumes a data cell
|
||||
and discards the content.
|
||||
.It Cm _
|
||||
Draw a single horizontal line in this cell.
|
||||
This consumes a data cell and discards the content.
|
||||
It may also be invoked with
|
||||
.Cm \- .
|
||||
.It Cm =
|
||||
Replace the data cell (its contents will be lost) with a double
|
||||
horizontal line.
|
||||
.It Cm \(ba
|
||||
Emit a vertical bar instead of data.
|
||||
.It Cm \(ba\(ba
|
||||
Emit a double-vertical bar instead of data.
|
||||
Draw a double horizontal line in this cell.
|
||||
This consumes a data cell and discards the content.
|
||||
.El
|
||||
.Pp
|
||||
Keys may be followed by a set of modifiers.
|
||||
A modifier is either a modifier key or a natural number for specifying
|
||||
the spacing to the right of the column.
|
||||
The following case-insensitive modifier keys are available:
|
||||
Each cell key may be followed by zero or more of the following
|
||||
case-insensitive modifiers:
|
||||
.Bl -tag -width 2n
|
||||
.It Cm b
|
||||
Use a bold font for the contents of this column.
|
||||
Use a bold font for the contents of this cell.
|
||||
.It Cm d
|
||||
Move cell content down to the last cell of a vertical span.
|
||||
Move content down to the last row of this vertical span.
|
||||
Currently ignored.
|
||||
.It Cm e
|
||||
Make this column wider to match the maximum width
|
||||
@ -259,12 +178,12 @@ of any other column also having the
|
||||
.Cm e
|
||||
modifier.
|
||||
.It Cm f
|
||||
The next character selects the font to use for this column.
|
||||
The next character selects the font to use for this cell.
|
||||
See the
|
||||
.Xr roff 7
|
||||
manual for supported one-character font names.
|
||||
.It Cm i
|
||||
Use an italic font for the contents of this column.
|
||||
Use an italic font for the contents of this cell.
|
||||
.It Cm m
|
||||
Specify a cell start macro.
|
||||
This is a GNU extension and currently unsupported.
|
||||
@ -277,14 +196,14 @@ Set the vertical line spacing to the following unsigned argument,
|
||||
or change it by the following signed argument.
|
||||
Currently ignored.
|
||||
.It Cm t
|
||||
Do not vertically center cell content in the vertical span,
|
||||
leave it at the top.
|
||||
Do not vertically center content in this vertical span,
|
||||
leave it in the top row.
|
||||
Currently ignored.
|
||||
.It Cm u
|
||||
Move cell content up by half a table line.
|
||||
Move cell content up by half a table row.
|
||||
Currently ignored.
|
||||
.It Cm w
|
||||
Specify the minimum column width.
|
||||
Specify a minimum column width.
|
||||
.It Cm x
|
||||
After determining the width of all other columns, distribute the
|
||||
rest of the line length among all columns having the
|
||||
@ -292,40 +211,185 @@ rest of the line length among all columns having the
|
||||
modifier.
|
||||
.It Cm z
|
||||
Do not use this cell for determining the width of this column.
|
||||
.It Cm \&|
|
||||
Draw a single vertical line to the right of this cell.
|
||||
.It Cm ||
|
||||
Draw a double vertical line to the right of this cell.
|
||||
.El
|
||||
.Pp
|
||||
For example, the following layout specifies a center-justified column of
|
||||
minimum width 10, followed by vertical bar, followed by a left-justified
|
||||
column of minimum width 10, another vertical bar, then a column using
|
||||
bold font justified about the decimal point in numbers:
|
||||
.Pp
|
||||
.Dl cw10 | lw10 | nfB
|
||||
If a modifier consists of decimal digits,
|
||||
it specifies a minimum spacing in units of
|
||||
.Cm n
|
||||
between this column and the next column to the right.
|
||||
The default is 3.
|
||||
If there is a vertical line, it is drawn inside the spacing.
|
||||
.Ss Data
|
||||
The data section follows the last layout row.
|
||||
By default, cells in a data section are delimited by a tab.
|
||||
This behaviour may be changed with the
|
||||
The data section follows the last
|
||||
.Sx Layout
|
||||
line.
|
||||
Each data line consists of one or more data cells, delimited by
|
||||
.Cm tab
|
||||
option.
|
||||
If
|
||||
.Cm _
|
||||
characters.
|
||||
.Pp
|
||||
If a data cells contains only the single character
|
||||
.Ql _
|
||||
or
|
||||
.Cm =
|
||||
is specified, a single or double line, respectively, is drawn across the
|
||||
data field.
|
||||
If
|
||||
.Cm \e-
|
||||
.Ql = ,
|
||||
a single or double horizontal line is drawn across the cell,
|
||||
joining its neighbours.
|
||||
If a data cells contains only the two character sequence
|
||||
.Ql \e_
|
||||
or
|
||||
.Cm \e=
|
||||
is specified, a line is drawn within the data field (i.e. terminating
|
||||
within the cell and not draw to the border).
|
||||
If the last cell of a line is
|
||||
.Cm T{ ,
|
||||
all subsequent lines are included as part of the cell until
|
||||
.Cm T}
|
||||
is specified as its own data cell.
|
||||
It may then be followed by a tab
|
||||
.Pq or as designated by Cm tab
|
||||
or an end-of-line to terminate the row.
|
||||
.Ql \e= ,
|
||||
a single or double horizontal line is drawn inside the cell,
|
||||
not joining its neighbours.
|
||||
If a data line contains nothing but the single character
|
||||
.Ql _
|
||||
or
|
||||
.Ql = ,
|
||||
a horizontal line across the whole table is inserted
|
||||
without consuming a layout row.
|
||||
.Pp
|
||||
In place of any data cell, a text block can be used.
|
||||
It starts with
|
||||
.Ic \&T{
|
||||
at the end of a physical input line.
|
||||
Input line breaks inside the text block
|
||||
neither end the text block nor its data cell.
|
||||
It only ends if
|
||||
.Ic \&T}
|
||||
occurs at the beginning of a physical input line and is followed
|
||||
by an end-of-cell indicator.
|
||||
If the
|
||||
.Ic \&T}
|
||||
is followed by the end of the physical input line, the text block,
|
||||
the data cell, and the data line ends at this point.
|
||||
If the
|
||||
.Ic \&T}
|
||||
is followed by the
|
||||
.Cm tab
|
||||
character, only the text block and the data cell end,
|
||||
but the data line continues with the data cell following the
|
||||
.Cm tab
|
||||
character.
|
||||
If
|
||||
.Ic \&T}
|
||||
is followed by any other character, it does not end the text block,
|
||||
which instead continues to the following physical input line.
|
||||
.Sh EXAMPLES
|
||||
String justification and font selection:
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
rb c lb
|
||||
r ci l.
|
||||
r center l
|
||||
ri ce le
|
||||
right c left
|
||||
\&.TE
|
||||
.Ed
|
||||
.Bd -filled -offset indent
|
||||
.TS
|
||||
rb c lb
|
||||
r ci l.
|
||||
r center l
|
||||
ri ce le
|
||||
right c left
|
||||
.TE
|
||||
.Ed
|
||||
.Pp
|
||||
Some ports in
|
||||
.Ox 6.1
|
||||
to show number alignment and line drawing:
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
box tab(:);
|
||||
r| l
|
||||
r n.
|
||||
software:version
|
||||
_
|
||||
AFL:2.39b
|
||||
Mutt:1.8.0
|
||||
Ruby:1.8.7.374
|
||||
TeX Live:2015
|
||||
\&.TE
|
||||
.Ed
|
||||
.Bd -filled -offset indent
|
||||
.TS
|
||||
box tab(:);
|
||||
r| l
|
||||
r n.
|
||||
software:version
|
||||
_
|
||||
AFL:2.39b
|
||||
Mutt:1.8.0
|
||||
Ruby:1.8.7.374
|
||||
TeX Live:2015
|
||||
.TE
|
||||
.Ed
|
||||
.sp 2v
|
||||
Spans and skipping width calculations:
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
box tab(:);
|
||||
lz s | rt
|
||||
lt| cb| ^
|
||||
^ | rz s.
|
||||
left:r
|
||||
l:center:
|
||||
:right
|
||||
\&.TE
|
||||
.Ed
|
||||
.Bd -filled -offset indent
|
||||
.TS
|
||||
box tab(:);
|
||||
lz s | rt
|
||||
lt| cb| ^
|
||||
^ | rz s.
|
||||
left:r
|
||||
l:center:
|
||||
:right
|
||||
.TE
|
||||
.Ed
|
||||
.sp 2v
|
||||
Text blocks, specifying spacings and specifying and equalizing
|
||||
column widths, putting lines into individual cells, and overriding
|
||||
.Cm allbox :
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
allbox tab(:);
|
||||
le le||7 lw10.
|
||||
The fourth line:_:line 1
|
||||
of this column:=:line 2
|
||||
determines:\_:line 3
|
||||
the column width.:T{
|
||||
This text is too wide to fit into a column of width 17.
|
||||
T}:line 4
|
||||
T{
|
||||
No break here.
|
||||
T}::line 5
|
||||
\&.TE
|
||||
.Ed
|
||||
.Bd -filled -offset indent
|
||||
.TS
|
||||
allbox tab(:);
|
||||
le le||7 lw10.
|
||||
The fourth line:_:line 1
|
||||
of this column:=:line 2
|
||||
determines:\_:line 3
|
||||
the column width.:T{
|
||||
This text is too wide to fit into a column of width 17.
|
||||
T}:line 4
|
||||
T{
|
||||
No break here.
|
||||
T}::line 5
|
||||
.TE
|
||||
.Ed
|
||||
.sp 2v
|
||||
These examples were constructed to demonstrate many
|
||||
.Nm
|
||||
features in a compact way.
|
||||
In real manual pages, keep tables as simple as possible:
|
||||
Like that, they usually look better, are less fragile, and more portable.
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Xr mandoc 1
|
||||
@ -363,4 +427,6 @@ utility.
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
and
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
||||
|
21
tbl.c
21
tbl.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl.c,v 1.41 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: tbl.c,v 1.42 2017/07/08 17:52:50 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -31,7 +31,7 @@
|
||||
#include "libroff.h"
|
||||
|
||||
|
||||
enum rofferr
|
||||
void
|
||||
tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
{
|
||||
const char *cp;
|
||||
@ -66,7 +66,7 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
if (*cp == ';') {
|
||||
tbl_option(tbl, ln, p, &pos);
|
||||
if (p[pos] == '\0')
|
||||
return ROFF_IGN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,15 +75,14 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
switch (tbl->part) {
|
||||
case TBL_PART_LAYOUT:
|
||||
tbl_layout(tbl, ln, p, pos);
|
||||
return ROFF_IGN;
|
||||
break;
|
||||
case TBL_PART_CDATA:
|
||||
return tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN;
|
||||
tbl_cdata(tbl, ln, p, pos);
|
||||
break;
|
||||
default:
|
||||
tbl_data(tbl, ln, p, pos);
|
||||
break;
|
||||
}
|
||||
|
||||
tbl_data(tbl, ln, p, pos);
|
||||
return ROFF_TBL;
|
||||
}
|
||||
|
||||
struct tbl_node *
|
||||
@ -160,14 +159,10 @@ tbl_span(struct tbl_node *tbl)
|
||||
}
|
||||
|
||||
int
|
||||
tbl_end(struct tbl_node **tblp)
|
||||
tbl_end(struct tbl_node *tbl)
|
||||
{
|
||||
struct tbl_node *tbl;
|
||||
struct tbl_span *sp;
|
||||
|
||||
tbl = *tblp;
|
||||
*tblp = NULL;
|
||||
|
||||
if (tbl->part == TBL_PART_CDATA)
|
||||
mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse,
|
||||
tbl->line, tbl->pos, "TE");
|
||||
|
111
tbl_data.c
111
tbl_data.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_data.c,v 1.42 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: tbl_data.c,v 1.45 2017/07/08 17:52:50 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -51,17 +51,26 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
||||
cp = cp->next;
|
||||
|
||||
/*
|
||||
* Stop processing when we reach the end of the available layout
|
||||
* cells. This means that we have extra input.
|
||||
* If the current layout row is out of cells, allocate
|
||||
* a new cell if another row of the table has at least
|
||||
* this number of columns, or discard the input if we
|
||||
* are beyond the last column of the table as a whole.
|
||||
*/
|
||||
|
||||
if (cp == NULL) {
|
||||
mandoc_msg(MANDOCERR_TBLDATA_EXTRA, tbl->parse,
|
||||
ln, *pos, p + *pos);
|
||||
/* Skip to the end... */
|
||||
while (p[*pos])
|
||||
(*pos)++;
|
||||
return;
|
||||
if (dp->layout->last->col + 1 < dp->opts->cols) {
|
||||
cp = mandoc_calloc(1, sizeof(*cp));
|
||||
cp->pos = TBL_CELL_LEFT;
|
||||
dp->layout->last->next = cp;
|
||||
cp->col = dp->layout->last->col + 1;
|
||||
dp->layout->last = cp;
|
||||
} else {
|
||||
mandoc_msg(MANDOCERR_TBLDATA_EXTRA, tbl->parse,
|
||||
ln, *pos, p + *pos);
|
||||
while (p[*pos])
|
||||
(*pos)++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dat = mandoc_calloc(1, sizeof(*dat));
|
||||
@ -119,7 +128,7 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
||||
tbl->parse, ln, sv, dat->string);
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
{
|
||||
struct tbl_dat *dat;
|
||||
@ -134,10 +143,10 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
pos++;
|
||||
while (p[pos] != '\0')
|
||||
getdata(tbl, tbl->last_span, ln, p, &pos);
|
||||
return 1;
|
||||
return;
|
||||
} else if (p[pos] == '\0') {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fallthrough: T} is part of a word. */
|
||||
@ -157,8 +166,6 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
if (dat->layout->pos == TBL_CELL_DOWN)
|
||||
mandoc_msg(MANDOCERR_TBLDATA_SPAN, tbl->parse,
|
||||
ln, pos, dat->string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct tbl_span *
|
||||
@ -185,58 +192,50 @@ newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
|
||||
void
|
||||
tbl_data(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
{
|
||||
struct tbl_span *dp;
|
||||
struct tbl_row *rp;
|
||||
struct tbl_cell *cp;
|
||||
struct tbl_span *sp;
|
||||
|
||||
/*
|
||||
* Choose a layout row: take the one following the last parsed
|
||||
* span's. If that doesn't exist, use the last parsed span's.
|
||||
* If there's no last parsed span, use the first row. Lastly,
|
||||
* if the last span was a horizontal line, use the same layout
|
||||
* (it doesn't "consume" the layout).
|
||||
*/
|
||||
rp = (sp = tbl->last_span) == NULL ? tbl->first_row :
|
||||
sp->pos == TBL_SPAN_DATA && sp->layout->next != NULL ?
|
||||
sp->layout->next : sp->layout;
|
||||
|
||||
if (tbl->last_span != NULL) {
|
||||
if (tbl->last_span->pos == TBL_SPAN_DATA) {
|
||||
for (rp = tbl->last_span->layout->next;
|
||||
rp != NULL && rp->first != NULL;
|
||||
rp = rp->next) {
|
||||
switch (rp->first->pos) {
|
||||
case TBL_CELL_HORIZ:
|
||||
dp = newspan(tbl, ln, rp);
|
||||
dp->pos = TBL_SPAN_HORIZ;
|
||||
continue;
|
||||
case TBL_CELL_DHORIZ:
|
||||
dp = newspan(tbl, ln, rp);
|
||||
dp->pos = TBL_SPAN_DHORIZ;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
rp = tbl->last_span->layout;
|
||||
|
||||
if (rp == NULL)
|
||||
rp = tbl->last_span->layout;
|
||||
} else
|
||||
rp = tbl->first_row;
|
||||
|
||||
assert(rp);
|
||||
|
||||
dp = newspan(tbl, ln, rp);
|
||||
assert(rp != NULL);
|
||||
|
||||
if ( ! strcmp(p, "_")) {
|
||||
dp->pos = TBL_SPAN_HORIZ;
|
||||
sp = newspan(tbl, ln, rp);
|
||||
sp->pos = TBL_SPAN_HORIZ;
|
||||
return;
|
||||
} else if ( ! strcmp(p, "=")) {
|
||||
dp->pos = TBL_SPAN_DHORIZ;
|
||||
sp = newspan(tbl, ln, rp);
|
||||
sp->pos = TBL_SPAN_DHORIZ;
|
||||
return;
|
||||
}
|
||||
|
||||
dp->pos = TBL_SPAN_DATA;
|
||||
/*
|
||||
* If the layout row contains nothing but horizontal lines,
|
||||
* allocate an empty span for it and assign the current span
|
||||
* to the next layout row accepting data.
|
||||
*/
|
||||
|
||||
while (rp->next != NULL) {
|
||||
if (rp->last->col + 1 < tbl->opts.cols)
|
||||
break;
|
||||
for (cp = rp->first; cp != NULL; cp = cp->next)
|
||||
if (cp->pos != TBL_CELL_HORIZ &&
|
||||
cp->pos != TBL_CELL_DHORIZ)
|
||||
break;
|
||||
if (cp != NULL)
|
||||
break;
|
||||
sp = newspan(tbl, ln, rp);
|
||||
sp->pos = TBL_SPAN_DATA;
|
||||
rp = rp->next;
|
||||
}
|
||||
|
||||
/* Process a real data row. */
|
||||
|
||||
sp = newspan(tbl, ln, rp);
|
||||
sp->pos = TBL_SPAN_DATA;
|
||||
while (p[pos] != '\0')
|
||||
getdata(tbl, dp, ln, p, &pos);
|
||||
getdata(tbl, sp, ln, p, &pos);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_html.c,v 1.21 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.22 2017/06/12 20:14:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -83,7 +83,7 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
|
||||
h->tbl.len = html_tbl_len;
|
||||
h->tbl.slen = html_tbl_strlen;
|
||||
h->tbl.sulen = html_tbl_sulen;
|
||||
tblcalc(&h->tbl, sp, 0);
|
||||
tblcalc(&h->tbl, sp, 0, 0);
|
||||
}
|
||||
|
||||
assert(NULL == h->tblt);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_layout.c,v 1.42 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: tbl_layout.c,v 1.44 2017/06/27 18:25:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -20,6 +20,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -298,6 +299,8 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
tbl->parse, ln, pos, NULL);
|
||||
cell_alloc(tbl, tbl->first_row,
|
||||
TBL_CELL_LEFT);
|
||||
if (tbl->opts.lvert < tbl->first_row->vert)
|
||||
tbl->opts.lvert = tbl->first_row->vert;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -355,6 +358,7 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
|
||||
struct tbl_cell *p, *pp;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(*p));
|
||||
p->spacing = SIZE_MAX;
|
||||
p->pos = pos;
|
||||
|
||||
if ((pp = rp->last) != NULL) {
|
||||
|
466
tbl_term.c
466
tbl_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_term.c,v 1.46 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.56 2017/07/08 13:43:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -28,11 +28,15 @@
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
#define IS_HORIZ(cp) ((cp)->pos == TBL_CELL_HORIZ || \
|
||||
(cp)->pos == TBL_CELL_DHORIZ)
|
||||
|
||||
static size_t term_tbl_len(size_t, void *);
|
||||
static size_t term_tbl_strlen(const char *, void *);
|
||||
static size_t term_tbl_sulen(const struct roffsu *, void *);
|
||||
static void tbl_char(struct termp *, char, size_t);
|
||||
static void tbl_data(struct termp *, const struct tbl_opts *,
|
||||
const struct tbl_cell *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_literal(struct termp *, const struct tbl_dat *,
|
||||
@ -47,7 +51,7 @@ static void tbl_word(struct termp *, const struct tbl_dat *);
|
||||
static size_t
|
||||
term_tbl_sulen(const struct roffsu *su, void *arg)
|
||||
{
|
||||
return term_hspan((const struct termp *)arg, su) / 24;
|
||||
return term_hen((const struct termp *)arg, su);
|
||||
}
|
||||
|
||||
static size_t
|
||||
@ -65,15 +69,16 @@ term_tbl_len(size_t sz, void *arg)
|
||||
void
|
||||
term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_cell *cp;
|
||||
const struct tbl_cell *cp, *cpn, *cpp;
|
||||
const struct tbl_dat *dp;
|
||||
static size_t offset;
|
||||
size_t tsz;
|
||||
int ic, horiz, spans, vert;
|
||||
size_t coloff, tsz;
|
||||
int ic, horiz, spans, vert, more;
|
||||
char fc;
|
||||
|
||||
/* Inhibit printing of spaces: we do padding ourselves. */
|
||||
|
||||
tp->flags |= TERMP_NOSPACE | TERMP_NONOSPACE | TERMP_BRNEVER;
|
||||
tp->flags |= TERMP_NOSPACE | TERMP_NONOSPACE;
|
||||
|
||||
/*
|
||||
* The first time we're invoked for a given table block,
|
||||
@ -86,7 +91,18 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
tp->tbl.sulen = term_tbl_sulen;
|
||||
tp->tbl.arg = tp;
|
||||
|
||||
tblcalc(&tp->tbl, sp, tp->tcol->rmargin - tp->tcol->offset);
|
||||
tblcalc(&tp->tbl, sp, tp->tcol->offset, tp->tcol->rmargin);
|
||||
|
||||
/* Tables leak .ta settings to subsequent text. */
|
||||
|
||||
term_tab_set(tp, NULL);
|
||||
coloff = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ||
|
||||
sp->opts->lvert;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++) {
|
||||
coloff += tp->tbl.cols[ic].width;
|
||||
term_tab_iset(coloff);
|
||||
coloff += tp->tbl.cols[ic].spacing;
|
||||
}
|
||||
|
||||
/* Center the table as a whole. */
|
||||
|
||||
@ -94,9 +110,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
if (sp->opts->opts & TBL_OPT_CENTRE) {
|
||||
tsz = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)
|
||||
? 2 : !!sp->opts->lvert + !!sp->opts->rvert;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++)
|
||||
tsz += tp->tbl.cols[ic].width + 3;
|
||||
tsz -= 3;
|
||||
for (ic = 0; ic + 1 < sp->opts->cols; ic++)
|
||||
tsz += tp->tbl.cols[ic].width +
|
||||
tp->tbl.cols[ic].spacing;
|
||||
if (sp->opts->cols)
|
||||
tsz += tp->tbl.cols[sp->opts->cols - 1].width;
|
||||
if (offset + tsz > tp->tcol->rmargin)
|
||||
tsz -= 1;
|
||||
tp->tcol->offset = offset + tp->tcol->rmargin > tsz ?
|
||||
@ -106,140 +124,377 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
/* Horizontal frame at the start of boxed tables. */
|
||||
|
||||
if (sp->opts->opts & TBL_OPT_DBOX)
|
||||
tbl_hrule(tp, sp, 2);
|
||||
tbl_hrule(tp, sp, 3);
|
||||
if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX))
|
||||
tbl_hrule(tp, sp, 1);
|
||||
tbl_hrule(tp, sp, 2);
|
||||
}
|
||||
|
||||
/* Vertical frame at the start of each row. */
|
||||
/* Set up the columns. */
|
||||
|
||||
horiz = sp->pos == TBL_SPAN_HORIZ || sp->pos == TBL_SPAN_DHORIZ;
|
||||
tp->flags |= TERMP_MULTICOL;
|
||||
horiz = 0;
|
||||
switch (sp->pos) {
|
||||
case TBL_SPAN_HORIZ:
|
||||
case TBL_SPAN_DHORIZ:
|
||||
horiz = 1;
|
||||
term_setcol(tp, 1);
|
||||
break;
|
||||
case TBL_SPAN_DATA:
|
||||
term_setcol(tp, sp->opts->cols + 2);
|
||||
coloff = tp->tcol->offset;
|
||||
|
||||
if (sp->layout->vert ||
|
||||
(sp->prev != NULL && sp->prev->layout->vert) ||
|
||||
sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX))
|
||||
term_word(tp, horiz ? "+" : "|");
|
||||
else if (sp->opts->lvert)
|
||||
tbl_char(tp, horiz ? '-' : ASCII_NBRSP, 1);
|
||||
/* Set up a column for a left vertical frame. */
|
||||
|
||||
/*
|
||||
* Now print the actual data itself depending on the span type.
|
||||
* Match data cells to column numbers.
|
||||
*/
|
||||
if (sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ||
|
||||
sp->opts->lvert)
|
||||
coloff++;
|
||||
tp->tcol->rmargin = coloff;
|
||||
|
||||
/* Set up the data columns. */
|
||||
|
||||
if (sp->pos == TBL_SPAN_DATA) {
|
||||
cp = sp->layout->first;
|
||||
dp = sp->first;
|
||||
spans = 0;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++) {
|
||||
|
||||
/*
|
||||
* Remeber whether we need a vertical bar
|
||||
* after this cell.
|
||||
*/
|
||||
|
||||
vert = cp == NULL ? 0 : cp->vert;
|
||||
|
||||
/*
|
||||
* Print the data and advance to the next cell.
|
||||
*/
|
||||
|
||||
if (spans == 0) {
|
||||
tbl_data(tp, sp->opts, dp, tp->tbl.cols + ic);
|
||||
tp->tcol++;
|
||||
tp->tcol->offset = coloff;
|
||||
}
|
||||
coloff += tp->tbl.cols[ic].width;
|
||||
tp->tcol->rmargin = coloff;
|
||||
if (ic + 1 < sp->opts->cols)
|
||||
coloff += tp->tbl.cols[ic].spacing;
|
||||
if (spans) {
|
||||
spans--;
|
||||
continue;
|
||||
}
|
||||
if (dp == NULL)
|
||||
continue;
|
||||
spans = dp->spans;
|
||||
if (ic || sp->layout->first->pos != TBL_CELL_SPAN)
|
||||
dp = dp->next;
|
||||
}
|
||||
|
||||
/* Set up a column for a right vertical frame. */
|
||||
|
||||
tp->tcol++;
|
||||
tp->tcol->offset = coloff + 1;
|
||||
tp->tcol->rmargin = tp->maxrmargin;
|
||||
|
||||
/* Spans may have reduced the number of columns. */
|
||||
|
||||
tp->lasttcol = tp->tcol - tp->tcols;
|
||||
|
||||
/* Fill the buffers for all data columns. */
|
||||
|
||||
tp->tcol = tp->tcols;
|
||||
cp = cpn = sp->layout->first;
|
||||
dp = sp->first;
|
||||
spans = 0;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++) {
|
||||
if (cpn != NULL) {
|
||||
cp = cpn;
|
||||
cpn = cpn->next;
|
||||
}
|
||||
if (spans) {
|
||||
spans--;
|
||||
continue;
|
||||
}
|
||||
tp->tcol++;
|
||||
tp->col = 0;
|
||||
tbl_data(tp, sp->opts, cp, dp, tp->tbl.cols + ic);
|
||||
if (dp == NULL)
|
||||
continue;
|
||||
spans = dp->spans;
|
||||
if (cp->pos != TBL_CELL_SPAN)
|
||||
dp = dp->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Print the vertical frame at the start of each row. */
|
||||
|
||||
tp->tcol = tp->tcols;
|
||||
fc = '\0';
|
||||
if (sp->layout->vert ||
|
||||
(sp->next != NULL && sp->next->layout->vert &&
|
||||
sp->next->pos == TBL_SPAN_DATA) ||
|
||||
(sp->prev != NULL && sp->prev->layout->vert &&
|
||||
(horiz || (IS_HORIZ(sp->layout->first) &&
|
||||
!IS_HORIZ(sp->prev->layout->first)))) ||
|
||||
sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX))
|
||||
fc = horiz || IS_HORIZ(sp->layout->first) ? '+' : '|';
|
||||
else if (horiz && sp->opts->lvert)
|
||||
fc = '-';
|
||||
if (fc != '\0') {
|
||||
(*tp->advance)(tp, tp->tcols->offset);
|
||||
(*tp->letter)(tp, fc);
|
||||
tp->viscol = tp->tcol->offset + 1;
|
||||
}
|
||||
|
||||
/* Print the data cells. */
|
||||
|
||||
more = 0;
|
||||
if (horiz) {
|
||||
tbl_hrule(tp, sp, 0);
|
||||
term_flushln(tp);
|
||||
} else {
|
||||
cp = sp->layout->first;
|
||||
cpn = sp->next == NULL ? NULL :
|
||||
sp->next->layout->first;
|
||||
cpp = sp->prev == NULL ? NULL :
|
||||
sp->prev->layout->first;
|
||||
dp = sp->first;
|
||||
spans = 0;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++) {
|
||||
|
||||
/*
|
||||
* Figure out whether to print a
|
||||
* vertical line after this cell
|
||||
* and advance to next layout cell.
|
||||
*/
|
||||
|
||||
if (cp != NULL) {
|
||||
vert = cp->vert;
|
||||
switch (cp->pos) {
|
||||
case TBL_CELL_HORIZ:
|
||||
fc = '-';
|
||||
break;
|
||||
case TBL_CELL_DHORIZ:
|
||||
fc = '=';
|
||||
break;
|
||||
default:
|
||||
fc = ' ';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
vert = 0;
|
||||
fc = ' ';
|
||||
}
|
||||
if (cpp != NULL) {
|
||||
if (vert == 0 &&
|
||||
cp != NULL &&
|
||||
((IS_HORIZ(cp) &&
|
||||
!IS_HORIZ(cpp)) ||
|
||||
(cp->next != NULL &&
|
||||
cpp->next != NULL &&
|
||||
IS_HORIZ(cp->next) &&
|
||||
!IS_HORIZ(cpp->next))))
|
||||
vert = cpp->vert;
|
||||
cpp = cpp->next;
|
||||
}
|
||||
if (vert == 0 &&
|
||||
sp->opts->opts & TBL_OPT_ALLBOX)
|
||||
vert = 1;
|
||||
if (cpn != NULL) {
|
||||
if (vert == 0)
|
||||
vert = cpn->vert;
|
||||
cpn = cpn->next;
|
||||
}
|
||||
if (cp != NULL)
|
||||
cp = cp->next;
|
||||
|
||||
/*
|
||||
* Skip later cells in a span,
|
||||
* figure out whether to start a span,
|
||||
* and advance to next data cell.
|
||||
*/
|
||||
|
||||
if (spans) {
|
||||
spans--;
|
||||
continue;
|
||||
}
|
||||
if (dp != NULL) {
|
||||
spans = dp->spans;
|
||||
dp = dp->next;
|
||||
if (ic || sp->layout->first->pos
|
||||
!= TBL_CELL_SPAN)
|
||||
dp = dp->next;
|
||||
}
|
||||
} else
|
||||
spans--;
|
||||
if (cp != NULL)
|
||||
cp = cp->next;
|
||||
|
||||
/*
|
||||
* Separate columns, except in the middle
|
||||
* of spans and after the last cell.
|
||||
*/
|
||||
/*
|
||||
* Print one line of text in the cell
|
||||
* and remember whether there is more.
|
||||
*/
|
||||
|
||||
if (ic + 1 == sp->opts->cols || spans)
|
||||
continue;
|
||||
tp->tcol++;
|
||||
if (tp->tcol->col < tp->tcol->lastcol)
|
||||
term_flushln(tp);
|
||||
if (tp->tcol->col < tp->tcol->lastcol)
|
||||
more = 1;
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP, 1);
|
||||
if (vert > 0)
|
||||
tbl_char(tp, '|', vert);
|
||||
if (vert < 2)
|
||||
tbl_char(tp, ASCII_NBRSP, 2 - vert);
|
||||
/*
|
||||
* Vertical frames between data cells,
|
||||
* but not after the last column.
|
||||
*/
|
||||
|
||||
if (fc == ' ' && ((vert == 0 &&
|
||||
(cp == NULL || !IS_HORIZ(cp))) ||
|
||||
tp->tcol + 1 == tp->tcols + tp->lasttcol))
|
||||
continue;
|
||||
|
||||
if (tp->viscol < tp->tcol->rmargin) {
|
||||
(*tp->advance)(tp, tp->tcol->rmargin
|
||||
- tp->viscol);
|
||||
tp->viscol = tp->tcol->rmargin;
|
||||
}
|
||||
while (tp->viscol < tp->tcol->rmargin +
|
||||
tp->tbl.cols[ic].spacing / 2) {
|
||||
(*tp->letter)(tp, fc);
|
||||
tp->viscol++;
|
||||
}
|
||||
|
||||
if (tp->tcol + 1 == tp->tcols + tp->lasttcol)
|
||||
continue;
|
||||
|
||||
if (fc == ' ' && cp != NULL) {
|
||||
switch (cp->pos) {
|
||||
case TBL_CELL_HORIZ:
|
||||
fc = '-';
|
||||
break;
|
||||
case TBL_CELL_DHORIZ:
|
||||
fc = '=';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tp->tbl.cols[ic].spacing) {
|
||||
(*tp->letter)(tp, fc == ' ' ? '|' :
|
||||
vert ? '+' : fc);
|
||||
tp->viscol++;
|
||||
}
|
||||
|
||||
if (fc != ' ') {
|
||||
if (cp != NULL &&
|
||||
cp->pos == TBL_CELL_HORIZ)
|
||||
fc = '-';
|
||||
else if (cp != NULL &&
|
||||
cp->pos == TBL_CELL_DHORIZ)
|
||||
fc = '=';
|
||||
else
|
||||
fc = ' ';
|
||||
}
|
||||
if (tp->tbl.cols[ic].spacing > 2 &&
|
||||
(vert > 1 || fc != ' ')) {
|
||||
(*tp->letter)(tp, fc == ' ' ? '|' :
|
||||
vert > 1 ? '+' : fc);
|
||||
tp->viscol++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (horiz)
|
||||
tbl_hrule(tp, sp, 0);
|
||||
|
||||
/* Vertical frame at the end of each row. */
|
||||
/* Print the vertical frame at the end of each row. */
|
||||
|
||||
if (sp->layout->last->vert ||
|
||||
(sp->prev != NULL && sp->prev->layout->last->vert) ||
|
||||
(sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)))
|
||||
term_word(tp, horiz ? "+" : " |");
|
||||
else if (sp->opts->rvert)
|
||||
tbl_char(tp, horiz ? '-' : ASCII_NBRSP, 1);
|
||||
term_flushln(tp);
|
||||
fc = '\0';
|
||||
if ((sp->layout->last->vert &&
|
||||
sp->layout->last->col + 1 == sp->opts->cols) ||
|
||||
(sp->next != NULL &&
|
||||
sp->next->layout->last->vert &&
|
||||
sp->next->layout->last->col + 1 == sp->opts->cols) ||
|
||||
(sp->prev != NULL &&
|
||||
sp->prev->layout->last->vert &&
|
||||
sp->prev->layout->last->col + 1 == sp->opts->cols &&
|
||||
(horiz || (IS_HORIZ(sp->layout->last) &&
|
||||
!IS_HORIZ(sp->prev->layout->last)))) ||
|
||||
(sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)))
|
||||
fc = horiz || IS_HORIZ(sp->layout->last) ? '+' : '|';
|
||||
else if (horiz && sp->opts->rvert)
|
||||
fc = '-';
|
||||
if (fc != '\0') {
|
||||
if (horiz == 0 && (IS_HORIZ(sp->layout->last) == 0 ||
|
||||
sp->layout->last->col + 1 < sp->opts->cols)) {
|
||||
tp->tcol++;
|
||||
(*tp->advance)(tp,
|
||||
tp->tcol->offset > tp->viscol ?
|
||||
tp->tcol->offset - tp->viscol : 1);
|
||||
}
|
||||
(*tp->letter)(tp, fc);
|
||||
}
|
||||
(*tp->endline)(tp);
|
||||
tp->viscol = 0;
|
||||
} while (more);
|
||||
|
||||
/*
|
||||
* If we're the last row, clean up after ourselves: clear the
|
||||
* existing table configuration and set it to NULL.
|
||||
* Clean up after this row. If it is the last line
|
||||
* of the table, print the box line and clean up
|
||||
* column data; otherwise, print the allbox line.
|
||||
*/
|
||||
|
||||
term_setcol(tp, 1);
|
||||
tp->flags &= ~TERMP_MULTICOL;
|
||||
tp->tcol->rmargin = tp->maxrmargin;
|
||||
if (sp->next == NULL) {
|
||||
if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX)) {
|
||||
tbl_hrule(tp, sp, 1);
|
||||
tbl_hrule(tp, sp, 2);
|
||||
tp->skipvsp = 1;
|
||||
}
|
||||
if (sp->opts->opts & TBL_OPT_DBOX) {
|
||||
tbl_hrule(tp, sp, 2);
|
||||
tbl_hrule(tp, sp, 3);
|
||||
tp->skipvsp = 2;
|
||||
}
|
||||
assert(tp->tbl.cols);
|
||||
free(tp->tbl.cols);
|
||||
tp->tbl.cols = NULL;
|
||||
tp->tcol->offset = offset;
|
||||
}
|
||||
tp->flags &= ~(TERMP_NONOSPACE | TERMP_BRNEVER);
|
||||
} else if (horiz == 0 && sp->opts->opts & TBL_OPT_ALLBOX &&
|
||||
(sp->next == NULL || sp->next->pos == TBL_SPAN_DATA ||
|
||||
sp->next->next != NULL))
|
||||
tbl_hrule(tp, sp, 1);
|
||||
|
||||
tp->flags &= ~TERMP_NONOSPACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kinds of horizontal rulers:
|
||||
* 0: inside the table (single or double line with crossings)
|
||||
* 1: inner frame (single line with crossings and ends)
|
||||
* 2: outer frame (single line without crossings with ends)
|
||||
* 1: inside the table (single or double line with crossings and ends)
|
||||
* 2: inner frame (single line with crossings and ends)
|
||||
* 3: outer frame (single line without crossings with ends)
|
||||
*/
|
||||
static void
|
||||
tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
|
||||
{
|
||||
const struct tbl_cell *c1, *c2;
|
||||
const struct tbl_cell *cp, *cpn, *cpp;
|
||||
const struct roffcol *col;
|
||||
int vert;
|
||||
char line, cross;
|
||||
|
||||
line = (kind == 0 && TBL_SPAN_DHORIZ == sp->pos) ? '=' : '-';
|
||||
cross = (kind < 2) ? '+' : '-';
|
||||
line = (kind < 2 && TBL_SPAN_DHORIZ == sp->pos) ? '=' : '-';
|
||||
cross = (kind < 3) ? '+' : '-';
|
||||
|
||||
if (kind)
|
||||
term_word(tp, "+");
|
||||
c1 = sp->layout->first;
|
||||
c2 = sp->prev == NULL ? NULL : sp->prev->layout->first;
|
||||
if (c2 == c1)
|
||||
c2 = NULL;
|
||||
cp = sp->layout->first;
|
||||
cpp = kind || sp->prev == NULL ? NULL : sp->prev->layout->first;
|
||||
if (cpp == cp)
|
||||
cpp = NULL;
|
||||
cpn = kind > 1 || sp->next == NULL ? NULL : sp->next->layout->first;
|
||||
if (cpn == cp)
|
||||
cpn = NULL;
|
||||
for (;;) {
|
||||
tbl_char(tp, line, tp->tbl.cols[c1->col].width + 1);
|
||||
vert = c1->vert;
|
||||
if ((c1 = c1->next) == NULL)
|
||||
col = tp->tbl.cols + cp->col;
|
||||
tbl_char(tp, line, col->width + col->spacing / 2);
|
||||
vert = cp->vert;
|
||||
if ((cp = cp->next) == NULL)
|
||||
break;
|
||||
if (c2 != NULL) {
|
||||
if (vert < c2->vert)
|
||||
vert = c2->vert;
|
||||
c2 = c2->next;
|
||||
if (cpp != NULL) {
|
||||
if (vert < cpp->vert)
|
||||
vert = cpp->vert;
|
||||
cpp = cpp->next;
|
||||
}
|
||||
if (vert)
|
||||
tbl_char(tp, cross, vert);
|
||||
if (vert < 2)
|
||||
tbl_char(tp, line, 2 - vert);
|
||||
if (cpn != NULL) {
|
||||
if (vert < cpn->vert)
|
||||
vert = cpn->vert;
|
||||
cpn = cpn->next;
|
||||
}
|
||||
if (sp->opts->opts & TBL_OPT_ALLBOX && !vert)
|
||||
vert = 1;
|
||||
if (col->spacing)
|
||||
tbl_char(tp, vert ? cross : line, 1);
|
||||
if (col->spacing > 2)
|
||||
tbl_char(tp, vert > 1 ? cross : line, 1);
|
||||
if (col->spacing > 4)
|
||||
tbl_char(tp, line, (col->spacing - 3) / 2);
|
||||
}
|
||||
if (kind) {
|
||||
term_word(tp, "+");
|
||||
@ -249,18 +504,25 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
|
||||
|
||||
static void
|
||||
tbl_data(struct termp *tp, const struct tbl_opts *opts,
|
||||
const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
const struct tbl_cell *cp, const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
|
||||
if (dp == NULL) {
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
switch (cp->pos) {
|
||||
case TBL_CELL_HORIZ:
|
||||
tbl_char(tp, '-', col->width);
|
||||
return;
|
||||
case TBL_CELL_DHORIZ:
|
||||
tbl_char(tp, '=', col->width);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dp == NULL)
|
||||
return;
|
||||
|
||||
switch (dp->pos) {
|
||||
case TBL_DATA_NONE:
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
return;
|
||||
case TBL_DATA_HORIZ:
|
||||
case TBL_DATA_NHORIZ:
|
||||
@ -274,13 +536,7 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dp->layout->pos) {
|
||||
case TBL_CELL_HORIZ:
|
||||
tbl_char(tp, '-', col->width);
|
||||
break;
|
||||
case TBL_CELL_DHORIZ:
|
||||
tbl_char(tp, '=', col->width);
|
||||
break;
|
||||
switch (cp->pos) {
|
||||
case TBL_CELL_LONG:
|
||||
case TBL_CELL_CENTRE:
|
||||
case TBL_CELL_LEFT:
|
||||
@ -291,7 +547,7 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
|
||||
tbl_number(tp, opts, dp, col);
|
||||
break;
|
||||
case TBL_CELL_DOWN:
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
case TBL_CELL_SPAN:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
|
132
term.c
132
term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: term.c,v 1.268 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.274 2017/07/28 14:25:48 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -39,6 +39,18 @@ static void encode1(struct termp *, int);
|
||||
static void endline(struct termp *);
|
||||
|
||||
|
||||
void
|
||||
term_setcol(struct termp *p, size_t maxtcol)
|
||||
{
|
||||
if (maxtcol > p->maxtcol) {
|
||||
p->tcols = mandoc_recallocarray(p->tcols,
|
||||
p->maxtcol, maxtcol, sizeof(*p->tcols));
|
||||
p->maxtcol = maxtcol;
|
||||
}
|
||||
p->lasttcol = maxtcol - 1;
|
||||
p->tcol = p->tcols;
|
||||
}
|
||||
|
||||
void
|
||||
term_free(struct termp *p)
|
||||
{
|
||||
@ -104,6 +116,7 @@ term_flushln(struct termp *p)
|
||||
size_t jhy; /* last hyph before overflow w/r/t j */
|
||||
size_t maxvis; /* output position of visible boundary */
|
||||
int ntab; /* number of tabs to prepend */
|
||||
int breakline; /* after this word */
|
||||
|
||||
vbl = (p->flags & TERMP_NOPAD) || p->tcol->offset < p->viscol ?
|
||||
0 : p->tcol->offset - p->viscol;
|
||||
@ -116,9 +129,9 @@ term_flushln(struct termp *p)
|
||||
p->maxrmargin - p->viscol - vbl : 0;
|
||||
vis = vend = 0;
|
||||
|
||||
if (p->lasttcol == 0)
|
||||
if ((p->flags & TERMP_MULTICOL) == 0)
|
||||
p->tcol->col = 0;
|
||||
while (p->tcol->col < p->lastcol) {
|
||||
while (p->tcol->col < p->tcol->lastcol) {
|
||||
|
||||
/*
|
||||
* Handle literal tab characters: collapse all
|
||||
@ -126,7 +139,7 @@ term_flushln(struct termp *p)
|
||||
*/
|
||||
|
||||
ntab = 0;
|
||||
while (p->tcol->col < p->lastcol &&
|
||||
while (p->tcol->col < p->tcol->lastcol &&
|
||||
p->tcol->buf[p->tcol->col] == '\t') {
|
||||
vend = term_tab_next(vis);
|
||||
vbl += vend - vis;
|
||||
@ -143,7 +156,13 @@ term_flushln(struct termp *p)
|
||||
*/
|
||||
|
||||
jhy = 0;
|
||||
for (j = p->tcol->col; j < p->lastcol; j++) {
|
||||
breakline = 0;
|
||||
for (j = p->tcol->col; j < p->tcol->lastcol; j++) {
|
||||
if (p->tcol->buf[j] == '\n') {
|
||||
if ((p->flags & TERMP_BRIND) == 0)
|
||||
breakline = 1;
|
||||
continue;
|
||||
}
|
||||
if (p->tcol->buf[j] == ' ' || p->tcol->buf[j] == '\t')
|
||||
break;
|
||||
|
||||
@ -178,7 +197,7 @@ term_flushln(struct termp *p)
|
||||
|
||||
if (vend > bp && jhy == 0 && vis > 0 &&
|
||||
(p->flags & TERMP_BRNEVER) == 0) {
|
||||
if (p->lasttcol)
|
||||
if (p->flags & TERMP_MULTICOL)
|
||||
return;
|
||||
|
||||
endline(p);
|
||||
@ -206,14 +225,16 @@ term_flushln(struct termp *p)
|
||||
* Write out the rest of the word.
|
||||
*/
|
||||
|
||||
for ( ; p->tcol->col < p->lastcol; p->tcol->col++) {
|
||||
for ( ; p->tcol->col < p->tcol->lastcol; p->tcol->col++) {
|
||||
if (vend > bp && jhy > 0 && p->tcol->col > jhy)
|
||||
break;
|
||||
if (p->tcol->buf[p->tcol->col] == '\n')
|
||||
continue;
|
||||
if (p->tcol->buf[p->tcol->col] == '\t')
|
||||
break;
|
||||
if (p->tcol->buf[p->tcol->col] == ' ') {
|
||||
j = p->tcol->col;
|
||||
while (p->tcol->col < p->lastcol &&
|
||||
while (p->tcol->col < p->tcol->lastcol &&
|
||||
p->tcol->buf[p->tcol->col] == ' ')
|
||||
p->tcol->col++;
|
||||
dv = (p->tcol->col - j) * (*p->width)(p, ' ');
|
||||
@ -248,6 +269,26 @@ term_flushln(struct termp *p)
|
||||
p->tcol->buf[p->tcol->col]);
|
||||
}
|
||||
vis = vend;
|
||||
|
||||
if (breakline == 0)
|
||||
continue;
|
||||
|
||||
/* Explicitly requested output line break. */
|
||||
|
||||
if (p->flags & TERMP_MULTICOL)
|
||||
return;
|
||||
|
||||
endline(p);
|
||||
breakline = 0;
|
||||
vis = vend = 0;
|
||||
|
||||
/* Re-establish indentation. */
|
||||
|
||||
vbl = p->tcol->offset;
|
||||
maxvis = p->tcol->rmargin > vbl ?
|
||||
p->tcol->rmargin - vbl : 0;
|
||||
bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
|
||||
p->maxrmargin > vbl ? p->maxrmargin - vbl : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -260,10 +301,13 @@ term_flushln(struct termp *p)
|
||||
else
|
||||
vis = 0;
|
||||
|
||||
p->col = p->lastcol = 0;
|
||||
p->col = p->tcol->col = p->tcol->lastcol = 0;
|
||||
p->minbl = p->trailspace;
|
||||
p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);
|
||||
|
||||
if (p->flags & TERMP_MULTICOL)
|
||||
return;
|
||||
|
||||
/* Trailing whitespace is significant in some columns. */
|
||||
|
||||
if (vis && vbl && (TERMP_BRTRSP & p->flags))
|
||||
@ -305,7 +349,7 @@ term_newln(struct termp *p)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (p->lastcol || p->viscol)
|
||||
if (p->tcol->lastcol || p->viscol)
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
@ -472,6 +516,9 @@ term_word(struct termp *p, const char *word)
|
||||
case ESCAPE_FONTPREV:
|
||||
term_fontlast(p);
|
||||
continue;
|
||||
case ESCAPE_BREAK:
|
||||
bufferc(p, '\n');
|
||||
continue;
|
||||
case ESCAPE_NOSPACE:
|
||||
if (p->flags & TERMP_BACKAFTER)
|
||||
p->flags &= ~TERMP_BACKAFTER;
|
||||
@ -479,9 +526,14 @@ term_word(struct termp *p, const char *word)
|
||||
p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE);
|
||||
continue;
|
||||
case ESCAPE_HORIZ:
|
||||
if (*seq == '|') {
|
||||
seq++;
|
||||
uc = -p->col;
|
||||
} else
|
||||
uc = 0;
|
||||
if (a2roffsu(seq, &su, SCALE_EM) == NULL)
|
||||
continue;
|
||||
uc = term_hspan(p, &su) / 24;
|
||||
uc += term_hen(p, &su);
|
||||
if (uc > 0)
|
||||
while (uc-- > 0)
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
@ -500,19 +552,19 @@ term_word(struct termp *p, const char *word)
|
||||
}
|
||||
continue;
|
||||
case ESCAPE_HLINE:
|
||||
if ((seq = a2roffsu(seq, &su, SCALE_EM)) == NULL)
|
||||
if ((cp = a2roffsu(seq, &su, SCALE_EM)) == NULL)
|
||||
continue;
|
||||
uc = term_hspan(p, &su) / 24;
|
||||
uc = term_hen(p, &su);
|
||||
if (uc <= 0) {
|
||||
if (p->tcol->rmargin <= p->tcol->offset)
|
||||
continue;
|
||||
lsz = p->tcol->rmargin - p->tcol->offset;
|
||||
} else
|
||||
lsz = uc;
|
||||
if (*seq == '\0')
|
||||
if (*cp == seq[-1])
|
||||
uc = -1;
|
||||
else if (*seq == '\\') {
|
||||
seq++;
|
||||
else if (*cp == '\\') {
|
||||
seq = cp + 1;
|
||||
esc = mandoc_escape(&seq, &cp, &sz);
|
||||
switch (esc) {
|
||||
case ESCAPE_UNICODE:
|
||||
@ -529,7 +581,7 @@ term_word(struct termp *p, const char *word)
|
||||
break;
|
||||
}
|
||||
} else
|
||||
uc = *seq;
|
||||
uc = *cp;
|
||||
if (uc < 0x20 || (uc > 0x7E && uc < 0xA0))
|
||||
uc = '_';
|
||||
if (p->enc == TERMENC_ASCII) {
|
||||
@ -565,12 +617,12 @@ term_word(struct termp *p, const char *word)
|
||||
}
|
||||
}
|
||||
/* Trim trailing backspace/blank pair. */
|
||||
if (p->lastcol > 2 &&
|
||||
(p->tcol->buf[p->lastcol - 1] == ' ' ||
|
||||
p->tcol->buf[p->lastcol - 1] == '\t'))
|
||||
p->lastcol -= 2;
|
||||
if (p->col > p->lastcol)
|
||||
p->col = p->lastcol;
|
||||
if (p->tcol->lastcol > 2 &&
|
||||
(p->tcol->buf[p->tcol->lastcol - 1] == ' ' ||
|
||||
p->tcol->buf[p->tcol->lastcol - 1] == '\t'))
|
||||
p->tcol->lastcol -= 2;
|
||||
if (p->col > p->tcol->lastcol)
|
||||
p->col = p->tcol->lastcol;
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
@ -613,10 +665,10 @@ bufferc(struct termp *p, char c)
|
||||
}
|
||||
if (p->col + 1 >= p->tcol->maxcols)
|
||||
adjbuf(p->tcol, p->col + 1);
|
||||
if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
|
||||
if (p->tcol->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
|
||||
p->tcol->buf[p->col] = c;
|
||||
if (p->lastcol < ++p->col)
|
||||
p->lastcol = p->col;
|
||||
if (p->tcol->lastcol < ++p->col)
|
||||
p->tcol->lastcol = p->col;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -659,10 +711,10 @@ encode1(struct termp *p, int c)
|
||||
p->tcol->buf[p->col++] = c;
|
||||
p->tcol->buf[p->col++] = '\b';
|
||||
}
|
||||
if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
|
||||
if (p->tcol->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
|
||||
p->tcol->buf[p->col] = c;
|
||||
if (p->lastcol < ++p->col)
|
||||
p->lastcol = p->col;
|
||||
if (p->tcol->lastcol < ++p->col)
|
||||
p->tcol->lastcol = p->col;
|
||||
if (p->flags & TERMP_BACKAFTER) {
|
||||
p->flags |= TERMP_BACKBEFORE;
|
||||
p->flags &= ~TERMP_BACKAFTER;
|
||||
@ -688,7 +740,7 @@ encode(struct termp *p, const char *word, size_t sz)
|
||||
isgraph((unsigned char)word[i]))
|
||||
encode1(p, word[i]);
|
||||
else {
|
||||
if (p->lastcol <= p->col ||
|
||||
if (p->tcol->lastcol <= p->col ||
|
||||
(word[i] != ' ' && word[i] != ASCII_NBRSP))
|
||||
p->tcol->buf[p->col] = word[i];
|
||||
p->col++;
|
||||
@ -705,8 +757,8 @@ encode(struct termp *p, const char *word, size_t sz)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p->lastcol < p->col)
|
||||
p->lastcol = p->col;
|
||||
if (p->tcol->lastcol < p->col)
|
||||
p->tcol->lastcol = p->col;
|
||||
}
|
||||
|
||||
void
|
||||
@ -919,7 +971,7 @@ term_vspan(const struct termp *p, const struct roffsu *su)
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a scaling width to basic units, rounding down.
|
||||
* Convert a scaling width to basic units, rounding towards 0.
|
||||
*/
|
||||
int
|
||||
term_hspan(const struct termp *p, const struct roffsu *su)
|
||||
@ -927,3 +979,17 @@ term_hspan(const struct termp *p, const struct roffsu *su)
|
||||
|
||||
return (*p->hspan)(p, su);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a scaling width to basic units, rounding to closest.
|
||||
*/
|
||||
int
|
||||
term_hen(const struct termp *p, const struct roffsu *su)
|
||||
{
|
||||
int bu;
|
||||
|
||||
if ((bu = (*p->hspan)(p, su)) >= 0)
|
||||
return (bu + 11) / 24;
|
||||
else
|
||||
return -((-bu + 11) / 24);
|
||||
}
|
||||
|
12
term.h
12
term.h
@ -1,4 +1,4 @@
|
||||
/* $Id: term.h,v 1.126 2017/06/07 20:01:19 schwarze Exp $ */
|
||||
/* $Id: term.h,v 1.130 2017/07/08 14:51:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -36,7 +36,7 @@ enum termfont {
|
||||
TERMFONT__MAX
|
||||
};
|
||||
|
||||
struct eqn;
|
||||
struct eqn_box;
|
||||
struct roff_meta;
|
||||
struct roff_node;
|
||||
struct tbl_span;
|
||||
@ -52,6 +52,7 @@ struct termp_tbl {
|
||||
struct termp_col {
|
||||
int *buf; /* Output buffer. */
|
||||
size_t maxcols; /* Allocated bytes in buf. */
|
||||
size_t lastcol; /* Last byte in buf. */
|
||||
size_t col; /* Byte in buf to be written. */
|
||||
size_t rmargin; /* Current right margin. */
|
||||
size_t offset; /* Current left margin. */
|
||||
@ -69,7 +70,6 @@ struct termp {
|
||||
size_t lastrmargin; /* Right margin before the last ll. */
|
||||
size_t maxrmargin; /* Max right margin. */
|
||||
size_t col; /* Byte position in buf. */
|
||||
size_t lastcol; /* Bytes in buf. */
|
||||
size_t viscol; /* Chars on current line. */
|
||||
size_t trailspace; /* See term_flushln(). */
|
||||
size_t minbl; /* Minimum blanks before next field. */
|
||||
@ -98,6 +98,7 @@ struct termp {
|
||||
#define TERMP_NOBUF (1 << 17) /* Bypass output buffer. */
|
||||
#define TERMP_NEWMC (1 << 18) /* No .mc printed yet. */
|
||||
#define TERMP_ENDMC (1 << 19) /* Next break ends .mc mode. */
|
||||
#define TERMP_MULTICOL (1 << 20) /* Multiple column mode. */
|
||||
enum termtype type; /* Terminal, PS, or PDF. */
|
||||
enum termenc enc; /* Type of encoding. */
|
||||
enum termfont fontl; /* Last font set. */
|
||||
@ -125,9 +126,10 @@ const char *ascii_uc2str(int);
|
||||
|
||||
void roff_term_pre(struct termp *, const struct roff_node *);
|
||||
|
||||
void term_eqn(struct termp *, const struct eqn *);
|
||||
void term_eqn(struct termp *, const struct eqn_box *);
|
||||
void term_tbl(struct termp *, const struct tbl_span *);
|
||||
void term_free(struct termp *);
|
||||
void term_setcol(struct termp *, size_t);
|
||||
void term_newln(struct termp *);
|
||||
void term_vspace(struct termp *);
|
||||
void term_word(struct termp *, const char *);
|
||||
@ -138,11 +140,13 @@ void term_end(struct termp *);
|
||||
|
||||
void term_setwidth(struct termp *, const char *);
|
||||
int term_hspan(const struct termp *, const struct roffsu *);
|
||||
int term_hen(const struct termp *, const struct roffsu *);
|
||||
int term_vspan(const struct termp *, const struct roffsu *);
|
||||
size_t term_strlen(const struct termp *, const char *);
|
||||
size_t term_len(const struct termp *, size_t);
|
||||
|
||||
void term_tab_set(const struct termp *, const char *);
|
||||
void term_tab_iset(size_t);
|
||||
size_t term_tab_next(size_t);
|
||||
|
||||
void term_fontpush(struct termp *, enum termfont);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: term_ascii.c,v 1.57 2017/06/07 17:38:26 schwarze Exp $ */
|
||||
/* $Id: term_ascii.c,v 1.58 2017/06/14 14:24:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -293,7 +293,7 @@ ascii_uc2str(int uc)
|
||||
"<80>", "<81>", "<82>", "<83>", "<84>", "<85>", "<86>", "<87>",
|
||||
"<88>", "<89>", "<8A>", "<8B>", "<8C>", "<8D>", "<8E>", "<8F>",
|
||||
"<90>", "<91>", "<92>", "<93>", "<94>", "<95>", "<96>", "<97>",
|
||||
"<99>", "<99>", "<9A>", "<9B>", "<9C>", "<9D>", "<9E>", "<9F>",
|
||||
"<98>", "<99>", "<9A>", "<9B>", "<9C>", "<9D>", "<9E>", "<9F>",
|
||||
nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<sec>",
|
||||
"\"", "(C)", "_\ba", "<<", "~", "", "(R)", "-",
|
||||
"<deg>","+-", "2", "3", "'", ",\bu", "<par>",".",
|
||||
|
27
term_tab.c
27
term_tab.c
@ -52,7 +52,7 @@ term_tab_set(const struct termp *p, const char *arg)
|
||||
recording_period = 0;
|
||||
if (tabs.d == 0) {
|
||||
a2roffsu(".8i", &su, SCALE_IN);
|
||||
tabs.d = term_hspan(p, &su) / 24;
|
||||
tabs.d = term_hen(p, &su);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -81,13 +81,28 @@ term_tab_set(const struct termp *p, const char *arg)
|
||||
|
||||
/* Append the new position. */
|
||||
|
||||
pos = term_hspan(p, &su);
|
||||
pos = term_hen(p, &su);
|
||||
tl->t[tl->n] = pos;
|
||||
if (add && tl->n)
|
||||
tl->t[tl->n] += tl->t[tl->n - 1];
|
||||
tl->n++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simplified version without a parser,
|
||||
* never incremental, never periodic, for use by tbl(7).
|
||||
*/
|
||||
void
|
||||
term_tab_iset(size_t inc)
|
||||
{
|
||||
if (tabs.a.n >= tabs.a.s) {
|
||||
tabs.a.s += 8;
|
||||
tabs.a.t = mandoc_reallocarray(tabs.a.t, tabs.a.s,
|
||||
sizeof(*tabs.a.t));
|
||||
}
|
||||
tabs.a.t[tabs.a.n++] = inc;
|
||||
}
|
||||
|
||||
size_t
|
||||
term_tab_next(size_t prev)
|
||||
{
|
||||
@ -97,10 +112,6 @@ term_tab_next(size_t prev)
|
||||
if (i == tabs.a.n) {
|
||||
if (tabs.p.n == 0)
|
||||
return prev;
|
||||
/*
|
||||
return i ? prev :
|
||||
(prev / tabs.d + 1) * tabs.d;
|
||||
*/
|
||||
tabs.a.n += tabs.p.n;
|
||||
if (tabs.a.s < tabs.a.n) {
|
||||
tabs.a.s = tabs.a.n;
|
||||
@ -111,7 +122,7 @@ term_tab_next(size_t prev)
|
||||
tabs.a.t[i + j] = tabs.p.t[j] +
|
||||
(i ? tabs.a.t[i - 1] : 0);
|
||||
}
|
||||
if (prev < tabs.a.t[i] / 24)
|
||||
return tabs.a.t[i] / 24;
|
||||
if (prev < tabs.a.t[i])
|
||||
return tabs.a.t[i];
|
||||
}
|
||||
}
|
||||
|
11
test-recallocarray.c
Normal file
11
test-recallocarray.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if ((p = calloc(2, 2)) == NULL)
|
||||
return 1;
|
||||
return !recallocarray(p, 2, 3, 2);
|
||||
}
|
10
tree.c
10
tree.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tree.c,v 1.74 2017/04/24 23:06:18 schwarze Exp $ */
|
||||
/* $Id: tree.c,v 1.77 2017/07/08 14:51:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -202,7 +202,7 @@ print_mdoc(const struct roff_node *n, int indent)
|
||||
}
|
||||
|
||||
if (n->eqn)
|
||||
print_box(n->eqn->root->first, indent + 4);
|
||||
print_box(n->eqn->first, indent + 4);
|
||||
if (n->child)
|
||||
print_mdoc(n->child, indent +
|
||||
(n->type == ROFFT_BLOCK ? 2 : 4));
|
||||
@ -287,7 +287,7 @@ print_man(const struct roff_node *n, int indent)
|
||||
}
|
||||
|
||||
if (n->eqn)
|
||||
print_box(n->eqn->root->first, indent + 4);
|
||||
print_box(n->eqn->first, indent + 4);
|
||||
if (n->child)
|
||||
print_man(n->child, indent +
|
||||
(n->type == ROFFT_BLOCK ? 2 : 4));
|
||||
@ -313,10 +313,6 @@ print_box(const struct eqn_box *ep, int indent)
|
||||
|
||||
t = NULL;
|
||||
switch (ep->type) {
|
||||
case EQN_ROOT:
|
||||
t = "eqn-root";
|
||||
break;
|
||||
case EQN_LISTONE:
|
||||
case EQN_LIST:
|
||||
t = "eqn-list";
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user