mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 04:43:53 +00:00
mandoc: import v1.14.6
This commit is contained in:
parent
a5efdeedef
commit
e9bf778aef
17
INSTALL
17
INSTALL
|
@ -1,4 +1,4 @@
|
|||
$Id: INSTALL,v 1.23 2019/03/06 15:58:10 schwarze Exp $
|
||||
$Id: INSTALL,v 1.24 2021/09/20 13:25:42 schwarze Exp $
|
||||
|
||||
About the portable mandoc distribution
|
||||
--------------------------------------
|
||||
|
@ -18,7 +18,7 @@ tech@ mailing list, too.
|
|||
|
||||
Enjoy using the mandoc toolset!
|
||||
|
||||
Ingo Schwarze, Karlsruhe, March 2019
|
||||
Ingo Schwarze, Karlsruhe, September 2021
|
||||
|
||||
|
||||
Installation
|
||||
|
@ -65,10 +65,15 @@ installed to the intended places. Otherwise, put some *DIR or *NM*
|
|||
variables into "configure.local" and go back to step 4.
|
||||
|
||||
7. Optionally run the regression suite.
|
||||
Basically, that amounts to "cd regress && ./regress.pl".
|
||||
But you should probably look at "./mandoc -l regress/regress.pl.1"
|
||||
first. In particular, regarding Solaris systems, look at the BUGS
|
||||
section of that manual page.
|
||||
Basically, that amounts to "make regress" to do a standard regression
|
||||
run, running all tests. For more fine-grained control,
|
||||
read "./mandoc -l regress/regress.pl.1",
|
||||
then run "cd regress && ./regress.pl" with optional arguments.
|
||||
The regression suite requires a reasonably modern Perl interpreter.
|
||||
Examples of systems that are too old to run the regression suite
|
||||
include Solaris 9, Solaris 10, and Mac OS X 10.4 Tiger.
|
||||
On Solaris 11, the suite does run, but some tests fail;
|
||||
look at the BUGS section of that manual page.
|
||||
|
||||
8. Run "sudo make install". If you intend to build a binary
|
||||
package using some kind of fake root mechanism, you may need a
|
||||
|
|
6
LICENSE
6
LICENSE
|
@ -1,11 +1,11 @@
|
|||
$Id: LICENSE,v 1.21 2018/11/26 17:11:11 schwarze Exp $
|
||||
$Id: LICENSE,v 1.22 2021/09/19 11:02:09 schwarze Exp $
|
||||
|
||||
With the exceptions noted below, all non-trivial files contained
|
||||
in the mandoc toolkit are protected by the Copyright of the following
|
||||
developers:
|
||||
|
||||
Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
Copyright (c) 2010-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
Copyright (c) 1999, 2004, 2017 Marc Espie <espie@openbsd.org>
|
||||
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
|
@ -13,7 +13,7 @@ Copyright (c) 2014 Baptiste Daroussin <bapt@freebsd.org>
|
|||
Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
Copyright (c) 2017 Anthony Bentley <bentley@openbsd.org>
|
||||
Copyright (c) 1998, 2004, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
Copyright (c) 1998, 2004, 2010, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
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>
|
||||
|
|
64
Makefile
64
Makefile
|
@ -1,7 +1,7 @@
|
|||
# $Id: Makefile,v 1.530 2019/03/06 16:08:41 schwarze Exp $
|
||||
# $Id: Makefile,v 1.540 2021/09/21 11:04:40 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2011, 2013-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
# Copyright (c) 2011, 2013-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -15,11 +15,12 @@
|
|||
# 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.5
|
||||
VERSION = 1.14.6
|
||||
|
||||
# === LIST OF FILES ====================================================
|
||||
|
||||
TESTSRCS = test-be32toh.c \
|
||||
TESTSRCS = test-attribute.c \
|
||||
test-be32toh.c \
|
||||
test-cmsg.c \
|
||||
test-dirent-namlen.c \
|
||||
test-EFTYPE.c \
|
||||
|
@ -29,6 +30,7 @@ TESTSRCS = test-be32toh.c \
|
|||
test-getsubopt.c \
|
||||
test-isblank.c \
|
||||
test-mkdtemp.c \
|
||||
test-mkstemps.c \
|
||||
test-nanosleep.c \
|
||||
test-noop.c \
|
||||
test-ntohl.c \
|
||||
|
@ -65,6 +67,7 @@ SRCS = arch.c \
|
|||
compat_getsubopt.c \
|
||||
compat_isblank.c \
|
||||
compat_mkdtemp.c \
|
||||
compat_mkstemps.c \
|
||||
compat_ohash.c \
|
||||
compat_progname.c \
|
||||
compat_reallocarray.c \
|
||||
|
@ -134,6 +137,7 @@ SRCS = arch.c \
|
|||
term_ascii.c \
|
||||
term_ps.c \
|
||||
term_tab.c \
|
||||
term_tag.c \
|
||||
tree.c
|
||||
|
||||
DISTFILES = INSTALL \
|
||||
|
@ -209,6 +213,7 @@ DISTFILES = INSTALL \
|
|||
tbl_int.h \
|
||||
tbl_parse.h \
|
||||
term.h \
|
||||
term_tag.h \
|
||||
$(SRCS) \
|
||||
$(TESTSRCS)
|
||||
|
||||
|
@ -245,19 +250,22 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
|||
mandoc_xr.o \
|
||||
msec.o \
|
||||
preconv.o \
|
||||
read.o
|
||||
read.o \
|
||||
tag.o
|
||||
|
||||
COMPAT_OBJS = compat_err.o \
|
||||
ALL_COBJS = compat_err.o \
|
||||
compat_fts.o \
|
||||
compat_getline.o \
|
||||
compat_getsubopt.o \
|
||||
compat_isblank.o \
|
||||
compat_mkdtemp.o \
|
||||
compat_mkstemps.o \
|
||||
compat_ohash.o \
|
||||
compat_progname.o \
|
||||
compat_reallocarray.o \
|
||||
compat_recallocarray.o \
|
||||
compat_strcasestr.o \
|
||||
compat_stringlist.o \
|
||||
compat_strlcat.o \
|
||||
compat_strlcpy.o \
|
||||
compat_strndup.o \
|
||||
|
@ -280,6 +288,7 @@ MANDOC_TERM_OBJS = eqn_term.o \
|
|||
term_ascii.o \
|
||||
term_ps.o \
|
||||
term_tab.o \
|
||||
term_tag.o \
|
||||
tbl_term.o
|
||||
|
||||
DBM_OBJS = dbm.o \
|
||||
|
@ -302,7 +311,6 @@ MAIN_OBJS = $(MANDOC_HTML_OBJS) \
|
|||
mdoc_man.o \
|
||||
mdoc_markdown.o \
|
||||
out.o \
|
||||
tag.o \
|
||||
tree.o
|
||||
|
||||
CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
|
@ -313,18 +321,10 @@ CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
|||
MANDOCD_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
$(MANDOC_TERM_OBJS) \
|
||||
mandocd.o \
|
||||
out.o \
|
||||
tag.o
|
||||
out.o
|
||||
|
||||
DEMANDOC_OBJS = demandoc.o
|
||||
|
||||
SOELIM_OBJS = soelim.o \
|
||||
compat_err.o \
|
||||
compat_getline.o \
|
||||
compat_progname.o \
|
||||
compat_reallocarray.o \
|
||||
compat_stringlist.o
|
||||
|
||||
WWW_MANS = apropos.1.html \
|
||||
demandoc.1.html \
|
||||
man.1.html \
|
||||
|
@ -373,7 +373,7 @@ include Makefile.local
|
|||
|
||||
# === DEPENDENCY HANDLING ==============================================
|
||||
|
||||
all: mandoc demandoc soelim $(BUILD_TARGETS) Makefile.local
|
||||
all: mandoc man demandoc soelim $(BUILD_TARGETS) Makefile.local
|
||||
|
||||
install: base-install $(INSTALL_TARGETS)
|
||||
|
||||
|
@ -392,13 +392,14 @@ distclean: clean
|
|||
rm -f Makefile.local config.h config.h.old config.log config.log.old
|
||||
|
||||
clean:
|
||||
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS)
|
||||
rm -f mandoc $(MAIN_OBJS)
|
||||
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(ALL_COBJS)
|
||||
rm -f mandoc man $(MAIN_OBJS)
|
||||
rm -f man.cgi $(CGI_OBJS)
|
||||
rm -f mandocd catman catman.o $(MANDOCD_OBJS)
|
||||
rm -f demandoc $(DEMANDOC_OBJS)
|
||||
rm -f soelim $(SOELIM_OBJS)
|
||||
rm -f soelim soelim.o
|
||||
rm -f $(WWW_MANS) $(WWW_INCS) mandoc*.tar.gz mandoc*.sha256
|
||||
rm -f Makefile.tmp1 Makefile.tmp2
|
||||
rm -rf *.dSYM
|
||||
|
||||
base-install: mandoc demandoc soelim
|
||||
|
@ -511,12 +512,15 @@ Makefile.local config.h: configure $(TESTSRCS)
|
|||
@echo "$@ is out of date; please run ./configure"
|
||||
@exit 1
|
||||
|
||||
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||
ar rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||
libmandoc.a: $(MANDOC_COBJS) $(LIBMANDOC_OBJS)
|
||||
$(AR) rs $@ $(MANDOC_COBJS) $(LIBMANDOC_OBJS)
|
||||
|
||||
mandoc: $(MAIN_OBJS) libmandoc.a
|
||||
$(CC) -o $@ $(LDFLAGS) $(MAIN_OBJS) libmandoc.a $(LDADD)
|
||||
|
||||
man: mandoc
|
||||
$(LN) mandoc man
|
||||
|
||||
man.cgi: $(CGI_OBJS) libmandoc.a
|
||||
$(CC) $(STATIC) -o $@ $(LDFLAGS) $(CGI_OBJS) libmandoc.a $(LDADD)
|
||||
|
||||
|
@ -529,8 +533,8 @@ catman: catman.o libmandoc.a
|
|||
demandoc: $(DEMANDOC_OBJS) libmandoc.a
|
||||
$(CC) -o $@ $(LDFLAGS) $(DEMANDOC_OBJS) libmandoc.a $(LDADD)
|
||||
|
||||
soelim: $(SOELIM_OBJS)
|
||||
$(CC) -o $@ $(LDFLAGS) $(SOELIM_OBJS)
|
||||
soelim: $(SOELIM_COBJS) soelim.o
|
||||
$(CC) -o $@ $(LDFLAGS) $(SOELIM_COBJS) soelim.o
|
||||
|
||||
# --- maintainer targets ---
|
||||
|
||||
|
@ -540,11 +544,13 @@ www-install: www
|
|||
$(INSTALL_DATA) $(WWW_INCS) $(HTDOCDIR)/includes
|
||||
|
||||
depend: config.h
|
||||
mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
|
||||
./configure -depend
|
||||
mkdep -f Makefile.tmp1 $(CFLAGS) $(SRCS)
|
||||
perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
|
||||
s|\\\n||g; s| +| |g; s| $$||mg; print;' \
|
||||
Makefile.depend > Makefile.tmp
|
||||
mv Makefile.tmp Makefile.depend
|
||||
Makefile.tmp1 > Makefile.tmp2
|
||||
rm Makefile.tmp1
|
||||
mv Makefile.tmp2 Makefile.depend
|
||||
|
||||
regress-distclean:
|
||||
@find regress \
|
||||
|
@ -597,7 +603,7 @@ dist-install: dist
|
|||
.h.h.html:
|
||||
highlight -I $< > $@
|
||||
|
||||
.1.1.html .3.3.html .5.5.html .7.7.html .8.8.html: mandoc
|
||||
mandoc -Thtml -Wwarning,stop \
|
||||
.1.1.html .3.3.html .5.5.html .7.7.html .8.8.html:
|
||||
./mandoc -Thtml -Wwarning,stop \
|
||||
-O 'style=/mandoc.css,man=/man/%N.%S.html;https://man.openbsd.org/%N.%S,includes=/includes/%I.html' \
|
||||
$< > $@
|
||||
|
|
|
@ -9,6 +9,7 @@ compat_getline.o: compat_getline.c config.h
|
|||
compat_getsubopt.o: compat_getsubopt.c config.h
|
||||
compat_isblank.o: compat_isblank.c config.h
|
||||
compat_mkdtemp.o: compat_mkdtemp.c config.h
|
||||
compat_mkstemps.o: compat_mkstemps.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
|
||||
|
@ -22,8 +23,8 @@ compat_strsep.o: compat_strsep.c config.h
|
|||
compat_strtonum.o: compat_strtonum.c config.h
|
||||
compat_vasprintf.o: compat_vasprintf.c config.h
|
||||
dba.o: dba.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mansearch.h dba_write.h dba_array.h dba.h
|
||||
dba_array.o: dba_array.c mandoc_aux.h dba_write.h dba_array.h
|
||||
dba_read.o: dba_read.c mandoc_aux.h mansearch.h dba_array.h dba.h dbm.h
|
||||
dba_array.o: dba_array.c config.h mandoc_aux.h dba_write.h dba_array.h
|
||||
dba_read.o: dba_read.c config.h 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
|
||||
|
@ -33,17 +34,17 @@ eqn_html.o: eqn_html.c config.h mandoc.h roff.h eqn.h out.h html.h
|
|||
eqn_term.o: eqn_term.c config.h eqn.h out.h term.h
|
||||
html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h
|
||||
lib.o: lib.c config.h roff.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 mandoc_parse.h tag.h main.h manconf.h mansearch.h
|
||||
main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h mandoc_parse.h tag.h term_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 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 tag.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
|
||||
man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h term_tag.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 tag.h
|
||||
mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h roff_int.h
|
||||
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||
mandoc_msg.o: mandoc_msg.c config.h mandoc.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
|
||||
mandoc_ohash.o: mandoc_ohash.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h
|
||||
mandoc_xr.o: mandoc_xr.c config.h 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 mandoc_parse.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 mandoc_parse.h manconf.h mansearch.h dba_array.h dba.h
|
||||
manpath.o: manpath.c config.h mandoc_aux.h mandoc.h manconf.h
|
||||
|
@ -53,21 +54,21 @@ mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.
|
|||
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 roff_int.h libmdoc.h
|
||||
mdoc_term.o: mdoc_term.c config.h mandoc_aux.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 mandoc_xr.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_markdown.o: mdoc_markdown.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h main.h
|
||||
mdoc_state.o: mdoc_state.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h roff.h mdoc.h out.h term.h term_tag.h main.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 tag.h
|
||||
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
||||
out.o: out.c config.h mandoc_aux.h tbl.h out.h
|
||||
out.o: out.c config.h mandoc_aux.h mandoc.h tbl.h out.h
|
||||
preconv.o: preconv.c config.h mandoc.h roff.h mandoc_parse.h libmandoc.h
|
||||
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h libmandoc.h roff_int.h
|
||||
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h libmandoc.h roff_int.h tag.h
|
||||
roff.o: roff.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mandoc_parse.h libmandoc.h roff_int.h tbl_parse.h eqn_parse.h predefs.in
|
||||
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
|
||||
roff_html.o: roff_html.c config.h mandoc.h roff.h out.h html.h
|
||||
roff_term.o: roff_term.c config.h mandoc.h roff.h out.h term.h
|
||||
roff_validate.o: roff_validate.c config.h mandoc.h roff.h libmandoc.h roff_int.h
|
||||
soelim.o: soelim.c config.h compat_stringlist.h
|
||||
st.o: st.c config.h mandoc.h roff.h libmdoc.h
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h tag.h
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h mdoc.h roff_int.h tag.h
|
||||
tbl.o: tbl.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_parse.h tbl_int.h
|
||||
tbl_data.o: tbl_data.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tbl_html.o: tbl_html.c config.h mandoc.h roff.h tbl.h out.h html.h
|
||||
|
@ -77,5 +78,6 @@ tbl_term.o: tbl_term.c config.h mandoc.h tbl.h out.h term.h
|
|||
term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
||||
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h manconf.h main.h
|
||||
term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h manconf.h main.h
|
||||
term_tab.o: term_tab.c mandoc_aux.h out.h term.h
|
||||
term_tab.o: term_tab.c config.h mandoc_aux.h out.h term.h
|
||||
term_tag.o: term_tag.c config.h mandoc.h roff.h roff_int.h tag.h term_tag.h
|
||||
tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h tbl.h eqn.h main.h
|
||||
|
|
201
NEWS
201
NEWS
|
@ -1,7 +1,206 @@
|
|||
$Id: NEWS,v 1.34 2019/03/10 09:32:00 schwarze Exp $
|
||||
$Id: NEWS,v 1.40 2021/09/23 18:03:00 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mandoc.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.14.6, released on September 23, 2021
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
* mdoc(7): automatic tagging improved in many respects
|
||||
* mdoc(7): new .Tg (tag) macro to explicitly mark a place as defining a term
|
||||
* man(7): implement some automatic tagging support
|
||||
* man(1): let -w without argument show the manpath, like in man-db and man-1.6
|
||||
* -T html: wrap text and phrasing elements in paragraphs unless already
|
||||
contained in flow containers; never put them directly into sections.
|
||||
This helps to format paragraphs with the CSS class selector .Pp.
|
||||
* man.conf(5): remove support for the "_whatdb" configuration directive
|
||||
that was deprecated in 2015; please use "manpath" instead
|
||||
--- MINOR NEW FEATURES ---
|
||||
* man(1): switch the default pager from "more -s" to "less"
|
||||
* man(1): in the fallback code to look for manual pages without using
|
||||
mandoc.db(5), accept files "man<one-digit-section>/<name>.<full-section>"
|
||||
in addition to the already supported "man<full-section>/name.[01-9]*"
|
||||
* if messages are shown and output is printed without a pager, display
|
||||
a heads-up on stderr at the end because otherwise, users may easily
|
||||
miss the messages
|
||||
* man.cgi(8): add a Content-Security-Policy HTTP header
|
||||
* man.cgi(8): switch off autocomplete and autocapitalize
|
||||
* mandoc.css: support prefers-color-scheme: dark
|
||||
* -T html: add meta viewport element to help mobile devices
|
||||
* -T html -O tag: let this pass a file:// URI to the pager
|
||||
* tbl(7): implement the "nospaces" option
|
||||
* tbl(7) -T html: implement the "a" (em indent) layout specification
|
||||
* tbl(7) -T html: implement the "b" (bold) and "i" (italic) layout modifiers
|
||||
* tbl(7): support two-character font names in the layout font modifier
|
||||
* tbl(7) -T html: support horinzontal rulers in individual cells
|
||||
* tbl(7) -T tree: print more details about columns, options, rows, and cells
|
||||
* roff(7): implement the .break request (break out of a .while loop)
|
||||
* roff(7): support the CB and CI fonts in \f and .ft
|
||||
* -T lint: new STYLE message if a file name extension contradicts .Dt/.TH
|
||||
* -T lint: new STYLE message about overlong text lines
|
||||
* -W style: check .Xr links along the full manpath
|
||||
--- RELIABILITY BUGFIXES ---
|
||||
* man(1): do not segfault if /tmp/ is not writeable
|
||||
* man(1): do not access a NULL pointer when both -l and -w are given
|
||||
* makewhatis(8): do not crash when a manpath directory contains
|
||||
a symbolic link that points to a directory
|
||||
* man(7): fix an assertion failure caused by doubly nested next-line scopes
|
||||
* tbl(7): fix a crash when the last column is only reached by spans
|
||||
* tbl(7): fix a NULL pointer access in some cases of two spans on one row
|
||||
* tbl(7) -T ascii: fix a NULL pointer access on empty data cells
|
||||
* tbl(7) -T ascii: fix a NULL pointer access on a line next to a short row
|
||||
* tbl(7): fix an assertion failure caused by excessive spacing modifiers
|
||||
* tbl(7): fix an infinite loop for some overlapping horizontal spans
|
||||
* roff(7): fix a rare case of writing one byte past the end of the input buffer
|
||||
* roff(7): do not call abort(3) when \*[.T] is encountered
|
||||
* roff(7): fix an assertion failure caused by a macro inside .ce .if
|
||||
* roff(7): fix assertion failures for .ti and .po with excessive arguments
|
||||
* roff(7): avoid near-infinte output for .ce inside explicit no-fill mode
|
||||
* -T ascii/utf8: fix assertion failures caused by excessive spacing
|
||||
* -T html: fix an assertion failure caused by .ft in rare situations
|
||||
* -T man: fix an assertion failure caused by tbl(7) and eqn(7) input
|
||||
--- PORTABILITY IMPROVEMENTS ---
|
||||
* rename HOMEBREWDIR to READ_ALLOWED_PATH, allow it to contain more than
|
||||
one directory, and explain how to use that for NixOS and GNU Guix Linux
|
||||
* configure: stop trying to ask make(1) what the default compiler is
|
||||
because that test was too fragile; just use "cc" by default
|
||||
* configure: various simplifications and improved robustness
|
||||
* configure: only compile compat_*.c implementations that are needed
|
||||
* configure: provide feature tests for __attribute__(()) and mkstemps(3)
|
||||
* compat_*: sync with upstreams for security, functionality, and style
|
||||
* in regress.pl, avoid the non-portable options sed(1) -i and echo(1) -n
|
||||
* in the regression suite, avoid file names that differ only by case
|
||||
--- MINOR FUNCTIONAL IMPROVEMENTS ---
|
||||
* man(1) -h: for pages lacking a SYNOPSIS, show the NAME section
|
||||
* man(1): when the first argument starts with a digit, optionally
|
||||
followed by a letter, and at least one more argument follows,
|
||||
interpret the first argument as a section name even when additional
|
||||
characters follow after the digit and letter
|
||||
* man(1): with a specific section requested, try harder to find
|
||||
the best match; use this order of preference:
|
||||
1. The section in both the directory name and the file name matches exactly.
|
||||
2. The section in the file name matches exactly.
|
||||
3. The section in the directory name matches exactly.
|
||||
4. Neither of them matches exactly.
|
||||
* man(1): if no tags were generated at all, unlink(2) the empty tags file
|
||||
as soon as the condition can be detected and do not pass it to less(1)
|
||||
* makewhatis(8): handle both dangling symlinks and .so links
|
||||
in manual page directories more gracefully
|
||||
* man.cgi(8): for invalid queries and for valid queries returning
|
||||
no result, return the appropriate 40x status code rather than 200
|
||||
* mdoc(7): let .Dd concatenate all arguments and default to the empty string
|
||||
* mdoc(7): convert ".Fl Fl" to ".Fl \-" during validation, improving -T html
|
||||
* mdoc(7): improve output of .At 32v
|
||||
* man(7): no longer print multiple blank lines before NAME and page footer
|
||||
* tbl(7) -T utf8: improved rendering of horizontal lines
|
||||
* tbl(7) -T html: in "n" cells, align by padding numbers on the right
|
||||
* tbl(7): no longer leak tabulator settings to subsequent roff(7) code
|
||||
* mdoc(7) -T html: for .Bl -tag, use "column-count: 1" rather
|
||||
than "overflow: auto" to avoid the ugly side effects
|
||||
* mdoc(7) -T html: render .Bd -unfilled in proportionally-spaced font
|
||||
* mdoc(7) -T html: format .Nd with <span> rather than <div>
|
||||
* mdoc(7) -T lint: do not warn about Mdocdate without an actual date
|
||||
* mdoc(7) -T lint: do not complain about function types of the
|
||||
form "ret_type (fname)(args)", but otherwise check names more strictly
|
||||
* -T html: append .html suffix to temporary files to please browsers
|
||||
* -T markdown: print a BAGARG message if called on man(7) input
|
||||
--- MINOR BUGFIXES ---
|
||||
* man(1): do the search for each name independently, and
|
||||
show the results in the order of the command line argument
|
||||
* man(1): escape shell wildcard characters in name arguments before glob(3)
|
||||
* man(1): when asking for a single manual page by name, prefer file name
|
||||
matches over .Dt/.TH matches over first NAME matches over later NAME
|
||||
matches, but do not change the ordering for apropos(1) nor for man -a
|
||||
* man(1): correctly extract the section name from the file name extension
|
||||
of gzipped manual page files
|
||||
* makewhatis(8): fix file type tests putting wrong data into mandoc.db(5)
|
||||
* man.cgi(8): fix section number in the <title> element for preformatted pages
|
||||
* tbl(7): correct handling of T& after horizontal rulers in the layout
|
||||
* tbl(7): correct column widths if rows have different numbers of cells
|
||||
* tbl(7): empty columns are 1n wide rather than 0n
|
||||
* tbl(7): correctly calculate required column widths for tables containing
|
||||
cells that horizontally span columns which contains "n" (number) formatted
|
||||
cells on other rows
|
||||
* tbl(7): skip escape sequences when looking for column separators
|
||||
* eqn(7): skip whitespace before tokens
|
||||
* roff(7): when calling an empty macro, do not clobber existing arguments
|
||||
* roff(7): recognize \} on lines closing a macro definition request
|
||||
* roff(7): do not throw a bogus warning for "'br\}" and similar lines
|
||||
* roff(7): stop generating comment nodes when encountering the first content
|
||||
* mandoc_char(7): make \0 (digit-width space) non-breaking
|
||||
* mdoc(7) .Bl -column: parse Macro in .It "word<tab>word" Ta word Macro<eol>
|
||||
* mdoc(7) -T html: display straight quotes, not curly quotes, for .Qq/.Qo
|
||||
* -T html: remove some spurious line breaks, in particular inside <pre>
|
||||
* -T html: use <br/> for a space character at the beginning of an input line
|
||||
* -T html: use ~%d for ordinal fragment suffixes, reserve '~' for that purpose
|
||||
--- STRUCTURAL IMPROVEMENTS ---
|
||||
* introduce the concept of semantically transparent syntax tree nodes,
|
||||
allowing improved decisions in various validators and formatters
|
||||
* move some code out of the giant main() into separate functions
|
||||
doing one well-defined task each
|
||||
* clearly separate parser state (struct curparse) and formatter state
|
||||
(struct outstate), don't mix them in the same struct
|
||||
* in the HTML formatter, assert(3) that no HTML nesting violation occurs
|
||||
* let html_close_paragraph() close any phrasing context
|
||||
--- THANKS TO ---
|
||||
* Anthony Bentley and Klemens Nanni (OpenBSD) for many patches and bug
|
||||
reports, for useful discussions, and for checking patches
|
||||
* Anton Lindqvist (OpenBSD) for two patches and a bug report
|
||||
* Marc Espie (OpenBSD) for a patch, many bug reports, and useful discussions
|
||||
* Lukas Epple (NixOS) for a patch, bug reports, suggesting a minor
|
||||
portability feature, checking patches, and extensive release testing
|
||||
* Abel Romero Perez for a patch, a bug report, and suggesting a new feature
|
||||
* nabijaczleweli for a patch and for suggesting feature improvements
|
||||
* Jonathan Gray (OpenBSD) for a patch and for bug reports
|
||||
* Otto Moerbeek (OpenBSD) and Alexander Gromnitsky for a patch
|
||||
* Armin Besirovic for a contribution to mandoc.css
|
||||
* Jason McIntyre (OpenBSD) for manual page patches, suggesting a new feature,
|
||||
checking many patches, and useful discussions
|
||||
* Martin Vahlensieck for a manual page patch and reporting a code style issue
|
||||
* Frederic Cambus and Ian Sutton (OpenBSD) for a manual page patch
|
||||
* Jan Schreiber for many bug reports found with afl(1)
|
||||
* G. Branden Robinson (GNU troff) for several bug reports, feature
|
||||
suggestions, and for checking many groff patches
|
||||
* Michael Stapelberg (Debian) for several bug reports and feature
|
||||
suggestions, and for extensive release testing
|
||||
* Ian Ropers, Lorenzo Beretta, and Oliver Corff for several bug reports
|
||||
and feature suggestions
|
||||
* Stephen Gregoratto for several bug reports
|
||||
* Theo de Raadt (OpenBSD) for two bug reports, checking a patch,
|
||||
and a useful discussion
|
||||
* Thomas Klausner (NetBSD) for two bug reports and for release testing
|
||||
* Andreas Kahari and Jason A. Donenfeld for two bug reports
|
||||
* Soeren Tempel (Alpine Linux) for a bug report, suggesting a feature
|
||||
improvement, and checking two patches
|
||||
* Aman Verma, Jan Stary, and John Gardner for a bug report
|
||||
and for suggesting a feature impovement
|
||||
* Todd Miller (OpenBSD) for a bug report, checking a patch,
|
||||
and a useful discussion
|
||||
* Andrew Fresh, Brian Callahan, Christian Weisgerber, Paul de Weerd (OpenBSD),
|
||||
Havard Eidnes, Jason Thorpe (NetBSD), Yuri Pankov (FreeBSD),
|
||||
Bjarni Ingi Gislason, Chris Bennett, Edgar Pettijohn, Eldred Habert,
|
||||
Jamie Landeg-Jones, Kazuo KUROI, and Wynn Wolf Arbor for a bug report
|
||||
* Theo Buehler (OpenBSD) for suggesting two feature impovements
|
||||
and for checking a patch
|
||||
* Leah Neukirchen (Void Linux) for suggesting a feature impovement
|
||||
and for release testing
|
||||
* Colin Watson (Debian) for suggesting a feature impovement
|
||||
and for checking groff patches
|
||||
* Matej Cepl (SUSE Linux), Matthew Martin, Steffen Nurpmeso,
|
||||
and Tim Baumgard for suggesting a feature impovement
|
||||
* Christos Zoulas (NetBSD) for a report regarding portability
|
||||
* Daniel Dickman (OpenBSD) for suggesting a portability improvement
|
||||
* Werner Lemberg (GNU troff) and Douglas McIlroy
|
||||
for reporting bugs in manual pages
|
||||
* Baptiste Daroussin and Eygene Ryabinkin (FreeBSD)
|
||||
for an additional regression test
|
||||
* Michal Nowak for reporting several code style issues
|
||||
* TJ Townsend (OpenBSD) for help with CSS
|
||||
* Sevan Janiyan (NetBSD) and Robert Mustacchi (Illumos)
|
||||
for extensive release testing
|
||||
* Job Snijders, Kinichiro INOGUCHI, and Martijn van Duren (OpenBSD)
|
||||
for checking patches
|
||||
* Bertrand Garrigues and Ralph Corderoy (GNU troff) for checking groff patches
|
||||
|
||||
Changes in version 1.14.5, released on March 10, 2019
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
|
|
142
TODO
142
TODO
|
@ -1,6 +1,6 @@
|
|||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.295 2019/06/11 16:04:36 schwarze Exp $
|
||||
* $Id: TODO,v 1.319 2021/09/21 17:58:13 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
|
@ -32,6 +32,43 @@ Many issues are annotated for difficulty as follows:
|
|||
Obviously, as the issues have not been solved yet, these annotations
|
||||
are mere guesses, and some may be wrong.
|
||||
|
||||
************************************************************************
|
||||
* assertion failures
|
||||
************************************************************************
|
||||
|
||||
- .if n .ce in the middle of .TS data
|
||||
afl case f1/id:000103,sig:06,src:009024+009105,op:splice,rep:2 (jes@)
|
||||
While roff_parseln() prevents .ce and similar requests in the middle
|
||||
of a tbl, the guard is no longer effective when the .ce is wrapped
|
||||
in a roff block, for example a conditional. The resulting assertion
|
||||
has never been seen in any real-world manual page.
|
||||
This is too dangerous to fix before release because it requires
|
||||
reorganizing the very delicate internals of roff_parseln(),
|
||||
which risks causing more severe bugs.
|
||||
loc * exist *** algo *** size * imp *
|
||||
|
||||
|
||||
************************************************************************
|
||||
* bugs: invalid output
|
||||
************************************************************************
|
||||
|
||||
- wrong number of layout columns in tbl(7) code generated by -T man
|
||||
https://savannah.gnu.org/bugs/?57720
|
||||
The reason likely is that tbl(7) does not support the -Bl -column
|
||||
feature of not explicitly specifying the last table column.
|
||||
loc ** exist * algo ** size * imp ***
|
||||
|
||||
- eqn(7) delimiters cause conditional lines to misbehave
|
||||
nabijaczleweli 8 Sep 2021 15:24:48 +0200
|
||||
loc * exist *** algo *** size * imp *
|
||||
|
||||
- roff.c, roff_expand() should not remove blanks before comments
|
||||
to Oliver Corff, Sep 7, 2021
|
||||
loc * exist * algo * size * imp *
|
||||
but watch out for regressions in the high-level parsers
|
||||
maybe it should not even remove comments? - consider T{\"
|
||||
|
||||
|
||||
************************************************************************
|
||||
* missing features
|
||||
************************************************************************
|
||||
|
@ -83,8 +120,39 @@ are mere guesses, and some may be wrong.
|
|||
Jan Stary 20 Apr 2019 20:16:54 +0200
|
||||
loc * exist *** algo *** size ** imp *
|
||||
|
||||
- mandoc replaces all ASCII control characters except tab and line feed
|
||||
with '?' during input. It would be better to replace them with
|
||||
Unicode escapes in preconv_encode() or somewhere in the vicinity,
|
||||
such that the already existing better replacement strings show
|
||||
up in the output. Emulating groff is not desirable: groff replaces
|
||||
0x00, 0x0b, and 0x0d to 0x1f with the empty string (bad because
|
||||
that's easy to overlook for the document author), 0x01 with '.'
|
||||
(very confusing), and passes through 0x02 to 0x08, 0x0c, and 0x7f
|
||||
raw (bad because that is insecure output). Remember that 0x07 may
|
||||
need special handling because it is sometimes used for certain
|
||||
delimiters, so it may need handling *after* roff.c rather than before.
|
||||
reminded by John Gardner 16 Jun 2020 14:26:28 +1000
|
||||
Actually, more ASCII control characters than just 0x07 may need
|
||||
later handling because they can for example be used in macro names.
|
||||
So they may need handling after roff(7) processing.
|
||||
pointed out by John Gardner 23 Jun 2020 18:28:08 +1000
|
||||
more info from John Gardner 29 Jun 2020 19:54:04 +1000
|
||||
loc ** exist ** algo ** size ** imp *
|
||||
|
||||
- many missing features used in old groff_char(7),
|
||||
some can possibly be supported
|
||||
kamil at netbsd 12 Nov 2020 17:27:09 +0100 + reply
|
||||
|
||||
- \s with arbitrary arg delimiters as already supported for other escapes
|
||||
found following jmc@'s mail 28 Apr 2021 18:31:41 +0100
|
||||
loc * exist * algo * size * imp *
|
||||
|
||||
--- missing mdoc features ----------------------------------------------
|
||||
|
||||
- .Sh and .Ss should be parsed and partially callable, see groff_mdoc(7)
|
||||
reed at reedmedia dot net Sat, 21 Dec 2019 17:13:07 -0600
|
||||
loc ** exist ** algo ** size ** imp *
|
||||
|
||||
- .Bl -column .Xo support is missing
|
||||
ultimate goal:
|
||||
restore .Xr and .Dv to
|
||||
|
@ -153,6 +221,13 @@ are mere guesses, and some may be wrong.
|
|||
|
||||
--- missing man features -----------------------------------------------
|
||||
|
||||
- MANWIDTH
|
||||
Markus Waldeck <waldeck at gmx dot de> 9 Jun 2015 05:49:56 +0200
|
||||
Laura Morales <lauretas at mail dot com> 26 Apr 2018 08:15:55 +0200
|
||||
Kamil Rytarowski <kamil at netbsd> 13 Nov 2020 00:19:36 +0100
|
||||
patch from Kamil 13 Nov 2020 22:37:07 +0100
|
||||
loc * exist * algo * size * imp *
|
||||
|
||||
- groff_www(7) .MTO and .URL
|
||||
These macros were used by the GNU grep(1) man page.
|
||||
The groff_www(7) manual page itself uses them, too.
|
||||
|
@ -217,6 +292,21 @@ are mere guesses, and some may be wrong.
|
|||
|
||||
--- missing misc features ----------------------------------------------
|
||||
|
||||
- conisder whether man(1) fallback code in main.c/fs_*() can find files
|
||||
like man3c/fopen.3c (illumos, Solaris) and man3p/fopen.3p (POSIX)
|
||||
discussed with Robert Mustacchi 21 Sep 2021 10:39:40 -0700
|
||||
loc * exist * algo ** size * imp **
|
||||
|
||||
- let makewhatis(8) follow symbolic links to dirs below READ_ALLOWED_PATH
|
||||
this may be feasible using fts_set(FTS_FOLLOW)
|
||||
mail to sternenseemann 19 Aug 2021 19:11:50 +0200
|
||||
loc * exist ** algo ** size * imp **
|
||||
|
||||
- -T man does not handle eqn(7) and tbl(7)
|
||||
Stephen Gregoratto 16 Feb 2020 01:28:07 +1100
|
||||
also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901636
|
||||
loc ** exist ** algo ** size *** imp **
|
||||
|
||||
- man -ks 1,8 route; kn@ Jul 13, 2018 orally
|
||||
|
||||
- italic correction (\/) in PostScript mode
|
||||
|
@ -291,6 +381,10 @@ are mere guesses, and some may be wrong.
|
|||
- check features of the Slackware man.conf(5) format
|
||||
Carsten Kunze Wed, 11 Mar 2015 17:57:24 +0100
|
||||
|
||||
- look at http://www.snake.net/software/troffcvt/ (troff to HTML)
|
||||
mentioned by Oliver Corff 22 Jan 2021 01:36:49 +0100
|
||||
|
||||
|
||||
************************************************************************
|
||||
* formatting issues: ugly output
|
||||
************************************************************************
|
||||
|
@ -370,10 +464,29 @@ are mere guesses, and some may be wrong.
|
|||
add a new <</Type /Font>> block to the PDF files with /BaseFont /Courier
|
||||
and change the /Name from /F0 to the new font (/F5 (?)).
|
||||
re-reported by tb@ Mon, 16 Mar 2015 16:47:21 +0100
|
||||
loc * exist ** algo ** size * imp **
|
||||
loc ** exist ** algo ** size * imp **
|
||||
|
||||
--- HTML issues --------------------------------------------------------
|
||||
|
||||
- make the HTML scaffolding customozable with -O skip=...
|
||||
mail to Oliver Corff 3 Jun 2021 17:28:02 +0200
|
||||
more feedback from Oliver 3 Jun 2021 18:27:56 +0200
|
||||
more feedback from Oliver 3 Jun 2021 23:37:18 +0200
|
||||
|
||||
- .Bd -unfilled should not use monospaced font
|
||||
anton@ 4 Mar 2021 08:19:35 +0100
|
||||
loc ** exist * algo * size * imp **
|
||||
|
||||
- HTML formatting of .nf should avoid <br/>
|
||||
and not close and re-open <pre> on .P
|
||||
my mail to ports@ 27 Jun 2021 16:09:20 +0200
|
||||
loc ** exist ** algo * size * imp **
|
||||
|
||||
- get rid of the last handful of style= attributes such that
|
||||
Content-Security-Policy: can be enabled without unsafe-inline
|
||||
suggested by bentley@ Nov 10, 2019 at 06:02:49AM -0700
|
||||
loc * exist * algo * size * imp **
|
||||
|
||||
- .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal
|
||||
space, see for example random(3). Introduced in
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92
|
||||
|
@ -386,6 +499,11 @@ are mere guesses, and some may be wrong.
|
|||
https://github.com/Debian/debiman/issues/15
|
||||
loc * exist * algo ** size ** imp **
|
||||
|
||||
- space characters can end up in href= attributes, for example coming
|
||||
from the first .Xr argument (where they make no sense, but still);
|
||||
does this affect other characters, other source macros...?
|
||||
Jackson Pauls 29 Aug 2017 16:56:27 +0100
|
||||
|
||||
- The tables used to render the three-part page headers actually force
|
||||
the width of the <body> to the max-width given for <html>.
|
||||
Not yet sure how to fix that...
|
||||
|
@ -470,6 +588,10 @@ are mere guesses, and some may be wrong.
|
|||
* warning issues
|
||||
************************************************************************
|
||||
|
||||
- shorten/simplify error messages for usage errors
|
||||
To: deraadt@ 25 Oct 2020 23:37:01 +0100
|
||||
loc ** exist * algo * size ** imp ***
|
||||
|
||||
- warn about duplicate .Sh/.Ss heads
|
||||
gre(4): Rename duplicate sections 20 Apr 2018 15:27:33 +0200
|
||||
loc * exist * algo * size * imp **
|
||||
|
@ -505,6 +627,10 @@ are mere guesses, and some may be wrong.
|
|||
output without intervening whitespace, in particular after a
|
||||
macro line (from the mdoclint TODO)
|
||||
|
||||
- report double .TH in man(7) as an ERROR and let the first win
|
||||
kristaps@ 28 Mar 2021 13:30:41 +0200
|
||||
loc * exist * algo * size * imp *
|
||||
|
||||
- makewhatis -p complains about language subdirectories:
|
||||
/usr/local/man//ru: Unknown directory part
|
||||
|
||||
|
@ -553,6 +679,9 @@ are mere guesses, and some may be wrong.
|
|||
* CGI issues
|
||||
************************************************************************
|
||||
|
||||
- Inspect httpd(8) logs on man.openbsd.org and consider
|
||||
whether logging can be improved, where bad syntax comes from,
|
||||
and what needs to be done to get rid of COMPAT_OLDURI.
|
||||
- Enable HTTP compression by detecting gzip encoding and filtering
|
||||
output through libz.
|
||||
- Privilege separation (see OpenSSH).
|
||||
|
@ -562,6 +691,15 @@ are mere guesses, and some may be wrong.
|
|||
* to improve in the groff_mdoc(7) macros
|
||||
************************************************************************
|
||||
|
||||
- delete OS release verification from .Dx, .Fx, .Nx, .Ox etc.
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=629161
|
||||
also Branden Robinson 18 Dec 2019 00:59:52 +1100
|
||||
|
||||
- Can the distinction between .Vt and .Va be made stricter,
|
||||
recommending .Vt extern char * Ns Va optarg ; ?
|
||||
What about the block macro properties of .Vt in the SYNOPSIS?
|
||||
zeurkous 25 Dec 2019 08:48:36 +0100
|
||||
|
||||
- .Cd # arch1, arch2 in section 4 pages:
|
||||
find better way to indicate multiple architectures, maybe:
|
||||
allow .Dt vgafb 4 "macppc sparc64"
|
||||
|
|
15
apropos.1
15
apropos.1
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: apropos.1,v 1.49 2018/11/22 12:33:52 schwarze Exp $
|
||||
.\" $Id: apropos.1,v 1.51 2020/10/01 22:50:00 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011,2012,2014,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -15,7 +15,7 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: November 22 2018 $
|
||||
.Dd $Mdocdate: October 1 2020 $
|
||||
.Dt APROPOS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -73,7 +73,7 @@ would.
|
|||
If the standard output is a terminal device and
|
||||
.Fl c
|
||||
is not specified, use
|
||||
.Xr more 1
|
||||
.Xr less 1
|
||||
to paginate them.
|
||||
In
|
||||
.Fl a
|
||||
|
@ -340,7 +340,7 @@ types appearing in function arguments in the SYNOPSIS
|
|||
Any non-empty value of the environment variable
|
||||
.Ev MANPAGER
|
||||
is used instead of the standard pagination program,
|
||||
.Xr more 1 ;
|
||||
.Xr less 1 ;
|
||||
see
|
||||
.Xr man 1
|
||||
for details.
|
||||
|
@ -363,8 +363,7 @@ Specifies the pagination program to use when
|
|||
.Ev MANPAGER
|
||||
is not defined.
|
||||
If neither PAGER nor MANPAGER is defined,
|
||||
.Xr more 1
|
||||
.Fl s
|
||||
.Xr less 1
|
||||
is used.
|
||||
Only used if
|
||||
.Fl a
|
||||
|
@ -404,6 +403,10 @@ Search in names and descriptions using a case-sensitive regular expression:
|
|||
.Pp
|
||||
.Dl $ apropos \(aq\(tiset.?[ug]id\(aq
|
||||
.Pp
|
||||
Search for all manual pages in a given section:
|
||||
.Pp
|
||||
.Dl $ apropos \-s 9 \&.
|
||||
.Pp
|
||||
Search for manuals in the library section mentioning both the
|
||||
.Qq optind
|
||||
and the
|
||||
|
|
4
arch.c
4
arch.c
|
@ -1,4 +1,4 @@
|
|||
/* $Id: arch.c,v 1.15 2019/05/21 07:52:00 schwarze Exp $ */
|
||||
/* $Id: arch.c,v 1.17 2021/05/13 13:33:11 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -26,7 +26,7 @@ arch_valid(const char *arch, enum mandoc_os os)
|
|||
const char *openbsd_arch[] = {
|
||||
"alpha", "amd64", "arm64", "armv7", "hppa", "i386",
|
||||
"landisk", "loongson", "luna88k", "macppc", "mips64",
|
||||
"octeon", "sgi", "sparc64", NULL
|
||||
"octeon", "powerpc64", "riscv64", "sparc64", NULL
|
||||
};
|
||||
const char *netbsd_arch[] = {
|
||||
"acorn26", "acorn32", "algor", "alpha", "amiga",
|
||||
|
|
4
att.c
4
att.c
|
@ -1,4 +1,4 @@
|
|||
/* $Id: att.c,v 1.18 2018/12/13 11:55:46 schwarze Exp $ */
|
||||
/* $Id: att.c,v 1.19 2021/09/04 20:26:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -37,7 +37,7 @@ mdoc_a2att(const char *p)
|
|||
LINE("v5", "Version\\~5 AT&T UNIX");
|
||||
LINE("v6", "Version\\~6 AT&T UNIX");
|
||||
LINE("v7", "Version\\~7 AT&T UNIX");
|
||||
LINE("32v", "Version\\~32V AT&T UNIX");
|
||||
LINE("32v", "Version\\~7 AT&T UNIX/32V");
|
||||
LINE("III", "AT&T System\\~III UNIX");
|
||||
LINE("V", "AT&T System\\~V UNIX");
|
||||
LINE("V.1", "AT&T System\\~V Release\\~1 UNIX");
|
||||
|
|
4
catman.c
4
catman.c
|
@ -1,4 +1,4 @@
|
|||
/* $Id: catman.c,v 1.21 2017/02/18 12:24:24 schwarze Exp $ */
|
||||
/* $Id: catman.c,v 1.22 2020/06/14 23:40:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_CMSG_XPG42
|
||||
#if NEED_XPG4_2
|
||||
#define _XPG4_2
|
||||
#endif
|
||||
|
||||
|
|
72
cgi.c
72
cgi.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: cgi.c,v 1.167 2019/07/10 12:49:20 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.175 2021/08/19 15:23:36 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014-2019, 2021 Ingo Schwarze <schwarze@usta.de>
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017, 2018 Ingo Schwarze <schwarze@usta.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Implementation of the man.cgi(8) program.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -70,14 +72,15 @@ enum focus {
|
|||
static void html_print(const char *);
|
||||
static void html_putchar(char);
|
||||
static int http_decode(char *);
|
||||
static void http_encode(const char *p);
|
||||
static void http_encode(const char *);
|
||||
static void parse_manpath_conf(struct req *);
|
||||
static void parse_path_info(struct req *req, const char *path);
|
||||
static void parse_path_info(struct req *, const char *);
|
||||
static void parse_query_string(struct req *, const char *);
|
||||
static void pg_error_badrequest(const char *);
|
||||
static void pg_error_internal(void);
|
||||
static void pg_index(const struct req *);
|
||||
static void pg_noresult(const struct req *, const char *);
|
||||
static void pg_noresult(const struct req *, int, const char *,
|
||||
const char *);
|
||||
static void pg_redirect(const struct req *, const char *);
|
||||
static void pg_search(const struct req *);
|
||||
static void pg_searchres(const struct req *,
|
||||
|
@ -119,16 +122,18 @@ static const char *const sec_names[] = {
|
|||
static const int sec_MAX = sizeof(sec_names) / sizeof(char *);
|
||||
|
||||
static const char *const arch_names[] = {
|
||||
"amd64", "alpha", "armv7", "arm64",
|
||||
"hppa", "i386", "landisk",
|
||||
"loongson", "luna88k", "macppc", "mips64",
|
||||
"octeon", "sgi", "socppc", "sparc64",
|
||||
"amd64", "alpha", "armv7", "arm64",
|
||||
"hppa", "i386", "landisk", "loongson",
|
||||
"luna88k", "macppc", "mips64", "octeon",
|
||||
"powerpc64", "riscv64", "sparc64",
|
||||
|
||||
"amiga", "arc", "armish", "arm32",
|
||||
"atari", "aviion", "beagle", "cats",
|
||||
"hppa64", "hp300",
|
||||
"ia64", "mac68k", "mvme68k", "mvme88k",
|
||||
"mvmeppc", "palm", "pc532", "pegasos",
|
||||
"pmax", "powerpc", "solbourne", "sparc",
|
||||
"pmax", "powerpc", "sgi", "socppc",
|
||||
"solbourne", "sparc",
|
||||
"sun3", "vax", "wgrisc", "x68k",
|
||||
"zaurus"
|
||||
};
|
||||
|
@ -339,6 +344,8 @@ resp_begin_http(int code, const char *msg)
|
|||
|
||||
printf("Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Cache-Control: no-cache\r\n"
|
||||
"Content-Security-Policy: default-src 'none'; "
|
||||
"style-src 'self' 'unsafe-inline'\r\n"
|
||||
"Pragma: no-cache\r\n"
|
||||
"\r\n");
|
||||
|
||||
|
@ -363,7 +370,8 @@ resp_copy(const char *filename)
|
|||
static void
|
||||
resp_begin_html(int code, const char *msg, const char *file)
|
||||
{
|
||||
char *cp;
|
||||
const char *name, *sec, *cp;
|
||||
int namesz, secsz;
|
||||
|
||||
resp_begin_http(code, msg);
|
||||
|
||||
|
@ -378,12 +386,27 @@ resp_begin_html(int code, const char *msg, const char *file)
|
|||
" <title>",
|
||||
CSS_DIR);
|
||||
if (file != NULL) {
|
||||
if ((cp = strrchr(file, '/')) != NULL)
|
||||
file = cp + 1;
|
||||
if ((cp = strrchr(file, '.')) != NULL) {
|
||||
printf("%.*s(%s) - ", (int)(cp - file), file, cp + 1);
|
||||
} else
|
||||
printf("%s - ", file);
|
||||
cp = strrchr(file, '/');
|
||||
name = cp == NULL ? file : cp + 1;
|
||||
cp = strrchr(name, '.');
|
||||
namesz = cp == NULL ? strlen(name) : cp - name;
|
||||
sec = NULL;
|
||||
if (cp != NULL && cp[1] != '0') {
|
||||
sec = cp + 1;
|
||||
secsz = strlen(sec);
|
||||
} else if (name - file > 1) {
|
||||
for (cp = name - 2; cp >= file; cp--) {
|
||||
if (*cp < '1' || *cp > '9')
|
||||
continue;
|
||||
sec = cp;
|
||||
secsz = name - cp - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("%.*s", namesz, name);
|
||||
if (sec != NULL)
|
||||
printf("(%.*s)", secsz, sec);
|
||||
fputs(" - ", stdout);
|
||||
}
|
||||
printf("%s</title>\n"
|
||||
"</head>\n"
|
||||
|
@ -408,7 +431,8 @@ resp_searchform(const struct req *req, enum focus focus)
|
|||
{
|
||||
int i;
|
||||
|
||||
printf("<form action=\"/%s\" method=\"get\">\n"
|
||||
printf("<form action=\"/%s\" method=\"get\" "
|
||||
"autocomplete=\"off\" autocapitalize=\"none\">\n"
|
||||
" <fieldset>\n"
|
||||
" <legend>Manual Page Search Parameters</legend>\n",
|
||||
scriptname);
|
||||
|
@ -546,12 +570,13 @@ pg_index(const struct req *req)
|
|||
}
|
||||
|
||||
static void
|
||||
pg_noresult(const struct req *req, const char *msg)
|
||||
pg_noresult(const struct req *req, int code, const char *http_msg,
|
||||
const char *user_msg)
|
||||
{
|
||||
resp_begin_html(200, NULL, NULL);
|
||||
resp_begin_html(code, http_msg, NULL);
|
||||
resp_searchform(req, FOCUS_QUERY);
|
||||
puts("<p>");
|
||||
puts(msg);
|
||||
puts(user_msg);
|
||||
puts("</p>");
|
||||
resp_end_html();
|
||||
}
|
||||
|
@ -1016,9 +1041,10 @@ pg_search(const struct req *req)
|
|||
if (req->isquery && req->q.equal && argc == 1)
|
||||
pg_redirect(req, argv[0]);
|
||||
else if (mansearch(&search, &paths, argc, argv, &res, &ressz) == 0)
|
||||
pg_noresult(req, "You entered an invalid query.");
|
||||
pg_noresult(req, 400, "Bad Request",
|
||||
"You entered an invalid query.");
|
||||
else if (ressz == 0)
|
||||
pg_noresult(req, "No results found.");
|
||||
pg_noresult(req, 404, "Not Found", "No results found.");
|
||||
else
|
||||
pg_searchres(req, res, ressz);
|
||||
|
||||
|
|
7
chars.c
7
chars.c
|
@ -1,7 +1,8 @@
|
|||
/* $Id: chars.c,v 1.78 2018/12/15 19:30:26 schwarze Exp $ */
|
||||
/* $Id: chars.c,v 1.79 2020/02/13 16:18:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2020
|
||||
* 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
|
||||
|
@ -47,7 +48,7 @@ static struct ln lines[] = {
|
|||
/* Spacing. */
|
||||
{ " ", ascii_nbrsp, 0x00a0 },
|
||||
{ "~", ascii_nbrsp, 0x00a0 },
|
||||
{ "0", " ", 0x2002 },
|
||||
{ "0", ascii_nbrsp, 0x00a0 },
|
||||
{ ":", ascii_break, 0 },
|
||||
|
||||
/* Lines. */
|
||||
|
|
13
compat_err.c
13
compat_err.c
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_ERR
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_err.c,v 1.4 2015/11/26 07:42:11 schwarze Exp $ */
|
||||
/* $Id: compat_err.c,v 1.5 2020/06/15 01:37:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -35,6 +27,7 @@ int dummy;
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -108,5 +101,3 @@ warnx(const char *fmt, ...)
|
|||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
29
compat_fts.c
29
compat_fts.c
|
@ -1,13 +1,5 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_FTS
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_fts.c,v 1.14 2017/02/18 12:24:24 schwarze Exp $ */
|
||||
/* $OpenBSD: fts.c,v 1.56 2016/09/21 04:38:56 guenther Exp $ */
|
||||
/* $Id: compat_fts.c,v 1.17 2020/06/15 01:37:14 schwarze Exp $ */
|
||||
/* $OpenBSD: fts.c,v 1.59 2019/06/28 13:32:41 deraadt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,6 +29,7 @@ int dummy;
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -62,6 +55,8 @@ static int fts_palloc(FTS *, size_t);
|
|||
static FTSENT *fts_sort(FTS *, FTSENT *, int);
|
||||
static unsigned short fts_stat(FTS *, FTSENT *);
|
||||
|
||||
typedef int (*qsort_compar_proto)(const void *, const void *);
|
||||
|
||||
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
|
@ -573,19 +568,20 @@ fts_sort(FTS *sp, FTSENT *head, int nitems)
|
|||
if (nitems > sp->fts_nitems) {
|
||||
struct _ftsent **a;
|
||||
|
||||
sp->fts_nitems = nitems + 40;
|
||||
if ((a = reallocarray(sp->fts_array,
|
||||
sp->fts_nitems, sizeof(FTSENT *))) == NULL) {
|
||||
nitems + 40, sizeof(FTSENT *))) == NULL) {
|
||||
free(sp->fts_array);
|
||||
sp->fts_array = NULL;
|
||||
sp->fts_nitems = 0;
|
||||
return (head);
|
||||
}
|
||||
sp->fts_nitems = nitems + 40;
|
||||
sp->fts_array = a;
|
||||
}
|
||||
for (ap = sp->fts_array, p = head; p; p = p->fts_link)
|
||||
*ap++ = p;
|
||||
qsort(sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
|
||||
qsort(sp->fts_array, nitems, sizeof(FTSENT *),
|
||||
(qsort_compar_proto)sp->fts_compar);
|
||||
for (head = *(ap = sp->fts_array); --nitems; ++ap)
|
||||
ap[0]->fts_link = ap[1];
|
||||
ap[0]->fts_link = NULL;
|
||||
|
@ -648,13 +644,14 @@ fts_palloc(FTS *sp, size_t more)
|
|||
errno = ENAMETOOLONG;
|
||||
return (1);
|
||||
}
|
||||
sp->fts_pathlen += more;
|
||||
p = realloc(sp->fts_path, sp->fts_pathlen);
|
||||
p = recallocarray(sp->fts_path, sp->fts_pathlen,
|
||||
sp->fts_pathlen + more, 1);
|
||||
if (p == NULL) {
|
||||
free(sp->fts_path);
|
||||
sp->fts_path = NULL;
|
||||
return (1);
|
||||
}
|
||||
sp->fts_pathlen += more;
|
||||
sp->fts_path = p;
|
||||
return (0);
|
||||
}
|
||||
|
@ -697,5 +694,3 @@ fts_maxarglen(char * const *argv)
|
|||
max = len;
|
||||
return (max + 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,7 +43,8 @@ typedef struct {
|
|||
char *fts_path; /* path for this descent */
|
||||
size_t fts_pathlen; /* sizeof(path) */
|
||||
int fts_nitems; /* elements in the sort array */
|
||||
int (*fts_compar)(); /* compare function */
|
||||
int (*fts_compar)(const struct _ftsent **, const struct _ftsent **);
|
||||
/* compare function */
|
||||
|
||||
#define FTS_NOCHDIR 0x0004 /* don't change directories */
|
||||
#define FTS_PHYSICAL 0x0010 /* physical walk */
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_GETLINE
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_getline.c,v 1.1 2015/11/07 20:52:52 schwarze Exp $ */
|
||||
/* $Id: compat_getline.c,v 1.2 2020/06/15 01:37:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -22,6 +14,7 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
@ -64,5 +57,3 @@ getline(char **buf, size_t *bufsz, FILE *fp)
|
|||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_GETSUBOPT
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_getsubopt.c,v 1.5 2014/08/17 20:53:50 schwarze Exp $ */
|
||||
/* $Id: compat_getsubopt.c,v 1.6 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -37,6 +29,7 @@ int dummy;
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -92,5 +85,3 @@ getsubopt(char **optionp, char * const *tokens, char **valuep)
|
|||
return(cnt);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_ISBLANK
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_isblank.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: compat_isblank.c,v 1.3 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -22,12 +14,10 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
int
|
||||
isblank(int c)
|
||||
{
|
||||
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_MKDTEMP
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_mkdtemp.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: compat_mkdtemp.c,v 1.4 2021/09/19 15:02:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2015, 2021 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
|
||||
|
@ -25,6 +17,7 @@ int dummy;
|
|||
* The algorithm of this function is inspired by OpenBSD mkdtemp(3)
|
||||
* by Theo de Raadt and Todd Miller, but the code differs.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
@ -43,19 +36,15 @@ mkdtemp(char *path)
|
|||
start--;
|
||||
|
||||
for (tries = INT_MAX; tries; tries--) {
|
||||
if (mktemp(path) == NULL) {
|
||||
errno = EEXIST;
|
||||
if (mktemp(path) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0)
|
||||
return path;
|
||||
if (errno != EEXIST)
|
||||
return NULL;
|
||||
for (cp = start; *cp != '\0'; cp++)
|
||||
*cp = 'X';
|
||||
if (errno != EEXIST)
|
||||
return NULL;
|
||||
}
|
||||
errno = EEXIST;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
63
compat_mkstemps.c
Normal file
63
compat_mkstemps.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* $Id: compat_mkstemps.c,v 1.1 2021/09/19 15:05:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015, 2021 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.
|
||||
*
|
||||
* Parts of the algorithm of this function are inspired by OpenBSD
|
||||
* mkdtemp(3) by Theo de Raadt and Todd Miller, but the code differs.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
mkstemps(char *path, int suffixlen)
|
||||
{
|
||||
char *start, *end, *cp;
|
||||
int fd, tries;
|
||||
char backup;
|
||||
|
||||
end = strchr(path, '\0');
|
||||
if (suffixlen < 0 || suffixlen > end - path - 6) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
end -= suffixlen;
|
||||
for (start = end; start > path; start--)
|
||||
if (start[-1] != 'X')
|
||||
break;
|
||||
|
||||
backup = *end;
|
||||
for (tries = INT_MAX; tries; tries--) {
|
||||
*end = '\0';
|
||||
cp = mktemp(path);
|
||||
*end = backup;
|
||||
if (cp == NULL)
|
||||
return -1;
|
||||
fd = open(path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (fd != -1)
|
||||
return fd;
|
||||
for (cp = start; cp < end; cp++)
|
||||
*cp = 'X';
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
|
@ -1,11 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_OHASH
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_ohash.c,v 1.7 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $OpenBSD: ohash.c,v 1.1 2014/06/02 18:52:03 deraadt Exp $ */
|
||||
|
||||
/* Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
|
||||
|
@ -22,9 +15,9 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -335,5 +328,3 @@ ohash_qlookupi(struct ohash *h, const char *s, const char **e)
|
|||
hv = ohash_interval(s, e);
|
||||
return ohash_lookup_interval(h, s, *e, hv);
|
||||
}
|
||||
|
||||
#endif /*!HAVE_OHASH*/
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_PROGNAME
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_progname.c,v 1.1 2015/11/06 16:30:33 schwarze Exp $ */
|
||||
/* $Id: compat_progname.c,v 1.2 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -22,21 +14,18 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
static const char *progname;
|
||||
|
||||
void
|
||||
setprogname(const char *name)
|
||||
{
|
||||
|
||||
progname = name;
|
||||
}
|
||||
|
||||
const char *
|
||||
getprogname(void)
|
||||
{
|
||||
|
||||
return progname;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_REALLOCARRAY
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_reallocarray.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */
|
||||
/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
|
||||
/* $Id: compat_reallocarray.c,v 1.5 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
|
@ -23,6 +15,7 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
@ -45,5 +38,3 @@ reallocarray(void *optr, size_t nmemb, size_t size)
|
|||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
||||
|
||||
#endif /*!HAVE_REALLOCARRAY*/
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
#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 $ */
|
||||
/* $Id: compat_recallocarray.c,v 1.2 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Otto Moerbeek <otto@drijf.net>
|
||||
* Copyright (c) 2008, 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
|
||||
|
@ -23,18 +15,19 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.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))
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
/*
|
||||
* Even though specified in POSIX, the PAGESIZE and PAGE_SIZE
|
||||
|
@ -42,7 +35,7 @@ int dummy;
|
|||
* to avoid free() overhead for small shrinking, simply pick
|
||||
* an arbitrary number.
|
||||
*/
|
||||
#define MALLOC_PAGESIZE (1UL << 12)
|
||||
#define getpagesize() (1UL << 12)
|
||||
|
||||
|
||||
void *
|
||||
|
@ -75,7 +68,7 @@ recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
|
|||
if (newsize <= oldsize) {
|
||||
size_t d = oldsize - newsize;
|
||||
|
||||
if (d < oldsize / 2 && d < MALLOC_PAGESIZE) {
|
||||
if (d < oldsize / 2 && d < getpagesize()) {
|
||||
memset((char *)ptr + newsize, 0, d);
|
||||
return ptr;
|
||||
}
|
||||
|
@ -104,5 +97,3 @@ recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
|
|||
|
||||
return newptr;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_RECALLOCARRAY */
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_STRCASESTR
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_strcasestr.c,v 1.4 2014/12/11 09:19:32 schwarze Exp $ */
|
||||
/* $Id: compat_strcasestr.c,v 1.5 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -40,6 +32,7 @@ int dummy;
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
@ -69,5 +62,3 @@ strcasestr(const char *s, const char *find)
|
|||
}
|
||||
return __UNCONST(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
#include "config.h"
|
||||
/* $Id: compat_stringlist.c,v 1.8 2020/06/15 21:48:09 schwarze Exp $ */
|
||||
/* $NetBSD: stringlist.c,v 1.14 2015/05/21 01:29:13 christos Exp $ */
|
||||
|
||||
#if HAVE_STRINGLIST
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_stringlist.c,v 1.6 2015/11/07 14:22:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
|
||||
/*-
|
||||
* Copyright (c) 1994, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
@ -20,22 +17,20 @@ int dummy;
|
|||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "compat_stringlist.h"
|
||||
|
@ -52,13 +47,15 @@ sl_init(void)
|
|||
|
||||
sl = malloc(sizeof(StringList));
|
||||
if (sl == NULL)
|
||||
err(1, "stringlist");
|
||||
return NULL;
|
||||
|
||||
sl->sl_cur = 0;
|
||||
sl->sl_max = _SL_CHUNKSIZE;
|
||||
sl->sl_str = reallocarray(NULL, sl->sl_max, sizeof(char *));
|
||||
if (sl->sl_str == NULL)
|
||||
err(1, "stringlist");
|
||||
if (sl->sl_str == NULL) {
|
||||
free(sl);
|
||||
sl = NULL;
|
||||
}
|
||||
return sl;
|
||||
}
|
||||
|
||||
|
@ -70,14 +67,17 @@ int
|
|||
sl_add(StringList *sl, char *name)
|
||||
{
|
||||
if (sl->sl_cur == sl->sl_max - 1) {
|
||||
char **new;
|
||||
|
||||
new = reallocarray(sl->sl_str, (sl->sl_max + _SL_CHUNKSIZE),
|
||||
sizeof(char *));
|
||||
if (new == NULL)
|
||||
return -1;
|
||||
sl->sl_max += _SL_CHUNKSIZE;
|
||||
sl->sl_str = reallocarray(sl->sl_str,
|
||||
sl->sl_max, sizeof(char *));
|
||||
if (sl->sl_str == NULL)
|
||||
return (-1);
|
||||
sl->sl_str = new;
|
||||
}
|
||||
sl->sl_str[sl->sl_cur++] = name;
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,4 +116,20 @@ sl_find(StringList *sl, const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
int
|
||||
sl_delete(StringList *sl, const char *name, int all)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < sl->sl_cur; i++)
|
||||
if (strcmp(sl->sl_str[i], name) == 0) {
|
||||
if (all)
|
||||
free(sl->sl_str[i]);
|
||||
for (j = i + 1; j < sl->sl_cur; j++)
|
||||
sl->sl_str[j - 1] = sl->sl_str[j];
|
||||
sl->sl_str[--sl->sl_cur] = NULL;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* $Id: compat_stringlist.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */
|
||||
/* $Id: compat_stringlist.h,v 1.5 2020/06/15 21:48:09 schwarze Exp $ */
|
||||
/* $NetBSD: stringlist.h,v 1.7 2008/04/28 20:22:54 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
|
||||
/*-
|
||||
* Copyright (c) 1994 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
@ -14,17 +17,17 @@
|
|||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -38,8 +41,8 @@ typedef struct _stringlist {
|
|||
size_t sl_cur;
|
||||
} StringList;
|
||||
|
||||
|
||||
StringList *sl_init(void);
|
||||
int sl_add(StringList *, char *);
|
||||
void sl_free(StringList *, int);
|
||||
char *sl_find(StringList *, const char *);
|
||||
StringList *sl_init(void);
|
||||
int sl_add(StringList *, char *);
|
||||
void sl_free(StringList *, int);
|
||||
char *sl_find(StringList *, const char *);
|
||||
int sl_delete(StringList *, const char *, int);
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_STRLCAT
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
||||
/* $Id: compat_strlcat.c,v 1.6 2020/06/15 20:49:57 schwarze Exp $ */
|
||||
/* $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <millert@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,43 +16,42 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
* Appends src to string dst of size dsize (unlike strncat, dsize is the
|
||||
* full size of dst, not space left). At most dsize-1 characters
|
||||
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
|
||||
* If retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
strlcat(char *dst, const char *src, size_t dsize)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
const char *odst = dst;
|
||||
const char *osrc = src;
|
||||
size_t n = dsize;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
/* Find the end of dst and adjust bytes left but don't go past end. */
|
||||
while (n-- != 0 && *dst != '\0')
|
||||
dst++;
|
||||
dlen = dst - odst;
|
||||
n = dsize - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
if (n-- == 0)
|
||||
return(dlen + strlen(src));
|
||||
while (*src != '\0') {
|
||||
if (n != 0) {
|
||||
*dst++ = *src;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
src++;
|
||||
}
|
||||
*d = '\0';
|
||||
*dst = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
return(dlen + (src - osrc)); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_STRLCPY
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
|
||||
/* $Id: compat_strlcpy.c,v 1.6 2020/06/15 20:49:57 schwarze Exp $ */
|
||||
/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <millert@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,39 +16,37 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
* Copy string src to buffer dst of size dsize. At most dsize-1
|
||||
* chars will be copied. Always NUL terminates (unless dsize == 0).
|
||||
* Returns strlen(src); if retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
strlcpy(char *dst, const char *src, size_t dsize)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
const char *osrc = src;
|
||||
size_t nleft = dsize;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0) {
|
||||
while (--n != 0) {
|
||||
if ((*d++ = *s++) == '\0')
|
||||
/* Copy as many bytes as will fit. */
|
||||
if (nleft != 0) {
|
||||
while (--nleft != 0) {
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
/* Not enough room in dst, add NUL and traverse rest of src. */
|
||||
if (nleft == 0) {
|
||||
if (dsize != 0)
|
||||
*dst = '\0'; /* NUL-terminate dst */
|
||||
while (*src++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
return(src - osrc - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
#include "config.h"
|
||||
/* $Id: compat_strndup.c,v 1.3 2020/06/15 20:19:39 schwarze Exp $ */
|
||||
/* $OpenBSD: strndup.c,v 1.3 2019/01/25 00:19:25 millert Exp $ */
|
||||
|
||||
#if HAVE_STRNDUP
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_strndup.c,v 1.1 2018/02/27 11:16:23 schwarze Exp $ */
|
||||
/* OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp */
|
||||
/*
|
||||
* Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2010 Todd C. Miller <millert@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,6 +16,7 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -46,5 +40,3 @@ strndup(const char *str, size_t maxlen)
|
|||
|
||||
return copy;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_STRSEP
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_strsep.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */
|
||||
/* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $ */
|
||||
/* $Id: compat_strsep.c,v 1.5 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $OpenBSD: strsep.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
|
@ -37,6 +29,7 @@ int dummy;
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are possibly-empty
|
||||
|
@ -75,5 +68,3 @@ strsep(char **stringp, const char *delim)
|
|||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_STRTONUM
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_strtonum.c,v 1.1 2015/02/16 14:56:22 schwarze Exp $ */
|
||||
/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */
|
||||
/* $Id: compat_strtonum.c,v 1.2 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Ted Unangst and Todd Miller
|
||||
|
@ -25,6 +17,7 @@ int dummy;
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
@ -72,5 +65,3 @@ strtonum(const char *numstr, long long minval, long long maxval,
|
|||
|
||||
return (ll);
|
||||
}
|
||||
|
||||
#endif /* !HAVE_STRTONUM */
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
#include "config.h"
|
||||
|
||||
#if HAVE_VASPRINTF
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $Id: compat_vasprintf.c,v 1.3 2015/10/06 18:32:19 schwarze Exp $ */
|
||||
/* $Id: compat_vasprintf.c,v 1.4 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -28,6 +20,7 @@ int dummy;
|
|||
* printf(3) or completely reimplementing printf(3), i can't think
|
||||
* of another portable solution.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -52,5 +45,3 @@ vasprintf(char **ret, const char *format, va_list ap)
|
|||
*ret = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
317
configure
vendored
317
configure
vendored
|
@ -1,8 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.71 2019/07/01 22:56:24 schwarze Exp $
|
||||
# $Id: configure,v 1.81 2021/09/20 10:19:51 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -33,7 +33,7 @@ echo "file config.log: writing..."
|
|||
# Initialize all variables here,
|
||||
# such that nothing can leak in from the environment.
|
||||
|
||||
SOURCEDIR=`dirname "$0"`
|
||||
SOURCEDIR=`dirname "${0}"`
|
||||
|
||||
MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
|
||||
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
|
@ -41,8 +41,10 @@ OSENUM=
|
|||
OSNAME=
|
||||
UTF8_LOCALE=
|
||||
|
||||
CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | env -i make -sf -`
|
||||
AR=ar
|
||||
CC=cc
|
||||
CFLAGS=
|
||||
FATAL=0
|
||||
LDADD=
|
||||
LDFLAGS=
|
||||
LD_NANOSLEEP=
|
||||
|
@ -54,8 +56,8 @@ BUILD_CGI=0
|
|||
BUILD_CATMAN=0
|
||||
INSTALL_LIBMANDOC=0
|
||||
|
||||
HAVE_ATTRIBUTE=
|
||||
HAVE_CMSG=
|
||||
HAVE_CMSG_XPG42=0
|
||||
HAVE_DIRENT_NAMLEN=
|
||||
HAVE_EFTYPE=
|
||||
HAVE_ENDIAN=
|
||||
|
@ -67,6 +69,7 @@ HAVE_GETSUBOPT=
|
|||
HAVE_ISBLANK=
|
||||
HAVE_LESS_T=
|
||||
HAVE_MKDTEMP=
|
||||
HAVE_MKSTEMPS=
|
||||
HAVE_NANOSLEEP=
|
||||
HAVE_NTOHL=
|
||||
HAVE_O_DIRECTORY=
|
||||
|
@ -94,6 +97,10 @@ HAVE_WCHAR=
|
|||
|
||||
NEED_GNU_SOURCE=0
|
||||
NEED_OPENBSD_SOURCE=0
|
||||
NEED_XPG4_2=0
|
||||
|
||||
MANDOC_COBJS=
|
||||
SOELIM_COBJS=
|
||||
|
||||
PREFIX="/usr/local"
|
||||
BINDIR=
|
||||
|
@ -102,7 +109,7 @@ BIN_FROM_SBIN=
|
|||
INCLUDEDIR=
|
||||
LIBDIR=
|
||||
MANDIR=
|
||||
HOMEBREWDIR=
|
||||
READ_ALLOWED_PATH=
|
||||
|
||||
WWWPREFIX="/var/www"
|
||||
HTDOCDIR=
|
||||
|
@ -114,6 +121,7 @@ BINM_MAKEWHATIS="makewhatis"
|
|||
BINM_MAN="man"
|
||||
BINM_SOELIM="soelim"
|
||||
BINM_WHATIS="whatis"
|
||||
BINM_PAGER=
|
||||
MANM_MAN="man"
|
||||
MANM_MANCONF="man.conf"
|
||||
MANM_MDOC="mdoc"
|
||||
|
@ -159,16 +167,17 @@ ismanual() {
|
|||
# In case of failure, do not decide anything yet.
|
||||
# Arguments: test file name, test var name, additional CFLAGS
|
||||
singletest() {
|
||||
n=${1}${3}${4}
|
||||
n=${1}${3}
|
||||
cat 1>&3 << __HEREDOC__
|
||||
testing ${n} ...
|
||||
${COMP} -o test-${1} test-${1}.c ${3} ${4}
|
||||
${COMP} -o test-${1} test-${1}.c ${3}
|
||||
__HEREDOC__
|
||||
|
||||
if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} ${4} 1>&3 2>&3
|
||||
if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} 1>&3 2>&3
|
||||
then
|
||||
echo "partial result of ${n}: ${CC} succeeded" 1>&3
|
||||
else
|
||||
echo "tested ${n}: no (compilation failed)" 1>&2
|
||||
echo "result of ${n}: ${CC} failed with exit status $?" 1>&3
|
||||
echo "result of compiling ${n}: no" 1>&3
|
||||
echo 1>&3
|
||||
|
@ -180,11 +189,16 @@ __HEREDOC__
|
|||
echo "result of running ${n}: yes" 1>&3
|
||||
echo 1>&3
|
||||
eval HAVE_${2}=1
|
||||
[ "X$3" = "X-D_GNU_SOURCE" ] && NEED_GNU_SOURCE=1
|
||||
[ "X$3" = "X-D_OPENBSD_SOURCE" ] && NEED_OPENBSD_SOURCE=1
|
||||
[ "${3}" = "-D_GNU_SOURCE" ] && NEED_GNU_SOURCE=1
|
||||
[ "${3}" = "-D_OPENBSD_SOURCE" ] && NEED_OPENBSD_SOURCE=1
|
||||
[ "${3}" = "-D_XPG4_2" ] && NEED_XPG4_2=1
|
||||
[ "${3}" = "-lrt" ] && LD_NANOSLEEP="-lrt"
|
||||
[ "${3}" = "-lsocket" ] && LD_RECVMSG="-lsocket"
|
||||
[ "${3}" = "-lutil" ] && LD_OHASH="-lutil"
|
||||
rm "test-${1}"
|
||||
return 0
|
||||
else
|
||||
echo "tested ${n}: no (execution failed)" 1>&2
|
||||
echo "result of ${n}: execution failed with exit status $?" 1>&3
|
||||
echo "result of running ${n}: no" 1>&3
|
||||
echo 1>&3
|
||||
|
@ -196,11 +210,12 @@ __HEREDOC__
|
|||
# Run a complete autoconfiguration test, including the check for
|
||||
# a manual override and disabling the feature on failure.
|
||||
# Arguments: test file name, test var name, additional CFLAGS
|
||||
# The final argument can optionally be repeated a second time.
|
||||
runtest() {
|
||||
eval _manual=\${HAVE_${2}}
|
||||
ismanual "${1}" "${2}" "${_manual}" && return 0
|
||||
singletest "${1}" "${2}" "${3}" "${4}" && return 0
|
||||
echo "tested ${1}${3}${4}: no" 1>&2
|
||||
singletest "${1}" "${2}" "${3}" && return 0
|
||||
[ -n "${4}" ] && singletest "${1}" "${2}" "${4}" && return 0
|
||||
eval HAVE_${2}=0
|
||||
return 1
|
||||
}
|
||||
|
@ -208,7 +223,7 @@ runtest() {
|
|||
# Select a UTF-8 locale.
|
||||
get_locale() {
|
||||
[ -n "${HAVE_WCHAR}" ] && [ "${HAVE_WCHAR}" -eq 0 ] && return 0
|
||||
ismanual UTF8_LOCALE UTF8_LOCALE "$UTF8_LOCALE" && return 0
|
||||
ismanual UTF8_LOCALE UTF8_LOCALE "${UTF8_LOCALE}" && return 0
|
||||
echo "testing UTF8_LOCALE ..." 1>&3
|
||||
UTF8_LOCALE=`locale -a | grep -i '^en_US\.UTF-*8$' | head -n 1`
|
||||
if [ -z "${UTF8_LOCALE}" ]; then
|
||||
|
@ -228,9 +243,9 @@ if [ -n "${OSENUM}" ]; then
|
|||
echo "OSENUM specified manually: ${OSENUM}" 1>&3
|
||||
else
|
||||
OSDETECT=`uname`
|
||||
if [ "X${OSDETECT}" = "XNetBSD" ]; then
|
||||
if [ "${OSDETECT}" = "NetBSD" ]; then
|
||||
OSENUM=MANDOC_OS_NETBSD
|
||||
elif [ "X${OSDETECT}" = "XOpenBSD" ]; then
|
||||
elif [ "${OSDETECT}" = "OpenBSD" ]; then
|
||||
OSENUM=MANDOC_OS_OPENBSD
|
||||
else
|
||||
OSENUM=MANDOC_OS_OTHER
|
||||
|
@ -250,8 +265,8 @@ if [ -n "${CFLAGS}" ]; then
|
|||
else
|
||||
COMP="${CC} ${DEFCFLAGS} -Wno-unused -Werror"
|
||||
fi
|
||||
echo -n "tested ${CC} -W: " 1>&2
|
||||
echo -n "testing ${CC} -W: " 1>&3
|
||||
printf "%s" "tested ${CC} -W: " 1>&2
|
||||
printf "%s" "testing ${CC} -W: " 1>&3
|
||||
runtest noop WFLAG || true
|
||||
|
||||
if [ -n "${CFLAGS}" ]; then
|
||||
|
@ -283,51 +298,48 @@ fi
|
|||
# --- tests for config.h ----------------------------------------------
|
||||
|
||||
# --- library functions ---
|
||||
runtest attribute ATTRIBUTE || true
|
||||
runtest cmsg CMSG "" "-D_XPG4_2" || true
|
||||
runtest dirent-namlen DIRENT_NAMLEN || true
|
||||
runtest be32toh ENDIAN || true
|
||||
runtest be32toh SYS_ENDIAN -DSYS_ENDIAN || true
|
||||
runtest EFTYPE EFTYPE || true
|
||||
runtest err ERR || true
|
||||
runtest getline GETLINE || true
|
||||
singletest getsubopt GETSUBOPT || \
|
||||
runtest getsubopt GETSUBOPT -D_GNU_SOURCE || true
|
||||
runtest getsubopt GETSUBOPT "" -D_GNU_SOURCE || true
|
||||
runtest isblank ISBLANK || true
|
||||
runtest mkdtemp MKDTEMP || true
|
||||
runtest mkstemps MKSTEMPS || true
|
||||
runtest nanosleep NANOSLEEP "${LD_NANOSLEEP}" "-lrt" || true
|
||||
runtest ntohl NTOHL || true
|
||||
runtest O_DIRECTORY O_DIRECTORY || true
|
||||
runtest PATH_MAX PATH_MAX || true
|
||||
runtest pledge PLEDGE || true
|
||||
runtest sandbox_init SANDBOX_INIT || true
|
||||
runtest progname PROGNAME || true
|
||||
singletest reallocarray REALLOCARRAY || \
|
||||
runtest reallocarray REALLOCARRAY -D_OPENBSD_SOURCE || true
|
||||
singletest recallocarray RECALLOCARRAY || \
|
||||
runtest recallocarray RECALLOCARRAY -D_OPENBSD_SOURCE || true
|
||||
runtest reallocarray REALLOCARRAY "" -D_OPENBSD_SOURCE || true
|
||||
runtest recallocarray RECALLOCARRAY "" -D_OPENBSD_SOURCE || true
|
||||
runtest recvmsg RECVMSG "${LD_RECVMSG}" "-lsocket" || true
|
||||
runtest rewb-bsd REWB_BSD || true
|
||||
runtest rewb-sysv REWB_SYSV || true
|
||||
singletest strcasestr STRCASESTR || \
|
||||
runtest strcasestr STRCASESTR -D_GNU_SOURCE || true
|
||||
runtest strcasestr STRCASESTR "" -D_GNU_SOURCE || true
|
||||
runtest stringlist STRINGLIST || true
|
||||
runtest strlcat STRLCAT || true
|
||||
runtest strlcpy STRLCPY || true
|
||||
runtest strndup STRNDUP || true
|
||||
singletest strptime STRPTIME || \
|
||||
runtest strptime STRPTIME -D_GNU_SOURCE || true
|
||||
runtest strptime STRPTIME "" -D_GNU_SOURCE || true
|
||||
runtest strsep STRSEP || true
|
||||
singletest strtonum STRTONUM || \
|
||||
runtest strtonum STRTONUM -D_OPENBSD_SOURCE || true
|
||||
singletest vasprintf VASPRINTF || \
|
||||
runtest vasprintf VASPRINTF -D_GNU_SOURCE || true
|
||||
runtest strtonum STRTONUM "" -D_OPENBSD_SOURCE || true
|
||||
runtest vasprintf VASPRINTF "" -D_GNU_SOURCE || true
|
||||
|
||||
if [ ${HAVE_ENDIAN} -eq 0 -a \
|
||||
${HAVE_SYS_ENDIAN} -eq 0 -a \
|
||||
${HAVE_NTOHL} -eq 0 ]; then
|
||||
echo "FATAL: no endian conversion functions found" 1>&2
|
||||
echo "FATAL: no endian conversion functions found" 1>&3
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ismanual fts FTS ${HAVE_FTS}; then
|
||||
# --- fts ---
|
||||
if [ "${1}" = "-depend" ]; then
|
||||
HAVE_FTS=0
|
||||
HAVE_FTS_COMPARE_CONST=0
|
||||
echo "tested fts: HAVE_FTS=0 (for make depend)" 1>&2
|
||||
echo "tested fts: HAVE_FTS=0 (for make depend)" 1>&3
|
||||
echo 1>&3
|
||||
elif ismanual fts FTS ${HAVE_FTS}; then
|
||||
HAVE_FTS_COMPARE_CONST=0
|
||||
elif runtest fts FTS_COMPARE_CONST -DFTS_COMPARE_CONST; then
|
||||
HAVE_FTS=1
|
||||
|
@ -335,25 +347,41 @@ else
|
|||
runtest fts FTS || true
|
||||
fi
|
||||
|
||||
if ismanual "less -T" LESS_T ${HAVE_LESS_T}; then
|
||||
# --- pager ---
|
||||
manual=
|
||||
if [ -n "${BINM_PAGER}" ]; then
|
||||
manual=" (manual)"
|
||||
elif less test-noop.c 1>/dev/null 2>&3; then
|
||||
BINM_PAGER=less
|
||||
echo "tested less: yes" 1>&2
|
||||
echo "tested less: yes" 1>&3
|
||||
else
|
||||
BINM_PAGER=more
|
||||
echo "tested less: no" 1>&2
|
||||
echo "tested less: no" 1>&3
|
||||
fi
|
||||
echo "selected BINM_PAGER=${BINM_PAGER}${manual}" 1>&2
|
||||
echo "selected BINM_PAGER=${BINM_PAGER}${manual}" 1>&3
|
||||
|
||||
# --- tagging support in the pager ---
|
||||
if ismanual "${BINM_PAGER} -T" LESS_T ${HAVE_LESS_T}; then
|
||||
:
|
||||
elif less -ET /dev/null test-noop.c 1>/dev/null 2>&3; then
|
||||
elif ${BINM_PAGER} -T /dev/null test-noop.c 1>/dev/null 2>&3; then
|
||||
HAVE_LESS_T=1
|
||||
echo "tested less -T: yes" 1>&2
|
||||
echo "tested less -T: yes" 1>&3
|
||||
echo "tested ${BINM_PAGER} -T: yes" 1>&2
|
||||
echo "tested ${BINM_PAGER} -T: yes" 1>&3
|
||||
echo 1>&3
|
||||
else
|
||||
HAVE_LESS_T=0
|
||||
echo "tested less -T: no" 1>&2
|
||||
echo "tested less -T: no" 1>&3
|
||||
echo "tested ${BINM_PAGER} -T: no" 1>&2
|
||||
echo "tested ${BINM_PAGER} -T: no" 1>&3
|
||||
echo 1>&3
|
||||
fi
|
||||
|
||||
# --- wide character and locale support ---
|
||||
if get_locale; then
|
||||
singletest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || \
|
||||
runtest wchar WCHAR -D_GNU_SOURCE \
|
||||
-DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true
|
||||
runtest wchar WCHAR "-DUTF8_LOCALE=\"${UTF8_LOCALE}\"" \
|
||||
"-D_GNU_SOURCE -DUTF8_LOCALE=\"${UTF8_LOCALE}\"" || true
|
||||
else
|
||||
HAVE_WCHAR=0
|
||||
echo "tested wchar: no (no UTF8_LOCALE)" 1>&2
|
||||
|
@ -361,64 +389,46 @@ else
|
|||
echo 1>&3
|
||||
fi
|
||||
|
||||
# --- nanosleep ---
|
||||
if [ -n "${LD_NANOSLEEP}" ]; then
|
||||
runtest nanosleep NANOSLEEP "${LD_NANOSLEEP}" || true
|
||||
elif singletest nanosleep NANOSLEEP; then
|
||||
:
|
||||
elif runtest nanosleep NANOSLEEP "-lrt"; then
|
||||
LD_NANOSLEEP="-lrt"
|
||||
fi
|
||||
if [ "${HAVE_NANOSLEEP}" -eq 0 ]; then
|
||||
echo "FATAL: nanosleep: no" 1>&2
|
||||
echo "FATAL: nanosleep: no" 1>&3
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${BUILD_CATMAN} -gt 0 ]; then
|
||||
# --- recvmsg ---
|
||||
if [ -n "${LD_RECVMSG}" ]; then
|
||||
runtest recvmsg RECVMSG "${LD_RECVMSG}" || true
|
||||
elif singletest recvmsg RECVMSG; then
|
||||
:
|
||||
elif runtest recvmsg RECVMSG "-lsocket"; then
|
||||
LD_RECVMSG="-lsocket"
|
||||
fi
|
||||
if [ "${HAVE_RECVMSG}" -eq 0 ]; then
|
||||
echo "FATAL: recvmsg: no" 1>&2
|
||||
echo "FATAL: recvmsg: no" 1>&3
|
||||
echo "Without recvmsg(2), you cannot BUILD_CATMAN." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- cmsg ---
|
||||
if singletest cmsg CMSG; then
|
||||
:
|
||||
elif runtest cmsg CMSG "-D_XPG4_2"; then
|
||||
HAVE_CMSG_XPG42=1
|
||||
fi
|
||||
if [ "${HAVE_CMSG}" -eq 0 ]; then
|
||||
echo "FATAL: cmsg: no" 1>&2
|
||||
echo "FATAL: cmsg: no" 1>&3
|
||||
echo "Without CMSG_FIRSTHDR(3), you cannot BUILD_CATMAN." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- ohash ---
|
||||
if ismanual ohash OHASH "${HAVE_OHASH}"; then
|
||||
:
|
||||
elif [ -n "${LD_OHASH}" ]; then
|
||||
runtest ohash OHASH "${LD_OHASH}" || true
|
||||
elif singletest ohash OHASH; then
|
||||
:
|
||||
elif runtest ohash OHASH "-lutil"; then
|
||||
LD_OHASH="-lutil"
|
||||
if [ "${1}" = "-depend" ]; then
|
||||
HAVE_OHASH=0
|
||||
echo "tested ohash: HAVE_OHASH=0 (for make depend)" 1>&2
|
||||
echo "tested ohash: HAVE_OHASH=0 (for make depend)" 1>&3
|
||||
echo 1>&3
|
||||
else
|
||||
runtest ohash OHASH "${LD_OHASH}" "-lutil" || true
|
||||
fi
|
||||
if [ "${HAVE_OHASH}" -eq 0 ]; then
|
||||
LD_OHASH=
|
||||
fi
|
||||
|
||||
# --- required functions ---
|
||||
if [ ${HAVE_ENDIAN} -eq 0 -a \
|
||||
${HAVE_SYS_ENDIAN} -eq 0 -a \
|
||||
${HAVE_NTOHL} -eq 0 ]; then
|
||||
echo "FATAL: no endian conversion functions found" 1>&2
|
||||
echo "FATAL: no endian conversion functions found" 1>&3
|
||||
FATAL=1
|
||||
fi
|
||||
if [ "${HAVE_NANOSLEEP}" -eq 0 ]; then
|
||||
echo "FATAL: nanosleep: no" 1>&2
|
||||
echo "FATAL: nanosleep: no" 1>&3
|
||||
FATAL=1
|
||||
fi
|
||||
if [ ${BUILD_CATMAN} -gt 0 -a "${HAVE_RECVMSG}" -eq 0 ]; then
|
||||
echo "FATAL: recvmsg: no" 1>&2
|
||||
echo "FATAL: recvmsg: no" 1>&3
|
||||
echo "Without recvmsg(2), you cannot BUILD_CATMAN." 1>&2
|
||||
FATAL=1
|
||||
fi
|
||||
if [ ${BUILD_CATMAN} -gt 0 -a "${HAVE_CMSG}" -eq 0 ]; then
|
||||
echo "FATAL: cmsg: no" 1>&2
|
||||
echo "FATAL: cmsg: no" 1>&3
|
||||
echo "Without CMSG_FIRSTHDR(3), you cannot BUILD_CATMAN." 1>&2
|
||||
FATAL=1
|
||||
fi
|
||||
[ "${FATAL}" -eq 0 ] || exit 1
|
||||
|
||||
# --- LDADD ---
|
||||
LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_RECVMSG} ${LD_OHASH} -lz"
|
||||
echo "selected LDADD=\"${LDADD}\"" 1>&2
|
||||
|
@ -434,10 +444,6 @@ cat << __HEREDOC__
|
|||
#error "Do not use C++. See the INSTALL file."
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 4)
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
__HEREDOC__
|
||||
|
||||
[ ${NEED_GNU_SOURCE} -eq 0 ] || echo "#define _GNU_SOURCE"
|
||||
|
@ -458,7 +464,9 @@ echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
|
|||
echo "#define OSENUM ${OSENUM}"
|
||||
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
|
||||
[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\""
|
||||
[ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\""
|
||||
[ -n "${READ_ALLOWED_PATH}" ] \
|
||||
&& echo "#define READ_ALLOWED_PATH \"${READ_ALLOWED_PATH}\""
|
||||
[ ${HAVE_ATTRIBUTE} -eq 0 ] && echo "#define __attribute__(x)"
|
||||
[ ${HAVE_EFTYPE} -eq 0 ] && echo "#define EFTYPE EINVAL"
|
||||
[ ${HAVE_O_DIRECTORY} -eq 0 ] && echo "#define O_DIRECTORY 0"
|
||||
[ ${HAVE_PATH_MAX} -eq 0 ] && echo "#define PATH_MAX 4096"
|
||||
|
@ -466,9 +474,8 @@ if [ ${HAVE_ENDIAN} -eq 0 -a ${HAVE_SYS_ENDIAN} -eq 0 ]; then
|
|||
echo "#define be32toh ntohl"
|
||||
echo "#define htobe32 htonl"
|
||||
fi
|
||||
|
||||
cat << __HEREDOC__
|
||||
#define HAVE_CMSG_XPG42 ${HAVE_CMSG_XPG42}
|
||||
|
||||
#define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN}
|
||||
#define HAVE_ENDIAN ${HAVE_ENDIAN}
|
||||
#define HAVE_ERR ${HAVE_ERR}
|
||||
|
@ -479,6 +486,7 @@ cat << __HEREDOC__
|
|||
#define HAVE_ISBLANK ${HAVE_ISBLANK}
|
||||
#define HAVE_LESS_T ${HAVE_LESS_T}
|
||||
#define HAVE_MKDTEMP ${HAVE_MKDTEMP}
|
||||
#define HAVE_MKSTEMPS ${HAVE_MKSTEMPS}
|
||||
#define HAVE_NTOHL ${HAVE_NTOHL}
|
||||
#define HAVE_PLEDGE ${HAVE_PLEDGE}
|
||||
#define HAVE_PROGNAME ${HAVE_PROGNAME}
|
||||
|
@ -499,6 +507,7 @@ cat << __HEREDOC__
|
|||
#define HAVE_VASPRINTF ${HAVE_VASPRINTF}
|
||||
#define HAVE_WCHAR ${HAVE_WCHAR}
|
||||
#define HAVE_OHASH ${HAVE_OHASH}
|
||||
#define NEED_XPG4_2 ${NEED_XPG4_2}
|
||||
|
||||
#define BINM_APROPOS "${BINM_APROPOS}"
|
||||
#define BINM_CATMAN "${BINM_CATMAN}"
|
||||
|
@ -506,6 +515,7 @@ cat << __HEREDOC__
|
|||
#define BINM_MAN "${BINM_MAN}"
|
||||
#define BINM_SOELIM "${BINM_SOELIM}"
|
||||
#define BINM_WHATIS "${BINM_WHATIS}"
|
||||
#define BINM_PAGER "${BINM_PAGER}"
|
||||
|
||||
__HEREDOC__
|
||||
|
||||
|
@ -514,52 +524,82 @@ if [ ${HAVE_ERR} -eq 0 ]; then
|
|||
echo "extern void errx(int, const char *, ...);"
|
||||
echo "extern void warn(const char *, ...);"
|
||||
echo "extern void warnx(const char *, ...);"
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_err.o"
|
||||
SOELIM_COBJS="${SOELIM_COBJS} compat_err.o"
|
||||
fi
|
||||
|
||||
[ ${HAVE_GETLINE} -eq 0 ] && \
|
||||
if [ ${HAVE_FTS} -eq 0 ]; then
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_fts.o"
|
||||
fi
|
||||
if [ ${HAVE_GETLINE} -eq 0 ]; then
|
||||
echo "extern ssize_t getline(char **, size_t *, FILE *);"
|
||||
|
||||
[ ${HAVE_GETSUBOPT} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_getline.o"
|
||||
SOELIM_COBJS="${SOELIM_COBJS} compat_getline.o"
|
||||
fi
|
||||
if [ ${HAVE_GETSUBOPT} -eq 0 ]; then
|
||||
echo "extern int getsubopt(char **, char * const *, char **);"
|
||||
|
||||
[ ${HAVE_ISBLANK} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_getsubopt.o"
|
||||
fi
|
||||
if [ ${HAVE_ISBLANK} -eq 0 ]; then
|
||||
echo "extern int isblank(int);"
|
||||
|
||||
[ ${HAVE_MKDTEMP} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_isblank.o"
|
||||
fi
|
||||
if [ ${HAVE_MKDTEMP} -eq 0 ]; then
|
||||
echo "extern char *mkdtemp(char *);"
|
||||
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_mkdtemp.o"
|
||||
fi
|
||||
if [ ${HAVE_MKSTEMPS} -eq 0 ]; then
|
||||
echo "extern int mkstemps(char *, int);"
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_mkstemps.o"
|
||||
fi
|
||||
if [ ${HAVE_OHASH} -eq 0 ]; then
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_ohash.o"
|
||||
fi
|
||||
if [ ${HAVE_PROGNAME} -eq 0 ]; then
|
||||
echo "extern const char *getprogname(void);"
|
||||
echo "extern void setprogname(const char *);"
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_progname.o"
|
||||
SOELIM_COBJS="${SOELIM_COBJS} compat_progname.o"
|
||||
fi
|
||||
|
||||
[ ${HAVE_REALLOCARRAY} -eq 0 ] && \
|
||||
if [ ${HAVE_REALLOCARRAY} -eq 0 ]; then
|
||||
echo "extern void *reallocarray(void *, size_t, size_t);"
|
||||
|
||||
[ ${HAVE_RECALLOCARRAY} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_reallocarray.o"
|
||||
SOELIM_COBJS="${SOELIM_COBJS} compat_reallocarray.o"
|
||||
fi
|
||||
if [ ${HAVE_RECALLOCARRAY} -eq 0 ]; then
|
||||
echo "extern void *recallocarray(void *, size_t, size_t, size_t);"
|
||||
|
||||
[ ${HAVE_STRCASESTR} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_recallocarray.o"
|
||||
fi
|
||||
if [ ${HAVE_STRCASESTR} -eq 0 ]; then
|
||||
echo "extern char *strcasestr(const char *, const char *);"
|
||||
|
||||
[ ${HAVE_STRLCAT} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_strcasestr.o"
|
||||
fi
|
||||
if [ ${HAVE_STRINGLIST} -eq 0 ]; then
|
||||
SOELIM_COBJS="${SOELIM_COBJS} compat_stringlist.o"
|
||||
fi
|
||||
if [ ${HAVE_STRLCAT} -eq 0 ]; then
|
||||
echo "extern size_t strlcat(char *, const char *, size_t);"
|
||||
|
||||
[ ${HAVE_STRLCPY} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_strlcat.o"
|
||||
fi
|
||||
if [ ${HAVE_STRLCPY} -eq 0 ]; then
|
||||
echo "extern size_t strlcpy(char *, const char *, size_t);"
|
||||
|
||||
[ ${HAVE_STRNDUP} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_strlcpy.o"
|
||||
fi
|
||||
if [ ${HAVE_STRNDUP} -eq 0 ]; then
|
||||
echo "extern char *strndup(const char *, size_t);"
|
||||
|
||||
[ ${HAVE_STRSEP} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_strndup.o"
|
||||
fi
|
||||
if [ ${HAVE_STRSEP} -eq 0 ]; then
|
||||
echo "extern char *strsep(char **, const char *);"
|
||||
|
||||
[ ${HAVE_STRTONUM} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_strsep.o"
|
||||
fi
|
||||
if [ ${HAVE_STRTONUM} -eq 0 ]; then
|
||||
echo "extern long long strtonum(const char *, long long, long long, const char **);"
|
||||
|
||||
[ ${HAVE_VASPRINTF} -eq 0 ] && \
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_strtonum.o"
|
||||
fi
|
||||
if [ ${HAVE_VASPRINTF} -eq 0 ]; then
|
||||
echo "extern int vasprintf(char **, const char *, va_list);"
|
||||
|
||||
MANDOC_COBJS="${MANDOC_COBJS} compat_vasprintf.o"
|
||||
fi
|
||||
echo "file config.h: written" 1>&2
|
||||
echo "file config.h: written" 1>&3
|
||||
|
||||
|
@ -595,10 +635,13 @@ INSTALL_TARGETS=
|
|||
cat << __HEREDOC__
|
||||
BUILD_TARGETS = ${BUILD_TARGETS}
|
||||
INSTALL_TARGETS = ${INSTALL_TARGETS}
|
||||
AR = ${AR}
|
||||
CC = ${CC}
|
||||
CFLAGS = ${CFLAGS}
|
||||
LDADD = ${LDADD}
|
||||
LDFLAGS = ${LDFLAGS}
|
||||
MANDOC_COBJS = ${MANDOC_COBJS}
|
||||
SOELIM_COBJS = ${SOELIM_COBJS}
|
||||
STATIC = ${STATIC}
|
||||
PREFIX = ${PREFIX}
|
||||
BINDIR = ${BINDIR}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# $Id: configure.local.example,v 1.36 2019/03/06 10:18:58 schwarze Exp $
|
||||
# $Id: configure.local.example,v 1.43 2021/09/20 13:25:42 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2014-2021 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
|
||||
|
@ -28,6 +28,19 @@
|
|||
|
||||
# --- user settings relevant for all builds ----------------------------
|
||||
|
||||
# By default, "cc" is used as the C compiler, but it can be overridden.
|
||||
# For example, the system compiler in SunOS 5.9 may not provide <stdint.h>,
|
||||
# which may require this line:
|
||||
CC=gcc
|
||||
|
||||
# IBM AIX may need:
|
||||
CC=xlc
|
||||
|
||||
# By default, "ar" is used as the library archive builder, but it
|
||||
# can be overridden. For example, NixOS may not have ar(1) in the
|
||||
# PATH, but may want to specify an absolute path instead.
|
||||
AR=ar
|
||||
|
||||
# For -Tutf8 and -Tlocale operation, mandoc(1) requires <locale.h>
|
||||
# providing setlocale(3) and <wchar.h> providing wcwidth(3) and
|
||||
# putwchar(3) with a wchar_t storing UCS-4 values. Theoretically,
|
||||
|
@ -88,7 +101,7 @@ OSENUM=MANDOC_OS_OTHER
|
|||
# If you do not want uname(3) to be called but instead want a fixed
|
||||
# string to be used, use the following line:
|
||||
|
||||
OSNAME="OpenBSD 6.5"
|
||||
OSNAME="OpenBSD 7.0"
|
||||
|
||||
# The following installation directories are used.
|
||||
# It is possible to set only one or a few of these variables,
|
||||
|
@ -143,6 +156,14 @@ BINM_WHATIS=mwhatis # default is "whatis"
|
|||
BINM_MAKEWHATIS=mandocdb # default is "makewhatis"
|
||||
BINM_SOELIM=msoelim # default is "soelim"
|
||||
|
||||
# If less(1) is available, it is used as the default manual pager.
|
||||
# Otherwise, more(1) is used: its existence is required by POSIX.
|
||||
# It is possible to force using a different default pager, either
|
||||
# by giving the name of a program found in the PATH, or by giving
|
||||
# an absolute path.
|
||||
|
||||
BINM_PAGER=pg # default is "less" or "more"
|
||||
|
||||
# Some distributions do not want hardlinks
|
||||
# between installed binary programs.
|
||||
# Set the following variable to use symbolic links instead.
|
||||
|
@ -193,14 +214,28 @@ INSTALL_LIB="${INSTALL} -m 0444"
|
|||
INSTALL_MAN="${INSTALL} -m 0444"
|
||||
INSTALL_DATA="${INSTALL} -m 0444"
|
||||
|
||||
# When using the "homebrew" package manager on Mac OS X, the actual
|
||||
# manuals are located in a so-called "cellar" and only symlinked
|
||||
# into the manual trees. To allow mandoc to follow such symlinks,
|
||||
# you have to specify the physical location of the cellar as returned
|
||||
# by realpath(3), for example:
|
||||
# By default, makewhatis(8) can only read from the paths passed on the
|
||||
# command line or configured in man.conf(5).
|
||||
# But some package managers on some operating systems store manual pages
|
||||
# in separate "cellar" or "store" directories and only symlink them
|
||||
# into the manual trees.
|
||||
# To support one or more such package managers, give makewhatis(8)
|
||||
# read access to the cellars and stores on your system, in the form
|
||||
# of a colon-separated path:
|
||||
|
||||
# Homebrow package manager on Mac OS X:
|
||||
PREFIX="/usr/local"
|
||||
HOMEBREWDIR="${PREFIX}/Cellar"
|
||||
READ_ALLOWED_PATH="${PREFIX}/Cellar"
|
||||
|
||||
# Nix package manager and/or NixOS Linux distribution:
|
||||
READ_ALLOWED_PATH="/nix/store"
|
||||
|
||||
# GNU Guix package manager and/or GNU Guix Linux distribution:
|
||||
READ_ALLOWED_PATH="/gnu/store"
|
||||
|
||||
# If multiple package managers are used concurrently:
|
||||
PREFIX="/usr/local"
|
||||
READ_ALLOWED_PATH="/nix/store:${PREFIX}/Cellar"
|
||||
|
||||
# --- user settings for the mandoc(3) library --------------------------
|
||||
|
||||
|
@ -256,6 +291,8 @@ CGIBINDIR="${WWWPREFIX}/cgi-bin"
|
|||
# To enable it, use the following line.
|
||||
# It does not work on SunOS 5.10 because there is no mkdirat(2)
|
||||
# nor on SunOS 5.9 which also lacks CMSG_LEN(3) and CMSG_SPACE(3).
|
||||
# It may not work on old releases of Mac OS X either. For example,
|
||||
# Mac OS X 10.4 Tiger provides neither mkdirat(2) nor openat(2).
|
||||
|
||||
BUILD_CATMAN=1
|
||||
|
||||
|
@ -268,21 +305,6 @@ BINM_CATMAN=mcatman # default is "catman"
|
|||
|
||||
# Do not set these variables unless you really need to.
|
||||
|
||||
# You can manually override the compiler to be used.
|
||||
# But that's rarely useful because ./configure asks your make(1)
|
||||
# which compiler to use, and that answer will hardly be wrong.
|
||||
|
||||
CC=cc
|
||||
|
||||
# Because the system compiler may not provide <stdint.h>,
|
||||
# SunOS 5.9 may need:
|
||||
|
||||
CC=gcc
|
||||
|
||||
# IBM AIX may need:
|
||||
|
||||
CC=xlc
|
||||
|
||||
# Normally, leave CFLAGS unset. In that case, -g will automatically
|
||||
# be used, and various -W options will be added if the compiler
|
||||
# supports them. If you define CFLAGS manually, it will be used
|
||||
|
@ -295,6 +317,7 @@ CFLAGS="-g"
|
|||
# and will be regarded as failed) or 1 (test will not be run and will
|
||||
# be regarded as successful).
|
||||
|
||||
HAVE_ATTRIBUTE=0
|
||||
HAVE_DIRENT_NAMLEN=0
|
||||
HAVE_ENDIAN=0
|
||||
HAVE_EFTYPE=0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dba_array.c,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/* $Id: dba_array.c,v 1.2 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -17,6 +17,8 @@
|
|||
* Allocation-based arrays for the mandoc database, for read-write access.
|
||||
* The interface is defined in "dba_array.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dba_read.c,v 1.4 2016/08/17 20:46:56 schwarze Exp $ */
|
||||
/* $Id: dba_read.c,v 1.5 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -19,6 +19,8 @@
|
|||
* The interface is defined in "dba.h".
|
||||
* This file is seperate from dba.c because this also uses "dbm.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <regex.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
55
eqn.7
55
eqn.7
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: eqn.7,v 1.38 2019/04/23 17:57:49 schwarze Exp $
|
||||
.\" $Id: eqn.7,v 1.39 2020/01/10 11:55:04 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: April 23 2019 $
|
||||
.Dd $Mdocdate: January 10 2020 $
|
||||
.Dt EQN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -44,28 +44,16 @@ specification (see
|
|||
.Sx SEE ALSO
|
||||
for references).
|
||||
.Pp
|
||||
Equations within
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
documents are enclosed by the standalone
|
||||
.Sq \&.EQ
|
||||
and
|
||||
.Sq \&.EN
|
||||
tags.
|
||||
Equations are multi-line blocks consisting of formulas and control
|
||||
statements.
|
||||
.Sh EQUATION STRUCTURE
|
||||
Each equation is bracketed by
|
||||
.Sq \&.EQ
|
||||
and
|
||||
.Sq \&.EN
|
||||
strings.
|
||||
.Em Note :
|
||||
these are not the same as
|
||||
.Xr roff 7
|
||||
macros, and may only be invoked as
|
||||
.Sq \&.EQ .
|
||||
An equation starts with an input line containing exactly the characters
|
||||
.Sq \&.EQ ,
|
||||
may contain multiple input lines, and ends with an input line
|
||||
containing exactly the characters
|
||||
.Sq \&.EN .
|
||||
Equivalently, an equation can be given in the middle of a single
|
||||
text input line by surrounding it with the equation delimiters
|
||||
defined with the
|
||||
.Cm delim
|
||||
statement.
|
||||
.Pp
|
||||
The equation grammar is as follows, where quoted strings are
|
||||
case-sensitive literals in the input:
|
||||
|
@ -178,6 +166,25 @@ statement is a synonym for
|
|||
while
|
||||
.Cm tdefine
|
||||
is discarded.
|
||||
.It Cm delim
|
||||
This statement takes a string argument consisting of two bytes,
|
||||
to be used as the opening and closing delimiters for equations
|
||||
in the middle of text input lines.
|
||||
Conventionally, the dollar sign is used for both delimiters,
|
||||
as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.EQ
|
||||
delim $$
|
||||
\&.EN
|
||||
An equation like $sin pi = 0$ can now be entered
|
||||
in the middle of a text input line.
|
||||
.Ed
|
||||
.Pp
|
||||
The special statement
|
||||
.Cm delim off
|
||||
temporarily disables previously declared delimiters and
|
||||
.Cm delim on
|
||||
reenables them.
|
||||
.It Cm gfont
|
||||
Set the default font of subsequent output.
|
||||
Its syntax is as follows:
|
||||
|
|
14
eqn.c
14
eqn.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: eqn.c,v 1.83 2018/12/14 06:33:14 schwarze Exp $ */
|
||||
/* $Id: eqn.c,v 1.84 2020/01/08 12:16:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014,2015,2017,2018,2020 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
|
||||
|
@ -399,6 +399,14 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
|||
case '"':
|
||||
quoted = 1;
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '~':
|
||||
case '^':
|
||||
if (quoted)
|
||||
break;
|
||||
ep->start++;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -669,7 +677,7 @@ eqn_parse(struct eqn_node *ep)
|
|||
if (ep->data == NULL)
|
||||
return;
|
||||
|
||||
ep->start = ep->end = ep->data + strspn(ep->data, " ^~");
|
||||
ep->start = ep->end = ep->data;
|
||||
|
||||
next_tok:
|
||||
tok = eqn_next(ep, MODE_TOK);
|
||||
|
|
337
html.c
337
html.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: html.c,v 1.255 2019/04/30 15:53:00 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.275 2021/09/09 14:47:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2015, 2017-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,9 @@
|
|||
* 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.
|
||||
*
|
||||
* Common functions for mandoc(1) HTML formatters.
|
||||
* For use by individual formatters and by the main program.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -42,34 +45,30 @@
|
|||
struct htmldata {
|
||||
const char *name;
|
||||
int flags;
|
||||
#define HTML_NOSTACK (1 << 0)
|
||||
#define HTML_AUTOCLOSE (1 << 1)
|
||||
#define HTML_NLBEFORE (1 << 2)
|
||||
#define HTML_NLBEGIN (1 << 3)
|
||||
#define HTML_NLEND (1 << 4)
|
||||
#define HTML_NLAFTER (1 << 5)
|
||||
#define HTML_INPHRASE (1 << 0) /* Can appear in phrasing context. */
|
||||
#define HTML_TOPHRASE (1 << 1) /* Establishes phrasing context. */
|
||||
#define HTML_NOSTACK (1 << 2) /* Does not have an end tag. */
|
||||
#define HTML_NLBEFORE (1 << 3) /* Output line break before opening. */
|
||||
#define HTML_NLBEGIN (1 << 4) /* Output line break after opening. */
|
||||
#define HTML_NLEND (1 << 5) /* Output line break before closing. */
|
||||
#define HTML_NLAFTER (1 << 6) /* Output line break after closing. */
|
||||
#define HTML_NLAROUND (HTML_NLBEFORE | HTML_NLAFTER)
|
||||
#define HTML_NLINSIDE (HTML_NLBEGIN | HTML_NLEND)
|
||||
#define HTML_NLALL (HTML_NLAROUND | HTML_NLINSIDE)
|
||||
#define HTML_INDENT (1 << 6)
|
||||
#define HTML_NOINDENT (1 << 7)
|
||||
#define HTML_INDENT (1 << 7) /* Indent content by two spaces. */
|
||||
#define HTML_NOINDENT (1 << 8) /* Exception: never indent content. */
|
||||
};
|
||||
|
||||
static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"html", HTML_NLALL},
|
||||
{"head", HTML_NLALL | HTML_INDENT},
|
||||
{"body", HTML_NLALL},
|
||||
{"meta", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"meta", HTML_NOSTACK | HTML_NLALL},
|
||||
{"link", HTML_NOSTACK | HTML_NLALL},
|
||||
{"style", HTML_NLALL | HTML_INDENT},
|
||||
{"title", HTML_NLAROUND},
|
||||
{"body", HTML_NLALL},
|
||||
{"div", HTML_NLAROUND},
|
||||
{"div", 0},
|
||||
{"section", HTML_NLALL},
|
||||
{"h1", HTML_NLAROUND},
|
||||
{"h2", HTML_NLAROUND},
|
||||
{"span", 0},
|
||||
{"link", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"br", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
|
||||
{"a", 0},
|
||||
{"table", HTML_NLALL | HTML_INDENT},
|
||||
{"tr", HTML_NLALL | HTML_INDENT},
|
||||
{"td", HTML_NLAROUND},
|
||||
|
@ -79,16 +78,22 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
|||
{"dl", HTML_NLALL | HTML_INDENT},
|
||||
{"dt", HTML_NLAROUND},
|
||||
{"dd", HTML_NLAROUND | HTML_INDENT},
|
||||
{"p", HTML_NLAROUND | HTML_INDENT},
|
||||
{"pre", HTML_NLALL | HTML_NOINDENT},
|
||||
{"var", 0},
|
||||
{"cite", 0},
|
||||
{"b", 0},
|
||||
{"i", 0},
|
||||
{"code", 0},
|
||||
{"small", 0},
|
||||
{"style", HTML_NLALL | HTML_INDENT},
|
||||
{"math", HTML_NLALL | HTML_INDENT},
|
||||
{"h1", HTML_TOPHRASE | HTML_NLAROUND},
|
||||
{"h2", HTML_TOPHRASE | HTML_NLAROUND},
|
||||
{"p", HTML_TOPHRASE | HTML_NLAROUND | HTML_INDENT},
|
||||
{"pre", HTML_TOPHRASE | HTML_NLAROUND | HTML_NOINDENT},
|
||||
{"a", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"b", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"cite", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"code", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"i", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"small", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"span", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"var", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
{"br", HTML_INPHRASE | HTML_NOSTACK | HTML_NLALL},
|
||||
{"hr", HTML_INPHRASE | HTML_NOSTACK},
|
||||
{"mark", HTML_INPHRASE },
|
||||
{"math", HTML_INPHRASE | HTML_NLALL | HTML_INDENT},
|
||||
{"mrow", 0},
|
||||
{"mi", 0},
|
||||
{"mn", 0},
|
||||
|
@ -108,6 +113,11 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
|||
};
|
||||
|
||||
/* Avoid duplicate HTML id= attributes. */
|
||||
|
||||
struct id_entry {
|
||||
int ord; /* Ordinal number of the latest occurrence. */
|
||||
char id[]; /* The id= attribute without any ordinal suffix. */
|
||||
};
|
||||
static struct ohash id_unique;
|
||||
|
||||
static void html_reset_internal(struct html *);
|
||||
|
@ -131,6 +141,7 @@ html_alloc(const struct manoutput *outopts)
|
|||
h = mandoc_calloc(1, sizeof(struct html));
|
||||
|
||||
h->tag = NULL;
|
||||
h->metac = h->metal = ESCAPE_FONTROMAN;
|
||||
h->style = outopts->style;
|
||||
if ((h->base_man1 = outopts->man) == NULL)
|
||||
h->base_man2 = NULL;
|
||||
|
@ -142,7 +153,7 @@ html_alloc(const struct manoutput *outopts)
|
|||
if (outopts->toc)
|
||||
h->oflags |= HTML_TOC;
|
||||
|
||||
mandoc_ohash_init(&id_unique, 4, 0);
|
||||
mandoc_ohash_init(&id_unique, 4, offsetof(struct id_entry, id));
|
||||
|
||||
return h;
|
||||
}
|
||||
|
@ -151,17 +162,17 @@ static void
|
|||
html_reset_internal(struct html *h)
|
||||
{
|
||||
struct tag *tag;
|
||||
char *cp;
|
||||
struct id_entry *entry;
|
||||
unsigned int slot;
|
||||
|
||||
while ((tag = h->tag) != NULL) {
|
||||
h->tag = tag->next;
|
||||
free(tag);
|
||||
}
|
||||
cp = ohash_first(&id_unique, &slot);
|
||||
while (cp != NULL) {
|
||||
free(cp);
|
||||
cp = ohash_next(&id_unique, &slot);
|
||||
entry = ohash_first(&id_unique, &slot);
|
||||
while (entry != NULL) {
|
||||
free(entry);
|
||||
entry = ohash_next(&id_unique, &slot);
|
||||
}
|
||||
ohash_delete(&id_unique);
|
||||
}
|
||||
|
@ -170,7 +181,7 @@ void
|
|||
html_reset(void *p)
|
||||
{
|
||||
html_reset_internal(p);
|
||||
mandoc_ohash_init(&id_unique, 4, 0);
|
||||
mandoc_ohash_init(&id_unique, 4, offsetof(struct id_entry, id));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -186,6 +197,8 @@ print_gen_head(struct html *h)
|
|||
struct tag *t;
|
||||
|
||||
print_otag(h, TAG_META, "?", "charset", "utf-8");
|
||||
print_otag(h, TAG_META, "??", "name", "viewport",
|
||||
"content", "width=device-width, initial-scale=1.0");
|
||||
if (h->style != NULL) {
|
||||
print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet",
|
||||
h->style, "type", "text/css", "media", "all");
|
||||
|
@ -203,23 +216,18 @@ print_gen_head(struct html *h)
|
|||
print_endline(h);
|
||||
print_text(h, "td.head-vol { text-align: center; }");
|
||||
print_endline(h);
|
||||
print_text(h, "div.Pp { margin: 1ex 0ex; }");
|
||||
print_text(h, ".Nd, .Bf, .Op { display: inline; }");
|
||||
print_endline(h);
|
||||
print_text(h, "div.Nd, div.Bf, div.Op { display: inline; }");
|
||||
print_text(h, ".Pa, .Ad { font-style: italic; }");
|
||||
print_endline(h);
|
||||
print_text(h, "span.Pa, span.Ad { font-style: italic; }");
|
||||
print_text(h, ".Ms { font-weight: bold; }");
|
||||
print_endline(h);
|
||||
print_text(h, "span.Ms { font-weight: bold; }");
|
||||
print_endline(h);
|
||||
print_text(h, "dl.Bl-diag ");
|
||||
print_text(h, ".Bl-diag ");
|
||||
print_byte(h, '>');
|
||||
print_text(h, " dt { font-weight: bold; }");
|
||||
print_endline(h);
|
||||
print_text(h, "code.Nm, code.Fl, code.Cm, code.Ic, "
|
||||
"code.In, code.Fd, code.Fn,");
|
||||
print_endline(h);
|
||||
print_text(h, "code.Cd { font-weight: bold; "
|
||||
"font-family: inherit; }");
|
||||
print_text(h, "code.Nm, .Fl, .Cm, .Ic, code.In, .Fd, .Fn, .Cd "
|
||||
"{ font-weight: bold; font-family: inherit; }");
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
@ -233,8 +241,10 @@ html_setfont(struct html *h, enum mandoc_esc font)
|
|||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTBI:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTCR:
|
||||
case ESCAPE_FONTCB:
|
||||
case ESCAPE_FONTCI:
|
||||
break;
|
||||
case ESCAPE_FONT:
|
||||
font = ESCAPE_FONTROMAN;
|
||||
|
@ -265,9 +275,17 @@ print_metaf(struct html *h)
|
|||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTCR:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
break;
|
||||
case ESCAPE_FONTCB:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
print_otag(h, TAG_B, "");
|
||||
break;
|
||||
case ESCAPE_FONTCI:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -276,21 +294,18 @@ print_metaf(struct html *h)
|
|||
void
|
||||
html_close_paragraph(struct html *h)
|
||||
{
|
||||
struct tag *t;
|
||||
struct tag *this, *next;
|
||||
int flags;
|
||||
|
||||
for (t = h->tag; t != NULL && t->closed == 0; t = t->next) {
|
||||
switch(t->tag) {
|
||||
case TAG_P:
|
||||
case TAG_PRE:
|
||||
print_tagq(h, t);
|
||||
this = h->tag;
|
||||
for (;;) {
|
||||
next = this->next;
|
||||
flags = htmltags[this->tag].flags;
|
||||
if (flags & (HTML_INPHRASE | HTML_TOPHRASE))
|
||||
print_ctag(h, this);
|
||||
if ((flags & HTML_INPHRASE) == 0)
|
||||
break;
|
||||
case TAG_A:
|
||||
print_tagq(h, t);
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
this = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,33 +343,66 @@ html_fillmode(struct html *h, enum roff_tok want)
|
|||
return had;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a string to be used for the "id=" attribute of an HTML
|
||||
* element and/or as a segment identifier for a URI in an <a> element.
|
||||
* The function may fail and return NULL if the node lacks text data
|
||||
* to create the attribute from.
|
||||
* The caller is responsible for free(3)ing the returned string.
|
||||
*
|
||||
* If the "unique" argument is non-zero, the "id_unique" ohash table
|
||||
* is used for de-duplication. If the "unique" argument is 1,
|
||||
* it is the first time the function is called for this tag and
|
||||
* location, so if an ordinal suffix is needed, it is incremented.
|
||||
* If the "unique" argument is 2, it is the second time the function
|
||||
* is called for this tag and location, so the ordinal suffix
|
||||
* remains unchanged.
|
||||
*/
|
||||
char *
|
||||
html_make_id(const struct roff_node *n, int unique)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
char *buf, *bufs, *cp;
|
||||
struct id_entry *entry;
|
||||
char *buf, *cp;
|
||||
size_t len;
|
||||
unsigned int slot;
|
||||
int suffix;
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next)
|
||||
if (nch->type != ROFFT_TEXT)
|
||||
return NULL;
|
||||
|
||||
buf = NULL;
|
||||
deroff(&buf, n);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
if (n->tag != NULL)
|
||||
buf = mandoc_strdup(n->tag);
|
||||
else {
|
||||
switch (n->tok) {
|
||||
case MDOC_Sh:
|
||||
case MDOC_Ss:
|
||||
case MDOC_Sx:
|
||||
case MAN_SH:
|
||||
case MAN_SS:
|
||||
for (nch = n->child; nch != NULL; nch = nch->next)
|
||||
if (nch->type != ROFFT_TEXT)
|
||||
return NULL;
|
||||
buf = NULL;
|
||||
deroff(&buf, n);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
break;
|
||||
default:
|
||||
if (n->child == NULL || n->child->type != ROFFT_TEXT)
|
||||
return NULL;
|
||||
buf = mandoc_strdup(n->child->string);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In ID attributes, only use ASCII characters that are
|
||||
* permitted in URL-fragment strings according to the
|
||||
* explicit list at:
|
||||
* https://url.spec.whatwg.org/#url-fragment-string
|
||||
* In addition, reserve '~' for ordinal suffixes.
|
||||
*/
|
||||
|
||||
for (cp = buf; *cp != '\0'; cp++)
|
||||
if (isalnum((unsigned char)*cp) == 0 &&
|
||||
strchr("!$&'()*+,-./:;=?@_~", *cp) == NULL)
|
||||
strchr("!$&'()*+,-./:;=?@_", *cp) == NULL)
|
||||
*cp = '_';
|
||||
|
||||
if (unique == 0)
|
||||
|
@ -362,25 +410,21 @@ html_make_id(const struct roff_node *n, int unique)
|
|||
|
||||
/* Avoid duplicate HTML id= attributes. */
|
||||
|
||||
bufs = NULL;
|
||||
suffix = 1;
|
||||
slot = ohash_qlookup(&id_unique, buf);
|
||||
cp = ohash_find(&id_unique, slot);
|
||||
if (cp != NULL) {
|
||||
while (cp != NULL) {
|
||||
free(bufs);
|
||||
if (++suffix > 127) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
mandoc_asprintf(&bufs, "%s_%d", buf, suffix);
|
||||
slot = ohash_qlookup(&id_unique, bufs);
|
||||
cp = ohash_find(&id_unique, slot);
|
||||
}
|
||||
free(buf);
|
||||
buf = bufs;
|
||||
if ((entry = ohash_find(&id_unique, slot)) == NULL) {
|
||||
len = strlen(buf) + 1;
|
||||
entry = mandoc_malloc(sizeof(*entry) + len);
|
||||
entry->ord = 1;
|
||||
memcpy(entry->id, buf, len);
|
||||
ohash_insert(&id_unique, slot, entry);
|
||||
} else if (unique == 1)
|
||||
entry->ord++;
|
||||
|
||||
if (entry->ord > 1) {
|
||||
cp = buf;
|
||||
mandoc_asprintf(&buf, "%s~%d", cp, entry->ord);
|
||||
free(cp);
|
||||
}
|
||||
ohash_insert(&id_unique, slot, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -470,8 +514,10 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
|||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBI:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTCR:
|
||||
case ESCAPE_FONTCB:
|
||||
case ESCAPE_FONTCI:
|
||||
if (0 == norecurse) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
if (html_setfont(h, esc))
|
||||
|
@ -589,6 +635,25 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
|||
|
||||
tflags = htmltags[tag].flags;
|
||||
|
||||
/* Flow content is not allowed in phrasing context. */
|
||||
|
||||
if ((tflags & HTML_INPHRASE) == 0) {
|
||||
for (t = h->tag; t != NULL; t = t->next) {
|
||||
if (t->closed)
|
||||
continue;
|
||||
assert((htmltags[t->tag].flags & HTML_TOPHRASE) == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Always wrap phrasing elements in a paragraph
|
||||
* unless already contained in some flow container;
|
||||
* never put them directly into a section.
|
||||
*/
|
||||
|
||||
} else if (tflags & HTML_TOPHRASE && h->tag->tag == TAG_SECTION)
|
||||
print_otag(h, TAG_P, "c", "Pp");
|
||||
|
||||
/* Push this tag onto the stack of open scopes. */
|
||||
|
||||
if ((tflags & HTML_NOSTACK) == 0) {
|
||||
|
@ -706,7 +771,7 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
|||
|
||||
/* Accommodate for "well-formed" singleton escaping. */
|
||||
|
||||
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
||||
if (htmltags[tag].flags & HTML_NOSTACK)
|
||||
print_byte(h, '/');
|
||||
|
||||
print_byte(h, '>');
|
||||
|
@ -724,6 +789,49 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
|||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an element with an optional "id=" attribute.
|
||||
* If the element has phrasing content and an "id=" attribute,
|
||||
* also add a permalink: outside if it can be in phrasing context,
|
||||
* inside otherwise.
|
||||
*/
|
||||
struct tag *
|
||||
print_otag_id(struct html *h, enum htmltag elemtype, const char *cattr,
|
||||
struct roff_node *n)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
struct tag *ret, *t;
|
||||
char *id, *href;
|
||||
|
||||
ret = NULL;
|
||||
id = href = NULL;
|
||||
if (n->flags & NODE_ID)
|
||||
id = html_make_id(n, 1);
|
||||
if (n->flags & NODE_HREF)
|
||||
href = id == NULL ? html_make_id(n, 2) : id;
|
||||
if (href != NULL && htmltags[elemtype].flags & HTML_INPHRASE)
|
||||
ret = print_otag(h, TAG_A, "chR", "permalink", href);
|
||||
t = print_otag(h, elemtype, "ci", cattr, id);
|
||||
if (ret == NULL) {
|
||||
ret = t;
|
||||
if (href != NULL && (nch = n->child) != NULL) {
|
||||
/* man(7) is safe, it tags phrasing content only. */
|
||||
if (n->tok > MDOC_MAX ||
|
||||
htmltags[elemtype].flags & HTML_TOPHRASE)
|
||||
nch = NULL;
|
||||
else /* For mdoc(7), beware of nested blocks. */
|
||||
while (nch != NULL && nch->type == ROFFT_TEXT)
|
||||
nch = nch->next;
|
||||
if (nch == NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", href);
|
||||
}
|
||||
}
|
||||
free(id);
|
||||
if (id == NULL)
|
||||
free(href);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
print_ctag(struct html *h, struct tag *tag)
|
||||
{
|
||||
|
@ -793,6 +901,25 @@ print_gen_comment(struct html *h, struct roff_node *n)
|
|||
void
|
||||
print_text(struct html *h, const char *word)
|
||||
{
|
||||
print_tagged_text(h, word, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
print_tagged_text(struct html *h, const char *word, struct roff_node *n)
|
||||
{
|
||||
struct tag *t;
|
||||
char *href;
|
||||
|
||||
/*
|
||||
* Always wrap text in a paragraph unless already contained in
|
||||
* some flow container; never put it directly into a section.
|
||||
*/
|
||||
|
||||
if (h->tag->tag == TAG_SECTION)
|
||||
print_otag(h, TAG_P, "c", "Pp");
|
||||
|
||||
/* Output whitespace before this text? */
|
||||
|
||||
if (h->col && (h->flags & HTML_NOSPACE) == 0) {
|
||||
if ( ! (HTML_KEEP & h->flags)) {
|
||||
if (HTML_PREKEEP & h->flags)
|
||||
|
@ -802,9 +929,21 @@ print_text(struct html *h, const char *word)
|
|||
print_word(h, " ");
|
||||
}
|
||||
|
||||
/*
|
||||
* Optionally switch fonts, optionally write a permalink, then
|
||||
* print the text, optionally surrounded by HTML whitespace.
|
||||
*/
|
||||
|
||||
assert(h->metaf == NULL);
|
||||
print_metaf(h);
|
||||
print_indent(h);
|
||||
|
||||
if (n != NULL && (href = html_make_id(n, 2)) != NULL) {
|
||||
t = print_otag(h, TAG_A, "chR", "permalink", href);
|
||||
free(href);
|
||||
} else
|
||||
t = NULL;
|
||||
|
||||
if ( ! print_encode(h, word, NULL, 0)) {
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
|
@ -815,7 +954,8 @@ print_text(struct html *h, const char *word)
|
|||
if (h->metaf != NULL) {
|
||||
print_tagq(h, h->metaf);
|
||||
h->metaf = NULL;
|
||||
}
|
||||
} else if (t != NULL)
|
||||
print_tagq(h, t);
|
||||
|
||||
h->flags &= ~HTML_IGNDELIM;
|
||||
}
|
||||
|
@ -942,15 +1082,12 @@ print_indent(struct html *h)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
if (h->col)
|
||||
if (h->col || h->noindent)
|
||||
return;
|
||||
|
||||
if (h->noindent == 0) {
|
||||
h->col = h->indent * 2;
|
||||
for (i = 0; i < h->col; i++)
|
||||
putchar(' ');
|
||||
}
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
h->col = h->indent * 2;
|
||||
for (i = 0; i < h->col; i++)
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
40
html.h
40
html.h
|
@ -1,7 +1,7 @@
|
|||
/* $Id: html.h,v 1.103 2019/04/30 15:53:00 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.109 2021/09/09 14:47:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,23 +14,21 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Internal interfaces for mandoc(1) HTML formatters.
|
||||
* For use by the individual HTML formatters only.
|
||||
*/
|
||||
|
||||
enum htmltag {
|
||||
TAG_HTML,
|
||||
TAG_HEAD,
|
||||
TAG_BODY,
|
||||
TAG_META,
|
||||
TAG_TITLE,
|
||||
TAG_DIV,
|
||||
TAG_IDIV,
|
||||
TAG_SECTION,
|
||||
TAG_H1,
|
||||
TAG_H2,
|
||||
TAG_SPAN,
|
||||
TAG_LINK,
|
||||
TAG_BR,
|
||||
TAG_A,
|
||||
TAG_STYLE,
|
||||
TAG_TITLE,
|
||||
TAG_BODY,
|
||||
TAG_DIV,
|
||||
TAG_SECTION,
|
||||
TAG_TABLE,
|
||||
TAG_TR,
|
||||
TAG_TD,
|
||||
|
@ -40,15 +38,21 @@ enum htmltag {
|
|||
TAG_DL,
|
||||
TAG_DT,
|
||||
TAG_DD,
|
||||
TAG_H1,
|
||||
TAG_H2,
|
||||
TAG_P,
|
||||
TAG_PRE,
|
||||
TAG_VAR,
|
||||
TAG_CITE,
|
||||
TAG_A,
|
||||
TAG_B,
|
||||
TAG_I,
|
||||
TAG_CITE,
|
||||
TAG_CODE,
|
||||
TAG_I,
|
||||
TAG_SMALL,
|
||||
TAG_STYLE,
|
||||
TAG_SPAN,
|
||||
TAG_VAR,
|
||||
TAG_BR,
|
||||
TAG_HR,
|
||||
TAG_MARK,
|
||||
TAG_MATH,
|
||||
TAG_MROW,
|
||||
TAG_MI,
|
||||
|
@ -120,8 +124,12 @@ void print_gen_comment(struct html *, struct roff_node *);
|
|||
void print_gen_decls(struct html *);
|
||||
void print_gen_head(struct html *);
|
||||
struct tag *print_otag(struct html *, enum htmltag, const char *, ...);
|
||||
struct tag *print_otag_id(struct html *, enum htmltag, const char *,
|
||||
struct roff_node *);
|
||||
void print_tagq(struct html *, const struct tag *);
|
||||
void print_stagq(struct html *, const struct tag *);
|
||||
void print_tagged_text(struct html *, const char *,
|
||||
struct roff_node *);
|
||||
void print_text(struct html *, const char *);
|
||||
void print_tblclose(struct html *);
|
||||
void print_tbl(struct html *, const struct tbl_span *);
|
||||
|
|
14
libmandoc.h
14
libmandoc.h
|
@ -1,7 +1,7 @@
|
|||
/* $Id: libmandoc.h,v 1.77 2018/12/21 17:15:18 schwarze Exp $ */
|
||||
/* $Id: libmandoc.h,v 1.80 2021/06/27 17:57:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015,2017,2018,2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,9 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Internal interfaces for parser utilities needed by multiple parsers
|
||||
* and the top-level functions to call the mdoc, man, and roff parsers.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -47,8 +50,9 @@ struct buf {
|
|||
|
||||
struct roff;
|
||||
struct roff_man;
|
||||
struct roff_node;
|
||||
|
||||
char *mandoc_normdate(struct roff_man *, char *, int, int);
|
||||
char *mandoc_normdate(struct roff_node *, struct roff_node *);
|
||||
int mandoc_eos(const char *, size_t);
|
||||
int mandoc_strntoi(const char *, size_t, int);
|
||||
const char *mandoc_a2msec(const char*);
|
||||
|
@ -69,10 +73,10 @@ void roff_reset(struct roff *);
|
|||
void roff_man_free(struct roff_man *);
|
||||
struct roff_man *roff_man_alloc(struct roff *, const char *, int);
|
||||
void roff_man_reset(struct roff_man *);
|
||||
int roff_parseln(struct roff *, int, struct buf *, int *);
|
||||
int roff_parseln(struct roff *, int, struct buf *, int *, size_t);
|
||||
void roff_userret(struct roff *);
|
||||
void roff_endparse(struct roff *);
|
||||
void roff_setreg(struct roff *, const char *, int, char sign);
|
||||
void roff_setreg(struct roff *, const char *, int, char);
|
||||
int roff_getreg(struct roff *, const char *);
|
||||
char *roff_strdup(const struct roff *, const char *);
|
||||
char *roff_getarg(struct roff *, char **, int, int *);
|
||||
|
|
112
man.1
112
man.1
|
@ -1,9 +1,9 @@
|
|||
.\" $Id: man.1,v 1.35 2019/03/09 15:55:01 schwarze Exp $
|
||||
.\" $Id: man.1,v 1.40 2020/07/20 16:57:30 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\" Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2014-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
|
@ -31,7 +31,7 @@
|
|||
.\"
|
||||
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
|
||||
.\"
|
||||
.Dd $Mdocdate: March 9 2019 $
|
||||
.Dd $Mdocdate: July 20 2020 $
|
||||
.Dt MAN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -51,7 +51,7 @@ The
|
|||
.Nm
|
||||
utility
|
||||
displays the
|
||||
manual pages entitled
|
||||
manual page entitled
|
||||
.Ar name .
|
||||
Pages may be selected according to
|
||||
a specific category
|
||||
|
@ -64,7 +64,6 @@ The options are as follows:
|
|||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
Display all matching manual pages.
|
||||
Normally, only the first page found is displayed.
|
||||
.It Fl C Ar file
|
||||
Use the specified
|
||||
.Ar file
|
||||
|
@ -75,7 +74,7 @@ See
|
|||
for a description of the contents of this file.
|
||||
.It Fl c
|
||||
Copy the manual page to the standard output instead of using
|
||||
.Xr more 1
|
||||
.Xr less 1
|
||||
to paginate it.
|
||||
This is done by default if the standard output is not a terminal device.
|
||||
.Pp
|
||||
|
@ -129,31 +128,31 @@ are ignored.
|
|||
This option implies
|
||||
.Fl a .
|
||||
.It Fl M Ar path
|
||||
Override the list of standard directories which
|
||||
.Nm
|
||||
searches for manual pages.
|
||||
Override the list of directories to search for manual pages.
|
||||
The supplied
|
||||
.Ar path
|
||||
must be a colon
|
||||
.Pq Ql \&:
|
||||
separated list of directories.
|
||||
This search path may also be set using the environment variable
|
||||
.Ev MANPATH .
|
||||
.It Fl m Ar path
|
||||
Augment the list of standard directories which
|
||||
.Nm
|
||||
searches for manual pages.
|
||||
The supplied
|
||||
.Ar path
|
||||
must be a colon
|
||||
.Pq Ql \&:
|
||||
separated list of directories.
|
||||
These directories will be searched before the standard directories or
|
||||
the directories specified using the
|
||||
.Fl M
|
||||
option or the
|
||||
This option also overrides the environment variable
|
||||
.Ev MANPATH
|
||||
environment variable.
|
||||
and any directories specified in the
|
||||
.Xr man.conf 5
|
||||
file.
|
||||
.It Fl m Ar path
|
||||
Augment the list of directories to search for manual pages.
|
||||
The supplied
|
||||
.Ar path
|
||||
must be a colon
|
||||
.Pq Ql \&:
|
||||
separated list of directories.
|
||||
These directories will be searched before those specified using the
|
||||
.Fl M
|
||||
option, the
|
||||
.Ev MANPATH
|
||||
environment variable, the
|
||||
.Xr man.conf 5
|
||||
file, or the default directories.
|
||||
.It Fl S Ar subsection
|
||||
Only show pages for the specified
|
||||
.Xr machine 1
|
||||
|
@ -168,6 +167,7 @@ architecture whilst using another.
|
|||
This option overrides the
|
||||
.Ev MACHINE
|
||||
environment variable.
|
||||
.Tg s
|
||||
.It Oo Fl s Oc Ar section
|
||||
Only select manuals from the specified
|
||||
.Ar section .
|
||||
|
@ -197,13 +197,12 @@ System maintenance and operation commands.
|
|||
.It 9
|
||||
Kernel internals.
|
||||
.El
|
||||
.Pp
|
||||
If not specified and a match is found in more than one section,
|
||||
the first match is selected from the following list:
|
||||
1, 8, 6, 2, 3, 5, 7, 4, 9, 3p.
|
||||
.It Fl w
|
||||
List the pathnames of all matching manual pages instead of displaying
|
||||
any of them.
|
||||
If no
|
||||
.Ar name
|
||||
is given, list the directories that would be searched.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
|
@ -214,9 +213,23 @@ The options
|
|||
.Fl fkl
|
||||
are mutually exclusive and override each other.
|
||||
.Pp
|
||||
Guidelines for writing
|
||||
man pages can be found in
|
||||
.Xr mdoc 7 .
|
||||
The search starts with the
|
||||
.Fl m
|
||||
argument if provided, then continues with the
|
||||
.Fl M
|
||||
argument, the
|
||||
.Ev MANPATH
|
||||
variable, the
|
||||
.Ic manpath
|
||||
entries in the
|
||||
.Xr man.conf 5
|
||||
file, or with
|
||||
.Pa /usr/share/man : Ns Pa /usr/X11R6/man : Ns Pa /usr/local/man
|
||||
by default.
|
||||
Within each of these, directories are searched in the order provided.
|
||||
Within each directory, the search proceeds according to the following
|
||||
list of sections: 1, 8, 6, 2, 3, 5, 7, 4, 9, 3p.
|
||||
The first match found is shown.
|
||||
.Pp
|
||||
The
|
||||
.Xr mandoc.db 5
|
||||
|
@ -236,6 +249,10 @@ The database is kept up to date with
|
|||
which is run by the
|
||||
.Xr weekly 8
|
||||
maintenance script.
|
||||
.Pp
|
||||
Guidelines for writing
|
||||
man pages can be found in
|
||||
.Xr mdoc 7 .
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width MANPATHX
|
||||
.It Ev MACHINE
|
||||
|
@ -258,7 +275,7 @@ is case insensitive.
|
|||
Any non-empty value of the environment variable
|
||||
.Ev MANPAGER
|
||||
is used instead of the standard pagination program,
|
||||
.Xr more 1 .
|
||||
.Xr less 1 .
|
||||
If
|
||||
.Xr less 1
|
||||
is used, the interactive
|
||||
|
@ -286,15 +303,15 @@ manual opens a manual page at the definition of a specific
|
|||
.Ar term
|
||||
rather than at the beginning.
|
||||
.It Ev MANPATH
|
||||
The standard search path used by
|
||||
.Nm
|
||||
may be changed by specifying a path in the
|
||||
Override the standard search path which is either specified in
|
||||
.Xr man.conf 5
|
||||
or the default path.
|
||||
The format of
|
||||
.Ev MANPATH
|
||||
environment variable.
|
||||
The format of the path is a colon
|
||||
is a colon
|
||||
.Pq Ql \&:
|
||||
separated list of directories.
|
||||
Invalid paths are ignored.
|
||||
Invalid directories are ignored.
|
||||
Overridden by
|
||||
.Fl M ,
|
||||
ignored if
|
||||
|
@ -303,25 +320,24 @@ is specified.
|
|||
.Pp
|
||||
If
|
||||
.Ev MANPATH
|
||||
begins with a colon, it is appended to the default list;
|
||||
if it ends with a colon, it is prepended to the default list;
|
||||
begins with a colon, it is appended to the standard path;
|
||||
if it ends with a colon, it is prepended to the standard path;
|
||||
or if it contains two adjacent colons,
|
||||
the standard search path is inserted between the colons.
|
||||
If none of these conditions are met, it overrides the
|
||||
standard search path.
|
||||
the standard path is inserted between the colons.
|
||||
.It Ev PAGER
|
||||
Specifies the pagination program to use when
|
||||
.Ev MANPAGER
|
||||
is not defined.
|
||||
If neither PAGER nor MANPAGER is defined,
|
||||
.Xr more 1
|
||||
.Fl s
|
||||
.Xr less 1
|
||||
is used.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/man.conf -compact
|
||||
.It Pa /etc/man.conf
|
||||
default man configuration file
|
||||
default
|
||||
.Nm
|
||||
configuration file
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std man
|
||||
|
@ -365,7 +381,7 @@ are extensions to that specification.
|
|||
A
|
||||
.Nm
|
||||
command first appeared in
|
||||
.At v3 .
|
||||
.At v2 .
|
||||
.Pp
|
||||
The
|
||||
.Fl w
|
||||
|
|
55
man.7
55
man.7
|
@ -1,7 +1,7 @@
|
|||
.\" $Id: man.7,v 1.144 2019/07/09 03:46:59 schwarze Exp $
|
||||
.\" $Id: man.7,v 1.148 2021/08/05 14:31:14 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011-2015,2017,2018,2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2017 Anthony Bentley <bentley@openbsd.org>
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
.\"
|
||||
|
@ -17,7 +17,7 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 9 2019 $
|
||||
.Dd $Mdocdate: August 5 2021 $
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -127,6 +127,8 @@ Sets the volume for the footer for compatibility with man pages from
|
|||
.At
|
||||
releases.
|
||||
The optional arguments specify which release it is from.
|
||||
This macro is an extension that first appeared in
|
||||
.Bx 4.3 .
|
||||
.It Ic B
|
||||
Text is rendered in bold face.
|
||||
.It Ic BI
|
||||
|
@ -244,7 +246,7 @@ link description to be shown
|
|||
.Ed
|
||||
.It Ic OP
|
||||
Optional command-line argument.
|
||||
This is a non-standard GNU extension.
|
||||
This is a non-standard DWB extension.
|
||||
It has the following syntax:
|
||||
.Pp
|
||||
.D1 Pf . Ic OP Ar key Op Ar value
|
||||
|
@ -255,8 +257,12 @@ is usually a command-line flag and
|
|||
.Ar value
|
||||
its argument.
|
||||
.It Ic P
|
||||
A synonym for
|
||||
.Ic PP .
|
||||
This synonym for
|
||||
.Ic PP
|
||||
is an
|
||||
.At III
|
||||
extension later adopted by
|
||||
.Bx 4.3 .
|
||||
.It Ic PD
|
||||
Specify the vertical space to be inserted before each new paragraph.
|
||||
.br
|
||||
|
@ -343,6 +349,9 @@ See also
|
|||
.It Ic SB
|
||||
Text is rendered in small size (one point smaller than the default font)
|
||||
bold face.
|
||||
This macro is an extension that probably first appeared in SunOS 4.0
|
||||
and was later adopted by GNU and by
|
||||
.Bx 4.4 .
|
||||
.It Ic SH
|
||||
Begin a section.
|
||||
The scope of a section is only closed by another section or the end of
|
||||
|
@ -435,6 +444,8 @@ Sets the volume for the footer for compatibility with man pages from
|
|||
.Bx
|
||||
releases.
|
||||
The optional first argument specifies which release it is from.
|
||||
This macro is an extension that first appeared in
|
||||
.Bx 3 .
|
||||
.It Ic UE
|
||||
End a uniform resource identifier block started with
|
||||
.Ic UR .
|
||||
|
@ -505,7 +516,7 @@ The syntax is as follows:
|
|||
.It Ic I Ta n Ta next-line Ta \&
|
||||
.It Ic IB Ta n Ta current Ta \&
|
||||
.It Ic IR Ta n Ta current Ta \&
|
||||
.It Ic OP Ta >=1 Ta current Ta GNU
|
||||
.It Ic OP Ta >=1 Ta current Ta DWB
|
||||
.It Ic PD Ta 1 Ta current Ta \&
|
||||
.It Ic RB Ta n Ta current Ta \&
|
||||
.It Ic RI Ta n Ta current Ta \&
|
||||
|
@ -601,16 +612,32 @@ The
|
|||
language first appeared as a macro package for the roff typesetting
|
||||
system in
|
||||
.At v7 .
|
||||
It was later rewritten by James Clark as a macro package for groff.
|
||||
Eric S. Raymond wrote the extended
|
||||
.Nm
|
||||
macros for groff in 2007.
|
||||
.Pp
|
||||
The stand-alone implementation that is part of the
|
||||
.Xr mandoc 1
|
||||
utility written by Kristaps Dzonsons appeared in
|
||||
utility first appeared in
|
||||
.Ox 4.6 .
|
||||
.Sh AUTHORS
|
||||
This
|
||||
.An -nosplit
|
||||
.An Douglas McIlroy Aq Mt m.douglas.mcilroy@dartmouth.edu
|
||||
designed and implemented the original version of these macros,
|
||||
wrote the original version of this manual page,
|
||||
and was the first to use them when he edited volume 1 of the
|
||||
.At v7
|
||||
manual pages.
|
||||
.Pp
|
||||
.An James Clark
|
||||
later rewrote the macros for groff.
|
||||
.An Eric S. Raymond Aq Mt esr@thyrsus.com
|
||||
and
|
||||
.An Werner Lemberg Aq Mt wl@gnu.org
|
||||
added the extended
|
||||
.Nm
|
||||
reference was written by
|
||||
macros to groff in 2007.
|
||||
.Pp
|
||||
The
|
||||
.Xr mandoc 1
|
||||
program and this
|
||||
.Nm
|
||||
reference were written by
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
|
|
14
man.conf.5
14
man.conf.5
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: man.conf.5,v 1.6 2018/10/02 14:56:47 schwarze Exp $
|
||||
.\" $Id: man.conf.5,v 1.8 2020/02/10 14:42:10 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015, 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: October 2 2018 $
|
||||
.Dd $Mdocdate: February 10 2020 $
|
||||
.Dt MAN.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -101,15 +101,11 @@ manual.
|
|||
.It Ic toc Ta none Ta Cm html Ta print table of contents
|
||||
.It Ic width Ta integer Ta Cm ascii , utf8 Ta right margin
|
||||
.El
|
||||
.It Ic _whatdb Ar path Ns Cm /whatis.db
|
||||
This directive provides the same functionality as
|
||||
.Ic manpath ,
|
||||
but using a historic and misleading syntax.
|
||||
It is kept for backward compatibility for now,
|
||||
but will eventually be removed.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Pa /etc/man.conf
|
||||
.Bl -tag -width /etc/examples/man.conf -compact
|
||||
.It Pa /etc/man.conf
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The following configuration file reproduces the defaults:
|
||||
installing it is equivalent to not having a
|
||||
|
|
43
man_html.c
43
man_html.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: man_html.c,v 1.174 2019/04/30 15:53:00 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.179 2020/10/16 17:22:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* HTML formatter for man(7) used by mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -34,7 +36,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#define MAN_ARGS const struct roff_meta *man, \
|
||||
const struct roff_node *n, \
|
||||
struct roff_node *n, \
|
||||
struct html *h
|
||||
|
||||
struct man_html_act {
|
||||
|
@ -167,7 +169,12 @@ print_man_node(MAN_ARGS)
|
|||
if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
|
||||
return;
|
||||
|
||||
html_fillmode(h, n->flags & NODE_NOFILL ? ROFF_nf : ROFF_fi);
|
||||
if ((n->flags & NODE_NOFILL) == 0)
|
||||
html_fillmode(h, ROFF_fi);
|
||||
else if (html_fillmode(h, ROFF_nf) == ROFF_nf &&
|
||||
n->tok != ROFF_fi && n->flags & NODE_LINE &&
|
||||
(n->prev == NULL || n->prev->tok != MAN_YS))
|
||||
print_endline(h);
|
||||
|
||||
child = 1;
|
||||
switch (n->type) {
|
||||
|
@ -178,7 +185,7 @@ print_man_node(MAN_ARGS)
|
|||
}
|
||||
if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(h->flags & HTML_NONEWLINE) == 0)
|
||||
print_endline(h);
|
||||
print_otag(h, TAG_BR, "");
|
||||
else if (n->flags & NODE_DELIMC)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
t = h->tag;
|
||||
|
@ -244,20 +251,13 @@ print_man_node(MAN_ARGS)
|
|||
* Close the list if no further item of the same type
|
||||
* follows; otherwise, close the item only.
|
||||
*/
|
||||
if (list_continues(n, n->next) == '\0') {
|
||||
if (list_continues(n, roff_node_next(n)) == '\0') {
|
||||
print_tagq(h, t);
|
||||
t = NULL;
|
||||
}
|
||||
}
|
||||
if (t != NULL)
|
||||
print_stagq(h, t);
|
||||
|
||||
if (n->flags & NODE_NOFILL && n->tok != MAN_YS &&
|
||||
(n->next != NULL && n->next->flags & NODE_LINE)) {
|
||||
/* In .nf = <pre>, print even empty lines. */
|
||||
h->col++;
|
||||
print_endline(h);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -310,7 +310,6 @@ static int
|
|||
man_SH_pre(MAN_ARGS)
|
||||
{
|
||||
const char *class;
|
||||
char *id;
|
||||
enum htmltag tag;
|
||||
|
||||
if (n->tok == MAN_SH) {
|
||||
|
@ -326,10 +325,7 @@ man_SH_pre(MAN_ARGS)
|
|||
print_otag(h, TAG_SECTION, "c", class);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
id = html_make_id(n, 1);
|
||||
print_otag(h, tag, "ci", class, id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag_id(h, tag, class, n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
|
@ -445,15 +441,17 @@ list_continues(const struct roff_node *n1, const struct roff_node *n2)
|
|||
static int
|
||||
man_IP_pre(MAN_ARGS)
|
||||
{
|
||||
const struct roff_node *nn;
|
||||
struct roff_node *nn;
|
||||
const char *list_class;
|
||||
enum htmltag list_elem, body_elem;
|
||||
char list_type;
|
||||
|
||||
nn = n->type == ROFFT_BLOCK ? n : n->parent;
|
||||
if ((list_type = list_continues(nn->prev, nn)) == '\0') {
|
||||
list_type = list_continues(roff_node_prev(nn), nn);
|
||||
if (list_type == '\0') {
|
||||
/* Start a new list. */
|
||||
if ((list_type = list_continues(nn, nn->next)) == '\0')
|
||||
list_type = list_continues(nn, roff_node_next(nn));
|
||||
if (list_type == '\0')
|
||||
list_type = ' ';
|
||||
switch (list_type) {
|
||||
case ' ':
|
||||
|
@ -487,7 +485,7 @@ man_IP_pre(MAN_ARGS)
|
|||
case ROFFT_HEAD:
|
||||
if (body_elem == TAG_LI)
|
||||
return 0;
|
||||
print_otag(h, TAG_DT, "");
|
||||
print_otag_id(h, TAG_DT, NULL, n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, body_elem, "");
|
||||
|
@ -495,7 +493,6 @@ man_IP_pre(MAN_ARGS)
|
|||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch(n->tok) {
|
||||
case MAN_IP: /* Only print the first header element. */
|
||||
if (n->child != NULL)
|
||||
|
|
12
man_macro.c
12
man_macro.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: man_macro.c,v 1.144 2019/01/05 18:59:46 schwarze Exp $ */
|
||||
/* $Id: man_macro.c,v 1.145 2020/09/09 17:01:10 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -107,9 +107,11 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
|||
mandoc_msg(MANDOCERR_BLK_LINE,
|
||||
n->line, n->pos,
|
||||
"EOF breaks %s", roff_name[n->tok]);
|
||||
if (man->flags & MAN_ELINE)
|
||||
man->flags &= ~MAN_ELINE;
|
||||
else {
|
||||
if (man->flags & MAN_ELINE) {
|
||||
if ((man_macro(n->parent->tok)->flags &
|
||||
MAN_ESCOPED) == 0)
|
||||
man->flags &= ~MAN_ELINE;
|
||||
} else {
|
||||
assert(n->type == ROFFT_HEAD);
|
||||
n = n->parent;
|
||||
man->flags &= ~MAN_BLINE;
|
||||
|
|
132
man_term.c
132
man_term.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: man_term.c,v 1.232 2019/07/23 17:53:35 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.236 2021/06/28 19:50:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,9 @@
|
|||
* 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.
|
||||
*
|
||||
* Plain text formatter for man(7), used by mandoc(1)
|
||||
* for ASCII, UTF-8, PostScript, and PDF output.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -32,7 +35,7 @@
|
|||
#include "man.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "tag.h"
|
||||
#include "term_tag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MAXMARGINS 64 /* maximum number of indented scopes */
|
||||
|
@ -64,7 +67,7 @@ static void print_man_head(struct termp *,
|
|||
static void print_man_foot(struct termp *,
|
||||
const struct roff_meta *);
|
||||
static void print_bvspace(struct termp *,
|
||||
const struct roff_node *, int);
|
||||
struct roff_node *, int);
|
||||
|
||||
static int pre_B(DECL_ARGS);
|
||||
static int pre_DT(DECL_ARGS);
|
||||
|
@ -94,8 +97,6 @@ static void post_SY(DECL_ARGS);
|
|||
static void post_TP(DECL_ARGS);
|
||||
static void post_UR(DECL_ARGS);
|
||||
|
||||
static void tag_man(struct termp *, struct roff_node *);
|
||||
|
||||
static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL, 0 }, /* TH */
|
||||
{ pre_SH, post_SH, 0 }, /* SH */
|
||||
|
@ -205,19 +206,20 @@ terminal_man(void *arg, const struct roff_meta *man)
|
|||
* first, print it.
|
||||
*/
|
||||
static void
|
||||
print_bvspace(struct termp *p, const struct roff_node *n, int pardist)
|
||||
print_bvspace(struct termp *p, struct roff_node *n, int pardist)
|
||||
{
|
||||
int i;
|
||||
struct roff_node *nch;
|
||||
int i;
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (n->body != NULL && n->body->child != NULL)
|
||||
if (n->body->child->type == ROFFT_TBL)
|
||||
return;
|
||||
if (n->body != NULL &&
|
||||
(nch = roff_node_child(n->body)) != NULL &&
|
||||
nch->type == ROFFT_TBL)
|
||||
return;
|
||||
|
||||
if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
|
||||
if (n->prev == NULL)
|
||||
return;
|
||||
if (n->parent->tok != MAN_RS && roff_node_prev(n) == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pardist; i++)
|
||||
term_vspace(p);
|
||||
|
@ -538,10 +540,8 @@ pre_IP(DECL_ARGS)
|
|||
case ROFFT_HEAD:
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
if (n->child != NULL) {
|
||||
if (n->child != NULL)
|
||||
print_man_node(p, mt, n->child, meta);
|
||||
tag_man(p, n->child);
|
||||
}
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = mt->offset + len;
|
||||
|
@ -621,18 +621,6 @@ pre_TP(DECL_ARGS)
|
|||
while (nn != NULL && (nn->flags & NODE_LINE) == 0)
|
||||
nn = nn->next;
|
||||
|
||||
if (nn == NULL)
|
||||
return 0;
|
||||
|
||||
if (nn->type == ROFFT_TEXT)
|
||||
tag_man(p, nn);
|
||||
else if (nn->child != NULL &&
|
||||
nn->child->type == ROFFT_TEXT &&
|
||||
(nn->tok == MAN_B || nn->tok == MAN_BI ||
|
||||
nn->tok == MAN_BR || nn->tok == MAN_I ||
|
||||
nn->tok == MAN_IB || nn->tok == MAN_IR))
|
||||
tag_man(p, nn->child);
|
||||
|
||||
while (nn != NULL) {
|
||||
print_man_node(p, mt, nn, meta);
|
||||
nn = nn->next;
|
||||
|
@ -683,12 +671,8 @@ pre_SS(DECL_ARGS)
|
|||
* and after an empty subsection.
|
||||
*/
|
||||
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (n != NULL && n->tok >= MAN_TH &&
|
||||
man_term_act(n->tok)->flags & MAN_NOTEXT);
|
||||
if (n == NULL || n->type == ROFFT_COMMENT ||
|
||||
(n->tok == MAN_SS && n->body->child == NULL))
|
||||
if ((n = roff_node_prev(n)) == NULL ||
|
||||
(n->tok == MAN_SS && roff_node_child(n->body) == NULL))
|
||||
break;
|
||||
|
||||
for (i = 0; i < mt->pardist; i++)
|
||||
|
@ -728,12 +712,8 @@ pre_SH(DECL_ARGS)
|
|||
* and after an empty section.
|
||||
*/
|
||||
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (n != NULL && n->tok >= MAN_TH &&
|
||||
man_term_act(n->tok)->flags & MAN_NOTEXT);
|
||||
if (n == NULL || n->type == ROFFT_COMMENT ||
|
||||
(n->tok == MAN_SH && n->body->child == NULL))
|
||||
if ((n = roff_node_prev(n)) == NULL ||
|
||||
(n->tok == MAN_SH && roff_node_child(n->body) == NULL))
|
||||
break;
|
||||
|
||||
for (i = 0; i < mt->pardist; i++)
|
||||
|
@ -839,7 +819,7 @@ pre_SY(DECL_ARGS)
|
|||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
if (n->prev == NULL || n->prev->tok != MAN_SY)
|
||||
if ((nn = roff_node_prev(n)) == NULL || nn->tok != MAN_SY)
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
|
@ -920,6 +900,9 @@ print_man_node(DECL_ARGS)
|
|||
const struct man_term_act *act;
|
||||
int c;
|
||||
|
||||
if (n->flags & NODE_ID)
|
||||
term_tag_write(n, p->line);
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
/*
|
||||
|
@ -1038,10 +1021,6 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
|
|||
*/
|
||||
|
||||
if ( ! p->mdocstyle) {
|
||||
if (meta->hasbody) {
|
||||
term_vspace(p);
|
||||
term_vspace(p);
|
||||
}
|
||||
mandoc_asprintf(&title, "%s(%s)",
|
||||
meta->title, meta->msec);
|
||||
} else if (meta->os != NULL) {
|
||||
|
@ -1160,66 +1139,5 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
|
|||
*/
|
||||
|
||||
term_vspace(p);
|
||||
if ( ! p->mdocstyle) {
|
||||
term_vspace(p);
|
||||
term_vspace(p);
|
||||
}
|
||||
free(title);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading whitespace, dashes, backslashes, and font escapes,
|
||||
* then create a tag if the first following byte is a letter.
|
||||
* Priority is high unless whitespace is present.
|
||||
*/
|
||||
static void
|
||||
tag_man(struct termp *p, struct roff_node *n)
|
||||
{
|
||||
const char *cp, *arg;
|
||||
int prio, sz;
|
||||
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
cp = n->string;
|
||||
prio = 1;
|
||||
for (;;) {
|
||||
switch (*cp) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
prio = INT_MAX;
|
||||
/* FALLTHROUGH */
|
||||
case '-':
|
||||
cp++;
|
||||
break;
|
||||
case '\\':
|
||||
cp++;
|
||||
switch (mandoc_escape(&cp, &arg, &sz)) {
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTPREV:
|
||||
case ESCAPE_FONTBI:
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (sz != 1)
|
||||
return;
|
||||
switch (*arg) {
|
||||
case '&':
|
||||
case '-':
|
||||
case 'e':
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isalpha((unsigned char)*cp))
|
||||
tag_put(cp, prio, p->line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
157
man_validate.c
157
man_validate.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: man_validate.c,v 1.149 2019/06/27 15:07:30 schwarze Exp $ */
|
||||
/* $Id: man_validate.c,v 1.156 2021/08/10 12:55:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Validation module for man(7) syntax trees used by mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -36,6 +38,7 @@
|
|||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
#include "libman.h"
|
||||
#include "tag.h"
|
||||
|
||||
#define CHKARGS struct roff_man *man, struct roff_node *n
|
||||
|
||||
|
@ -45,6 +48,7 @@ static void check_abort(CHKARGS) __attribute__((__noreturn__));
|
|||
static void check_par(CHKARGS);
|
||||
static void check_part(CHKARGS);
|
||||
static void check_root(CHKARGS);
|
||||
static void check_tag(struct roff_node *, struct roff_node *);
|
||||
static void check_text(CHKARGS);
|
||||
|
||||
static void post_AT(CHKARGS);
|
||||
|
@ -54,6 +58,7 @@ static void post_IP(CHKARGS);
|
|||
static void post_OP(CHKARGS);
|
||||
static void post_SH(CHKARGS);
|
||||
static void post_TH(CHKARGS);
|
||||
static void post_TP(CHKARGS);
|
||||
static void post_UC(CHKARGS);
|
||||
static void post_UR(CHKARGS);
|
||||
static void post_in(CHKARGS);
|
||||
|
@ -62,8 +67,8 @@ static const v_check man_valids[MAN_MAX - MAN_TH] = {
|
|||
post_TH, /* TH */
|
||||
post_SH, /* SH */
|
||||
post_SH, /* SS */
|
||||
NULL, /* TP */
|
||||
NULL, /* TQ */
|
||||
post_TP, /* TP */
|
||||
post_TP, /* TQ */
|
||||
check_abort,/* LP */
|
||||
check_par, /* PP */
|
||||
check_abort,/* P */
|
||||
|
@ -185,7 +190,7 @@ check_root(CHKARGS)
|
|||
|
||||
man->meta.title = mandoc_strdup("");
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
man->meta.date = mandoc_normdate(man, NULL, n->line, n->pos);
|
||||
man->meta.date = mandoc_normdate(NULL, NULL);
|
||||
}
|
||||
|
||||
if (man->meta.os_e &&
|
||||
|
@ -201,6 +206,68 @@ check_abort(CHKARGS)
|
|||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading whitespace, dashes, backslashes, and font escapes,
|
||||
* then create a tag if the first following byte is a letter.
|
||||
* Priority is high unless whitespace is present.
|
||||
*/
|
||||
static void
|
||||
check_tag(struct roff_node *n, struct roff_node *nt)
|
||||
{
|
||||
const char *cp, *arg;
|
||||
int prio, sz;
|
||||
|
||||
if (nt == NULL || nt->type != ROFFT_TEXT)
|
||||
return;
|
||||
|
||||
cp = nt->string;
|
||||
prio = TAG_STRONG;
|
||||
for (;;) {
|
||||
switch (*cp) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
prio = TAG_WEAK;
|
||||
/* FALLTHROUGH */
|
||||
case '-':
|
||||
cp++;
|
||||
break;
|
||||
case '\\':
|
||||
cp++;
|
||||
switch (mandoc_escape(&cp, &arg, &sz)) {
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBI:
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTCR:
|
||||
case ESCAPE_FONTCB:
|
||||
case ESCAPE_FONTCI:
|
||||
case ESCAPE_FONTPREV:
|
||||
case ESCAPE_IGNORE:
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (sz != 1)
|
||||
return;
|
||||
switch (*arg) {
|
||||
case '-':
|
||||
case 'e':
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isalpha((unsigned char)*cp))
|
||||
tag_put(cp, prio, n);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check_text(CHKARGS)
|
||||
{
|
||||
|
@ -246,9 +313,32 @@ static void
|
|||
post_SH(CHKARGS)
|
||||
{
|
||||
struct roff_node *nc;
|
||||
char *cp, *tag;
|
||||
|
||||
if (n->type != ROFFT_BODY || (nc = n->child) == NULL)
|
||||
nc = n->child;
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
tag = NULL;
|
||||
deroff(&tag, n);
|
||||
if (tag != NULL) {
|
||||
for (cp = tag; *cp != '\0'; cp++)
|
||||
if (*cp == ' ')
|
||||
*cp = '_';
|
||||
if (nc != NULL && nc->type == ROFFT_TEXT &&
|
||||
strcmp(nc->string, tag) == 0)
|
||||
tag_put(NULL, TAG_STRONG, n);
|
||||
else
|
||||
tag_put(tag, TAG_FALLBACK, n);
|
||||
free(tag);
|
||||
}
|
||||
return;
|
||||
case ROFFT_BODY:
|
||||
if (nc != NULL)
|
||||
break;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (nc->tok == MAN_PP && nc->body->child != NULL) {
|
||||
while (nc->body->last != NULL) {
|
||||
|
@ -332,12 +422,14 @@ check_par(CHKARGS)
|
|||
static void
|
||||
post_IP(CHKARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
if (n->head->child == NULL && n->body->child == NULL)
|
||||
roff_node_delete(man, n);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
check_tag(n, n->child);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->parent->head->child == NULL && n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos,
|
||||
|
@ -348,6 +440,37 @@ post_IP(CHKARGS)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The first next-line element in the head is the tag.
|
||||
* If that's a font macro, use its first child instead.
|
||||
*/
|
||||
static void
|
||||
post_TP(CHKARGS)
|
||||
{
|
||||
struct roff_node *nt;
|
||||
|
||||
if (n->type != ROFFT_HEAD || (nt = n->child) == NULL)
|
||||
return;
|
||||
|
||||
while ((nt->flags & NODE_LINE) == 0)
|
||||
if ((nt = nt->next) == NULL)
|
||||
return;
|
||||
|
||||
switch (nt->tok) {
|
||||
case MAN_B:
|
||||
case MAN_BI:
|
||||
case MAN_BR:
|
||||
case MAN_I:
|
||||
case MAN_IB:
|
||||
case MAN_IR:
|
||||
nt = nt->child;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
check_tag(n, nt);
|
||||
}
|
||||
|
||||
static void
|
||||
post_TH(CHKARGS)
|
||||
{
|
||||
|
@ -389,9 +512,14 @@ post_TH(CHKARGS)
|
|||
|
||||
if (n != NULL)
|
||||
n = n->next;
|
||||
if (n != NULL && n->string != NULL)
|
||||
if (n != NULL && n->string != NULL) {
|
||||
man->meta.msec = mandoc_strdup(n->string);
|
||||
else {
|
||||
if (man->filesec != '\0' &&
|
||||
man->filesec != *n->string &&
|
||||
*n->string >= '1' && *n->string <= '9')
|
||||
mandoc_msg(MANDOCERR_MSEC_FILE, n->line, n->pos,
|
||||
"*.%c vs TH ... %c", man->filesec, *n->string);
|
||||
} else {
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
mandoc_msg(MANDOCERR_MSEC_MISSING,
|
||||
nb->line, nb->pos, "TH %s", man->meta.title);
|
||||
|
@ -401,15 +529,10 @@ post_TH(CHKARGS)
|
|||
|
||||
if (n != NULL)
|
||||
n = n->next;
|
||||
if (n != NULL && n->string != NULL && n->string[0] != '\0')
|
||||
man->meta.date = mandoc_normdate(man,
|
||||
n->string, n->line, n->pos);
|
||||
else {
|
||||
if (man->quick && n != NULL)
|
||||
man->meta.date = mandoc_strdup("");
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING,
|
||||
n == NULL ? nb->line : n->line,
|
||||
n == NULL ? nb->pos : n->pos, "TH");
|
||||
}
|
||||
else
|
||||
man->meta.date = mandoc_normdate(n, nb);
|
||||
|
||||
/* TITLE MSEC DATE ->OS<- VOL */
|
||||
|
||||
|
|
10
manconf.h
10
manconf.h
|
@ -1,6 +1,6 @@
|
|||
/* $Id: manconf.h,v 1.7 2018/11/22 11:30:23 schwarze Exp $ */
|
||||
/* $OpenBSD: manconf.h,v 1.7 2018/11/22 11:30:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011,2015,2017,2018,2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -14,6 +14,9 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Public interface to man(1) configuration management.
|
||||
* For use by the main program and by the formatters.
|
||||
*/
|
||||
|
||||
/* List of unique, absolute paths to manual trees. */
|
||||
|
@ -28,15 +31,18 @@ struct manpaths {
|
|||
struct manoutput {
|
||||
char *includes;
|
||||
char *man;
|
||||
char *outfilename;
|
||||
char *paper;
|
||||
char *style;
|
||||
char *tag;
|
||||
char *tagfilename;
|
||||
size_t indent;
|
||||
size_t width;
|
||||
int fragment;
|
||||
int mdoc;
|
||||
int noval;
|
||||
int synopsisonly;
|
||||
int tag_found;
|
||||
int toc;
|
||||
};
|
||||
|
||||
|
|
141
mandoc.1
141
mandoc.1
|
@ -1,7 +1,7 @@
|
|||
.\" $Id: mandoc.1,v 1.240 2019/07/10 19:39:01 schwarze Exp $
|
||||
.\" $OpenBSD: mandoc.1,v 1.166 2020/02/15 15:28:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2012, 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -15,7 +15,7 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 10 2019 $
|
||||
.Dd $Mdocdate: August 14 2021 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -52,13 +52,13 @@ The options are as follows:
|
|||
If the standard output is a terminal device and
|
||||
.Fl c
|
||||
is not specified, use
|
||||
.Xr more 1
|
||||
.Xr less 1
|
||||
to paginate the output, just like
|
||||
.Xr man 1
|
||||
would.
|
||||
.It Fl c
|
||||
Copy the formatted manual pages to the standard output without using
|
||||
.Xr more 1
|
||||
.Xr less 1
|
||||
to paginate them.
|
||||
This is the default.
|
||||
It can be specified to override
|
||||
|
@ -301,8 +301,8 @@ Format
|
|||
input files in
|
||||
.Xr mdoc 7
|
||||
output style.
|
||||
Specifically, this suppresses the two additional blank lines near the
|
||||
top and the bottom of each page, and it implies
|
||||
This prints the operating system name rather than the page title
|
||||
on the right side of the footer line, and it implies
|
||||
.Fl O Cm indent Ns =5 .
|
||||
One useful application is for checking that
|
||||
.Fl T Cm man
|
||||
|
@ -410,6 +410,30 @@ The file
|
|||
is used for an external style-sheet.
|
||||
This must be a valid absolute or
|
||||
relative URI.
|
||||
.It Cm tag Ns Op = Ns Ar term
|
||||
Same syntax and semantics as for
|
||||
.Sx ASCII Output .
|
||||
This is implemented by passing a
|
||||
.Ic file://
|
||||
URI ending in a fragment identifier to the pager
|
||||
rather than passing merely a file name.
|
||||
When using this argument, use a pager supporting such URIs, for example
|
||||
.Bd -literal -offset 3n
|
||||
MANPAGER='lynx -force_html' man -T html -O tag=MANPAGER man
|
||||
MANPAGER='w3m -T text/html' man -T html -O tag=toc mandoc
|
||||
.Ed
|
||||
.Pp
|
||||
Consequently, for HTML output, this argument does not work with
|
||||
.Xr more 1
|
||||
or
|
||||
.Xr less 1 .
|
||||
For example,
|
||||
.Ql MANPAGER=less man -T html -O tag=toc mandoc
|
||||
does not work because
|
||||
.Xr less 1
|
||||
does not support
|
||||
.Ic file://
|
||||
URIs.
|
||||
.It Cm toc
|
||||
If an input file contains at least two non-standard sections,
|
||||
print a table of contents near the beginning of the output.
|
||||
|
@ -443,13 +467,15 @@ This is useful for distributing manual sources to legacy systems
|
|||
lacking
|
||||
.Xr mdoc 7
|
||||
formatters.
|
||||
Embedded
|
||||
.Xr eqn 7
|
||||
and
|
||||
.Xr tbl 7
|
||||
code is not supported.
|
||||
.Pp
|
||||
If the input format of a file is
|
||||
.Xr man 7 ,
|
||||
the input is copied to the output, expanding any
|
||||
.Xr roff 7
|
||||
.Ic so
|
||||
requests.
|
||||
the input is copied to the output.
|
||||
The parser is also run, and as usual, the
|
||||
.Fl W
|
||||
level controls which
|
||||
|
@ -628,7 +654,7 @@ It never affects the interpretation of input files.
|
|||
Any non-empty value of the environment variable
|
||||
.Ev MANPAGER
|
||||
is used instead of the standard pagination program,
|
||||
.Xr more 1 ;
|
||||
.Xr less 1 ;
|
||||
see
|
||||
.Xr man 1
|
||||
for details.
|
||||
|
@ -642,8 +668,7 @@ Specifies the pagination program to use when
|
|||
.Ev MANPAGER
|
||||
is not defined.
|
||||
If neither PAGER nor MANPAGER is defined,
|
||||
.Xr more 1
|
||||
.Fl s
|
||||
.Xr less 1
|
||||
is used.
|
||||
Only used if
|
||||
.Fl a
|
||||
|
@ -897,14 +922,6 @@ generated by CVS
|
|||
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
|
||||
|
@ -991,6 +1008,35 @@ list contains two consecutive
|
|||
entries describing the same
|
||||
.Ic \&Er
|
||||
number.
|
||||
.It Sy "referenced manual not found"
|
||||
.Pq mdoc
|
||||
An
|
||||
.Ic \&Xr
|
||||
macro references a manual page that was not found.
|
||||
When running with
|
||||
.Fl W Cm base ,
|
||||
the search is restricted to the base system, by default to
|
||||
.Pa /usr/share/man : Ns Pa /usr/X11R6/man .
|
||||
This path can be configured at compile time using the
|
||||
.Dv MANPATH_BASE
|
||||
preprocessor macro.
|
||||
When running with
|
||||
.Fl W Cm style ,
|
||||
the search is done along the full search path as described in the
|
||||
.Xr man 1
|
||||
manual page, respecting the
|
||||
.Fl m
|
||||
and
|
||||
.Fl M
|
||||
command line options, the
|
||||
.Ev MANPATH
|
||||
environment variable, the
|
||||
.Xr man.conf 5
|
||||
file and falling back to the default of
|
||||
.Pa /usr/share/man : Ns Pa /usr/X11R6/man : Ns Pa /usr/local/man ,
|
||||
also configurable at compile time using the
|
||||
.Dv MANPATH_DEFAULT
|
||||
preprocessor macro.
|
||||
.It Sy "trailing delimiter"
|
||||
.Pq mdoc
|
||||
The last argument of an
|
||||
|
@ -1020,6 +1066,9 @@ An
|
|||
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 "input text line longer than 80 bytes"
|
||||
Consider breaking the input text line
|
||||
at one of the blank characters before column 80.
|
||||
.It Sy "verbatim \(dq--\(dq, maybe consider using \e(em"
|
||||
.Pq mdoc
|
||||
Even though the ASCII output device renders an em-dash as
|
||||
|
@ -1073,7 +1122,21 @@ macro lacks the mandatory section argument.
|
|||
The section number in a
|
||||
.Ic \&Dt
|
||||
line is invalid, but still used.
|
||||
.It Sy "missing date, using today's date"
|
||||
.It Sy "filename/section mismatch"
|
||||
.Pq mdoc , man
|
||||
The name of the input file being processed is known and its file
|
||||
name extension starts with a non-zero digit, but the
|
||||
.Ic \&Dt
|
||||
or
|
||||
.Ic \&TH
|
||||
macro contains a
|
||||
.Ar section
|
||||
argument that starts with a different non-zero digit.
|
||||
The
|
||||
.Ar section
|
||||
argument is used as provided anyway.
|
||||
Consider checking whether the file name or the argument need a correction.
|
||||
.It Sy "missing date, using \(dq\(dq"
|
||||
.Pq mdoc, man
|
||||
The document was parsed as
|
||||
.Xr mdoc 7
|
||||
|
@ -1811,6 +1874,10 @@ The invalid character is discarded.
|
|||
A table layout specification contains an opening parenthesis,
|
||||
but no matching closing parenthesis.
|
||||
The rest of the input line, starting from the parenthesis, has no effect.
|
||||
.It Sy "ignoring excessive spacing in tbl layout"
|
||||
.Pq tbl
|
||||
A spacing modifier in a table layout is unreasonably large.
|
||||
The default spacing of 3n is used instead.
|
||||
.It Sy "tbl without any data cells"
|
||||
.Pq tbl
|
||||
A table does not contain any data cells.
|
||||
|
@ -2247,6 +2314,26 @@ or
|
|||
macro or of an undefined macro.
|
||||
The macro is ignored, and its arguments are handled
|
||||
as if they were a text line.
|
||||
.It Sy "skipping tbl in -Tman mode"
|
||||
.Pq mdoc , tbl
|
||||
An input file contains the
|
||||
.Ic \&TS
|
||||
macro.
|
||||
This message is only generated in
|
||||
.Fl T Cm man
|
||||
output mode, where
|
||||
.Xr tbl 7
|
||||
input is not supported.
|
||||
.It Sy "skipping eqn in -Tman mode"
|
||||
.Pq mdoc , eqn
|
||||
An input file contains the
|
||||
.Ic \&EQ
|
||||
macro.
|
||||
This message is only generated in
|
||||
.Fl T Cm man
|
||||
output mode, where
|
||||
.Xr eqn 7
|
||||
input is not supported.
|
||||
.El
|
||||
.Ss Bad command line arguments
|
||||
.Bl -ohang
|
||||
|
@ -2284,6 +2371,14 @@ The
|
|||
.Fl O Cm tag
|
||||
option was specified but the tag was not found in any of the displayed
|
||||
manual pages.
|
||||
.It Sy "\-Tmarkdown unsupported for man(7) input"
|
||||
.Pq man
|
||||
The
|
||||
.Fl T Cm markdown
|
||||
option was specified but an input file uses the
|
||||
.Xr man 7
|
||||
language.
|
||||
No output is produced for that input file.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr apropos 1 ,
|
||||
|
|
85
mandoc.c
85
mandoc.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mandoc.c,v 1.116 2019/06/27 15:07:30 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.119 2021/08/10 12:55:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2015, 2017-2021 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
|
||||
|
@ -74,12 +74,12 @@ mandoc_font(const char *cp, int sz)
|
|||
case 'C':
|
||||
switch (cp[1]) {
|
||||
case 'B':
|
||||
return ESCAPE_FONTBOLD;
|
||||
return ESCAPE_FONTCB;
|
||||
case 'I':
|
||||
return ESCAPE_FONTITALIC;
|
||||
return ESCAPE_FONTCI;
|
||||
case 'R':
|
||||
case 'W':
|
||||
return ESCAPE_FONTCW;
|
||||
return ESCAPE_FONTCR;
|
||||
default:
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
|
@ -203,7 +203,18 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||
case 'O':
|
||||
case 'V':
|
||||
case 'Y':
|
||||
gly = (*start)[-1] == 'f' ? ESCAPE_FONT : ESCAPE_IGNORE;
|
||||
case '*':
|
||||
switch ((*start)[-1]) {
|
||||
case 'f':
|
||||
gly = ESCAPE_FONT;
|
||||
break;
|
||||
case '*':
|
||||
gly = ESCAPE_DEVICE;
|
||||
break;
|
||||
default:
|
||||
gly = ESCAPE_IGNORE;
|
||||
break;
|
||||
}
|
||||
switch (**start) {
|
||||
case '(':
|
||||
if ((*start)[-1] == 'O')
|
||||
|
@ -238,13 +249,6 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
if (strncmp(*start, "(.T", 3) != 0)
|
||||
abort();
|
||||
gly = ESCAPE_DEVICE;
|
||||
*start = ++*end;
|
||||
*sz = 2;
|
||||
break;
|
||||
|
||||
/*
|
||||
* These escapes are of the form \X'Y', where 'X' is the trigger
|
||||
|
@ -459,6 +463,9 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
|||
+ 1 == *sz)
|
||||
gly = ESCAPE_UNICODE;
|
||||
break;
|
||||
case ESCAPE_DEVICE:
|
||||
assert(*sz == 2 && (*start)[0] == '.' && (*start)[1] == 'T');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -536,45 +543,59 @@ time2a(time_t t)
|
|||
}
|
||||
|
||||
char *
|
||||
mandoc_normdate(struct roff_man *man, char *in, int ln, int pos)
|
||||
mandoc_normdate(struct roff_node *nch, struct roff_node *nbl)
|
||||
{
|
||||
char *cp;
|
||||
time_t t;
|
||||
|
||||
if (man->quick)
|
||||
return mandoc_strdup(in == NULL ? "" : in);
|
||||
/* No date specified. */
|
||||
|
||||
/* No date specified: use today's date. */
|
||||
|
||||
if (in == NULL || *in == '\0')
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, ln, pos, NULL);
|
||||
if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0)
|
||||
if (nch == NULL) {
|
||||
if (nbl == NULL)
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, 0, 0, NULL);
|
||||
else
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, nbl->line,
|
||||
nbl->pos, "%s", roff_name[nbl->tok]);
|
||||
return mandoc_strdup("");
|
||||
}
|
||||
if (*nch->string == '\0') {
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, nch->line,
|
||||
nch->pos, "%s", roff_name[nbl->tok]);
|
||||
return mandoc_strdup("");
|
||||
}
|
||||
if (strcmp(nch->string, "$" "Mdocdate$") == 0)
|
||||
return time2a(time(NULL));
|
||||
|
||||
/* Valid mdoc(7) date format. */
|
||||
|
||||
if (a2time(&t, "$" "Mdocdate: %b %d %Y $", in) ||
|
||||
a2time(&t, "%b %d, %Y", in)) {
|
||||
if (a2time(&t, "$" "Mdocdate: %b %d %Y $", nch->string) ||
|
||||
a2time(&t, "%b %d, %Y", nch->string)) {
|
||||
cp = time2a(t);
|
||||
if (t > time(NULL) + 86400)
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, ln, pos, "%s", cp);
|
||||
else if (*in != '$' && strcmp(in, cp) != 0)
|
||||
mandoc_msg(MANDOCERR_DATE_NORM, ln, pos, "%s", cp);
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, nch->line,
|
||||
nch->pos, "%s %s", roff_name[nbl->tok], cp);
|
||||
else if (*nch->string != '$' &&
|
||||
strcmp(nch->string, cp) != 0)
|
||||
mandoc_msg(MANDOCERR_DATE_NORM, nch->line,
|
||||
nch->pos, "%s %s", roff_name[nbl->tok], cp);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* In man(7), do not warn about the legacy format. */
|
||||
|
||||
if (a2time(&t, "%Y-%m-%d", in) == 0)
|
||||
mandoc_msg(MANDOCERR_DATE_BAD, ln, pos, "%s", in);
|
||||
if (a2time(&t, "%Y-%m-%d", nch->string) == 0)
|
||||
mandoc_msg(MANDOCERR_DATE_BAD, nch->line, nch->pos,
|
||||
"%s %s", roff_name[nbl->tok], nch->string);
|
||||
else if (t > time(NULL) + 86400)
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, ln, pos, "%s", in);
|
||||
else if (man->meta.macroset == MACROSET_MDOC)
|
||||
mandoc_msg(MANDOCERR_DATE_LEGACY, ln, pos, "Dd %s", in);
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, nch->line, nch->pos,
|
||||
"%s %s", roff_name[nbl->tok], nch->string);
|
||||
else if (nbl->tok == MDOC_Dd)
|
||||
mandoc_msg(MANDOCERR_DATE_LEGACY, nch->line, nch->pos,
|
||||
"Dd %s", nch->string);
|
||||
|
||||
/* Use any non-mdoc(7) date verbatim. */
|
||||
|
||||
return mandoc_strdup(in);
|
||||
return mandoc_strdup(nch->string);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mandoc.css,v 1.46 2019/06/02 16:57:13 schwarze Exp $ */
|
||||
/* $Id: mandoc.css,v 1.48 2021/03/30 19:26:20 schwarze Exp $ */
|
||||
/*
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*
|
||||
|
@ -31,6 +31,7 @@ td { vertical-align: top;
|
|||
ul, ol, dl { margin-top: 0em;
|
||||
margin-bottom: 0em; }
|
||||
li, dt { margin-top: 1em; }
|
||||
pre { font-family: inherit; }
|
||||
|
||||
.permalink { border-bottom: thin dotted;
|
||||
color: inherit;
|
||||
|
@ -135,12 +136,12 @@ h2.Ss { margin-top: 1.2em;
|
|||
vertical-align: top; }
|
||||
.Bl-tag > dd {
|
||||
clear: right;
|
||||
column-count: 1; /* Force block formatting context. */
|
||||
width: 100%;
|
||||
margin-top: 0em;
|
||||
margin-left: 0em;
|
||||
margin-bottom: 0.6em;
|
||||
vertical-align: top;
|
||||
overflow: auto; }
|
||||
vertical-align: top; }
|
||||
.Bl-compact { margin-top: 0em; }
|
||||
.Bl-compact > dd {
|
||||
margin-bottom: 0em; }
|
||||
|
|
22
mandoc.h
22
mandoc.h
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mandoc.h,v 1.264 2019/07/14 18:16:13 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.274 2021/08/14 13:53:08 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012-2019 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
|
||||
|
@ -16,6 +16,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Error handling, escape sequence, and character utilities.
|
||||
* Can be used by all code in the mandoc package.
|
||||
*/
|
||||
|
||||
#define ASCII_NBRSP 31 /* non-breaking space */
|
||||
|
@ -53,7 +54,6 @@ enum mandocerr {
|
|||
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 ===== */
|
||||
|
||||
|
@ -67,10 +67,12 @@ enum mandocerr {
|
|||
MANDOCERR_BX, /* consider using OS macro: macro */
|
||||
MANDOCERR_ER_ORDER, /* errnos out of order: Er ... */
|
||||
MANDOCERR_ER_REP, /* duplicate errno: Er ... */
|
||||
MANDOCERR_XR_BAD, /* referenced manual not found: Xr name sec */
|
||||
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_TEXT_LONG, /* input text line longer than 80 bytes */
|
||||
MANDOCERR_DASHDASH, /* verbatim "--", maybe consider using \(em */
|
||||
MANDOCERR_FUNC, /* function name without markup: name() */
|
||||
MANDOCERR_SPACE_EOL, /* whitespace at end of input line */
|
||||
|
@ -83,7 +85,8 @@ enum mandocerr {
|
|||
MANDOCERR_TH_NOTITLE, /* missing manual title, using "": [macro] */
|
||||
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_MSEC_FILE, /* filename/section mismatch: ... */
|
||||
MANDOCERR_DATE_MISSING, /* missing date, using "": [macro] */
|
||||
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 "" */
|
||||
|
@ -187,6 +190,7 @@ enum mandocerr {
|
|||
MANDOCERR_TBLLAYOUT_NONE, /* empty tbl layout */
|
||||
MANDOCERR_TBLLAYOUT_CHAR, /* invalid character in tbl layout: char */
|
||||
MANDOCERR_TBLLAYOUT_PAR, /* unmatched parenthesis in tbl layout */
|
||||
MANDOCERR_TBLLAYOUT_SPC, /* ignoring excessive spacing in tbl layout */
|
||||
MANDOCERR_TBLDATA_NONE, /* tbl without any data cells */
|
||||
MANDOCERR_TBLDATA_SPAN, /* ignoring data in spanned tbl cell: data */
|
||||
MANDOCERR_TBLDATA_EXTRA, /* ignoring extra tbl data cells: data */
|
||||
|
@ -223,6 +227,7 @@ enum mandocerr {
|
|||
MANDOCERR_SHIFT, /* excessive shift: ..., but max is ... */
|
||||
MANDOCERR_SO_PATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
||||
MANDOCERR_SO_FAIL, /* .so request failed */
|
||||
MANDOCERR_TG_SPC, /* skipping tag containing whitespace: tag */
|
||||
MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */
|
||||
MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */
|
||||
MANDOCERR_DIVZERO, /* divide by zero */
|
||||
|
@ -240,6 +245,8 @@ enum mandocerr {
|
|||
MANDOCERR_TBLOPT_EQN, /* eqn delim option in tbl: arg */
|
||||
MANDOCERR_TBLLAYOUT_MOD, /* unsupported tbl layout modifier: m */
|
||||
MANDOCERR_TBLMACRO, /* ignoring macro in table: macro */
|
||||
MANDOCERR_TBL_TMAN, /* skipping tbl in -Tman mode */
|
||||
MANDOCERR_EQN_TMAN, /* skipping eqn in -Tman mode */
|
||||
|
||||
MANDOCERR_BADARG, /* ===== start of bad invocations ===== */
|
||||
|
||||
|
@ -250,6 +257,7 @@ enum mandocerr {
|
|||
MANDOCERR_BADVAL_BAD, /* bad argument value */
|
||||
MANDOCERR_BADVAL_DUPE, /* duplicate argument value */
|
||||
MANDOCERR_TAG, /* no such tag */
|
||||
MANDOCERR_MAN_TMARKDOWN, /* -Tmarkdown unsupported for man(7) input */
|
||||
|
||||
MANDOCERR_SYSERR, /* ===== start of system errors ===== */
|
||||
|
||||
|
@ -284,7 +292,9 @@ enum mandoc_esc {
|
|||
ESCAPE_FONTITALIC, /* italic font mode */
|
||||
ESCAPE_FONTBI, /* bold italic font mode */
|
||||
ESCAPE_FONTROMAN, /* roman font mode */
|
||||
ESCAPE_FONTCW, /* constant width font mode */
|
||||
ESCAPE_FONTCR, /* constant width font mode */
|
||||
ESCAPE_FONTCB, /* constant width bold font mode */
|
||||
ESCAPE_FONTCI, /* constant width italic font mode */
|
||||
ESCAPE_FONTPREV, /* previous font mode */
|
||||
ESCAPE_NUMBERED, /* a numbered glyph */
|
||||
ESCAPE_UNICODE, /* a unicode codepoint */
|
||||
|
@ -298,7 +308,7 @@ enum mandoc_esc {
|
|||
};
|
||||
|
||||
|
||||
enum mandoc_esc mandoc_font(const char *, int sz);
|
||||
enum mandoc_esc mandoc_font(const char *, int);
|
||||
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
||||
void mandoc_msg_setoutfile(FILE *);
|
||||
const char *mandoc_msg_getinfilename(void);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.\" $Id: mandoc_char.7,v 1.76 2019/03/31 19:17:26 schwarze Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.78 2020/10/31 11:45:16 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011,2013,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011,2013,2015,2017-2020 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
|
||||
|
@ -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: March 31 2019 $
|
||||
.Dd $Mdocdate: October 31 2020 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -261,15 +261,15 @@ subsection of the
|
|||
.Xr roff 7
|
||||
manual.
|
||||
.Pp
|
||||
Spacing:
|
||||
Spaces, non-breaking unless stated otherwise:
|
||||
.Bl -column "Input" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Description
|
||||
.It Sq \e\ \& Ta unpaddable non-breaking space
|
||||
.It \e\(ti Ta paddable non-breaking space
|
||||
.It \e0 Ta digit-width space allowing line break
|
||||
.It Sq \e\ \& Ta unpaddable space
|
||||
.It \e\(ti Ta paddable space
|
||||
.It \e0 Ta digit-width space
|
||||
.It \e| Ta one-sixth \e(em narrow space, zero width in nroff mode
|
||||
.It \e^ Ta one-twelfth \e(em half-narrow space, zero width in nroff
|
||||
.It \e& Ta zero-width non-breaking space
|
||||
.It \e& Ta zero-width space
|
||||
.It \e) Ta zero-width space transparent to end-of-sentence detection
|
||||
.It \e% Ta zero-width space allowing hyphenation
|
||||
.It \e: Ta zero-width space allowing line break
|
||||
|
@ -709,11 +709,6 @@ Their syntax is similar to special characters, using
|
|||
and
|
||||
.Sq \e*[N]
|
||||
.Pq N-character .
|
||||
For details, see the
|
||||
.Em Predefined Strings
|
||||
subsection of the
|
||||
.Xr roff 7
|
||||
manual.
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e*(Ba Ta \*(Ba Ta vertical bar
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" $Id: mandoc_headers.3,v 1.31 2019/03/17 18:21:45 schwarze Exp $
|
||||
.\" $Id: mandoc_headers.3,v 1.34 2021/08/10 12:55:03 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,7 +14,7 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: March 17 2019 $
|
||||
.Dd $Mdocdate: August 10 2021 $
|
||||
.Dt MANDOC_HEADERS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -167,7 +167,11 @@ parse tree; can be used everywhere.
|
|||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Vt size_t
|
||||
and
|
||||
.Qq Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandoc_esc .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum tbl_cellt ,
|
||||
|
@ -232,6 +236,30 @@ and the functions
|
|||
.Fn mandoc_xr_get ,
|
||||
and
|
||||
.Fn mandoc_xr_free .
|
||||
.It Qq Pa tag.h
|
||||
Internal interfaces to tag syntax tree nodes,
|
||||
for use by validation modules only.
|
||||
.Pp
|
||||
Requires
|
||||
.In limits.h
|
||||
for
|
||||
.Dv INT_MAX .
|
||||
.Pp
|
||||
Provides the functions
|
||||
.Fn tag_alloc ,
|
||||
.Fn tag_put ,
|
||||
.Fn tag_check ,
|
||||
and
|
||||
.Fn tag_free
|
||||
and some
|
||||
.Dv TAG_*
|
||||
constants.
|
||||
.Pp
|
||||
Uses the type
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Qq Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.El
|
||||
.Pp
|
||||
The following two require
|
||||
|
@ -587,6 +615,33 @@ When this header is included, the same file should not include
|
|||
.Qq Pa html.h
|
||||
or
|
||||
.Qq Pa mansearch.h .
|
||||
.It Qq Pa tag_term.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t
|
||||
and
|
||||
.In stdio.h
|
||||
for
|
||||
.Vt FILE .
|
||||
.Pp
|
||||
Provides an interface to generate
|
||||
.Xr ctags 1
|
||||
files for the
|
||||
.Ic :t
|
||||
functionality mentioned in
|
||||
.Xr man 1 .
|
||||
.Pp
|
||||
Uses the type
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Qq Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Qq Pa html.h
|
||||
or
|
||||
.Qq Pa mansearch.h .
|
||||
.It Qq Pa html.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
|
@ -629,21 +684,10 @@ from
|
|||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Qq Pa term.h
|
||||
.Qq Pa term.h ,
|
||||
.Qq Pa tab_term.h ,
|
||||
or
|
||||
.Qq Pa mansearch.h .
|
||||
.It Qq Pa tag.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides an interface to generate
|
||||
.Xr ctags 1
|
||||
files for the
|
||||
.Ic :t
|
||||
functionality mentioned in
|
||||
.Xr man 1 .
|
||||
.It Qq Pa main.h
|
||||
Provides the top level steering functions for all formatters.
|
||||
.Pp
|
||||
|
@ -696,6 +740,7 @@ as an opaque type for function prototypes.
|
|||
When this header is included, the same file should not include
|
||||
.Qq Pa out.h ,
|
||||
.Qq Pa term.h ,
|
||||
.Qq Pa tab_term.h ,
|
||||
or
|
||||
.Qq Pa html.h .
|
||||
.El
|
||||
|
|
272
mandoc_html.3
272
mandoc_html.3
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: mandoc_html.3,v 1.19 2019/01/11 12:56:43 schwarze Exp $
|
||||
.\" $Id: mandoc_html.3,v 1.23 2020/04/24 13:13:06 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
|
@ -14,14 +14,18 @@
|
|||
.\" 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 11 2019 $
|
||||
.Dd $Mdocdate: April 24 2020 $
|
||||
.Dt MANDOC_HTML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc_html
|
||||
.Nd internals of the mandoc HTML formatter
|
||||
.Sh SYNOPSIS
|
||||
.In "html.h"
|
||||
.In sys/types.h
|
||||
.Fd #include """mandoc.h"""
|
||||
.Fd #include """roff.h"""
|
||||
.Fd #include """out.h"""
|
||||
.Fd #include """html.h"""
|
||||
.Ft void
|
||||
.Fn print_gen_decls "struct html *h"
|
||||
.Ft void
|
||||
|
@ -46,18 +50,42 @@
|
|||
.Fa "const struct tag *suntil"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn html_close_paragraph "struct html *h"
|
||||
.Ft enum roff_tok
|
||||
.Fo html_fillmode
|
||||
.Fa "struct html *h"
|
||||
.Fa "enum roff_tok tok"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo html_setfont
|
||||
.Fa "struct html *h"
|
||||
.Fa "enum mandoc_esc font"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo print_text
|
||||
.Fa "struct html *h"
|
||||
.Fa "const char *word"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo print_tagged_text
|
||||
.Fa "struct html *h"
|
||||
.Fa "const char *word"
|
||||
.Fa "struct roff_node *n"
|
||||
.Fc
|
||||
.Ft char *
|
||||
.Fo html_make_id
|
||||
.Fa "const struct roff_node *n"
|
||||
.Fa "int unique"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo html_strlen
|
||||
.Fa "const char *cp"
|
||||
.Ft struct tag *
|
||||
.Fo print_otag_id
|
||||
.Fa "struct html *h"
|
||||
.Fa "enum htmltag tag"
|
||||
.Fa "const char *cattr"
|
||||
.Fa "struct roff_node *n"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn print_endline "struct html *h"
|
||||
.Sh DESCRIPTION
|
||||
The mandoc HTML formatter is not a formal library.
|
||||
However, as it is compiled into more than one program, in particular
|
||||
|
@ -96,7 +124,7 @@ These structures are declared in
|
|||
Internal state of the HTML formatter.
|
||||
.It Vt struct tag
|
||||
One entry for the LIFO stack of HTML elements.
|
||||
Members are
|
||||
Members include
|
||||
.Fa "enum htmltag tag"
|
||||
and
|
||||
.Fa "struct tag *next" .
|
||||
|
@ -105,10 +133,8 @@ and
|
|||
The function
|
||||
.Fn print_gen_decls
|
||||
prints the opening
|
||||
.Ao Pf \&? Ic xml ? Ac
|
||||
and
|
||||
.Aq Pf \&! Ic DOCTYPE
|
||||
declarations required for the current document type.
|
||||
declaration.
|
||||
.Pp
|
||||
The function
|
||||
.Fn print_gen_comment
|
||||
|
@ -235,6 +261,59 @@ is used to close out all open elements up to and including
|
|||
.Fn print_stagq
|
||||
is a variant to close out all open elements up to but excluding
|
||||
.Fa suntil .
|
||||
The function
|
||||
.Fn html_close_paragraph
|
||||
closes all open elements that establish phrasing context,
|
||||
thus returning to the innermost flow context.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_fillmode
|
||||
switches to fill mode if
|
||||
.Fa want
|
||||
is
|
||||
.Dv ROFF_fi
|
||||
or to no-fill mode if
|
||||
.Fa want
|
||||
is
|
||||
.Dv ROFF_nf .
|
||||
Switching from fill mode to no-fill mode closes the current paragraph
|
||||
and opens a
|
||||
.Aq Ic PRE
|
||||
element.
|
||||
Switching in the opposite direction closes the
|
||||
.Aq Ic PRE
|
||||
element, but does not open a new paragraph.
|
||||
If
|
||||
.Fa want
|
||||
matches the mode that is already active, no elements are closed nor opened.
|
||||
If
|
||||
.Fa want
|
||||
is
|
||||
.Dv TOKEN_NONE ,
|
||||
the mode remains as it is.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_setfont
|
||||
selects the
|
||||
.Fa font ,
|
||||
which can be
|
||||
.Dv ESCAPE_FONTROMAN ,
|
||||
.Dv ESCAPE_FONTBOLD ,
|
||||
.Dv ESCAPE_FONTITALIC ,
|
||||
.Dv ESCAPE_FONTBI ,
|
||||
or
|
||||
.Dv ESCAPE_FONTCW ,
|
||||
for future text output and internally remembers
|
||||
the font that was active before the change.
|
||||
If the
|
||||
.Fa font
|
||||
argument is
|
||||
.Dv ESCAPE_FONTPREV ,
|
||||
the current and the previous font are exchanged.
|
||||
This function only changes the internal state of the
|
||||
.Fa h
|
||||
object; no HTML elements are written yet.
|
||||
Subsequent text output will write font elements when needed.
|
||||
.Pp
|
||||
The function
|
||||
.Fn print_text
|
||||
|
@ -256,24 +335,118 @@ and
|
|||
functions.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_make_id
|
||||
takes a node containing one or more text children
|
||||
and returns a newly allocated string containing the concatenation
|
||||
of the child strings, with blanks replaced by underscores.
|
||||
If the node
|
||||
.Fn print_tagged_text
|
||||
is a variant of
|
||||
.Fn print_text
|
||||
that wraps
|
||||
.Fa word
|
||||
in an
|
||||
.Aq Ic A
|
||||
element of class
|
||||
.Qq permalink
|
||||
if
|
||||
.Fa n
|
||||
contains any non-text child node,
|
||||
.Fn html_make_id
|
||||
returns
|
||||
is not
|
||||
.Dv NULL
|
||||
instead.
|
||||
The caller is responsible for freeing the returned string.
|
||||
and yields a segment identifier when passed to
|
||||
.Fn html_make_id .
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_strlen
|
||||
counts the number of characters in
|
||||
.Fa cp .
|
||||
It is used as a crude estimate of the width needed to display a string.
|
||||
.Fn html_make_id
|
||||
allocates a string to be used for the
|
||||
.Cm id
|
||||
attribute of an HTML element and/or as a segment identifier for a URI in an
|
||||
.Aq Ic A
|
||||
element.
|
||||
If
|
||||
.Fa n
|
||||
contains a
|
||||
.Fa tag
|
||||
attribute, it is used; otherwise, child nodes are used.
|
||||
If
|
||||
.Fa n
|
||||
is an
|
||||
.Ic \&Sh ,
|
||||
.Ic \&Ss ,
|
||||
.Ic \&Sx ,
|
||||
.Ic SH ,
|
||||
or
|
||||
.Ic SS
|
||||
node, the resulting string is the concatenation of the child strings;
|
||||
for other node types, only the first child is used.
|
||||
Bytes not permitted in URI-fragment strings are replaced by underscores.
|
||||
If any of the children to be used is not a text node,
|
||||
no string is generated and
|
||||
.Dv NULL
|
||||
is returned instead.
|
||||
If the
|
||||
.Fa unique
|
||||
argument is non-zero, deduplication is performed by appending an
|
||||
underscore and a decimal integer, if necessary.
|
||||
If the
|
||||
.Fa unique
|
||||
argument is 1, this is assumed to be the first call for this tag
|
||||
at this location, typically for use by
|
||||
.Dv NODE_ID ,
|
||||
so the integer is incremented before use.
|
||||
If the
|
||||
.Fa unique
|
||||
argument is 2, this is ssumed to be the second call for this tag
|
||||
at this location, typically for use by
|
||||
.Dv NODE_HREF ,
|
||||
so the existing integer, if any, is used without incrementing it.
|
||||
.Pp
|
||||
The function
|
||||
.Fn print_otag_id
|
||||
opens a
|
||||
.Fa tag
|
||||
element of class
|
||||
.Fa cattr
|
||||
for the node
|
||||
.Fa n .
|
||||
If the flag
|
||||
.Dv NODE_ID
|
||||
is set in
|
||||
.Fa n ,
|
||||
it attempts to generate an
|
||||
.Cm id
|
||||
attribute with
|
||||
.Fn html_make_id .
|
||||
If the flag
|
||||
.Dv NODE_HREF
|
||||
is set in
|
||||
.Fa n ,
|
||||
an
|
||||
.Aq Ic A
|
||||
element of class
|
||||
.Qq permalink
|
||||
is added:
|
||||
outside if
|
||||
.Fa n
|
||||
generates an element that can only occur in phrasing context,
|
||||
or inside otherwise.
|
||||
This function is a wrapper around
|
||||
.Fn html_make_id
|
||||
and
|
||||
.Fn print_otag ,
|
||||
automatically chosing the
|
||||
.Fa unique
|
||||
argument appropriately and setting the
|
||||
.Fa fmt
|
||||
arguments to
|
||||
.Qq chR
|
||||
and
|
||||
.Qq ci ,
|
||||
respectively.
|
||||
.Pp
|
||||
The function
|
||||
.Fn print_endline
|
||||
makes sure subsequent output starts on a new HTML output line.
|
||||
If nothing was printed on the current output line yet, it has no effect.
|
||||
Otherwise, it appends any buffered text to the current output line,
|
||||
ends the line, and updates the internal state of the
|
||||
.Fa h
|
||||
object.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn print_eqn ,
|
||||
|
@ -281,6 +454,46 @@ The functions
|
|||
and
|
||||
.Fn print_tblclose
|
||||
are not yet documented.
|
||||
.Sh RETURN VALUES
|
||||
The functions
|
||||
.Fn print_otag
|
||||
and
|
||||
.Fn print_otag_id
|
||||
return a pointer to a new element on the stack of HTML elements.
|
||||
When
|
||||
.Fn print_otag_id
|
||||
opens two elements, a pointer to the outer one is returned.
|
||||
The memory pointed to is owned by the library and is automatically
|
||||
.Xr free 3 Ns d
|
||||
when
|
||||
.Fn print_tagq
|
||||
is called on it or when
|
||||
.Fn print_stagq
|
||||
is called on a parent element.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_fillmode
|
||||
returns
|
||||
.Dv ROFF_fi
|
||||
if fill mode was active before the call or
|
||||
.Dv ROFF_nf
|
||||
otherwise.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_make_id
|
||||
returns a newly allocated string or
|
||||
.Dv NULL
|
||||
if
|
||||
.Fa n
|
||||
lacks text data to create the attribute from.
|
||||
The caller is responsible for
|
||||
.Xr free 3 Ns ing
|
||||
the returned string after using it.
|
||||
.Pp
|
||||
In case of
|
||||
.Xr malloc 3
|
||||
failure, these functions do not return but call
|
||||
.Xr err 3 .
|
||||
.Sh FILES
|
||||
.Bl -tag -width mandoc_aux.c -compact
|
||||
.It Pa main.h
|
||||
|
@ -303,6 +516,17 @@ HTML formatter
|
|||
.It Pa eqn_html.c
|
||||
.Xr eqn 7
|
||||
HTML formatter
|
||||
.It Pa roff_html.c
|
||||
.Xr roff 7
|
||||
HTML formatter, handling requests like
|
||||
.Ic br ,
|
||||
.Ic ce ,
|
||||
.Ic fi ,
|
||||
.Ic ft ,
|
||||
.Ic nf ,
|
||||
.Ic rj ,
|
||||
and
|
||||
.Ic sp .
|
||||
.It Pa out.h
|
||||
declarations of data types and private functions
|
||||
for shared use by all mandoc formatters,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: mandoc_malloc.3,v 1.2 2016/07/07 19:19:01 schwarze Exp $
|
||||
.\" $Id: mandoc_malloc.3,v 1.3 2021/09/17 18:50:21 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: July 7 2016 $
|
||||
.Dd $Mdocdate: September 17 2021 $
|
||||
.Dt MANDOC_MALLOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -22,6 +22,7 @@
|
|||
.Nm mandoc_realloc ,
|
||||
.Nm mandoc_reallocarray ,
|
||||
.Nm mandoc_calloc ,
|
||||
.Nm mandoc_recallocarray ,
|
||||
.Nm mandoc_strdup ,
|
||||
.Nm mandoc_strndup ,
|
||||
.Nm mandoc_asprintf
|
||||
|
@ -49,6 +50,13 @@
|
|||
.Fa "size_t nmemb"
|
||||
.Fa "size_t size"
|
||||
.Fc
|
||||
.Ft "void *"
|
||||
.Fo mandoc_recallocarray
|
||||
.Fa "void *ptr"
|
||||
.Fa "size_t oldnmemb"
|
||||
.Fa "size_t nmemb"
|
||||
.Fa "size_t size"
|
||||
.Fc
|
||||
.Ft "char *"
|
||||
.Fo mandoc_strdup
|
||||
.Fa "const char *s"
|
||||
|
@ -82,12 +90,15 @@ The function
|
|||
.Fn mandoc_malloc
|
||||
allocates one new object, leaving the memory uninitialized.
|
||||
The functions
|
||||
.Fn mandoc_realloc
|
||||
.Fn mandoc_realloc ,
|
||||
.Fn mandoc_reallocarray ,
|
||||
and
|
||||
.Fn mandoc_reallocarray
|
||||
.Fn mandoc_recallocarray
|
||||
change the size of an existing object or array, possibly moving it.
|
||||
When shrinking the size, existing data is truncated; when growing,
|
||||
the additional memory is not initialized.
|
||||
only
|
||||
.Fn mandoc_recallocarray
|
||||
initializes the new elements to zero.
|
||||
The function
|
||||
.Fn mandoc_calloc
|
||||
allocates a new array, initializing it to zero.
|
||||
|
@ -99,6 +110,9 @@ The argument
|
|||
.Fa nmemb
|
||||
is the new number of objects in the array.
|
||||
The argument
|
||||
.Fa oldnmemb
|
||||
is the number of objects in the array before the call.
|
||||
The argument
|
||||
.Fa ptr
|
||||
is a pointer to the existing object or array to be resized; if it is
|
||||
.Dv NULL ,
|
||||
|
@ -168,9 +182,13 @@ is a widespread extension that first appeared in the GNU C library.
|
|||
The function
|
||||
.Fn reallocarray
|
||||
is an extension that first appeared in
|
||||
.Ox 5.6 .
|
||||
If it is not provided by the operating system, the mandoc build system
|
||||
uses a bundled portable implementation.
|
||||
.Ox 5.6 ,
|
||||
and
|
||||
.Fn recallocarray
|
||||
in
|
||||
.Ox 6.1 .
|
||||
If these two are not provided by the operating system,
|
||||
the mandoc build system uses bundled portable implementations.
|
||||
.Sh HISTORY
|
||||
The functions
|
||||
.Fn mandoc_malloc ,
|
||||
|
@ -181,11 +199,12 @@ and
|
|||
have been available since mandoc 1.9.12,
|
||||
.Fn mandoc_strndup
|
||||
since 1.11.5,
|
||||
and
|
||||
.Fn mandoc_asprintf
|
||||
and
|
||||
since 1.12.4,
|
||||
.Fn mandoc_reallocarray
|
||||
since 1.12.4 and 1.13.0.
|
||||
since 1.13.0, and
|
||||
.Fn mandoc_recallocarray
|
||||
since 1.14.2.
|
||||
.Sh AUTHORS
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
||||
|
|
17
mandoc_msg.c
17
mandoc_msg.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mandoc_msg.c,v 1.8 2019/07/14 18:16:13 schwarze Exp $ */
|
||||
/* $OpenBSD: mandoc_msg.c,v 1.8 2020/01/19 17:59:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Implementation of warning and error messages for mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -53,7 +55,6 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"unknown architecture",
|
||||
"operating system explicitly specified",
|
||||
"RCS id missing",
|
||||
"referenced manual not found",
|
||||
|
||||
"generic style suggestion",
|
||||
|
||||
|
@ -67,10 +68,12 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"consider using OS macro",
|
||||
"errnos out of order",
|
||||
"duplicate errno",
|
||||
"referenced manual not found",
|
||||
"trailing delimiter",
|
||||
"no blank before trailing delimiter",
|
||||
"fill mode already enabled, skipping",
|
||||
"fill mode already disabled, skipping",
|
||||
"input text line longer than 80 bytes",
|
||||
"verbatim \"--\", maybe consider using \\(em",
|
||||
"function name without markup",
|
||||
"whitespace at end of input line",
|
||||
|
@ -83,7 +86,8 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"missing manual title, using \"\"",
|
||||
"missing manual section, using \"\"",
|
||||
"unknown manual section",
|
||||
"missing date, using today's date",
|
||||
"filename/section mismatch",
|
||||
"missing date, using \"\"",
|
||||
"cannot parse date, using it verbatim",
|
||||
"date in the future, using it anyway",
|
||||
"missing Os macro, using \"\"",
|
||||
|
@ -187,6 +191,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"empty tbl layout",
|
||||
"invalid character in tbl layout",
|
||||
"unmatched parenthesis in tbl layout",
|
||||
"ignoring excessive spacing in tbl layout",
|
||||
"tbl without any data cells",
|
||||
"ignoring data in spanned tbl cell",
|
||||
"ignoring extra tbl data cells",
|
||||
|
@ -223,6 +228,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"excessive shift",
|
||||
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
||||
".so request failed",
|
||||
"skipping tag containing whitespace",
|
||||
"skipping all arguments",
|
||||
"skipping excess arguments",
|
||||
"divide by zero",
|
||||
|
@ -239,6 +245,8 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"eqn delim option in tbl",
|
||||
"unsupported tbl layout modifier",
|
||||
"ignoring macro in table",
|
||||
"skipping tbl in -Tman mode",
|
||||
"skipping eqn in -Tman mode",
|
||||
|
||||
/* bad command line arguments */
|
||||
NULL,
|
||||
|
@ -249,6 +257,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
|||
"bad option value",
|
||||
"duplicate option value",
|
||||
"no such tag",
|
||||
"-Tmarkdown unsupported for man(7) input",
|
||||
|
||||
/* system errors */
|
||||
NULL,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mandoc_ohash.c,v 1.2 2015/10/19 18:58:47 schwarze Exp $ */
|
||||
/* $Id: mandoc_ohash.c,v 1.3 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -14,6 +14,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mandoc_parse.h,v 1.4 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/* $Id: mandoc_parse.h,v 1.5 2019/11/09 14:39:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -29,6 +29,7 @@
|
|||
#define MPARSE_UTF8 (1 << 4) /* accept UTF-8 input */
|
||||
#define MPARSE_LATIN1 (1 << 5) /* accept ISO-LATIN-1 input */
|
||||
#define MPARSE_VALIDATE (1 << 6) /* call validation functions */
|
||||
#define MPARSE_COMMENT (1 << 7) /* save comments in the tree */
|
||||
|
||||
|
||||
struct roff_meta;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mandoc_xr.c,v 1.3 2017/07/02 21:18:29 schwarze Exp $ */
|
||||
/* $Id: mandoc_xr.c,v 1.4 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -14,6 +14,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mandocd.c,v 1.11 2019/03/03 13:02:11 schwarze Exp $ */
|
||||
/* $Id: mandocd.c,v 1.12 2020/06/14 23:40:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
* Copyright (c) 2017, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_CMSG_XPG42
|
||||
#if NEED_XPG4_2
|
||||
#define _XPG4_2
|
||||
#endif
|
||||
|
||||
|
|
247
mandocdb.c
247
mandocdb.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mandocdb.c,v 1.263 2019/05/03 18:17:12 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.269 2021/08/19 16:55:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -15,6 +15,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Implementation of the makewhatis(8) program.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -118,7 +120,7 @@ struct mdoc_handler {
|
|||
int mandocdb(int, char *[]);
|
||||
|
||||
static void dbadd(struct dba *, struct mpage *);
|
||||
static void dbadd_mlink(const struct mlink *mlink);
|
||||
static void dbadd_mlink(const struct mlink *);
|
||||
static void dbprune(struct dba *);
|
||||
static void dbwrite(struct dba *);
|
||||
static void filescan(const char *);
|
||||
|
@ -163,6 +165,9 @@ static void putkey(const struct mpage *, char *, uint64_t);
|
|||
static void putkeys(const struct mpage *, char *, size_t, uint64_t);
|
||||
static void putmdockey(const struct mpage *,
|
||||
const struct roff_node *, uint64_t, int);
|
||||
#ifdef READ_ALLOWED_PATH
|
||||
static int read_allowed(const char *);
|
||||
#endif
|
||||
static int render_string(char **, size_t *);
|
||||
static void say(const char *, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 2, 3)));
|
||||
|
@ -179,6 +184,7 @@ static int write_utf8; /* write UTF-8 output; else ASCII */
|
|||
static int exitcode; /* to be returned by main */
|
||||
static enum op op; /* operational mode */
|
||||
static char basedir[PATH_MAX]; /* current base directory */
|
||||
static size_t basedir_len; /* strlen(basedir) */
|
||||
static struct mpage *mpage_head; /* list of distinct manual pages */
|
||||
static struct ohash mpages; /* table of distinct manual pages */
|
||||
static struct ohash mlinks; /* table of directory entries */
|
||||
|
@ -342,7 +348,7 @@ mandocdb(int argc, char *argv[])
|
|||
* clobber each other.
|
||||
*/
|
||||
#define CHECKOP(_op, _ch) do \
|
||||
if (OP_DEFAULT != (_op)) { \
|
||||
if ((_op) != OP_DEFAULT) { \
|
||||
warnx("-%c: Conflicting option", (_ch)); \
|
||||
goto usage; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
@ -351,7 +357,7 @@ mandocdb(int argc, char *argv[])
|
|||
path_arg = NULL;
|
||||
op = OP_DEFAULT;
|
||||
|
||||
while (-1 != (ch = getopt(argc, argv, "aC:Dd:npQT:tu:v")))
|
||||
while ((ch = getopt(argc, argv, "aC:Dd:npQT:tu:v")) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
use_all = 1;
|
||||
|
@ -379,7 +385,7 @@ mandocdb(int argc, char *argv[])
|
|||
mparse_options |= MPARSE_QUICK;
|
||||
break;
|
||||
case 'T':
|
||||
if (strcmp(optarg, "utf8")) {
|
||||
if (strcmp(optarg, "utf8") != 0) {
|
||||
warnx("-T%s: Unsupported output format",
|
||||
optarg);
|
||||
goto usage;
|
||||
|
@ -416,7 +422,7 @@ mandocdb(int argc, char *argv[])
|
|||
}
|
||||
#endif
|
||||
|
||||
if (OP_CONFFILE == op && argc > 0) {
|
||||
if (op == OP_CONFFILE && argc > 0) {
|
||||
warnx("-C: Too many arguments");
|
||||
goto usage;
|
||||
}
|
||||
|
@ -427,13 +433,13 @@ mandocdb(int argc, char *argv[])
|
|||
mandoc_ohash_init(&mpages, 6, offsetof(struct mpage, inodev));
|
||||
mandoc_ohash_init(&mlinks, 6, offsetof(struct mlink, file));
|
||||
|
||||
if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) {
|
||||
if (op == OP_UPDATE || op == OP_DELETE || op == OP_TEST) {
|
||||
|
||||
/*
|
||||
* Most of these deal with a specific directory.
|
||||
* Jump into that directory first.
|
||||
*/
|
||||
if (OP_TEST != op && 0 == set_basedir(path_arg, 1))
|
||||
if (op != OP_TEST && set_basedir(path_arg, 1) == 0)
|
||||
goto out;
|
||||
|
||||
dba = nodb ? dba_new(128) : dba_read(MANDOC_DB);
|
||||
|
@ -454,11 +460,11 @@ mandocdb(int argc, char *argv[])
|
|||
" from scratch", strerror(errno));
|
||||
exitcode = (int)MANDOCLEVEL_OK;
|
||||
op = OP_DEFAULT;
|
||||
if (0 == treescan())
|
||||
if (treescan() == 0)
|
||||
goto out;
|
||||
dba = dba_new(128);
|
||||
}
|
||||
if (OP_DELETE != op)
|
||||
if (op != OP_DELETE)
|
||||
mpages_merge(dba, mp);
|
||||
if (nodb == 0)
|
||||
dbwrite(dba);
|
||||
|
@ -492,7 +498,7 @@ mandocdb(int argc, char *argv[])
|
|||
sz = strlen(conf.manpath.paths[j]);
|
||||
if (sz && conf.manpath.paths[j][sz - 1] == '/')
|
||||
conf.manpath.paths[j][--sz] = '\0';
|
||||
if (0 == sz)
|
||||
if (sz == 0)
|
||||
continue;
|
||||
|
||||
if (j) {
|
||||
|
@ -502,9 +508,9 @@ mandocdb(int argc, char *argv[])
|
|||
offsetof(struct mlink, file));
|
||||
}
|
||||
|
||||
if ( ! set_basedir(conf.manpath.paths[j], argc > 0))
|
||||
if (set_basedir(conf.manpath.paths[j], argc > 0) == 0)
|
||||
continue;
|
||||
if (0 == treescan())
|
||||
if (treescan() == 0)
|
||||
continue;
|
||||
dba = dba_new(128);
|
||||
mpages_merge(dba, mp);
|
||||
|
@ -608,9 +614,9 @@ treescan(void)
|
|||
say(path, "&realpath");
|
||||
continue;
|
||||
}
|
||||
if (strstr(buf, basedir) != buf
|
||||
#ifdef HOMEBREWDIR
|
||||
&& strstr(buf, HOMEBREWDIR) != buf
|
||||
if (strncmp(buf, basedir, basedir_len) != 0
|
||||
#ifdef READ_ALLOWED_PATH
|
||||
&& !read_allowed(buf)
|
||||
#endif
|
||||
) {
|
||||
if (warnings) say("",
|
||||
|
@ -623,6 +629,8 @@ treescan(void)
|
|||
say(path, "&stat");
|
||||
continue;
|
||||
}
|
||||
if ((ff->fts_statp->st_mode & S_IFMT) != S_IFREG)
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/*
|
||||
|
@ -777,17 +785,17 @@ treescan(void)
|
|||
* See treescan() for the fts(3) version of this.
|
||||
*/
|
||||
static void
|
||||
filescan(const char *file)
|
||||
filescan(const char *infile)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
struct stat st;
|
||||
struct mlink *mlink;
|
||||
char *p, *start;
|
||||
char *linkfile, *p, *realdir, *start, *usefile;
|
||||
size_t realdir_len;
|
||||
|
||||
assert(use_all);
|
||||
|
||||
if (0 == strncmp(file, "./", 2))
|
||||
file += 2;
|
||||
if (strncmp(infile, "./", 2) == 0)
|
||||
infile += 2;
|
||||
|
||||
/*
|
||||
* We have to do lstat(2) before realpath(3) loses
|
||||
|
@ -796,13 +804,13 @@ filescan(const char *file)
|
|||
* we want to use the orginal file name, while for
|
||||
* regular files, we want to use the real path.
|
||||
*/
|
||||
if (-1 == lstat(file, &st)) {
|
||||
if (lstat(infile, &st) == -1) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say(file, "&lstat");
|
||||
say(infile, "&lstat");
|
||||
return;
|
||||
} else if (0 == ((S_IFREG | S_IFLNK) & st.st_mode)) {
|
||||
} else if (S_ISREG(st.st_mode) == 0 && S_ISLNK(st.st_mode) == 0) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say(file, "Not a regular file");
|
||||
say(infile, "Not a regular file");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -810,23 +818,24 @@ filescan(const char *file)
|
|||
* We have to resolve the file name to the real path
|
||||
* in any case for the base directory check.
|
||||
*/
|
||||
if (NULL == realpath(file, buf)) {
|
||||
if ((usefile = realpath(infile, NULL)) == NULL) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say(file, "&realpath");
|
||||
say(infile, "&realpath");
|
||||
return;
|
||||
}
|
||||
|
||||
if (OP_TEST == op)
|
||||
start = buf;
|
||||
else if (strstr(buf, basedir) == buf)
|
||||
start = buf + strlen(basedir);
|
||||
#ifdef HOMEBREWDIR
|
||||
else if (strstr(buf, HOMEBREWDIR) == buf)
|
||||
start = buf;
|
||||
if (op == OP_TEST)
|
||||
start = usefile;
|
||||
else if (strncmp(usefile, basedir, basedir_len) == 0)
|
||||
start = usefile + basedir_len;
|
||||
#ifdef READ_ALLOWED_PATH
|
||||
else if (read_allowed(usefile))
|
||||
start = usefile;
|
||||
#endif
|
||||
else {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say("", "%s: outside base directory", buf);
|
||||
say("", "%s: outside base directory", infile);
|
||||
free(usefile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -834,25 +843,72 @@ filescan(const char *file)
|
|||
* Now we are sure the file is inside our tree.
|
||||
* If it is a symbolic link, ignore the real path
|
||||
* and use the original name.
|
||||
* This implies passing stuff like "cat1/../man1/foo.1"
|
||||
* on the command line won't work. So don't do that.
|
||||
* Note the stat(2) can still fail if the link target
|
||||
* doesn't exist.
|
||||
*/
|
||||
if (S_IFLNK & st.st_mode) {
|
||||
if (-1 == stat(buf, &st)) {
|
||||
do {
|
||||
if (S_ISLNK(st.st_mode) == 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Some implementations of realpath(3) may succeed
|
||||
* even if the target of the link does not exist,
|
||||
* so check again for extra safety.
|
||||
*/
|
||||
if (stat(usefile, &st) == -1) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say(file, "&stat");
|
||||
say(infile, "&stat");
|
||||
free(usefile);
|
||||
return;
|
||||
}
|
||||
if (strlcpy(buf, file, sizeof(buf)) >= sizeof(buf)) {
|
||||
say(file, "Filename too long");
|
||||
return;
|
||||
linkfile = mandoc_strdup(infile);
|
||||
if (op == OP_TEST) {
|
||||
free(usefile);
|
||||
start = usefile = linkfile;
|
||||
break;
|
||||
}
|
||||
start = buf;
|
||||
if (OP_TEST != op && strstr(buf, basedir) == buf)
|
||||
start += strlen(basedir);
|
||||
}
|
||||
if (strncmp(infile, basedir, basedir_len) == 0) {
|
||||
free(usefile);
|
||||
usefile = linkfile;
|
||||
start = usefile + basedir_len;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* This symbolic link points into the basedir
|
||||
* from the outside. Let's see whether any of
|
||||
* the parent directories resolve to the basedir.
|
||||
*/
|
||||
p = strchr(linkfile, '\0');
|
||||
do {
|
||||
while (*--p != '/')
|
||||
continue;
|
||||
*p = '\0';
|
||||
if ((realdir = realpath(linkfile, NULL)) == NULL) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say(infile, "&realpath");
|
||||
free(linkfile);
|
||||
free(usefile);
|
||||
return;
|
||||
}
|
||||
realdir_len = strlen(realdir) + 1;
|
||||
free(realdir);
|
||||
*p = '/';
|
||||
} while (realdir_len > basedir_len);
|
||||
|
||||
/*
|
||||
* If one of the directories resolves to the basedir,
|
||||
* use the rest of the original name.
|
||||
* Otherwise, the best we can do
|
||||
* is to use the filename pointed to.
|
||||
*/
|
||||
if (realdir_len == basedir_len) {
|
||||
free(usefile);
|
||||
usefile = linkfile;
|
||||
start = p + 1;
|
||||
} else {
|
||||
free(linkfile);
|
||||
start = usefile + basedir_len;
|
||||
}
|
||||
} while (/* CONSTCOND */ 0);
|
||||
|
||||
mlink = mandoc_calloc(1, sizeof(struct mlink));
|
||||
mlink->dform = FORM_NONE;
|
||||
|
@ -860,6 +916,7 @@ filescan(const char *file)
|
|||
sizeof(mlink->file)) {
|
||||
say(start, "Filename too long");
|
||||
free(mlink);
|
||||
free(usefile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -868,13 +925,13 @@ filescan(const char *file)
|
|||
* but outside our tree, guess the base directory.
|
||||
*/
|
||||
|
||||
if (op == OP_TEST || (start == buf && *start == '/')) {
|
||||
if (strncmp(buf, "man/", 4) == 0)
|
||||
start = buf + 4;
|
||||
else if ((start = strstr(buf, "/man/")) != NULL)
|
||||
if (op == OP_TEST || (start == usefile && *start == '/')) {
|
||||
if (strncmp(usefile, "man/", 4) == 0)
|
||||
start = usefile + 4;
|
||||
else if ((start = strstr(usefile, "/man/")) != NULL)
|
||||
start += 5;
|
||||
else
|
||||
start = buf;
|
||||
start = usefile;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -883,18 +940,18 @@ filescan(const char *file)
|
|||
* If we find one of these and what's underneath is a directory,
|
||||
* assume it's an architecture.
|
||||
*/
|
||||
if (NULL != (p = strchr(start, '/'))) {
|
||||
if ((p = strchr(start, '/')) != NULL) {
|
||||
*p++ = '\0';
|
||||
if (0 == strncmp(start, "man", 3)) {
|
||||
if (strncmp(start, "man", 3) == 0) {
|
||||
mlink->dform = FORM_SRC;
|
||||
mlink->dsec = start + 3;
|
||||
} else if (0 == strncmp(start, "cat", 3)) {
|
||||
} else if (strncmp(start, "cat", 3) == 0) {
|
||||
mlink->dform = FORM_CAT;
|
||||
mlink->dsec = start + 3;
|
||||
}
|
||||
|
||||
start = p;
|
||||
if (NULL != mlink->dsec && NULL != (p = strchr(start, '/'))) {
|
||||
if (mlink->dsec != NULL && (p = strchr(start, '/')) != NULL) {
|
||||
*p++ = '\0';
|
||||
mlink->arch = start;
|
||||
start = p;
|
||||
|
@ -906,10 +963,10 @@ filescan(const char *file)
|
|||
* Suffix of `.0' indicates a catpage, `.1-9' is a manpage.
|
||||
*/
|
||||
p = strrchr(start, '\0');
|
||||
while (p-- > start && '/' != *p && '.' != *p)
|
||||
/* Loop. */ ;
|
||||
while (p-- > start && *p != '/' && *p != '.')
|
||||
continue;
|
||||
|
||||
if ('.' == *p) {
|
||||
if (*p == '.') {
|
||||
*p++ = '\0';
|
||||
mlink->fsec = p;
|
||||
}
|
||||
|
@ -919,11 +976,12 @@ filescan(const char *file)
|
|||
* Use the filename portion of the path.
|
||||
*/
|
||||
mlink->name = start;
|
||||
if (NULL != (p = strrchr(start, '/'))) {
|
||||
if ((p = strrchr(start, '/')) != NULL) {
|
||||
mlink->name = p + 1;
|
||||
*p = '\0';
|
||||
}
|
||||
mlink_add(mlink, &st);
|
||||
free(usefile);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2250,7 +2308,6 @@ set_basedir(const char *targetdir, int report_baddir)
|
|||
static char startdir[PATH_MAX];
|
||||
static int getcwd_status; /* 1 = ok, 2 = failure */
|
||||
static int chdir_status; /* 1 = changed directory */
|
||||
char *cp;
|
||||
|
||||
/*
|
||||
* Remember the original working directory, if possible.
|
||||
|
@ -2259,8 +2316,8 @@ set_basedir(const char *targetdir, int report_baddir)
|
|||
* Do not error out if the current directory is not
|
||||
* searchable: Maybe it won't be needed after all.
|
||||
*/
|
||||
if (0 == getcwd_status) {
|
||||
if (NULL == getcwd(startdir, sizeof(startdir))) {
|
||||
if (getcwd_status == 0) {
|
||||
if (getcwd(startdir, sizeof(startdir)) == NULL) {
|
||||
getcwd_status = 2;
|
||||
(void)strlcpy(startdir, strerror(errno),
|
||||
sizeof(startdir));
|
||||
|
@ -2273,19 +2330,20 @@ set_basedir(const char *targetdir, int report_baddir)
|
|||
* Do not use it any longer, not even for messages.
|
||||
*/
|
||||
*basedir = '\0';
|
||||
basedir_len = 0;
|
||||
|
||||
/*
|
||||
* If and only if the directory was changed earlier and
|
||||
* the next directory to process is given as a relative path,
|
||||
* first go back, or bail out if that is impossible.
|
||||
*/
|
||||
if (chdir_status && '/' != *targetdir) {
|
||||
if (2 == getcwd_status) {
|
||||
if (chdir_status && *targetdir != '/') {
|
||||
if (getcwd_status == 2) {
|
||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||
say("", "getcwd: %s", startdir);
|
||||
return 0;
|
||||
}
|
||||
if (-1 == chdir(startdir)) {
|
||||
if (chdir(startdir) == -1) {
|
||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||
say("", "&chdir %s", startdir);
|
||||
return 0;
|
||||
|
@ -2297,48 +2355,71 @@ set_basedir(const char *targetdir, int report_baddir)
|
|||
* pathname and append a trailing slash, such that
|
||||
* we can reliably check whether files are inside.
|
||||
*/
|
||||
if (NULL == realpath(targetdir, basedir)) {
|
||||
if (realpath(targetdir, basedir) == NULL) {
|
||||
if (report_baddir || errno != ENOENT) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say("", "&%s: realpath", targetdir);
|
||||
}
|
||||
*basedir = '\0';
|
||||
return 0;
|
||||
} else if (-1 == chdir(basedir)) {
|
||||
} else if (chdir(basedir) == -1) {
|
||||
if (report_baddir || errno != ENOENT) {
|
||||
exitcode = (int)MANDOCLEVEL_BADARG;
|
||||
say("", "&chdir");
|
||||
}
|
||||
*basedir = '\0';
|
||||
return 0;
|
||||
}
|
||||
chdir_status = 1;
|
||||
cp = strchr(basedir, '\0');
|
||||
if ('/' != cp[-1]) {
|
||||
if (cp - basedir >= PATH_MAX - 1) {
|
||||
basedir_len = strlen(basedir);
|
||||
if (basedir[basedir_len - 1] != '/') {
|
||||
if (basedir_len >= PATH_MAX - 1) {
|
||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||
say("", "Filename too long");
|
||||
*basedir = '\0';
|
||||
basedir_len = 0;
|
||||
return 0;
|
||||
}
|
||||
*cp++ = '/';
|
||||
*cp = '\0';
|
||||
basedir[basedir_len++] = '/';
|
||||
basedir[basedir_len] = '\0';
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef READ_ALLOWED_PATH
|
||||
static int
|
||||
read_allowed(const char *candidate)
|
||||
{
|
||||
const char *cp;
|
||||
size_t len;
|
||||
|
||||
for (cp = READ_ALLOWED_PATH;; cp += len) {
|
||||
while (*cp == ':')
|
||||
cp++;
|
||||
if (*cp == '\0')
|
||||
return 0;
|
||||
len = strcspn(cp, ":");
|
||||
if (strncmp(candidate, cp, len) == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
say(const char *file, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int use_errno;
|
||||
|
||||
if ('\0' != *basedir)
|
||||
if (*basedir != '\0')
|
||||
fprintf(stderr, "%s", basedir);
|
||||
if ('\0' != *basedir && '\0' != *file)
|
||||
if (*basedir != '\0' && *file != '\0')
|
||||
fputc('/', stderr);
|
||||
if ('\0' != *file)
|
||||
if (*file != '\0')
|
||||
fprintf(stderr, "%s", file);
|
||||
|
||||
use_errno = 1;
|
||||
if (NULL != format) {
|
||||
if (format != NULL) {
|
||||
switch (*format) {
|
||||
case '&':
|
||||
format++;
|
||||
|
@ -2351,15 +2432,15 @@ say(const char *file, const char *format, ...)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (NULL != format) {
|
||||
if ('\0' != *basedir || '\0' != *file)
|
||||
if (format != NULL) {
|
||||
if (*basedir != '\0' || *file != '\0')
|
||||
fputs(": ", stderr);
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
if (use_errno) {
|
||||
if ('\0' != *basedir || '\0' != *file || NULL != format)
|
||||
if (*basedir != '\0' || *file != '\0' || format != NULL)
|
||||
fputs(": ", stderr);
|
||||
perror(NULL);
|
||||
} else
|
||||
|
|
48
manpath.c
48
manpath.c
|
@ -1,4 +1,4 @@
|
|||
/* $Id: manpath.c,v 1.40 2019/07/10 19:39:01 schwarze Exp $ */
|
||||
/* $Id: manpath.c,v 1.43 2020/08/27 14:59:47 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011,2014,2015,2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
|
@ -163,7 +163,7 @@ manconf_free(struct manconf *conf)
|
|||
static void
|
||||
manconf_file(struct manconf *conf, const char *file)
|
||||
{
|
||||
const char *const toks[] = { "manpath", "output", "_whatdb" };
|
||||
const char *const toks[] = { "manpath", "output" };
|
||||
char manpath_default[] = MANPATH_DEFAULT;
|
||||
|
||||
FILE *stream;
|
||||
|
@ -200,13 +200,6 @@ manconf_file(struct manconf *conf, const char *file)
|
|||
}
|
||||
|
||||
switch (tok) {
|
||||
case 2: /* _whatdb */
|
||||
while (ep > cp && ep[-1] != '/')
|
||||
ep--;
|
||||
if (ep == cp)
|
||||
continue;
|
||||
*ep = '\0';
|
||||
/* FALLTHROUGH */
|
||||
case 0: /* manpath */
|
||||
manpath_add(&conf->manpath, cp, '\0');
|
||||
*manpath_default = '\0';
|
||||
|
@ -230,8 +223,13 @@ int
|
|||
manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
{
|
||||
const char *const toks[] = {
|
||||
/* Tokens requiring an argument. */
|
||||
"includes", "man", "paper", "style", "indent", "width",
|
||||
"tag", "fragment", "mdoc", "noval", "toc"
|
||||
"outfilename", "tagfilename",
|
||||
/* Token taking an optional argument. */
|
||||
"tag",
|
||||
/* Tokens not taking arguments. */
|
||||
"fragment", "mdoc", "noval", "toc"
|
||||
};
|
||||
const size_t ntoks = sizeof(toks) / sizeof(toks[0]);
|
||||
|
||||
|
@ -252,11 +250,11 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
|||
}
|
||||
}
|
||||
|
||||
if (tok < 6 && *cp == '\0') {
|
||||
if (tok < 8 && *cp == '\0') {
|
||||
mandoc_msg(MANDOCERR_BADVAL_MISS, 0, 0, "-O %s=?", toks[tok]);
|
||||
return -1;
|
||||
}
|
||||
if (tok > 6 && tok < ntoks && *cp != '\0') {
|
||||
if (tok > 8 && tok < ntoks && *cp != '\0') {
|
||||
mandoc_msg(MANDOCERR_BADVAL, 0, 0, "-O %s=%s", toks[tok], cp);
|
||||
return -1;
|
||||
}
|
||||
|
@ -313,22 +311,40 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
|||
"-O width=%s is %s", cp, errstr);
|
||||
return -1;
|
||||
case 6:
|
||||
if (conf->outfilename != NULL) {
|
||||
oldval = mandoc_strdup(conf->outfilename);
|
||||
break;
|
||||
}
|
||||
conf->outfilename = mandoc_strdup(cp);
|
||||
return 0;
|
||||
case 7:
|
||||
if (conf->tagfilename != NULL) {
|
||||
oldval = mandoc_strdup(conf->tagfilename);
|
||||
break;
|
||||
}
|
||||
conf->tagfilename = mandoc_strdup(cp);
|
||||
return 0;
|
||||
/*
|
||||
* If the index of the following token changes,
|
||||
* do not forget to adjust the range check above the switch.
|
||||
*/
|
||||
case 8:
|
||||
if (conf->tag != NULL) {
|
||||
oldval = mandoc_strdup(conf->tag);
|
||||
break;
|
||||
}
|
||||
conf->tag = mandoc_strdup(cp);
|
||||
return 0;
|
||||
case 7:
|
||||
case 9:
|
||||
conf->fragment = 1;
|
||||
return 0;
|
||||
case 8:
|
||||
case 10:
|
||||
conf->mdoc = 1;
|
||||
return 0;
|
||||
case 9:
|
||||
case 11:
|
||||
conf->noval = 1;
|
||||
return 0;
|
||||
case 10:
|
||||
case 12:
|
||||
conf->toc = 1;
|
||||
return 0;
|
||||
default:
|
||||
|
|
183
mdoc.7
183
mdoc.7
|
@ -1,7 +1,7 @@
|
|||
.\" $Id: mdoc.7,v 1.279 2019/07/15 19:20:30 schwarze Exp $
|
||||
.\" $Id: mdoc.7,v 1.287 2021/07/29 17:32:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -15,7 +15,7 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 15 2019 $
|
||||
.Dd $Mdocdate: July 29 2021 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -297,7 +297,7 @@ utility does this, that, and the other.
|
|||
It usually follows with a breakdown of the options (if documenting a
|
||||
command), such as:
|
||||
.Bd -literal -offset indent
|
||||
The arguments are as follows:
|
||||
The options are as follows:
|
||||
\&.Bl \-tag \-width Ds
|
||||
\&.It Fl v
|
||||
Print verbose information.
|
||||
|
@ -449,6 +449,7 @@ in the alphabetical
|
|||
.It Ic \&Ss Ta subsection header (one line)
|
||||
.It Ic \&Sx Ta internal cross reference to a section or subsection
|
||||
.It Ic \&Xr Ta cross reference to another manual page: Ar name section
|
||||
.It Ic \&Tg Ta tag the definition of a Ar term Pq <= 1 arguments
|
||||
.It Ic \&Pp Ta start a text paragraph (no arguments)
|
||||
.El
|
||||
.Ss Displays and lists
|
||||
|
@ -631,6 +632,7 @@ Close an
|
|||
.Ic \&Ao
|
||||
block.
|
||||
Does not have any tail arguments.
|
||||
.Tg Ad
|
||||
.It Ic \&Ad Ar address
|
||||
Memory address.
|
||||
Do not use this for postal addresses.
|
||||
|
@ -638,6 +640,7 @@ Do not use this for postal addresses.
|
|||
Examples:
|
||||
.Dl \&.Ad [0,$]
|
||||
.Dl \&.Ad 0x00000000
|
||||
.Tg An
|
||||
.It Ic \&An Fl split | nosplit | Ar first_name ... last_name
|
||||
Author name.
|
||||
Can be used both for the authors of the program, function, or driver
|
||||
|
@ -678,6 +681,7 @@ This macro is almost never useful.
|
|||
See
|
||||
.Ic \&Aq
|
||||
for more details.
|
||||
.Tg Ap
|
||||
.It Ic \&Ap
|
||||
Inserts an apostrophe without any surrounding whitespace.
|
||||
This is generally used as a grammatical device when referring to the verb
|
||||
|
@ -685,6 +689,7 @@ form of a function.
|
|||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Fn execve \&Ap d
|
||||
.Tg Aq
|
||||
.It Ic \&Aq Ar line
|
||||
Enclose the rest of the input line in angle brackets.
|
||||
The only important use case is for email addresses.
|
||||
|
@ -729,6 +734,7 @@ as needed.
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Ao .
|
||||
.Tg Ar
|
||||
.It Ic \&Ar Op Ar placeholder ...
|
||||
Command arguments.
|
||||
If an argument is not provided, the string
|
||||
|
@ -747,6 +753,7 @@ for fixed strings to be passed verbatim as arguments, use
|
|||
.Ic \&Fl
|
||||
or
|
||||
.Ic \&Cm .
|
||||
.Tg At
|
||||
.It Ic \&At Op Ar version
|
||||
Formats an
|
||||
.At
|
||||
|
@ -784,6 +791,7 @@ Close a
|
|||
.Ic \&Bo
|
||||
block.
|
||||
Does not have any tail arguments.
|
||||
.Tg Bd
|
||||
.It Ic \&Bd Fl Ns Ar type Oo Fl offset Ar width Oc Op Fl compact
|
||||
Begin a display block.
|
||||
Display blocks are used to select a different indentation and
|
||||
|
@ -874,6 +882,7 @@ See also
|
|||
.Ic \&D1
|
||||
and
|
||||
.Ic \&Dl .
|
||||
.Tg Bf
|
||||
.It Ic \&Bf Fl emphasis | literal | symbolic | Cm \&Em | \&Li | \&Sy
|
||||
Change the font mode for a scoped block of text.
|
||||
The
|
||||
|
@ -900,6 +909,7 @@ See also
|
|||
.Ic \&Em ,
|
||||
and
|
||||
.Ic \&Sy .
|
||||
.Tg Bk
|
||||
.It Ic \&Bk Fl words
|
||||
For each macro, keep its output together on the same output line,
|
||||
until the end of the macro or the end of the input line is reached,
|
||||
|
@ -922,6 +932,7 @@ macro line:
|
|||
.Pp
|
||||
Be careful in using over-long lines within a keep block!
|
||||
Doing so will clobber the right margin.
|
||||
.Tg Bl
|
||||
.It Xo
|
||||
.Ic \&Bl
|
||||
.Fl Ns Ar type
|
||||
|
@ -1064,6 +1075,7 @@ Examples:
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Bq .
|
||||
.Tg Bq
|
||||
.It Ic \&Bq Ar line
|
||||
Encloses its arguments in square brackets.
|
||||
.Pp
|
||||
|
@ -1097,6 +1109,7 @@ Examples:
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Brq .
|
||||
.Tg Brq
|
||||
.It Ic \&Brq Ar line
|
||||
Encloses its arguments in curly braces.
|
||||
.Pp
|
||||
|
@ -1105,6 +1118,7 @@ Examples:
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Bro .
|
||||
.Tg Bsx
|
||||
.It Ic \&Bsx Op Ar version
|
||||
Format the
|
||||
.Bsx
|
||||
|
@ -1127,6 +1141,7 @@ and
|
|||
Supported only for compatibility, do not use this in new manuals.
|
||||
Prints
|
||||
.Dq is currently in beta test.
|
||||
.Tg Bx
|
||||
.It Ic \&Bx Op Ar version Op Ar variant
|
||||
Format the
|
||||
.Bx
|
||||
|
@ -1146,6 +1161,7 @@ See also
|
|||
.Ic \&Nx ,
|
||||
and
|
||||
.Ic \&Ox .
|
||||
.Tg Cd
|
||||
.It Ic \&Cd Ar line
|
||||
Kernel configuration declaration.
|
||||
This denotes strings accepted by
|
||||
|
@ -1161,6 +1177,7 @@ whitespace and align consecutive
|
|||
.Ic \&Cd
|
||||
declarations.
|
||||
This practise is discouraged.
|
||||
.Tg Cm
|
||||
.It Ic \&Cm Ar keyword ...
|
||||
Command modifiers.
|
||||
Typically used for fixed strings passed as arguments to interactive
|
||||
|
@ -1176,6 +1193,7 @@ Examples:
|
|||
.Dl ".Ic set Fl o Cm vi"
|
||||
.Dl ".Ic lookup Cm file bind"
|
||||
.Dl ".Ic permit Ar identity Op Cm as Ar target"
|
||||
.Tg D1
|
||||
.It Ic \&D1 Ar line
|
||||
One-line indented display.
|
||||
This is formatted by the default rules and is useful for simple indented
|
||||
|
@ -1201,8 +1219,10 @@ Close a
|
|||
.Ic \&Do
|
||||
block.
|
||||
Does not have any tail arguments.
|
||||
.Tg Dd
|
||||
.It Ic \&Dd Cm $\&Mdocdate$ | Ar month day , year
|
||||
Document date for display in the page footer.
|
||||
Document date for display in the page footer,
|
||||
by convention the date of the last change.
|
||||
This is the mandatory first macro of any
|
||||
.Nm
|
||||
manual.
|
||||
|
@ -1248,6 +1268,7 @@ See also
|
|||
.Ic \&Dt
|
||||
and
|
||||
.Ic \&Os .
|
||||
.Tg Dl
|
||||
.It Ic \&Dl Ar line
|
||||
One-line indented display.
|
||||
This is formatted as literal text and is useful for commands and
|
||||
|
@ -1276,6 +1297,7 @@ April is the cruellest month
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Dq .
|
||||
.Tg Dq
|
||||
.It Ic \&Dq Ar line
|
||||
Encloses its arguments in
|
||||
.Dq typographic
|
||||
|
@ -1292,6 +1314,7 @@ See also
|
|||
.Ic \&Sq ,
|
||||
and
|
||||
.Ic \&Do .
|
||||
.Tg Dt
|
||||
.It Ic \&Dt Ar TITLE section Op Ar arch
|
||||
Document title for display in the page header.
|
||||
This is the mandatory second macro of any
|
||||
|
@ -1351,6 +1374,7 @@ See also
|
|||
.Ic \&Dd
|
||||
and
|
||||
.Ic \&Os .
|
||||
.Tg Dv
|
||||
.It Ic \&Dv Ar identifier ...
|
||||
Defined variables such as preprocessor constants, constant symbols,
|
||||
enumeration values, and so on.
|
||||
|
@ -1370,6 +1394,7 @@ for variable symbols, and
|
|||
.Ic \&Fd
|
||||
for listing preprocessor variable definitions in the
|
||||
.Em SYNOPSIS .
|
||||
.Tg Dx
|
||||
.It Ic \&Dx Op Ar version
|
||||
Format the
|
||||
.Dx
|
||||
|
@ -1411,6 +1436,7 @@ End a list context started by
|
|||
.Ic \&Bl .
|
||||
See also
|
||||
.Ic \&It .
|
||||
.Tg Em
|
||||
.It Ic \&Em Ar word ...
|
||||
Request an italic font.
|
||||
If the output device does not provide that, underline.
|
||||
|
@ -1450,6 +1476,7 @@ or any of the other enclosure macros.
|
|||
It encloses its argument in the delimiters specified by the last
|
||||
.Ic \&Es
|
||||
macro.
|
||||
.Tg Eo
|
||||
.It Ic \&Eo Op Ar opening_delimiter
|
||||
An arbitrary enclosure.
|
||||
The
|
||||
|
@ -1457,6 +1484,7 @@ The
|
|||
argument is used as the enclosure head, for example, specifying \e(lq
|
||||
will emulate
|
||||
.Ic \&Do .
|
||||
.Tg Er
|
||||
.It Ic \&Er Ar identifier ...
|
||||
Error constants for definitions of the
|
||||
.Va errno
|
||||
|
@ -1479,6 +1507,7 @@ or any of the other enclosure macros.
|
|||
It takes two arguments, defining the delimiters to be used by subsequent
|
||||
.Ic \&En
|
||||
macros.
|
||||
.Tg Ev
|
||||
.It Ic \&Ev Ar identifier ...
|
||||
Environmental variables such as those specified in
|
||||
.Xr environ 7 .
|
||||
|
@ -1490,6 +1519,7 @@ Examples:
|
|||
See also
|
||||
.Ic \&Dv
|
||||
for general constants.
|
||||
.Tg Ex
|
||||
.It Ic \&Ex Fl std Op Ar utility ...
|
||||
Insert a standard sentence regarding command exit values of 0 on success
|
||||
and >0 on failure.
|
||||
|
@ -1506,6 +1536,7 @@ arguments are treated as separate utilities.
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Rv .
|
||||
.Tg Fa
|
||||
.It Ic \&Fa Ar argument ...
|
||||
Function argument or parameter.
|
||||
Each argument may be a name and a type (recommended for the
|
||||
|
@ -1543,6 +1574,7 @@ See also
|
|||
.It Ic \&Fc
|
||||
End a function context started by
|
||||
.Ic \&Fo .
|
||||
.Tg Fd
|
||||
.It Ic \&Fd Pf # Ar directive Op Ar argument ...
|
||||
Preprocessor directive, in particular for listing it in the
|
||||
.Em SYNOPSIS .
|
||||
|
@ -1563,25 +1595,33 @@ See also
|
|||
.Ic \&In ,
|
||||
and
|
||||
.Ic \&Dv .
|
||||
.Tg Fl
|
||||
.It Ic \&Fl Op Ar word ...
|
||||
Command-line flag or option.
|
||||
Used when listing arguments to command-line utilities.
|
||||
Prints a fixed-width hyphen
|
||||
.Sq \-
|
||||
directly followed by each argument.
|
||||
If no arguments are provided, a hyphen is printed followed by a space.
|
||||
If the argument is a macro, a hyphen is prefixed to the subsequent macro
|
||||
output.
|
||||
For each argument, prints an ASCII hyphen-minus character
|
||||
.Sq \- ,
|
||||
immediately followed by the argument.
|
||||
If no arguments are provided, a hyphen-minus is printed followed by a space.
|
||||
If the argument is a macro, a hyphen-minus is prefixed
|
||||
to the subsequent macro output.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl ".Fl R Op Fl H | L | P"
|
||||
.Dl ".Op Fl 1AaCcdFfgHhikLlmnopqRrSsTtux"
|
||||
.Dl ".Fl type Cm d Fl name Pa CVS"
|
||||
.Dl ".Fl Ar signal_number"
|
||||
.Dl ".Fl o Fl"
|
||||
.Dl ".Nm du Op Fl H | L | P"
|
||||
.Dl ".Nm ls Op Fl 1AaCcdFfgHhikLlmnopqRrSsTtux"
|
||||
.Dl ".Nm route Cm add Fl inet Ar destination gateway"
|
||||
.Dl ".Nm locate.updatedb Op Fl \e-fcodes Ns = Ns Ar dbfile"
|
||||
.Dl ".Nm aucat Fl o Fl"
|
||||
.Dl ".Nm kill Fl Ar signal_number"
|
||||
.Pp
|
||||
For GNU-sytle long options, escaping the additional hyphen-minus is not
|
||||
strictly required, but may be safer with future versions of GNU troff; see
|
||||
.Xr mandoc_char 7
|
||||
for details.
|
||||
.Pp
|
||||
See also
|
||||
.Ic \&Cm .
|
||||
.Tg Fn
|
||||
.It Ic \&Fn Ar funcname Op Ar argument ...
|
||||
A function name.
|
||||
.Pp
|
||||
|
@ -1610,6 +1650,7 @@ See also
|
|||
.Ic \&Fo ,
|
||||
and
|
||||
.Ic \&Ft .
|
||||
.Tg Fo
|
||||
.It Ic \&Fo Ar funcname
|
||||
Begin a function block.
|
||||
This is a multi-line version of
|
||||
|
@ -1644,6 +1685,7 @@ This macro is obsolete.
|
|||
No replacement markup is needed.
|
||||
.Pp
|
||||
It was used to show numerical function return values in an italic font.
|
||||
.Tg Ft
|
||||
.It Ic \&Ft Ar functype
|
||||
A function type.
|
||||
.Pp
|
||||
|
@ -1663,6 +1705,7 @@ See also
|
|||
.Ic \&Fn ,
|
||||
and
|
||||
.Ic \&Fo .
|
||||
.Tg Fx
|
||||
.It Ic \&Fx Op Ar version
|
||||
Format the
|
||||
.Fx
|
||||
|
@ -1685,6 +1728,7 @@ and
|
|||
This macro is not implemented in
|
||||
.Xr mandoc 1 .
|
||||
It was used to include the contents of a (header) file literally.
|
||||
.Tg Ic
|
||||
.It Ic \&Ic Ar keyword ...
|
||||
Internal or interactive command, or configuration instruction
|
||||
in a configuration file.
|
||||
|
@ -1704,6 +1748,7 @@ or
|
|||
is preferred for displaying code samples; the
|
||||
.Ic \&Ic
|
||||
macro is used when referring to an individual command name.
|
||||
.Tg In
|
||||
.It Ic \&In Ar filename
|
||||
The name of an include file.
|
||||
This macro is most often used in section 2, 3, and 9 manual pages.
|
||||
|
@ -1723,6 +1768,7 @@ Examples:
|
|||
.Pp
|
||||
See also
|
||||
.Sx MANUAL STRUCTURE .
|
||||
.Tg It
|
||||
.It Ic \&It Op Ar head
|
||||
A list item.
|
||||
The syntax of this macro depends on the list type.
|
||||
|
@ -1813,6 +1859,7 @@ but not the whitespace before the semicolon.
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Bl .
|
||||
.Tg Lb
|
||||
.It Ic \&Lb Cm lib Ns Ar name
|
||||
Specify a library.
|
||||
.Pp
|
||||
|
@ -1833,6 +1880,7 @@ section as described in
|
|||
Examples:
|
||||
.Dl \&.Lb libz
|
||||
.Dl \&.Lb libmandoc
|
||||
.Tg Li
|
||||
.It Ic \&Li Ar word ...
|
||||
Request a typewriter (literal) font.
|
||||
Deprecated because on terminal output devices, this is usually
|
||||
|
@ -1843,24 +1891,27 @@ For literal displays, use
|
|||
or
|
||||
.Ic \&Bd Fl literal Pq multi-line
|
||||
instead.
|
||||
.Tg Lk
|
||||
.It Ic \&Lk Ar uri Op Ar display_name
|
||||
Format a hyperlink.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Lk http://bsd.lv \(dqThe BSD.lv Project\(dq
|
||||
.Dl \&.Lk http://bsd.lv
|
||||
.Dl \&.Lk https://bsd.lv \(dqThe BSD.lv Project\(dq
|
||||
.Dl \&.Lk https://bsd.lv
|
||||
.Pp
|
||||
See also
|
||||
.Ic \&Mt .
|
||||
.It Ic \&Lp
|
||||
Deprecated synonym for
|
||||
.Ic \&Pp .
|
||||
.Tg Ms
|
||||
.It Ic \&Ms Ar name
|
||||
Display a mathematical symbol.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Ms sigma
|
||||
.Dl \&.Ms aleph
|
||||
.Tg Mt
|
||||
.It Ic \&Mt Ar localpart Ns @ Ns Ar domain
|
||||
Format a
|
||||
.Dq mailto:
|
||||
|
@ -1869,6 +1920,7 @@ hyperlink.
|
|||
Examples:
|
||||
.Dl \&.Mt discuss@manpages.bsd.lv
|
||||
.Dl \&.An Kristaps Dzonsons \&Aq \&Mt kristaps@bsd.lv
|
||||
.Tg Nd
|
||||
.It Ic \&Nd Ar line
|
||||
A one line description of the manual's content.
|
||||
This is the mandatory last macro of the
|
||||
|
@ -1891,6 +1943,7 @@ arguments and will display macros verbatim.
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Nm .
|
||||
.Tg Nm
|
||||
.It Ic \&Nm Op Ar name
|
||||
The name of the manual page, or \(em in particular in section 1, 6,
|
||||
and 8 pages \(em of an additional command or feature documented in
|
||||
|
@ -1928,6 +1981,7 @@ of section 2, 3 and 9 manual pages, use the
|
|||
macro rather than
|
||||
.Ic \&Nm
|
||||
to mark up the name of the manual page.
|
||||
.Tg No
|
||||
.It Ic \&No Ar word ...
|
||||
Normal text.
|
||||
Closes the scope of any preceding in-line macro.
|
||||
|
@ -1952,6 +2006,7 @@ See also
|
|||
.Ic \&Ql ,
|
||||
and
|
||||
.Ic \&Sy .
|
||||
.Tg Ns
|
||||
.It Ic \&Ns
|
||||
Suppress a space between the output of the preceding macro
|
||||
and the following text or macro.
|
||||
|
@ -1971,6 +2026,7 @@ See also
|
|||
.Ic \&No
|
||||
and
|
||||
.Ic \&Sm .
|
||||
.Tg Nx
|
||||
.It Ic \&Nx Op Ar version
|
||||
Format the
|
||||
.Nx
|
||||
|
@ -2003,6 +2059,7 @@ Examples:
|
|||
\&.Op Fl flag Ns Ar value
|
||||
\&.Oc
|
||||
.Ed
|
||||
.Tg Op
|
||||
.It Ic \&Op Ar line
|
||||
Optional part of a command line.
|
||||
Prints the argument(s) in brackets.
|
||||
|
@ -2016,6 +2073,7 @@ Examples:
|
|||
.Pp
|
||||
See also
|
||||
.Ic \&Oo .
|
||||
.Tg Os
|
||||
.It Ic \&Os Op Ar system Op Ar version
|
||||
Operating system version for display in the page footer.
|
||||
This is the mandatory third macro of
|
||||
|
@ -2058,6 +2116,7 @@ Historical
|
|||
.Nm
|
||||
packages described it as
|
||||
.Dq "old function type (FORTRAN)" .
|
||||
.Tg Ox
|
||||
.It Ic \&Ox Op Ar version
|
||||
Format the
|
||||
.Ox
|
||||
|
@ -2076,6 +2135,7 @@ See also
|
|||
.Ic \&Fx ,
|
||||
and
|
||||
.Ic \&Nx .
|
||||
.Tg Pa
|
||||
.It Ic \&Pa Ar name ...
|
||||
An absolute or relative file system path, or a file or directory name.
|
||||
If an argument is not provided, the character
|
||||
|
@ -2091,6 +2151,7 @@ See also
|
|||
.It Ic \&Pc
|
||||
Close parenthesised context opened by
|
||||
.Ic \&Po .
|
||||
.Tg Pf
|
||||
.It Ic \&Pf Ar prefix macro Op Ar argument ...
|
||||
Removes the space between its argument and the following macro.
|
||||
It is equivalent to:
|
||||
|
@ -2114,6 +2175,7 @@ and
|
|||
.It Ic \&Po Ar block
|
||||
Multi-line version of
|
||||
.Ic \&Pq .
|
||||
.Tg Pp
|
||||
.It Ic \&Pp
|
||||
Break a paragraph.
|
||||
This will assert vertical space between prior and subsequent macros
|
||||
|
@ -2130,6 +2192,7 @@ or lists
|
|||
unless the
|
||||
.Fl compact
|
||||
flag is given.
|
||||
.Tg Pq
|
||||
.It Ic \&Pq Ar line
|
||||
Parenthesised enclosure.
|
||||
.Pp
|
||||
|
@ -2138,6 +2201,7 @@ See also
|
|||
.It Ic \&Qc
|
||||
Close quoted context opened by
|
||||
.Ic \&Qo .
|
||||
.Tg Ql
|
||||
.It Ic \&Ql Ar line
|
||||
In-line literal display.
|
||||
This can be used for complete command invocations and for multi-word
|
||||
|
@ -2151,6 +2215,7 @@ and
|
|||
.It Ic \&Qo Ar block
|
||||
Multi-line version of
|
||||
.Ic \&Qq .
|
||||
.Tg Qq
|
||||
.It Ic \&Qq Ar line
|
||||
Encloses its arguments in
|
||||
.Qq typewriter
|
||||
|
@ -2168,6 +2233,7 @@ Close an
|
|||
.Ic \&Rs
|
||||
block.
|
||||
Does not have any tail arguments.
|
||||
.Tg Rs
|
||||
.It Ic \&Rs
|
||||
Begin a bibliographic
|
||||
.Pq Dq reference
|
||||
|
@ -2208,6 +2274,7 @@ If an
|
|||
block is used within a SEE ALSO section, a vertical space is asserted
|
||||
before the rendered output, else the block continues on the current
|
||||
line.
|
||||
.Tg Rv
|
||||
.It Ic \&Rv Fl std Op Ar function ...
|
||||
Insert a standard sentence regarding a function call's return value of 0
|
||||
on success and \-1 on error, with the
|
||||
|
@ -2228,6 +2295,7 @@ See also
|
|||
.It Ic \&Sc
|
||||
Close single-quoted context opened by
|
||||
.Ic \&So .
|
||||
.Tg Sh
|
||||
.It Ic \&Sh Ar TITLE LINE
|
||||
Begin a new section.
|
||||
For a list of conventional manual sections, see
|
||||
|
@ -2246,6 +2314,7 @@ See also
|
|||
.Ic \&Ss ,
|
||||
and
|
||||
.Ic \&Sx .
|
||||
.Tg Sm
|
||||
.It Ic \&Sm Op Cm on | off
|
||||
Switches the spacing mode for output generated from macros.
|
||||
.Pp
|
||||
|
@ -2264,6 +2333,7 @@ Using this is not recommended because it makes the code harder to read.
|
|||
.It Ic \&So Ar block
|
||||
Multi-line version of
|
||||
.Ic \&Sq .
|
||||
.Tg Sq
|
||||
.It Ic \&Sq Ar line
|
||||
Encloses its arguments in
|
||||
.Sq typewriter
|
||||
|
@ -2274,6 +2344,7 @@ See also
|
|||
.Ic \&Qq ,
|
||||
and
|
||||
.Ic \&So .
|
||||
.Tg Ss
|
||||
.It Ic \&Ss Ar Title line
|
||||
Begin a new subsection.
|
||||
Unlike with
|
||||
|
@ -2296,6 +2367,7 @@ See also
|
|||
.Ic \&Sh ,
|
||||
and
|
||||
.Ic \&Sx .
|
||||
.Tg St
|
||||
.It Ic \&St Fl Ns Ar abbreviation
|
||||
Replace an abbreviation for a standard with the full form.
|
||||
The following standards are recognised.
|
||||
|
@ -2506,6 +2578,7 @@ Ethernet local area networks.
|
|||
.St -ieee1275-94
|
||||
.El
|
||||
.El
|
||||
.Tg Sx
|
||||
.It Ic \&Sx Ar Title line
|
||||
Reference a section or subsection in the same manual page.
|
||||
The referenced section or subsection name must be identical to the
|
||||
|
@ -2518,6 +2591,7 @@ See also
|
|||
.Ic \&Sh
|
||||
and
|
||||
.Ic \&Ss .
|
||||
.Tg Sy
|
||||
.It Ic \&Sy Ar word ...
|
||||
Request a boldface font.
|
||||
.Pp
|
||||
|
@ -2543,11 +2617,56 @@ See also
|
|||
.Ic \&No ,
|
||||
and
|
||||
.Ic \&Ql .
|
||||
.Tg Ta
|
||||
.It Ic \&Ta
|
||||
Table cell separator in
|
||||
.Ic \&Bl Fl column
|
||||
lists; can only be used below
|
||||
.Ic \&It .
|
||||
.Tg Tg
|
||||
.It Ic \&Tg Op Ar term
|
||||
Announce that the next input line starts a definition of the
|
||||
.Ar term .
|
||||
This macro must appear alone on its own input line.
|
||||
The argument defaults to the first argument of the first macro
|
||||
on the next line.
|
||||
The argument may not contain whitespace characters, not even when it is quoted.
|
||||
This macro is a
|
||||
.Xr mandoc 1
|
||||
extension and is typically ignored by other formatters.
|
||||
.Pp
|
||||
When viewing terminal output with
|
||||
.Xr less 1 ,
|
||||
the interactive
|
||||
.Ic :t
|
||||
command can be used to go to the definition of the
|
||||
.Ar term
|
||||
as described for the
|
||||
.Ev MANPAGER
|
||||
variable in
|
||||
.Xr man 1 ;
|
||||
when producing HTML output, a fragment identifier
|
||||
.Pq Ic id No attribute
|
||||
is generated, to be used for deep linking to this place of the document.
|
||||
.Pp
|
||||
In most cases, adding a
|
||||
.Ic \&Tg
|
||||
macro would be redundant because
|
||||
.Xr mandoc 1
|
||||
is able to automatically tag most definitions.
|
||||
This macro is intended for cases where automatic tagging of a
|
||||
.Ar term
|
||||
is unsatisfactory, for example if a definition is not tagged
|
||||
automatically (false negative) or if places are tagged that do
|
||||
not define the
|
||||
.Ar term
|
||||
(false positives).
|
||||
When there is at least one
|
||||
.Ic \&Tg
|
||||
macro for a
|
||||
.Ar term ,
|
||||
no other places are automatically marked as definitions of that
|
||||
.Ar term .
|
||||
.It Ic \&Tn Ar word ...
|
||||
Supported only for compatibility, do not use this in new manuals.
|
||||
Even though the macro name
|
||||
|
@ -2562,6 +2681,7 @@ Prints out
|
|||
Supported only for compatibility, do not use this in new manuals.
|
||||
Prints out
|
||||
.Dq Ux .
|
||||
.Tg Va
|
||||
.It Ic \&Va Oo Ar type Oc Ar identifier ...
|
||||
A variable name.
|
||||
.Pp
|
||||
|
@ -2576,6 +2696,7 @@ For declarations of global variables in the
|
|||
.Em SYNOPSIS
|
||||
section, use
|
||||
.Ic \&Vt .
|
||||
.Tg Vt
|
||||
.It Ic \&Vt Ar type Op Ar identifier
|
||||
A variable type.
|
||||
.Pp
|
||||
|
@ -2619,6 +2740,7 @@ beyond the end of the input line.
|
|||
This macro originally existed to work around the 9-argument limit
|
||||
of historic
|
||||
.Xr roff 7 .
|
||||
.Tg Xr
|
||||
.It Ic \&Xr Ar name section
|
||||
Link to another manual
|
||||
.Pq Qq cross-reference .
|
||||
|
@ -2681,7 +2803,7 @@ column, if applicable, describes closure rules.
|
|||
.Ss Block full-explicit
|
||||
Multi-line scope closed by an explicit closing macro.
|
||||
All macros contains bodies; only
|
||||
.Ic \s&Bf
|
||||
.Ic \&Bf
|
||||
and
|
||||
.Pq optionally
|
||||
.Ic \&Bl
|
||||
|
@ -2912,6 +3034,7 @@ then the macro accepts an arbitrary number of arguments.
|
|||
.It Ic \&St Ta \&No Ta Yes Ta 1
|
||||
.It Ic \&Sx Ta Yes Ta Yes Ta >0
|
||||
.It Ic \&Sy Ta Yes Ta Yes Ta >0
|
||||
.It Ic \&Tg Ta \&No Ta \&No Ta <2
|
||||
.It Ic \&Tn Ta Yes Ta Yes Ta >0
|
||||
.It Ic \&Ud Ta \&No Ta \&No Ta 0
|
||||
.It Ic \&Ux Ta Yes Ta Yes Ta n
|
||||
|
@ -3039,17 +3162,6 @@ The following problematic behaviour is found in groff:
|
|||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
.Ic \&Dd
|
||||
with non-standard arguments behaves very strangely.
|
||||
When there are three arguments, they are printed verbatim.
|
||||
Any other number of arguments is replaced by the current date,
|
||||
but without any arguments the string
|
||||
.Dq Epoch
|
||||
is printed.
|
||||
.It
|
||||
.Ic \&Lk
|
||||
only accepts a single link-name argument; the remainder is misformatted.
|
||||
.It
|
||||
.Ic \&Pa
|
||||
does not format its arguments when used in the FILES section under
|
||||
certain list types.
|
||||
|
@ -3057,9 +3169,6 @@ certain list types.
|
|||
.Ic \&Ta
|
||||
can only be called by other macros, but not at the beginning of a line.
|
||||
.It
|
||||
.Ic \&%C
|
||||
is not implemented (up to and including groff-1.22.2).
|
||||
.It
|
||||
.Sq \ef
|
||||
.Pq font face
|
||||
and
|
||||
|
@ -3109,10 +3218,16 @@ but produces large indentations.
|
|||
.Xr tbl 7
|
||||
.Pp
|
||||
The web page
|
||||
.Lk http://mandoc.bsd.lv/mdoc/ "extended documentation for the mdoc language"
|
||||
.Lk https://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.
|
||||
.Pp
|
||||
The manual page
|
||||
.Lk https://man.voidlinux.org/groff_mdoc "groff_mdoc(7)"
|
||||
contained in the
|
||||
.Dq groff
|
||||
package documents exactly the same language in a somewhat different style.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
|
13
mdoc.c
13
mdoc.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mdoc.c,v 1.274 2018/12/31 07:46:07 schwarze Exp $ */
|
||||
/* $Id: mdoc.c,v 1.275 2020/04/06 10:16:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2018, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Top level and utility functions of the mdoc(7) parser for mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -352,12 +354,13 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
|||
mandoc_msg(MANDOCERR_SPACE_EOL, ln, offs - 1, NULL);
|
||||
|
||||
/*
|
||||
* If an initial macro or a list invocation, divert directly
|
||||
* into macro processing.
|
||||
* If an initial or transparent macro or a list invocation,
|
||||
* divert directly into macro processing.
|
||||
*/
|
||||
|
||||
n = mdoc->last;
|
||||
if (n == NULL || tok == MDOC_It || tok == MDOC_El) {
|
||||
if (n == NULL || tok == MDOC_It || tok == MDOC_El ||
|
||||
roff_tok_transparent(tok)) {
|
||||
(*mdoc_macro(tok)->fp)(mdoc, tok, ln, sv, &offs, buf);
|
||||
return 1;
|
||||
}
|
||||
|
|
385
mdoc_html.c
385
mdoc_html.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mdoc_html.c,v 1.328 2019/03/01 10:57:18 schwarze Exp $ */
|
||||
/* $Id: mdoc_html.c,v 1.342 2021/03/30 19:26:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* HTML formatter for mdoc(7) used by mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -47,13 +49,11 @@ struct mdoc_html_act {
|
|||
void (*post)(MDOC_ARGS);
|
||||
};
|
||||
|
||||
static char *cond_id(const struct roff_node *);
|
||||
static void print_mdoc_head(const struct roff_meta *,
|
||||
struct html *);
|
||||
static void print_mdoc_node(MDOC_ARGS);
|
||||
static void print_mdoc_nodelist(MDOC_ARGS);
|
||||
static void synopsis_pre(struct html *,
|
||||
const struct roff_node *);
|
||||
static void synopsis_pre(struct html *, struct roff_node *);
|
||||
|
||||
static void mdoc_root_post(const struct roff_meta *,
|
||||
struct html *);
|
||||
|
@ -73,9 +73,8 @@ static void mdoc_bk_post(MDOC_ARGS);
|
|||
static int mdoc_bk_pre(MDOC_ARGS);
|
||||
static int mdoc_bl_pre(MDOC_ARGS);
|
||||
static int mdoc_cd_pre(MDOC_ARGS);
|
||||
static int mdoc_cm_pre(MDOC_ARGS);
|
||||
static int mdoc_code_pre(MDOC_ARGS);
|
||||
static int mdoc_d1_pre(MDOC_ARGS);
|
||||
static int mdoc_dv_pre(MDOC_ARGS);
|
||||
static int mdoc_fa_pre(MDOC_ARGS);
|
||||
static int mdoc_fd_pre(MDOC_ARGS);
|
||||
static int mdoc_fl_pre(MDOC_ARGS);
|
||||
|
@ -84,20 +83,15 @@ static int mdoc_ft_pre(MDOC_ARGS);
|
|||
static int mdoc_em_pre(MDOC_ARGS);
|
||||
static void mdoc_eo_post(MDOC_ARGS);
|
||||
static int mdoc_eo_pre(MDOC_ARGS);
|
||||
static int mdoc_er_pre(MDOC_ARGS);
|
||||
static int mdoc_ev_pre(MDOC_ARGS);
|
||||
static int mdoc_ex_pre(MDOC_ARGS);
|
||||
static void mdoc_fo_post(MDOC_ARGS);
|
||||
static int mdoc_fo_pre(MDOC_ARGS);
|
||||
static int mdoc_ic_pre(MDOC_ARGS);
|
||||
static int mdoc_igndelim_pre(MDOC_ARGS);
|
||||
static int mdoc_in_pre(MDOC_ARGS);
|
||||
static int mdoc_it_pre(MDOC_ARGS);
|
||||
static int mdoc_lb_pre(MDOC_ARGS);
|
||||
static int mdoc_li_pre(MDOC_ARGS);
|
||||
static int mdoc_lk_pre(MDOC_ARGS);
|
||||
static int mdoc_mt_pre(MDOC_ARGS);
|
||||
static int mdoc_ms_pre(MDOC_ARGS);
|
||||
static int mdoc_nd_pre(MDOC_ARGS);
|
||||
static int mdoc_nm_pre(MDOC_ARGS);
|
||||
static int mdoc_no_pre(MDOC_ARGS);
|
||||
|
@ -115,6 +109,7 @@ static int mdoc_ss_pre(MDOC_ARGS);
|
|||
static int mdoc_st_pre(MDOC_ARGS);
|
||||
static int mdoc_sx_pre(MDOC_ARGS);
|
||||
static int mdoc_sy_pre(MDOC_ARGS);
|
||||
static int mdoc_tg_pre(MDOC_ARGS);
|
||||
static int mdoc_va_pre(MDOC_ARGS);
|
||||
static int mdoc_vt_pre(MDOC_ARGS);
|
||||
static int mdoc_xr_pre(MDOC_ARGS);
|
||||
|
@ -139,19 +134,19 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{mdoc_ap_pre, NULL}, /* Ap */
|
||||
{mdoc_ar_pre, NULL}, /* Ar */
|
||||
{mdoc_cd_pre, NULL}, /* Cd */
|
||||
{mdoc_cm_pre, NULL}, /* Cm */
|
||||
{mdoc_dv_pre, NULL}, /* Dv */
|
||||
{mdoc_er_pre, NULL}, /* Er */
|
||||
{mdoc_ev_pre, NULL}, /* Ev */
|
||||
{mdoc_code_pre, NULL}, /* Cm */
|
||||
{mdoc_code_pre, NULL}, /* Dv */
|
||||
{mdoc_code_pre, NULL}, /* Er */
|
||||
{mdoc_code_pre, NULL}, /* Ev */
|
||||
{mdoc_ex_pre, NULL}, /* Ex */
|
||||
{mdoc_fa_pre, NULL}, /* Fa */
|
||||
{mdoc_fd_pre, NULL}, /* Fd */
|
||||
{mdoc_fl_pre, NULL}, /* Fl */
|
||||
{mdoc_fn_pre, NULL}, /* Fn */
|
||||
{mdoc_ft_pre, NULL}, /* Ft */
|
||||
{mdoc_ic_pre, NULL}, /* Ic */
|
||||
{mdoc_code_pre, NULL}, /* Ic */
|
||||
{mdoc_in_pre, NULL}, /* In */
|
||||
{mdoc_li_pre, NULL}, /* Li */
|
||||
{mdoc_code_pre, NULL}, /* Li */
|
||||
{mdoc_nd_pre, NULL}, /* Nd */
|
||||
{mdoc_nm_pre, NULL}, /* Nm */
|
||||
{mdoc_quote_pre, mdoc_quote_post}, /* Op */
|
||||
|
@ -192,7 +187,7 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{mdoc_em_pre, NULL}, /* Em */
|
||||
{mdoc_eo_pre, mdoc_eo_post}, /* Eo */
|
||||
{mdoc_xx_pre, NULL}, /* Fx */
|
||||
{mdoc_ms_pre, NULL}, /* Ms */
|
||||
{mdoc_no_pre, NULL}, /* Ms */
|
||||
{mdoc_no_pre, NULL}, /* No */
|
||||
{mdoc_ns_pre, NULL}, /* Ns */
|
||||
{mdoc_xx_pre, NULL}, /* Nx */
|
||||
|
@ -241,6 +236,7 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{mdoc__x_pre, mdoc__x_post}, /* %Q */
|
||||
{mdoc__x_pre, mdoc__x_post}, /* %U */
|
||||
{NULL, NULL}, /* Ta */
|
||||
{mdoc_tg_pre, NULL}, /* Tg */
|
||||
};
|
||||
|
||||
|
||||
|
@ -248,13 +244,15 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
* See the same function in mdoc_term.c for documentation.
|
||||
*/
|
||||
static void
|
||||
synopsis_pre(struct html *h, const struct roff_node *n)
|
||||
synopsis_pre(struct html *h, struct roff_node *n)
|
||||
{
|
||||
struct roff_node *np;
|
||||
|
||||
if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
|
||||
if ((n->flags & NODE_SYNPRETTY) == 0 ||
|
||||
(np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
if (n->prev->tok == n->tok &&
|
||||
if (np->tok == n->tok &&
|
||||
MDOC_Fo != n->tok &&
|
||||
MDOC_Ft != n->tok &&
|
||||
MDOC_Fn != n->tok) {
|
||||
|
@ -262,7 +260,7 @@ synopsis_pre(struct html *h, const struct roff_node *n)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (n->prev->tok) {
|
||||
switch (np->tok) {
|
||||
case MDOC_Fd:
|
||||
case MDOC_Fn:
|
||||
case MDOC_Fo:
|
||||
|
@ -351,30 +349,40 @@ print_mdoc_node(MDOC_ARGS)
|
|||
if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
|
||||
return;
|
||||
|
||||
html_fillmode(h, n->flags & NODE_NOFILL ? ROFF_nf : ROFF_fi);
|
||||
if ((n->flags & NODE_NOFILL) == 0)
|
||||
html_fillmode(h, ROFF_fi);
|
||||
else if (html_fillmode(h, ROFF_nf) == ROFF_nf &&
|
||||
n->tok != ROFF_fi && n->flags & NODE_LINE)
|
||||
print_endline(h);
|
||||
|
||||
child = 1;
|
||||
n->flags &= ~NODE_ENDED;
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
if (n->flags & NODE_LINE) {
|
||||
switch (*n->string) {
|
||||
case '\0':
|
||||
h->col = 1;
|
||||
print_endline(h);
|
||||
return;
|
||||
case ' ':
|
||||
if ((h->flags & HTML_NONEWLINE) == 0 &&
|
||||
(n->flags & NODE_NOFILL) == 0)
|
||||
print_otag(h, TAG_BR, "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
t = h->tag;
|
||||
t->refcnt++;
|
||||
|
||||
/* No tables in this mode... */
|
||||
assert(NULL == h->tblt);
|
||||
|
||||
/*
|
||||
* Make sure that if we're in a literal mode already
|
||||
* (i.e., within a <PRE>) don't print the newline.
|
||||
*/
|
||||
if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(h->flags & HTML_NONEWLINE) == 0 &&
|
||||
(n->flags & NODE_NOFILL) == 0)
|
||||
print_otag(h, TAG_BR, "");
|
||||
if (NODE_DELIMC & n->flags)
|
||||
if (n->flags & NODE_DELIMC)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->string);
|
||||
if (NODE_DELIMO & n->flags)
|
||||
if (n->flags & NODE_HREF)
|
||||
print_tagged_text(h, n->string, n);
|
||||
else
|
||||
print_text(h, n->string);
|
||||
if (n->flags & NODE_DELIMO)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
|
@ -439,12 +447,6 @@ print_mdoc_node(MDOC_ARGS)
|
|||
n->body->flags |= NODE_ENDED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n->flags & NODE_NOFILL &&
|
||||
(n->next == NULL || n->next->flags & NODE_LINE)) {
|
||||
h->col++;
|
||||
print_endline(h);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -502,20 +504,11 @@ mdoc_root_pre(const struct roff_meta *meta, struct html *h)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static char *
|
||||
cond_id(const struct roff_node *n)
|
||||
static int
|
||||
mdoc_code_pre(MDOC_ARGS)
|
||||
{
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT &&
|
||||
(n->prev == NULL ||
|
||||
(n->prev->type == ROFFT_TEXT &&
|
||||
strcmp(n->prev->string, "|") == 0)) &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Xo &&
|
||||
n->parent->parent->prev == NULL &&
|
||||
n->parent->parent->parent->tok == MDOC_It)))
|
||||
return html_make_id(n, 1);
|
||||
return NULL;
|
||||
print_otag_id(h, TAG_CODE, roff_name[n->tok], n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -578,10 +571,7 @@ mdoc_sh_pre(MDOC_ARGS)
|
|||
print_otag(h, TAG_SECTION, "c", "Sh");
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
id = html_make_id(n, 1);
|
||||
print_otag(h, TAG_H1, "ci", "Sh", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag_id(h, TAG_H1, "Sh", n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->sec == SEC_AUTHORS)
|
||||
|
@ -596,64 +586,43 @@ mdoc_sh_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_ss_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
print_otag(h, TAG_SECTION, "c", "Ss");
|
||||
return 1;
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
print_otag_id(h, TAG_H2, "Ss", n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
id = html_make_id(n, 1);
|
||||
print_otag(h, TAG_H2, "ci", "Ss", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_fl_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Fl", id);
|
||||
struct roff_node *nn;
|
||||
|
||||
print_otag_id(h, TAG_CODE, "Fl", n);
|
||||
print_text(h, "\\-");
|
||||
if (!(n->child == NULL &&
|
||||
(n->next == NULL ||
|
||||
n->next->type == ROFFT_TEXT ||
|
||||
n->next->flags & NODE_LINE)))
|
||||
if (n->child != NULL ||
|
||||
((nn = roff_node_next(n)) != NULL &&
|
||||
nn->type != ROFFT_TEXT &&
|
||||
(nn->flags & NODE_LINE) == 0))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_cm_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Cm", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_nd_pre(MDOC_ARGS)
|
||||
{
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
|
@ -663,8 +632,7 @@ mdoc_nd_pre(MDOC_ARGS)
|
|||
abort();
|
||||
}
|
||||
print_text(h, "\\(em");
|
||||
/* Cannot use TAG_SPAN because it may contain blocks. */
|
||||
print_otag(h, TAG_DIV, "c", "Nd");
|
||||
print_otag(h, TAG_SPAN, "c", "Nd");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -721,6 +689,18 @@ mdoc_xr_pre(MDOC_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_tg_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = html_make_id(n, 1)) != NULL) {
|
||||
print_tagq(h, print_otag(h, TAG_MARK, "i", id));
|
||||
free(id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_ns_pre(MDOC_ARGS)
|
||||
{
|
||||
|
@ -765,7 +745,7 @@ mdoc_it_pre(MDOC_ARGS)
|
|||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, TAG_LI, "");
|
||||
print_otag_id(h, TAG_LI, NULL, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -777,7 +757,7 @@ mdoc_it_pre(MDOC_ARGS)
|
|||
case LIST_ohang:
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
print_otag(h, TAG_DT, "");
|
||||
print_otag_id(h, TAG_DT, NULL, n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, TAG_DD, "");
|
||||
|
@ -789,7 +769,7 @@ mdoc_it_pre(MDOC_ARGS)
|
|||
case LIST_tag:
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
print_otag(h, TAG_DT, "");
|
||||
print_otag_id(h, TAG_DT, NULL, n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->child == NULL) {
|
||||
|
@ -810,7 +790,7 @@ mdoc_it_pre(MDOC_ARGS)
|
|||
print_otag(h, TAG_TD, "");
|
||||
break;
|
||||
default:
|
||||
print_otag(h, TAG_TR, "");
|
||||
print_otag_id(h, TAG_TR, NULL, n);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
@ -876,8 +856,8 @@ mdoc_bl_pre(MDOC_ARGS)
|
|||
case LIST_tag:
|
||||
if (bl->offs)
|
||||
print_otag(h, TAG_DIV, "c", "Bd-indent");
|
||||
print_otag(h, TAG_DL, "c", bl->comp ?
|
||||
"Bl-tag Bl-compact" : "Bl-tag");
|
||||
print_otag_id(h, TAG_DL,
|
||||
bl->comp ? "Bl-tag Bl-compact" : "Bl-tag", n->body);
|
||||
return 1;
|
||||
case LIST_column:
|
||||
elemtype = TAG_TABLE;
|
||||
|
@ -890,14 +870,14 @@ mdoc_bl_pre(MDOC_ARGS)
|
|||
(void)strlcat(cattr, " Bd-indent", sizeof(cattr));
|
||||
if (bl->comp)
|
||||
(void)strlcat(cattr, " Bl-compact", sizeof(cattr));
|
||||
print_otag(h, elemtype, "c", cattr);
|
||||
print_otag_id(h, elemtype, cattr, n->body);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_ex_pre(MDOC_ARGS)
|
||||
{
|
||||
if (n->prev)
|
||||
if (roff_node_prev(n) != NULL)
|
||||
print_otag(h, TAG_BR, "");
|
||||
return 1;
|
||||
}
|
||||
|
@ -912,7 +892,7 @@ mdoc_st_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_em_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_I, "c", "Em");
|
||||
print_otag_id(h, TAG_I, "Em", n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -922,15 +902,15 @@ mdoc_d1_pre(MDOC_ARGS)
|
|||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
break;
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
print_otag(h, TAG_DIV, "c", "Bd Bd-indent");
|
||||
print_otag_id(h, TAG_DIV, "Bd Bd-indent", n);
|
||||
if (n->tok == MDOC_Dl)
|
||||
print_otag(h, TAG_CODE, "c", "Li");
|
||||
return 1;
|
||||
|
@ -950,7 +930,7 @@ mdoc_sx_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_bd_pre(MDOC_ARGS)
|
||||
{
|
||||
char buf[16];
|
||||
char buf[20];
|
||||
struct roff_node *nn;
|
||||
int comp;
|
||||
|
||||
|
@ -974,7 +954,7 @@ mdoc_bd_pre(MDOC_ARGS)
|
|||
continue;
|
||||
if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss)
|
||||
comp = 1;
|
||||
if (nn->prev != NULL)
|
||||
if (roff_node_prev(nn) != NULL)
|
||||
break;
|
||||
}
|
||||
(void)strlcpy(buf, "Bd", sizeof(buf));
|
||||
|
@ -987,7 +967,10 @@ mdoc_bd_pre(MDOC_ARGS)
|
|||
strcmp(n->norm->Bd.offs, "left") != 0)
|
||||
(void)strlcat(buf, " Bd-indent", sizeof(buf));
|
||||
|
||||
print_otag(h, TAG_DIV, "c", buf);
|
||||
if (n->norm->Bd.type == DISP_literal)
|
||||
(void)strlcat(buf, " Li", sizeof(buf));
|
||||
|
||||
print_otag_id(h, TAG_DIV, buf, n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1037,45 +1020,6 @@ mdoc_cd_pre(MDOC_ARGS)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_dv_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Dv", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_ev_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Ev", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_er_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
id = n->sec == SEC_ERRORS &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Bq &&
|
||||
n->parent->parent->parent->tok == MDOC_It)) ?
|
||||
html_make_id(n, 1) : NULL;
|
||||
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Er", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_fa_pre(MDOC_ARGS)
|
||||
{
|
||||
|
@ -1086,22 +1030,21 @@ mdoc_fa_pre(MDOC_ARGS)
|
|||
print_otag(h, TAG_VAR, "c", "Fa");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
for (nn = n->child; nn != NULL; nn = nn->next) {
|
||||
t = print_otag(h, TAG_VAR, "c", "Fa");
|
||||
print_text(h, nn->string);
|
||||
print_tagq(h, t);
|
||||
if (nn->next) {
|
||||
if (nn->next != NULL) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if (n->child && n->next && n->next->tok == MDOC_Fa) {
|
||||
if (n->child != NULL &&
|
||||
(nn = roff_node_next(n)) != NULL &&
|
||||
nn->tok == MDOC_Fa) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ",");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1152,7 @@ mdoc_fn_pre(MDOC_ARGS)
|
|||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
t = print_otag(h, TAG_CODE, "c", "Fn");
|
||||
t = print_otag_id(h, TAG_CODE, "Fn", n);
|
||||
|
||||
if (sp)
|
||||
print_text(h, sp);
|
||||
|
@ -1272,9 +1215,21 @@ mdoc_skip_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_pp_pre(MDOC_ARGS)
|
||||
{
|
||||
if ((n->flags & NODE_NOFILL) == 0) {
|
||||
char *id;
|
||||
|
||||
if (n->flags & NODE_NOFILL) {
|
||||
print_endline(h);
|
||||
if (n->flags & NODE_ID)
|
||||
mdoc_tg_pre(meta, n, h);
|
||||
else {
|
||||
h->col = 1;
|
||||
print_endline(h);
|
||||
}
|
||||
} else {
|
||||
html_close_paragraph(h);
|
||||
print_otag(h, TAG_P, "c", "Pp");
|
||||
id = n->flags & NODE_ID ? html_make_id(n, 1) : NULL;
|
||||
print_otag(h, TAG_P, "ci", "Pp", id);
|
||||
free(id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1324,14 +1279,12 @@ mdoc_mt_pre(MDOC_ARGS)
|
|||
|
||||
for (n = n->child; n; n = n->next) {
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
|
||||
mandoc_asprintf(&cp, "mailto:%s", n->string);
|
||||
t = print_otag(h, TAG_A, "ch", "Mt", cp);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
free(cp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1340,30 +1293,30 @@ mdoc_fo_pre(MDOC_ARGS)
|
|||
{
|
||||
struct tag *t;
|
||||
|
||||
if (n->type == ROFFT_BODY) {
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
synopsis_pre(h, n);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
if (n->child != NULL) {
|
||||
t = print_otag_id(h, TAG_CODE, "Fn", n);
|
||||
print_text(h, n->child->string);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "(");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
return 1;
|
||||
} else if (n->type == ROFFT_BLOCK) {
|
||||
synopsis_pre(h, n);
|
||||
return 1;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (n->child == NULL)
|
||||
return 0;
|
||||
|
||||
assert(n->child->string);
|
||||
t = print_otag(h, TAG_CODE, "c", "Fn");
|
||||
print_text(h, n->child->string);
|
||||
print_tagq(h, t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mdoc_fo_post(MDOC_ARGS)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_BODY)
|
||||
return;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
@ -1413,21 +1366,9 @@ mdoc_in_pre(MDOC_ARGS)
|
|||
assert(n->type == ROFFT_TEXT);
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_ic_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Ic", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_va_pre(MDOC_ARGS)
|
||||
{
|
||||
|
@ -1438,7 +1379,6 @@ mdoc_va_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_ap_pre(MDOC_ARGS)
|
||||
{
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "\\(aq");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
@ -1476,21 +1416,9 @@ mdoc_bf_pre(MDOC_ARGS)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_ms_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_SPAN, "ci", "Ms", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_igndelim_pre(MDOC_ARGS)
|
||||
{
|
||||
|
||||
h->flags |= HTML_IGNDELIM;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1498,7 +1426,6 @@ mdoc_igndelim_pre(MDOC_ARGS)
|
|||
static void
|
||||
mdoc_pf_post(MDOC_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
}
|
||||
|
@ -1527,36 +1454,23 @@ mdoc_rs_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_no_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_SPAN, "ci", "No", id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_li_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Li", id);
|
||||
print_otag_id(h, TAG_SPAN, roff_name[n->tok], n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_sy_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_B, "c", "Sy");
|
||||
print_otag_id(h, TAG_B, "Sy", n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_lb_pre(MDOC_ARGS)
|
||||
{
|
||||
if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev)
|
||||
if (n->sec == SEC_LIBRARY &&
|
||||
n->flags & NODE_LINE &&
|
||||
roff_node_prev(n) != NULL)
|
||||
print_otag(h, TAG_BR, "");
|
||||
|
||||
print_otag(h, TAG_SPAN, "c", "Lb");
|
||||
|
@ -1566,17 +1480,18 @@ mdoc_lb_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc__x_pre(MDOC_ARGS)
|
||||
{
|
||||
const char *cattr;
|
||||
enum htmltag t;
|
||||
struct roff_node *nn;
|
||||
const char *cattr;
|
||||
enum htmltag t;
|
||||
|
||||
t = TAG_SPAN;
|
||||
|
||||
switch (n->tok) {
|
||||
case MDOC__A:
|
||||
cattr = "RsA";
|
||||
if (n->prev && MDOC__A == n->prev->tok)
|
||||
if (NULL == n->next || MDOC__A != n->next->tok)
|
||||
print_text(h, "and");
|
||||
if ((nn = roff_node_prev(n)) != NULL && nn->tok == MDOC__A &&
|
||||
((nn = roff_node_next(n)) == NULL || nn->tok != MDOC__A))
|
||||
print_text(h, "and");
|
||||
break;
|
||||
case MDOC__B:
|
||||
t = TAG_I;
|
||||
|
@ -1631,19 +1546,21 @@ mdoc__x_pre(MDOC_ARGS)
|
|||
static void
|
||||
mdoc__x_post(MDOC_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok)
|
||||
if (NULL == n->next->next || MDOC__A != n->next->next->tok)
|
||||
if (NULL == n->prev || MDOC__A != n->prev->tok)
|
||||
return;
|
||||
if (n->tok == MDOC__A &&
|
||||
(nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A &&
|
||||
((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) &&
|
||||
((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A))
|
||||
return;
|
||||
|
||||
/* TODO: %U */
|
||||
|
||||
if (NULL == n->parent || MDOC_Rs != n->parent->tok)
|
||||
if (n->parent == NULL || n->parent->tok != MDOC_Rs)
|
||||
return;
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->next ? "," : ".");
|
||||
print_text(h, roff_node_next(n) ? "," : ".");
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1700,7 +1617,7 @@ mdoc_quote_pre(MDOC_ARGS)
|
|||
/*
|
||||
* Give up on semantic markup for now.
|
||||
* We cannot use TAG_SPAN because .Oo may contain blocks.
|
||||
* We cannot use TAG_IDIV because we might be in a
|
||||
* We cannot use TAG_DIV because we might be in a
|
||||
* phrasing context (like .Dl or .Pp); we cannot
|
||||
* close out a .Pp at this point either because
|
||||
* that would break the line.
|
||||
|
@ -1715,9 +1632,11 @@ mdoc_quote_pre(MDOC_ARGS)
|
|||
break;
|
||||
case MDOC_Do:
|
||||
case MDOC_Dq:
|
||||
print_text(h, "\\(lq");
|
||||
break;
|
||||
case MDOC_Qo:
|
||||
case MDOC_Qq:
|
||||
print_text(h, "\\(lq");
|
||||
print_text(h, "\"");
|
||||
break;
|
||||
case MDOC_Po:
|
||||
case MDOC_Pq:
|
||||
|
@ -1773,12 +1692,14 @@ mdoc_quote_post(MDOC_ARGS)
|
|||
else
|
||||
print_text(h, n->norm->Es->child->next->string);
|
||||
break;
|
||||
case MDOC_Qo:
|
||||
case MDOC_Qq:
|
||||
case MDOC_Do:
|
||||
case MDOC_Dq:
|
||||
print_text(h, "\\(rq");
|
||||
break;
|
||||
case MDOC_Qo:
|
||||
case MDOC_Qq:
|
||||
print_text(h, "\"");
|
||||
break;
|
||||
case MDOC_Po:
|
||||
case MDOC_Pq:
|
||||
print_text(h, ")");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mdoc_macro.c,v 1.232 2019/01/07 07:26:29 schwarze Exp $ */
|
||||
/* $Id: mdoc_macro.c,v 1.234 2020/01/19 18:02:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012-2020 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
|
||||
|
@ -61,7 +61,7 @@ static void rew_pending(struct roff_man *,
|
|||
const struct roff_node *);
|
||||
|
||||
static const struct mdoc_macro mdoc_macros[MDOC_MAX - MDOC_Dd] = {
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Dd */
|
||||
{ in_line_eoln, MDOC_PROLOGUE | MDOC_JOIN }, /* Dd */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Dt */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Os */
|
||||
{ blk_full, MDOC_PARSED | MDOC_JOIN }, /* Sh */
|
||||
|
@ -200,6 +200,7 @@ static const struct mdoc_macro mdoc_macros[MDOC_MAX - MDOC_Dd] = {
|
|||
{ in_line_eoln, MDOC_JOIN }, /* %Q */
|
||||
{ in_line_eoln, 0 }, /* %U */
|
||||
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
|
||||
{ in_line_eoln, 0 }, /* Tg */
|
||||
};
|
||||
|
||||
|
||||
|
|
124
mdoc_man.c
124
mdoc_man.c
|
@ -1,6 +1,6 @@
|
|||
/* $Id: mdoc_man.c,v 1.132 2019/01/04 03:17:36 schwarze Exp $ */
|
||||
/* $Id: mdoc_man.c,v 1.137 2021/07/04 15:38:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2021 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
|
||||
|
@ -113,7 +113,7 @@ static int pre_sm(DECL_ARGS);
|
|||
static void pre_sp(DECL_ARGS);
|
||||
static int pre_sect(DECL_ARGS);
|
||||
static int pre_sy(DECL_ARGS);
|
||||
static void pre_syn(const struct roff_node *);
|
||||
static void pre_syn(struct roff_node *);
|
||||
static void pre_ta(DECL_ARGS);
|
||||
static int pre_vt(DECL_ARGS);
|
||||
static int pre_xr(DECL_ARGS);
|
||||
|
@ -262,6 +262,7 @@ static const struct mdoc_man_act mdoc_man_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
|
||||
{ NULL, pre_skip, NULL, NULL, NULL }, /* Tg */
|
||||
};
|
||||
static const struct mdoc_man_act *mdoc_man_act(enum roff_tok);
|
||||
|
||||
|
@ -582,9 +583,9 @@ print_width(const struct mdoc_bl *bl, const struct roff_node *child)
|
|||
|
||||
/* Set up the current list. */
|
||||
if (chsz > sz && bl->type != LIST_tag)
|
||||
print_block(".HP", 0);
|
||||
print_block(".HP", MMAN_spc);
|
||||
else {
|
||||
print_block(".TP", 0);
|
||||
print_block(".TP", MMAN_spc);
|
||||
remain = sz + 2;
|
||||
}
|
||||
if (numeric) {
|
||||
|
@ -649,7 +650,9 @@ print_node(DECL_ARGS)
|
|||
* Break the line if we were parsed subsequent the current node.
|
||||
* This makes the page structure be more consistent.
|
||||
*/
|
||||
if (MMAN_spc & outflags && NODE_LINE & n->flags)
|
||||
if (outflags & MMAN_spc &&
|
||||
n->flags & NODE_LINE &&
|
||||
!roff_node_transparent(n))
|
||||
outflags |= MMAN_nl;
|
||||
|
||||
act = NULL;
|
||||
|
@ -657,7 +660,20 @@ print_node(DECL_ARGS)
|
|||
do_sub = 1;
|
||||
n->flags &= ~NODE_ENDED;
|
||||
|
||||
if (n->type == ROFFT_TEXT) {
|
||||
switch (n->type) {
|
||||
case ROFFT_EQN:
|
||||
case ROFFT_TBL:
|
||||
mandoc_msg(n->type == ROFFT_EQN ? MANDOCERR_EQN_TMAN :
|
||||
MANDOCERR_TBL_TMAN, n->line, n->pos, NULL);
|
||||
outflags |= MMAN_PP | MMAN_sp | MMAN_nl;
|
||||
print_word("The");
|
||||
print_line(".B \\-T man", MMAN_nl);
|
||||
print_word("output mode does not support");
|
||||
print_word(n->type == ROFFT_EQN ? "eqn(7)" : "tbl(7)");
|
||||
print_word("input.");
|
||||
outflags |= MMAN_PP | MMAN_sp | MMAN_nl;
|
||||
return;
|
||||
case ROFFT_TEXT:
|
||||
/*
|
||||
* Make sure that we don't happen to start with a
|
||||
* control character at the start of a line.
|
||||
|
@ -677,19 +693,18 @@ print_node(DECL_ARGS)
|
|||
outflags &= ~(MMAN_spc | MMAN_spc_force);
|
||||
else if (outflags & MMAN_Sm)
|
||||
outflags |= MMAN_spc;
|
||||
} else if (n->tok < ROFF_MAX) {
|
||||
(*roff_man_acts[n->tok])(meta, n);
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* Conditionally run the pre-node action handler for a
|
||||
* node.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
if (n->tok < ROFF_MAX) {
|
||||
(*roff_man_acts[n->tok])(meta, n);
|
||||
return;
|
||||
}
|
||||
act = mdoc_man_act(n->tok);
|
||||
cond = act->cond == NULL || (*act->cond)(meta, n);
|
||||
if (cond && act->pre != NULL &&
|
||||
(n->end == ENDBODY_NOT || n->child != NULL))
|
||||
do_sub = (*act->pre)(meta, n);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -776,13 +791,20 @@ post_font(DECL_ARGS)
|
|||
static void
|
||||
post_percent(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *np, *nn, *nnn;
|
||||
|
||||
if (mdoc_man_act(n->tok)->pre == pre_em)
|
||||
font_pop();
|
||||
if (n->next) {
|
||||
print_word(",");
|
||||
if (n->prev && n->prev->tok == n->tok &&
|
||||
n->next->tok == n->tok)
|
||||
|
||||
if ((nn = roff_node_next(n)) != NULL) {
|
||||
np = roff_node_prev(n);
|
||||
nnn = nn == NULL ? NULL : roff_node_next(nn);
|
||||
if (nn->tok != n->tok ||
|
||||
(np != NULL && np->tok == n->tok) ||
|
||||
(nnn != NULL && nnn->tok == n->tok))
|
||||
print_word(",");
|
||||
if (nn->tok == n->tok &&
|
||||
(nnn == NULL || nnn->tok != n->tok))
|
||||
print_word("and");
|
||||
} else {
|
||||
print_word(".");
|
||||
|
@ -850,13 +872,15 @@ post_sect(DECL_ARGS)
|
|||
|
||||
/* See mdoc_term.c, synopsis_pre() for comments. */
|
||||
static void
|
||||
pre_syn(const struct roff_node *n)
|
||||
pre_syn(struct roff_node *n)
|
||||
{
|
||||
struct roff_node *np;
|
||||
|
||||
if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
|
||||
if ((n->flags & NODE_SYNPRETTY) == 0 ||
|
||||
(np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
if (n->prev->tok == n->tok &&
|
||||
if (np->tok == n->tok &&
|
||||
MDOC_Ft != n->tok &&
|
||||
MDOC_Fo != n->tok &&
|
||||
MDOC_Fn != n->tok) {
|
||||
|
@ -864,7 +888,7 @@ pre_syn(const struct roff_node *n)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (n->prev->tok) {
|
||||
switch (np->tok) {
|
||||
case MDOC_Fd:
|
||||
case MDOC_Fn:
|
||||
case MDOC_Fo:
|
||||
|
@ -940,11 +964,10 @@ static int
|
|||
pre_bd(DECL_ARGS)
|
||||
{
|
||||
outflags &= ~(MMAN_PP | MMAN_sp | MMAN_br);
|
||||
|
||||
if (DISP_unfilled == n->norm->Bd.type ||
|
||||
DISP_literal == n->norm->Bd.type)
|
||||
if (n->norm->Bd.type == DISP_unfilled ||
|
||||
n->norm->Bd.type == DISP_literal)
|
||||
print_line(".nf", 0);
|
||||
if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
|
||||
if (n->norm->Bd.comp == 0 && roff_node_prev(n->parent) != NULL)
|
||||
outflags |= MMAN_sp;
|
||||
print_offs(n->norm->Bd.offs, 1);
|
||||
return 1;
|
||||
|
@ -976,7 +999,7 @@ post_bd(DECL_ARGS)
|
|||
}
|
||||
|
||||
/* Maybe we are inside an enclosing list? */
|
||||
if (NULL != n->parent->next)
|
||||
if (roff_node_next(n->parent) != NULL)
|
||||
mid_it();
|
||||
}
|
||||
|
||||
|
@ -1101,16 +1124,15 @@ post_bl(DECL_ARGS)
|
|||
print_line(".RE", MMAN_nl);
|
||||
assert(Bl_stack_len);
|
||||
Bl_stack_len--;
|
||||
assert(0 == Bl_stack[Bl_stack_len]);
|
||||
assert(Bl_stack[Bl_stack_len] == 0);
|
||||
} else {
|
||||
outflags |= MMAN_PP | MMAN_nl;
|
||||
outflags &= ~(MMAN_sp | MMAN_br);
|
||||
}
|
||||
|
||||
/* Maybe we are inside an enclosing list? */
|
||||
if (NULL != n->parent->next)
|
||||
if (roff_node_next(n->parent) != NULL)
|
||||
mid_it();
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1122,7 +1144,6 @@ pre_br(DECL_ARGS)
|
|||
static int
|
||||
pre_dl(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_offs("6n", 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1130,11 +1151,10 @@ pre_dl(DECL_ARGS)
|
|||
static void
|
||||
post_dl(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_line(".RE", MMAN_nl);
|
||||
|
||||
/* Maybe we are inside an enclosing list? */
|
||||
if (NULL != n->parent->next)
|
||||
if (roff_node_next(n->parent) != NULL)
|
||||
mid_it();
|
||||
}
|
||||
|
||||
|
@ -1235,15 +1255,15 @@ pre_fa(DECL_ARGS)
|
|||
static void
|
||||
post_fa(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
if (NULL != n->next && MDOC_Fa == n->next->tok)
|
||||
if ((nn = roff_node_next(n)) != NULL && nn->tok == MDOC_Fa)
|
||||
print_word(",");
|
||||
}
|
||||
|
||||
static int
|
||||
pre_fd(DECL_ARGS)
|
||||
{
|
||||
|
||||
pre_syn(n);
|
||||
font_push('B');
|
||||
return 1;
|
||||
|
@ -1252,7 +1272,6 @@ pre_fd(DECL_ARGS)
|
|||
static void
|
||||
post_fd(DECL_ARGS)
|
||||
{
|
||||
|
||||
font_pop();
|
||||
outflags |= MMAN_br;
|
||||
}
|
||||
|
@ -1260,7 +1279,6 @@ post_fd(DECL_ARGS)
|
|||
static int
|
||||
pre_fl(DECL_ARGS)
|
||||
{
|
||||
|
||||
font_push('B');
|
||||
print_word("\\-");
|
||||
if (n->child != NULL)
|
||||
|
@ -1271,12 +1289,13 @@ pre_fl(DECL_ARGS)
|
|||
static void
|
||||
post_fl(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
font_pop();
|
||||
if (!(n->child != NULL ||
|
||||
n->next == NULL ||
|
||||
n->next->type == ROFFT_TEXT ||
|
||||
n->next->flags & NODE_LINE))
|
||||
if (n->child == NULL &&
|
||||
((nn = roff_node_next(n)) != NULL &&
|
||||
nn->type != ROFFT_TEXT &&
|
||||
(nn->flags & NODE_LINE) == 0))
|
||||
outflags &= ~MMAN_spc;
|
||||
}
|
||||
|
||||
|
@ -1419,9 +1438,9 @@ pre_it(DECL_ARGS)
|
|||
case ROFFT_HEAD:
|
||||
outflags |= MMAN_PP | MMAN_nl;
|
||||
bln = n->parent->parent;
|
||||
if (0 == bln->norm->Bl.comp ||
|
||||
(NULL == n->parent->prev &&
|
||||
NULL == bln->parent->prev))
|
||||
if (bln->norm->Bl.comp == 0 ||
|
||||
(n->parent->prev == NULL &&
|
||||
roff_node_prev(bln->parent) == NULL))
|
||||
outflags |= MMAN_sp;
|
||||
outflags &= ~MMAN_br;
|
||||
switch (bln->norm->Bl.type) {
|
||||
|
@ -1633,17 +1652,22 @@ pre_nm(DECL_ARGS)
|
|||
{
|
||||
char *name;
|
||||
|
||||
if (n->type == ROFFT_BLOCK) {
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
outflags |= MMAN_Bk;
|
||||
pre_syn(n);
|
||||
}
|
||||
if (n->type != ROFFT_ELEM && n->type != ROFFT_HEAD)
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
case ROFFT_ELEM:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
name = n->child == NULL ? NULL : n->child->string;
|
||||
if (NULL == name)
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
if (n->type == ROFFT_HEAD) {
|
||||
if (NULL == n->parent->prev)
|
||||
if (roff_node_prev(n->parent) == NULL)
|
||||
outflags |= MMAN_sp;
|
||||
print_block(".HP", 0);
|
||||
printf(" %dn", man_strlen(name) + 1);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $Id: mdoc_markdown.c,v 1.31 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/* $Id: mdoc_markdown.c,v 1.37 2021/08/10 12:55:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -13,7 +13,11 @@
|
|||
* 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.
|
||||
*
|
||||
* Markdown formatter for mdoc(7) used by mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -29,16 +33,16 @@
|
|||
#include "main.h"
|
||||
|
||||
struct md_act {
|
||||
int (*cond)(struct roff_node *n);
|
||||
int (*pre)(struct roff_node *n);
|
||||
void (*post)(struct roff_node *n);
|
||||
int (*cond)(struct roff_node *);
|
||||
int (*pre)(struct roff_node *);
|
||||
void (*post)(struct roff_node *);
|
||||
const char *prefix; /* pre-node string constant */
|
||||
const char *suffix; /* post-node string constant */
|
||||
};
|
||||
|
||||
static void md_nodelist(struct roff_node *);
|
||||
static void md_node(struct roff_node *);
|
||||
static const char *md_stack(char c);
|
||||
static const char *md_stack(char);
|
||||
static void md_preword(void);
|
||||
static void md_rawword(const char *);
|
||||
static void md_word(const char *);
|
||||
|
@ -226,6 +230,7 @@ static const struct md_act md_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{ NULL, NULL, md_post_pc, NULL, NULL }, /* %Q */
|
||||
{ NULL, md_pre_Lk, md_post_pc, NULL, NULL }, /* %U */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
|
||||
{ NULL, md_pre_skip, NULL, NULL, NULL }, /* Tg */
|
||||
};
|
||||
static const struct md_act *md_act(enum roff_tok);
|
||||
|
||||
|
@ -309,7 +314,9 @@ md_node(struct roff_node *n)
|
|||
|
||||
if (outflags & MD_nonl)
|
||||
outflags &= ~(MD_nl | MD_sp);
|
||||
else if (outflags & MD_spc && n->flags & NODE_LINE)
|
||||
else if (outflags & MD_spc &&
|
||||
n->flags & NODE_LINE &&
|
||||
!roff_node_transparent(n))
|
||||
outflags |= MD_nl;
|
||||
|
||||
act = NULL;
|
||||
|
@ -596,16 +603,18 @@ md_word(const char *s)
|
|||
md_rawword("markdown");
|
||||
continue;
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTCB:
|
||||
nextfont = "**";
|
||||
break;
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTCI:
|
||||
nextfont = "*";
|
||||
break;
|
||||
case ESCAPE_FONTBI:
|
||||
nextfont = "***";
|
||||
break;
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTCR:
|
||||
case ESCAPE_FONTROMAN:
|
||||
nextfont = "";
|
||||
break;
|
||||
|
@ -786,14 +795,17 @@ md_post_word(struct roff_node *n)
|
|||
static void
|
||||
md_post_pc(struct roff_node *n)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
md_post_raw(n);
|
||||
if (n->parent->tok != MDOC_Rs)
|
||||
return;
|
||||
if (n->next != NULL) {
|
||||
|
||||
if ((nn = roff_node_next(n)) != NULL) {
|
||||
md_word(",");
|
||||
if (n->prev != NULL &&
|
||||
n->prev->tok == n->tok &&
|
||||
n->next->tok == n->tok)
|
||||
if (nn->tok == n->tok &&
|
||||
(nn = roff_node_prev(n)) != NULL &&
|
||||
nn->tok == n->tok)
|
||||
md_word("and");
|
||||
} else {
|
||||
md_word(".");
|
||||
|
@ -810,10 +822,13 @@ md_pre_skip(struct roff_node *n)
|
|||
static void
|
||||
md_pre_syn(struct roff_node *n)
|
||||
{
|
||||
if (n->prev == NULL || ! (n->flags & NODE_SYNPRETTY))
|
||||
struct roff_node *np;
|
||||
|
||||
if ((n->flags & NODE_SYNPRETTY) == 0 ||
|
||||
(np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
if (n->prev->tok == n->tok &&
|
||||
if (np->tok == n->tok &&
|
||||
n->tok != MDOC_Ft &&
|
||||
n->tok != MDOC_Fo &&
|
||||
n->tok != MDOC_Fn) {
|
||||
|
@ -821,7 +836,7 @@ md_pre_syn(struct roff_node *n)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (n->prev->tok) {
|
||||
switch (np->tok) {
|
||||
case MDOC_Fd:
|
||||
case MDOC_Fn:
|
||||
case MDOC_Fo:
|
||||
|
@ -1052,7 +1067,9 @@ md_pre_Fa(struct roff_node *n)
|
|||
static void
|
||||
md_post_Fa(struct roff_node *n)
|
||||
{
|
||||
if (n->next != NULL && n->next->tok == MDOC_Fa)
|
||||
struct roff_node *nn;
|
||||
|
||||
if ((nn = roff_node_next(n)) != NULL && nn->tok == MDOC_Fa)
|
||||
md_word(",");
|
||||
}
|
||||
|
||||
|
@ -1074,9 +1091,11 @@ md_post_Fd(struct roff_node *n)
|
|||
static void
|
||||
md_post_Fl(struct roff_node *n)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
md_post_raw(n);
|
||||
if (n->child == NULL && n->next != NULL &&
|
||||
n->next->type != ROFFT_TEXT && !(n->next->flags & NODE_LINE))
|
||||
if (n->child == NULL && (nn = roff_node_next(n)) != NULL &&
|
||||
nn->type != ROFFT_TEXT && (nn->flags & NODE_LINE) == 0)
|
||||
outflags &= ~MD_spc;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mdoc_state.c,v 1.15 2019/01/01 07:42:04 schwarze Exp $ */
|
||||
/* $Id: mdoc_state.c,v 1.17 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -14,6 +14,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -157,6 +159,7 @@ static const state_handler state_handlers[MDOC_MAX - MDOC_Dd] = {
|
|||
NULL, /* %Q */
|
||||
NULL, /* %U */
|
||||
NULL, /* Ta */
|
||||
NULL, /* Tg */
|
||||
};
|
||||
|
||||
|
||||
|
|
440
mdoc_term.c
440
mdoc_term.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mdoc_term.c,v 1.374 2019/06/27 12:20:18 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.380 2020/04/06 10:16:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -15,6 +15,9 @@
|
|||
* 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.
|
||||
*
|
||||
* Plain text formatter for mdoc(7), used by mandoc(1)
|
||||
* for ASCII, UTF-8, PostScript, and PDF output.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -33,7 +36,7 @@
|
|||
#include "mdoc.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "tag.h"
|
||||
#include "term_tag.h"
|
||||
#include "main.h"
|
||||
|
||||
struct termpair {
|
||||
|
@ -54,14 +57,12 @@ struct mdoc_term_act {
|
|||
static int a2width(const struct termp *, const char *);
|
||||
|
||||
static void print_bvspace(struct termp *,
|
||||
const struct roff_node *,
|
||||
const struct roff_node *);
|
||||
struct roff_node *, struct roff_node *);
|
||||
static void print_mdoc_node(DECL_ARGS);
|
||||
static void print_mdoc_nodelist(DECL_ARGS);
|
||||
static void print_mdoc_head(struct termp *, const struct roff_meta *);
|
||||
static void print_mdoc_foot(struct termp *, const struct roff_meta *);
|
||||
static void synopsis_pre(struct termp *,
|
||||
const struct roff_node *);
|
||||
static void synopsis_pre(struct termp *, struct roff_node *);
|
||||
|
||||
static void termp____post(DECL_ARGS);
|
||||
static void termp__t_post(DECL_ARGS);
|
||||
|
@ -91,11 +92,8 @@ static int termp_bf_pre(DECL_ARGS);
|
|||
static int termp_bk_pre(DECL_ARGS);
|
||||
static int termp_bl_pre(DECL_ARGS);
|
||||
static int termp_bold_pre(DECL_ARGS);
|
||||
static int termp_cd_pre(DECL_ARGS);
|
||||
static int termp_d1_pre(DECL_ARGS);
|
||||
static int termp_eo_pre(DECL_ARGS);
|
||||
static int termp_em_pre(DECL_ARGS);
|
||||
static int termp_er_pre(DECL_ARGS);
|
||||
static int termp_ex_pre(DECL_ARGS);
|
||||
static int termp_fa_pre(DECL_ARGS);
|
||||
static int termp_fd_pre(DECL_ARGS);
|
||||
|
@ -117,8 +115,6 @@ static int termp_skip_pre(DECL_ARGS);
|
|||
static int termp_sm_pre(DECL_ARGS);
|
||||
static int termp_pp_pre(DECL_ARGS);
|
||||
static int termp_ss_pre(DECL_ARGS);
|
||||
static int termp_sy_pre(DECL_ARGS);
|
||||
static int termp_tag_pre(DECL_ARGS);
|
||||
static int termp_under_pre(DECL_ARGS);
|
||||
static int termp_vt_pre(DECL_ARGS);
|
||||
static int termp_xr_pre(DECL_ARGS);
|
||||
|
@ -142,11 +138,11 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{ termp_an_pre, NULL }, /* An */
|
||||
{ termp_ap_pre, NULL }, /* Ap */
|
||||
{ termp_under_pre, NULL }, /* Ar */
|
||||
{ termp_cd_pre, NULL }, /* Cd */
|
||||
{ termp_fd_pre, NULL }, /* Cd */
|
||||
{ termp_bold_pre, NULL }, /* Cm */
|
||||
{ termp_li_pre, NULL }, /* Dv */
|
||||
{ termp_er_pre, NULL }, /* Er */
|
||||
{ termp_tag_pre, NULL }, /* Ev */
|
||||
{ NULL, NULL }, /* Er */
|
||||
{ NULL, NULL }, /* Ev */
|
||||
{ termp_ex_pre, NULL }, /* Ex */
|
||||
{ termp_fa_pre, NULL }, /* Fa */
|
||||
{ termp_fd_pre, termp_fd_post }, /* Fd */
|
||||
|
@ -193,7 +189,7 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{ termp_quote_pre, termp_quote_post }, /* Dq */
|
||||
{ NULL, NULL }, /* Ec */ /* FIXME: no space */
|
||||
{ NULL, NULL }, /* Ef */
|
||||
{ termp_em_pre, NULL }, /* Em */
|
||||
{ termp_under_pre, NULL }, /* Em */
|
||||
{ termp_eo_pre, termp_eo_post }, /* Eo */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Fx */
|
||||
{ termp_bold_pre, NULL }, /* Ms */
|
||||
|
@ -216,7 +212,7 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{ termp_quote_pre, termp_quote_post }, /* Sq */
|
||||
{ termp_sm_pre, NULL }, /* Sm */
|
||||
{ termp_under_pre, NULL }, /* Sx */
|
||||
{ termp_sy_pre, NULL }, /* Sy */
|
||||
{ termp_bold_pre, NULL }, /* Sy */
|
||||
{ NULL, NULL }, /* Tn */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Ux */
|
||||
{ NULL, NULL }, /* Xc */
|
||||
|
@ -245,10 +241,9 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = {
|
|||
{ NULL, termp____post }, /* %Q */
|
||||
{ NULL, termp____post }, /* %U */
|
||||
{ NULL, NULL }, /* Ta */
|
||||
{ termp_skip_pre, NULL }, /* Tg */
|
||||
};
|
||||
|
||||
static int fn_prio;
|
||||
|
||||
|
||||
void
|
||||
terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
|
@ -301,7 +296,6 @@ terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
|||
static void
|
||||
print_mdoc_nodelist(DECL_ARGS)
|
||||
{
|
||||
|
||||
while (n != NULL) {
|
||||
print_mdoc_node(p, pair, meta, n);
|
||||
n = n->next;
|
||||
|
@ -341,6 +335,10 @@ print_mdoc_node(DECL_ARGS)
|
|||
memset(&npair, 0, sizeof(struct termpair));
|
||||
npair.ppair = pair;
|
||||
|
||||
if (n->flags & NODE_ID && n->tok != MDOC_Pp &&
|
||||
(n->tok != MDOC_It || n->type != ROFFT_BLOCK))
|
||||
term_tag_write(n, p->line);
|
||||
|
||||
/*
|
||||
* Keeps only work until the end of a line. If a keep was
|
||||
* invoked in a prior line, revert it to PREKEEP.
|
||||
|
@ -580,29 +578,20 @@ a2width(const struct termp *p, const char *v)
|
|||
* too.
|
||||
*/
|
||||
static void
|
||||
print_bvspace(struct termp *p,
|
||||
const struct roff_node *bl,
|
||||
const struct roff_node *n)
|
||||
print_bvspace(struct termp *p, struct roff_node *bl, struct roff_node *n)
|
||||
{
|
||||
const struct roff_node *nn;
|
||||
|
||||
assert(n);
|
||||
struct roff_node *nn;
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (MDOC_Bd == bl->tok && bl->norm->Bd.comp)
|
||||
return;
|
||||
if (MDOC_Bl == bl->tok && bl->norm->Bl.comp)
|
||||
if ((bl->tok == MDOC_Bd && bl->norm->Bd.comp) ||
|
||||
(bl->tok == MDOC_Bl && bl->norm->Bl.comp))
|
||||
return;
|
||||
|
||||
/* Do not vspace directly after Ss/Sh. */
|
||||
|
||||
nn = n;
|
||||
while (nn->prev != NULL &&
|
||||
(nn->prev->type == ROFFT_COMMENT ||
|
||||
nn->prev->flags & NODE_NOPRT))
|
||||
nn = nn->prev;
|
||||
while (nn->prev == NULL) {
|
||||
while (roff_node_prev(nn) == NULL) {
|
||||
do {
|
||||
nn = nn->parent;
|
||||
if (nn->type == ROFFT_ROOT)
|
||||
|
@ -615,22 +604,18 @@ print_bvspace(struct termp *p,
|
|||
break;
|
||||
}
|
||||
|
||||
/* A `-column' does not assert vspace within the list. */
|
||||
/*
|
||||
* No vertical space after:
|
||||
* items in .Bl -column
|
||||
* items without a body in .Bl -diag
|
||||
*/
|
||||
|
||||
if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type)
|
||||
if (n->prev && MDOC_It == n->prev->tok)
|
||||
return;
|
||||
|
||||
/* A `-diag' without body does not vspace. */
|
||||
|
||||
if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type)
|
||||
if (n->prev && MDOC_It == n->prev->tok) {
|
||||
assert(n->prev->body);
|
||||
if (NULL == n->prev->body->child)
|
||||
return;
|
||||
}
|
||||
|
||||
term_vspace(p);
|
||||
if (bl->tok != MDOC_Bl ||
|
||||
n->prev == NULL || n->prev->tok != MDOC_It ||
|
||||
(bl->norm->Bl.type != LIST_column &&
|
||||
(bl->norm->Bl.type != LIST_diag ||
|
||||
n->prev->body->child != NULL)))
|
||||
term_vspace(p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -646,6 +631,8 @@ termp_it_pre(DECL_ARGS)
|
|||
|
||||
if (n->type == ROFFT_BLOCK) {
|
||||
print_bvspace(p, n->parent->parent, n);
|
||||
if (n->flags & NODE_ID)
|
||||
term_tag_write(n, p->line);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1018,38 +1005,44 @@ termp_nm_pre(DECL_ARGS)
|
|||
p->flags |= TERMP_HANG;
|
||||
}
|
||||
}
|
||||
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
return 1;
|
||||
return termp_bold_pre(p, pair, meta, n);
|
||||
}
|
||||
|
||||
static void
|
||||
termp_nm_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BLOCK) {
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||
} else if (n->type == ROFFT_HEAD &&
|
||||
NULL != n->next && NULL != n->next->child) {
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
if (n->next == NULL || n->next->child == NULL)
|
||||
break;
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
|
||||
p->trailspace = 0;
|
||||
} else if (n->type == ROFFT_BODY && n->child != NULL)
|
||||
term_flushln(p);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->child != NULL)
|
||||
term_flushln(p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
termp_fl_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
termp_tag_pre(p, pair, meta, n);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, "\\-");
|
||||
|
||||
if (!(n->child == NULL &&
|
||||
(n->next == NULL ||
|
||||
n->next->type == ROFFT_TEXT ||
|
||||
n->next->flags & NODE_LINE)))
|
||||
if (n->child != NULL ||
|
||||
((nn = roff_node_next(n)) != NULL &&
|
||||
nn->type != ROFFT_TEXT &&
|
||||
(nn->flags & NODE_LINE) == 0))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
return 1;
|
||||
|
@ -1058,10 +1051,11 @@ termp_fl_pre(DECL_ARGS)
|
|||
static int
|
||||
termp__a_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
if (n->prev && MDOC__A == n->prev->tok)
|
||||
if (NULL == n->next || MDOC__A != n->next->tok)
|
||||
term_word(p, "and");
|
||||
if ((nn = roff_node_prev(n)) != NULL && nn->tok == MDOC__A &&
|
||||
((nn = roff_node_next(n)) == NULL || nn->tok != MDOC__A))
|
||||
term_word(p, "and");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1102,10 +1096,9 @@ termp_ns_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_rs_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (SEC_SEE_ALSO != n->sec)
|
||||
return 1;
|
||||
if (n->type == ROFFT_BLOCK && n->prev != NULL)
|
||||
if (n->type == ROFFT_BLOCK && roff_node_prev(n) != NULL)
|
||||
term_vspace(p);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1120,7 +1113,6 @@ termp_ex_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_nd_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BODY)
|
||||
term_word(p, "\\(en");
|
||||
return 1;
|
||||
|
@ -1129,14 +1121,20 @@ termp_nd_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_bl_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
return n->type != ROFFT_HEAD;
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
term_newln(p);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
termp_bl_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_BLOCK)
|
||||
return;
|
||||
term_newln(p);
|
||||
|
@ -1150,7 +1148,6 @@ termp_bl_post(DECL_ARGS)
|
|||
static int
|
||||
termp_xr_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (NULL == (n = n->child))
|
||||
return 0;
|
||||
|
||||
|
@ -1179,13 +1176,12 @@ termp_xr_pre(DECL_ARGS)
|
|||
* macro combos).
|
||||
*/
|
||||
static void
|
||||
synopsis_pre(struct termp *p, const struct roff_node *n)
|
||||
synopsis_pre(struct termp *p, struct roff_node *n)
|
||||
{
|
||||
/*
|
||||
* Obviously, if we're not in a SYNOPSIS or no prior macros
|
||||
* exist, do nothing.
|
||||
*/
|
||||
if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags))
|
||||
struct roff_node *np;
|
||||
|
||||
if ((n->flags & NODE_SYNPRETTY) == 0 ||
|
||||
(np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -1193,7 +1189,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n)
|
|||
* newline and return. UNLESS we're `Fo', `Fn', `Fn', in which
|
||||
* case we soldier on.
|
||||
*/
|
||||
if (n->prev->tok == n->tok &&
|
||||
if (np->tok == n->tok &&
|
||||
MDOC_Ft != n->tok &&
|
||||
MDOC_Fo != n->tok &&
|
||||
MDOC_Fn != n->tok) {
|
||||
|
@ -1206,7 +1202,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n)
|
|||
* another (or Fn/Fo, which we've let slip through) then assert
|
||||
* vertical space, else only newline and move on.
|
||||
*/
|
||||
switch (n->prev->tok) {
|
||||
switch (np->tok) {
|
||||
case MDOC_Fd:
|
||||
case MDOC_Fn:
|
||||
case MDOC_Fo:
|
||||
|
@ -1215,7 +1211,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n)
|
|||
term_vspace(p);
|
||||
break;
|
||||
case MDOC_Ft:
|
||||
if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
|
||||
if (n->tok != MDOC_Fn && n->tok != MDOC_Fo) {
|
||||
term_vspace(p);
|
||||
break;
|
||||
}
|
||||
|
@ -1229,24 +1225,22 @@ synopsis_pre(struct termp *p, const struct roff_node *n)
|
|||
static int
|
||||
termp_vt_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_ELEM) {
|
||||
synopsis_pre(p, n);
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
} else if (n->type == ROFFT_BLOCK) {
|
||||
switch (n->type) {
|
||||
case ROFFT_ELEM:
|
||||
return termp_ft_pre(p, pair, meta, n);
|
||||
case ROFFT_BLOCK:
|
||||
synopsis_pre(p, n);
|
||||
return 1;
|
||||
} else if (n->type == ROFFT_HEAD)
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
default:
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
termp_bold_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
termp_tag_pre(p, pair, meta, n);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1254,7 +1248,6 @@ termp_bold_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_fd_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
synopsis_pre(p, n);
|
||||
return termp_bold_pre(p, pair, meta, n);
|
||||
}
|
||||
|
@ -1262,13 +1255,13 @@ termp_fd_pre(DECL_ARGS)
|
|||
static void
|
||||
termp_fd_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_newln(p);
|
||||
}
|
||||
|
||||
static int
|
||||
termp_sh_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *np;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
|
@ -1276,30 +1269,20 @@ termp_sh_pre(DECL_ARGS)
|
|||
* Vertical space before sections, except
|
||||
* when the previous section was empty.
|
||||
*/
|
||||
if (n->prev == NULL ||
|
||||
n->prev->tok != MDOC_Sh ||
|
||||
(n->prev->body != NULL &&
|
||||
n->prev->body->child != NULL))
|
||||
if ((np = roff_node_prev(n)) == NULL ||
|
||||
np->tok != MDOC_Sh ||
|
||||
(np->body != NULL && np->body->child != NULL))
|
||||
term_vspace(p);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
break;
|
||||
return termp_bold_pre(p, pair, meta, n);
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = term_len(p, p->defindent);
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
switch (n->sec) {
|
||||
case SEC_DESCRIPTION:
|
||||
fn_prio = 0;
|
||||
break;
|
||||
case SEC_AUTHORS:
|
||||
if (n->sec == SEC_AUTHORS)
|
||||
p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1310,7 +1293,6 @@ termp_sh_pre(DECL_ARGS)
|
|||
static void
|
||||
termp_sh_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
term_newln(p);
|
||||
|
@ -1327,15 +1309,13 @@ termp_sh_post(DECL_ARGS)
|
|||
static void
|
||||
termp_lb_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags)
|
||||
if (n->sec == SEC_LIBRARY && n->flags & NODE_LINE)
|
||||
term_newln(p);
|
||||
}
|
||||
|
||||
static int
|
||||
termp_d1_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_BLOCK)
|
||||
return 1;
|
||||
term_newln(p);
|
||||
|
@ -1349,11 +1329,8 @@ termp_d1_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_ft_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
/* NB: NODE_LINE does not effect this! */
|
||||
synopsis_pre(p, n);
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1362,11 +1339,9 @@ termp_fn_pre(DECL_ARGS)
|
|||
size_t rmargin = 0;
|
||||
int pretty;
|
||||
|
||||
pretty = NODE_SYNPRETTY & n->flags;
|
||||
|
||||
synopsis_pre(p, n);
|
||||
|
||||
if (NULL == (n = n->child))
|
||||
pretty = n->flags & NODE_SYNPRETTY;
|
||||
if ((n = n->child) == NULL)
|
||||
return 0;
|
||||
|
||||
if (pretty) {
|
||||
|
@ -1380,9 +1355,6 @@ termp_fn_pre(DECL_ARGS)
|
|||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (n->sec == SEC_DESCRIPTION || n->sec == SEC_CUSTOM)
|
||||
tag_put(n->string, ++fn_prio, p->line);
|
||||
|
||||
if (pretty) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
|
||||
|
@ -1417,7 +1389,6 @@ termp_fn_pre(DECL_ARGS)
|
|||
term_word(p, ";");
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1426,23 +1397,25 @@ termp_fa_pre(DECL_ARGS)
|
|||
{
|
||||
const struct roff_node *nn;
|
||||
|
||||
if (n->parent->tok != MDOC_Fo) {
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
}
|
||||
if (n->parent->tok != MDOC_Fo)
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
for (nn = n->child; nn != NULL; nn = nn->next) {
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
p->flags |= TERMP_NBRWORD;
|
||||
term_word(p, nn->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (nn->next || (n->next && n->next->tok == MDOC_Fa)) {
|
||||
if (nn->next != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if (n->child != NULL &&
|
||||
(nn = roff_node_next(n)) != NULL &&
|
||||
nn->tok == MDOC_Fa) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1522,30 +1495,23 @@ termp_xx_post(DECL_ARGS)
|
|||
static void
|
||||
termp_pf_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
|
||||
if (n->next != NULL && (n->next->flags & NODE_LINE) == 0)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_ss_pre(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
term_newln(p);
|
||||
for (nn = n->prev; nn != NULL; nn = nn->prev)
|
||||
if (nn->type != ROFFT_COMMENT &&
|
||||
(nn->flags & NODE_NOPRT) == 0)
|
||||
break;
|
||||
if (nn != NULL)
|
||||
if (roff_node_prev(n) == NULL)
|
||||
term_newln(p);
|
||||
else
|
||||
term_vspace(p);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
p->tcol->offset = term_len(p, (p->defindent+1)/2);
|
||||
break;
|
||||
return termp_bold_pre(p, pair, meta, n);
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = term_len(p, p->defindent);
|
||||
term_tab_set(p, NULL);
|
||||
|
@ -1555,34 +1521,21 @@ termp_ss_pre(DECL_ARGS)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
termp_ss_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_HEAD || n->type == ROFFT_BODY)
|
||||
term_newln(p);
|
||||
}
|
||||
|
||||
static int
|
||||
termp_cd_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
synopsis_pre(p, n);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_in_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
synopsis_pre(p, n);
|
||||
|
||||
if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags) {
|
||||
if (n->flags & NODE_SYNPRETTY && n->flags & NODE_LINE) {
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, "#include");
|
||||
term_word(p, "<");
|
||||
|
@ -1590,7 +1543,6 @@ termp_in_pre(DECL_ARGS)
|
|||
term_word(p, "<");
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
}
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1598,36 +1550,32 @@ termp_in_pre(DECL_ARGS)
|
|||
static void
|
||||
termp_in_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
if (n->flags & NODE_SYNPRETTY)
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ">");
|
||||
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
if (n->flags & NODE_SYNPRETTY)
|
||||
term_fontpop(p);
|
||||
}
|
||||
|
||||
static int
|
||||
termp_pp_pre(DECL_ARGS)
|
||||
{
|
||||
fn_prio = 0;
|
||||
term_vspace(p);
|
||||
if (n->flags & NODE_ID)
|
||||
term_tag_write(n, p->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_skip_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_quote_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM)
|
||||
return 1;
|
||||
|
||||
|
@ -1784,17 +1732,15 @@ termp_eo_post(DECL_ARGS)
|
|||
static int
|
||||
termp_fo_pre(DECL_ARGS)
|
||||
{
|
||||
size_t rmargin = 0;
|
||||
int pretty;
|
||||
size_t rmargin;
|
||||
|
||||
pretty = NODE_SYNPRETTY & n->flags;
|
||||
|
||||
if (n->type == ROFFT_BLOCK) {
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
synopsis_pre(p, n);
|
||||
return 1;
|
||||
} else if (n->type == ROFFT_BODY) {
|
||||
if (pretty) {
|
||||
rmargin = p->tcol->rmargin;
|
||||
case ROFFT_BODY:
|
||||
rmargin = p->tcol->rmargin;
|
||||
if (n->flags & NODE_SYNPRETTY) {
|
||||
p->tcol->rmargin = p->tcol->offset + term_len(p, 4);
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND |
|
||||
TERMP_HANG;
|
||||
|
@ -1802,7 +1748,7 @@ termp_fo_pre(DECL_ARGS)
|
|||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (pretty) {
|
||||
if (n->flags & NODE_SYNPRETTY) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND |
|
||||
TERMP_HANG);
|
||||
|
@ -1811,30 +1757,21 @@ termp_fo_pre(DECL_ARGS)
|
|||
p->tcol->rmargin = rmargin;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return termp_bold_pre(p, pair, meta, n);
|
||||
}
|
||||
|
||||
if (NULL == n->child)
|
||||
return 0;
|
||||
|
||||
/* XXX: we drop non-initial arguments as per groff. */
|
||||
|
||||
assert(n->child->string);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, n->child->string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
termp_fo_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_BODY)
|
||||
return;
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ")");
|
||||
|
||||
if (NODE_SYNPRETTY & n->flags) {
|
||||
if (n->flags & NODE_SYNPRETTY) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ";");
|
||||
term_flushln(p);
|
||||
|
@ -1844,29 +1781,30 @@ termp_fo_post(DECL_ARGS)
|
|||
static int
|
||||
termp_bf_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_HEAD)
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
else if (n->type != ROFFT_BODY)
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
|
||||
if (FONT_Em == n->norm->Bf.font)
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
else if (FONT_Sy == n->norm->Bf.font)
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
else
|
||||
term_fontpush(p, TERMFONT_NONE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
switch (n->norm->Bf.font) {
|
||||
case FONT_Em:
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
case FONT_Sy:
|
||||
return termp_bold_pre(p, pair, meta, n);
|
||||
default:
|
||||
return termp_li_pre(p, pair, meta, n);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
termp_sm_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (NULL == n->child)
|
||||
if (n->child == NULL)
|
||||
p->flags ^= TERMP_NONOSPACE;
|
||||
else if (0 == strcmp("on", n->child->string))
|
||||
else if (strcmp(n->child->string, "on") == 0)
|
||||
p->flags &= ~TERMP_NONOSPACE;
|
||||
else
|
||||
p->flags |= TERMP_NONOSPACE;
|
||||
|
@ -1880,7 +1818,6 @@ termp_sm_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_ap_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "'");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
@ -1890,24 +1827,26 @@ termp_ap_pre(DECL_ARGS)
|
|||
static void
|
||||
termp____post(DECL_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
|
||||
/*
|
||||
* Handle lists of authors. In general, print each followed by
|
||||
* a comma. Don't print the comma if there are only two
|
||||
* authors.
|
||||
*/
|
||||
if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok)
|
||||
if (NULL == n->next->next || MDOC__A != n->next->next->tok)
|
||||
if (NULL == n->prev || MDOC__A != n->prev->tok)
|
||||
return;
|
||||
if (n->tok == MDOC__A &&
|
||||
(nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A &&
|
||||
((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) &&
|
||||
((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A))
|
||||
return;
|
||||
|
||||
/* TODO: %U. */
|
||||
|
||||
if (NULL == n->parent || MDOC_Rs != n->parent->tok)
|
||||
if (n->parent == NULL || n->parent->tok != MDOC_Rs)
|
||||
return;
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (NULL == n->next) {
|
||||
if (roff_node_next(n) == NULL) {
|
||||
term_word(p, ".");
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
} else
|
||||
|
@ -1917,8 +1856,6 @@ termp____post(DECL_ARGS)
|
|||
static int
|
||||
termp_li_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
termp_tag_pre(p, pair, meta, n);
|
||||
term_fontpush(p, TERMFONT_NONE);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1968,7 +1905,6 @@ termp_lk_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_bk_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
break;
|
||||
|
@ -1981,106 +1917,46 @@ termp_bk_pre(DECL_ARGS)
|
|||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
termp_bk_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BODY)
|
||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are in an `Rs' and there is a journal present,
|
||||
* then quote us instead of underlining us (for disambiguation).
|
||||
*/
|
||||
static void
|
||||
termp__t_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
/*
|
||||
* If we're in an `Rs' and there's a journal present, then quote
|
||||
* us instead of underlining us (for disambiguation).
|
||||
*/
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
if (n->parent != NULL && n->parent->tok == MDOC_Rs &&
|
||||
n->parent->norm->Rs.quote_T)
|
||||
termp_quote_post(p, pair, meta, n);
|
||||
|
||||
termp____post(p, pair, meta, n);
|
||||
}
|
||||
|
||||
static int
|
||||
termp__t_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
/*
|
||||
* If we're in an `Rs' and there's a journal present, then quote
|
||||
* us instead of underlining us (for disambiguation).
|
||||
*/
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
if (n->parent != NULL && n->parent->tok == MDOC_Rs &&
|
||||
n->parent->norm->Rs.quote_T)
|
||||
return termp_quote_pre(p, pair, meta, n);
|
||||
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
else
|
||||
return termp_under_pre(p, pair, meta, n);
|
||||
}
|
||||
|
||||
static int
|
||||
termp_under_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_em_pre(DECL_ARGS)
|
||||
{
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT)
|
||||
tag_put(n->child->string, 0, p->line);
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_sy_pre(DECL_ARGS)
|
||||
{
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT)
|
||||
tag_put(n->child->string, 0, p->line);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_er_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->sec == SEC_ERRORS &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Bq &&
|
||||
n->parent->parent->parent->tok == MDOC_It)))
|
||||
tag_put(n->child->string, 1, p->line);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_tag_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT &&
|
||||
(n->prev == NULL ||
|
||||
(n->prev->type == ROFFT_TEXT &&
|
||||
strcmp(n->prev->string, "|") == 0)) &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Xo &&
|
||||
n->parent->parent->prev == NULL &&
|
||||
n->parent->parent->parent->tok == MDOC_It)))
|
||||
tag_put(n->child->string, 1, p->line);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_abort_pre(DECL_ARGS)
|
||||
{
|
||||
|
|
531
mdoc_validate.c
531
mdoc_validate.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: mdoc_validate.c,v 1.374 2019/06/27 15:07:30 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.389 2021/07/18 11:41:23 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -15,6 +15,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Validation module for mdoc(7) syntax trees used by mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -39,6 +41,7 @@
|
|||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
#include "libmdoc.h"
|
||||
#include "tag.h"
|
||||
|
||||
/* FIXME: .Bl -diag can't have non-text children in HEAD. */
|
||||
|
||||
|
@ -82,16 +85,18 @@ 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_em(POST_ARGS);
|
||||
static void post_en(POST_ARGS);
|
||||
static void post_er(POST_ARGS);
|
||||
static void post_es(POST_ARGS);
|
||||
static void post_eoln(POST_ARGS);
|
||||
static void post_ex(POST_ARGS);
|
||||
static void post_fa(POST_ARGS);
|
||||
static void post_fl(POST_ARGS);
|
||||
static void post_fn(POST_ARGS);
|
||||
static void post_fname(POST_ARGS);
|
||||
static void post_fo(POST_ARGS);
|
||||
static void post_hyph(POST_ARGS);
|
||||
static void post_ignpar(POST_ARGS);
|
||||
static void post_it(POST_ARGS);
|
||||
static void post_lb(POST_ARGS);
|
||||
static void post_nd(POST_ARGS);
|
||||
|
@ -104,6 +109,7 @@ static void post_prevpar(POST_ARGS);
|
|||
static void post_root(POST_ARGS);
|
||||
static void post_rs(POST_ARGS);
|
||||
static void post_rv(POST_ARGS);
|
||||
static void post_section(POST_ARGS);
|
||||
static void post_sh(POST_ARGS);
|
||||
static void post_sh_head(POST_ARGS);
|
||||
static void post_sh_name(POST_ARGS);
|
||||
|
@ -113,6 +119,8 @@ 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_tag(POST_ARGS);
|
||||
static void post_tg(POST_ARGS);
|
||||
static void post_useless(POST_ARGS);
|
||||
static void post_xr(POST_ARGS);
|
||||
static void post_xx(POST_ARGS);
|
||||
|
@ -122,7 +130,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
|||
post_dt, /* Dt */
|
||||
post_os, /* Os */
|
||||
post_sh, /* Sh */
|
||||
post_ignpar, /* Ss */
|
||||
post_section, /* Ss */
|
||||
post_par, /* Pp */
|
||||
post_display, /* D1 */
|
||||
post_display, /* Dl */
|
||||
|
@ -136,19 +144,19 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
|||
NULL, /* Ap */
|
||||
post_defaults, /* Ar */
|
||||
NULL, /* Cd */
|
||||
post_delim_nb, /* Cm */
|
||||
post_delim_nb, /* Dv */
|
||||
post_delim_nb, /* Er */
|
||||
post_delim_nb, /* Ev */
|
||||
post_tag, /* Cm */
|
||||
post_tag, /* Dv */
|
||||
post_er, /* Er */
|
||||
post_tag, /* Ev */
|
||||
post_ex, /* Ex */
|
||||
post_fa, /* Fa */
|
||||
NULL, /* Fd */
|
||||
post_delim_nb, /* Fl */
|
||||
post_fl, /* Fl */
|
||||
post_fn, /* Fn */
|
||||
post_delim_nb, /* Ft */
|
||||
post_delim_nb, /* Ic */
|
||||
post_tag, /* Ic */
|
||||
post_delim_nb, /* In */
|
||||
post_defaults, /* Li */
|
||||
post_tag, /* Li */
|
||||
post_nd, /* Nd */
|
||||
post_nm, /* Nm */
|
||||
post_delim_nb, /* Op */
|
||||
|
@ -156,7 +164,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
|||
post_defaults, /* Pa */
|
||||
post_rv, /* Rv */
|
||||
post_st, /* St */
|
||||
post_delim_nb, /* Va */
|
||||
post_tag, /* Va */
|
||||
post_delim_nb, /* Vt */
|
||||
post_xr, /* Xr */
|
||||
NULL, /* %A */
|
||||
|
@ -186,11 +194,11 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
|||
NULL, /* Dq */
|
||||
NULL, /* Ec */
|
||||
NULL, /* Ef */
|
||||
post_delim_nb, /* Em */
|
||||
post_em, /* Em */
|
||||
NULL, /* Eo */
|
||||
post_xx, /* Fx */
|
||||
post_delim_nb, /* Ms */
|
||||
NULL, /* No */
|
||||
post_tag, /* Ms */
|
||||
post_tag, /* No */
|
||||
post_ns, /* Ns */
|
||||
post_xx, /* Nx */
|
||||
post_xx, /* Ox */
|
||||
|
@ -209,7 +217,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
|||
post_delim_nb, /* Sq */
|
||||
post_sm, /* Sm */
|
||||
post_sx, /* Sx */
|
||||
post_delim_nb, /* Sy */
|
||||
post_em, /* Sy */
|
||||
post_useless, /* Tn */
|
||||
post_xx, /* Ux */
|
||||
NULL, /* Xc */
|
||||
|
@ -238,6 +246,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
|||
NULL, /* %Q */
|
||||
NULL, /* %U */
|
||||
NULL, /* Ta */
|
||||
post_tg, /* Tg */
|
||||
};
|
||||
|
||||
#define RSORD_MAX 14 /* Number of `Rs' blocks. */
|
||||
|
@ -285,6 +294,8 @@ static const char * const secnames[SEC__MAX] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int fn_prio = TAG_STRONG;
|
||||
|
||||
|
||||
/* Validate the subtree rooted at mdoc->last. */
|
||||
void
|
||||
|
@ -1089,6 +1100,125 @@ post_st(POST_ARGS)
|
|||
mdoc->last= n;
|
||||
}
|
||||
|
||||
static void
|
||||
post_tg(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n; /* The .Tg node. */
|
||||
struct roff_node *nch; /* The first child of the .Tg node. */
|
||||
struct roff_node *nn; /* The next node after the .Tg node. */
|
||||
struct roff_node *np; /* The parent of the next node. */
|
||||
struct roff_node *nt; /* The TEXT node containing the tag. */
|
||||
size_t len; /* The number of bytes in the tag. */
|
||||
|
||||
/* Find the next node. */
|
||||
n = mdoc->last;
|
||||
for (nn = n; nn != NULL; nn = nn->parent) {
|
||||
if (nn->next != NULL) {
|
||||
nn = nn->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the tag. */
|
||||
nt = nch = n->child;
|
||||
if (nch == NULL && nn != NULL && nn->child != NULL &&
|
||||
nn->child->type == ROFFT_TEXT)
|
||||
nt = nn->child;
|
||||
|
||||
/* Validate the tag. */
|
||||
if (nt == NULL || *nt->string == '\0')
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, n->line, n->pos, "Tg");
|
||||
if (nt == NULL) {
|
||||
roff_node_delete(mdoc, n);
|
||||
return;
|
||||
}
|
||||
len = strcspn(nt->string, " \t\\");
|
||||
if (nt->string[len] != '\0')
|
||||
mandoc_msg(MANDOCERR_TG_SPC, nt->line,
|
||||
nt->pos + len, "Tg %s", nt->string);
|
||||
|
||||
/* Keep only the first argument. */
|
||||
if (nch != NULL && nch->next != NULL) {
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS, nch->next->line,
|
||||
nch->next->pos, "Tg ... %s", nch->next->string);
|
||||
while (nch->next != NULL)
|
||||
roff_node_delete(mdoc, nch->next);
|
||||
}
|
||||
|
||||
/* Drop the macro if the first argument is invalid. */
|
||||
if (len == 0 || nt->string[len] != '\0') {
|
||||
roff_node_delete(mdoc, n);
|
||||
return;
|
||||
}
|
||||
|
||||
/* By default, tag the .Tg node itself. */
|
||||
if (nn == NULL || nn->flags & NODE_ID)
|
||||
nn = n;
|
||||
|
||||
/* Explicit tagging of specific macros. */
|
||||
switch (nn->tok) {
|
||||
case MDOC_Sh:
|
||||
case MDOC_Ss:
|
||||
case MDOC_Fo:
|
||||
nn = nn->head->child == NULL ? n : nn->head;
|
||||
break;
|
||||
case MDOC_It:
|
||||
np = nn->parent;
|
||||
while (np->tok != MDOC_Bl)
|
||||
np = np->parent;
|
||||
switch (np->norm->Bl.type) {
|
||||
case LIST_column:
|
||||
break;
|
||||
case LIST_diag:
|
||||
case LIST_hang:
|
||||
case LIST_inset:
|
||||
case LIST_ohang:
|
||||
case LIST_tag:
|
||||
nn = nn->head;
|
||||
break;
|
||||
case LIST_bullet:
|
||||
case LIST_dash:
|
||||
case LIST_enum:
|
||||
case LIST_hyphen:
|
||||
case LIST_item:
|
||||
nn = nn->body->child == NULL ? n : nn->body;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
break;
|
||||
case MDOC_Bd:
|
||||
case MDOC_Bl:
|
||||
case MDOC_D1:
|
||||
case MDOC_Dl:
|
||||
nn = nn->body->child == NULL ? n : nn->body;
|
||||
break;
|
||||
case MDOC_Pp:
|
||||
break;
|
||||
case MDOC_Cm:
|
||||
case MDOC_Dv:
|
||||
case MDOC_Em:
|
||||
case MDOC_Er:
|
||||
case MDOC_Ev:
|
||||
case MDOC_Fl:
|
||||
case MDOC_Fn:
|
||||
case MDOC_Ic:
|
||||
case MDOC_Li:
|
||||
case MDOC_Ms:
|
||||
case MDOC_No:
|
||||
case MDOC_Sy:
|
||||
if (nn->child == NULL)
|
||||
nn = n;
|
||||
break;
|
||||
default:
|
||||
nn = n;
|
||||
break;
|
||||
}
|
||||
tag_put(nt->string, TAG_MANUAL, nn);
|
||||
if (nn != n)
|
||||
n->flags |= NODE_NOPRT;
|
||||
}
|
||||
|
||||
static void
|
||||
post_obsolete(POST_ARGS)
|
||||
{
|
||||
|
@ -1181,22 +1311,32 @@ post_bf(POST_ARGS)
|
|||
static void
|
||||
post_fname(POST_ARGS)
|
||||
{
|
||||
const struct roff_node *n;
|
||||
struct roff_node *n, *nch;
|
||||
const char *cp;
|
||||
size_t pos;
|
||||
|
||||
n = mdoc->last->child;
|
||||
pos = strcspn(n->string, "()");
|
||||
cp = n->string + pos;
|
||||
if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*')))
|
||||
mandoc_msg(MANDOCERR_FN_PAREN, n->line, n->pos + pos,
|
||||
"%s", n->string);
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
cp = nch->string;
|
||||
if (*cp == '(') {
|
||||
if (cp[strlen(cp + 1)] == ')')
|
||||
return;
|
||||
pos = 0;
|
||||
} else {
|
||||
pos = strcspn(cp, "()");
|
||||
if (cp[pos] == '\0') {
|
||||
if (n->sec == SEC_DESCRIPTION ||
|
||||
n->sec == SEC_CUSTOM)
|
||||
tag_put(NULL, fn_prio++, n);
|
||||
return;
|
||||
}
|
||||
}
|
||||
mandoc_msg(MANDOCERR_FN_PAREN, nch->line, nch->pos + pos, "%s", cp);
|
||||
}
|
||||
|
||||
static void
|
||||
post_fn(POST_ARGS)
|
||||
{
|
||||
|
||||
post_fname(mdoc);
|
||||
post_fa(mdoc);
|
||||
}
|
||||
|
@ -1360,38 +1500,29 @@ post_display(POST_ARGS)
|
|||
static void
|
||||
post_defaults(POST_ARGS)
|
||||
{
|
||||
struct roff_node *nn;
|
||||
struct roff_node *n;
|
||||
|
||||
if (mdoc->last->child != NULL) {
|
||||
n = mdoc->last;
|
||||
if (n->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.
|
||||
*/
|
||||
|
||||
nn = mdoc->last;
|
||||
switch (nn->tok) {
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
switch (n->tok) {
|
||||
case MDOC_Ar:
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, nn->line, nn->pos, "file");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, nn->line, nn->pos, "...");
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "file");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "...");
|
||||
break;
|
||||
case MDOC_Pa:
|
||||
case MDOC_Mt:
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(mdoc, nn->line, nn->pos, "~");
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "~");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
mdoc->last = nn;
|
||||
mdoc->last->flags |= NODE_NOSRC;
|
||||
mdoc->last = n;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1444,23 +1575,82 @@ post_an(POST_ARGS)
|
|||
nch->line, nch->pos, "An ... %s", nch->string);
|
||||
}
|
||||
|
||||
static void
|
||||
post_em(POST_ARGS)
|
||||
{
|
||||
post_tag(mdoc);
|
||||
tag_put(NULL, TAG_FALLBACK, mdoc->last);
|
||||
}
|
||||
|
||||
static void
|
||||
post_en(POST_ARGS)
|
||||
{
|
||||
|
||||
post_obsolete(mdoc);
|
||||
if (mdoc->last->type == ROFFT_BLOCK)
|
||||
mdoc->last->norm->Es = mdoc->last_es;
|
||||
}
|
||||
|
||||
static void
|
||||
post_er(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->sec == SEC_ERRORS &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Bq &&
|
||||
n->parent->parent->parent->tok == MDOC_It)))
|
||||
tag_put(NULL, TAG_STRONG, n);
|
||||
post_delim_nb(mdoc);
|
||||
}
|
||||
|
||||
static void
|
||||
post_tag(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
n = mdoc->last;
|
||||
if ((n->prev == NULL ||
|
||||
(n->prev->type == ROFFT_TEXT &&
|
||||
strcmp(n->prev->string, "|") == 0)) &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Xo &&
|
||||
n->parent->parent->prev == NULL &&
|
||||
n->parent->parent->parent->tok == MDOC_It)))
|
||||
tag_put(NULL, TAG_STRONG, n);
|
||||
post_delim_nb(mdoc);
|
||||
}
|
||||
|
||||
static void
|
||||
post_es(POST_ARGS)
|
||||
{
|
||||
|
||||
post_obsolete(mdoc);
|
||||
mdoc->last_es = mdoc->last;
|
||||
}
|
||||
|
||||
static void
|
||||
post_fl(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
char *cp;
|
||||
|
||||
/*
|
||||
* Transform ".Fl Fl long" to ".Fl \-long",
|
||||
* resulting for example in better HTML output.
|
||||
*/
|
||||
|
||||
n = mdoc->last;
|
||||
if (n->prev != NULL && n->prev->tok == MDOC_Fl &&
|
||||
n->prev->child == NULL && n->child != NULL &&
|
||||
(n->flags & NODE_LINE) == 0) {
|
||||
mandoc_asprintf(&cp, "\\-%s", n->child->string);
|
||||
free(n->child->string);
|
||||
n->child->string = cp;
|
||||
roff_node_delete(mdoc, n->prev);
|
||||
}
|
||||
post_tag(mdoc);
|
||||
}
|
||||
|
||||
static void
|
||||
post_xx(POST_ARGS)
|
||||
{
|
||||
|
@ -1553,8 +1743,8 @@ post_it(POST_ARGS)
|
|||
if ((nch = nit->head->child) != NULL)
|
||||
mandoc_msg(MANDOCERR_ARG_SKIP,
|
||||
nit->line, nit->pos, "It %s",
|
||||
nch->string == NULL ? roff_name[nch->tok] :
|
||||
nch->string);
|
||||
nch->type == ROFFT_TEXT ? nch->string :
|
||||
roff_name[nch->tok]);
|
||||
break;
|
||||
case LIST_column:
|
||||
cols = (int)nbl->norm->Bl.ncols;
|
||||
|
@ -1717,8 +1907,7 @@ post_bl_head(POST_ARGS)
|
|||
static void
|
||||
post_bl(POST_ARGS)
|
||||
{
|
||||
struct roff_node *nparent, *nprev; /* of the Bl block */
|
||||
struct roff_node *nblock, *nbody; /* of the Bl */
|
||||
struct roff_node *nbody; /* of the Bl */
|
||||
struct roff_node *nchild, *nnext; /* of the Bl body */
|
||||
const char *prev_Er;
|
||||
int order;
|
||||
|
@ -1739,88 +1928,73 @@ post_bl(POST_ARGS)
|
|||
if (nbody->end != ENDBODY_NOT)
|
||||
return;
|
||||
|
||||
nchild = nbody->child;
|
||||
if (nchild == NULL) {
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY,
|
||||
nbody->line, nbody->pos, "Bl");
|
||||
return;
|
||||
}
|
||||
while (nchild != NULL) {
|
||||
nnext = nchild->next;
|
||||
if (nchild->tok == MDOC_It ||
|
||||
(nchild->tok == MDOC_Sm &&
|
||||
nnext != NULL && nnext->tok == MDOC_It)) {
|
||||
nchild = nnext;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Up to the first item, move nodes before the list,
|
||||
* but leave transparent nodes where they are
|
||||
* if they precede an item.
|
||||
* The next non-transparent node is kept in nchild.
|
||||
* It only needs to be updated after a non-transparent
|
||||
* node was moved out, and at the very beginning
|
||||
* when no node at all was moved yet.
|
||||
*/
|
||||
|
||||
/*
|
||||
* In .Bl -column, the first rows may be implicit,
|
||||
* that is, they may not start with .It macros.
|
||||
* Such rows may be followed by nodes generated on the
|
||||
* roff level, for example .TS, which cannot be moved
|
||||
* out of the list. In that case, wrap such roff nodes
|
||||
* into an implicit row.
|
||||
*/
|
||||
|
||||
if (nchild->prev != NULL) {
|
||||
mdoc->last = nchild;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_block_alloc(mdoc, nchild->line,
|
||||
nchild->pos, MDOC_It);
|
||||
roff_head_alloc(mdoc, nchild->line,
|
||||
nchild->pos, MDOC_It);
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_body_alloc(mdoc, nchild->line,
|
||||
nchild->pos, MDOC_It);
|
||||
while (nchild->tok != MDOC_It) {
|
||||
roff_node_relink(mdoc, nchild);
|
||||
if ((nchild = nnext) == NULL)
|
||||
break;
|
||||
nnext = nchild->next;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
nchild = mdoc->last;
|
||||
for (;;) {
|
||||
if (nchild == mdoc->last)
|
||||
nchild = roff_node_child(nbody);
|
||||
if (nchild == NULL) {
|
||||
mdoc->last = nbody;
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY,
|
||||
nbody->line, nbody->pos, "Bl");
|
||||
return;
|
||||
}
|
||||
if (nchild->tok == MDOC_It) {
|
||||
mdoc->last = nbody;
|
||||
break;
|
||||
}
|
||||
mandoc_msg(MANDOCERR_BL_MOVE, nbody->child->line,
|
||||
nbody->child->pos, "%s", roff_name[nbody->child->tok]);
|
||||
if (nbody->parent->prev == NULL) {
|
||||
mdoc->last = nbody->parent->parent;
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
} else {
|
||||
mdoc->last = nbody->parent->prev;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
roff_node_relink(mdoc, nbody->child);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have reached the first item,
|
||||
* so moving nodes out is no longer possible.
|
||||
* But in .Bl -column, the first rows may be implicit,
|
||||
* that is, they may not start with .It macros.
|
||||
* Such rows may be followed by nodes generated on the
|
||||
* roff level, for example .TS.
|
||||
* Wrap such roff nodes into an implicit row.
|
||||
*/
|
||||
|
||||
while (nchild != NULL) {
|
||||
if (nchild->tok == MDOC_It) {
|
||||
nchild = roff_node_next(nchild);
|
||||
continue;
|
||||
}
|
||||
|
||||
mandoc_msg(MANDOCERR_BL_MOVE, nchild->line, nchild->pos,
|
||||
"%s", roff_name[nchild->tok]);
|
||||
|
||||
/*
|
||||
* Move the node out of the Bl block.
|
||||
* First, collect all required node pointers.
|
||||
*/
|
||||
|
||||
nblock = nbody->parent;
|
||||
nprev = nblock->prev;
|
||||
nparent = nblock->parent;
|
||||
|
||||
/*
|
||||
* Unlink this child.
|
||||
*/
|
||||
|
||||
nbody->child = nnext;
|
||||
if (nnext == NULL)
|
||||
nbody->last = NULL;
|
||||
else
|
||||
nnext->prev = NULL;
|
||||
|
||||
/*
|
||||
* Relink this child.
|
||||
*/
|
||||
|
||||
nchild->parent = nparent;
|
||||
nchild->prev = nprev;
|
||||
nchild->next = nblock;
|
||||
|
||||
nblock->prev = nchild;
|
||||
if (nprev == NULL)
|
||||
nparent->child = nchild;
|
||||
else
|
||||
nprev->next = nchild;
|
||||
|
||||
nchild = nnext;
|
||||
nnext = nchild->next;
|
||||
mdoc->last = nchild->prev;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_block_alloc(mdoc, nchild->line, nchild->pos, MDOC_It);
|
||||
roff_head_alloc(mdoc, nchild->line, nchild->pos, MDOC_It);
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
roff_body_alloc(mdoc, nchild->line, nchild->pos, MDOC_It);
|
||||
while (nchild->tok != MDOC_It) {
|
||||
roff_node_relink(mdoc, nchild);
|
||||
if (nnext == NULL)
|
||||
break;
|
||||
nchild = nnext;
|
||||
nnext = nchild->next;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
mdoc->last = nbody;
|
||||
}
|
||||
|
||||
if (mdoc->meta.os_e != MANDOC_OS_NETBSD)
|
||||
|
@ -1903,7 +2077,7 @@ post_root(POST_ARGS)
|
|||
/* Add missing prologue data. */
|
||||
|
||||
if (mdoc->meta.date == NULL)
|
||||
mdoc->meta.date = mandoc_normdate(mdoc, NULL, 0, 0);
|
||||
mdoc->meta.date = mandoc_normdate(NULL, NULL);
|
||||
|
||||
if (mdoc->meta.title == NULL) {
|
||||
mandoc_msg(MANDOCERR_DT_NOTITLE, 0, 0, "EOF");
|
||||
|
@ -2048,10 +2222,11 @@ post_rs(POST_ARGS)
|
|||
static void
|
||||
post_hyph(POST_ARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
struct roff_node *n, *nch;
|
||||
char *cp;
|
||||
|
||||
for (nch = mdoc->last->child; nch != NULL; nch = nch->next) {
|
||||
n = mdoc->last;
|
||||
for (nch = n->child; nch != NULL; nch = nch->next) {
|
||||
if (nch->type != ROFFT_TEXT)
|
||||
continue;
|
||||
cp = nch->string;
|
||||
|
@ -2060,8 +2235,11 @@ post_hyph(POST_ARGS)
|
|||
while (*(++cp) != '\0')
|
||||
if (*cp == '-' &&
|
||||
isalpha((unsigned char)cp[-1]) &&
|
||||
isalpha((unsigned char)cp[1]))
|
||||
isalpha((unsigned char)cp[1])) {
|
||||
if (n->tag == NULL && n->flags & NODE_ID)
|
||||
n->tag = mandoc_strdup(nch->string);
|
||||
*cp = ASCII_HYPH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2086,8 +2264,7 @@ post_sx(POST_ARGS)
|
|||
static void
|
||||
post_sh(POST_ARGS)
|
||||
{
|
||||
|
||||
post_ignpar(mdoc);
|
||||
post_section(mdoc);
|
||||
|
||||
switch (mdoc->last->type) {
|
||||
case ROFFT_HEAD:
|
||||
|
@ -2318,6 +2495,8 @@ post_sh_head(POST_ARGS)
|
|||
roff_setreg(mdoc->roff, "nS", 0, '=');
|
||||
mdoc->flags &= ~MDOC_SYNOPSIS;
|
||||
}
|
||||
if (sec == SEC_DESCRIPTION)
|
||||
fn_prio = TAG_STRONG;
|
||||
|
||||
/* Mark our last section. */
|
||||
|
||||
|
@ -2418,15 +2597,31 @@ post_xr(POST_ARGS)
|
|||
}
|
||||
|
||||
static void
|
||||
post_ignpar(POST_ARGS)
|
||||
post_section(POST_ARGS)
|
||||
{
|
||||
struct roff_node *np;
|
||||
struct roff_node *n, *nch;
|
||||
char *cp, *tag;
|
||||
|
||||
switch (mdoc->last->type) {
|
||||
n = mdoc->last;
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
post_prevpar(mdoc);
|
||||
return;
|
||||
case ROFFT_HEAD:
|
||||
tag = NULL;
|
||||
deroff(&tag, n);
|
||||
if (tag != NULL) {
|
||||
for (cp = tag; *cp != '\0'; cp++)
|
||||
if (*cp == ' ')
|
||||
*cp = '_';
|
||||
if ((nch = n->child) != NULL &&
|
||||
nch->type == ROFFT_TEXT &&
|
||||
strcmp(nch->string, tag) == 0)
|
||||
tag_put(NULL, TAG_STRONG, n);
|
||||
else
|
||||
tag_put(tag, TAG_FALLBACK, n);
|
||||
free(tag);
|
||||
}
|
||||
post_delim(mdoc);
|
||||
post_hyph(mdoc);
|
||||
return;
|
||||
|
@ -2435,42 +2630,40 @@ post_ignpar(POST_ARGS)
|
|||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if ((np = mdoc->last->child) != NULL)
|
||||
if (np->tok == MDOC_Pp ||
|
||||
np->tok == ROFF_br || np->tok == ROFF_sp) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos,
|
||||
"%s after %s", roff_name[np->tok],
|
||||
roff_name[mdoc->last->tok]);
|
||||
roff_node_delete(mdoc, np);
|
||||
}
|
||||
|
||||
if ((np = mdoc->last->last) != NULL)
|
||||
if (np->tok == MDOC_Pp || np->tok == ROFF_br) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos,
|
||||
"%s at the end of %s", roff_name[np->tok],
|
||||
roff_name[mdoc->last->tok]);
|
||||
roff_node_delete(mdoc, np);
|
||||
}
|
||||
if ((nch = n->child) != NULL &&
|
||||
(nch->tok == MDOC_Pp || nch->tok == ROFF_br ||
|
||||
nch->tok == ROFF_sp)) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, nch->line, nch->pos,
|
||||
"%s after %s", roff_name[nch->tok],
|
||||
roff_name[n->tok]);
|
||||
roff_node_delete(mdoc, nch);
|
||||
}
|
||||
if ((nch = n->last) != NULL &&
|
||||
(nch->tok == MDOC_Pp || nch->tok == ROFF_br)) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, nch->line, nch->pos,
|
||||
"%s at the end of %s", roff_name[nch->tok],
|
||||
roff_name[n->tok]);
|
||||
roff_node_delete(mdoc, nch);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_prevpar(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
struct roff_node *n, *np;
|
||||
|
||||
n = mdoc->last;
|
||||
if (NULL == n->prev)
|
||||
return;
|
||||
if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK)
|
||||
return;
|
||||
if ((np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Don't allow `Pp' prior to a paragraph-type
|
||||
* block: `Pp' or non-compact `Bd' or `Bl'.
|
||||
*/
|
||||
|
||||
if (n->prev->tok != MDOC_Pp && n->prev->tok != ROFF_br)
|
||||
if (np->tok != MDOC_Pp && np->tok != ROFF_br)
|
||||
return;
|
||||
if (n->tok == MDOC_Bl && n->norm->Bl.comp)
|
||||
return;
|
||||
|
@ -2479,9 +2672,9 @@ post_prevpar(POST_ARGS)
|
|||
if (n->tok == MDOC_It && n->parent->norm->Bl.comp)
|
||||
return;
|
||||
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, n->prev->line, n->prev->pos,
|
||||
"%s before %s", roff_name[n->prev->tok], roff_name[n->tok]);
|
||||
roff_node_delete(mdoc, n->prev);
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos,
|
||||
"%s before %s", roff_name[np->tok], roff_name[n->tok]);
|
||||
roff_node_delete(mdoc, np);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2489,6 +2682,7 @@ post_par(POST_ARGS)
|
|||
{
|
||||
struct roff_node *np;
|
||||
|
||||
fn_prio = TAG_STRONG;
|
||||
post_prevpar(mdoc);
|
||||
|
||||
np = mdoc->last;
|
||||
|
@ -2501,7 +2695,6 @@ static void
|
|||
post_dd(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
char *datestr;
|
||||
|
||||
n = mdoc->last;
|
||||
n->flags |= NODE_NOPRT;
|
||||
|
@ -2518,10 +2711,10 @@ post_dd(POST_ARGS)
|
|||
mandoc_msg(MANDOCERR_PROLOG_ORDER,
|
||||
n->line, n->pos, "Dd after Os");
|
||||
|
||||
datestr = NULL;
|
||||
deroff(&datestr, n);
|
||||
mdoc->meta.date = mandoc_normdate(mdoc, datestr, n->line, n->pos);
|
||||
free(datestr);
|
||||
if (mdoc->quick && n != NULL)
|
||||
mdoc->meta.date = mandoc_strdup("");
|
||||
else
|
||||
mdoc->meta.date = mandoc_normdate(n->child, n);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2596,8 +2789,14 @@ post_dt(POST_ARGS)
|
|||
mandoc_msg(MANDOCERR_MSEC_BAD,
|
||||
nn->line, nn->pos, "Dt ... %s", nn->string);
|
||||
mdoc->meta.vol = mandoc_strdup(nn->string);
|
||||
} else
|
||||
} else {
|
||||
mdoc->meta.vol = mandoc_strdup(cp);
|
||||
if (mdoc->filesec != '\0' &&
|
||||
mdoc->filesec != *nn->string &&
|
||||
*nn->string >= '1' && *nn->string <= '9')
|
||||
mandoc_msg(MANDOCERR_MSEC_FILE, nn->line, nn->pos,
|
||||
"*.%c vs Dt ... %c", mdoc->filesec, *nn->string);
|
||||
}
|
||||
|
||||
/* Optional third argument: architecture. */
|
||||
|
||||
|
|
75
out.c
75
out.c
|
@ -1,7 +1,8 @@
|
|||
/* $Id: out.c,v 1.78 2019/03/29 21:27:06 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.82 2021/09/07 17:07:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021
|
||||
* 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,11 +23,13 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "tbl.h"
|
||||
#include "out.h"
|
||||
|
||||
|
@ -120,7 +123,6 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
const struct tbl_dat *dp;
|
||||
struct roffcol *col;
|
||||
struct tbl_colgroup *first_group, **gp, *g;
|
||||
size_t *colwidth;
|
||||
size_t ewidth, min1, min2, wanted, width, xwidth;
|
||||
int done, icol, maxcol, necol, nxcol, quirkcol;
|
||||
|
||||
|
@ -209,13 +211,25 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
}
|
||||
|
||||
/*
|
||||
* Column spacings are needed for span width calculations,
|
||||
* so set the default values now.
|
||||
* The minimum width of columns explicitly specified
|
||||
* in the layout is 1n.
|
||||
*/
|
||||
|
||||
for (icol = 0; icol <= maxcol; icol++)
|
||||
if (tbl->cols[icol].spacing == SIZE_MAX || icol == maxcol)
|
||||
tbl->cols[icol].spacing = 3;
|
||||
if (maxcol < sp_first->opts->cols - 1)
|
||||
maxcol = sp_first->opts->cols - 1;
|
||||
for (icol = 0; icol <= maxcol; icol++) {
|
||||
col = tbl->cols + icol;
|
||||
if (col->width < 1)
|
||||
col->width = 1;
|
||||
|
||||
/*
|
||||
* Column spacings are needed for span width
|
||||
* calculations, so set the default values now.
|
||||
*/
|
||||
|
||||
if (col->spacing == SIZE_MAX || icol == maxcol)
|
||||
col->spacing = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace the minimum widths with the missing widths,
|
||||
|
@ -242,20 +256,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
gp = &(*gp)->next;
|
||||
}
|
||||
|
||||
colwidth = mandoc_reallocarray(NULL, maxcol + 1, sizeof(*colwidth));
|
||||
while (first_group != NULL) {
|
||||
|
||||
/*
|
||||
* Rebuild the array of the widths of all columns
|
||||
* participating in spans that require expansion.
|
||||
*/
|
||||
|
||||
for (icol = 0; icol <= maxcol; icol++)
|
||||
colwidth[icol] = SIZE_MAX;
|
||||
for (g = first_group; g != NULL; g = g->next)
|
||||
for (icol = g->startcol; icol <= g->endcol; icol++)
|
||||
colwidth[icol] = tbl->cols[icol].width;
|
||||
|
||||
/*
|
||||
* Find the smallest and second smallest column width
|
||||
* among the columns which may need expamsion.
|
||||
|
@ -263,12 +265,12 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
|
||||
min1 = min2 = SIZE_MAX;
|
||||
for (icol = 0; icol <= maxcol; icol++) {
|
||||
if (min1 > colwidth[icol]) {
|
||||
width = tbl->cols[icol].width;
|
||||
if (min1 > width) {
|
||||
min2 = min1;
|
||||
min1 = colwidth[icol];
|
||||
} else if (min1 < colwidth[icol] &&
|
||||
min2 > colwidth[icol])
|
||||
min2 = colwidth[icol];
|
||||
min1 = width;
|
||||
} else if (min1 < width && min2 > width)
|
||||
min2 = width;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -290,26 +292,22 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
width = min2;
|
||||
if (wanted > width)
|
||||
wanted = width;
|
||||
for (icol = g->startcol; icol <= g->endcol; icol++)
|
||||
if (colwidth[icol] == min1 ||
|
||||
(colwidth[icol] < min2 &&
|
||||
colwidth[icol] > width))
|
||||
colwidth[icol] = width;
|
||||
}
|
||||
|
||||
/* Record the effect of the widening on the group list. */
|
||||
/* Record the effect of the widening. */
|
||||
|
||||
gp = &first_group;
|
||||
while ((g = *gp) != NULL) {
|
||||
done = 0;
|
||||
for (icol = g->startcol; icol <= g->endcol; icol++) {
|
||||
if (colwidth[icol] != wanted ||
|
||||
tbl->cols[icol].width == wanted)
|
||||
if (tbl->cols[icol].width != min1)
|
||||
continue;
|
||||
if (g->wanted <= wanted - min1) {
|
||||
tbl->cols[icol].width += g->wanted;
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
tbl->cols[icol].width = wanted;
|
||||
g->wanted -= wanted - min1;
|
||||
}
|
||||
if (done) {
|
||||
|
@ -318,14 +316,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
} else
|
||||
gp = &(*gp)->next;
|
||||
}
|
||||
|
||||
/* Record the effect of the widening on the columns. */
|
||||
|
||||
for (icol = 0; icol <= maxcol; icol++)
|
||||
if (colwidth[icol] == wanted)
|
||||
tbl->cols[icol].width = wanted;
|
||||
}
|
||||
free(colwidth);
|
||||
|
||||
/*
|
||||
* Align numbers with text.
|
||||
|
@ -340,8 +331,6 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
|||
col = tbl->cols + icol;
|
||||
if (col->width > col->nwidth)
|
||||
col->decimal += (col->width - col->nwidth) / 2;
|
||||
else
|
||||
col->width = col->nwidth;
|
||||
if (col->flags & TBL_CELL_EQUAL) {
|
||||
necol++;
|
||||
if (ewidth < col->width)
|
||||
|
@ -549,5 +538,7 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
|||
|
||||
if (totsz > col->nwidth)
|
||||
col->nwidth = totsz;
|
||||
if (col->nwidth > col->width)
|
||||
col->width = col->nwidth;
|
||||
return totsz;
|
||||
}
|
||||
|
|
6
out.h
6
out.h
|
@ -1,4 +1,4 @@
|
|||
/* $Id: out.h,v 1.33 2018/08/18 20:18:14 schwarze Exp $ */
|
||||
/* $Id: out.h,v 1.34 2020/04/03 11:35:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Utilities for use by multiple mandoc(1) formatters.
|
||||
*/
|
||||
|
||||
enum roffscale {
|
||||
|
@ -64,5 +66,5 @@ struct rofftbl {
|
|||
struct tbl_span;
|
||||
|
||||
const char *a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
void tblcalc(struct rofftbl *tbl,
|
||||
void tblcalc(struct rofftbl *,
|
||||
const struct tbl_span *, size_t, size_t);
|
||||
|
|
31
read.c
31
read.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: read.c,v 1.214 2019/07/10 19:39:01 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.220 2021/06/27 17:57:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -15,6 +15,12 @@
|
|||
* 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.
|
||||
*
|
||||
* Top-level functions of the mandoc(3) parser:
|
||||
* Parser and input encoding selection, decompression,
|
||||
* handling of input bytes, characters, lines, and files,
|
||||
* handling of roff(7) loops and file inclusion,
|
||||
* and steering of the various parsers.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -41,6 +47,7 @@
|
|||
#include "mandoc_parse.h"
|
||||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
#include "tag.h"
|
||||
|
||||
#define REPARSE_LIMIT 1000
|
||||
|
||||
|
@ -147,6 +154,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
|||
struct buf *firstln, *lastln, *thisln, *loop;
|
||||
char *cp;
|
||||
size_t pos; /* byte number in the ln buffer */
|
||||
size_t spos; /* at the start of the current line parse */
|
||||
int line_result, result;
|
||||
int of;
|
||||
int lnn; /* line number in the real file */
|
||||
|
@ -173,6 +181,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
|||
curp->filenc & MPARSE_LATIN1)
|
||||
curp->filenc = preconv_cue(&blk, i);
|
||||
}
|
||||
spos = pos;
|
||||
|
||||
while (i < blk.sz && (start || blk.buf[i] != '\0')) {
|
||||
|
||||
|
@ -272,7 +281,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
|||
|
||||
of = 0;
|
||||
rerun:
|
||||
line_result = roff_parseln(curp->roff, curp->line, &ln, &of);
|
||||
line_result = roff_parseln(curp->roff, curp->line,
|
||||
&ln, &of, start && spos == 0 ? pos : 0);
|
||||
|
||||
/* Process options. */
|
||||
|
||||
|
@ -547,7 +557,7 @@ mparse_readfd(struct mparse *curp, int fd, const char *filename)
|
|||
|
||||
struct buf blk;
|
||||
struct buf *save_primary;
|
||||
const char *save_filename;
|
||||
const char *save_filename, *cp;
|
||||
size_t offset;
|
||||
int save_filenc, save_lineno;
|
||||
int with_mmap;
|
||||
|
@ -555,7 +565,13 @@ mparse_readfd(struct mparse *curp, int fd, const char *filename)
|
|||
if (recursion_depth > 64) {
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP, curp->line, 0, NULL);
|
||||
return;
|
||||
}
|
||||
} else if (recursion_depth == 0 &&
|
||||
(cp = strrchr(filename, '.')) != NULL &&
|
||||
cp[1] >= '1' && cp[1] <= '9')
|
||||
curp->man->filesec = cp[1];
|
||||
else
|
||||
curp->man->filesec = '\0';
|
||||
|
||||
if (read_whole_file(curp, fd, &blk, &with_mmap) == -1)
|
||||
return;
|
||||
|
||||
|
@ -664,22 +680,26 @@ mparse_alloc(int options, enum mandoc_os os_e, const char *os_s)
|
|||
}
|
||||
curp->man->meta.first->tok = TOKEN_NONE;
|
||||
curp->man->meta.os_e = os_e;
|
||||
tag_alloc();
|
||||
return curp;
|
||||
}
|
||||
|
||||
void
|
||||
mparse_reset(struct mparse *curp)
|
||||
{
|
||||
tag_free();
|
||||
roff_reset(curp->roff);
|
||||
roff_man_reset(curp->man);
|
||||
free_buf_list(curp->secondary);
|
||||
curp->secondary = NULL;
|
||||
curp->gzip = 0;
|
||||
tag_alloc();
|
||||
}
|
||||
|
||||
void
|
||||
mparse_free(struct mparse *curp)
|
||||
{
|
||||
tag_free();
|
||||
roffhash_free(curp->man->mdocmac);
|
||||
roffhash_free(curp->man->manmac);
|
||||
roff_man_free(curp->man);
|
||||
|
@ -697,6 +717,7 @@ mparse_result(struct mparse *curp)
|
|||
mdoc_validate(curp->man);
|
||||
else
|
||||
man_validate(curp->man);
|
||||
tag_postprocess(curp->man, curp->man->meta.first);
|
||||
}
|
||||
return &curp->man->meta;
|
||||
}
|
||||
|
|
8
roff.7
8
roff.7
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: roff.7,v 1.114 2019/07/15 19:20:30 schwarze Exp $
|
||||
.\" $Id: roff.7,v 1.116 2021/09/18 12:23:06 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010-2019 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: July 15 2019 $
|
||||
.Dd $Mdocdate: September 18 2021 $
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -624,7 +624,7 @@ Its syntax can be either
|
|||
.Pp
|
||||
or
|
||||
.Bd -literal -offset indent
|
||||
.Pf . Ic \&de Ar macroname Ar endmacro
|
||||
.Pf . Ic \&de Ar macroname endmacro
|
||||
.Ar definition
|
||||
.Pf . Ar endmacro
|
||||
.Ed
|
||||
|
@ -2331,7 +2331,7 @@ for
|
|||
.At v2 ,
|
||||
then ported nroff to C as troff, which Brian W. Kernighan released with
|
||||
.At v7 .
|
||||
In 1989, James Clarke re-implemented troff in C++, naming it groff.
|
||||
In 1989, James Clark re-implemented troff in C++, naming it groff.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
This
|
||||
|
|
233
roff.c
233
roff.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: roff.c,v 1.366 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/* $Id: roff.c,v 1.378 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* 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.
|
||||
*
|
||||
* Implementation of the roff(7) parser for mandoc(1).
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
@ -190,13 +192,14 @@ static int roff_cc(ROFF_ARGS);
|
|||
static int roff_ccond(struct roff *, int, int);
|
||||
static int roff_char(ROFF_ARGS);
|
||||
static int roff_cond(ROFF_ARGS);
|
||||
static int roff_cond_checkend(ROFF_ARGS);
|
||||
static int roff_cond_text(ROFF_ARGS);
|
||||
static int roff_cond_sub(ROFF_ARGS);
|
||||
static int roff_ds(ROFF_ARGS);
|
||||
static int roff_ec(ROFF_ARGS);
|
||||
static int roff_eo(ROFF_ARGS);
|
||||
static int roff_eqndelim(struct roff *, struct buf *, int);
|
||||
static int roff_evalcond(struct roff *r, int, char *, int *);
|
||||
static int roff_evalcond(struct roff *, int, char *, int *);
|
||||
static int roff_evalnum(struct roff *, int,
|
||||
const char *, int *, int *, int);
|
||||
static int roff_evalpar(struct roff *, int,
|
||||
|
@ -355,7 +358,7 @@ const char *__roff_name[MAN_MAX + 1] = {
|
|||
"Lk", "Mt", "Brq", "Bro",
|
||||
"Brc", "%C", "Es", "En",
|
||||
"Dx", "%Q", "%U", "Ta",
|
||||
NULL,
|
||||
"Tg", NULL,
|
||||
"TH", "SH", "SS", "TP",
|
||||
"TQ",
|
||||
"LP", "PP", "P", "IP",
|
||||
|
@ -771,6 +774,7 @@ void
|
|||
roff_reset(struct roff *r)
|
||||
{
|
||||
roff_free1(r);
|
||||
r->options |= MPARSE_COMMENT;
|
||||
r->format = r->options & (MPARSE_MDOC | MPARSE_MAN);
|
||||
r->control = '\0';
|
||||
r->escape = '\\';
|
||||
|
@ -800,7 +804,7 @@ roff_alloc(int options)
|
|||
|
||||
r = mandoc_calloc(1, sizeof(struct roff));
|
||||
r->reqtab = roffhash_alloc(0, ROFF_RENAMED);
|
||||
r->options = options;
|
||||
r->options = options | MPARSE_COMMENT;
|
||||
r->format = options & (MPARSE_MDOC | MPARSE_MAN);
|
||||
r->mstackpos = -1;
|
||||
r->rstackpos = -1;
|
||||
|
@ -1100,6 +1104,7 @@ roff_node_free(struct roff_node *n)
|
|||
free(n->norm);
|
||||
eqn_box_free(n->eqn);
|
||||
free(n->string);
|
||||
free(n->tag);
|
||||
free(n);
|
||||
}
|
||||
|
||||
|
@ -1113,13 +1118,72 @@ roff_node_delete(struct roff_man *man, struct roff_node *n)
|
|||
roff_node_free(n);
|
||||
}
|
||||
|
||||
int
|
||||
roff_node_transparent(struct roff_node *n)
|
||||
{
|
||||
if (n == NULL)
|
||||
return 0;
|
||||
if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
|
||||
return 1;
|
||||
return roff_tok_transparent(n->tok);
|
||||
}
|
||||
|
||||
int
|
||||
roff_tok_transparent(enum roff_tok tok)
|
||||
{
|
||||
switch (tok) {
|
||||
case ROFF_ft:
|
||||
case ROFF_ll:
|
||||
case ROFF_mc:
|
||||
case ROFF_po:
|
||||
case ROFF_ta:
|
||||
case MDOC_Db:
|
||||
case MDOC_Es:
|
||||
case MDOC_Sm:
|
||||
case MDOC_Tg:
|
||||
case MAN_DT:
|
||||
case MAN_UC:
|
||||
case MAN_PD:
|
||||
case MAN_AT:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct roff_node *
|
||||
roff_node_child(struct roff_node *n)
|
||||
{
|
||||
for (n = n->child; roff_node_transparent(n); n = n->next)
|
||||
continue;
|
||||
return n;
|
||||
}
|
||||
|
||||
struct roff_node *
|
||||
roff_node_prev(struct roff_node *n)
|
||||
{
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (roff_node_transparent(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
struct roff_node *
|
||||
roff_node_next(struct roff_node *n)
|
||||
{
|
||||
do {
|
||||
n = n->next;
|
||||
} while (roff_node_transparent(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
deroff(char **dest, const struct roff_node *n)
|
||||
{
|
||||
char *cp;
|
||||
size_t sz;
|
||||
|
||||
if (n->type != ROFFT_TEXT) {
|
||||
if (n->string == NULL) {
|
||||
for (n = n->child; n != NULL; n = n->next)
|
||||
deroff(dest, n);
|
||||
return;
|
||||
|
@ -1246,7 +1310,7 @@ roff_expand(struct roff *r, struct buf *buf, int ln, int pos, char newesc)
|
|||
* in the syntax tree.
|
||||
*/
|
||||
|
||||
if (newesc != ASCII_ESC && r->format == 0) {
|
||||
if (newesc != ASCII_ESC && r->options & MPARSE_COMMENT) {
|
||||
while (*ep == ' ' || *ep == '\t')
|
||||
ep--;
|
||||
ep[1] = '\0';
|
||||
|
@ -1759,7 +1823,7 @@ roff_parsetext(struct roff *r, struct buf *buf, int pos, int *offs)
|
|||
}
|
||||
|
||||
int
|
||||
roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs)
|
||||
roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs, size_t len)
|
||||
{
|
||||
enum roff_tok t;
|
||||
int e;
|
||||
|
@ -1770,6 +1834,14 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs)
|
|||
|
||||
ppos = pos = *offs;
|
||||
|
||||
if (len > 80 && r->tbl == NULL && r->eqn == NULL &&
|
||||
(r->man->flags & ROFF_NOFILL) == 0 &&
|
||||
strchr(" .\\", buf->buf[pos]) == NULL &&
|
||||
buf->buf[pos] != r->control &&
|
||||
strcspn(buf->buf, " ") < 80)
|
||||
mandoc_msg(MANDOCERR_TEXT_LONG, ln, (int)len - 1,
|
||||
"%.20s...", buf->buf + pos);
|
||||
|
||||
/* Handle in-line equation delimiters. */
|
||||
|
||||
if (r->tbl == NULL &&
|
||||
|
@ -1815,8 +1887,10 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs)
|
|||
roff_addtbl(r->man, ln, r->tbl);
|
||||
return e;
|
||||
}
|
||||
if ( ! ctl)
|
||||
if ( ! ctl) {
|
||||
r->options &= ~MPARSE_COMMENT;
|
||||
return roff_parsetext(r, buf, pos, offs) | e;
|
||||
}
|
||||
|
||||
/* Skip empty request lines. */
|
||||
|
||||
|
@ -1839,6 +1913,7 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs)
|
|||
|
||||
/* No scope is open. This is a new request or macro. */
|
||||
|
||||
r->options &= ~MPARSE_COMMENT;
|
||||
spos = pos;
|
||||
t = roff_parse(r, buf->buf, &pos, ln, ppos);
|
||||
|
||||
|
@ -1968,14 +2043,13 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos)
|
|||
|
||||
/* --- handling of request blocks ----------------------------------------- */
|
||||
|
||||
/*
|
||||
* Close a macro definition block or an "ignore" block.
|
||||
*/
|
||||
static int
|
||||
roff_cblock(ROFF_ARGS)
|
||||
{
|
||||
|
||||
/*
|
||||
* A block-close `..' should only be invoked as a child of an
|
||||
* ignore macro, otherwise raise a warning and just ignore it.
|
||||
*/
|
||||
int rr;
|
||||
|
||||
if (r->last == NULL) {
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "..");
|
||||
|
@ -1984,26 +2058,38 @@ roff_cblock(ROFF_ARGS)
|
|||
|
||||
switch (r->last->tok) {
|
||||
case ROFF_am:
|
||||
/* ROFF_am1 is remapped to ROFF_am in roff_block(). */
|
||||
case ROFF_ami:
|
||||
case ROFF_de:
|
||||
/* ROFF_de1 is remapped to ROFF_de in roff_block(). */
|
||||
case ROFF_dei:
|
||||
case ROFF_ig:
|
||||
break;
|
||||
case ROFF_am1:
|
||||
case ROFF_de1:
|
||||
/* Remapped in roff_block(). */
|
||||
abort();
|
||||
default:
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, ppos, "..");
|
||||
return ROFF_IGN;
|
||||
}
|
||||
|
||||
roffnode_pop(r);
|
||||
roffnode_cleanscope(r);
|
||||
|
||||
/*
|
||||
* If a conditional block with braces is still open,
|
||||
* check for "\}" block end markers.
|
||||
*/
|
||||
|
||||
if (r->last != NULL && r->last->endspan < 0) {
|
||||
rr = 1; /* If arguments follow "\}", warn about them. */
|
||||
roff_cond_checkend(r, tok, buf, ln, ppos, pos, &rr);
|
||||
}
|
||||
|
||||
if (buf->buf[pos] != '\0')
|
||||
mandoc_msg(MANDOCERR_ARG_SKIP, ln, pos,
|
||||
".. %s", buf->buf + pos);
|
||||
|
||||
roffnode_pop(r);
|
||||
roffnode_cleanscope(r);
|
||||
return ROFF_IGN;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2016,7 +2102,7 @@ roffnode_cleanscope(struct roff *r)
|
|||
int inloop;
|
||||
|
||||
inloop = 0;
|
||||
while (r->last != NULL) {
|
||||
while (r->last != NULL && r->last->endspan > 0) {
|
||||
if (--r->last->endspan != 0)
|
||||
break;
|
||||
inloop += roffnode_pop(r);
|
||||
|
@ -2025,7 +2111,7 @@ roffnode_cleanscope(struct roff *r)
|
|||
}
|
||||
|
||||
/*
|
||||
* Handle the closing \} of a conditional block.
|
||||
* Handle the closing "\}" of a conditional block.
|
||||
* Apart from generating warnings, this only pops nodes.
|
||||
* Return the number of loops ended.
|
||||
*/
|
||||
|
@ -2245,13 +2331,20 @@ roff_block_text(ROFF_ARGS)
|
|||
return ROFF_IGN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a closing "\}" and handle it.
|
||||
* In this function, the final "int *offs" argument is used for
|
||||
* different purposes than elsewhere:
|
||||
* Input: *offs == 0: caller wants to discard arguments following \}
|
||||
* *offs == 1: caller wants to preserve text following \}
|
||||
* Output: *offs = 0: tell caller to discard input line
|
||||
* *offs = 1: tell caller to use input line
|
||||
*/
|
||||
static int
|
||||
roff_cond_sub(ROFF_ARGS)
|
||||
roff_cond_checkend(ROFF_ARGS)
|
||||
{
|
||||
struct roffnode *bl;
|
||||
char *ep;
|
||||
int endloop, irc, rr;
|
||||
enum roff_tok t;
|
||||
|
||||
irc = ROFF_IGN;
|
||||
rr = r->last->rule;
|
||||
|
@ -2261,23 +2354,28 @@ roff_cond_sub(ROFF_ARGS)
|
|||
irc |= endloop;
|
||||
|
||||
/*
|
||||
* If `\}' occurs on a macro line without a preceding macro,
|
||||
* drop the line completely.
|
||||
* If "\}" occurs on a macro line without a preceding macro or
|
||||
* a text line contains nothing else, drop the line completely.
|
||||
*/
|
||||
|
||||
ep = buf->buf + pos;
|
||||
if (ep[0] == '\\' && ep[1] == '}')
|
||||
if (ep[0] == '\\' && ep[1] == '}' && (ep[2] == '\0' || *offs == 0))
|
||||
rr = 0;
|
||||
|
||||
/*
|
||||
* The closing delimiter `\}' rewinds the conditional scope
|
||||
* The closing delimiter "\}" rewinds the conditional scope
|
||||
* but is otherwise ignored when interpreting the line.
|
||||
*/
|
||||
|
||||
while ((ep = strchr(ep, '\\')) != NULL) {
|
||||
switch (ep[1]) {
|
||||
case '}':
|
||||
memmove(ep, ep + 2, strlen(ep + 2) + 1);
|
||||
if (ep[2] == '\0')
|
||||
ep[0] = '\0';
|
||||
else if (rr)
|
||||
ep[1] = '&';
|
||||
else
|
||||
memmove(ep, ep + 2, strlen(ep + 2) + 1);
|
||||
if (roff_ccond(r, ln, ep - buf->buf))
|
||||
irc |= endloop;
|
||||
break;
|
||||
|
@ -2289,13 +2387,40 @@ roff_cond_sub(ROFF_ARGS)
|
|||
break;
|
||||
}
|
||||
}
|
||||
*offs = rr;
|
||||
return irc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and process a request or macro line in conditional scope.
|
||||
*/
|
||||
static int
|
||||
roff_cond_sub(ROFF_ARGS)
|
||||
{
|
||||
struct roffnode *bl;
|
||||
int irc, rr;
|
||||
enum roff_tok t;
|
||||
|
||||
rr = 0; /* If arguments follow "\}", skip them. */
|
||||
irc = roff_cond_checkend(r, tok, buf, ln, ppos, pos, &rr);
|
||||
t = roff_parse(r, buf->buf, &pos, ln, ppos);
|
||||
|
||||
/* For now, let high level macros abort .ce mode. */
|
||||
|
||||
if (roffce_node != NULL &&
|
||||
(t == TOKEN_NONE || t == ROFF_Dd || t == ROFF_EQ ||
|
||||
t == ROFF_TH || t == ROFF_TS)) {
|
||||
r->man->last = roffce_node;
|
||||
r->man->next = ROFF_NEXT_SIBLING;
|
||||
roffce_lines = 0;
|
||||
roffce_node = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fully handle known macros when they are structurally
|
||||
* required or when the conditional evaluated to true.
|
||||
*/
|
||||
|
||||
t = roff_parse(r, buf->buf, &pos, ln, ppos);
|
||||
if (t == ROFF_break) {
|
||||
if (irc & ROFF_LOOPMASK)
|
||||
irc = ROFF_IGN | ROFF_LOOPEXIT;
|
||||
|
@ -2314,48 +2439,16 @@ roff_cond_sub(ROFF_ARGS)
|
|||
return irc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and process a text line in conditional scope.
|
||||
*/
|
||||
static int
|
||||
roff_cond_text(ROFF_ARGS)
|
||||
{
|
||||
char *ep;
|
||||
int endloop, irc, rr;
|
||||
int irc, rr;
|
||||
|
||||
irc = ROFF_IGN;
|
||||
rr = r->last->rule;
|
||||
endloop = tok != ROFF_while ? ROFF_IGN :
|
||||
rr ? ROFF_LOOPCONT : ROFF_LOOPEXIT;
|
||||
if (roffnode_cleanscope(r))
|
||||
irc |= endloop;
|
||||
|
||||
/*
|
||||
* If `\}' occurs on a text line with neither preceding
|
||||
* nor following characters, drop the line completely.
|
||||
*/
|
||||
|
||||
ep = buf->buf + pos;
|
||||
if (strcmp(ep, "\\}") == 0)
|
||||
rr = 0;
|
||||
|
||||
/*
|
||||
* The closing delimiter `\}' rewinds the conditional scope
|
||||
* but is otherwise ignored when interpreting the line.
|
||||
*/
|
||||
|
||||
while ((ep = strchr(ep, '\\')) != NULL) {
|
||||
switch (ep[1]) {
|
||||
case '}':
|
||||
memmove(ep, ep + 2, strlen(ep + 2) + 1);
|
||||
if (roff_ccond(r, ln, ep - buf->buf))
|
||||
irc |= endloop;
|
||||
break;
|
||||
case '\0':
|
||||
++ep;
|
||||
break;
|
||||
default:
|
||||
ep += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rr = 1; /* If arguments follow "\}", preserve them. */
|
||||
irc = roff_cond_checkend(r, tok, buf, ln, ppos, pos, &rr);
|
||||
if (rr)
|
||||
irc |= ROFF_CONT;
|
||||
return irc;
|
||||
|
@ -3574,7 +3667,9 @@ roff_char(ROFF_ARGS)
|
|||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTBI:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTCR:
|
||||
case ESCAPE_FONTCB:
|
||||
case ESCAPE_FONTCI:
|
||||
case ESCAPE_FONTPREV:
|
||||
font++;
|
||||
break;
|
||||
|
|
17
roff.h
17
roff.h
|
@ -1,7 +1,7 @@
|
|||
/* $Id: roff.h,v 1.69 2019/03/04 13:01:57 schwarze Exp $ */
|
||||
/* $Id: roff.h,v 1.74 2020/04/08 11:56:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2015, 2017-2019 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
|
||||
|
@ -437,6 +437,7 @@ enum roff_tok {
|
|||
MDOC__Q,
|
||||
MDOC__U,
|
||||
MDOC_Ta,
|
||||
MDOC_Tg,
|
||||
MDOC_MAX,
|
||||
MAN_TH,
|
||||
MAN_SH,
|
||||
|
@ -505,6 +506,7 @@ struct roff_node {
|
|||
struct mdoc_arg *args; /* BLOCK/ELEM */
|
||||
union mdoc_data *norm; /* Normalized arguments. */
|
||||
char *string; /* TEXT */
|
||||
char *tag; /* For less(1) :t and HTML id=. */
|
||||
struct tbl_span *span; /* TBL */
|
||||
struct eqn_box *eqn; /* EQN */
|
||||
int line; /* Input file line number. */
|
||||
|
@ -521,6 +523,8 @@ struct roff_node {
|
|||
#define NODE_NOFILL (1 << 8) /* Fill mode switched off. */
|
||||
#define NODE_NOSRC (1 << 9) /* Generated node, not in input file. */
|
||||
#define NODE_NOPRT (1 << 10) /* Shall not print anything. */
|
||||
#define NODE_ID (1 << 11) /* Target for deep linking. */
|
||||
#define NODE_HREF (1 << 12) /* Link to another place in this page. */
|
||||
int prev_font; /* Before entering this node. */
|
||||
int aux; /* Decoded node data, type-dependent. */
|
||||
enum roff_tok tok; /* Request or macro ID. */
|
||||
|
@ -548,5 +552,10 @@ struct roff_meta {
|
|||
extern const char *const *roff_name;
|
||||
|
||||
|
||||
int arch_valid(const char *, enum mandoc_os);
|
||||
void deroff(char **, const struct roff_node *);
|
||||
int arch_valid(const char *, enum mandoc_os);
|
||||
void deroff(char **, const struct roff_node *);
|
||||
struct roff_node *roff_node_child(struct roff_node *);
|
||||
struct roff_node *roff_node_next(struct roff_node *);
|
||||
struct roff_node *roff_node_prev(struct roff_node *);
|
||||
int roff_node_transparent(struct roff_node *);
|
||||
int roff_tok_transparent(enum roff_tok);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: roff_html.c,v 1.20 2019/04/30 15:53:01 schwarze Exp $ */
|
||||
/* $Id: roff_html.c,v 1.21 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -15,6 +15,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $Id: roff_int.h,v 1.16 2019/01/05 00:36:50 schwarze Exp $ */
|
||||
/* $OpenBSD: roff_int.h,v 1.16 2019/01/05 00:36:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2015, 2017-2019 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
|
||||
|
@ -59,6 +59,7 @@ struct roff_man {
|
|||
enum roff_sec lastsec; /* Last section seen. */
|
||||
enum roff_sec lastnamed; /* Last standard section seen. */
|
||||
enum roff_next next; /* Where to put the next node. */
|
||||
char filesec; /* Section digit in the file name. */
|
||||
};
|
||||
|
||||
|
||||
|
|
56
roff_term.c
56
roff_term.c
|
@ -1,6 +1,6 @@
|
|||
/* $Id: roff_term.c,v 1.19 2019/01/04 03:24:33 schwarze Exp $ */
|
||||
/* $OpenBSD: roff_term.c,v 1.20 2020/09/03 17:37:06 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010,2014,2015,2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010,2014,2015,2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -110,9 +112,11 @@ roff_term_pre_ft(ROFF_TERM_ARGS)
|
|||
cp = n->child->string;
|
||||
switch (mandoc_font(cp, (int)strlen(cp))) {
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTCB:
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTCI:
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
break;
|
||||
case ESCAPE_FONTBI:
|
||||
|
@ -122,7 +126,7 @@ roff_term_pre_ft(ROFF_TERM_ARGS)
|
|||
term_fontlast(p);
|
||||
break;
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTCR:
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
break;
|
||||
default:
|
||||
|
@ -155,9 +159,13 @@ static void
|
|||
roff_term_pre_po(ROFF_TERM_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
static int po, polast;
|
||||
static int po, pouse, polast;
|
||||
int ponew;
|
||||
|
||||
/* Revert the currently active page offset. */
|
||||
p->tcol->offset -= pouse;
|
||||
|
||||
/* Determine the requested page offset. */
|
||||
if (n->child != NULL &&
|
||||
a2roffsu(n->child->string, &su, SCALE_EM) != NULL) {
|
||||
ponew = term_hen(p, &su);
|
||||
|
@ -166,11 +174,15 @@ roff_term_pre_po(ROFF_TERM_ARGS)
|
|||
ponew += po;
|
||||
} else
|
||||
ponew = polast;
|
||||
|
||||
/* Remeber both the previous and the newly requested offset. */
|
||||
polast = po;
|
||||
po = ponew;
|
||||
|
||||
ponew = po - polast + (int)p->tcol->offset;
|
||||
p->tcol->offset = ponew > 0 ? ponew : 0;
|
||||
/* Truncate to the range [-offset, 60], remember, and apply it. */
|
||||
pouse = po >= 60 ? 60 :
|
||||
po < -(int)p->tcol->offset ? -(int)p->tcol->offset : po;
|
||||
p->tcol->offset += pouse;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -208,6 +220,7 @@ roff_term_pre_ti(ROFF_TERM_ARGS)
|
|||
{
|
||||
struct roffsu su;
|
||||
const char *cp;
|
||||
const size_t maxoff = 72;
|
||||
int len, sign;
|
||||
|
||||
roff_term_pre_br(p, n);
|
||||
|
@ -228,17 +241,26 @@ roff_term_pre_ti(ROFF_TERM_ARGS)
|
|||
return;
|
||||
len = term_hen(p, &su);
|
||||
|
||||
if (sign == 0) {
|
||||
switch (sign) {
|
||||
case 1:
|
||||
if (p->tcol->offset + len <= maxoff)
|
||||
p->ti = len;
|
||||
else if (p->tcol->offset < maxoff)
|
||||
p->ti = maxoff - p->tcol->offset;
|
||||
else
|
||||
p->ti = 0;
|
||||
break;
|
||||
case -1:
|
||||
if ((size_t)len < p->tcol->offset)
|
||||
p->ti = -len;
|
||||
else
|
||||
p->ti = -p->tcol->offset;
|
||||
break;
|
||||
default:
|
||||
if ((size_t)len > maxoff)
|
||||
len = maxoff;
|
||||
p->ti = len - p->tcol->offset;
|
||||
p->tcol->offset = len;
|
||||
} else if (sign == 1) {
|
||||
p->ti = len;
|
||||
p->tcol->offset += len;
|
||||
} else if ((size_t)len < p->tcol->offset) {
|
||||
p->ti = -len;
|
||||
p->tcol->offset -= len;
|
||||
} else {
|
||||
p->ti = -p->tcol->offset;
|
||||
p->tcol->offset = 0;
|
||||
break;
|
||||
}
|
||||
p->tcol->offset += p->ti;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $Id: roff_validate.c,v 1.18 2018/12/31 09:02:37 schwarze Exp $ */
|
||||
/* $Id: roff_validate.c,v 1.20 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -75,7 +77,7 @@ roff_valid_br(ROFF_VALID_ARGS)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((np = n->prev) == NULL)
|
||||
if ((np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
switch (np->tok) {
|
||||
|
@ -129,7 +131,7 @@ roff_valid_sp(ROFF_VALID_ARGS)
|
|||
{
|
||||
struct roff_node *np;
|
||||
|
||||
if ((np = n->prev) == NULL)
|
||||
if ((np = roff_node_prev(n)) == NULL)
|
||||
return;
|
||||
|
||||
switch (np->tok) {
|
||||
|
|
8
soelim.c
8
soelim.c
|
@ -1,4 +1,4 @@
|
|||
/* $Id: soelim.c,v 1.5 2015/11/07 14:22:29 schwarze Exp $ */
|
||||
/* $Id: soelim.c,v 1.6 2021/09/19 18:14:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
|
@ -104,16 +104,16 @@ soelim_file(FILE *f, int flag)
|
|||
}
|
||||
|
||||
walk = line + 3;
|
||||
if (!isspace(*walk) && ((flag & C_OPTION) == 0)) {
|
||||
if (!isspace((unsigned char)*walk) && (flag & C_OPTION) == 0) {
|
||||
printf("%s", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (isspace(*walk))
|
||||
while (isspace((unsigned char)*walk))
|
||||
walk++;
|
||||
|
||||
cp = walk;
|
||||
while (*cp != '\0' && !isspace(*cp))
|
||||
while (*cp != '\0' && !isspace((unsigned char)*cp))
|
||||
cp++;
|
||||
*cp = 0;
|
||||
if (cp < line + linelen)
|
||||
|
|
433
tag.c
433
tag.c
|
@ -1,6 +1,6 @@
|
|||
/* $Id: tag.c,v 1.24 2019/07/22 03:21:50 schwarze Exp $ */
|
||||
/* $Id: tag.c,v 1.36 2020/04/19 16:36:16 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -13,142 +13,109 @@
|
|||
* 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.
|
||||
*
|
||||
* Functions to tag syntax tree nodes.
|
||||
* For internal use by mandoc(1) validation modules only.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "roff_int.h"
|
||||
#include "tag.h"
|
||||
|
||||
struct tag_entry {
|
||||
size_t *lines;
|
||||
size_t maxlines;
|
||||
size_t nlines;
|
||||
struct roff_node **nodes;
|
||||
size_t maxnodes;
|
||||
size_t nnodes;
|
||||
int prio;
|
||||
char s[];
|
||||
};
|
||||
|
||||
static void tag_signal(int) __attribute__((__noreturn__));
|
||||
static void tag_move_href(struct roff_man *,
|
||||
struct roff_node *, const char *);
|
||||
static void tag_move_id(struct roff_node *);
|
||||
|
||||
static struct ohash tag_data;
|
||||
static struct tag_files tag_files;
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for using a pager.
|
||||
* Not all pagers are capable of using a tag file,
|
||||
* but for simplicity, create it anyway.
|
||||
* Set up the ohash table to collect nodes
|
||||
* where various marked-up terms are documented.
|
||||
*/
|
||||
struct tag_files *
|
||||
tag_init(void)
|
||||
void
|
||||
tag_alloc(void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
int ofd;
|
||||
|
||||
ofd = -1;
|
||||
tag_files.tfd = -1;
|
||||
tag_files.tcpgid = -1;
|
||||
|
||||
/* Clean up when dying from a signal. */
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigfillset(&sa.sa_mask);
|
||||
sa.sa_handler = tag_signal;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
/*
|
||||
* POSIX requires that a process calling tcsetpgrp(3)
|
||||
* from the background gets a SIGTTOU signal.
|
||||
* In that case, do not stop.
|
||||
*/
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGTTOU, &sa, NULL);
|
||||
|
||||
/* Save the original standard output for use by the pager. */
|
||||
|
||||
if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Create both temporary output files. */
|
||||
|
||||
(void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX",
|
||||
sizeof(tag_files.ofn));
|
||||
(void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
|
||||
sizeof(tag_files.tfn));
|
||||
if ((ofd = mkstemp(tag_files.ofn)) == -1) {
|
||||
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
|
||||
"%s: %s", tag_files.ofn, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1) {
|
||||
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
|
||||
"%s: %s", tag_files.tfn, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
if (dup2(ofd, STDOUT_FILENO) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
close(ofd);
|
||||
|
||||
/*
|
||||
* Set up the ohash table to collect output line numbers
|
||||
* where various marked-up terms are documented.
|
||||
*/
|
||||
|
||||
mandoc_ohash_init(&tag_data, 4, offsetof(struct tag_entry, s));
|
||||
return &tag_files;
|
||||
}
|
||||
|
||||
fail:
|
||||
tag_unlink();
|
||||
if (ofd != -1)
|
||||
close(ofd);
|
||||
if (tag_files.ofd != -1)
|
||||
close(tag_files.ofd);
|
||||
if (tag_files.tfd != -1)
|
||||
close(tag_files.tfd);
|
||||
*tag_files.ofn = '\0';
|
||||
*tag_files.tfn = '\0';
|
||||
tag_files.ofd = -1;
|
||||
tag_files.tfd = -1;
|
||||
return NULL;
|
||||
void
|
||||
tag_free(void)
|
||||
{
|
||||
struct tag_entry *entry;
|
||||
unsigned int slot;
|
||||
|
||||
if (tag_data.info.free == NULL)
|
||||
return;
|
||||
entry = ohash_first(&tag_data, &slot);
|
||||
while (entry != NULL) {
|
||||
free(entry->nodes);
|
||||
free(entry);
|
||||
entry = ohash_next(&tag_data, &slot);
|
||||
}
|
||||
ohash_delete(&tag_data);
|
||||
tag_data.info.free = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the line number where a term is defined,
|
||||
* Set a node where a term is defined,
|
||||
* unless it is already defined at a lower priority.
|
||||
*/
|
||||
void
|
||||
tag_put(const char *s, int prio, size_t line)
|
||||
tag_put(const char *s, int prio, struct roff_node *n)
|
||||
{
|
||||
struct tag_entry *entry;
|
||||
struct roff_node *nold;
|
||||
const char *se;
|
||||
size_t len;
|
||||
unsigned int slot;
|
||||
|
||||
if (tag_files.tfd <= 0)
|
||||
return;
|
||||
assert(prio <= TAG_FALLBACK);
|
||||
|
||||
if (s[0] == '\\' && (s[1] == '&' || s[1] == 'e'))
|
||||
s += 2;
|
||||
if (s == NULL) {
|
||||
if (n->child == NULL || n->child->type != ROFFT_TEXT)
|
||||
return;
|
||||
s = n->child->string;
|
||||
switch (s[0]) {
|
||||
case '-':
|
||||
s++;
|
||||
break;
|
||||
case '\\':
|
||||
switch (s[1]) {
|
||||
case '&':
|
||||
case '-':
|
||||
case 'e':
|
||||
s += 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip whitespace and escapes and whatever follows,
|
||||
|
@ -160,137 +127,201 @@ tag_put(const char *s, int prio, size_t line)
|
|||
return;
|
||||
|
||||
se = s + len;
|
||||
if (*se != '\0')
|
||||
prio = INT_MAX;
|
||||
if (*se != '\0' && prio < TAG_WEAK)
|
||||
prio = TAG_WEAK;
|
||||
|
||||
slot = ohash_qlookupi(&tag_data, s, &se);
|
||||
entry = ohash_find(&tag_data, slot);
|
||||
|
||||
/* Build a new entry. */
|
||||
|
||||
if (entry == NULL) {
|
||||
|
||||
/* Build a new entry. */
|
||||
|
||||
entry = mandoc_malloc(sizeof(*entry) + len + 1);
|
||||
memcpy(entry->s, s, len);
|
||||
entry->s[len] = '\0';
|
||||
entry->lines = NULL;
|
||||
entry->maxlines = entry->nlines = 0;
|
||||
entry->nodes = NULL;
|
||||
entry->maxnodes = entry->nnodes = 0;
|
||||
ohash_insert(&tag_data, slot, entry);
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Lower priority numbers take precedence.
|
||||
* If a better entry is already present, ignore the new one.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lower priority numbers take precedence,
|
||||
* but 0 is special.
|
||||
* A tag with priority 0 is only used
|
||||
* if the tag occurs exactly once.
|
||||
*/
|
||||
else if (entry->prio < prio)
|
||||
return;
|
||||
|
||||
if (prio == 0) {
|
||||
if (entry->prio == 0)
|
||||
entry->prio = -1;
|
||||
/*
|
||||
* If the existing entry is worse, clear it.
|
||||
* In addition, a tag with priority TAG_FALLBACK
|
||||
* is only used if the tag occurs exactly once.
|
||||
*/
|
||||
|
||||
else if (entry->prio > prio || prio == TAG_FALLBACK) {
|
||||
while (entry->nnodes > 0) {
|
||||
nold = entry->nodes[--entry->nnodes];
|
||||
nold->flags &= ~NODE_ID;
|
||||
free(nold->tag);
|
||||
nold->tag = NULL;
|
||||
}
|
||||
if (prio == TAG_FALLBACK) {
|
||||
entry->prio = TAG_DELETE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* A better entry is already present, ignore the new one. */
|
||||
|
||||
if (entry->prio > 0 && entry->prio < prio)
|
||||
return;
|
||||
|
||||
/* The existing entry is worse, clear it. */
|
||||
|
||||
if (entry->prio < 1 || entry->prio > prio)
|
||||
entry->nlines = 0;
|
||||
}
|
||||
|
||||
/* Remember the new line. */
|
||||
/* Remember the new node. */
|
||||
|
||||
if (entry->maxlines == entry->nlines) {
|
||||
entry->maxlines += 4;
|
||||
entry->lines = mandoc_reallocarray(entry->lines,
|
||||
entry->maxlines, sizeof(*entry->lines));
|
||||
if (entry->maxnodes == entry->nnodes) {
|
||||
entry->maxnodes += 4;
|
||||
entry->nodes = mandoc_reallocarray(entry->nodes,
|
||||
entry->maxnodes, sizeof(*entry->nodes));
|
||||
}
|
||||
entry->lines[entry->nlines++] = line;
|
||||
entry->nodes[entry->nnodes++] = n;
|
||||
entry->prio = prio;
|
||||
n->flags |= NODE_ID;
|
||||
if (n->child == NULL || n->child->string != s || *se != '\0') {
|
||||
assert(n->tag == NULL);
|
||||
n->tag = mandoc_strndup(s, len);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tag_exists(const char *tag)
|
||||
{
|
||||
return ohash_find(&tag_data, ohash_qlookup(&tag_data, tag)) != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the tags file using the previously collected
|
||||
* information and clear the ohash table while going along.
|
||||
* For in-line elements, move the link target
|
||||
* to the enclosing paragraph when appropriate.
|
||||
*/
|
||||
static void
|
||||
tag_move_id(struct roff_node *n)
|
||||
{
|
||||
struct roff_node *np;
|
||||
|
||||
np = n;
|
||||
for (;;) {
|
||||
if (np->prev != NULL)
|
||||
np = np->prev;
|
||||
else if ((np = np->parent) == NULL)
|
||||
return;
|
||||
switch (np->tok) {
|
||||
case MDOC_It:
|
||||
switch (np->parent->parent->norm->Bl.type) {
|
||||
case LIST_column:
|
||||
/* Target the ROFFT_BLOCK = <tr>. */
|
||||
np = np->parent;
|
||||
break;
|
||||
case LIST_diag:
|
||||
case LIST_hang:
|
||||
case LIST_inset:
|
||||
case LIST_ohang:
|
||||
case LIST_tag:
|
||||
/* Target the ROFFT_HEAD = <dt>. */
|
||||
np = np->parent->head;
|
||||
break;
|
||||
default:
|
||||
/* Target the ROFF_BODY = <li>. */
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case MDOC_Pp: /* Target the ROFFT_ELEM = <p>. */
|
||||
if (np->tag == NULL) {
|
||||
np->tag = mandoc_strdup(n->tag == NULL ?
|
||||
n->child->string : n->tag);
|
||||
np->flags |= NODE_ID;
|
||||
n->flags &= ~NODE_ID;
|
||||
}
|
||||
return;
|
||||
case MDOC_Sh:
|
||||
case MDOC_Ss:
|
||||
case MDOC_Bd:
|
||||
case MDOC_Bl:
|
||||
case MDOC_D1:
|
||||
case MDOC_Dl:
|
||||
case MDOC_Rs:
|
||||
/* Do not move past major blocks. */
|
||||
return;
|
||||
default:
|
||||
/*
|
||||
* Move past in-line content and partial
|
||||
* blocks, for example .It Xo or .It Bq Er.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When a paragraph is tagged and starts with text,
|
||||
* move the permalink to the first few words.
|
||||
*/
|
||||
static void
|
||||
tag_move_href(struct roff_man *man, struct roff_node *n, const char *tag)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (n == NULL || n->type != ROFFT_TEXT ||
|
||||
*n->string == '\0' || *n->string == ' ')
|
||||
return;
|
||||
|
||||
cp = n->string;
|
||||
while (cp != NULL && cp - n->string < 5)
|
||||
cp = strchr(cp + 1, ' ');
|
||||
|
||||
/* If the first text node is longer, split it. */
|
||||
|
||||
if (cp != NULL && cp[1] != '\0') {
|
||||
man->last = n;
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
roff_word_alloc(man, n->line,
|
||||
n->pos + (cp - n->string), cp + 1);
|
||||
man->last->flags = n->flags & ~NODE_LINE;
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
assert(n->tag == NULL);
|
||||
n->tag = mandoc_strdup(tag);
|
||||
n->flags |= NODE_HREF;
|
||||
}
|
||||
|
||||
/*
|
||||
* When all tags have been set, decide where to put
|
||||
* the associated permalinks, and maybe move some tags
|
||||
* to the beginning of the respective paragraphs.
|
||||
*/
|
||||
void
|
||||
tag_write(void)
|
||||
tag_postprocess(struct roff_man *man, struct roff_node *n)
|
||||
{
|
||||
FILE *stream;
|
||||
struct tag_entry *entry;
|
||||
size_t i;
|
||||
unsigned int slot;
|
||||
int empty;
|
||||
|
||||
if (tag_files.tfd <= 0)
|
||||
return;
|
||||
if (tag_files.tagname != NULL && ohash_find(&tag_data,
|
||||
ohash_qlookup(&tag_data, tag_files.tagname)) == NULL) {
|
||||
mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname);
|
||||
tag_files.tagname = NULL;
|
||||
}
|
||||
if ((stream = fdopen(tag_files.tfd, "w")) == NULL)
|
||||
mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
|
||||
empty = 1;
|
||||
entry = ohash_first(&tag_data, &slot);
|
||||
while (entry != NULL) {
|
||||
if (stream != NULL && entry->prio >= 0) {
|
||||
for (i = 0; i < entry->nlines; i++) {
|
||||
fprintf(stream, "%s %s %zu\n",
|
||||
entry->s, tag_files.ofn, entry->lines[i]);
|
||||
empty = 0;
|
||||
if (n->flags & NODE_ID) {
|
||||
switch (n->tok) {
|
||||
case MDOC_Pp:
|
||||
tag_move_href(man, n->next, n->tag);
|
||||
break;
|
||||
case MDOC_Bd:
|
||||
case MDOC_D1:
|
||||
case MDOC_Dl:
|
||||
tag_move_href(man, n->child, n->tag);
|
||||
break;
|
||||
case MDOC_Bl:
|
||||
/* XXX No permalink for now. */
|
||||
break;
|
||||
default:
|
||||
if (n->type == ROFFT_ELEM || n->tok == MDOC_Fo)
|
||||
tag_move_id(n);
|
||||
if (n->tok != MDOC_Tg)
|
||||
n->flags |= NODE_HREF;
|
||||
else if ((n->flags & NODE_ID) == 0) {
|
||||
n->flags |= NODE_NOPRT;
|
||||
free(n->tag);
|
||||
n->tag = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(entry->lines);
|
||||
free(entry);
|
||||
entry = ohash_next(&tag_data, &slot);
|
||||
}
|
||||
ohash_delete(&tag_data);
|
||||
if (stream != NULL)
|
||||
fclose(stream);
|
||||
else
|
||||
close(tag_files.tfd);
|
||||
tag_files.tfd = -1;
|
||||
if (empty) {
|
||||
unlink(tag_files.tfn);
|
||||
*tag_files.tfn = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tag_unlink(void)
|
||||
{
|
||||
pid_t tc_pgid;
|
||||
|
||||
if (tag_files.tcpgid != -1) {
|
||||
tc_pgid = tcgetpgrp(tag_files.ofd);
|
||||
if (tc_pgid == tag_files.pager_pid ||
|
||||
tc_pgid == getpgid(0) ||
|
||||
getpgid(tc_pgid) == -1)
|
||||
(void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid);
|
||||
}
|
||||
if (*tag_files.ofn != '\0')
|
||||
unlink(tag_files.ofn);
|
||||
if (*tag_files.tfn != '\0')
|
||||
unlink(tag_files.tfn);
|
||||
}
|
||||
|
||||
static void
|
||||
tag_signal(int signum)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
tag_unlink();
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction(signum, &sa, NULL);
|
||||
kill(getpid(), signum);
|
||||
/* NOTREACHED */
|
||||
_exit(1);
|
||||
for (n = n->child; n != NULL; n = n->next)
|
||||
tag_postprocess(man, n);
|
||||
}
|
||||
|
|
35
tag.h
35
tag.h
|
@ -1,6 +1,6 @@
|
|||
/* $Id: tag.h,v 1.8 2018/11/22 11:30:23 schwarze Exp $ */
|
||||
/* $Id: tag.h,v 1.14 2020/04/18 20:40:10 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2015, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -13,20 +13,23 @@
|
|||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Internal interfaces to tag syntax tree nodes.
|
||||
* For use by mandoc(1) validation modules only.
|
||||
*/
|
||||
|
||||
struct tag_files {
|
||||
char ofn[20];
|
||||
char tfn[20];
|
||||
char *tagname;
|
||||
int ofd;
|
||||
int tfd;
|
||||
pid_t tcpgid;
|
||||
pid_t pager_pid;
|
||||
};
|
||||
/*
|
||||
* Tagging priorities.
|
||||
* Lower numbers indicate higher importance.
|
||||
*/
|
||||
#define TAG_MANUAL 1 /* Set with a .Tg macro. */
|
||||
#define TAG_STRONG 2 /* Good automatic tagging. */
|
||||
#define TAG_WEAK (INT_MAX - 2) /* Dubious automatic tagging. */
|
||||
#define TAG_FALLBACK (INT_MAX - 1) /* Tag only used if unique. */
|
||||
#define TAG_DELETE (INT_MAX) /* Tag not used at all. */
|
||||
|
||||
|
||||
struct tag_files *tag_init(void);
|
||||
void tag_put(const char *, int, size_t);
|
||||
void tag_write(void);
|
||||
void tag_unlink(void);
|
||||
void tag_alloc(void);
|
||||
int tag_exists(const char *);
|
||||
void tag_put(const char *, int, struct roff_node *);
|
||||
void tag_postprocess(struct roff_man *, struct roff_node *);
|
||||
void tag_free(void);
|
||||
|
|
13
tbl.7
13
tbl.7
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: tbl.7,v 1.34 2019/03/02 21:03:02 schwarze Exp $
|
||||
.\" $Id: tbl.7,v 1.37 2021/09/18 12:34:27 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2014,2015,2017,2018,2019 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 2 2019 $
|
||||
.Dd $Mdocdate: September 18 2021 $
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -94,7 +94,7 @@ Allow page breaks within the table.
|
|||
This is a GNU extension and currently ignored.
|
||||
.It Cm nospaces
|
||||
Ignore leading and trailing spaces in data cells.
|
||||
This is a GNU extension and currently ignored.
|
||||
This is a GNU extension.
|
||||
.It Cm nowarn
|
||||
Suppress warnings about tables exceeding the current line length.
|
||||
This is a GNU extension and currently ignored.
|
||||
|
@ -178,10 +178,11 @@ of any other column also having the
|
|||
.Cm e
|
||||
modifier.
|
||||
.It Cm f
|
||||
The next character selects the font to use for this cell.
|
||||
The next one or two characters select the font to use for this cell.
|
||||
One-character font names must be followed by a blank or period.
|
||||
See the
|
||||
.Xr roff 7
|
||||
manual for supported one-character font names.
|
||||
manual for supported font names.
|
||||
.It Cm i
|
||||
Use an italic font for the contents of this cell.
|
||||
.It Cm m
|
||||
|
@ -416,7 +417,7 @@ equations inside tables.
|
|||
.Xr roff 7
|
||||
.Rs
|
||||
.%A M. E. Lesk
|
||||
.%T Tbl\(emA Program to Format Tables
|
||||
.%T Tbl \(em A Program to Format Tables
|
||||
.%D June 11, 1976
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
|
|
7
tbl.h
7
tbl.h
|
@ -1,7 +1,7 @@
|
|||
/* $Id: tbl.h,v 1.1 2018/12/12 21:54:35 schwarze Exp $ */
|
||||
/* $Id: tbl.h,v 1.2 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014,2015,2017,2018,2021 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
|
||||
|
@ -57,14 +57,13 @@ struct tbl_cell {
|
|||
int vert; /* Width of subsequent vertical line. */
|
||||
int col; /* Column number, starting from 0. */
|
||||
int flags;
|
||||
#define TBL_CELL_BOLD (1 << 0) /* b, B, fB */
|
||||
#define TBL_CELL_ITALIC (1 << 1) /* i, I, fI */
|
||||
#define TBL_CELL_TALIGN (1 << 2) /* t, T */
|
||||
#define TBL_CELL_UP (1 << 3) /* u, U */
|
||||
#define TBL_CELL_BALIGN (1 << 4) /* d, D */
|
||||
#define TBL_CELL_WIGN (1 << 5) /* z, Z */
|
||||
#define TBL_CELL_EQUAL (1 << 6) /* e, E */
|
||||
#define TBL_CELL_WMAX (1 << 7) /* x, X */
|
||||
enum mandoc_esc font;
|
||||
enum tbl_cellt pos;
|
||||
};
|
||||
|
||||
|
|
53
tbl_data.c
53
tbl_data.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: tbl_data.c,v 1.52 2019/02/09 16:00:39 schwarze Exp $ */
|
||||
/* $Id: tbl_data.c,v 1.59 2021/09/10 13:24:38 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011,2015,2017,2018,2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011,2015,2017-2019,2021 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
|
||||
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -45,16 +46,20 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
struct tbl_dat *dat, *pdat;
|
||||
struct tbl_cell *cp;
|
||||
struct tbl_span *pdp;
|
||||
int sv;
|
||||
const char *ccp;
|
||||
int startpos, endpos;
|
||||
|
||||
/*
|
||||
* Determine the length of the string in the cell
|
||||
* and advance the parse point to the end of the cell.
|
||||
*/
|
||||
|
||||
sv = *pos;
|
||||
while (p[*pos] != '\0' && p[*pos] != tbl->opts.tab)
|
||||
(*pos)++;
|
||||
startpos = *pos;
|
||||
ccp = p + startpos;
|
||||
while (*ccp != '\0' && *ccp != tbl->opts.tab)
|
||||
if (*ccp++ == '\\')
|
||||
mandoc_escape(&ccp, NULL, NULL);
|
||||
*pos = ccp - p;
|
||||
|
||||
/* Advance to the next layout cell, skipping spanners. */
|
||||
|
||||
|
@ -73,12 +78,14 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
if (dp->layout->last->col + 1 < dp->opts->cols) {
|
||||
cp = mandoc_calloc(1, sizeof(*cp));
|
||||
cp->pos = TBL_CELL_LEFT;
|
||||
cp->font = ESCAPE_FONTROMAN;
|
||||
cp->spacing = SIZE_MAX;
|
||||
dp->layout->last->next = cp;
|
||||
cp->col = dp->layout->last->col + 1;
|
||||
dp->layout->last = cp;
|
||||
} else {
|
||||
mandoc_msg(MANDOCERR_TBLDATA_EXTRA,
|
||||
ln, sv, "%s", p + sv);
|
||||
ln, startpos, "%s", p + startpos);
|
||||
while (p[*pos] != '\0')
|
||||
(*pos)++;
|
||||
return;
|
||||
|
@ -103,7 +110,8 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
*/
|
||||
|
||||
if (cp->pos == TBL_CELL_DOWN ||
|
||||
(*pos - sv == 2 && p[sv] == '\\' && p[sv + 1] == '^')) {
|
||||
(*pos - startpos == 2 &&
|
||||
p[startpos] == '\\' && p[startpos + 1] == '^')) {
|
||||
pdp = dp;
|
||||
while ((pdp = pdp->prev) != NULL) {
|
||||
pdat = pdp->first;
|
||||
|
@ -139,18 +147,29 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
dp->last->next = dat;
|
||||
dp->last = dat;
|
||||
|
||||
/* Strip leading and trailing spaces, if requested. */
|
||||
|
||||
endpos = *pos;
|
||||
if (dp->opts->opts & TBL_OPT_NOSPACE) {
|
||||
while (p[startpos] == ' ')
|
||||
startpos++;
|
||||
while (endpos > startpos && p[endpos - 1] == ' ')
|
||||
endpos--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a continued-data scope opening. This consists of a
|
||||
* trailing `T{' at the end of the line. Subsequent lines,
|
||||
* until a standalone `T}', are included in our cell.
|
||||
*/
|
||||
|
||||
if (*pos - sv == 2 && p[sv] == 'T' && p[sv + 1] == '{') {
|
||||
if (endpos - startpos == 2 &&
|
||||
p[startpos] == 'T' && p[startpos + 1] == '{') {
|
||||
tbl->part = TBL_PART_CDATA;
|
||||
return;
|
||||
}
|
||||
|
||||
dat->string = mandoc_strndup(p + sv, *pos - sv);
|
||||
dat->string = mandoc_strndup(p + startpos, endpos - startpos);
|
||||
|
||||
if (p[*pos] != '\0')
|
||||
(*pos)++;
|
||||
|
@ -171,7 +190,7 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
dat->layout->pos == TBL_CELL_DOWN) &&
|
||||
dat->pos == TBL_DATA_DATA && *dat->string != '\0')
|
||||
mandoc_msg(MANDOCERR_TBLDATA_SPAN,
|
||||
ln, sv, "%s", dat->string);
|
||||
ln, startpos, "%s", dat->string);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -184,6 +203,9 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
|||
|
||||
if (p[pos] == 'T' && p[pos + 1] == '}') {
|
||||
pos += 2;
|
||||
if (tbl->opts.opts & TBL_OPT_NOSPACE)
|
||||
while (p[pos] == ' ')
|
||||
pos++;
|
||||
if (p[pos] == tbl->opts.tab) {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
pos++;
|
||||
|
@ -242,10 +264,11 @@ tbl_data(struct tbl_node *tbl, int ln, const char *p, int pos)
|
|||
struct tbl_cell *cp;
|
||||
struct tbl_span *sp;
|
||||
|
||||
rp = (sp = tbl->last_span) == NULL ? tbl->first_row :
|
||||
sp->pos == TBL_SPAN_DATA && sp->layout->next != NULL ?
|
||||
sp->layout->next : sp->layout;
|
||||
|
||||
for (sp = tbl->last_span; sp != NULL; sp = sp->prev)
|
||||
if (sp->pos == TBL_SPAN_DATA)
|
||||
break;
|
||||
rp = sp == NULL ? tbl->first_row :
|
||||
sp->layout->next == NULL ? sp->layout : sp->layout->next;
|
||||
assert(rp != NULL);
|
||||
|
||||
if (p[1] == '\0') {
|
||||
|
|
42
tbl_html.c
42
tbl_html.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: tbl_html.c,v 1.33 2019/03/17 18:21:45 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.38 2021/09/09 16:52:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014,2015,2017,2018,2021 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
|
||||
|
@ -115,10 +115,14 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
|||
const struct tbl_dat *dp;
|
||||
const struct tbl_cell *cp;
|
||||
const struct tbl_span *psp;
|
||||
const struct roffcol *col;
|
||||
struct tag *tt;
|
||||
const char *hspans, *vspans, *halign, *valign;
|
||||
const char *bborder, *lborder, *rborder;
|
||||
const char *ccp;
|
||||
char hbuf[4], vbuf[4];
|
||||
size_t sz;
|
||||
enum mandoc_esc save_font;
|
||||
int i;
|
||||
|
||||
if (h->tblt == NULL)
|
||||
|
@ -240,8 +244,40 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
|||
"vertical-align", valign,
|
||||
"text-align", halign,
|
||||
"border-right-style", rborder);
|
||||
if (dp->string != NULL)
|
||||
if (dp->layout->pos == TBL_CELL_HORIZ ||
|
||||
dp->layout->pos == TBL_CELL_DHORIZ ||
|
||||
dp->pos == TBL_DATA_HORIZ ||
|
||||
dp->pos == TBL_DATA_DHORIZ)
|
||||
print_otag(h, TAG_HR, "");
|
||||
else if (dp->string != NULL) {
|
||||
save_font = h->metac;
|
||||
html_setfont(h, dp->layout->font);
|
||||
if (dp->layout->pos == TBL_CELL_LONG)
|
||||
print_text(h, "\\[u2003]"); /* em space */
|
||||
print_text(h, dp->string);
|
||||
if (dp->layout->pos == TBL_CELL_NUMBER) {
|
||||
col = h->tbl.cols + dp->layout->col;
|
||||
if (col->decimal < col->nwidth) {
|
||||
if ((ccp = strrchr(dp->string,
|
||||
sp->opts->decimal)) == NULL) {
|
||||
/* Punctuation space. */
|
||||
print_text(h, "\\[u2008]");
|
||||
ccp = strchr(dp->string, '\0');
|
||||
} else
|
||||
ccp++;
|
||||
sz = col->nwidth - col->decimal;
|
||||
while (--sz > 0) {
|
||||
if (*ccp == '\0')
|
||||
/* Figure space. */
|
||||
print_text(h,
|
||||
"\\[u2007]");
|
||||
else
|
||||
ccp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
html_setfont(h, save_font);
|
||||
}
|
||||
}
|
||||
|
||||
print_tagq(h, tt);
|
||||
|
|
61
tbl_layout.c
61
tbl_layout.c
|
@ -1,7 +1,8 @@
|
|||
/* $Id: tbl_layout.c,v 1.48 2018/12/14 05:18:03 schwarze Exp $ */
|
||||
/* $Id: tbl_layout.c,v 1.50 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021
|
||||
* Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -65,7 +66,10 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||
int ln, const char *p, int *pos)
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long spacing;
|
||||
size_t sz;
|
||||
int isz;
|
||||
enum mandoc_esc fontesc;
|
||||
|
||||
mod:
|
||||
while (p[*pos] == ' ' || p[*pos] == '\t')
|
||||
|
@ -93,14 +97,18 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||
/* Parse numerical spacing from modifier string. */
|
||||
|
||||
if (isdigit((unsigned char)p[*pos])) {
|
||||
cp->spacing = strtoull(p + *pos, &endptr, 10);
|
||||
if ((spacing = strtoul(p + *pos, &endptr, 10)) > 9)
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT_SPC, ln, *pos,
|
||||
"%lu", spacing);
|
||||
else
|
||||
cp->spacing = spacing;
|
||||
*pos = endptr - p;
|
||||
goto mod;
|
||||
}
|
||||
|
||||
switch (tolower((unsigned char)p[(*pos)++])) {
|
||||
case 'b':
|
||||
cp->flags |= TBL_CELL_BOLD;
|
||||
cp->font = ESCAPE_FONTBOLD;
|
||||
goto mod;
|
||||
case 'd':
|
||||
cp->flags |= TBL_CELL_BALIGN;
|
||||
|
@ -111,7 +119,7 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||
case 'f':
|
||||
break;
|
||||
case 'i':
|
||||
cp->flags |= TBL_CELL_ITALIC;
|
||||
cp->font = ESCAPE_FONTITALIC;
|
||||
goto mod;
|
||||
case 'm':
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT_MOD, ln, *pos, "m");
|
||||
|
@ -165,40 +173,34 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||
goto mod;
|
||||
}
|
||||
|
||||
while (p[*pos] == ' ' || p[*pos] == '\t')
|
||||
(*pos)++;
|
||||
|
||||
/* Ignore parenthised font names for now. */
|
||||
|
||||
if (p[*pos] == '(')
|
||||
goto mod;
|
||||
|
||||
/* Support only one-character font-names for now. */
|
||||
isz = 0;
|
||||
if (p[*pos] != '\0')
|
||||
isz++;
|
||||
if (strchr(" \t.", p[*pos + isz]) == NULL)
|
||||
isz++;
|
||||
|
||||
fontesc = mandoc_font(p + *pos, isz);
|
||||
|
||||
if (p[*pos] == '\0' || (p[*pos + 1] != ' ' && p[*pos + 1] != '.')) {
|
||||
switch (fontesc) {
|
||||
case ESCAPE_FONTPREV:
|
||||
case ESCAPE_ERROR:
|
||||
mandoc_msg(MANDOCERR_FT_BAD,
|
||||
ln, *pos, "TS %s", p + *pos - 1);
|
||||
if (p[*pos] != '\0')
|
||||
(*pos)++;
|
||||
if (p[*pos] != '\0')
|
||||
(*pos)++;
|
||||
goto mod;
|
||||
}
|
||||
|
||||
switch (p[(*pos)++]) {
|
||||
case '3':
|
||||
case 'B':
|
||||
cp->flags |= TBL_CELL_BOLD;
|
||||
goto mod;
|
||||
case '2':
|
||||
case 'I':
|
||||
cp->flags |= TBL_CELL_ITALIC;
|
||||
goto mod;
|
||||
case '1':
|
||||
case 'R':
|
||||
goto mod;
|
||||
break;
|
||||
default:
|
||||
mandoc_msg(MANDOCERR_FT_BAD,
|
||||
ln, *pos - 1, "TS f%c", p[*pos - 1]);
|
||||
goto mod;
|
||||
cp->font = fontesc;
|
||||
break;
|
||||
}
|
||||
*pos += isz;
|
||||
goto mod;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -357,6 +359,7 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
|
|||
|
||||
p = mandoc_calloc(1, sizeof(*p));
|
||||
p->spacing = SIZE_MAX;
|
||||
p->font = ESCAPE_FONTROMAN;
|
||||
p->pos = pos;
|
||||
|
||||
if ((pp = rp->last) != NULL) {
|
||||
|
|
60
tbl_term.c
60
tbl_term.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: tbl_term.c,v 1.72 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.75 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2021 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
|
||||
|
@ -190,17 +190,6 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
|
||||
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. */
|
||||
|
||||
offset = tp->tcol->offset;
|
||||
|
@ -267,11 +256,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
hspans--;
|
||||
continue;
|
||||
}
|
||||
if (dp == NULL)
|
||||
continue;
|
||||
hspans = dp->hspans;
|
||||
if (ic || sp->layout->first->pos != TBL_CELL_SPAN)
|
||||
if (dp != NULL &&
|
||||
(ic || sp->layout->first->pos != TBL_CELL_SPAN)) {
|
||||
hspans = dp->hspans;
|
||||
dp = dp->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up a column for a right vertical frame. */
|
||||
|
@ -302,11 +291,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
tp->tcol++;
|
||||
tp->col = 0;
|
||||
tbl_data(tp, sp->opts, cp, dp, tp->tbl.cols + ic);
|
||||
if (dp == NULL)
|
||||
continue;
|
||||
hspans = dp->hspans;
|
||||
if (cp->pos != TBL_CELL_SPAN)
|
||||
if (dp != NULL &&
|
||||
(ic || sp->layout->first->pos != TBL_CELL_SPAN)) {
|
||||
hspans = dp->hspans;
|
||||
dp = dp->next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -425,11 +414,10 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
cp = cp->next;
|
||||
continue;
|
||||
}
|
||||
if (dp != NULL) {
|
||||
if (dp != NULL && (ic ||
|
||||
sp->layout->first->pos != TBL_CELL_SPAN)) {
|
||||
hspans = dp->hspans;
|
||||
if (ic || sp->layout->first->pos
|
||||
!= TBL_CELL_SPAN)
|
||||
dp = dp->next;
|
||||
dp = dp->next;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -935,10 +923,24 @@ tbl_word(struct termp *tp, const struct tbl_dat *dp)
|
|||
int prev_font;
|
||||
|
||||
prev_font = tp->fonti;
|
||||
if (dp->layout->flags & TBL_CELL_BOLD)
|
||||
term_fontpush(tp, TERMFONT_BOLD);
|
||||
else if (dp->layout->flags & TBL_CELL_ITALIC)
|
||||
term_fontpush(tp, TERMFONT_UNDER);
|
||||
switch (dp->layout->font) {
|
||||
case ESCAPE_FONTBI:
|
||||
term_fontpush(tp, TERMFONT_BI);
|
||||
break;
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTCB:
|
||||
term_fontpush(tp, TERMFONT_BOLD);
|
||||
break;
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTCI:
|
||||
term_fontpush(tp, TERMFONT_UNDER);
|
||||
break;
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTCR:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
term_word(tp, dp->string);
|
||||
|
||||
|
|
25
term.c
25
term.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: term.c,v 1.281 2019/06/03 20:23:41 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.283 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2020 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,8 +38,7 @@ static void bufferc(struct termp *, char);
|
|||
static void encode(struct termp *, const char *, size_t);
|
||||
static void encode1(struct termp *, int);
|
||||
static void endline(struct termp *);
|
||||
static void term_field(struct termp *, size_t, size_t,
|
||||
size_t, size_t);
|
||||
static void term_field(struct termp *, size_t, size_t);
|
||||
static void term_fill(struct termp *, size_t *, size_t *,
|
||||
size_t);
|
||||
|
||||
|
@ -127,8 +126,7 @@ term_flushln(struct termp *p)
|
|||
* and with the BRNEVER flag, never break it at all.
|
||||
*/
|
||||
|
||||
vtarget = p->flags & TERMP_BRNEVER ? SIZE_MAX :
|
||||
(p->flags & TERMP_NOBREAK) == 0 ? vfield :
|
||||
vtarget = (p->flags & TERMP_NOBREAK) == 0 ? vfield :
|
||||
p->maxrmargin > p->viscol + vbl ?
|
||||
p->maxrmargin - p->viscol - vbl : 0;
|
||||
|
||||
|
@ -137,7 +135,8 @@ term_flushln(struct termp *p)
|
|||
* If there is whitespace only, print nothing.
|
||||
*/
|
||||
|
||||
term_fill(p, &nbr, &vbr, vtarget);
|
||||
term_fill(p, &nbr, &vbr,
|
||||
p->flags & TERMP_BRNEVER ? SIZE_MAX : vtarget);
|
||||
if (nbr == 0)
|
||||
break;
|
||||
|
||||
|
@ -156,7 +155,7 @@ term_flushln(struct termp *p)
|
|||
|
||||
/* Finally, print the field content. */
|
||||
|
||||
term_field(p, vbl, nbr, vbr, vtarget);
|
||||
term_field(p, vbl, nbr);
|
||||
|
||||
/*
|
||||
* If there is no text left in the field, exit the loop.
|
||||
|
@ -345,12 +344,10 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
|
|||
/*
|
||||
* Print the contents of one field
|
||||
* with an indentation of vbl visual columns,
|
||||
* an input string length of nbr characters,
|
||||
* an output width of vbr visual columns,
|
||||
* and a desired field width of vtarget visual columns.
|
||||
* and an input string length of nbr characters.
|
||||
*/
|
||||
static void
|
||||
term_field(struct termp *p, size_t vbl, size_t nbr, size_t vbr, size_t vtarget)
|
||||
term_field(struct termp *p, size_t vbl, size_t nbr)
|
||||
{
|
||||
size_t ic; /* Character position in the input buffer. */
|
||||
size_t vis; /* Visual position of the current character. */
|
||||
|
@ -592,16 +589,18 @@ term_word(struct termp *p, const char *word)
|
|||
uc = *seq;
|
||||
break;
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTCB:
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
continue;
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTCI:
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
continue;
|
||||
case ESCAPE_FONTBI:
|
||||
term_fontrepl(p, TERMFONT_BI);
|
||||
continue;
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTCR:
|
||||
case ESCAPE_FONTROMAN:
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
continue;
|
||||
|
|
32
term_ascii.c
32
term_ascii.c
|
@ -1,7 +1,7 @@
|
|||
/* $Id: term_ascii.c,v 1.64 2018/11/28 14:23:06 schwarze Exp $ */
|
||||
/* $Id: term_ascii.c,v 1.66 2020/09/09 13:45:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014,2015,2017,2018,2020 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
|
||||
|
@ -232,7 +232,10 @@ ascii_endline(struct termp *p)
|
|||
{
|
||||
|
||||
p->line++;
|
||||
p->tcol->offset -= p->ti;
|
||||
if ((int)p->tcol->offset > p->ti)
|
||||
p->tcol->offset -= p->ti;
|
||||
else
|
||||
p->tcol->offset = 0;
|
||||
p->ti = 0;
|
||||
putchar('\n');
|
||||
}
|
||||
|
@ -242,7 +245,14 @@ ascii_advance(struct termp *p, size_t len)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
assert(len < UINT16_MAX);
|
||||
/*
|
||||
* XXX We used to have "assert(len < UINT16_MAX)" here.
|
||||
* that is not quite right because the input document
|
||||
* can trigger that by merely providing large input.
|
||||
* For now, simply truncate.
|
||||
*/
|
||||
if (len > 256)
|
||||
len = 256;
|
||||
for (i = 0; i < len; i++)
|
||||
putchar(' ');
|
||||
}
|
||||
|
@ -380,7 +390,14 @@ locale_advance(struct termp *p, size_t len)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
assert(len < UINT16_MAX);
|
||||
/*
|
||||
* XXX We used to have "assert(len < UINT16_MAX)" here.
|
||||
* that is not quite right because the input document
|
||||
* can trigger that by merely providing large input.
|
||||
* For now, simply truncate.
|
||||
*/
|
||||
if (len > 256)
|
||||
len = 256;
|
||||
for (i = 0; i < len; i++)
|
||||
putwchar(L' ');
|
||||
}
|
||||
|
@ -390,7 +407,10 @@ locale_endline(struct termp *p)
|
|||
{
|
||||
|
||||
p->line++;
|
||||
p->tcol->offset -= p->ti;
|
||||
if ((int)p->tcol->offset > p->ti)
|
||||
p->tcol->offset -= p->ti;
|
||||
else
|
||||
p->tcol->offset = 0;
|
||||
p->ti = 0;
|
||||
putwchar(L'\n');
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $Id: term_ps.c,v 1.91 2017/11/10 23:42:52 schwarze Exp $ */
|
||||
/* $Id: term_ps.c,v 1.92 2020/09/06 14:45:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014,2015,2016,2017,2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2017 Marc Espie <espie@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -1252,7 +1252,10 @@ ps_endline(struct termp *p)
|
|||
|
||||
ps_closepage(p);
|
||||
|
||||
p->tcol->offset -= p->ti;
|
||||
if ((int)p->tcol->offset > p->ti)
|
||||
p->tcol->offset -= p->ti;
|
||||
else
|
||||
p->tcol->offset = 0;
|
||||
p->ti = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: term_tab.c,v 1.5 2018/12/16 00:21:05 schwarze Exp $ */
|
||||
/* $Id: term_tab.c,v 1.6 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -14,6 +14,8 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
|
227
term_tag.c
Normal file
227
term_tag.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/* $Id: term_tag.c,v 1.6 2021/03/30 17:16:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015,2016,2018,2019,2020 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.
|
||||
*
|
||||
* Functions to write a ctags(1) file.
|
||||
* For use by the mandoc(1) ASCII and UTF-8 formatters only.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "roff_int.h"
|
||||
#include "tag.h"
|
||||
#include "term_tag.h"
|
||||
|
||||
static void tag_signal(int) __attribute__((__noreturn__));
|
||||
|
||||
static struct tag_files tag_files;
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for using a pager.
|
||||
* Not all pagers are capable of using a tag file,
|
||||
* but for simplicity, create it anyway.
|
||||
*/
|
||||
struct tag_files *
|
||||
term_tag_init(const char *outfilename, const char *suffix,
|
||||
const char *tagfilename)
|
||||
{
|
||||
struct sigaction sa;
|
||||
int ofd; /* In /tmp/, dup(2)ed to stdout. */
|
||||
int tfd;
|
||||
|
||||
ofd = tfd = -1;
|
||||
tag_files.tfs = NULL;
|
||||
tag_files.tcpgid = -1;
|
||||
|
||||
/* Clean up when dying from a signal. */
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigfillset(&sa.sa_mask);
|
||||
sa.sa_handler = tag_signal;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
/*
|
||||
* POSIX requires that a process calling tcsetpgrp(3)
|
||||
* from the background gets a SIGTTOU signal.
|
||||
* In that case, do not stop.
|
||||
*/
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGTTOU, &sa, NULL);
|
||||
|
||||
/* Save the original standard output for use by the pager. */
|
||||
|
||||
if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Create both temporary output files. */
|
||||
|
||||
if (outfilename == NULL) {
|
||||
(void)snprintf(tag_files.ofn, sizeof(tag_files.ofn),
|
||||
"/tmp/man.XXXXXXXXXX%s", suffix);
|
||||
if ((ofd = mkstemps(tag_files.ofn, strlen(suffix))) == -1) {
|
||||
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
|
||||
"%s: %s", tag_files.ofn, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
(void)strlcpy(tag_files.ofn, outfilename,
|
||||
sizeof(tag_files.ofn));
|
||||
unlink(outfilename);
|
||||
ofd = open(outfilename, O_WRONLY | O_CREAT | O_EXCL, 0644);
|
||||
if (ofd == -1) {
|
||||
mandoc_msg(MANDOCERR_OPEN, 0, 0,
|
||||
"%s: %s", outfilename, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (tagfilename == NULL) {
|
||||
(void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
|
||||
sizeof(tag_files.tfn));
|
||||
if ((tfd = mkstemp(tag_files.tfn)) == -1) {
|
||||
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
|
||||
"%s: %s", tag_files.tfn, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
(void)strlcpy(tag_files.tfn, tagfilename,
|
||||
sizeof(tag_files.tfn));
|
||||
unlink(tagfilename);
|
||||
tfd = open(tagfilename, O_WRONLY | O_CREAT | O_EXCL, 0644);
|
||||
if (tfd == -1) {
|
||||
mandoc_msg(MANDOCERR_OPEN, 0, 0,
|
||||
"%s: %s", tagfilename, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if ((tag_files.tfs = fdopen(tfd, "w")) == NULL) {
|
||||
mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
tfd = -1;
|
||||
if (dup2(ofd, STDOUT_FILENO) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
close(ofd);
|
||||
return &tag_files;
|
||||
|
||||
fail:
|
||||
term_tag_unlink();
|
||||
if (ofd != -1)
|
||||
close(ofd);
|
||||
if (tfd != -1)
|
||||
close(tfd);
|
||||
if (tag_files.ofd != -1) {
|
||||
close(tag_files.ofd);
|
||||
tag_files.ofd = -1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
term_tag_write(struct roff_node *n, size_t line)
|
||||
{
|
||||
const char *cp;
|
||||
int len;
|
||||
|
||||
if (tag_files.tfs == NULL)
|
||||
return;
|
||||
cp = n->tag == NULL ? n->child->string : n->tag;
|
||||
if (cp[0] == '\\' && (cp[1] == '&' || cp[1] == 'e'))
|
||||
cp += 2;
|
||||
len = strcspn(cp, " \t\\");
|
||||
fprintf(tag_files.tfs, "%.*s %s %zu\n",
|
||||
len, cp, tag_files.ofn, line);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close both output files and restore the original standard output
|
||||
* to the terminal. In the unlikely case that the latter fails,
|
||||
* trying to start a pager would be useless, so report the failure
|
||||
* to the main program.
|
||||
*/
|
||||
int
|
||||
term_tag_close(void)
|
||||
{
|
||||
int irc = 0;
|
||||
|
||||
if (tag_files.tfs != NULL) {
|
||||
fclose(tag_files.tfs);
|
||||
tag_files.tfs = NULL;
|
||||
}
|
||||
if (tag_files.ofd != -1) {
|
||||
fflush(stdout);
|
||||
if ((irc = dup2(tag_files.ofd, STDOUT_FILENO)) == -1)
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
close(tag_files.ofd);
|
||||
tag_files.ofd = -1;
|
||||
}
|
||||
return irc;
|
||||
}
|
||||
|
||||
void
|
||||
term_tag_unlink(void)
|
||||
{
|
||||
pid_t tc_pgid;
|
||||
|
||||
if (tag_files.tcpgid != -1) {
|
||||
tc_pgid = tcgetpgrp(STDOUT_FILENO);
|
||||
if (tc_pgid == tag_files.pager_pid ||
|
||||
tc_pgid == getpgid(0) ||
|
||||
getpgid(tc_pgid) == -1)
|
||||
(void)tcsetpgrp(STDOUT_FILENO, tag_files.tcpgid);
|
||||
}
|
||||
if (strncmp(tag_files.ofn, "/tmp/man.", 9) == 0) {
|
||||
unlink(tag_files.ofn);
|
||||
*tag_files.ofn = '\0';
|
||||
}
|
||||
if (strncmp(tag_files.tfn, "/tmp/man.", 9) == 0) {
|
||||
unlink(tag_files.tfn);
|
||||
*tag_files.tfn = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tag_signal(int signum)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
term_tag_unlink();
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction(signum, &sa, NULL);
|
||||
kill(getpid(), signum);
|
||||
/* NOTREACHED */
|
||||
_exit(1);
|
||||
}
|
34
term_tag.h
Normal file
34
term_tag.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* $Id: term_tag.h,v 1.4 2021/03/30 17:16:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Internal interfaces to write a ctags(1) file.
|
||||
* For use by the mandoc(1) ASCII and UTF-8 formatters only.
|
||||
*/
|
||||
|
||||
struct tag_files {
|
||||
char ofn[80]; /* Output file name. */
|
||||
char tfn[80]; /* Tag file name. */
|
||||
FILE *tfs; /* Tag file object. */
|
||||
int ofd; /* Original output file descriptor. */
|
||||
pid_t tcpgid; /* Process group controlling the terminal. */
|
||||
pid_t pager_pid; /* Process ID of the pager. */
|
||||
};
|
||||
|
||||
|
||||
struct tag_files *term_tag_init(const char *, const char *, const char *);
|
||||
void term_tag_write(struct roff_node *, size_t);
|
||||
int term_tag_close(void);
|
||||
void term_tag_unlink(void);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue