mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
Merge mandoc snapshot 2024-09-22
This commit is contained in:
commit
c1c95add8c
75 files changed
+3249
-1689
No files matched your search
@@ -1,11 +1,11 @@
|
||||
$Id: LICENSE,v 1.22 2021/09/19 11:02:09 schwarze Exp $
|
||||
$Id: LICENSE,v 1.23 2022/06/25 12:44:25 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) 2010-2022 Ingo Schwarze <[email protected]>
|
||||
Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <[email protected]>
|
||||
Copyright (c) 2010-2021 Ingo Schwarze <[email protected]>
|
||||
Copyright (c) 1999, 2004, 2017 Marc Espie <[email protected]>
|
||||
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <[email protected]>
|
||||
Copyright (c) 2013 Franco Fichtner <[email protected]>
|
||||
@@ -13,6 +13,7 @@ Copyright (c) 2014 Baptiste Daroussin <[email protected]>
|
||||
Copyright (c) 2016 Ed Maste <[email protected]>
|
||||
Copyright (c) 2017 Michael Stapelberg <[email protected]>
|
||||
Copyright (c) 2017 Anthony Bentley <[email protected]>
|
||||
Copyright (c) 2022 Anna Vyalkova <[email protected]>
|
||||
Copyright (c) 1998, 2004, 2010, 2015 Todd C. Miller <[email protected]>
|
||||
Copyright (c) 2008, 2017 Otto Moerbeek <[email protected]>
|
||||
Copyright (c) 2004 Ted Unangst <[email protected]>
|
||||
|
||||
+11
-2
@@ -1,6 +1,6 @@
|
||||
# $Id: Makefile,v 1.540 2021/09/21 11:04:40 schwarze Exp $
|
||||
# $Id: Makefile,v 1.543 2023/10/19 11:45:42 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2011, 2013-2021 Ingo Schwarze <[email protected]>
|
||||
# Copyright (c) 2011, 2013-2022 Ingo Schwarze <[email protected]>
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <[email protected]>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -100,6 +100,7 @@ SRCS = arch.c \
|
||||
man_validate.c \
|
||||
mandoc.c \
|
||||
mandoc_aux.c \
|
||||
mandoc_dbg.c \
|
||||
mandoc_msg.c \
|
||||
mandoc_ohash.c \
|
||||
mandoc_xr.c \
|
||||
@@ -121,6 +122,7 @@ SRCS = arch.c \
|
||||
preconv.c \
|
||||
read.c \
|
||||
roff.c \
|
||||
roff_escape.c \
|
||||
roff_html.c \
|
||||
roff_term.c \
|
||||
roff_validate.c \
|
||||
@@ -186,6 +188,8 @@ DISTFILES = INSTALL \
|
||||
mandoc.h \
|
||||
mandoc_aux.h \
|
||||
mandoc_char.7 \
|
||||
mandoc_dbg.h \
|
||||
mandoc_dbg_init.3 \
|
||||
mandoc_escape.3 \
|
||||
mandoc_headers.3 \
|
||||
mandoc_html.3 \
|
||||
@@ -232,6 +236,7 @@ LIBMDOC_OBJS = att.o \
|
||||
|
||||
LIBROFF_OBJS = eqn.o \
|
||||
roff.o \
|
||||
roff_escape.o \
|
||||
roff_validate.o \
|
||||
tbl.o \
|
||||
tbl_data.o \
|
||||
@@ -241,6 +246,7 @@ LIBROFF_OBJS = eqn.o \
|
||||
LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
||||
$(LIBMDOC_OBJS) \
|
||||
$(LIBROFF_OBJS) \
|
||||
$(DEBUG_OBJS) \
|
||||
arch.o \
|
||||
chars.o \
|
||||
mandoc.o \
|
||||
@@ -333,6 +339,7 @@ WWW_MANS = apropos.1.html \
|
||||
soelim.1.html \
|
||||
man.cgi.3.html \
|
||||
mandoc.3.html \
|
||||
mandoc_dbg_init.3.html \
|
||||
mandoc_escape.3.html \
|
||||
mandoc_headers.3.html \
|
||||
mandoc_html.3.html \
|
||||
@@ -409,6 +416,7 @@ base-install: mandoc demandoc soelim
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man7
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
mkdir -p $(DESTDIR)$(MISCDIR)
|
||||
$(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_PROGRAM) soelim $(DESTDIR)$(BINDIR)/$(BINM_SOELIM)
|
||||
cd $(DESTDIR)$(BINDIR) && $(LN) mandoc $(BINM_MAN)
|
||||
@@ -431,6 +439,7 @@ base-install: mandoc demandoc soelim
|
||||
$(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
|
||||
$(INSTALL_MAN) makewhatis.8 \
|
||||
$(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8
|
||||
$(INSTALL_DATA) mandoc.css $(DESTDIR)$(MISCDIR)
|
||||
|
||||
lib-install: libmandoc.a
|
||||
mkdir -p $(DESTDIR)$(LIBDIR)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
arch.o: arch.c config.h roff.h
|
||||
att.o: att.c config.h roff.h libmdoc.h
|
||||
catman.o: catman.c config.h compat_fts.h
|
||||
cgi.o: cgi.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h main.h manconf.h mansearch.h cgi.h
|
||||
chars.o: chars.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h libmandoc.h
|
||||
cgi.o: cgi.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h main.h manconf.h mansearch.h cgi.h
|
||||
chars.o: chars.c config.h mandoc.h mandoc_aux.h mandoc_dbg.h mandoc_ohash.h compat_ohash.h libmandoc.h
|
||||
compat_err.o: compat_err.c config.h
|
||||
compat_fts.o: compat_fts.c config.h compat_fts.h
|
||||
compat_getline.o: compat_getline.c config.h
|
||||
@@ -22,62 +22,63 @@ compat_strndup.o: compat_strndup.c config.h
|
||||
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 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.o: dba.c config.h mandoc_aux.h mandoc_dbg.h mandoc_ohash.h compat_ohash.h mansearch.h dba_write.h dba_array.h dba.h
|
||||
dba_array.o: dba_array.c config.h mandoc_aux.h mandoc_dbg.h dba_write.h dba_array.h
|
||||
dba_read.o: dba_read.c config.h mandoc_aux.h mandoc_dbg.h mansearch.h dba_array.h dba.h dbm.h
|
||||
dba_write.o: dba_write.c config.h dba_write.h
|
||||
dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h
|
||||
dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h
|
||||
demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h mandoc_parse.h
|
||||
eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.h eqn.h libmandoc.h eqn_parse.h
|
||||
demandoc.o: demandoc.c config.h mandoc.h mandoc_dbg.h roff.h man.h mdoc.h mandoc_parse.h
|
||||
eqn.o: eqn.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h roff.h eqn.h libmandoc.h eqn_parse.h
|
||||
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
|
||||
html.o: html.c config.h mandoc_aux.h mandoc_dbg.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 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 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
|
||||
main.o: main.c config.h mandoc_aux.h mandoc_dbg.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_dbg.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_dbg.h mandoc.h roff.h man.h out.h html.h main.h
|
||||
man_macro.o: man_macro.c config.h mandoc_dbg.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_dbg.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_dbg.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_dbg.h mandoc.h roff.h libmandoc.h roff_int.h
|
||||
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h mandoc_dbg.h
|
||||
mandoc_dbg.o: mandoc_dbg.c config.h compat_ohash.h mandoc_aux.h mandoc_dbg.h mandoc.h
|
||||
mandoc_msg.o: mandoc_msg.c config.h mandoc.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
|
||||
mansearch.o: mansearch.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h 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 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
|
||||
mandoc_ohash.o: mandoc_ohash.c config.h mandoc_aux.h mandoc_dbg.h mandoc_ohash.h compat_ohash.h
|
||||
mandoc_xr.o: mandoc_xr.c config.h mandoc_aux.h mandoc_dbg.h mandoc_ohash.h compat_ohash.h mandoc_xr.h
|
||||
mandocd.o: mandocd.c config.h mandoc.h mandoc_dbg.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_dbg.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_dbg.h mandoc.h manconf.h
|
||||
mansearch.o: mansearch.c config.h mandoc_aux.h mandoc_dbg.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h roff.h mdoc.h out.h html.h main.h
|
||||
mdoc_macro.o: mdoc_macro.c config.h mandoc_dbg.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_dbg.h mandoc.h roff.h mdoc.h man.h out.h main.h
|
||||
mdoc_markdown.o: mdoc_markdown.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h roff.h mdoc.h main.h
|
||||
mdoc_state.o: mdoc_state.c config.h mandoc_dbg.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 mandoc_dbg.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_dbg.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 mandoc.h tbl.h out.h
|
||||
out.o: out.c config.h mandoc_aux.h mandoc_dbg.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 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
|
||||
read.o: read.c config.h mandoc_aux.h mandoc_dbg.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_dbg.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 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 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
|
||||
tbl_layout.o: tbl_layout.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_dbg.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_dbg.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_dbg.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tbl_html.o: tbl_html.c config.h mandoc_dbg.h mandoc.h roff.h tbl.h out.h html.h
|
||||
tbl_layout.o: tbl_layout.c config.h mandoc_aux.h mandoc_dbg.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tbl_opts.o: tbl_opts.c config.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
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 config.h mandoc_aux.h out.h term.h
|
||||
tbl_term.o: tbl_term.c config.h mandoc_dbg.h mandoc.h tbl.h out.h term.h
|
||||
term.o: term.c config.h mandoc.h mandoc_aux.h mandoc_dbg.h out.h term.h main.h
|
||||
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h mandoc_dbg.h out.h term.h manconf.h main.h
|
||||
term_ps.o: term_ps.c config.h mandoc_aux.h mandoc_dbg.h out.h term.h manconf.h main.h
|
||||
term_tab.o: term_tab.c config.h mandoc_aux.h mandoc_dbg.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
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
$Id: NEWS,v 1.40 2021/09/23 18:03:00 schwarze Exp $
|
||||
$Id: NEWS,v 1.41 2021/09/25 15:42:08 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mandoc.bsd.lv distribution.
|
||||
|
||||
@@ -195,7 +195,7 @@ Changes in version 1.14.6, released on September 23, 2021
|
||||
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)
|
||||
* Sevan Janiyan (Viewpoint Linux) and Robert Mustacchi (Illumos)
|
||||
for extensive release testing
|
||||
* Job Snijders, Kinichiro INOGUCHI, and Martijn van Duren (OpenBSD)
|
||||
for checking patches
|
||||
|
||||
+93
-12
@@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.319 2021/09/21 17:58:13 schwarze Exp $
|
||||
* $Id: TODO,v 1.335 2024/09/21 12:08:54 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@@ -68,6 +68,14 @@ are mere guesses, and some may be wrong.
|
||||
but watch out for regressions in the high-level parsers
|
||||
maybe it should not even remove comments? - consider T{\"
|
||||
|
||||
- In the body of conditional requests, escape sequence expansion
|
||||
must not be performed if the condition is false. This implies
|
||||
the first part of a request line must be expanded before
|
||||
request parsing (like it is now), but expansion in the second
|
||||
part must be delayed.
|
||||
to Nab 8 Aug 2023 20:05:32 +0200 Subject: if/ie d condition always true
|
||||
loc ** exist *** algo *** size ** imp *
|
||||
|
||||
|
||||
************************************************************************
|
||||
* missing features
|
||||
@@ -149,6 +157,11 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- missing mdoc features ----------------------------------------------
|
||||
|
||||
- support mixed case for section names
|
||||
also, first section is not "NAME" should not appear more than once per page
|
||||
Alejandro Colomar 28 Apr 2023 16:57:49 +0200
|
||||
loc * exist * algo * size * imp ***
|
||||
|
||||
- .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 *
|
||||
@@ -292,7 +305,11 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- missing misc features ----------------------------------------------
|
||||
|
||||
- conisder whether man(1) fallback code in main.c/fs_*() can find files
|
||||
- use the default volume headers for sections with suffixes
|
||||
certainly affects man(7); possibly mdoc(7)?; and also groff(1)
|
||||
Alejandro Colomar 21 Aug 2022
|
||||
|
||||
- consider 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 **
|
||||
@@ -302,6 +319,11 @@ are mere guesses, and some may be wrong.
|
||||
mail to sternenseemann 19 Aug 2021 19:11:50 +0200
|
||||
loc * exist ** algo ** size * imp **
|
||||
|
||||
- handle Unicode letters in tags in both HTML and terminal output
|
||||
thread "section headers with diacritics" starting with
|
||||
Mario Blaettermann 24 Mar 2022 18:13:23 +0100
|
||||
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
|
||||
@@ -325,6 +347,10 @@ are mere guesses, and some may be wrong.
|
||||
(3) undefined, just output the character -> perhaps WARNING
|
||||
loc *** exist ** algo ** size ** imp *** (parser reorg helps)
|
||||
|
||||
- man.conf(5) alias aliasname dirname or just -Mb -Mx -Mp
|
||||
mail to jmc@ Mar 23, 2015 03:53:14PM +0100
|
||||
loc * exist * algo * size * imp **
|
||||
|
||||
- kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET)
|
||||
loc ** exist ** algo ** size *** imp *
|
||||
|
||||
@@ -443,6 +469,10 @@ are mere guesses, and some may be wrong.
|
||||
reminded by jmc@ Thu, 23 Sep 2010 18:13:39 +0059
|
||||
loc * exist ** algo *** size * imp ***
|
||||
|
||||
- the man(7) single-font macros (e.g. .B) use .itc,
|
||||
so ".B foo\c" followed by "bar" prints "bar" in bold
|
||||
gbranden@ Sun, 5 Jun 2022 18:08:46 -0500
|
||||
|
||||
- a line starting with "\fB something" counts as starting with whitespace
|
||||
and triggers a line break; found in audio/normalize-mp3(1)
|
||||
This will become easier once escape sequences are represented
|
||||
@@ -468,20 +498,46 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- HTML issues --------------------------------------------------------
|
||||
|
||||
- make the HTML scaffolding customozable with -O skip=...
|
||||
- support the idiom .TP .IP .TP for multi-paragraph list item bodies
|
||||
to: Alejandro Colomar Thu, 19 Oct 2023 16:45:21 +0200
|
||||
loc ** exist ** algo ** size ** imp **
|
||||
|
||||
- .Nm without an argument and .Bx cause premature </pre>
|
||||
Nab Sun, 5 Jun 2022 18:30:09 +0200
|
||||
|
||||
- .Aq Mt could set and reset "white-space: nowrap";
|
||||
Check whether other enclosure macros could profit from similar handling,
|
||||
or whether that is covered by Unicode line-breaking classes WJ, ZW, GL, ZWJ.
|
||||
John Gardner 25 Mar 2022 04:44:27 +1100
|
||||
|
||||
- make the HTML scaffolding customizable 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
|
||||
would also be useful for
|
||||
https://github.com/gbdev/rgbds-www/blob/master/
|
||||
maintainer/support/man_postproc.awk
|
||||
|
||||
- .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/>
|
||||
- HTML formatting of .nf should avoid <br/>,
|
||||
even when input lines start with whitespace,
|
||||
and not close and re-open <pre> on .P
|
||||
my mail to ports@ 27 Jun 2021 16:09:20 +0200
|
||||
reported again by Mohamed Akram 25 Jun 2022 16:28:18 +0000
|
||||
loc ** exist ** algo * size * imp **
|
||||
|
||||
- tbl(7) HTML output does not implement column width specifications
|
||||
reported by Ted Bullock 11 Jan 2022 16:00:44 -0700
|
||||
loc * exist * algo ? size ? imp *
|
||||
|
||||
- link from flags in the SYNOPSIS to their descriptions
|
||||
https://github.com/gbdev/rgbds-www/blob/master/
|
||||
maintainer/support/man_postproc.awk
|
||||
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
|
||||
@@ -504,19 +560,18 @@ are mere guesses, and some may be wrong.
|
||||
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...
|
||||
Observed by an Anonymous Coward on undeadly.org:
|
||||
http://undeadly.org/cgi?action=article&sid=20140925064244&pid=1
|
||||
loc * exist * algo ** size * imp ***
|
||||
|
||||
- generate <img> tags in HTML
|
||||
idea from florian@ Tue, 7 Apr 2015 00:26:28 +0000
|
||||
may be possible to implement with .Lk img://something.png alt_text
|
||||
|
||||
- check https://github.com/trentm/mdocml
|
||||
|
||||
--- CSS issues ---------------------------------------------------------
|
||||
|
||||
- use flexbox for .Bl-tag instead of the fragile float/clear mechanism
|
||||
John Gardner 25 Mar 2022 04:44:27 +1100
|
||||
|
||||
|
||||
************************************************************************
|
||||
* formatting issues: gratuitous differences
|
||||
************************************************************************
|
||||
@@ -527,7 +582,17 @@ are mere guesses, and some may be wrong.
|
||||
Steffen Nurpmeso Sat, 08 Nov 2014 13:34:59 +0100
|
||||
loc * exist ** algo ** size * imp **
|
||||
|
||||
- In .Bl -enum -width 0n, groff continues one the same line after
|
||||
- Multiple issues with .In below SYNOPSIS; groff behaviour is:
|
||||
text line + .In -> no line break before #include
|
||||
called .In -> no line break before angle bracket
|
||||
.In + .In -> second one gets #include, too
|
||||
two arguments -> line break before second
|
||||
child macro -> line break before child
|
||||
.In + text line -> line break before the text line
|
||||
Evan Silberman Fri, 20 Sep 2024 16:48:19 -0700
|
||||
loc ** exist ** algo * size * imp *
|
||||
|
||||
- In .Bl -enum -width 0n, groff continues on the same line after
|
||||
the number, mandoc breaks the line.
|
||||
mail to kristaps@ Mon, 20 Jul 2009 02:21:39 +0200
|
||||
loc * exist ** algo ** size * imp **
|
||||
@@ -562,6 +627,10 @@ are mere guesses, and some may be wrong.
|
||||
reported again by Nicolas Joly Thu, 1 Mar 2012 13:41:26 +0100 via wiz@ 5 Mar
|
||||
reported again by Franco Fichtner Fri, 27 Sep 2013 21:02:28 +0200
|
||||
reported again by Bruce Evans Fri, 17 Feb 2017 21:22:44 +0100 via bapt@
|
||||
https://reviews.freebsd.org/D35245
|
||||
even groff_mdoc(7) uses this: Nab Sun, 5 Jun 2022 22:16:37 +0200
|
||||
When implementing this, try to avoid breaking existing manuals,
|
||||
or at least fix them: Jan Stary Sun, 5 Jun 2022 22:48:05 +0200
|
||||
loc *** exist *** algo *** size ** imp ***
|
||||
An easy partial fix has been implemented as skip_leading_dot_word().
|
||||
|
||||
@@ -574,6 +643,10 @@ are mere guesses, and some may be wrong.
|
||||
with .ps and .nf/.fi produce execessive blank lines, see libJudy
|
||||
and graphics/dcmtk. The parser reorg may help with this.
|
||||
|
||||
- The man(7) .UR macro produces UTF-8 angle brackets in -Tutf8 output mode
|
||||
with groff, but ASCII <> with mandoc
|
||||
Alejandro Colomar Mon, 7 Aug 2023 17:13:29 +0200 Subject: hostname
|
||||
|
||||
- trailing whitespace must be ignored even when followed by a font escape,
|
||||
see for example
|
||||
makes
|
||||
@@ -590,6 +663,14 @@ are mere guesses, and some may be wrong.
|
||||
To: deraadt@ 25 Oct 2020 23:37:01 +0100
|
||||
loc ** exist * algo * size ** imp ***
|
||||
|
||||
- warn about \\ and \. in interpretation mode
|
||||
gbranden@, groff issue #62776, 10 Nov 2023 01:57:32 -0500
|
||||
|
||||
- warn about output lines exceeding 80 characters
|
||||
Alejandro Colomar Aug 22, 2022
|
||||
not trivial because -T lint does not call any formatter
|
||||
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 **
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: catman.c,v 1.22 2020/06/14 23:40:31 schwarze Exp $ */
|
||||
/* $Id: catman.c,v 1.23 2021/10/15 15:04:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -62,7 +62,7 @@ run_mandocd(int sockfd, const char *outtype, const char* defos)
|
||||
else
|
||||
execlp("mandocd", "mandocd", "-T", outtype,
|
||||
"-I", defos, sockfdstr, (char *)NULL);
|
||||
err(1, "exec");
|
||||
err(1, "exec(mandocd)");
|
||||
}
|
||||
|
||||
ssize_t
|
||||
|
||||
+76
-45
@@ -1,7 +1,8 @@
|
||||
/* $Id: cgi.c,v 1.175 2021/08/19 15:23:36 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.181 2023/04/28 19:11:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014-2019, 2021 Ingo Schwarze <schwarze@usta.de>
|
||||
* Copyright (c) 2014-2019, 2021, 2022 Ingo Schwarze <schwarze@usta.de>
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2022 Anna Vyalkova <cyber@sysrq.in>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -86,10 +87,10 @@ static void pg_search(const struct req *);
|
||||
static void pg_searchres(const struct req *,
|
||||
struct manpage *, size_t);
|
||||
static void pg_show(struct req *, const char *);
|
||||
static void resp_begin_html(int, const char *, const char *);
|
||||
static int resp_begin_html(int, const char *, const char *);
|
||||
static void resp_begin_http(int, const char *);
|
||||
static void resp_catman(const struct req *, const char *);
|
||||
static void resp_copy(const char *);
|
||||
static int resp_copy(const char *, const char *);
|
||||
static void resp_end_html(void);
|
||||
static void resp_format(const struct req *, const char *);
|
||||
static void resp_searchform(const struct req *, enum focus);
|
||||
@@ -352,22 +353,26 @@ resp_begin_http(int code, const char *msg)
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
resp_copy(const char *filename)
|
||||
static int
|
||||
resp_copy(const char *element, const char *filename)
|
||||
{
|
||||
char buf[4096];
|
||||
ssize_t sz;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(filename, O_RDONLY)) != -1) {
|
||||
fflush(stdout);
|
||||
while ((sz = read(fd, buf, sizeof(buf))) > 0)
|
||||
write(STDOUT_FILENO, buf, sz);
|
||||
close(fd);
|
||||
}
|
||||
if ((fd = open(filename, O_RDONLY)) == -1)
|
||||
return 0;
|
||||
|
||||
if (element != NULL)
|
||||
printf("<%s>\n", element);
|
||||
fflush(stdout);
|
||||
while ((sz = read(fd, buf, sizeof(buf))) > 0)
|
||||
write(STDOUT_FILENO, buf, sz);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
resp_begin_html(int code, const char *msg, const char *file)
|
||||
{
|
||||
const char *name, *sec, *cp;
|
||||
@@ -413,14 +418,14 @@ resp_begin_html(int code, const char *msg, const char *file)
|
||||
"<body>\n",
|
||||
CUSTOMIZE_TITLE);
|
||||
|
||||
resp_copy(MAN_DIR "/header.html");
|
||||
return resp_copy("header", MAN_DIR "/header.html");
|
||||
}
|
||||
|
||||
static void
|
||||
resp_end_html(void)
|
||||
{
|
||||
|
||||
resp_copy(MAN_DIR "/footer.html");
|
||||
if (resp_copy("footer", MAN_DIR "/footer.html"))
|
||||
puts("</footer>");
|
||||
|
||||
puts("</body>\n"
|
||||
"</html>");
|
||||
@@ -431,7 +436,7 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("<form action=\"/%s\" method=\"get\" "
|
||||
printf("<form role=\"search\" action=\"/%s\" method=\"get\" "
|
||||
"autocomplete=\"off\" autocapitalize=\"none\">\n"
|
||||
" <fieldset>\n"
|
||||
" <legend>Manual Page Search Parameters</legend>\n",
|
||||
@@ -439,13 +444,14 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
|
||||
/* Write query input box. */
|
||||
|
||||
printf(" <input type=\"search\" name=\"query\" value=\"");
|
||||
printf(" <label>Search query:\n"
|
||||
" <input type=\"search\" name=\"query\" value=\"");
|
||||
if (req->q.query != NULL)
|
||||
html_print(req->q.query);
|
||||
printf( "\" size=\"40\"");
|
||||
printf("\" size=\"40\"");
|
||||
if (focus == FOCUS_QUERY)
|
||||
printf(" autofocus");
|
||||
puts(">");
|
||||
puts(">\n </label>");
|
||||
|
||||
/* Write submission buttons. */
|
||||
|
||||
@@ -457,7 +463,7 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
|
||||
/* Write section selector. */
|
||||
|
||||
puts(" <select name=\"sec\">");
|
||||
puts(" <select name=\"sec\" aria-label=\"Manual section\">");
|
||||
for (i = 0; i < sec_MAX; i++) {
|
||||
printf(" <option value=\"%s\"", sec_numbers[i]);
|
||||
if (NULL != req->q.sec &&
|
||||
@@ -469,7 +475,7 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
|
||||
/* Write architecture selector. */
|
||||
|
||||
printf( " <select name=\"arch\">\n"
|
||||
printf( " <select name=\"arch\" aria-label=\"CPU architecture\">\n"
|
||||
" <option value=\"default\"");
|
||||
if (NULL == req->q.arch)
|
||||
printf(" selected=\"selected\"");
|
||||
@@ -486,7 +492,8 @@ resp_searchform(const struct req *req, enum focus focus)
|
||||
/* Write manpath selector. */
|
||||
|
||||
if (req->psz > 1) {
|
||||
puts(" <select name=\"manpath\">");
|
||||
puts(" <select name=\"manpath\""
|
||||
" aria-label=\"Manual path\">");
|
||||
for (i = 0; i < (int)req->psz; i++) {
|
||||
printf(" <option");
|
||||
if (strcmp(req->q.manpath, req->p[i]) == 0)
|
||||
@@ -554,16 +561,21 @@ validate_filename(const char *file)
|
||||
static void
|
||||
pg_index(const struct req *req)
|
||||
{
|
||||
|
||||
resp_begin_html(200, NULL, NULL);
|
||||
if (resp_begin_html(200, NULL, NULL) == 0)
|
||||
puts("<header>");
|
||||
resp_searchform(req, FOCUS_QUERY);
|
||||
printf("<p>\n"
|
||||
printf("</header>\n"
|
||||
"<main>\n"
|
||||
"<p role=\"doc-notice\" aria-label=\"Usage\">\n"
|
||||
"This web interface is documented in the\n"
|
||||
"<a class=\"Xr\" href=\"/%s%sman.cgi.8\">man.cgi(8)</a>\n"
|
||||
"<a class=\"Xr\" href=\"/%s%sman.cgi.8\""
|
||||
" aria-label=\"man dot CGI, section 8\">man.cgi(8)</a>\n"
|
||||
"manual, and the\n"
|
||||
"<a class=\"Xr\" href=\"/%s%sapropos.1\">apropos(1)</a>\n"
|
||||
"<a class=\"Xr\" href=\"/%s%sapropos.1\""
|
||||
" aria-label=\"apropos, section 1\">apropos(1)</a>\n"
|
||||
"manual explains the query syntax.\n"
|
||||
"</p>\n",
|
||||
"</p>\n"
|
||||
"</main>\n",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
scriptname, *scriptname == '\0' ? "" : "/");
|
||||
resp_end_html();
|
||||
@@ -573,33 +585,40 @@ static void
|
||||
pg_noresult(const struct req *req, int code, const char *http_msg,
|
||||
const char *user_msg)
|
||||
{
|
||||
resp_begin_html(code, http_msg, NULL);
|
||||
if (resp_begin_html(code, http_msg, NULL) == 0)
|
||||
puts("<header>");
|
||||
resp_searchform(req, FOCUS_QUERY);
|
||||
puts("<p>");
|
||||
puts("</header>");
|
||||
puts("<main>");
|
||||
puts("<p role=\"doc-notice\" aria-label=\"No result\">");
|
||||
puts(user_msg);
|
||||
puts("</p>");
|
||||
puts("</main>");
|
||||
resp_end_html();
|
||||
}
|
||||
|
||||
static void
|
||||
pg_error_badrequest(const char *msg)
|
||||
{
|
||||
|
||||
resp_begin_html(400, "Bad Request", NULL);
|
||||
puts("<h1>Bad Request</h1>\n"
|
||||
"<p>\n");
|
||||
if (resp_begin_html(400, "Bad Request", NULL))
|
||||
puts("</header>");
|
||||
puts("<main>\n"
|
||||
"<h1>Bad Request</h1>\n"
|
||||
"<p role=\"doc-notice\" aria-label=\"Bad Request\">");
|
||||
puts(msg);
|
||||
printf("Try again from the\n"
|
||||
"<a href=\"/%s\">main page</a>.\n"
|
||||
"</p>", scriptname);
|
||||
"</p>\n"
|
||||
"</main>\n", scriptname);
|
||||
resp_end_html();
|
||||
}
|
||||
|
||||
static void
|
||||
pg_error_internal(void)
|
||||
{
|
||||
resp_begin_html(500, "Internal Server Error", NULL);
|
||||
puts("<p>Internal Server Error</p>");
|
||||
if (resp_begin_html(500, "Internal Server Error", NULL))
|
||||
puts("</header>");
|
||||
puts("<main><p role=\"doc-notice\">Internal Server Error</p></main>");
|
||||
resp_end_html();
|
||||
}
|
||||
|
||||
@@ -630,6 +649,7 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
size_t i, iuse;
|
||||
int archprio, archpriouse;
|
||||
int prio, priouse;
|
||||
int have_header;
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
if (validate_filename(r[i].file))
|
||||
@@ -696,14 +716,18 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
priouse = prio;
|
||||
iuse = i;
|
||||
}
|
||||
resp_begin_html(200, NULL, r[iuse].file);
|
||||
have_header = resp_begin_html(200, NULL, r[iuse].file);
|
||||
} else
|
||||
resp_begin_html(200, NULL, NULL);
|
||||
have_header = resp_begin_html(200, NULL, NULL);
|
||||
|
||||
if (have_header == 0)
|
||||
puts("<header>");
|
||||
resp_searchform(req,
|
||||
req->q.equal || sz == 1 ? FOCUS_NONE : FOCUS_QUERY);
|
||||
puts("</header>");
|
||||
|
||||
if (sz > 1) {
|
||||
puts("<nav>");
|
||||
puts("<table class=\"results\">");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf(" <tr>\n"
|
||||
@@ -722,6 +746,7 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
" </tr>");
|
||||
}
|
||||
puts("</table>");
|
||||
puts("</nav>");
|
||||
}
|
||||
|
||||
if (req->q.equal || sz == 1) {
|
||||
@@ -743,7 +768,9 @@ resp_catman(const struct req *req, const char *file)
|
||||
int italic, bold;
|
||||
|
||||
if ((f = fopen(file, "r")) == NULL) {
|
||||
puts("<p>You specified an invalid manual file.</p>");
|
||||
puts("<p role=\"doc-notice\">\n"
|
||||
" You specified an invalid manual file.\n"
|
||||
"</p>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -879,8 +906,10 @@ resp_format(const struct req *req, const char *file)
|
||||
int fd;
|
||||
int usepath;
|
||||
|
||||
if (-1 == (fd = open(file, O_RDONLY, 0))) {
|
||||
puts("<p>You specified an invalid manual file.</p>");
|
||||
if (-1 == (fd = open(file, O_RDONLY))) {
|
||||
puts("<p role=\"doc-notice\">\n"
|
||||
" You specified an invalid manual file.\n"
|
||||
"</p>");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -966,8 +995,10 @@ pg_show(struct req *req, const char *fullpath)
|
||||
return;
|
||||
}
|
||||
|
||||
resp_begin_html(200, NULL, file);
|
||||
if (resp_begin_html(200, NULL, file) == 0)
|
||||
puts("<header>");
|
||||
resp_searchform(req, FOCUS_NONE);
|
||||
puts("</header>");
|
||||
resp_show(req, file);
|
||||
resp_end_html();
|
||||
}
|
||||
@@ -1066,7 +1097,7 @@ main(void)
|
||||
#if HAVE_PLEDGE
|
||||
/*
|
||||
* The "rpath" pledge could be revoked after mparse_readfd()
|
||||
* if the file desciptor to "/footer.html" would be opened
|
||||
* if the file descriptor to "/footer.html" would be opened
|
||||
* up front, but it's probably not worth the complication
|
||||
* of the code it would cause: it would require scattering
|
||||
* pledge() calls in multiple low-level resp_*() functions.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: chars.c,v 1.79 2020/02/13 16:18:29 schwarze Exp $ */
|
||||
/* $Id: chars.c,v 1.81 2022/06/26 20:33:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2020
|
||||
@@ -92,7 +92,6 @@ static struct ln lines[] = {
|
||||
{ "en", "-", 0x2013 },
|
||||
{ "hy", "-", 0x2010 },
|
||||
{ "e", "\\", 0x005c },
|
||||
{ ".", ".", 0x002e },
|
||||
{ "r!", "!", 0x00a1 },
|
||||
{ "r?", "?", 0x00bf },
|
||||
|
||||
@@ -365,7 +364,7 @@ static struct ln lines[] = {
|
||||
{ "de", "<degree>", 0x00b0 },
|
||||
{ "%0", "<permille>", 0x2030 },
|
||||
{ "fm", "\'", 0x2032 },
|
||||
{ "sd", "''", 0x2033 },
|
||||
{ "sd", "\"", 0x2033 },
|
||||
{ "mc", "<micro>", 0x00b5 },
|
||||
{ "Of", "_\ba", 0x00aa },
|
||||
{ "Om", "_\bo", 0x00ba },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: compat_strsep.c,v 1.5 2020/06/15 01:37:15 schwarze Exp $ */
|
||||
/* $Id: compat_strsep.c,v 1.6 2022/06/21 10:34:14 schwarze Exp $ */
|
||||
/* $OpenBSD: strsep.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
|
||||
|
||||
/*-
|
||||
@@ -31,6 +31,8 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are possibly-empty
|
||||
* strings separated by characters from delim.
|
||||
|
||||
Vendored
+12
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.81 2021/09/20 10:19:51 schwarze Exp $
|
||||
# $Id: configure,v 1.83 2023/10/19 11:45:42 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014-2021 Ingo Schwarze <[email protected]>
|
||||
#
|
||||
@@ -37,6 +37,7 @@ SOURCEDIR=`dirname "${0}"`
|
||||
|
||||
MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
|
||||
MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
DEBUG_MEMORY=0
|
||||
OSENUM=
|
||||
OSNAME=
|
||||
UTF8_LOCALE=
|
||||
@@ -99,6 +100,7 @@ NEED_GNU_SOURCE=0
|
||||
NEED_OPENBSD_SOURCE=0
|
||||
NEED_XPG4_2=0
|
||||
|
||||
DEBUG_OBJS=
|
||||
MANDOC_COBJS=
|
||||
SOELIM_COBJS=
|
||||
|
||||
@@ -109,6 +111,7 @@ BIN_FROM_SBIN=
|
||||
INCLUDEDIR=
|
||||
LIBDIR=
|
||||
MANDIR=
|
||||
MISCDIR=
|
||||
READ_ALLOWED_PATH=
|
||||
|
||||
WWWPREFIX="/var/www"
|
||||
@@ -334,6 +337,7 @@ runtest vasprintf VASPRINTF "" -D_GNU_SOURCE || true
|
||||
|
||||
# --- fts ---
|
||||
if [ "${1}" = "-depend" ]; then
|
||||
DEBUG_MEMORY=1
|
||||
HAVE_FTS=0
|
||||
HAVE_FTS_COMPARE_CONST=0
|
||||
echo "tested fts: HAVE_FTS=0 (for make depend)" 1>&2
|
||||
@@ -461,6 +465,10 @@ echo
|
||||
echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\""
|
||||
echo "#define MANPATH_BASE \"${MANPATH_BASE}\""
|
||||
echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
|
||||
if [ ${DEBUG_MEMORY} -ne 0 ]; then
|
||||
echo "#define DEBUG_MEMORY ${DEBUG_MEMORY}"
|
||||
DEBUG_OBJS=mandoc_dbg.o
|
||||
fi
|
||||
echo "#define OSENUM ${OSENUM}"
|
||||
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
|
||||
[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\""
|
||||
@@ -613,6 +621,7 @@ exec > Makefile.local
|
||||
[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||
[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib/mandoc"
|
||||
[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"
|
||||
[ -z "${MISCDIR}" ] && MISCDIR="${PREFIX}/share/misc"
|
||||
|
||||
[ -z "${HTDOCDIR}" ] && HTDOCDIR="${WWWPREFIX}/htdocs"
|
||||
[ -z "${CGIBINDIR}" ] && CGIBINDIR="${WWWPREFIX}/cgi-bin"
|
||||
@@ -640,6 +649,7 @@ CC = ${CC}
|
||||
CFLAGS = ${CFLAGS}
|
||||
LDADD = ${LDADD}
|
||||
LDFLAGS = ${LDFLAGS}
|
||||
DEBUG_OBJS = ${DEBUG_OBJS}
|
||||
MANDOC_COBJS = ${MANDOC_COBJS}
|
||||
SOELIM_COBJS = ${SOELIM_COBJS}
|
||||
STATIC = ${STATIC}
|
||||
@@ -650,6 +660,7 @@ BIN_FROM_SBIN = ${BIN_FROM_SBIN}
|
||||
INCLUDEDIR = ${INCLUDEDIR}
|
||||
LIBDIR = ${LIBDIR}
|
||||
MANDIR = ${MANDIR}
|
||||
MISCDIR = ${MISCDIR}
|
||||
WWWPREFIX = ${WWWPREFIX}
|
||||
HTDOCDIR = ${HTDOCDIR}
|
||||
CGIBINDIR = ${CGIBINDIR}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# $Id: configure.local.example,v 1.43 2021/09/20 13:25:42 schwarze Exp $
|
||||
# $Id: configure.local.example,v 1.45 2023/10/19 11:45:42 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014-2021 Ingo Schwarze <[email protected]>
|
||||
# Copyright (c) 2014-2022 Ingo Schwarze <[email protected]>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -108,11 +108,15 @@ OSNAME="OpenBSD 7.0"
|
||||
# there is no need to copy the whole block.
|
||||
# Even if you set PREFIX to something else, the other variables
|
||||
# pick it up without copying them all over.
|
||||
# MISCDIR is only used for installing the file mandoc.css.
|
||||
# That is important because users of "mandoc -T html" often need it
|
||||
# even if they are not using man.cgi(8), see mandoc(1) for details.
|
||||
|
||||
PREFIX="/usr/local"
|
||||
BINDIR="${PREFIX}/bin"
|
||||
SBINDIR="${PREFIX}/sbin"
|
||||
MANDIR="${PREFIX}/man"
|
||||
MISCDIR="${PREFIX}/share/misc"
|
||||
|
||||
# If BINDIR and SBINDIR are not subdirectories of the same parent
|
||||
# directory or if the basename(1) of BINDIR differs from "bin",
|
||||
@@ -312,6 +316,12 @@ BINM_CATMAN=mcatman # default is "catman"
|
||||
|
||||
CFLAGS="-g"
|
||||
|
||||
# Hunt for memory leaks.
|
||||
# Do not use for production builds.
|
||||
# See mandoc_dbg_init(3) for more information.
|
||||
|
||||
DEBUG_MEMORY=1
|
||||
|
||||
# In rare cases, it may be required to skip individual automatic tests.
|
||||
# Each of the following variables can be set to 0 (test will not be run
|
||||
# and will be regarded as failed) or 1 (test will not be run and will
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: dba_read.c,v 1.5 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/* $Id: dba_read.c,v 1.6 2023/04/28 19:11:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
* Function to read the mandoc database from disk into RAM,
|
||||
* such that data can be added or removed.
|
||||
* The interface is defined in "dba.h".
|
||||
* This file is seperate from dba.c because this also uses "dbm.h".
|
||||
* This file is separate from dba.c because this also uses "dbm.h".
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: demandoc.1,v 1.8 2014/09/12 00:10:26 schwarze Exp $
|
||||
.\" $Id: demandoc.1,v 1.9 2022/03/20 15:41:47 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <[email protected]>
|
||||
.\"
|
||||
@@ -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: September 12 2014 $
|
||||
.Dd $Mdocdate: March 20 2022 $
|
||||
.Dt DEMANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -80,7 +80,6 @@ error accessing input files.
|
||||
Such errors cause
|
||||
.Nm
|
||||
to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
The output databases are corrupt and should be removed .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The traditional usage of
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: demandoc.c,v 1.33 2019/03/03 11:01:15 schwarze Exp $ */
|
||||
/* $Id: demandoc.c,v 1.34 2022/04/14 16:43:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@@ -26,6 +26,10 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#if DEBUG_MEMORY
|
||||
#define DEBUG_NODEF
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "mdoc.h"
|
||||
@@ -47,6 +51,10 @@ main(int argc, char *argv[])
|
||||
int ch, fd, i, list;
|
||||
extern int optind;
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_init(argc, argv);
|
||||
#endif
|
||||
|
||||
if (argc < 1)
|
||||
progname = "demandoc";
|
||||
else if ((progname = strrchr(argv[0], '/')) == NULL)
|
||||
@@ -97,6 +105,9 @@ main(int argc, char *argv[])
|
||||
|
||||
mparse_free(mp);
|
||||
mchars_free();
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_finish();
|
||||
#endif
|
||||
return (int)MANDOCLEVEL_OK;
|
||||
}
|
||||
|
||||
|
||||
+16
-12
@@ -1,7 +1,8 @@
|
||||
/* $Id: eqn.c,v 1.84 2020/01/08 12:16:24 schwarze Exp $ */
|
||||
/* $Id: eqn.c,v 1.86 2023/04/28 19:11:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 2017, 2018, 2020, 2022
|
||||
* Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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
|
||||
@@ -355,7 +356,7 @@ eqn_def_find(struct eqn_node *ep)
|
||||
/*
|
||||
* Parse a token from the input text. The modes are:
|
||||
* MODE_QUOTED: Use *ep->start as the delimiter; the token ends
|
||||
* before its next occurence. Do not interpret the token in any
|
||||
* before its next occurrence. Do not interpret the token in any
|
||||
* way and return EQN_TOK_QUOTED. All other modes behave like
|
||||
* MODE_QUOTED when *ep->start is '"'.
|
||||
* MODE_NOSUB: If *ep->start is a curly brace, the token ends after it;
|
||||
@@ -375,19 +376,17 @@ eqn_def_find(struct eqn_node *ep)
|
||||
static enum eqn_tok
|
||||
eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
||||
{
|
||||
static int last_len, lim;
|
||||
|
||||
struct eqn_def *def;
|
||||
size_t start;
|
||||
int diff, i, quoted;
|
||||
int diff, i, newlen, quoted;
|
||||
enum eqn_tok tok;
|
||||
|
||||
/*
|
||||
* Reset the recursion counter after advancing
|
||||
* beyond the end of the previous substitution.
|
||||
* beyond the end of the rightmost substitution.
|
||||
*/
|
||||
if (ep->end - ep->data >= last_len)
|
||||
lim = 0;
|
||||
if (ep->end - ep->data >= ep->sublen)
|
||||
ep->subcnt = 0;
|
||||
|
||||
ep->start = ep->end;
|
||||
quoted = mode == MODE_QUOTED;
|
||||
@@ -434,10 +433,10 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
||||
return EQN_TOK__MAX;
|
||||
if ((def = eqn_def_find(ep)) == NULL)
|
||||
break;
|
||||
if (++lim > EQN_NEST_MAX) {
|
||||
if (++ep->subcnt > EQN_NEST_MAX) {
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP,
|
||||
ep->node->line, ep->node->pos, NULL);
|
||||
return EQN_TOK_EOF;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Replace a defined name with its string value. */
|
||||
@@ -446,12 +445,15 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
||||
ep->sz += diff;
|
||||
ep->data = mandoc_realloc(ep->data, ep->sz + 1);
|
||||
ep->start = ep->data + start;
|
||||
ep->sublen += diff;
|
||||
}
|
||||
if (diff)
|
||||
memmove(ep->start + def->valsz, ep->start + ep->toksz,
|
||||
strlen(ep->start + ep->toksz) + 1);
|
||||
memcpy(ep->start, def->val, def->valsz);
|
||||
last_len = ep->start - ep->data + def->valsz;
|
||||
newlen = ep->start - ep->data + def->valsz;
|
||||
if (ep->sublen < newlen)
|
||||
ep->sublen = newlen;
|
||||
}
|
||||
if (mode != MODE_TOK)
|
||||
return quoted ? EQN_TOK_QUOTED : EQN_TOK__MAX;
|
||||
@@ -678,6 +680,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
return;
|
||||
|
||||
ep->start = ep->end = ep->data;
|
||||
ep->sublen = 0;
|
||||
ep->subcnt = 0;
|
||||
|
||||
next_tok:
|
||||
tok = eqn_next(ep, MODE_TOK);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: eqn_parse.h,v 1.3 2018/12/14 06:33:14 schwarze Exp $ */
|
||||
/* $Id: eqn_parse.h,v 1.4 2022/04/13 20:26:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2017, 2018, 2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 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
|
||||
@@ -32,6 +32,8 @@ struct eqn_node {
|
||||
size_t defsz; /* Number of definitions. */
|
||||
size_t sz; /* Length of the source code. */
|
||||
size_t toksz; /* Length of the current token. */
|
||||
int sublen; /* End of rightmost substitution, so far. */
|
||||
int subcnt; /* Number of recursive substitutions. */
|
||||
int gsize; /* Default point size. */
|
||||
int delim; /* In-line delimiters enabled. */
|
||||
char odelim; /* In-line opening delimiter. */
|
||||
|
||||
+13
-4
@@ -1,7 +1,8 @@
|
||||
/* $Id: html.c,v 1.275 2021/09/09 14:47:24 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.279 2022/08/09 11:23:11 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2022 Anna Vyalkova <cyber@sysrq.in>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -67,8 +68,10 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"style", HTML_NLALL | HTML_INDENT},
|
||||
{"title", HTML_NLAROUND},
|
||||
{"body", HTML_NLALL},
|
||||
{"main", HTML_NLALL},
|
||||
{"div", HTML_NLAROUND},
|
||||
{"section", HTML_NLALL},
|
||||
{"nav", HTML_NLALL},
|
||||
{"table", HTML_NLALL | HTML_INDENT},
|
||||
{"tr", HTML_NLALL | HTML_INDENT},
|
||||
{"td", HTML_NLAROUND},
|
||||
@@ -78,8 +81,8 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"dl", HTML_NLALL | HTML_INDENT},
|
||||
{"dt", HTML_NLAROUND},
|
||||
{"dd", HTML_NLAROUND | HTML_INDENT},
|
||||
{"h1", HTML_TOPHRASE | HTML_NLAROUND},
|
||||
{"h2", HTML_TOPHRASE | HTML_NLAROUND},
|
||||
{"h3", HTML_TOPHRASE | HTML_NLAROUND},
|
||||
{"p", HTML_TOPHRASE | HTML_NLAROUND | HTML_INDENT},
|
||||
{"pre", HTML_TOPHRASE | HTML_NLAROUND | HTML_NOINDENT},
|
||||
{"a", HTML_INPHRASE | HTML_TOPHRASE},
|
||||
@@ -400,10 +403,13 @@ html_make_id(const struct roff_node *n, int unique)
|
||||
* In addition, reserve '~' for ordinal suffixes.
|
||||
*/
|
||||
|
||||
for (cp = buf; *cp != '\0'; cp++)
|
||||
if (isalnum((unsigned char)*cp) == 0 &&
|
||||
for (cp = buf; *cp != '\0'; cp++) {
|
||||
if (*cp == ASCII_HYPH)
|
||||
*cp = '-';
|
||||
else if (isalnum((unsigned char)*cp) == 0 &&
|
||||
strchr("!$&'()*+,-./:;=?@_", *cp) == NULL)
|
||||
*cp = '_';
|
||||
}
|
||||
|
||||
if (unique == 0)
|
||||
return buf;
|
||||
@@ -708,6 +714,9 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
case 'i':
|
||||
attr = "id";
|
||||
break;
|
||||
case 'r':
|
||||
attr = "role";
|
||||
break;
|
||||
case '?':
|
||||
attr = arg1;
|
||||
arg1 = va_arg(ap, char *);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: html.h,v 1.109 2021/09/09 14:47:24 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.112 2022/07/06 14:34:59 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@@ -27,8 +27,10 @@ enum htmltag {
|
||||
TAG_STYLE,
|
||||
TAG_TITLE,
|
||||
TAG_BODY,
|
||||
TAG_MAIN,
|
||||
TAG_DIV,
|
||||
TAG_SECTION,
|
||||
TAG_NAV,
|
||||
TAG_TABLE,
|
||||
TAG_TR,
|
||||
TAG_TD,
|
||||
@@ -38,8 +40,8 @@ enum htmltag {
|
||||
TAG_DL,
|
||||
TAG_DT,
|
||||
TAG_DD,
|
||||
TAG_H1,
|
||||
TAG_H2,
|
||||
TAG_H3,
|
||||
TAG_P,
|
||||
TAG_PRE,
|
||||
TAG_A,
|
||||
|
||||
+27
-16
@@ -1,4 +1,4 @@
|
||||
/* $Id: main.c,v 1.358 2021/09/04 22:38:46 schwarze Exp $ */
|
||||
/* $Id: main.c,v 1.361 2022/04/14 16:43:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2012, 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@@ -149,11 +149,14 @@ main(int argc, char *argv[])
|
||||
enum mandoc_os os_e; /* Check base system conventions. */
|
||||
enum outmode outmode; /* According to command line. */
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_init(argc, argv);
|
||||
#endif
|
||||
#if HAVE_PROGNAME
|
||||
progname = getprogname();
|
||||
#else
|
||||
if (argc < 1)
|
||||
progname = mandoc_strdup("mandoc");
|
||||
progname = "mandoc";
|
||||
else if ((progname = strrchr(argv[0], '/')) == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
@@ -546,6 +549,9 @@ main(int argc, char *argv[])
|
||||
memcpy(res + ressz, resn,
|
||||
sizeof(*resn) * resnsz);
|
||||
ressz += resnsz;
|
||||
free(resn);
|
||||
resn = NULL;
|
||||
resnsz = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -584,6 +590,10 @@ main(int argc, char *argv[])
|
||||
res = mandoc_reallocarray(res, ressz + 1,
|
||||
sizeof(*res));
|
||||
memcpy(res + ressz++, resn + ib, sizeof(*resn));
|
||||
memset(resn + ib, 0, sizeof(*resn));
|
||||
mansearch_free(resn, resnsz);
|
||||
resn = NULL;
|
||||
resnsz = 0;
|
||||
}
|
||||
|
||||
/* apropos(1), whatis(1): Process the full search expression. */
|
||||
@@ -694,6 +704,9 @@ out:
|
||||
} else if (outst.had_output && outst.outtype != OUTT_LINT)
|
||||
mandoc_msg_summary();
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_finish();
|
||||
#endif
|
||||
return (int)mandoc_msg_getrc();
|
||||
}
|
||||
|
||||
@@ -1309,6 +1322,7 @@ spawn_pager(struct outstate *outst, char *tag_target)
|
||||
char *argv[MAX_PAGER_ARGS];
|
||||
const char *pager;
|
||||
char *cp;
|
||||
size_t wordlen;
|
||||
#if HAVE_LESS_T
|
||||
size_t cmdlen;
|
||||
#endif
|
||||
@@ -1323,7 +1337,6 @@ spawn_pager(struct outstate *outst, char *tag_target)
|
||||
pager = getenv("PAGER");
|
||||
if (pager == NULL || *pager == '\0')
|
||||
pager = BINM_PAGER;
|
||||
cp = mandoc_strdup(pager);
|
||||
|
||||
/*
|
||||
* Parse the pager command into words.
|
||||
@@ -1331,16 +1344,12 @@ spawn_pager(struct outstate *outst, char *tag_target)
|
||||
*/
|
||||
|
||||
argc = 0;
|
||||
while (argc + 5 < MAX_PAGER_ARGS) {
|
||||
argv[argc++] = cp;
|
||||
cp = strchr(cp, ' ');
|
||||
if (cp == NULL)
|
||||
break;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ')
|
||||
cp++;
|
||||
if (*cp == '\0')
|
||||
break;
|
||||
while (*pager != '\0' && argc + 5 < MAX_PAGER_ARGS) {
|
||||
wordlen = strcspn(pager, " ");
|
||||
argv[argc++] = mandoc_strndup(pager, wordlen);
|
||||
pager += wordlen;
|
||||
while (*pager == ' ')
|
||||
pager++;
|
||||
}
|
||||
|
||||
/* For less(1), use the tag file. */
|
||||
@@ -1352,10 +1361,10 @@ spawn_pager(struct outstate *outst, char *tag_target)
|
||||
cp = argv[0] + cmdlen - 4;
|
||||
if (strcmp(cp, "less") == 0) {
|
||||
argv[argc++] = mandoc_strdup("-T");
|
||||
argv[argc++] = outst->tag_files->tfn;
|
||||
argv[argc++] = mandoc_strdup(outst->tag_files->tfn);
|
||||
if (tag_target != NULL) {
|
||||
argv[argc++] = mandoc_strdup("-t");
|
||||
argv[argc++] = tag_target;
|
||||
argv[argc++] = mandoc_strdup(tag_target);
|
||||
use_ofn = 0;
|
||||
}
|
||||
}
|
||||
@@ -1366,7 +1375,7 @@ spawn_pager(struct outstate *outst, char *tag_target)
|
||||
mandoc_asprintf(&argv[argc], "file://%s#%s",
|
||||
outst->tag_files->ofn, tag_target);
|
||||
else
|
||||
argv[argc] = outst->tag_files->ofn;
|
||||
argv[argc] = mandoc_strdup(outst->tag_files->ofn);
|
||||
argc++;
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
@@ -1378,6 +1387,8 @@ spawn_pager(struct outstate *outst, char *tag_target)
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
while (argc > 0)
|
||||
free(argv[--argc]);
|
||||
(void)setpgid(pager_pid, 0);
|
||||
(void)tcsetpgrp(STDOUT_FILENO, pager_pid);
|
||||
#if HAVE_PLEDGE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: makewhatis.8,v 1.6 2017/05/17 22:27:12 schwarze Exp $
|
||||
.\" $Id: makewhatis.8,v 1.7 2022/03/16 23:26:14 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <[email protected]>
|
||||
.\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze <[email protected]>
|
||||
@@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 17 2017 $
|
||||
.Dd $Mdocdate: March 16 2022 $
|
||||
.Dt MAKEWHATIS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -52,9 +52,7 @@ manuals and indexes them in a database for fast retrieval by
|
||||
.Xr apropos 1 ,
|
||||
.Xr whatis 1 ,
|
||||
and
|
||||
.Xr man 1 Ns 's
|
||||
.Fl k
|
||||
option.
|
||||
.Xr man 1 .
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: man.1,v 1.40 2020/07/20 16:57:30 schwarze Exp $
|
||||
.\" $Id: man.1,v 1.41 2022/08/04 11:32:23 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
|
||||
.\"
|
||||
.Dd $Mdocdate: July 20 2020 $
|
||||
.Dd $Mdocdate: August 4 2022 $
|
||||
.Dt MAN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -391,7 +391,9 @@ option first appeared in
|
||||
and
|
||||
.Fl k
|
||||
in
|
||||
.Bx 4 ;
|
||||
.Pa /usr/usb/man
|
||||
in
|
||||
.Bx 4.0 ;
|
||||
.Fl M
|
||||
in
|
||||
.Bx 4.3 ;
|
||||
|
||||
+18
-16
@@ -1,7 +1,7 @@
|
||||
.\" $Id: man.7,v 1.148 2021/08/05 14:31:14 schwarze Exp $
|
||||
.\" $Id: man.7,v 1.150 2023/10/23 22:57:54 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <[email protected]>
|
||||
.\" Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2011-2015,2017-2020,2023 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2017 Anthony Bentley <[email protected]>
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger <[email protected]>
|
||||
.\"
|
||||
@@ -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: August 5 2021 $
|
||||
.Dd $Mdocdate: October 23 2023 $
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -97,10 +97,11 @@ but can be found in the alphabetical reference below.
|
||||
.It Ic SH Ta section header (one line)
|
||||
.It Ic SS Ta subsection header (one line)
|
||||
.It Ic PP Ta start an undecorated paragraph (no arguments)
|
||||
.It Ic RS , RE Ta reset the left margin: Op Ar width
|
||||
.It Ic IP Ta indented paragraph: Op Ar head Op Ar width
|
||||
.It Ic TP Ta tagged paragraph: Op Ar width
|
||||
.It Ic PD Ta set vertical paragraph distance: Op Ar height
|
||||
.It Ic EX , EE Ta display an example (no arguments)
|
||||
.It Ic RS , RE Ta reset the left margin: Op Ar width
|
||||
.It Ic in Ta additional indent: Op Ar width
|
||||
.El
|
||||
.Ss Physical markup
|
||||
@@ -162,7 +163,9 @@ This has no effect unless the tabulator positions were changed with the
|
||||
.Ic ta
|
||||
request.
|
||||
.It Ic EE
|
||||
This is a non-standard Version 9
|
||||
End an example block started with
|
||||
.Ic EX .
|
||||
This is a Version 9
|
||||
.At
|
||||
extension later adopted by GNU.
|
||||
In
|
||||
@@ -172,7 +175,8 @@ it does the same as the
|
||||
.Ic fi
|
||||
request (switch to fill mode).
|
||||
.It Ic EX
|
||||
This is a non-standard Version 9
|
||||
Begin a block to display an example.
|
||||
This is a Version 9
|
||||
.At
|
||||
extension later adopted by GNU.
|
||||
In
|
||||
@@ -234,10 +238,10 @@ A synonym for
|
||||
.It Ic ME
|
||||
End a mailto block started with
|
||||
.Ic MT .
|
||||
This is a non-standard GNU extension.
|
||||
This is a GNU extension.
|
||||
.It Ic MT
|
||||
Begin a mailto block.
|
||||
This is a non-standard GNU extension.
|
||||
This is a GNU extension.
|
||||
It has the following syntax:
|
||||
.Bd -unfilled -offset indent
|
||||
.Pf . Ic MT Ar address
|
||||
@@ -246,7 +250,7 @@ link description to be shown
|
||||
.Ed
|
||||
.It Ic OP
|
||||
Optional command-line argument.
|
||||
This is a non-standard DWB extension.
|
||||
This is a rarely used DWB extension.
|
||||
It has the following syntax:
|
||||
.Pp
|
||||
.D1 Pf . Ic OP Ar key Op Ar value
|
||||
@@ -373,8 +377,7 @@ Begin a synopsis block with the following syntax:
|
||||
.Pf . Ic YS
|
||||
.Ed
|
||||
.Pp
|
||||
This is a non-standard GNU extension
|
||||
and very rarely used even in GNU manual pages.
|
||||
This is a GNU extension and rarely used even in GNU manual pages.
|
||||
Formatting is similar to
|
||||
.Ic IP .
|
||||
.It Ic TH
|
||||
@@ -437,8 +440,7 @@ unspecified, the saved or default width is used.
|
||||
Like
|
||||
.Ic TP ,
|
||||
except that no vertical spacing is inserted before the paragraph.
|
||||
This is a non-standard GNU extension
|
||||
and very rarely used even in GNU manual pages.
|
||||
This is a GNU extension.
|
||||
.It Ic UC
|
||||
Sets the volume for the footer for compatibility with man pages from
|
||||
.Bx
|
||||
@@ -449,10 +451,10 @@ This macro is an extension that first appeared in
|
||||
.It Ic UE
|
||||
End a uniform resource identifier block started with
|
||||
.Ic UR .
|
||||
This is a non-standard GNU extension.
|
||||
This is a GNU extension.
|
||||
.It Ic UR
|
||||
Begin a uniform resource identifier block.
|
||||
This is a non-standard GNU extension.
|
||||
This is a GNU extension.
|
||||
It has the following syntax:
|
||||
.Bd -unfilled -offset indent
|
||||
.Pf . Ic UR Ar uri
|
||||
@@ -462,7 +464,7 @@ link description to be shown
|
||||
.It Ic YS
|
||||
End a synopsis block started with
|
||||
.Ic SY .
|
||||
This is a non-standard GNU extension.
|
||||
This is a GNU extension.
|
||||
.It Ic in
|
||||
Indent relative to the current indentation:
|
||||
.Pp
|
||||
|
||||
+27
-16
@@ -1,7 +1,7 @@
|
||||
/* $Id: man.c,v 1.187 2019/01/05 00:36:50 schwarze Exp $ */
|
||||
/* $Id: man.c,v 1.189 2022/08/16 23:01:09 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015,2017-2019,2022 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>
|
||||
* Copyright (c) 2011 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -70,19 +70,13 @@ man_hasc(char *start)
|
||||
return (ep - cp) % 2 ? NULL : ep;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind all open next-line scopes.
|
||||
*/
|
||||
void
|
||||
man_descope(struct roff_man *man, int line, int offs, char *start)
|
||||
{
|
||||
/* Trailing \c keeps next-line scope open. */
|
||||
|
||||
if (start != NULL && man_hasc(start) != NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Co-ordinate what happens with having a next-line scope open:
|
||||
* first close out the element scopes (if applicable),
|
||||
* then close out the block scope (also if applicable).
|
||||
*/
|
||||
/* First close out all next-line element scopes, if any. */
|
||||
|
||||
if (man->flags & MAN_ELINE) {
|
||||
while (man->last->parent->type != ROFFT_ROOT &&
|
||||
@@ -90,6 +84,14 @@ man_descope(struct roff_man *man, int line, int offs, char *start)
|
||||
man_unscope(man, man->last->parent);
|
||||
man->flags &= ~MAN_ELINE;
|
||||
}
|
||||
|
||||
/* Trailing \c keeps next-line block scope open. */
|
||||
|
||||
if (start != NULL && man_hasc(start) != NULL)
|
||||
return;
|
||||
|
||||
/* Close out the next-line block scope, if there is one. */
|
||||
|
||||
if ( ! (man->flags & MAN_BLINE))
|
||||
return;
|
||||
man_unscope(man, man->last->parent);
|
||||
@@ -274,6 +276,10 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind open next-line scopes
|
||||
* unless the tok request or macro is allowed inside them.
|
||||
*/
|
||||
void
|
||||
man_breakscope(struct roff_man *man, int tok)
|
||||
{
|
||||
@@ -294,10 +300,15 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
(man_macro(n->tok)->flags & (MAN_NSCOPED | MAN_ESCOPED))
|
||||
== MAN_NSCOPED)
|
||||
n = n->parent;
|
||||
|
||||
mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos,
|
||||
"%s breaks %s", roff_name[tok], roff_name[n->tok]);
|
||||
|
||||
for (;;) {
|
||||
mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos,
|
||||
"%s breaks %s", roff_name[tok], roff_name[n->tok]);
|
||||
if (n->parent->type != ROFFT_ELEM ||
|
||||
(man_macro(n->parent->tok)->flags &
|
||||
MAN_ESCOPED) == 0)
|
||||
break;
|
||||
n = n->parent;
|
||||
}
|
||||
roff_node_delete(man, n);
|
||||
man->flags &= ~MAN_ELINE;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: man.cgi.8,v 1.23 2018/05/20 21:48:44 schwarze Exp $
|
||||
.\" $Id: man.cgi.8,v 1.24 2022/07/06 15:47:28 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2015, 2016 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
@@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 20 2018 $
|
||||
.Dd $Mdocdate: July 6 2022 $
|
||||
.Dt MAN.CGI 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -381,11 +381,13 @@ or any character not contained in the
|
||||
.Nm
|
||||
reports an internal server error and exits without doing anything.
|
||||
.It Pa /man/header.html
|
||||
An optional file containing static HTML code to be inserted right
|
||||
after opening the <BODY> element.
|
||||
An optional file containing static HTML code to be wrapped in
|
||||
a <HEADER> element and inserted right after opening the <BODY> element.
|
||||
For example, it can contain an <H1> element
|
||||
specifying the name of the website.
|
||||
.It Pa /man/footer.html
|
||||
An optional file containing static HTML code to be inserted right
|
||||
before closing the <BODY> element.
|
||||
An optional file containing static HTML code to be wrapped in
|
||||
a <FOOTER> element and inserted right before closing the <BODY> element.
|
||||
.It Pa /man/OpenBSD-current/man1/mandoc.1
|
||||
An example
|
||||
.Xr mdoc 7
|
||||
|
||||
+79
-33
@@ -1,6 +1,6 @@
|
||||
/* $Id: man_html.c,v 1.179 2020/10/16 17:22:43 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.187 2023/10/24 20:53:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -53,6 +53,7 @@ static char list_continues(const struct roff_node *,
|
||||
static int man_B_pre(MAN_ARGS);
|
||||
static int man_IP_pre(MAN_ARGS);
|
||||
static int man_I_pre(MAN_ARGS);
|
||||
static int man_MR_pre(MAN_ARGS);
|
||||
static int man_OP_pre(MAN_ARGS);
|
||||
static int man_PP_pre(MAN_ARGS);
|
||||
static int man_RS_pre(MAN_ARGS);
|
||||
@@ -60,7 +61,6 @@ static int man_SH_pre(MAN_ARGS);
|
||||
static int man_SM_pre(MAN_ARGS);
|
||||
static int man_SY_pre(MAN_ARGS);
|
||||
static int man_UR_pre(MAN_ARGS);
|
||||
static int man_abort_pre(MAN_ARGS);
|
||||
static int man_alt_pre(MAN_ARGS);
|
||||
static int man_ign_pre(MAN_ARGS);
|
||||
static int man_in_pre(MAN_ARGS);
|
||||
@@ -75,9 +75,9 @@ static const struct man_html_act man_html_acts[MAN_MAX - MAN_TH] = {
|
||||
{ man_SH_pre, NULL }, /* SS */
|
||||
{ man_IP_pre, NULL }, /* TP */
|
||||
{ man_IP_pre, NULL }, /* TQ */
|
||||
{ man_abort_pre, NULL }, /* LP */
|
||||
{ man_PP_pre, NULL }, /* LP */
|
||||
{ man_PP_pre, NULL }, /* PP */
|
||||
{ man_abort_pre, NULL }, /* P */
|
||||
{ man_PP_pre, NULL }, /* P */
|
||||
{ man_IP_pre, NULL }, /* IP */
|
||||
{ man_PP_pre, NULL }, /* HP */
|
||||
{ man_SM_pre, NULL }, /* SM */
|
||||
@@ -107,6 +107,7 @@ static const struct man_html_act man_html_acts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL }, /* UE */
|
||||
{ man_UR_pre, NULL }, /* MT */
|
||||
{ NULL, NULL }, /* ME */
|
||||
{ man_MR_pre, NULL }, /* MR */
|
||||
};
|
||||
|
||||
|
||||
@@ -123,16 +124,16 @@ html_man(void *arg, const struct roff_meta *man)
|
||||
if ((h->oflags & HTML_FRAGMENT) == 0) {
|
||||
print_gen_decls(h);
|
||||
print_otag(h, TAG_HTML, "");
|
||||
if (n != NULL && n->type == ROFFT_COMMENT)
|
||||
print_gen_comment(h, n);
|
||||
t = print_otag(h, TAG_HEAD, "");
|
||||
print_man_head(man, h);
|
||||
print_tagq(h, t);
|
||||
if (n != NULL && n->type == ROFFT_COMMENT)
|
||||
print_gen_comment(h, n);
|
||||
print_otag(h, TAG_BODY, "");
|
||||
}
|
||||
|
||||
man_root_pre(man, h);
|
||||
t = print_otag(h, TAG_DIV, "c", "manual-text");
|
||||
t = print_otag(h, TAG_MAIN, "c", "manual-text");
|
||||
print_man_nodelist(man, n, h);
|
||||
print_tagq(h, t);
|
||||
man_root_post(man, h);
|
||||
@@ -263,26 +264,26 @@ print_man_node(MAN_ARGS)
|
||||
static void
|
||||
man_root_pre(const struct roff_meta *man, struct html *h)
|
||||
{
|
||||
struct tag *t, *tt;
|
||||
struct tag *t;
|
||||
char *title;
|
||||
|
||||
assert(man->title);
|
||||
assert(man->msec);
|
||||
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
|
||||
|
||||
t = print_otag(h, TAG_TABLE, "c", "head");
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
t = print_otag(h, TAG_DIV, "cr?", "head", "doc-pageheader",
|
||||
"aria-label", "Manual header line");
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-ltitle");
|
||||
print_otag(h, TAG_SPAN, "c", "head-ltitle");
|
||||
print_text(h, title);
|
||||
print_stagq(h, tt);
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-vol");
|
||||
print_otag(h, TAG_SPAN, "c", "head-vol");
|
||||
if (man->vol != NULL)
|
||||
print_text(h, man->vol);
|
||||
print_stagq(h, tt);
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-rtitle");
|
||||
print_otag(h, TAG_SPAN, "c", "head-rtitle");
|
||||
print_text(h, title);
|
||||
print_tagq(h, t);
|
||||
free(title);
|
||||
@@ -291,16 +292,19 @@ man_root_pre(const struct roff_meta *man, struct html *h)
|
||||
static void
|
||||
man_root_post(const struct roff_meta *man, struct html *h)
|
||||
{
|
||||
struct tag *t, *tt;
|
||||
struct tag *t;
|
||||
|
||||
t = print_otag(h, TAG_TABLE, "c", "foot");
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
t = print_otag(h, TAG_DIV, "cr?", "foot", "doc-pagefooter",
|
||||
"aria-label", "Manual footer line");
|
||||
|
||||
print_otag(h, TAG_TD, "c", "foot-date");
|
||||
print_otag(h, TAG_SPAN, "c", "foot-left");
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_SPAN, "c", "foot-date");
|
||||
print_text(h, man->date);
|
||||
print_stagq(h, tt);
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "foot-os");
|
||||
print_otag(h, TAG_SPAN, "c", "foot-os");
|
||||
if (man->os != NULL)
|
||||
print_text(h, man->os);
|
||||
print_tagq(h, t);
|
||||
@@ -313,10 +317,10 @@ man_SH_pre(MAN_ARGS)
|
||||
enum htmltag tag;
|
||||
|
||||
if (n->tok == MAN_SH) {
|
||||
tag = TAG_H1;
|
||||
tag = TAG_H2;
|
||||
class = "Sh";
|
||||
} else {
|
||||
tag = TAG_H2;
|
||||
tag = TAG_H3;
|
||||
class = "Ss";
|
||||
}
|
||||
switch (n->type) {
|
||||
@@ -403,7 +407,7 @@ man_PP_pre(MAN_ARGS)
|
||||
if (n->child != NULL &&
|
||||
(n->child->flags & NODE_NOFILL) == 0)
|
||||
print_otag(h, TAG_P, "c",
|
||||
n->tok == MAN_PP ? "Pp" : "Pp HP");
|
||||
n->tok == MAN_HP ? "Pp HP" : "Pp");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@@ -431,10 +435,12 @@ list_continues(const struct roff_node *n1, const struct roff_node *n2)
|
||||
s2 = n2 == NULL ? "" : n2->string;
|
||||
c1 = strcmp(s1, "*") == 0 ? '*' :
|
||||
strcmp(s1, "\\-") == 0 ? '-' :
|
||||
strcmp(s1, "\\(bu") == 0 ? 'b' : ' ';
|
||||
strcmp(s1, "\\(bu") == 0 ? 'b' :
|
||||
strcmp(s1, "\\[bu]") == 0 ? 'b' : ' ';
|
||||
c2 = strcmp(s2, "*") == 0 ? '*' :
|
||||
strcmp(s2, "\\-") == 0 ? '-' :
|
||||
strcmp(s2, "\\(bu") == 0 ? 'b' : ' ';
|
||||
strcmp(s2, "\\(bu") == 0 ? 'b' :
|
||||
strcmp(s2, "\\[bu]") == 0 ? 'b' : ' ';
|
||||
return c1 != c2 ? '\0' : c1 == 'b' ? '*' : c1;
|
||||
}
|
||||
|
||||
@@ -514,6 +520,52 @@ man_IP_pre(MAN_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
man_MR_pre(MAN_ARGS)
|
||||
{
|
||||
struct tag *t;
|
||||
const char *name, *section, *suffix;
|
||||
char *label;
|
||||
|
||||
html_setfont(h, ESCAPE_FONTROMAN);
|
||||
name = section = suffix = label = NULL;
|
||||
if (n->child != NULL) {
|
||||
name = n->child->string;
|
||||
if (n->child->next != NULL) {
|
||||
section = n->child->next->string;
|
||||
mandoc_asprintf(&label,
|
||||
"%s, section %s", name, section);
|
||||
if (n->child->next->next != NULL)
|
||||
suffix = n->child->next->next->string;
|
||||
}
|
||||
}
|
||||
|
||||
if (name != NULL && section != NULL && h->base_man1 != NULL)
|
||||
t = print_otag(h, TAG_A, "chM?", "Xr",
|
||||
name, section, "aria-label", label);
|
||||
else
|
||||
t = print_otag(h, TAG_A, "c?", "Xr", "aria-label", label);
|
||||
|
||||
free(label);
|
||||
if (name != NULL) {
|
||||
print_text(h, name);
|
||||
h->flags |= HTML_NOSPACE;
|
||||
}
|
||||
print_text(h, "(");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
if (section != NULL) {
|
||||
print_text(h, section);
|
||||
h->flags |= HTML_NOSPACE;
|
||||
}
|
||||
print_text(h, ")");
|
||||
print_tagq(h, t);
|
||||
if (suffix != NULL) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, suffix);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
man_OP_pre(MAN_ARGS)
|
||||
{
|
||||
@@ -632,9 +684,3 @@ man_UR_pre(MAN_ARGS)
|
||||
print_man_nodelist(man, n->child, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
man_abort_pre(MAN_ARGS)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: man_macro.c,v 1.145 2020/09/09 17:01:10 schwarze Exp $ */
|
||||
/* $Id: man_macro.c,v 1.150 2023/11/13 19:13:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012-2015,2017-2020,2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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
|
||||
@@ -26,6 +26,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
@@ -65,10 +68,10 @@ static const struct man_macro man_macros[MAN_MAX - MAN_TH] = {
|
||||
{ in_line_eoln, 0 }, /* RI */
|
||||
{ blk_close, MAN_XSCOPE }, /* RE */
|
||||
{ blk_exp, MAN_XSCOPE }, /* RS */
|
||||
{ in_line_eoln, 0 }, /* DT */
|
||||
{ in_line_eoln, 0 }, /* UC */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* DT */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* UC */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* PD */
|
||||
{ in_line_eoln, 0 }, /* AT */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* AT */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* in */
|
||||
{ blk_imp, MAN_XSCOPE }, /* SY */
|
||||
{ blk_close, MAN_XSCOPE }, /* YS */
|
||||
@@ -79,6 +82,7 @@ static const struct man_macro man_macros[MAN_MAX - MAN_TH] = {
|
||||
{ blk_close, MAN_XSCOPE }, /* UE */
|
||||
{ blk_exp, MAN_XSCOPE }, /* MT */
|
||||
{ blk_close, MAN_XSCOPE }, /* ME */
|
||||
{ in_line_eoln, 0 }, /* MR */
|
||||
};
|
||||
|
||||
|
||||
@@ -108,7 +112,8 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
n->line, n->pos,
|
||||
"EOF breaks %s", roff_name[n->tok]);
|
||||
if (man->flags & MAN_ELINE) {
|
||||
if ((man_macro(n->parent->tok)->flags &
|
||||
if (n->parent->type == ROFFT_ROOT ||
|
||||
(man_macro(n->parent->tok)->flags &
|
||||
MAN_ESCOPED) == 0)
|
||||
man->flags &= ~MAN_ELINE;
|
||||
} else {
|
||||
@@ -312,7 +317,7 @@ blk_exp(MACRO_PROT_ARGS)
|
||||
if (tok == MAN_RS) {
|
||||
if (roff_getreg(man->roff, "an-margin") == 0)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
7 * 24, '=');
|
||||
5 * 24, '=');
|
||||
if ((head->aux = strtod(p, NULL) * 24.0) > 0)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
head->aux, '+');
|
||||
@@ -393,6 +398,11 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
else if (tok == MAN_EE)
|
||||
man->flags &= ~ROFF_NOFILL;
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
if (tok == MAN_TH)
|
||||
mandoc_dbg_name(buf);
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if (buf[*pos] != '\0' && man->last != n && tok == MAN_PD) {
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS, line, *pos,
|
||||
|
||||
+60
-48
@@ -1,6 +1,6 @@
|
||||
/* $Id: man_term.c,v 1.236 2021/06/28 19:50:15 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.244 2023/11/13 19:13:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -74,6 +74,7 @@ static int pre_DT(DECL_ARGS);
|
||||
static int pre_HP(DECL_ARGS);
|
||||
static int pre_I(DECL_ARGS);
|
||||
static int pre_IP(DECL_ARGS);
|
||||
static int pre_MR(DECL_ARGS);
|
||||
static int pre_OP(DECL_ARGS);
|
||||
static int pre_PD(DECL_ARGS);
|
||||
static int pre_PP(DECL_ARGS);
|
||||
@@ -83,7 +84,6 @@ static int pre_SS(DECL_ARGS);
|
||||
static int pre_SY(DECL_ARGS);
|
||||
static int pre_TP(DECL_ARGS);
|
||||
static int pre_UR(DECL_ARGS);
|
||||
static int pre_abort(DECL_ARGS);
|
||||
static int pre_alternate(DECL_ARGS);
|
||||
static int pre_ign(DECL_ARGS);
|
||||
static int pre_in(DECL_ARGS);
|
||||
@@ -103,9 +103,9 @@ static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
|
||||
{ pre_SS, post_SH, 0 }, /* SS */
|
||||
{ pre_TP, post_TP, 0 }, /* TP */
|
||||
{ pre_TP, post_TP, 0 }, /* TQ */
|
||||
{ pre_abort, NULL, 0 }, /* LP */
|
||||
{ pre_PP, NULL, 0 }, /* LP */
|
||||
{ pre_PP, NULL, 0 }, /* PP */
|
||||
{ pre_abort, NULL, 0 }, /* P */
|
||||
{ pre_PP, NULL, 0 }, /* P */
|
||||
{ pre_IP, post_IP, 0 }, /* IP */
|
||||
{ pre_HP, post_HP, 0 }, /* HP */
|
||||
{ NULL, NULL, 0 }, /* SM */
|
||||
@@ -121,10 +121,10 @@ static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
|
||||
{ pre_alternate, NULL, 0 }, /* RI */
|
||||
{ NULL, NULL, 0 }, /* RE */
|
||||
{ pre_RS, post_RS, 0 }, /* RS */
|
||||
{ pre_DT, NULL, 0 }, /* DT */
|
||||
{ pre_DT, NULL, MAN_NOTEXT }, /* DT */
|
||||
{ pre_ign, NULL, MAN_NOTEXT }, /* UC */
|
||||
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
|
||||
{ pre_ign, NULL, 0 }, /* AT */
|
||||
{ pre_ign, NULL, MAN_NOTEXT }, /* AT */
|
||||
{ pre_in, NULL, MAN_NOTEXT }, /* in */
|
||||
{ pre_SY, post_SY, 0 }, /* SY */
|
||||
{ NULL, NULL, 0 }, /* YS */
|
||||
@@ -135,6 +135,7 @@ static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL, 0 }, /* UE */
|
||||
{ pre_UR, post_UR, 0 }, /* MT */
|
||||
{ NULL, NULL, 0 }, /* ME */
|
||||
{ pre_MR, NULL, 0 }, /* MR */
|
||||
};
|
||||
static const struct man_term_act *man_term_act(enum roff_tok);
|
||||
|
||||
@@ -152,19 +153,15 @@ terminal_man(void *arg, const struct roff_meta *man)
|
||||
struct mtermp mt;
|
||||
struct termp *p;
|
||||
struct roff_node *n, *nc, *nn;
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
save_defindent = p->defindent;
|
||||
if (p->synopsisonly == 0 && p->defindent == 0)
|
||||
p->defindent = 7;
|
||||
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
|
||||
memset(&mt, 0, sizeof(mt));
|
||||
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
||||
mt.lmargin[mt.lmargincur] = term_len(p, 7);
|
||||
mt.offset = term_len(p, p->defindent);
|
||||
mt.pardist = 1;
|
||||
|
||||
@@ -194,7 +191,6 @@ terminal_man(void *arg, const struct roff_meta *man)
|
||||
print_man_nodelist(p, &mt, n, man);
|
||||
term_end(p);
|
||||
}
|
||||
p->defindent = save_defindent;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -225,13 +221,6 @@ print_bvspace(struct termp *p, struct roff_node *n, int pardist)
|
||||
term_vspace(p);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pre_abort(DECL_ARGS)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ign(DECL_ARGS)
|
||||
{
|
||||
@@ -335,6 +324,29 @@ pre_B(DECL_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_MR(DECL_ARGS)
|
||||
{
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
n = n->child;
|
||||
if (n != NULL) {
|
||||
term_word(p, n->string); /* name */
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
term_word(p, "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (n != NULL && (n = n->next) != NULL) {
|
||||
term_word(p, n->string); /* section */
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
term_word(p, ")");
|
||||
if (n != NULL && (n = n->next) != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, n->string); /* suffix */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_OP(DECL_ARGS)
|
||||
{
|
||||
@@ -487,7 +499,7 @@ pre_PP(DECL_ARGS)
|
||||
{
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, 7);
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
@@ -517,7 +529,7 @@ pre_IP(DECL_ARGS)
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NONEWLINE;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@@ -591,7 +603,7 @@ pre_TP(DECL_ARGS)
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NONEWLINE;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@@ -663,7 +675,7 @@ pre_SS(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, 7);
|
||||
mt->offset = term_len(p, p->defindent);
|
||||
|
||||
/*
|
||||
@@ -704,7 +716,7 @@ pre_SH(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, 7);
|
||||
mt->offset = term_len(p, p->defindent);
|
||||
|
||||
/*
|
||||
@@ -788,7 +800,7 @@ pre_RS(DECL_ARGS)
|
||||
if (++mt->lmarginsz < MAXMARGINS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, 7);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -900,6 +912,22 @@ print_man_node(DECL_ARGS)
|
||||
const struct man_term_act *act;
|
||||
int c;
|
||||
|
||||
/*
|
||||
* In no-fill mode, break the output line at the beginning
|
||||
* of new input lines except after \c, and nowhere else.
|
||||
*/
|
||||
|
||||
if (n->flags & NODE_NOFILL) {
|
||||
if (n->flags & NODE_LINE &&
|
||||
(p->flags & TERMP_NONEWLINE) == 0)
|
||||
term_newln(p);
|
||||
p->flags |= TERMP_BRNEVER;
|
||||
} else {
|
||||
if (n->flags & NODE_LINE)
|
||||
term_tab_ref(p);
|
||||
p->flags &= ~TERMP_BRNEVER;
|
||||
}
|
||||
|
||||
if (n->flags & NODE_ID)
|
||||
term_tag_write(n, p->line);
|
||||
|
||||
@@ -935,7 +963,7 @@ print_man_node(DECL_ARGS)
|
||||
return;
|
||||
case ROFFT_TBL:
|
||||
if (p->tbl.cols == NULL)
|
||||
term_vspace(p);
|
||||
term_newln(p);
|
||||
term_tbl(p, n->span);
|
||||
return;
|
||||
default:
|
||||
@@ -964,27 +992,11 @@ print_man_node(DECL_ARGS)
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
out:
|
||||
/*
|
||||
* If we're in a literal context, make sure that words
|
||||
* together on the same line stay together. This is a
|
||||
* POST-printing call, so we check the NEXT word. Since
|
||||
* -man doesn't have nested macros, we don't need to be
|
||||
* more specific than this.
|
||||
*/
|
||||
if (n->flags & NODE_NOFILL &&
|
||||
! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
|
||||
(n->next == NULL || n->next->flags & NODE_LINE)) {
|
||||
p->flags |= TERMP_BRNEVER | TERMP_NOSPACE;
|
||||
if (n->string != NULL && *n->string != '\0')
|
||||
term_flushln(p);
|
||||
else
|
||||
term_newln(p);
|
||||
p->flags &= ~TERMP_BRNEVER;
|
||||
if (p->tcol->rmargin < p->maxrmargin &&
|
||||
n->parent->tok == MAN_HP) {
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
}
|
||||
if (n->parent->tok == MAN_HP && n->parent->type == ROFFT_BODY &&
|
||||
n->prev == NULL && n->flags & NODE_NOFILL) {
|
||||
term_newln(p);
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
}
|
||||
if (n->flags & NODE_EOS)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* $Id: man_validate.c,v 1.156 2021/08/10 12:55:03 schwarze Exp $ */
|
||||
/* $Id: man_validate.c,v 1.159 2023/10/24 20:53:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012-2020, 2023 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_xr.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "libmandoc.h"
|
||||
@@ -44,7 +45,6 @@
|
||||
|
||||
typedef void (*v_check)(CHKARGS);
|
||||
|
||||
static void check_abort(CHKARGS) __attribute__((__noreturn__));
|
||||
static void check_par(CHKARGS);
|
||||
static void check_part(CHKARGS);
|
||||
static void check_root(CHKARGS);
|
||||
@@ -55,6 +55,7 @@ static void post_AT(CHKARGS);
|
||||
static void post_EE(CHKARGS);
|
||||
static void post_EX(CHKARGS);
|
||||
static void post_IP(CHKARGS);
|
||||
static void post_MR(CHKARGS);
|
||||
static void post_OP(CHKARGS);
|
||||
static void post_SH(CHKARGS);
|
||||
static void post_TH(CHKARGS);
|
||||
@@ -69,9 +70,9 @@ static const v_check man_valids[MAN_MAX - MAN_TH] = {
|
||||
post_SH, /* SS */
|
||||
post_TP, /* TP */
|
||||
post_TP, /* TQ */
|
||||
check_abort,/* LP */
|
||||
check_par, /* LP */
|
||||
check_par, /* PP */
|
||||
check_abort,/* P */
|
||||
check_par, /* P */
|
||||
post_IP, /* IP */
|
||||
NULL, /* HP */
|
||||
NULL, /* SM */
|
||||
@@ -101,6 +102,7 @@ static const v_check man_valids[MAN_MAX - MAN_TH] = {
|
||||
NULL, /* UE */
|
||||
post_UR, /* MT */
|
||||
NULL, /* ME */
|
||||
post_MR, /* MR */
|
||||
};
|
||||
|
||||
|
||||
@@ -111,26 +113,12 @@ man_validate(struct roff_man *man)
|
||||
struct roff_node *n;
|
||||
const v_check *cp;
|
||||
|
||||
/*
|
||||
* Translate obsolete macros such that later code
|
||||
* does not need to look for them.
|
||||
*/
|
||||
|
||||
n = man->last;
|
||||
switch (n->tok) {
|
||||
case MAN_LP:
|
||||
case MAN_P:
|
||||
n->tok = MAN_PP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over all children, recursing into each one
|
||||
* in turn, depth-first.
|
||||
*/
|
||||
|
||||
n = man->last;
|
||||
man->last = man->last->child;
|
||||
while (man->last != NULL) {
|
||||
man_validate(man);
|
||||
@@ -200,12 +188,6 @@ check_root(CHKARGS)
|
||||
"(OpenBSD)" : "(NetBSD)");
|
||||
}
|
||||
|
||||
static void
|
||||
check_abort(CHKARGS)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading whitespace, dashes, backslashes, and font escapes,
|
||||
* then create a tag if the first following byte is a letter.
|
||||
@@ -340,7 +322,8 @@ post_SH(CHKARGS)
|
||||
return;
|
||||
}
|
||||
|
||||
if (nc->tok == MAN_PP && nc->body->child != NULL) {
|
||||
if ((nc->tok == MAN_LP || nc->tok == MAN_PP || nc->tok == MAN_P) &&
|
||||
nc->body->child != NULL) {
|
||||
while (nc->body->last != NULL) {
|
||||
man->next = ROFF_NEXT_CHILD;
|
||||
roff_node_relink(man, nc->body->last);
|
||||
@@ -348,7 +331,8 @@ post_SH(CHKARGS)
|
||||
}
|
||||
}
|
||||
|
||||
if (nc->tok == MAN_PP || nc->tok == ROFF_sp || nc->tok == ROFF_br) {
|
||||
if (nc->tok == MAN_LP || nc->tok == MAN_PP || nc->tok == MAN_P ||
|
||||
nc->tok == ROFF_sp || nc->tok == ROFF_br) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, nc->line, nc->pos,
|
||||
"%s after %s", roff_name[nc->tok], roff_name[n->tok]);
|
||||
roff_node_delete(man, nc);
|
||||
@@ -373,13 +357,11 @@ post_UR(CHKARGS)
|
||||
if (n->type == ROFFT_HEAD && n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_UR_NOHEAD, n->line, n->pos,
|
||||
"%s", roff_name[n->tok]);
|
||||
check_part(man, n);
|
||||
}
|
||||
|
||||
static void
|
||||
check_part(CHKARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BODY && n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY, n->line, n->pos,
|
||||
"%s", roff_name[n->tok]);
|
||||
@@ -567,6 +549,32 @@ post_TH(CHKARGS)
|
||||
roff_node_delete(man, man->last);
|
||||
}
|
||||
|
||||
static void
|
||||
post_MR(CHKARGS)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
|
||||
if ((nch = n->child) == NULL) {
|
||||
mandoc_msg(MANDOCERR_NM_NONAME, n->line, n->pos, "MR");
|
||||
return;
|
||||
}
|
||||
if (nch->next == NULL) {
|
||||
mandoc_msg(MANDOCERR_XR_NOSEC,
|
||||
n->line, n->pos, "MR %s", nch->string);
|
||||
return;
|
||||
}
|
||||
if (mandoc_xr_add(nch->next->string, nch->string, nch->line, nch->pos))
|
||||
mandoc_msg(MANDOCERR_XR_SELF, nch->line, nch->pos,
|
||||
"MR %s %s", nch->string, nch->next->string);
|
||||
if ((nch = nch->next->next) == NULL || nch->next == NULL)
|
||||
return;
|
||||
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS, nch->next->line, nch->next->pos,
|
||||
"MR ... %s", nch->next->string);
|
||||
while (nch->next != NULL)
|
||||
roff_node_delete(man, nch->next);
|
||||
}
|
||||
|
||||
static void
|
||||
post_UC(CHKARGS)
|
||||
{
|
||||
|
||||
+150
-56
@@ -1,6 +1,6 @@
|
||||
.\" $OpenBSD: mandoc.1,v 1.166 2020/02/15 15:28:01 schwarze Exp $
|
||||
.\" $Id: mandoc.1,v 1.267 2023/11/13 19:13:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2012, 2014-2021 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2012, 2014-2023 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <[email protected]>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -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: August 14 2021 $
|
||||
.Dd $Mdocdate: November 13 2023 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -287,10 +287,7 @@ arguments are accepted:
|
||||
.It Cm indent Ns = Ns Ar indent
|
||||
The left margin for normal text is set to
|
||||
.Ar indent
|
||||
blank characters instead of the default of five for
|
||||
.Xr mdoc 7
|
||||
and seven for
|
||||
.Xr man 7 .
|
||||
blank characters instead of the default of five.
|
||||
Increasing this is not recommended; it may result in degraded formatting,
|
||||
for example overfull lines or ugly line breaks.
|
||||
When output is to a pager on a terminal that is less than 66 columns
|
||||
@@ -302,8 +299,7 @@ input files in
|
||||
.Xr mdoc 7
|
||||
output style.
|
||||
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 .
|
||||
on the right side of the footer line.
|
||||
One useful application is for checking that
|
||||
.Fl T Cm man
|
||||
output formats in the same way as the
|
||||
@@ -342,21 +338,9 @@ and may exceed the output width.
|
||||
Output produced by
|
||||
.Fl T Cm html
|
||||
conforms to HTML5 using optional self-closing tags.
|
||||
Default styles use only CSS1.
|
||||
Equations rendered from
|
||||
.Xr eqn 7
|
||||
blocks use MathML.
|
||||
.Pp
|
||||
The file
|
||||
.Pa /usr/share/misc/mandoc.css
|
||||
documents style-sheet classes available for customising output.
|
||||
If a style-sheet is not specified with
|
||||
.Fl O Cm style ,
|
||||
.Fl T Cm html
|
||||
defaults to simple output (via an embedded style-sheet)
|
||||
readable in any graphical or text-based web
|
||||
browser.
|
||||
.Pp
|
||||
Non-ASCII characters are rendered
|
||||
as hexadecimal Unicode character references.
|
||||
.Pp
|
||||
@@ -407,9 +391,49 @@ otherwise, the second format is used.
|
||||
.It Cm style Ns = Ns Ar style.css
|
||||
The file
|
||||
.Ar style.css
|
||||
is used for an external style-sheet.
|
||||
is used as an external stylesheet.
|
||||
This must be a valid absolute or
|
||||
relative URI.
|
||||
.Pp
|
||||
Using the file
|
||||
.Pa mandoc.css
|
||||
that is distributed with
|
||||
.Nm
|
||||
is recommended.
|
||||
It provides an appearance similar to terminal output with some additional
|
||||
features specific to
|
||||
.Nm
|
||||
HTML output, in particular making anchor locations that support
|
||||
deep linking stand out visually by putting a dotted line under them,
|
||||
providing tooltips showing the semantic function of elements (macro
|
||||
names), providing some simple aspects of responsive web design, and
|
||||
providing simple support for users who prefer a dark color scheme.
|
||||
.Pp
|
||||
Using a custom CSS file is possible, but writing it requires
|
||||
proficiency in all of the languages HTML 5, CSS 4, and
|
||||
.Xr mdoc 7
|
||||
and familiarity with the
|
||||
.Nm Ns -specific
|
||||
classes used in
|
||||
.Pa mandoc.css .
|
||||
Besides, while the file
|
||||
.Pa mandoc.css
|
||||
is always adapted to the HTML output generated by the
|
||||
.Nm
|
||||
version it is distributed with, maintaining a custom CSS file usually
|
||||
requires adaptations each time
|
||||
.Nm
|
||||
is upgraded to a new version.
|
||||
.Pp
|
||||
If a stylesheet is not specified with
|
||||
.Fl O Cm style ,
|
||||
.Fl T Cm html
|
||||
embeds a minimal stylesheet into the HTML output, mostly to select
|
||||
adequate font-style and font-weight attributes for various macros.
|
||||
The result is readable in any graphical or text-based web browser,
|
||||
but does not aim for looking similar to terminal output.
|
||||
Instead, formatting is mostly left to browser defaults
|
||||
and to user settings in the browser configuration.
|
||||
.It Cm tag Ns Op = Ns Ar term
|
||||
Same syntax and semantics as for
|
||||
.Sx ASCII Output .
|
||||
@@ -487,10 +511,10 @@ Use
|
||||
to translate
|
||||
.Xr mdoc 7
|
||||
input to the markdown format conforming to
|
||||
.Lk http://daringfireball.net/projects/markdown/syntax.text\
|
||||
.Lk https://daringfireball.net/projects/markdown/syntax.text\
|
||||
"John Gruber's 2004 specification" .
|
||||
The output also almost conforms to the
|
||||
.Lk http://commonmark.org/ CommonMark
|
||||
.Lk https://commonmark.org/ CommonMark
|
||||
specification.
|
||||
.Pp
|
||||
The character set used for the markdown output is ASCII.
|
||||
@@ -735,11 +759,11 @@ output mode implies
|
||||
.Sh EXAMPLES
|
||||
To page manuals to the terminal:
|
||||
.Pp
|
||||
.Dl $ mandoc -l mandoc.1 man.1 apropos.1 makewhatis.8
|
||||
.Dl $ mandoc -a mandoc.1 man.1 apropos.1 makewhatis.8
|
||||
.Pp
|
||||
To produce HTML manuals with
|
||||
.Pa /usr/share/misc/mandoc.css
|
||||
as the style-sheet:
|
||||
as the stylesheet:
|
||||
.Pp
|
||||
.Dl $ mandoc \-T html -O style=/usr/share/misc/mandoc.css mdoc.7 > mdoc.7.html
|
||||
.Pp
|
||||
@@ -766,7 +790,7 @@ Messages displayed by
|
||||
follow this format:
|
||||
.Bd -ragged -offset indent
|
||||
.Nm :
|
||||
.Ar file : Ns Ar line : Ns Ar column : level : message : macro arguments
|
||||
.Ar file : Ns Ar line : Ns Ar column : level : message : macro argument ...
|
||||
.Pq Ar os
|
||||
.Ed
|
||||
.Pp
|
||||
@@ -786,9 +810,7 @@ and
|
||||
strings are explained below.
|
||||
The name of the
|
||||
.Ar macro
|
||||
triggering the message and its
|
||||
.Ar arguments
|
||||
are omitted where meaningless.
|
||||
triggering the message and its arguments are omitted where meaningless.
|
||||
The
|
||||
.Ar os
|
||||
operating system specifier is omitted for messages that are relevant
|
||||
@@ -835,7 +857,7 @@ message levels, the
|
||||
.Cm style
|
||||
level tries to reduce the probability that issues go unnoticed,
|
||||
so it may occasionally issue bogus suggestions.
|
||||
Please use your good judgement to decide whether any particular
|
||||
Use your judgement to decide whether any particular
|
||||
.Cm style
|
||||
suggestion really justifies a change to the input file.
|
||||
.It Cm base
|
||||
@@ -1269,9 +1291,11 @@ The same standard section title occurs more than once.
|
||||
A standard section header occurs in a section of the manual
|
||||
where it normally isn't useful.
|
||||
.It Sy "cross reference to self"
|
||||
.Pq mdoc
|
||||
.Pq mdoc , man
|
||||
An
|
||||
.Ic \&Xr
|
||||
or
|
||||
.Ic \&MR
|
||||
macro refers to a name and section matching the section of the present
|
||||
manual page and a name mentioned in an
|
||||
.Ic \&Nm
|
||||
@@ -1474,10 +1498,8 @@ A
|
||||
.Ic \&Bl ,
|
||||
.Ic \&D1 ,
|
||||
.Ic \&Dl ,
|
||||
.Ic \&MT ,
|
||||
.Ic \&RS ,
|
||||
or
|
||||
.Ic \&UR
|
||||
.Ic \&RS
|
||||
block contains nothing in its body and will produce no output.
|
||||
.It Sy "empty argument, using 0n"
|
||||
.Pq mdoc
|
||||
@@ -1592,12 +1614,16 @@ macro is immediately followed by an
|
||||
macro on the next input line.
|
||||
Such an empty block does not produce any output.
|
||||
.It Sy "missing section argument"
|
||||
.Pq mdoc
|
||||
.Pq mdoc , man
|
||||
An
|
||||
.Ic \&Xr
|
||||
or
|
||||
.Ic \&MR
|
||||
macro lacks its second, section number argument.
|
||||
The first argument, i.e. the name, is printed, but without subsequent
|
||||
parentheses.
|
||||
The first argument, i.e. the name, is printed, but without a section number.
|
||||
In the case of
|
||||
.Ic \&Xr ,
|
||||
the parentheses are also omitted.
|
||||
.It Sy "missing -std argument, adding it"
|
||||
.Pq mdoc
|
||||
An
|
||||
@@ -1754,6 +1780,15 @@ request or a
|
||||
layout modifier has an unknown
|
||||
.Ar font
|
||||
argument.
|
||||
.It Sy "ignoring distance argument"
|
||||
.Pq roff
|
||||
In addition to the margin character, an
|
||||
.Ic \&mc
|
||||
request has a second argument supposed to represent a distance, but the
|
||||
.Nm
|
||||
implementation of
|
||||
.Ic \&mc
|
||||
always ignores the second argument.
|
||||
.It Sy "odd number of characters in request"
|
||||
.Pq roff
|
||||
A
|
||||
@@ -1788,23 +1823,10 @@ it is hard to predict which tab stop position the tab will advance to.
|
||||
.Pq mdoc
|
||||
A new sentence starts in the middle of a text line.
|
||||
Start it on a new input line to help formatters produce correct spacing.
|
||||
.It Sy "invalid escape sequence"
|
||||
.It Sy "invalid escape sequence argument"
|
||||
.Pq roff
|
||||
An escape sequence has an invalid opening argument delimiter, lacks the
|
||||
closing argument delimiter, the argument is of an invalid form, or it is
|
||||
a character escape sequence with an invalid name.
|
||||
If the argument is incomplete,
|
||||
.Ic \e*
|
||||
and
|
||||
.Ic \en
|
||||
expand to an empty string,
|
||||
.Ic \eB
|
||||
to the digit
|
||||
.Sq 0 ,
|
||||
and
|
||||
.Ic \ew
|
||||
to the length of the incomplete argument.
|
||||
All other invalid escape sequences are ignored.
|
||||
The argument of an escape sequence is of an invalid form.
|
||||
Invalid escape sequences are ignored.
|
||||
.It Sy "undefined escape, printing literally"
|
||||
.Pq roff
|
||||
In an escape sequence, the first character
|
||||
@@ -2082,6 +2104,13 @@ and expands to the empty string.
|
||||
.Pq roff
|
||||
The argument of the escape sequence \e$ is not a digit;
|
||||
the escape sequence expands to the empty string.
|
||||
.It Sy "negative argument, using 0"
|
||||
.Pq roff
|
||||
A
|
||||
.Ic \&shift
|
||||
request has a negative argument
|
||||
or an argument that is negative due to integer overflow.
|
||||
Macro argument numbering remains unchanged.
|
||||
.It Sy "NOT IMPLEMENTED: Bd -file"
|
||||
.Pq mdoc
|
||||
For security reasons, the
|
||||
@@ -2117,11 +2146,20 @@ The first argument of a
|
||||
request is neither a single ASCII character
|
||||
nor a single character escape sequence.
|
||||
The request is ignored including all its arguments.
|
||||
.It Sy "skipping unusable escape sequence"
|
||||
.Pq roff
|
||||
The first argument of an
|
||||
.Ic mc
|
||||
request is neither a single ASCII character
|
||||
nor a single character escape sequence.
|
||||
All arguments are ignored and printing of a margin character is disabled.
|
||||
.It Sy "missing manual name, using \(dq\(dq"
|
||||
.Pq mdoc
|
||||
.Pq mdoc , man
|
||||
The first call to
|
||||
.Ic \&Nm ,
|
||||
or any call in the NAME section, lacks the required argument.
|
||||
or any call in the NAME section, lacks the required argument, or
|
||||
.Ic \&MR
|
||||
is called without any argument.
|
||||
.It Sy "uname(3) system call failed, using UNKNOWN"
|
||||
.Pq mdoc
|
||||
The
|
||||
@@ -2249,6 +2287,8 @@ or a request of the
|
||||
family with more than two arguments
|
||||
.It
|
||||
.Ic \&Dt
|
||||
or
|
||||
.Ic \&MR
|
||||
with more than three arguments
|
||||
.It
|
||||
.Ic \&TH
|
||||
@@ -2262,6 +2302,60 @@ with invalid arguments
|
||||
.El
|
||||
The excess arguments are ignored.
|
||||
.El
|
||||
.Ss "Errors related to escape sequences"
|
||||
.Bl -ohang
|
||||
.It Sy "incomplete escape sequence"
|
||||
.Pq roff
|
||||
The end of the input line is encountered
|
||||
while parsing the argument of an escape sequence.
|
||||
In this case,
|
||||
.Ic \e*
|
||||
and
|
||||
.Ic \en
|
||||
expand to an empty string,
|
||||
.Ic \eB
|
||||
to the digit
|
||||
.Sq 0 ,
|
||||
and
|
||||
.Ic \ew
|
||||
to the length of the incomplete argument.
|
||||
All other incomplete escape sequences are ignored.
|
||||
.It Sy "invalid special character"
|
||||
.Pq roff
|
||||
A special character escape sequence is invalid,
|
||||
for example a Unicode sequence pointing to a surrogate
|
||||
or beyond the Unicode range, a \e[char...] escape sequence
|
||||
representing a control character or pointing beyond the
|
||||
.Vt unsigned char
|
||||
range, or an invalid variable-length form
|
||||
of a single-byte character escape sequence, for example writing
|
||||
.Qq \e[e]
|
||||
or
|
||||
.Qq \e[~]
|
||||
instead of
|
||||
.Qq \ee
|
||||
or
|
||||
.Qq \e~ ,
|
||||
respectively.
|
||||
The escape sequence is ignored.
|
||||
.It Sy "unknown special character"
|
||||
.Pq roff
|
||||
The name given in a special character escape sequence is not known to
|
||||
.Nm .
|
||||
The escape sequence is ignored.
|
||||
.It Sy "invalid escape argument delimiter"
|
||||
.Pq roff
|
||||
An escape sequence that expects a numerical argument
|
||||
attempts to employ one of the characters
|
||||
.Qq " %&()*+-./0123456789:<=>"
|
||||
as an argument delimiter.
|
||||
The escape sequence is ignored including the invalid opening delimiter
|
||||
and the rest of the argument may appear as output text.
|
||||
While various characters can be used as argument delimiters,
|
||||
using the apostrophe-quote character
|
||||
.Pq Sq \(aq
|
||||
is recommended for readability and robustness.
|
||||
.El
|
||||
.Ss Unsupported features
|
||||
.Bl -ohang
|
||||
.It Sy "input too large"
|
||||
|
||||
+9
-385
@@ -1,7 +1,8 @@
|
||||
/* $Id: mandoc.c,v 1.119 2021/08/10 12:55:03 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.121 2022/05/19 15:37:47 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011, 2015, 2017, 2018, 2019, 2020, 2021
|
||||
* Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -14,6 +15,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.
|
||||
*
|
||||
* Utility functions to handle end of sentence punctuation
|
||||
* and dates and times, for use by mdoc(7) and man(7) parsers.
|
||||
* Utility functions to handle fonts and numbers,
|
||||
* for use by mandoc(1) parsers and formatters.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
@@ -91,388 +97,6 @@ mandoc_font(const char *cp, int sz)
|
||||
}
|
||||
}
|
||||
|
||||
enum mandoc_esc
|
||||
mandoc_escape(const char **end, const char **start, int *sz)
|
||||
{
|
||||
const char *local_start;
|
||||
int local_sz, c, i;
|
||||
char term;
|
||||
enum mandoc_esc gly;
|
||||
|
||||
/*
|
||||
* When the caller doesn't provide return storage,
|
||||
* use local storage.
|
||||
*/
|
||||
|
||||
if (NULL == start)
|
||||
start = &local_start;
|
||||
if (NULL == sz)
|
||||
sz = &local_sz;
|
||||
|
||||
/*
|
||||
* Treat "\E" just like "\";
|
||||
* it only makes a difference in copy mode.
|
||||
*/
|
||||
|
||||
if (**end == 'E')
|
||||
++*end;
|
||||
|
||||
/*
|
||||
* Beyond the backslash, at least one input character
|
||||
* is part of the escape sequence. With one exception
|
||||
* (see below), that character won't be returned.
|
||||
*/
|
||||
|
||||
gly = ESCAPE_ERROR;
|
||||
*start = ++*end;
|
||||
*sz = 0;
|
||||
term = '\0';
|
||||
|
||||
switch ((*start)[-1]) {
|
||||
/*
|
||||
* First the glyphs. There are several different forms of
|
||||
* these, but each eventually returns a substring of the glyph
|
||||
* name.
|
||||
*/
|
||||
case '(':
|
||||
gly = ESCAPE_SPECIAL;
|
||||
*sz = 2;
|
||||
break;
|
||||
case '[':
|
||||
if (**start == ' ') {
|
||||
++*end;
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
gly = ESCAPE_SPECIAL;
|
||||
term = ']';
|
||||
break;
|
||||
case 'C':
|
||||
if ('\'' != **start)
|
||||
return ESCAPE_ERROR;
|
||||
*start = ++*end;
|
||||
gly = ESCAPE_SPECIAL;
|
||||
term = '\'';
|
||||
break;
|
||||
|
||||
/*
|
||||
* Escapes taking no arguments at all.
|
||||
*/
|
||||
case '!':
|
||||
case '?':
|
||||
return ESCAPE_UNSUPP;
|
||||
case '%':
|
||||
case '&':
|
||||
case ')':
|
||||
case ',':
|
||||
case '/':
|
||||
case '^':
|
||||
case 'a':
|
||||
case 'd':
|
||||
case 'r':
|
||||
case 't':
|
||||
case 'u':
|
||||
case '{':
|
||||
case '|':
|
||||
case '}':
|
||||
return ESCAPE_IGNORE;
|
||||
case 'c':
|
||||
return ESCAPE_NOSPACE;
|
||||
case 'p':
|
||||
return ESCAPE_BREAK;
|
||||
|
||||
/*
|
||||
* The \z escape is supposed to output the following
|
||||
* character without advancing the cursor position.
|
||||
* Since we are mostly dealing with terminal mode,
|
||||
* let us just skip the next character.
|
||||
*/
|
||||
case 'z':
|
||||
return ESCAPE_SKIPCHAR;
|
||||
|
||||
/*
|
||||
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
|
||||
* 'X' is the trigger. These have opaque sub-strings.
|
||||
*/
|
||||
case 'F':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'k':
|
||||
case 'M':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'O':
|
||||
case 'V':
|
||||
case 'Y':
|
||||
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')
|
||||
gly = ESCAPE_ERROR;
|
||||
*start = ++*end;
|
||||
*sz = 2;
|
||||
break;
|
||||
case '[':
|
||||
if ((*start)[-1] == 'O')
|
||||
gly = (*start)[1] == '5' ?
|
||||
ESCAPE_UNSUPP : ESCAPE_ERROR;
|
||||
*start = ++*end;
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
if ((*start)[-1] == 'O') {
|
||||
switch (**start) {
|
||||
case '0':
|
||||
gly = ESCAPE_UNSUPP;
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
break;
|
||||
default:
|
||||
gly = ESCAPE_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*sz = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* These escapes are of the form \X'Y', where 'X' is the trigger
|
||||
* and 'Y' is any string. These have opaque sub-strings.
|
||||
* The \B and \w escapes are handled in roff.c, roff_res().
|
||||
*/
|
||||
case 'A':
|
||||
case 'b':
|
||||
case 'D':
|
||||
case 'R':
|
||||
case 'X':
|
||||
case 'Z':
|
||||
gly = ESCAPE_IGNORE;
|
||||
/* FALLTHROUGH */
|
||||
case 'o':
|
||||
if (**start == '\0')
|
||||
return ESCAPE_ERROR;
|
||||
if (gly == ESCAPE_ERROR)
|
||||
gly = ESCAPE_OVERSTRIKE;
|
||||
term = **start;
|
||||
*start = ++*end;
|
||||
break;
|
||||
|
||||
/*
|
||||
* These escapes are of the form \X'N', where 'X' is the trigger
|
||||
* and 'N' resolves to a numerical expression.
|
||||
*/
|
||||
case 'h':
|
||||
case 'H':
|
||||
case 'L':
|
||||
case 'l':
|
||||
case 'S':
|
||||
case 'v':
|
||||
case 'x':
|
||||
if (strchr(" %&()*+-./0123456789:<=>", **start)) {
|
||||
if ('\0' != **start)
|
||||
++*end;
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
switch ((*start)[-1]) {
|
||||
case 'h':
|
||||
gly = ESCAPE_HORIZ;
|
||||
break;
|
||||
case 'l':
|
||||
gly = ESCAPE_HLINE;
|
||||
break;
|
||||
default:
|
||||
gly = ESCAPE_IGNORE;
|
||||
break;
|
||||
}
|
||||
term = **start;
|
||||
*start = ++*end;
|
||||
break;
|
||||
|
||||
/*
|
||||
* Special handling for the numbered character escape.
|
||||
* XXX Do any other escapes need similar handling?
|
||||
*/
|
||||
case 'N':
|
||||
if ('\0' == **start)
|
||||
return ESCAPE_ERROR;
|
||||
(*end)++;
|
||||
if (isdigit((unsigned char)**start)) {
|
||||
*sz = 1;
|
||||
return ESCAPE_IGNORE;
|
||||
}
|
||||
(*start)++;
|
||||
while (isdigit((unsigned char)**end))
|
||||
(*end)++;
|
||||
*sz = *end - *start;
|
||||
if ('\0' != **end)
|
||||
(*end)++;
|
||||
return ESCAPE_NUMBERED;
|
||||
|
||||
/*
|
||||
* Sizes get a special category of their own.
|
||||
*/
|
||||
case 's':
|
||||
gly = ESCAPE_IGNORE;
|
||||
|
||||
/* See +/- counts as a sign. */
|
||||
if ('+' == **end || '-' == **end || ASCII_HYPH == **end)
|
||||
*start = ++*end;
|
||||
|
||||
switch (**end) {
|
||||
case '(':
|
||||
*start = ++*end;
|
||||
*sz = 2;
|
||||
break;
|
||||
case '[':
|
||||
*start = ++*end;
|
||||
term = ']';
|
||||
break;
|
||||
case '\'':
|
||||
*start = ++*end;
|
||||
term = '\'';
|
||||
break;
|
||||
case '3':
|
||||
case '2':
|
||||
case '1':
|
||||
*sz = (*end)[-1] == 's' &&
|
||||
isdigit((unsigned char)(*end)[1]) ? 2 : 1;
|
||||
break;
|
||||
default:
|
||||
*sz = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
* Several special characters can be encoded as
|
||||
* one-byte escape sequences without using \[].
|
||||
*/
|
||||
case ' ':
|
||||
case '\'':
|
||||
case '-':
|
||||
case '.':
|
||||
case '0':
|
||||
case ':':
|
||||
case '_':
|
||||
case '`':
|
||||
case 'e':
|
||||
case '~':
|
||||
gly = ESCAPE_SPECIAL;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (gly == ESCAPE_ERROR)
|
||||
gly = ESCAPE_UNDEF;
|
||||
*start = --*end;
|
||||
*sz = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read up to the terminating character,
|
||||
* paying attention to nested escapes.
|
||||
*/
|
||||
|
||||
if ('\0' != term) {
|
||||
while (**end != term) {
|
||||
switch (**end) {
|
||||
case '\0':
|
||||
return ESCAPE_ERROR;
|
||||
case '\\':
|
||||
(*end)++;
|
||||
if (ESCAPE_ERROR ==
|
||||
mandoc_escape(end, NULL, NULL))
|
||||
return ESCAPE_ERROR;
|
||||
break;
|
||||
default:
|
||||
(*end)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*sz = (*end)++ - *start;
|
||||
|
||||
/*
|
||||
* The file chars.c only provides one common list
|
||||
* of character names, but \[-] == \- is the only
|
||||
* one of the characters with one-byte names that
|
||||
* allows enclosing the name in brackets.
|
||||
*/
|
||||
if (gly == ESCAPE_SPECIAL && *sz == 1 && **start != '-')
|
||||
return ESCAPE_ERROR;
|
||||
} else {
|
||||
assert(*sz > 0);
|
||||
if ((size_t)*sz > strlen(*start))
|
||||
return ESCAPE_ERROR;
|
||||
*end += *sz;
|
||||
}
|
||||
|
||||
/* Run post-processors. */
|
||||
|
||||
switch (gly) {
|
||||
case ESCAPE_FONT:
|
||||
gly = mandoc_font(*start, *sz);
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (**start == 'c') {
|
||||
if (*sz < 6 || *sz > 7 ||
|
||||
strncmp(*start, "char", 4) != 0 ||
|
||||
(int)strspn(*start + 4, "0123456789") + 4 < *sz)
|
||||
break;
|
||||
c = 0;
|
||||
for (i = 4; i < *sz; i++)
|
||||
c = 10 * c + ((*start)[i] - '0');
|
||||
if (c < 0x21 || (c > 0x7e && c < 0xa0) || c > 0xff)
|
||||
break;
|
||||
*start += 4;
|
||||
*sz -= 4;
|
||||
gly = ESCAPE_NUMBERED;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unicode escapes are defined in groff as \[u0000]
|
||||
* to \[u10FFFF], where the contained value must be
|
||||
* a valid Unicode codepoint. Here, however, only
|
||||
* check the length and range.
|
||||
*/
|
||||
if (**start != 'u' || *sz < 5 || *sz > 7)
|
||||
break;
|
||||
if (*sz == 7 && ((*start)[1] != '1' || (*start)[2] != '0'))
|
||||
break;
|
||||
if (*sz == 6 && (*start)[1] == '0')
|
||||
break;
|
||||
if (*sz == 5 && (*start)[1] == 'D' &&
|
||||
strchr("89ABCDEF", (*start)[2]) != NULL)
|
||||
break;
|
||||
if ((int)strspn(*start + 1, "0123456789ABCDEFabcdef")
|
||||
+ 1 == *sz)
|
||||
gly = ESCAPE_UNICODE;
|
||||
break;
|
||||
case ESCAPE_DEVICE:
|
||||
assert(*sz == 2 && (*start)[0] == '.' && (*start)[1] == 'T');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return gly;
|
||||
}
|
||||
|
||||
static int
|
||||
a2time(time_t *t, const char *fmt, const char *p)
|
||||
{
|
||||
|
||||
+29
-22
@@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.css,v 1.48 2021/03/30 19:26:20 schwarze Exp $ */
|
||||
/* $Id: mandoc.css,v 1.52 2022/07/06 14:34:59 schwarze Exp $ */
|
||||
/*
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*
|
||||
@@ -16,7 +16,7 @@ html { max-width: 65em;
|
||||
body { background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: Helvetica,Arial,sans-serif; }
|
||||
h1 { font-size: 110%; }
|
||||
h1, h2 { font-size: 110%; }
|
||||
table { margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
border-collapse: collapse; }
|
||||
@@ -53,31 +53,39 @@ table.results { margin-top: 1em;
|
||||
|
||||
/* Header and footer lines. */
|
||||
|
||||
table.head { width: 100%;
|
||||
div[role=doc-pageheader] {
|
||||
display: flex;
|
||||
border-bottom: 1px dotted #808080;
|
||||
margin-bottom: 1em;
|
||||
font-size: smaller; }
|
||||
td.head-vol { text-align: center; }
|
||||
td.head-rtitle {
|
||||
.head-ltitle { flex: 1; }
|
||||
.head-vol { flex: 0 1 auto;
|
||||
text-align: center; }
|
||||
.head-rtitle { flex: 1;
|
||||
text-align: right; }
|
||||
|
||||
table.foot { width: 100%;
|
||||
div[role=doc-pagefooter] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-top: 1px dotted #808080;
|
||||
margin-top: 1em;
|
||||
font-size: smaller; }
|
||||
td.foot-os { text-align: right; }
|
||||
.foot-left { flex: 1; }
|
||||
.foot-date { flex: 0 1 auto;
|
||||
text-align: center; }
|
||||
.foot-os { flex: 1;
|
||||
text-align: right; }
|
||||
|
||||
/* Sections and paragraphs. */
|
||||
|
||||
.manual-text {
|
||||
margin-left: 3.8em; }
|
||||
main { margin-left: 3.8em; }
|
||||
.Nd { }
|
||||
section.Sh { }
|
||||
h1.Sh { margin-top: 1.2em;
|
||||
h2.Sh { margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: -3.2em; }
|
||||
section.Ss { }
|
||||
h2.Ss { margin-top: 1.2em;
|
||||
h3.Ss { margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: -1.2em;
|
||||
font-size: 105%; }
|
||||
@@ -195,7 +203,7 @@ code.Nm { font-style: normal;
|
||||
font-family: inherit; }
|
||||
.Ar { font-style: italic;
|
||||
font-weight: normal; }
|
||||
.Op { display: inline; }
|
||||
.Op { display: inline flow; }
|
||||
.Ic { font-style: normal;
|
||||
font-weight: bold;
|
||||
font-family: inherit; }
|
||||
@@ -250,7 +258,7 @@ a.In { }
|
||||
|
||||
/* Physical markup. */
|
||||
|
||||
.Bf { display: inline; }
|
||||
.Bf { display: inline flow; }
|
||||
.No { font-style: normal;
|
||||
font-weight: normal; }
|
||||
.Em { font-style: italic;
|
||||
@@ -263,11 +271,11 @@ a.In { }
|
||||
|
||||
/* Tooltip support. */
|
||||
|
||||
h1.Sh, h2.Ss { position: relative; }
|
||||
h2.Sh, h3.Ss { position: relative; }
|
||||
.An, .Ar, .Cd, .Cm, .Dv, .Em, .Er, .Ev, .Fa, .Fd, .Fl, .Fn, .Ft,
|
||||
.Ic, code.In, .Lb, .Lk, .Ms, .Mt, .Nd, code.Nm, .Pa, .Rs,
|
||||
.St, .Sx, .Sy, .Va, .Vt, .Xr {
|
||||
display: inline-block;
|
||||
display: inline flow;
|
||||
position: relative; }
|
||||
|
||||
.An::before { content: "An"; }
|
||||
@@ -293,8 +301,8 @@ code.In::before { content: "In"; }
|
||||
code.Nm::before { content: "Nm"; }
|
||||
.Pa::before { content: "Pa"; }
|
||||
.Rs::before { content: "Rs"; }
|
||||
h1.Sh::before { content: "Sh"; }
|
||||
h2.Ss::before { content: "Ss"; }
|
||||
h2.Sh::before { content: "Sh"; }
|
||||
h3.Ss::before { content: "Ss"; }
|
||||
.St::before { content: "St"; }
|
||||
.Sx::before { content: "Sx"; }
|
||||
.Sy::before { content: "Sy"; }
|
||||
@@ -308,7 +316,7 @@ h2.Ss::before { content: "Ss"; }
|
||||
.Ic::before, code.In::before, .Lb::before, .Lk::before,
|
||||
.Ms::before, .Mt::before, .Nd::before, code.Nm::before,
|
||||
.Pa::before, .Rs::before,
|
||||
h1.Sh::before, h2.Ss::before, .St::before, .Sx::before, .Sy::before,
|
||||
h2.Sh::before, h3.Ss::before, .St::before, .Sx::before, .Sy::before,
|
||||
.Va::before, .Vt::before, .Xr::before {
|
||||
opacity: 0;
|
||||
transition: .15s ease opacity;
|
||||
@@ -329,7 +337,7 @@ h1.Sh::before, h2.Ss::before, .St::before, .Sx::before, .Sy::before,
|
||||
.Ft:hover::before, .Ic:hover::before, code.In:hover::before,
|
||||
.Lb:hover::before, .Lk:hover::before, .Ms:hover::before, .Mt:hover::before,
|
||||
.Nd:hover::before, code.Nm:hover::before, .Pa:hover::before,
|
||||
.Rs:hover::before, h1.Sh:hover::before, h2.Ss:hover::before, .St:hover::before,
|
||||
.Rs:hover::before, h2.Sh:hover::before, h3.Ss:hover::before, .St:hover::before,
|
||||
.Sx:hover::before, .Sy:hover::before, .Va:hover::before, .Vt:hover::before,
|
||||
.Xr:hover::before {
|
||||
opacity: 1;
|
||||
@@ -338,9 +346,8 @@ h1.Sh::before, h2.Ss::before, .St::before, .Sx::before, .Sy::before,
|
||||
/* Overrides to avoid excessive margins on small devices. */
|
||||
|
||||
@media (max-width: 37.5em) {
|
||||
.manual-text {
|
||||
margin-left: 0.5em; }
|
||||
h1.Sh, h2.Ss { margin-left: 0em; }
|
||||
main { margin-left: 0.5em; }
|
||||
h2.Sh, h3.Ss { margin-left: 0em; }
|
||||
.Bd-indent { margin-left: 2em; }
|
||||
.Bl-hang > dd {
|
||||
margin-left: 2em; }
|
||||
|
||||
+22
-10
@@ -1,6 +1,6 @@
|
||||
/* $Id: mandoc.h,v 1.274 2021/08/14 13:53:08 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.282 2023/10/21 17:10:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012-2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -20,8 +20,10 @@
|
||||
*/
|
||||
|
||||
#define ASCII_NBRSP 31 /* non-breaking space */
|
||||
#define ASCII_HYPH 30 /* breakable hyphen */
|
||||
#define ASCII_BREAK 29 /* breakable zero-width space */
|
||||
#define ASCII_NBRZW 30 /* non-breaking zero-width space */
|
||||
#define ASCII_BREAK 29 /* breakable zero-width space */
|
||||
#define ASCII_HYPH 28 /* breakable hyphen */
|
||||
#define ASCII_TABREF 26 /* reset tab reference position */
|
||||
|
||||
/*
|
||||
* Status level. This refers to both internal status (i.e., whilst
|
||||
@@ -165,13 +167,14 @@ enum mandocerr {
|
||||
MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */
|
||||
MANDOCERR_CHAR_FONT, /* argument contains two font escapes */
|
||||
MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */
|
||||
MANDOCERR_MC_DIST, /* ignoring distance argument: mc ... arg */
|
||||
MANDOCERR_TR_ODD, /* odd number of characters in request: tr char */
|
||||
|
||||
/* related to plain text */
|
||||
MANDOCERR_FI_BLANK, /* blank line in fill mode, using .sp */
|
||||
MANDOCERR_FI_TAB, /* tab in filled text */
|
||||
MANDOCERR_EOS, /* new sentence, new line */
|
||||
MANDOCERR_ESC_BAD, /* invalid escape sequence: esc */
|
||||
MANDOCERR_ESC_ARG, /* invalid escape sequence argument: esc */
|
||||
MANDOCERR_ESC_UNDEF, /* undefined escape, printing literally: char */
|
||||
MANDOCERR_STR_UNDEF, /* undefined string, using "": name */
|
||||
|
||||
@@ -215,11 +218,13 @@ enum mandocerr {
|
||||
MANDOCERR_NAMESC, /* escaped character not allowed in a name: name */
|
||||
MANDOCERR_ARG_UNDEF, /* using macro argument outside macro */
|
||||
MANDOCERR_ARG_NONUM, /* argument number is not numeric */
|
||||
MANDOCERR_ARG_NEG, /* negative argument, using 0: request arg */
|
||||
MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
|
||||
MANDOCERR_BD_NOARG, /* skipping display without arguments: Bd */
|
||||
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
|
||||
MANDOCERR_CE_NONUM, /* argument is not numeric, using 1: ce ... */
|
||||
MANDOCERR_CHAR_ARG, /* argument is not a character: char ... */
|
||||
MANDOCERR_MC_ESC, /* skipping unusable escape sequence: mc arg */
|
||||
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
|
||||
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
|
||||
MANDOCERR_ST_BAD, /* unknown standard specifier: St standard */
|
||||
@@ -232,6 +237,12 @@ enum mandocerr {
|
||||
MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */
|
||||
MANDOCERR_DIVZERO, /* divide by zero */
|
||||
|
||||
/* related to escape sequences */
|
||||
MANDOCERR_ESC_INCOMPLETE, /* incomplete escape sequence: esc */
|
||||
MANDOCERR_ESC_BADCHAR, /* invalid special character: esc */
|
||||
MANDOCERR_ESC_UNKCHAR, /* unknown special character: esc */
|
||||
MANDOCERR_ESC_DELIM, /* invalid escape argument delimiter: esc */
|
||||
|
||||
MANDOCERR_UNSUPP, /* ===== start of unsupported features ===== */
|
||||
|
||||
MANDOCERR_TOOLARGE, /* input too large */
|
||||
@@ -282,11 +293,12 @@ enum mandocerr {
|
||||
};
|
||||
|
||||
enum mandoc_esc {
|
||||
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
||||
ESCAPE_UNSUPP, /* unsupported escape; ignore it */
|
||||
ESCAPE_IGNORE, /* escape to be ignored */
|
||||
ESCAPE_UNDEF, /* undefined escape; print literal character */
|
||||
ESCAPE_SPECIAL, /* a regular special character */
|
||||
ESCAPE_EXPAND = 0, /* interpolation and iterative call needed */
|
||||
ESCAPE_ERROR, /* non-fatal error: unparsable escape */
|
||||
ESCAPE_UNSUPP, /* unsupported escape: warn and ignore */
|
||||
ESCAPE_IGNORE, /* valid escape to be ignored */
|
||||
ESCAPE_UNDEF, /* undefined escape: print literal character */
|
||||
ESCAPE_SPECIAL, /* special character escape */
|
||||
ESCAPE_FONT, /* a generic font mode */
|
||||
ESCAPE_FONTBOLD, /* bold font mode */
|
||||
ESCAPE_FONTITALIC, /* italic font mode */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc_aux.c,v 1.11 2018/02/07 20:04:57 schwarze Exp $ */
|
||||
/* $Id: mandoc_aux.c,v 1.12 2022/04/14 16:43:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DEBUG_NODEF 1
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_aux.h"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc_aux.h,v 1.7 2017/06/12 19:05:47 schwarze Exp $ */
|
||||
/* $Id: mandoc_aux.h,v 1.8 2022/04/14 16:43:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2017, 2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -25,3 +25,7 @@ void *mandoc_reallocarray(void *, size_t, size_t);
|
||||
void *mandoc_recallocarray(void *, size_t, size_t, size_t);
|
||||
char *mandoc_strdup(const char *);
|
||||
char *mandoc_strndup(const char *, size_t);
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
.\" $Id: mandoc_char.7,v 1.78 2020/10/31 11:45:16 schwarze Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.79 2022/06/02 14:51:41 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <[email protected]>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <[email protected]>
|
||||
.\" Copyright (c) 2011,2013,2015,2017-2020 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2011, 2013, 2015, 2017-2020, 2022
|
||||
.\" Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
.\" 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 +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: October 31 2020 $
|
||||
.Dd $Mdocdate: June 2 2022 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -220,13 +221,18 @@ where it introduces a
|
||||
request or a macro, and when appearing alone as a macro argument in
|
||||
.Xr mdoc 7 .
|
||||
In such situations, prepend a zero-width space
|
||||
.Pq Sq \e&.
|
||||
.Pq Sq \e&.\&
|
||||
to make it behave like normal text.
|
||||
.Pp
|
||||
Do not use the
|
||||
Do not use the character pair
|
||||
.Sq \e.
|
||||
escape sequence.
|
||||
It does not prevent special handling of the period.
|
||||
to escape a period because
|
||||
.Sq \e.
|
||||
is not a character escape sequence, does not prevent special handling
|
||||
of the period under normal circumstances, and is only intended to
|
||||
be used in the very special situation of defining a user-defined
|
||||
macro that, when called, defines another user-defined macro, which
|
||||
no manual page is ever supposed to do.
|
||||
.Ss Backslashes
|
||||
To include a literal backslash
|
||||
.Pq Sq \e
|
||||
@@ -326,7 +332,6 @@ Punctuation:
|
||||
.It \e(en Ta \(en Ta en-dash
|
||||
.It \e(hy Ta \(hy Ta hyphen
|
||||
.It \ee Ta \e Ta back-slash
|
||||
.It \e. Ta \. Ta period
|
||||
.It \e(r! Ta \(r! Ta upside-down exclamation
|
||||
.It \e(r? Ta \(r? Ta upside-down question
|
||||
.El
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
/* $Id: mandoc_dbg.c,v 1.1 2022/04/14 16:43:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2021, 2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_OHASH
|
||||
#include <ohash.h>
|
||||
#else
|
||||
#include "compat_ohash.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG_NODEF 1
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_dbg.h"
|
||||
#include "mandoc.h"
|
||||
|
||||
/* Store information about one allocation. */
|
||||
struct dhash_entry {
|
||||
const char *file;
|
||||
int line;
|
||||
const char *func;
|
||||
size_t num;
|
||||
size_t size;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
/* Store information about all allocations. */
|
||||
static struct ohash dhash_table;
|
||||
static FILE *dhash_fp;
|
||||
static int dhash_aflag;
|
||||
static int dhash_fflag;
|
||||
static int dhash_lflag;
|
||||
static int dhash_nflag;
|
||||
static int dhash_sflag;
|
||||
|
||||
static void *dhash_alloc(size_t, void *);
|
||||
static void *dhash_calloc(size_t, size_t, void *);
|
||||
static void dhash_free(void *, void *);
|
||||
static unsigned int dhash_slot(void *);
|
||||
static void dhash_register(const char *, int, const char *,
|
||||
size_t, size_t, void *, const char *);
|
||||
static void dhash_print(struct dhash_entry *);
|
||||
static void dhash_purge(const char *, int, const char *, void *);
|
||||
|
||||
|
||||
/* *** Debugging wrappers of public API functions. ************************ */
|
||||
|
||||
int
|
||||
mandoc_dbg_asprintf(const char *file, int line,
|
||||
char **dest, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vasprintf(dest, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, NULL);
|
||||
|
||||
dhash_register(file, line, "asprintf", 1, strlen(*dest) + 1,
|
||||
*dest, *dest);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_dbg_calloc(size_t num, size_t size, const char *file, int line)
|
||||
{
|
||||
void *ptr = mandoc_calloc(num, size);
|
||||
dhash_register(file, line, "calloc", num, size, ptr, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_dbg_malloc(size_t size, const char *file, int line)
|
||||
{
|
||||
void *ptr = mandoc_malloc(size);
|
||||
dhash_register(file, line, "malloc", 1, size, ptr, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_dbg_realloc(void *ptr, size_t size, const char *file, int line)
|
||||
{
|
||||
dhash_purge(file, line, "realloc", ptr);
|
||||
ptr = mandoc_realloc(ptr, size);
|
||||
dhash_register(file, line, "realloc", 1, size, ptr, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_dbg_reallocarray(void *ptr, size_t num, size_t size,
|
||||
const char *file, int line)
|
||||
{
|
||||
dhash_purge(file, line, "reallocarray", ptr);
|
||||
ptr = mandoc_reallocarray(ptr, num, size);
|
||||
dhash_register(file, line, "reallocarray", num, size, ptr, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_dbg_recallocarray(void *ptr, size_t oldnum, size_t num, size_t size,
|
||||
const char *file, int line)
|
||||
{
|
||||
dhash_purge(file, line, "recallocarray", ptr);
|
||||
ptr = mandoc_recallocarray(ptr, oldnum, num, size);
|
||||
dhash_register(file, line, "recallocarray", num, size, ptr, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_dbg_strdup(const char *ptr, const char *file, int line)
|
||||
{
|
||||
char *p = mandoc_strdup(ptr);
|
||||
dhash_register(file, line, "strdup", 1, strlen(p) + 1, p, ptr);
|
||||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_dbg_strndup(const char *ptr, size_t sz, const char *file, int line)
|
||||
{
|
||||
char *p = mandoc_strndup(ptr, sz);
|
||||
dhash_register(file, line, "strndup", 1, strlen(p) + 1, p, NULL);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_dbg_free(void *ptr, const char *file, int line)
|
||||
{
|
||||
dhash_purge(file, line, "free", ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
/* *** Memory allocation callbacks for the debugging table. *************** */
|
||||
|
||||
static void *
|
||||
dhash_alloc(size_t sz, void *arg)
|
||||
{
|
||||
return malloc(sz);
|
||||
}
|
||||
|
||||
static void *
|
||||
dhash_calloc(size_t n, size_t sz, void *arg)
|
||||
{
|
||||
return calloc(n, sz);
|
||||
}
|
||||
|
||||
static void
|
||||
dhash_free(void *p, void *arg)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
/* *** Debugging utility functions. *************************************** */
|
||||
|
||||
/* Initialize the debugging table, to be called from the top of main(). */
|
||||
void
|
||||
mandoc_dbg_init(int argc, char *argv[])
|
||||
{
|
||||
struct ohash_info info;
|
||||
char *dhash_fn;
|
||||
int argi;
|
||||
|
||||
info.alloc = dhash_alloc;
|
||||
info.calloc = dhash_calloc;
|
||||
info.free = dhash_free;
|
||||
info.data = NULL;
|
||||
info.key_offset = offsetof(struct dhash_entry, ptr);
|
||||
ohash_init(&dhash_table, 18, &info);
|
||||
|
||||
dhash_fp = stderr;
|
||||
if ((dhash_fn = getenv("DEBUG_MEMORY")) == NULL)
|
||||
return;
|
||||
|
||||
dhash_sflag = 1;
|
||||
for(;; dhash_fn++) {
|
||||
switch (*dhash_fn) {
|
||||
case '\0':
|
||||
break;
|
||||
case 'A':
|
||||
dhash_aflag = 1;
|
||||
continue;
|
||||
case 'F':
|
||||
dhash_fflag = 1;
|
||||
continue;
|
||||
case 'L':
|
||||
dhash_lflag = 1;
|
||||
continue;
|
||||
case 'N':
|
||||
dhash_nflag = 1;
|
||||
continue;
|
||||
case '/':
|
||||
if ((dhash_fp = fopen(dhash_fn, "a+e")) == NULL)
|
||||
err((int)MANDOCLEVEL_SYSERR, "%s", dhash_fn);
|
||||
break;
|
||||
default:
|
||||
errx((int)MANDOCLEVEL_BADARG,
|
||||
"invalid char '%c' in $DEBUG_MEMORY",
|
||||
*dhash_fn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (setvbuf(dhash_fp, NULL, _IOLBF, 0) != 0)
|
||||
err((int)MANDOCLEVEL_SYSERR, "setvbuf");
|
||||
|
||||
fprintf(dhash_fp, "P %d", getpid());
|
||||
for (argi = 0; argi < argc; argi++)
|
||||
fprintf(dhash_fp, " [%s]", argv[argi]);
|
||||
fprintf(dhash_fp, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_dbg_name(const char *name)
|
||||
{
|
||||
if (dhash_nflag)
|
||||
fprintf(dhash_fp, "N %s\n", name);
|
||||
}
|
||||
|
||||
/* Hash a pointer and return the table slot currently used for it. */
|
||||
static unsigned int
|
||||
dhash_slot(void *ptr)
|
||||
{
|
||||
const char *ks, *ke;
|
||||
uint32_t hv;
|
||||
|
||||
ks = (const char *)&ptr;
|
||||
ke = ks + sizeof(ptr);
|
||||
hv = ohash_interval(ks, &ke);
|
||||
return ohash_lookup_memory(&dhash_table, ks, sizeof(ptr), hv);
|
||||
}
|
||||
|
||||
/* Record one allocation in the debugging table. */
|
||||
static void
|
||||
dhash_register(const char *file, int line, const char *func,
|
||||
size_t num, size_t size, void *ptr, const char *str)
|
||||
{
|
||||
struct dhash_entry *e;
|
||||
unsigned int slot;
|
||||
|
||||
slot = dhash_slot(ptr);
|
||||
e = ohash_find(&dhash_table, slot);
|
||||
if (dhash_aflag || e != NULL) {
|
||||
fprintf(dhash_fp, "A %s:%d %s(%zu, %zu) = %p",
|
||||
file, line, func, num, size, ptr);
|
||||
if (str != NULL)
|
||||
fprintf(dhash_fp, " \"%s\"", str);
|
||||
fprintf(dhash_fp, "\n");
|
||||
}
|
||||
if (e != NULL) {
|
||||
dhash_print(e);
|
||||
fprintf(dhash_fp, "E duplicate address %p\n", e->ptr);
|
||||
errx((int)MANDOCLEVEL_BADARG, "duplicate address %p", e->ptr);
|
||||
}
|
||||
|
||||
if ((e = malloc(sizeof(*e))) == NULL)
|
||||
err(1, NULL);
|
||||
e->file = file;
|
||||
e->line = line;
|
||||
e->func = func;
|
||||
e->num = num;
|
||||
e->size = size;
|
||||
e->ptr = ptr;
|
||||
|
||||
ohash_insert(&dhash_table, slot, e);
|
||||
}
|
||||
|
||||
/* Remove one allocation from the debugging table. */
|
||||
static void
|
||||
dhash_purge(const char *file, int line, const char *func, void *ptr)
|
||||
{
|
||||
struct dhash_entry *e;
|
||||
unsigned int slot;
|
||||
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
if (dhash_fflag)
|
||||
fprintf(dhash_fp, "F %s:%d %s(%p)\n", file, line, func, ptr);
|
||||
|
||||
slot = dhash_slot(ptr);
|
||||
e = ohash_remove(&dhash_table, slot);
|
||||
free(e);
|
||||
}
|
||||
|
||||
/* Pretty-print information about one allocation. */
|
||||
static void
|
||||
dhash_print(struct dhash_entry *e)
|
||||
{
|
||||
fprintf(dhash_fp, "L %s:%d %s(%zu, %zu) = %p\n",
|
||||
e->file, e->line, e->func, e->num, e->size, e->ptr);
|
||||
}
|
||||
|
||||
/* Pretty-print information about all active allocations. */
|
||||
void
|
||||
mandoc_dbg_finish(void)
|
||||
{
|
||||
struct dhash_entry *e;
|
||||
unsigned int errcount, slot;
|
||||
|
||||
errcount = ohash_entries(&dhash_table);
|
||||
e = ohash_first(&dhash_table, &slot);
|
||||
while (e != NULL) {
|
||||
if (dhash_lflag)
|
||||
dhash_print(e);
|
||||
free(e);
|
||||
e = ohash_next(&dhash_table, &slot);
|
||||
}
|
||||
ohash_delete(&dhash_table);
|
||||
if (dhash_sflag)
|
||||
fprintf(dhash_fp, "S %u memory leaks found\n", errcount);
|
||||
if (dhash_fp != stderr)
|
||||
fclose(dhash_fp);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* $Id: mandoc_dbg.h,v 1.1 2022/04/14 16:43:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
int mandoc_dbg_asprintf(const char *, int, char **, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 4, 5)));
|
||||
void *mandoc_dbg_calloc(size_t, size_t, const char *, int);
|
||||
void *mandoc_dbg_malloc(size_t, const char *, int);
|
||||
void *mandoc_dbg_realloc(void *, size_t, const char *, int);
|
||||
void *mandoc_dbg_reallocarray(void *, size_t, size_t,
|
||||
const char *, int);
|
||||
void *mandoc_dbg_recallocarray(void *, size_t, size_t, size_t,
|
||||
const char *, int);
|
||||
char *mandoc_dbg_strdup(const char *, const char *, int);
|
||||
char *mandoc_dbg_strndup(const char *, size_t, const char *, int);
|
||||
void mandoc_dbg_free(void *, const char *, int);
|
||||
|
||||
void mandoc_dbg_init(int argc, char *argv[]);
|
||||
void mandoc_dbg_name(const char *);
|
||||
void mandoc_dbg_finish(void);
|
||||
|
||||
#ifndef DEBUG_NODEF
|
||||
#define mandoc_asprintf(dest, fmt, ...) \
|
||||
mandoc_dbg_asprintf(__FILE__, __LINE__, (dest), (fmt), __VA_ARGS__)
|
||||
#define mandoc_calloc(num, size) \
|
||||
mandoc_dbg_calloc((num), (size), __FILE__, __LINE__)
|
||||
#define mandoc_malloc(size) \
|
||||
mandoc_dbg_malloc((size), __FILE__, __LINE__)
|
||||
#define mandoc_realloc(ptr, size) \
|
||||
mandoc_dbg_realloc((ptr), (size), __FILE__, __LINE__)
|
||||
#define mandoc_reallocarray(ptr, num, size) \
|
||||
mandoc_dbg_reallocarray((ptr), (num), (size), __FILE__, __LINE__)
|
||||
#define mandoc_recallocarray(ptr, old, num, size) \
|
||||
mandoc_dbg_recallocarray((ptr), (old), (num), (size), \
|
||||
__FILE__, __LINE__)
|
||||
#define mandoc_strdup(ptr) \
|
||||
mandoc_dbg_strdup((ptr), __FILE__, __LINE__)
|
||||
#define mandoc_strndup(ptr, size) \
|
||||
mandoc_dbg_strndup((ptr), (size), __FILE__, __LINE__)
|
||||
#define free(ptr) \
|
||||
mandoc_dbg_free((ptr), __FILE__, __LINE__)
|
||||
#endif
|
||||
@@ -0,0 +1,280 @@
|
||||
.\" $Id: mandoc_dbg_init.3,v 1.1 2022/04/14 16:43:44 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2021, 2022 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: April 14 2022 $
|
||||
.Dt MANDOC_DBG_INIT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc_dbg_init ,
|
||||
.Nm mandoc_dbg_name ,
|
||||
.Nm mandoc_dbg_finish
|
||||
.Nd search for memory leaks in mandoc
|
||||
.Sh SYNOPSIS
|
||||
.Ft void
|
||||
.Fn mandoc_dbg_init "int argc" "char *argv[]"
|
||||
.Ft void
|
||||
.Fn mandoc_dbg_name "const char *"
|
||||
.Ft void
|
||||
.Fn mandoc_dbg_finish void
|
||||
.Sh DESCRIPTION
|
||||
If the mandoc package is built with the line
|
||||
.Ql DEBUG_MEMORY=1
|
||||
in the file
|
||||
.Pa configure.local ,
|
||||
the functions documented in
|
||||
.Xr mandoc_malloc 3
|
||||
and the function
|
||||
.Xr free 3
|
||||
are instrumented to record every memory allocation in a dedicated
|
||||
hash table and to check that every allocation is freed again.
|
||||
This compile time option is only intended for binaries that are
|
||||
used exclusively for debugging.
|
||||
It is not intended for production binaries because it significantly
|
||||
increases run time and memory usage and makes the programs more
|
||||
fragile and more error-prone.
|
||||
.Pp
|
||||
The function
|
||||
.Fn mandoc_dbg_init
|
||||
initializes the memory debugging subsystem.
|
||||
It is called from the top of the
|
||||
.Fn main
|
||||
programs, passing through the arguments that
|
||||
.Fn main
|
||||
received.
|
||||
The
|
||||
.Sx ENVIRONMENT
|
||||
section of the present manual page explains how the
|
||||
.Ev DEBUG_MEMORY
|
||||
environment variable controls the amount and destination of reporting.
|
||||
.Pp
|
||||
The function
|
||||
.Fn mandoc_dbg_name
|
||||
is called from the
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
parsers whenever a
|
||||
.Ic \&Dt
|
||||
or
|
||||
.Ic \&TH
|
||||
macro is parsed, passing the complete macro line as the argument.
|
||||
.Pp
|
||||
The function
|
||||
.Fn mandoc_dbg_finish
|
||||
performs cleanup and optionally final reporting.
|
||||
It is called from the end of the
|
||||
.Fn main
|
||||
programs, just before normal termination.
|
||||
.Pp
|
||||
Getting the
|
||||
.Sy #include
|
||||
directives right for these functions is slightly tricky.
|
||||
If a file already includes
|
||||
.Qq Pa mandoc_aux.h ,
|
||||
no additional directive is needed because
|
||||
.Qq Pa mandoc_aux.h
|
||||
already includes
|
||||
.Qq Pa mandoc_dgb.h
|
||||
if
|
||||
.Ql DEBUG_MEMORY=1
|
||||
is set in
|
||||
.Pa configure.local .
|
||||
.Pp
|
||||
If a file does not need
|
||||
.Qq Pa mandoc_aux.h
|
||||
but calls a function documented in the present manual page and also calls
|
||||
.Xr free 3
|
||||
directly, it needs this code before the other
|
||||
.Xr mandoc_headers 3 :
|
||||
.Bd -literal -offset indent
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
.Ed
|
||||
.Pp
|
||||
If a file calls a function documented in the present manual page
|
||||
but does not directly call
|
||||
.Xr free 3 ,
|
||||
it can use this less intrusive idiom:
|
||||
.Bd -literal -offset indent
|
||||
#if DEBUG_MEMORY
|
||||
#define DEBUG_NODEF
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
.Ed
|
||||
.Sh ENVIRONMENT
|
||||
The environment variable
|
||||
.Ev DEBUG_MEMORY
|
||||
controls the amount and destination of reporting.
|
||||
.Pp
|
||||
If it is unset, diagnostic output is directed to standard error output
|
||||
and only fatal errors are reported.
|
||||
Even though full memory accounting is always performed
|
||||
by any binary that was compiled with
|
||||
.Ql DEBUG_MEMORY=1 ,
|
||||
resulting in a significant increase in both run time and memory usage,
|
||||
memory leaks are
|
||||
.Em not
|
||||
reported when
|
||||
.Ev DEBUG_MEMORY
|
||||
is not set at run time.
|
||||
.Pp
|
||||
If
|
||||
.Ev DEBUG_MEMORY
|
||||
is set, it is interpreted as a string of flags.
|
||||
The flags are as follows:
|
||||
.Bl -tag -width 1n
|
||||
.It Cm A
|
||||
Log every allocation.
|
||||
This produces huge amounts of output and is usually not needed
|
||||
to find memory leaks.
|
||||
Its main purpose is debugging the memory debugging subsystem itself.
|
||||
.Pp
|
||||
When enabled, allocations are logged in this format:
|
||||
.Pp
|
||||
.D1 Cm A Ar file Ns .c: Ns Ar line function Ns Po Fa nmemb , size Pc\
|
||||
No = Ar address
|
||||
.Pp
|
||||
The meaning of the fields is the same as for the
|
||||
.Cm L
|
||||
option.
|
||||
.It Cm F
|
||||
Log every
|
||||
.Xr free 3
|
||||
and every reallocation where the memory to be released or reallocated
|
||||
was allocated with one of the functions documented in
|
||||
.Xr mandoc_malloc 3 .
|
||||
Again, this produces huge amounts of output and is usually not
|
||||
needed to find memory leaks, and its main purpose is debugging the
|
||||
memory debugging subsystem itself.
|
||||
.Pp
|
||||
The logging format is:
|
||||
.Pp
|
||||
.D1 Cm F Ar file Ns .c: Ns Ar line function Ns Pq address
|
||||
.Pp
|
||||
It provides the name of the
|
||||
.Ar file
|
||||
and the number of the
|
||||
.Ar line
|
||||
in that file which called the
|
||||
.Xr free 3
|
||||
or reallocation
|
||||
.Ar function ,
|
||||
and the
|
||||
.Fa address
|
||||
that was given as an argument.
|
||||
.Pp
|
||||
If both the
|
||||
.Cm A
|
||||
and the
|
||||
.Cm F
|
||||
flags are enabled, calls to reallocation functions often log two lines,
|
||||
first an
|
||||
.Cm F
|
||||
line reporting the address passed in as an argument, then an
|
||||
.Cm A
|
||||
line reporting the adress returned as the function return value.
|
||||
.It Cm L
|
||||
Log every memory leak.
|
||||
For every allocation made after
|
||||
.Fn mandoc_dbg_init
|
||||
using functions documented in
|
||||
.Xr mandoc_malloc 3
|
||||
that was not freed before
|
||||
.Fn mandoc_dbg_finish ,
|
||||
print a line in this format:
|
||||
.Pp
|
||||
.D1 Cm L Ar file Ns .c: Ns Ar line function Ns Po Fa nmemb , size Pc\
|
||||
No = Ar address
|
||||
.Pp
|
||||
It provides the name of the
|
||||
.Ar file
|
||||
and the number of the
|
||||
.Ar line
|
||||
in that file which called the allocation
|
||||
.Ar function
|
||||
with the arguments
|
||||
.Fa nmemb
|
||||
and
|
||||
.Fa size
|
||||
documented for
|
||||
.Xr calloc 3 .
|
||||
If the
|
||||
.Ar function
|
||||
does not take an
|
||||
.Fa nmemb
|
||||
argument,
|
||||
.Fa nmemb
|
||||
is reported as 1.
|
||||
At the end of the line, the virtual
|
||||
.Ar address
|
||||
of the memory returned from the allocation function is reported.
|
||||
.It Cm N
|
||||
Log the names of manual pages processed in the following formats:
|
||||
.Bd -unfilled -offset indent
|
||||
.Cm N Pf . Ic \&Dt Ar name section Op Ar architecture
|
||||
.Cm N Pf . Ic \&TH Ar name section Op Ar additional arguments
|
||||
.Ed
|
||||
.Pp
|
||||
This is particularly useful if a program crashes, runs out of memory,
|
||||
or enters an infinite loop.
|
||||
The last
|
||||
.Cm N
|
||||
line logged often indicates the input file triggering the problem.
|
||||
.It Cm /
|
||||
Interpret the rest of
|
||||
.Ev DEBUG_MEMORY
|
||||
as an absolute path and redirect debugging output to that file,
|
||||
appending to the file if it already exists or creating it otherwise.
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
.Ev DEBUG_MEMORY
|
||||
is set, even if it is empty,
|
||||
.Fn mandoc_dbg_init
|
||||
always writes the line
|
||||
.Pp
|
||||
.D1 Cm P Ar pid Sy \&[ Ns Ar progname Ns Sy \&]\
|
||||
Sy \&[ Ns Ar argument Ns Sy \&] Ar ...
|
||||
.Pp
|
||||
enclosing each element of
|
||||
.Fa argv
|
||||
in square brackets, to avoid that arguments containing whitespace
|
||||
appear in the same way as multiple arguments, and
|
||||
.Fn mandoc_dbg_finish
|
||||
always writes the line:
|
||||
.Pp
|
||||
.D1 Cm S Ar number No memory leaks found
|
||||
.Sh EXAMPLES
|
||||
The following is a typical sequence of commands for finding memory
|
||||
leaks in the parsers, in the HTML formatter, and in the regression suite:
|
||||
.Bd -literal -offset indent
|
||||
make distclean
|
||||
echo BUILD_CATMAN=1 >> configure.local
|
||||
echo DEBUG_MEMORY=1 >> configure.local
|
||||
\&./configure
|
||||
make
|
||||
export DEBUG_MEMORY=NL/tmp/mandoc.debug.txt
|
||||
mkdir Out
|
||||
export PATH=$PATH:$(pwd)
|
||||
\&./catman -T html /usr/share/man Out
|
||||
make regress-clean
|
||||
make regress
|
||||
less /tmp/mandoc.debug.txt
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc_malloc 3 ,
|
||||
.Xr catman 8
|
||||
+108
-64
@@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_escape.3,v 1.4 2017/07/04 23:40:01 schwarze Exp $
|
||||
.\" $Id: mandoc_escape.3,v 1.6 2023/10/23 14:46:22 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
@@ -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 4 2017 $
|
||||
.Dd $Mdocdate: October 23 2023 $
|
||||
.Dt MANDOC_ESCAPE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -80,12 +80,12 @@ that can be used as quoting characters.
|
||||
.El
|
||||
.Pp
|
||||
Upon function entry,
|
||||
.Fa end
|
||||
.Pf * Fa end
|
||||
is expected to point to the escape sequence identifier.
|
||||
The values passed in as
|
||||
.Fa start
|
||||
.Pf * Fa start
|
||||
and
|
||||
.Fa sz
|
||||
.Pf * Fa sz
|
||||
are ignored and overwritten.
|
||||
.Pp
|
||||
By design, this function cannot handle those
|
||||
@@ -100,9 +100,11 @@ width measurements
|
||||
and numerical expression control
|
||||
.Ic \eB .
|
||||
These are handled by
|
||||
.Fn roff_res ,
|
||||
.Fn roff_expand ,
|
||||
a private preprocessor function called from
|
||||
.Fn roff_parseln ,
|
||||
.Fn roff_parseln
|
||||
and
|
||||
.Fn roff_getarg ,
|
||||
see the file
|
||||
.Pa roff.c .
|
||||
.Pp
|
||||
@@ -114,13 +116,22 @@ is used
|
||||
recursively by itself, because some escape sequence arguments can
|
||||
in turn contain other escape sequences,
|
||||
.It
|
||||
for error detection internally by the
|
||||
for parsing and error detection internally by the
|
||||
.Xr roff 7
|
||||
parser part of the
|
||||
.Xr mandoc 3
|
||||
library, see the file
|
||||
.Pa roff.c ,
|
||||
.It
|
||||
occasionally by high-level parser and validation modules when they
|
||||
need to skip escape sequences while scanning the input, see the files
|
||||
.Pa mdoc.c ,
|
||||
.Pa man.c ,
|
||||
.Pa man_validate.c ,
|
||||
.Pa eqn.c ,
|
||||
and
|
||||
.Pa tbl_data.c
|
||||
.It
|
||||
above all externally by the
|
||||
.Xr mandoc 1
|
||||
formatting modules, in particular
|
||||
@@ -139,19 +150,19 @@ to purge escape sequences from text.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
Upon function return, the pointer
|
||||
.Fa end
|
||||
.Pf * Fa end
|
||||
is set to the character after the end of the escape sequence,
|
||||
such that the calling higher-level parser can easily continue.
|
||||
.Pp
|
||||
For escape sequences taking an argument, the pointer
|
||||
.Fa start
|
||||
.Pf * Fa start
|
||||
is set to the beginning of the argument and
|
||||
.Fa sz
|
||||
.Pf * Fa sz
|
||||
is set to the length of the argument.
|
||||
For escape sequences not taking an argument,
|
||||
.Fa start
|
||||
.Pf * Fa start
|
||||
is set to the character after the end of the sequence and
|
||||
.Fa sz
|
||||
.Pf * Fa sz
|
||||
is set to 0.
|
||||
Both
|
||||
.Fa start
|
||||
@@ -165,6 +176,11 @@ For sequences taking an argument, the function
|
||||
.Fn mandoc_escape
|
||||
returns one of the following values:
|
||||
.Bl -tag -width 2n
|
||||
.It Dv ESCAPE_DEVICE
|
||||
The escape sequence
|
||||
.Ic \e*(.T
|
||||
or
|
||||
.Ic \e*[.T] .
|
||||
.It Dv ESCAPE_FONT
|
||||
The escape sequence
|
||||
.Ic \ef
|
||||
@@ -183,6 +199,33 @@ More specific values are returned for the most commonly used arguments:
|
||||
.It Cm P Ta Dv ESCAPE_FONTPREV
|
||||
.It Cm BI Ta Dv ESCAPE_FONTBI
|
||||
.El
|
||||
.It Dv ESCAPE_HLINE
|
||||
The escape sequence
|
||||
.Ic \eh
|
||||
followed by an argument delimited by an arbitrary character.
|
||||
.It Dv ESCAPE_HORIZ
|
||||
The escape sequence
|
||||
.Ic \el
|
||||
followed by an argument delimited by an arbitrary character.
|
||||
.It Dv ESCAPE_NUMBERED
|
||||
The escape sequence
|
||||
.Ic \eN
|
||||
followed by a delimited argument.
|
||||
The delimiter character is arbitrary except that digits cannot be used.
|
||||
If a digit is encountered instead of the opening delimiter, that
|
||||
digit is considered to be the argument and the end of the sequence, and
|
||||
.Dv ESCAPE_IGNORE
|
||||
is returned.
|
||||
.Pp
|
||||
Such ASCII character escape sequences can be rendered using the function
|
||||
.Fn mchars_num2char
|
||||
described in the
|
||||
.Xr mchars_alloc 3
|
||||
manual.
|
||||
.It Dv ESCAPE_OVERSTRIKE
|
||||
The escape sequence
|
||||
.Ic \eo
|
||||
followed by an argument delimited by an arbitrary character.
|
||||
.It Dv ESCAPE_SPECIAL
|
||||
The escape sequence
|
||||
.Ic \eC
|
||||
@@ -225,11 +268,11 @@ are hexadecimal digits and
|
||||
is not zero:
|
||||
.Ic \eC'u , \e[u .
|
||||
As a special exception,
|
||||
.Fa start
|
||||
.Pf * Fa start
|
||||
is set to the character after the
|
||||
.Ic u ,
|
||||
and the
|
||||
.Fa sz
|
||||
.Pf * Fa sz
|
||||
return value does not include the
|
||||
.Ic u
|
||||
either.
|
||||
@@ -239,26 +282,10 @@ Such Unicode character escape sequences can be rendered using the function
|
||||
described in the
|
||||
.Xr mchars_alloc 3
|
||||
manual.
|
||||
.It Dv ESCAPE_NUMBERED
|
||||
The escape sequence
|
||||
.Ic \eN
|
||||
followed by a delimited argument.
|
||||
The delimiter character is arbitrary except that digits cannot be used.
|
||||
If a digit is encountered instead of the opening delimiter, that
|
||||
digit is considered to be the argument and the end of the sequence, and
|
||||
.Dv ESCAPE_IGNORE
|
||||
is returned.
|
||||
.Pp
|
||||
Such ASCII character escape sequences can be rendered using the function
|
||||
.Fn mchars_num2char
|
||||
described in the
|
||||
.Xr mchars_alloc 3
|
||||
manual.
|
||||
.It Dv ESCAPE_OVERSTRIKE
|
||||
The escape sequence
|
||||
.Ic \eo
|
||||
followed by an argument delimited by an arbitrary character.
|
||||
.It Dv ESCAPE_IGNORE
|
||||
Many escape sequences that
|
||||
.Xr mandoc 1
|
||||
intends to ignore, in particular:
|
||||
.Bl -bullet -width 2n
|
||||
.It
|
||||
The escape sequence
|
||||
@@ -276,18 +303,15 @@ for all forms.
|
||||
.It
|
||||
The escape sequences
|
||||
.Ic \eF ,
|
||||
.Ic \eg ,
|
||||
.Ic \ek ,
|
||||
.Ic \eM ,
|
||||
.Ic \em ,
|
||||
.Ic \en ,
|
||||
.Ic \eV ,
|
||||
.Ic \eO ,
|
||||
and
|
||||
.Ic \eY
|
||||
followed by an argument in standard form.
|
||||
.It
|
||||
The escape sequences
|
||||
.Ic \eA ,
|
||||
.Ic \eb ,
|
||||
.Ic \eD ,
|
||||
.Ic \eR ,
|
||||
@@ -298,9 +322,7 @@ followed by an argument delimited by an arbitrary character.
|
||||
.It
|
||||
The escape sequences
|
||||
.Ic \eH ,
|
||||
.Ic \eh ,
|
||||
.Ic \eL ,
|
||||
.Ic \el ,
|
||||
.Ic \eS ,
|
||||
.Ic \ev ,
|
||||
and
|
||||
@@ -312,9 +334,21 @@ is found instead of a delimiter, the sequence is considered to end
|
||||
with that character, and
|
||||
.Dv ESCAPE_ERROR
|
||||
is returned.
|
||||
.It
|
||||
The escape sequences
|
||||
.Ic \eO
|
||||
with a single-digit argument in the range from 1 to 4 inclusive.
|
||||
.El
|
||||
.It Dv ESCAPE_UNSUPP
|
||||
An escape sequence that
|
||||
.Xr mandoc 1
|
||||
can parse, but for which formatting in unsupported, in particular
|
||||
.Qq \eO0
|
||||
and
|
||||
.Qq \eO5 .
|
||||
.It Dv ESCAPE_ERROR
|
||||
Escape sequences taking an argument but not matching any of the above patterns.
|
||||
Escape sequences taking an argument
|
||||
where the actual argument contains a syntax error.
|
||||
In particular, that happens if the end of the logical input line
|
||||
is reached before the end of the argument.
|
||||
.El
|
||||
@@ -323,17 +357,45 @@ For sequences that do not take an argument, the function
|
||||
.Fn mandoc_escape
|
||||
returns one of the following values:
|
||||
.Bl -tag -width 2n
|
||||
.It Dv ESCAPE_SKIPCHAR
|
||||
.It Dv ESCAPE_BREAK
|
||||
The escape sequence
|
||||
.Qq \ez .
|
||||
.Qq \ep .
|
||||
.It Dv ESCAPE_IGNORE
|
||||
Many escape sequences including
|
||||
.Qq \e% ,
|
||||
.Qq \e& ,
|
||||
.Qq \e| ,
|
||||
.Qq \ed ,
|
||||
and
|
||||
.Qq \eu .
|
||||
.It Dv ESCAPE_NOSPACE
|
||||
The escape sequence
|
||||
.Qq \ec .
|
||||
.It Dv ESCAPE_IGNORE
|
||||
.It Dv ESCAPE_SKIPCHAR
|
||||
The escape sequence
|
||||
.Qq \ez .
|
||||
.It Dv ESCAPE_UNSUPP
|
||||
The escape sequences
|
||||
.Qq \ed
|
||||
.Qq \e! ,
|
||||
.Qq \e? ,
|
||||
and
|
||||
.Qq \eu .
|
||||
.Qq \er .
|
||||
.It Dv ESCAPE_UNDEF
|
||||
Many escape sequences that other
|
||||
.Xr roff 7
|
||||
implementations do not define either, for example
|
||||
.Qq \eG ,
|
||||
.Qq \eI ,
|
||||
.Qq \ei ,
|
||||
.Qq \eJ ,
|
||||
.Qq \ej ,
|
||||
.Qq \eK ,
|
||||
.Qq \eP ,
|
||||
.Qq \eT ,
|
||||
.Qq \eU ,
|
||||
.Qq \eW ,
|
||||
and
|
||||
.Qq \ey .
|
||||
.El
|
||||
.Sh FILES
|
||||
This function is implemented in
|
||||
@@ -347,21 +409,3 @@ This function has been available since mandoc 1.11.2.
|
||||
.Sh AUTHORS
|
||||
.An Kristaps Dzonsons Aq Mt [email protected]
|
||||
.An Ingo Schwarze Aq Mt [email protected]
|
||||
.Sh BUGS
|
||||
The function doesn't cleanly distinguish between sequences that are
|
||||
valid and supported, valid and ignored, valid and unsupported,
|
||||
syntactically invalid, or undefined.
|
||||
For sequences that are ignored or unsupported, it doesn't tell
|
||||
whether that deficiency is likely to cause major formatting problems
|
||||
and/or loss of document content.
|
||||
The function is already rather complicated and still parses some
|
||||
sequences incorrectly.
|
||||
.
|
||||
.ig
|
||||
For these sequences, the list given below specifies a starting string
|
||||
and either the length of the argument or an ending character.
|
||||
The argument starts after the starting string.
|
||||
In the former case, the sequence ends with the end of the argument.
|
||||
In the latter case, the argument ends before the ending character,
|
||||
and the sequence ends with the ending character.
|
||||
..
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" $Id: mandoc_headers.3,v 1.34 2021/08/10 12:55:03 schwarze Exp $
|
||||
.\" $Id: mandoc_headers.3,v 1.35 2022/04/14 16:43:44 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014-2021 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2014-2022 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
.\" 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: August 10 2021 $
|
||||
.Dd $Mdocdate: April 14 2022 $
|
||||
.Dt MANDOC_HEADERS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -25,8 +25,8 @@ To support a cleaner coding style, the mandoc header files do not
|
||||
contain any include directives and do not guard against multiple
|
||||
inclusion.
|
||||
The application developer has to make sure that the headers are
|
||||
included in a proper order, and that no header is included more
|
||||
than once.
|
||||
included in the order shown in this manual page,
|
||||
and that no header is included more than once.
|
||||
.Pp
|
||||
The headers and functions form three major groups:
|
||||
.Sx Parser interface ,
|
||||
@@ -83,6 +83,33 @@ for
|
||||
.Pp
|
||||
Provides the functions documented in
|
||||
.Xr mandoc_malloc 3 .
|
||||
.Pp
|
||||
When this header is included, the same file must not include
|
||||
.Qq Pa mandoc_dbg.h
|
||||
because
|
||||
.Qq Pa mandoc_aux.h
|
||||
automatically includes
|
||||
.Qq Pa mandoc_dbg.h
|
||||
if and only if the preprocessor symbol
|
||||
.Dv DEBUG_MEMORY
|
||||
is defined.
|
||||
.It Qq Pa mandoc_dbg.h
|
||||
Debugging utility functions and
|
||||
debugging wrappers around memory allocation functions.
|
||||
.Pp
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides the functions documented in
|
||||
.Xr mandoc_dbg_init 3 .
|
||||
.Pp
|
||||
This header must not be included unless the preprocessor symbol
|
||||
.Dv DEBUG_MEMORY
|
||||
is defined.
|
||||
When this header is included, the same file must not include
|
||||
.Qq Pa mandoc_aux.h .
|
||||
.It Qq Pa mandoc_ohash.h
|
||||
Hashing utility functions; can be used everywhere.
|
||||
.Pp
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_html.3,v 1.23 2020/04/24 13:13:06 schwarze Exp $
|
||||
.\" $Id: mandoc_html.3,v 1.24 2022/06/24 11:15:53 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2017, 2018 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
@@ -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: April 24 2020 $
|
||||
.Dd $Mdocdate: June 24 2022 $
|
||||
.Dt MANDOC_HTML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -221,6 +221,10 @@ option.
|
||||
Print an
|
||||
.Cm id
|
||||
attribute.
|
||||
.It Cm r
|
||||
Print an ARIA
|
||||
.Cm role
|
||||
attribute.
|
||||
.It Cm \&?
|
||||
Print an arbitrary attribute.
|
||||
This format letter requires two
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* $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) 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -166,13 +166,14 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
||||
"invalid Boolean argument",
|
||||
"argument contains two font escapes",
|
||||
"unknown font, skipping request",
|
||||
"ignoring distance argument",
|
||||
"odd number of characters in request",
|
||||
|
||||
/* related to plain text */
|
||||
"blank line in fill mode, using .sp",
|
||||
"tab in filled text",
|
||||
"new sentence, new line",
|
||||
"invalid escape sequence",
|
||||
"invalid escape sequence argument",
|
||||
"undefined escape, printing literally",
|
||||
"undefined string, using \"\"",
|
||||
|
||||
@@ -216,11 +217,13 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
||||
"escaped character not allowed in a name",
|
||||
"using macro argument outside macro",
|
||||
"argument number is not numeric",
|
||||
"negative argument, using 0",
|
||||
"NOT IMPLEMENTED: Bd -file",
|
||||
"skipping display without arguments",
|
||||
"missing list type, using -item",
|
||||
"argument is not numeric, using 1",
|
||||
"argument is not a character",
|
||||
"skipping unusable escape sequence",
|
||||
"missing manual name, using \"\"",
|
||||
"uname(3) system call failed, using UNKNOWN",
|
||||
"unknown standard specifier",
|
||||
@@ -233,6 +236,12 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
||||
"skipping excess arguments",
|
||||
"divide by zero",
|
||||
|
||||
/* related to escape sequences */
|
||||
"incomplete escape sequence",
|
||||
"invalid special character",
|
||||
"unknown special character",
|
||||
"invalid escape argument delimiter",
|
||||
|
||||
"unsupported feature",
|
||||
"input too large",
|
||||
"unsupported control character",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: mandocd.8,v 1.2 2017/03/18 19:56:01 schwarze Exp $
|
||||
.\" $Id: mandocd.8,v 1.3 2021/09/28 15:41:41 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2017 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
@@ -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 18 2017 $
|
||||
.Dd $Mdocdate: September 28 2021 $
|
||||
.Dt MANDOCD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -174,7 +174,7 @@ will simply accept and process the next input file descriptor.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility appeared in version 1.14.1 or the
|
||||
utility appeared in version 1.14.1 of the
|
||||
.Sy mandoc
|
||||
toolkit.
|
||||
.Sh AUTHORS
|
||||
@@ -194,5 +194,5 @@ requests,
|
||||
needs to be started with the current working directory set to the
|
||||
root of the manual page tree.
|
||||
Avoid starting it in directories that contain secret files in any
|
||||
subdirectories, in particular in the user starting it has read
|
||||
subdirectories, in particular if the user starting it has read
|
||||
access to these secret files.
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: mandocd.c,v 1.12 2020/06/14 23:40:31 schwarze Exp $ */
|
||||
/* $Id: mandocd.c,v 1.13 2022/04/14 16:43:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
* Copyright (c) 2017, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 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
|
||||
@@ -35,6 +35,10 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#if DEBUG_MEMORY
|
||||
#define DEBUG_NODEF 1
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
@@ -129,6 +133,10 @@ main(int argc, char *argv[])
|
||||
int state, opt;
|
||||
enum outt outtype;
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_init(argc, argv);
|
||||
#endif
|
||||
|
||||
defos = NULL;
|
||||
outtype = OUTT_ASCII;
|
||||
while ((opt = getopt(argc, argv, "I:T:")) != -1) {
|
||||
@@ -240,6 +248,9 @@ main(int argc, char *argv[])
|
||||
}
|
||||
mparse_free(parser);
|
||||
mchars_free();
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_finish();
|
||||
#endif
|
||||
return state == -1 ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
+37
-38
@@ -1,6 +1,6 @@
|
||||
/* $Id: mandocdb.c,v 1.269 2021/08/19 16:55:31 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.274 2024/05/14 21:19:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2021, 2024 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
*
|
||||
@@ -173,7 +173,7 @@ static void say(const char *, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 2, 3)));
|
||||
static int set_basedir(const char *, int);
|
||||
static int treescan(void);
|
||||
static size_t utf8(unsigned int, char [7]);
|
||||
static size_t utf8(unsigned int, char[5]);
|
||||
|
||||
static int nodb; /* no database changes */
|
||||
static int mparse_options; /* abort the parse early */
|
||||
@@ -353,7 +353,7 @@ mandocdb(int argc, char *argv[])
|
||||
goto usage; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
mparse_options = MPARSE_VALIDATE;
|
||||
mparse_options = MPARSE_UTF8 | MPARSE_LATIN1 | MPARSE_VALIDATE;
|
||||
path_arg = NULL;
|
||||
op = OP_DEFAULT;
|
||||
|
||||
@@ -532,6 +532,9 @@ out:
|
||||
mpages_free();
|
||||
ohash_delete(&mpages);
|
||||
ohash_delete(&mlinks);
|
||||
#if DEBUG_MEMORY
|
||||
mandoc_dbg_finish();
|
||||
#endif
|
||||
return exitcode;
|
||||
usage:
|
||||
progname = getprogname();
|
||||
@@ -801,7 +804,7 @@ filescan(const char *infile)
|
||||
* We have to do lstat(2) before realpath(3) loses
|
||||
* the information whether this is a symbolic link.
|
||||
* We need to know that because for symbolic links,
|
||||
* we want to use the orginal file name, while for
|
||||
* we want to use the original file name, while for
|
||||
* regular files, we want to use the real path.
|
||||
*/
|
||||
if (lstat(infile, &st) == -1) {
|
||||
@@ -1904,49 +1907,35 @@ putkeys(const struct mpage *mpage, char *cp, size_t sz, uint64_t v)
|
||||
* Take a Unicode codepoint and produce its UTF-8 encoding.
|
||||
* This isn't the best way to do this, but it works.
|
||||
* The magic numbers are from the UTF-8 packaging.
|
||||
* They're not as scary as they seem: read the UTF-8 spec for details.
|
||||
* Read the UTF-8 spec or the utf8(7) manual page for details.
|
||||
*/
|
||||
static size_t
|
||||
utf8(unsigned int cp, char out[7])
|
||||
utf8(unsigned int cp, char out[5])
|
||||
{
|
||||
size_t rc;
|
||||
|
||||
rc = 0;
|
||||
if (cp <= 0x0000007F) {
|
||||
if (cp <= 0x7f) {
|
||||
rc = 1;
|
||||
out[0] = (char)cp;
|
||||
} else if (cp <= 0x000007FF) {
|
||||
} else if (cp <= 0x7ff) {
|
||||
rc = 2;
|
||||
out[0] = (cp >> 6 & 31) | 192;
|
||||
out[1] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x0000FFFF) {
|
||||
} else if (cp >= 0xd800 && cp <= 0xdfff) {
|
||||
rc = 0; /* reject UTF-16 surrogate */
|
||||
} else if (cp <= 0xffff) {
|
||||
rc = 3;
|
||||
out[0] = (cp >> 12 & 15) | 224;
|
||||
out[1] = (cp >> 6 & 63) | 128;
|
||||
out[2] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x001FFFFF) {
|
||||
} else if (cp <= 0x10ffff) {
|
||||
rc = 4;
|
||||
out[0] = (cp >> 18 & 7) | 240;
|
||||
out[1] = (cp >> 12 & 63) | 128;
|
||||
out[2] = (cp >> 6 & 63) | 128;
|
||||
out[3] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x03FFFFFF) {
|
||||
rc = 5;
|
||||
out[0] = (cp >> 24 & 3) | 248;
|
||||
out[1] = (cp >> 18 & 63) | 128;
|
||||
out[2] = (cp >> 12 & 63) | 128;
|
||||
out[3] = (cp >> 6 & 63) | 128;
|
||||
out[4] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x7FFFFFFF) {
|
||||
rc = 6;
|
||||
out[0] = (cp >> 30 & 1) | 252;
|
||||
out[1] = (cp >> 24 & 63) | 128;
|
||||
out[2] = (cp >> 18 & 63) | 128;
|
||||
out[3] = (cp >> 12 & 63) | 128;
|
||||
out[4] = (cp >> 6 & 63) | 128;
|
||||
out[5] = (cp & 63) | 128;
|
||||
} else
|
||||
return 0;
|
||||
rc = 0;
|
||||
|
||||
out[rc] = '\0';
|
||||
return rc;
|
||||
@@ -2028,7 +2017,21 @@ render_string(char **public, size_t *psz)
|
||||
*/
|
||||
|
||||
scp++;
|
||||
if (mandoc_escape(&scp, &seq, &seqlen) != ESCAPE_SPECIAL)
|
||||
switch (mandoc_escape(&scp, &seq, &seqlen)) {
|
||||
case ESCAPE_UNICODE:
|
||||
unicode = mchars_num2uc(seq + 1, seqlen - 1);
|
||||
break;
|
||||
case ESCAPE_NUMBERED:
|
||||
unicode = mchars_num2char(seq, seqlen);
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
unicode = mchars_spec2cp(seq, seqlen);
|
||||
break;
|
||||
default:
|
||||
unicode = -1;
|
||||
break;
|
||||
}
|
||||
if (unicode <= 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -2037,21 +2040,17 @@ render_string(char **public, size_t *psz)
|
||||
*/
|
||||
|
||||
if (write_utf8) {
|
||||
unicode = mchars_spec2cp(seq, seqlen);
|
||||
if (unicode <= 0)
|
||||
continue;
|
||||
addsz = utf8(unicode, utfbuf);
|
||||
if (addsz == 0)
|
||||
continue;
|
||||
addcp = utfbuf;
|
||||
} else {
|
||||
addcp = mchars_spec2str(seq, seqlen, &addsz);
|
||||
addcp = mchars_uc2str(unicode);
|
||||
if (addcp == NULL)
|
||||
continue;
|
||||
if (*addcp == ASCII_NBRSP) {
|
||||
if (*addcp == ASCII_NBRSP)
|
||||
addcp = " ";
|
||||
addsz = 1;
|
||||
}
|
||||
addsz = strlen(addcp);
|
||||
}
|
||||
|
||||
/* Copy the rendered glyph into the stream. */
|
||||
@@ -2251,11 +2250,11 @@ dbwrite(struct dba *dba)
|
||||
say(tfn, "&dba_write");
|
||||
goto err;
|
||||
}
|
||||
if ((fd1 = open(MANDOC_DB, O_RDONLY, 0)) == -1) {
|
||||
if ((fd1 = open(MANDOC_DB, O_RDONLY)) == -1) {
|
||||
say(MANDOC_DB, "&open");
|
||||
goto err;
|
||||
}
|
||||
if ((fd2 = open(tfn, O_RDONLY, 0)) == -1) {
|
||||
if ((fd2 = open(tfn, O_RDONLY)) == -1) {
|
||||
say(tfn, "&open");
|
||||
goto err;
|
||||
}
|
||||
|
||||
+37
-48
@@ -1,4 +1,4 @@
|
||||
/* $Id: manpath.c,v 1.43 2020/08/27 14:59:47 schwarze Exp $ */
|
||||
/* $Id: manpath.c,v 1.44 2021/11/05 18:03:08 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011,2014,2015,2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@@ -31,63 +31,51 @@
|
||||
#include "mandoc.h"
|
||||
#include "manconf.h"
|
||||
|
||||
static void manconf_file(struct manconf *, const char *);
|
||||
static void manconf_file(struct manconf *, const char *, int);
|
||||
static void manpath_add(struct manpaths *, const char *, char);
|
||||
static void manpath_parseline(struct manpaths *, char *, char);
|
||||
|
||||
|
||||
void
|
||||
manconf_parse(struct manconf *conf, const char *file,
|
||||
char *defp, char *auxp)
|
||||
manconf_parse(struct manconf *conf, const char *file, char *pend, char *pbeg)
|
||||
{
|
||||
char *insert;
|
||||
int use_path_from_file = 1;
|
||||
|
||||
/* Always prepend -m. */
|
||||
manpath_parseline(&conf->manpath, auxp, 'm');
|
||||
manpath_parseline(&conf->manpath, pbeg, 'm');
|
||||
|
||||
/* If -M is given, it overrides everything else. */
|
||||
if (NULL != defp) {
|
||||
manpath_parseline(&conf->manpath, defp, 'M');
|
||||
return;
|
||||
if (pend != NULL && *pend != '\0') {
|
||||
/* If -M is given, it overrides everything else. */
|
||||
manpath_parseline(&conf->manpath, pend, 'M');
|
||||
use_path_from_file = 0;
|
||||
pbeg = pend = NULL;
|
||||
} else if ((pbeg = getenv("MANPATH")) == NULL || *pbeg == '\0') {
|
||||
/* No MANPATH; use man.conf(5) only. */
|
||||
pbeg = pend = NULL;
|
||||
} else if (*pbeg == ':') {
|
||||
/* Prepend man.conf(5) to MANPATH. */
|
||||
pend = pbeg + 1;
|
||||
pbeg = NULL;
|
||||
} else if ((pend = strstr(pbeg, "::")) != NULL) {
|
||||
/* Insert man.conf(5) into MANPATH. */
|
||||
*pend = '\0';
|
||||
pend += 2;
|
||||
} else if (pbeg[strlen(pbeg) - 1] == ':') {
|
||||
/* Append man.conf(5) to MANPATH. */
|
||||
pend = NULL;
|
||||
} else {
|
||||
/* MANPATH overrides man.conf(5) completely. */
|
||||
use_path_from_file = 0;
|
||||
pend = NULL;
|
||||
}
|
||||
|
||||
/* MANPATH and man.conf(5) cooperate. */
|
||||
defp = getenv("MANPATH");
|
||||
if (NULL == file)
|
||||
manpath_parseline(&conf->manpath, pbeg, '\0');
|
||||
|
||||
if (file == NULL)
|
||||
file = MAN_CONF_FILE;
|
||||
manconf_file(conf, file, use_path_from_file);
|
||||
|
||||
/* No MANPATH; use man.conf(5) only. */
|
||||
if (NULL == defp || '\0' == defp[0]) {
|
||||
manconf_file(conf, file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepend man.conf(5) to MANPATH. */
|
||||
if (':' == defp[0]) {
|
||||
manconf_file(conf, file);
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append man.conf(5) to MANPATH. */
|
||||
if (':' == defp[strlen(defp) - 1]) {
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
manconf_file(conf, file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Insert man.conf(5) into MANPATH. */
|
||||
insert = strstr(defp, "::");
|
||||
if (NULL != insert) {
|
||||
*insert++ = '\0';
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
manconf_file(conf, file);
|
||||
manpath_parseline(&conf->manpath, insert + 1, '\0');
|
||||
return;
|
||||
}
|
||||
|
||||
/* MANPATH overrides man.conf(5) completely. */
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
manpath_parseline(&conf->manpath, pend, '\0');
|
||||
}
|
||||
|
||||
void
|
||||
@@ -161,7 +149,7 @@ manconf_free(struct manconf *conf)
|
||||
}
|
||||
|
||||
static void
|
||||
manconf_file(struct manconf *conf, const char *file)
|
||||
manconf_file(struct manconf *conf, const char *file, int use_path_from_file)
|
||||
{
|
||||
const char *const toks[] = { "manpath", "output" };
|
||||
char manpath_default[] = MANPATH_DEFAULT;
|
||||
@@ -201,7 +189,8 @@ manconf_file(struct manconf *conf, const char *file)
|
||||
|
||||
switch (tok) {
|
||||
case 0: /* manpath */
|
||||
manpath_add(&conf->manpath, cp, '\0');
|
||||
if (use_path_from_file)
|
||||
manpath_add(&conf->manpath, cp, '\0');
|
||||
*manpath_default = '\0';
|
||||
break;
|
||||
case 1: /* output */
|
||||
@@ -215,7 +204,7 @@ manconf_file(struct manconf *conf, const char *file)
|
||||
fclose(stream);
|
||||
|
||||
out:
|
||||
if (*manpath_default != '\0')
|
||||
if (use_path_from_file && *manpath_default != '\0')
|
||||
manpath_parseline(&conf->manpath, manpath_default, '\0');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mansearch.c,v 1.82 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/* $Id: mansearch.c,v 1.84 2023/04/28 19:11:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -220,7 +220,7 @@ mansearch(const struct mansearch *search,
|
||||
if (cur && search->firstmatch)
|
||||
break;
|
||||
}
|
||||
if (res != NULL)
|
||||
if (res != NULL && cur > 1)
|
||||
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
|
||||
if (chdir_status && getcwd_status && chdir(buf) == -1)
|
||||
warn("%s", buf);
|
||||
@@ -491,7 +491,7 @@ lstlen(const char *cp, size_t sep)
|
||||
|
||||
/*
|
||||
* Print the NUL-terminated list of NUL-terminated strings
|
||||
* into the buffer, seperating strings with sep.
|
||||
* into the buffer, separating strings with sep.
|
||||
*/
|
||||
static void
|
||||
lstcat(char *buf, size_t *i, const char *cp, const char *sep)
|
||||
|
||||
+40
-35
@@ -1,4 +1,4 @@
|
||||
.\" $Id: mdoc.7,v 1.287 2021/07/29 17:32:01 schwarze Exp $
|
||||
.\" $Id: mdoc.7,v 1.294 2024/09/22 10:34:58 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <[email protected]>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2020 Ingo Schwarze <[email protected]>
|
||||
@@ -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 29 2021 $
|
||||
.Dd $Mdocdate: September 22 2024 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -439,7 +439,7 @@ in the alphabetical
|
||||
.Bl -column "Brq, Bro, Brc" description
|
||||
.It Ic \&Dd Ta document date: Cm $\&Mdocdate$ | Ar month day , year
|
||||
.It Ic \&Dt Ta document title: Ar TITLE section Op Ar arch
|
||||
.It Ic \&Os Ta operating system version: Op Ar system Op Ar version
|
||||
.It Ic \&Os Ta operating system footer: Op Ar footer text
|
||||
.It Ic \&Nm Ta document name (one argument)
|
||||
.It Ic \&Nd Ta document description (one line)
|
||||
.El
|
||||
@@ -1015,7 +1015,7 @@ A numbered list.
|
||||
No item heads can be specified.
|
||||
Formatted like
|
||||
.Fl bullet ,
|
||||
except that cardinal numbers are used in place of bullets,
|
||||
except that ordinal numbers are used in place of bullets,
|
||||
starting at 1.
|
||||
.It Fl hang
|
||||
Like
|
||||
@@ -1614,7 +1614,7 @@ Examples:
|
||||
.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
|
||||
For GNU-style 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.
|
||||
@@ -2074,31 +2074,28 @@ Examples:
|
||||
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
|
||||
any
|
||||
.It Ic \&Os Op Ar footer text
|
||||
The mandatory third macro of every
|
||||
.Nm
|
||||
file.
|
||||
Usually, do not specify any arguments,
|
||||
in particular not the operating system name and/or version.
|
||||
.Pp
|
||||
The optional
|
||||
.Ar system
|
||||
parameter specifies the relevant operating system or environment.
|
||||
It is suggested to leave it unspecified, in which case
|
||||
If no argument is given,
|
||||
.Xr mandoc 1
|
||||
uses its
|
||||
prints its
|
||||
.Fl Ios
|
||||
argument or, if that isn't specified either,
|
||||
argument in the page footer, or
|
||||
.Fa sysname
|
||||
and
|
||||
.Fa release
|
||||
as returned by
|
||||
.Xr uname 3 .
|
||||
.Xr uname 3
|
||||
by default.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Os
|
||||
.Dl \&.Os KTH/CSC/TCS
|
||||
.Dl \&.Os BSD 4.3
|
||||
Manual pages that are part of a portable software project can override
|
||||
the default by giving the project name and version number as arguments,
|
||||
but leaving it blank is never a bad choice.
|
||||
.Pp
|
||||
See also
|
||||
.Ic \&Dd
|
||||
@@ -2408,7 +2405,7 @@ The second major version of the C language standard.
|
||||
.br
|
||||
The third major version of the C language standard.
|
||||
.El
|
||||
.It POSIX.1 before the Single UNIX Specification
|
||||
.It POSIX.1 before XPG4.2
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||
.It \-p1003.1-88
|
||||
@@ -2449,7 +2446,7 @@ Technical Corrigendum.
|
||||
.br
|
||||
Includes POSIX.1-1990, 1b, 1c, and 1i.
|
||||
.El
|
||||
.It X/Open Portability Guide version 4 and related standards
|
||||
.It X/Open Portability Guide before XPG4.2
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||
.It \-xpg3
|
||||
@@ -2476,7 +2473,7 @@ Updates to POSIX.2.
|
||||
.br
|
||||
Based on POSIX.1 and POSIX.2, published in 1992.
|
||||
.El
|
||||
.It Single UNIX Specification version 1 and related standards
|
||||
.It X/Open Portability Guide Issue 4 Version 2 and related standards
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||
.It \-susv1
|
||||
@@ -2486,10 +2483,7 @@ Based on POSIX.1 and POSIX.2, published in 1992.
|
||||
.br
|
||||
This standard was published in 1994.
|
||||
It was used as the basis for UNIX 95 certification.
|
||||
The following three refer to parts of it.
|
||||
.Pp
|
||||
.It \-xsh4.2
|
||||
.St -xsh4.2
|
||||
The following two refer to parts of it.
|
||||
.Pp
|
||||
.It \-xcurses4.2
|
||||
.St -xcurses4.2
|
||||
@@ -2504,13 +2498,14 @@ Networking APIs, including sockets.
|
||||
.br
|
||||
Published in 1995.
|
||||
.El
|
||||
.It Single UNIX Specification version 2 and related standards
|
||||
.It X/Open Portability Guide Issue 5 and related standards
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||
.It \-susv2
|
||||
.St -susv2
|
||||
.br
|
||||
This Standard was published in 1997
|
||||
and is also called X/Open Portability Guide version 5.
|
||||
and is also called X/Open Portability Guide Issue 5.
|
||||
It was used as the basis for UNIX 98 certification.
|
||||
The following refer to parts of it.
|
||||
.Pp
|
||||
@@ -2528,7 +2523,7 @@ The following refer to parts of it.
|
||||
.It \-xns5.2
|
||||
.St -xns5.2
|
||||
.El
|
||||
.It Single UNIX Specification version 3
|
||||
.It POSIX Issue 6
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1-2001" -compact
|
||||
.It \-p1003.1-2001
|
||||
@@ -2537,7 +2532,7 @@ The following refer to parts of it.
|
||||
.St -susv3
|
||||
.br
|
||||
This standard is based on C99, SUSv2, POSIX.1-1996, 1d, and 1j.
|
||||
It is also called X/Open Portability Guide version 6.
|
||||
It is also called X/Open Portability Guide Issue 6.
|
||||
It is used as the basis for UNIX 03 certification.
|
||||
.Pp
|
||||
.It \-p1003.1-2004
|
||||
@@ -2545,7 +2540,7 @@ It is used as the basis for UNIX 03 certification.
|
||||
.br
|
||||
The second and last Technical Corrigendum.
|
||||
.El
|
||||
.It Single UNIX Specification version 4
|
||||
.It POSIX Issues 7 and 8
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||
.It \-p1003.1-2008
|
||||
@@ -2553,8 +2548,18 @@ The second and last Technical Corrigendum.
|
||||
.It \-susv4
|
||||
.St -susv4
|
||||
.br
|
||||
This standard is also called
|
||||
X/Open Portability Guide version 7.
|
||||
This standard is based on C99.
|
||||
It is also called the
|
||||
Open Group Standard Base Specifications, Issue 7.
|
||||
.El
|
||||
.Pp
|
||||
.Bl -tag -width "-p1003.1g-2000" -compact
|
||||
.It \-p1003.1-2024
|
||||
.St -p1003.1-2024
|
||||
.br
|
||||
This standard is based on C17.
|
||||
It is also called the
|
||||
Open Group Standard Base Specifications, Issue 8.
|
||||
.El
|
||||
.It Other standards
|
||||
.Pp
|
||||
@@ -3012,7 +3017,7 @@ then the macro accepts an arbitrary number of arguments.
|
||||
.It Ic \&Fx Ta Yes Ta Yes Ta n
|
||||
.It Ic \&Hf Ta \&No Ta \&No Ta n
|
||||
.It Ic \&Ic Ta Yes Ta Yes Ta >0
|
||||
.It Ic \&In Ta \&No Ta \&No Ta 1
|
||||
.It Ic \&In Ta Yes Ta Yes Ta 1
|
||||
.It Ic \&Lb Ta \&No Ta \&No Ta 1
|
||||
.It Ic \&Li Ta Yes Ta Yes Ta >0
|
||||
.It Ic \&Lk Ta Yes Ta Yes Ta >0
|
||||
|
||||
+47
-34
@@ -1,7 +1,8 @@
|
||||
/* $Id: mdoc_html.c,v 1.342 2021/03/30 19:26:20 schwarze Exp $ */
|
||||
/* $Id: mdoc_html.c,v 1.350 2022/07/06 16:05:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2022 Anna Vyalkova <cyber@sysrq.in>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -292,16 +293,16 @@ html_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
if ((h->oflags & HTML_FRAGMENT) == 0) {
|
||||
print_gen_decls(h);
|
||||
print_otag(h, TAG_HTML, "");
|
||||
if (n != NULL && n->type == ROFFT_COMMENT)
|
||||
print_gen_comment(h, n);
|
||||
t = print_otag(h, TAG_HEAD, "");
|
||||
print_mdoc_head(mdoc, h);
|
||||
print_tagq(h, t);
|
||||
if (n != NULL && n->type == ROFFT_COMMENT)
|
||||
print_gen_comment(h, n);
|
||||
print_otag(h, TAG_BODY, "");
|
||||
}
|
||||
|
||||
mdoc_root_pre(mdoc, h);
|
||||
t = print_otag(h, TAG_DIV, "c", "manual-text");
|
||||
t = print_otag(h, TAG_MAIN, "c", "manual-text");
|
||||
print_mdoc_nodelist(mdoc, n, h);
|
||||
print_tagq(h, t);
|
||||
mdoc_root_post(mdoc, h);
|
||||
@@ -452,16 +453,19 @@ print_mdoc_node(MDOC_ARGS)
|
||||
static void
|
||||
mdoc_root_post(const struct roff_meta *meta, struct html *h)
|
||||
{
|
||||
struct tag *t, *tt;
|
||||
struct tag *t;
|
||||
|
||||
t = print_otag(h, TAG_TABLE, "c", "foot");
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
t = print_otag(h, TAG_DIV, "cr?", "foot", "doc-pagefooter",
|
||||
"aria-label", "Manual footer line");
|
||||
|
||||
print_otag(h, TAG_TD, "c", "foot-date");
|
||||
print_otag(h, TAG_SPAN, "c", "foot-left");
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_SPAN, "c", "foot-date");
|
||||
print_text(h, meta->date);
|
||||
print_stagq(h, tt);
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "foot-os");
|
||||
print_otag(h, TAG_SPAN, "c", "foot-os");
|
||||
print_text(h, meta->os);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
@@ -469,7 +473,7 @@ mdoc_root_post(const struct roff_meta *meta, struct html *h)
|
||||
static int
|
||||
mdoc_root_pre(const struct roff_meta *meta, struct html *h)
|
||||
{
|
||||
struct tag *t, *tt;
|
||||
struct tag *t;
|
||||
char *volume, *title;
|
||||
|
||||
if (NULL == meta->arch)
|
||||
@@ -484,18 +488,18 @@ mdoc_root_pre(const struct roff_meta *meta, struct html *h)
|
||||
mandoc_asprintf(&title, "%s(%s)",
|
||||
meta->title, meta->msec);
|
||||
|
||||
t = print_otag(h, TAG_TABLE, "c", "head");
|
||||
tt = print_otag(h, TAG_TR, "");
|
||||
t = print_otag(h, TAG_DIV, "cr?", "head", "doc-pageheader",
|
||||
"aria-label", "Manual header line");
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-ltitle");
|
||||
print_otag(h, TAG_SPAN, "c", "head-ltitle");
|
||||
print_text(h, title);
|
||||
print_stagq(h, tt);
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-vol");
|
||||
print_otag(h, TAG_SPAN, "c", "head-vol");
|
||||
print_text(h, volume);
|
||||
print_stagq(h, tt);
|
||||
print_stagq(h, t);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-rtitle");
|
||||
print_otag(h, TAG_SPAN, "c", "head-rtitle");
|
||||
print_text(h, title);
|
||||
print_tagq(h, t);
|
||||
|
||||
@@ -515,7 +519,7 @@ static int
|
||||
mdoc_sh_pre(MDOC_ARGS)
|
||||
{
|
||||
struct roff_node *sn, *subn;
|
||||
struct tag *t, *tsec, *tsub;
|
||||
struct tag *t, *tnav, *tsec, *tsub;
|
||||
char *id;
|
||||
int sc;
|
||||
|
||||
@@ -536,7 +540,8 @@ mdoc_sh_pre(MDOC_ARGS)
|
||||
break;
|
||||
if (sc < 2)
|
||||
break;
|
||||
t = print_otag(h, TAG_H1, "c", "Sh");
|
||||
tnav = print_otag(h, TAG_NAV, "r", "doc-toc");
|
||||
t = print_otag(h, TAG_H2, "c", "Sh");
|
||||
print_text(h, "TABLE OF CONTENTS");
|
||||
print_tagq(h, t);
|
||||
t = print_otag(h, TAG_UL, "c", "Bl-compact");
|
||||
@@ -567,11 +572,11 @@ mdoc_sh_pre(MDOC_ARGS)
|
||||
}
|
||||
print_tagq(h, tsec);
|
||||
}
|
||||
print_tagq(h, t);
|
||||
print_tagq(h, tnav);
|
||||
print_otag(h, TAG_SECTION, "c", "Sh");
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
print_otag_id(h, TAG_H1, "Sh", n);
|
||||
print_otag_id(h, TAG_H2, "Sh", n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->sec == SEC_AUTHORS)
|
||||
@@ -592,7 +597,7 @@ mdoc_ss_pre(MDOC_ARGS)
|
||||
print_otag(h, TAG_SECTION, "c", "Ss");
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
print_otag_id(h, TAG_H2, "Ss", n);
|
||||
print_otag_id(h, TAG_H3, "Ss", n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
@@ -632,7 +637,7 @@ mdoc_nd_pre(MDOC_ARGS)
|
||||
abort();
|
||||
}
|
||||
print_text(h, "\\(em");
|
||||
print_otag(h, TAG_SPAN, "c", "Nd");
|
||||
print_otag(h, TAG_SPAN, "cr", "Nd", "doc-subtitle");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -664,26 +669,34 @@ mdoc_nm_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_xr_pre(MDOC_ARGS)
|
||||
{
|
||||
if (NULL == n->child)
|
||||
char *name, *section, *label;
|
||||
|
||||
if (n->child == NULL)
|
||||
return 0;
|
||||
|
||||
name = n->child->string;
|
||||
if (n->child->next != NULL) {
|
||||
section = n->child->next->string;
|
||||
mandoc_asprintf(&label, "%s, section %s", name, section);
|
||||
} else
|
||||
section = label = NULL;
|
||||
|
||||
if (h->base_man1)
|
||||
print_otag(h, TAG_A, "chM", "Xr",
|
||||
n->child->string, n->child->next == NULL ?
|
||||
NULL : n->child->next->string);
|
||||
print_otag(h, TAG_A, "chM?", "Xr",
|
||||
name, section, "aria-label", label);
|
||||
else
|
||||
print_otag(h, TAG_A, "c", "Xr");
|
||||
print_otag(h, TAG_A, "c?", "Xr", "aria-label", label);
|
||||
|
||||
n = n->child;
|
||||
print_text(h, n->string);
|
||||
free(label);
|
||||
print_text(h, name);
|
||||
|
||||
if (NULL == (n = n->next))
|
||||
if (section == NULL)
|
||||
return 0;
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "(");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->string);
|
||||
print_text(h, section);
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ")");
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_macro.c,v 1.234 2020/01/19 18:02:00 schwarze Exp $ */
|
||||
/* $Id: mdoc_macro.c,v 1.235 2022/04/14 16:43:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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
|
||||
@@ -26,6 +26,9 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
@@ -1511,6 +1514,11 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
rew_last(mdoc, n->parent);
|
||||
}
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
if (tok == MDOC_Dt)
|
||||
mandoc_dbg_name(buf);
|
||||
#endif
|
||||
|
||||
if (buf[*pos] == '\0' &&
|
||||
(tok == MDOC_Fd || *roff_name[tok] == '%')) {
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_man.c,v 1.137 2021/07/04 15:38:26 schwarze Exp $ */
|
||||
/* $Id: mdoc_man.c,v 1.138 2023/04/28 19:11:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@@ -1518,7 +1518,7 @@ mid_it(void)
|
||||
Bl_stack[Bl_stack_len - 1]);
|
||||
print_word(buf);
|
||||
|
||||
/* Remeber to close out this .RS block later. */
|
||||
/* Remember to close out this .RS block later. */
|
||||
Bl_stack_post[Bl_stack_len - 1] = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_markdown.c,v 1.37 2021/08/10 12:55:03 schwarze Exp $ */
|
||||
/* $Id: mdoc_markdown.c,v 1.38 2024/08/13 12:44:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@@ -750,7 +750,7 @@ md_pre_raw(struct roff_node *n)
|
||||
if ((prefix = md_act(n->tok)->prefix) != NULL) {
|
||||
md_rawword(prefix);
|
||||
outflags &= ~MD_spc;
|
||||
if (*prefix == '`')
|
||||
if (strchr(prefix, '`') != NULL)
|
||||
code_blocks++;
|
||||
}
|
||||
return 1;
|
||||
@@ -764,7 +764,7 @@ md_post_raw(struct roff_node *n)
|
||||
if ((suffix = md_act(n->tok)->suffix) != NULL) {
|
||||
outflags &= ~(MD_spc | MD_nl);
|
||||
md_rawword(suffix);
|
||||
if (*suffix == '`')
|
||||
if (strchr(suffix, '`') != NULL)
|
||||
code_blocks--;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-24
@@ -1,6 +1,6 @@
|
||||
/* $Id: mdoc_state.c,v 1.17 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/* $Id: mdoc_state.c,v 1.19 2022/08/19 12:59:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014,2015,2017,2018,2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
@@ -34,6 +37,7 @@
|
||||
|
||||
typedef void (*state_handler)(STATE_ARGS);
|
||||
|
||||
static void setsec(struct roff_node *, enum roff_sec);
|
||||
static void state_bl(STATE_ARGS);
|
||||
static void state_sh(STATE_ARGS);
|
||||
static void state_sm(STATE_ARGS);
|
||||
@@ -205,35 +209,36 @@ state_bl(STATE_ARGS)
|
||||
}
|
||||
|
||||
static void
|
||||
state_sh(STATE_ARGS)
|
||||
setsec(struct roff_node *n, enum roff_sec sec)
|
||||
{
|
||||
struct roff_node *nch;
|
||||
char *secname;
|
||||
|
||||
n->sec = sec;
|
||||
for (nch = n->child; nch != NULL; nch = nch->next)
|
||||
setsec(nch, sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the section attribute for the BLOCK, HEAD, and HEAD children.
|
||||
* For other nodes, including the .Sh BODY, this is done when allocating
|
||||
* the node data structures, but for .Sh BLOCK and HEAD, the section is
|
||||
* still unknown at that time.
|
||||
*/
|
||||
static void
|
||||
state_sh(STATE_ARGS)
|
||||
{
|
||||
enum roff_sec sec;
|
||||
|
||||
if (n->type != ROFFT_HEAD)
|
||||
return;
|
||||
|
||||
if ( ! (n->flags & NODE_VALID)) {
|
||||
secname = NULL;
|
||||
deroff(&secname, n);
|
||||
|
||||
/*
|
||||
* Set the section attribute for the BLOCK, HEAD,
|
||||
* and HEAD children; the latter can only be TEXT
|
||||
* nodes, so no recursion is needed. For other
|
||||
* nodes, including the .Sh BODY, this is done
|
||||
* when allocating the node data structures, but
|
||||
* for .Sh BLOCK and HEAD, the section is still
|
||||
* unknown at that time.
|
||||
*/
|
||||
|
||||
n->sec = n->parent->sec = secname == NULL ?
|
||||
SEC_CUSTOM : mdoc_a2sec(secname);
|
||||
for (nch = n->child; nch != NULL; nch = nch->next)
|
||||
nch->sec = n->sec;
|
||||
free(secname);
|
||||
if ((n->flags & NODE_VALID) == 0) {
|
||||
sec = n->child != NULL && n->child->type == ROFFT_TEXT &&
|
||||
n->child->next == NULL ? mdoc_a2sec(n->child->string) :
|
||||
SEC_CUSTOM;
|
||||
n->parent->sec = sec;
|
||||
setsec(n, sec);
|
||||
}
|
||||
|
||||
if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
|
||||
roff_setreg(mdoc->roff, "nS", 1, '=');
|
||||
mdoc->flags |= MDOC_SYNOPSIS;
|
||||
|
||||
+14
-15
@@ -1,6 +1,6 @@
|
||||
/* $Id: mdoc_term.c,v 1.380 2020/04/06 10:16:17 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.383 2023/11/13 19:13:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012-2020, 2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
@@ -250,7 +250,6 @@ terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
{
|
||||
struct roff_node *n, *nn;
|
||||
struct termp *p;
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
|
||||
@@ -275,9 +274,6 @@ terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
print_mdoc_nodelist(p, NULL, mdoc, n);
|
||||
term_newln(p);
|
||||
} else {
|
||||
save_defindent = p->defindent;
|
||||
if (p->defindent == 0)
|
||||
p->defindent = 5;
|
||||
term_begin(p, print_mdoc_head, print_mdoc_foot, mdoc);
|
||||
while (n != NULL &&
|
||||
(n->type == ROFFT_COMMENT ||
|
||||
@@ -289,7 +285,6 @@ terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
print_mdoc_nodelist(p, NULL, mdoc, n);
|
||||
}
|
||||
term_end(p);
|
||||
p->defindent = save_defindent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,8 +315,11 @@ print_mdoc_node(DECL_ARGS)
|
||||
(p->flags & TERMP_NONEWLINE) == 0)
|
||||
term_newln(p);
|
||||
p->flags |= TERMP_BRNEVER;
|
||||
} else
|
||||
} else {
|
||||
if (n->flags & NODE_LINE)
|
||||
term_tab_ref(p);
|
||||
p->flags &= ~TERMP_BRNEVER;
|
||||
}
|
||||
|
||||
if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
|
||||
return;
|
||||
@@ -566,8 +564,8 @@ a2width(const struct termp *p, const char *v)
|
||||
|
||||
end = a2roffsu(v, &su, SCALE_MAX);
|
||||
if (end == NULL || *end != '\0') {
|
||||
SCALE_HS_INIT(&su, term_strlen(p, v));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
su.unit = SCALE_EN;
|
||||
su.scale = term_strlen(p, v) / term_strlen(p, "0");
|
||||
}
|
||||
return term_hen(p, &su);
|
||||
}
|
||||
@@ -703,9 +701,9 @@ termp_it_pre(DECL_ARGS)
|
||||
for (i = 0, nn = n->prev;
|
||||
nn->prev && i < (int)ncols;
|
||||
nn = nn->prev, i++) {
|
||||
SCALE_HS_INIT(&su,
|
||||
term_strlen(p, bl->norm->Bl.cols[i]));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
su.unit = SCALE_EN;
|
||||
su.scale = term_strlen(p, bl->norm->Bl.cols[i]) /
|
||||
term_strlen(p, "0");
|
||||
offset += term_hen(p, &su) + dcol;
|
||||
}
|
||||
|
||||
@@ -722,8 +720,9 @@ termp_it_pre(DECL_ARGS)
|
||||
* Use the declared column widths, extended as explained
|
||||
* in the preceding paragraph.
|
||||
*/
|
||||
SCALE_HS_INIT(&su, term_strlen(p, bl->norm->Bl.cols[i]));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
su.unit = SCALE_EN;
|
||||
su.scale = term_strlen(p, bl->norm->Bl.cols[i]) /
|
||||
term_strlen(p, "0");
|
||||
width = term_hen(p, &su) + dcol;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* $Id: mdoc_validate.c,v 1.389 2021/07/18 11:41:23 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.391 2022/06/08 16:31:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
@@ -1113,7 +1113,8 @@ post_tg(POST_ARGS)
|
||||
/* Find the next node. */
|
||||
n = mdoc->last;
|
||||
for (nn = n; nn != NULL; nn = nn->parent) {
|
||||
if (nn->next != NULL) {
|
||||
if (nn->type != ROFFT_HEAD && nn->type != ROFFT_BODY &&
|
||||
nn->type != ROFFT_TAIL && nn->next != NULL) {
|
||||
nn = nn->next;
|
||||
break;
|
||||
}
|
||||
@@ -2916,7 +2917,6 @@ post_os(POST_ARGS)
|
||||
{
|
||||
#ifndef OSNAME
|
||||
struct utsname utsname;
|
||||
static char *defbuf;
|
||||
#endif
|
||||
struct roff_node *n;
|
||||
|
||||
@@ -2953,15 +2953,15 @@ post_os(POST_ARGS)
|
||||
#ifdef OSNAME
|
||||
mdoc->meta.os = mandoc_strdup(OSNAME);
|
||||
#else /*!OSNAME */
|
||||
if (defbuf == NULL) {
|
||||
if (mdoc->os_r == NULL) {
|
||||
if (uname(&utsname) == -1) {
|
||||
mandoc_msg(MANDOCERR_OS_UNAME, n->line, n->pos, "Os");
|
||||
defbuf = mandoc_strdup("UNKNOWN");
|
||||
mdoc->os_r = mandoc_strdup("UNKNOWN");
|
||||
} else
|
||||
mandoc_asprintf(&defbuf, "%s %s",
|
||||
mandoc_asprintf(&mdoc->os_r, "%s %s",
|
||||
utsname.sysname, utsname.release);
|
||||
}
|
||||
mdoc->meta.os = mandoc_strdup(defbuf);
|
||||
mdoc->meta.os = mandoc_strdup(mdoc->os_r);
|
||||
#endif /*!OSNAME*/
|
||||
|
||||
out:
|
||||
|
||||
+26
-13
@@ -1,4 +1,4 @@
|
||||
/* $Id: out.c,v 1.82 2021/09/07 17:07:58 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.85 2021/10/17 21:05:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021
|
||||
@@ -123,6 +123,7 @@ 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;
|
||||
|
||||
@@ -148,7 +149,6 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
* to data cells in the data section.
|
||||
*/
|
||||
|
||||
gp = &first_group;
|
||||
for (dp = sp->first; dp != NULL; dp = dp->next) {
|
||||
icol = dp->layout->col;
|
||||
while (maxcol < icol + dp->hspans)
|
||||
@@ -189,16 +189,16 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Build an ordered, singly linked list
|
||||
* Build a singly linked list
|
||||
* of all groups of columns joined by spans,
|
||||
* recording the minimum width for each group.
|
||||
*/
|
||||
|
||||
while (*gp != NULL && ((*gp)->startcol < icol ||
|
||||
(*gp)->endcol < icol + dp->hspans))
|
||||
gp = &first_group;
|
||||
while (*gp != NULL && ((*gp)->startcol != icol ||
|
||||
(*gp)->endcol != icol + dp->hspans))
|
||||
gp = &(*gp)->next;
|
||||
if (*gp == NULL || (*gp)->startcol > icol ||
|
||||
(*gp)->endcol > icol + dp->hspans) {
|
||||
if (*gp == NULL) {
|
||||
g = mandoc_malloc(sizeof(*g));
|
||||
g->next = *gp;
|
||||
g->wanted = width;
|
||||
@@ -247,17 +247,29 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
done = 1;
|
||||
break;
|
||||
} else
|
||||
(*gp)->wanted -= width;
|
||||
g->wanted -= width;
|
||||
}
|
||||
if (done) {
|
||||
*gp = g->next;
|
||||
free(g);
|
||||
} else
|
||||
gp = &(*gp)->next;
|
||||
gp = &g->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.
|
||||
@@ -265,7 +277,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
|
||||
min1 = min2 = SIZE_MAX;
|
||||
for (icol = 0; icol <= maxcol; icol++) {
|
||||
width = tbl->cols[icol].width;
|
||||
width = colwidth[icol];
|
||||
if (min1 > width) {
|
||||
min2 = min1;
|
||||
min1 = width;
|
||||
@@ -283,7 +295,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
for (g = first_group; g != NULL; g = g->next) {
|
||||
necol = 0;
|
||||
for (icol = g->startcol; icol <= g->endcol; icol++)
|
||||
if (tbl->cols[icol].width == min1)
|
||||
if (colwidth[icol] == min1)
|
||||
necol++;
|
||||
if (necol == 0)
|
||||
continue;
|
||||
@@ -300,7 +312,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
while ((g = *gp) != NULL) {
|
||||
done = 0;
|
||||
for (icol = g->startcol; icol <= g->endcol; icol++) {
|
||||
if (tbl->cols[icol].width != min1)
|
||||
if (colwidth[icol] != min1)
|
||||
continue;
|
||||
if (g->wanted <= wanted - min1) {
|
||||
tbl->cols[icol].width += g->wanted;
|
||||
@@ -314,9 +326,10 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
*gp = g->next;
|
||||
free(g);
|
||||
} else
|
||||
gp = &(*gp)->next;
|
||||
gp = &g->next;
|
||||
}
|
||||
}
|
||||
free(colwidth);
|
||||
|
||||
/*
|
||||
* Align numbers with text.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: out.h,v 1.34 2020/04/03 11:35:01 schwarze Exp $ */
|
||||
/* $Id: out.h,v 1.35 2022/09/11 09:13:48 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -57,11 +57,6 @@ struct rofftbl {
|
||||
void *arg; /* passed to sulen, slen, and len */
|
||||
};
|
||||
|
||||
#define SCALE_HS_INIT(p, v) \
|
||||
do { (p)->unit = SCALE_EN; \
|
||||
(p)->scale = (v); } \
|
||||
while (/* CONSTCOND */ 0)
|
||||
|
||||
|
||||
struct tbl_span;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: read.c,v 1.220 2021/06/27 17:57:54 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.221 2022/05/19 14:48:56 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@@ -261,7 +261,12 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
lastln = thisln;
|
||||
}
|
||||
|
||||
/* XXX Ugly hack to mark the end of the input. */
|
||||
/*
|
||||
* XXX Ugly hack to mark the end of the input,
|
||||
* such that the function roff_parse_comment()
|
||||
* doesn't attempt to append another line if the
|
||||
* last input line ends with an escape character.
|
||||
*/
|
||||
|
||||
if (i == blk.sz || blk.buf[i] == '\0') {
|
||||
if (pos + 2 > ln.sz)
|
||||
|
||||
+32
-11
@@ -1,7 +1,7 @@
|
||||
.\" $Id: roff.7,v 1.116 2021/09/18 12:23:06 schwarze Exp $
|
||||
.\" $Id: roff.7,v 1.121 2023/10/23 20:25:02 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010-2019, 2022-2023 Ingo Schwarze <[email protected]>
|
||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <[email protected]>
|
||||
.\" Copyright (c) 2010-2019 Ingo Schwarze <[email protected]>
|
||||
.\"
|
||||
.\" 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: September 18 2021 $
|
||||
.Dd $Mdocdate: October 23 2023 $
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -2021,8 +2021,23 @@ End conditional input; see
|
||||
Paddable non-breaking space character.
|
||||
.It Ic \e0
|
||||
Digit width space character.
|
||||
.It Ic \eA\(aq Ns Ar string Ns Ic \(aq
|
||||
Anchor definition; ignored by
|
||||
.It Ic \eA\(aq Ns Ar name Ns Ic \(aq
|
||||
Interpolate
|
||||
.Sq 1
|
||||
if
|
||||
.Ar name
|
||||
is a syntactically valid identifier that can be used
|
||||
as a name for a macro or user-defined string, or
|
||||
.Sq 0
|
||||
otherwise.
|
||||
This is a thoroughly non-portable groff extension.
|
||||
Heirloom troff uses the same escape sequence with the same syntax
|
||||
for a completely different purpose,
|
||||
defining a hyperlink target position, also called an
|
||||
.Dq anchor ,
|
||||
with the given
|
||||
.Ar name .
|
||||
The Heirloom semantics is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Ic \ea
|
||||
Leader character; ignored by
|
||||
@@ -2085,7 +2100,8 @@ defaults to
|
||||
.Ic \efP .
|
||||
.It Ic \eg[ Ns Ar name Ns Ic \&]
|
||||
Interpolate the format of a number register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Xr mandoc 1 ,
|
||||
which interpolates an empty string instead.
|
||||
For short names, there are variants
|
||||
.Ic \eg Ns Ar c
|
||||
and
|
||||
@@ -2166,8 +2182,8 @@ Break the output line at the end of the current word.
|
||||
Set number register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.It Ic \er
|
||||
Move up by one line; ignored by
|
||||
.Xr mandoc 1 .
|
||||
Reverse line feed: move up by one output line.
|
||||
Currently unsupported.
|
||||
.It Ic \eS\(aq Ns Ar number Ns Ic \(aq
|
||||
Slant output; ignored by
|
||||
.Xr mandoc 1 .
|
||||
@@ -2188,12 +2204,16 @@ Horizontal tab; ignored by
|
||||
Move up by half a line; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.It Ic \eV[ Ns Ar name Ns Ic \&]
|
||||
Interpolate an environment variable; ignored by
|
||||
.Xr mandoc 1 .
|
||||
Interpolate an environment variable.
|
||||
For short names, there are variants
|
||||
.Ic \eV Ns Ar c
|
||||
and
|
||||
.Ic \eV( Ns Ar cc .
|
||||
This escape sequence is intentionally unsupported;
|
||||
.Xr mandoc 1
|
||||
prints the string
|
||||
.Dq Pf $ Brq Ar name
|
||||
instead of inspecting the environment.
|
||||
.It Ic \ev\(aq Ns Ar number Ns Ic \(aq
|
||||
Vertical motion; ignored by
|
||||
.Xr mandoc 1 .
|
||||
@@ -2204,7 +2224,8 @@ The
|
||||
.Xr mandoc 1
|
||||
implementation assumes that after expansion of user-defined strings, the
|
||||
.Ar string
|
||||
only contains normal characters, no escape sequences, and that each
|
||||
only contains normal characters, characters expressed as escape sequences,
|
||||
and zero-width escape sequences, and that each
|
||||
character has a width of 24 basic units.
|
||||
.It Ic \eX\(aq Ns Ar string Ns Ic \(aq
|
||||
Output
|
||||
|
||||
+481
-447
File diff suppressed because it is too large.
Load diff
+14
-13
@@ -1,6 +1,6 @@
|
||||
/* $Id: roff.h,v 1.74 2020/04/08 11:56:03 schwarze Exp $ */
|
||||
/* $Id: roff.h,v 1.76 2023/10/24 20:53:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013-2015,2017-2020,2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -71,7 +71,7 @@ enum roff_type {
|
||||
};
|
||||
|
||||
enum roff_tok {
|
||||
ROFF_br = 0,
|
||||
ROFF_br = 0, /* Beginning of roff(7) requests. */
|
||||
ROFF_ce,
|
||||
ROFF_fi,
|
||||
ROFF_ft,
|
||||
@@ -83,8 +83,8 @@ enum roff_tok {
|
||||
ROFF_sp,
|
||||
ROFF_ta,
|
||||
ROFF_ti,
|
||||
ROFF_MAX,
|
||||
ROFF_ab,
|
||||
ROFF_MAX, /* End of requests that generate nodes. */
|
||||
ROFF_ab, /* Requests only used during preprocessing. */
|
||||
ROFF_ad,
|
||||
ROFF_af,
|
||||
ROFF_aln,
|
||||
@@ -313,11 +313,11 @@ enum roff_tok {
|
||||
ROFF_writec,
|
||||
ROFF_writem,
|
||||
ROFF_xflag,
|
||||
ROFF_cblock,
|
||||
ROFF_RENAMED,
|
||||
ROFF_USERDEF,
|
||||
TOKEN_NONE,
|
||||
MDOC_Dd,
|
||||
ROFF_cblock, /* Block end marker "..". */
|
||||
ROFF_RENAMED, /* New name of a renamed request or macro. */
|
||||
ROFF_USERDEF, /* User defined macro. */
|
||||
TOKEN_NONE, /* Undefined macro or text/tbl/eqn/comment node. */
|
||||
MDOC_Dd, /* Beginning of mdoc(7) macros. */
|
||||
MDOC_Dt,
|
||||
MDOC_Os,
|
||||
MDOC_Sh,
|
||||
@@ -438,8 +438,8 @@ enum roff_tok {
|
||||
MDOC__U,
|
||||
MDOC_Ta,
|
||||
MDOC_Tg,
|
||||
MDOC_MAX,
|
||||
MAN_TH,
|
||||
MDOC_MAX, /* End of mdoc(7) macros. */
|
||||
MAN_TH, /* Beginning of man(7) macros. */
|
||||
MAN_SH,
|
||||
MAN_SS,
|
||||
MAN_TP,
|
||||
@@ -476,7 +476,8 @@ enum roff_tok {
|
||||
MAN_UE,
|
||||
MAN_MT,
|
||||
MAN_ME,
|
||||
MAN_MAX
|
||||
MAN_MR,
|
||||
MAN_MAX /* End of man(7) macros. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,546 @@
|
||||
/* $Id: roff_escape.c,v 1.15 2024/05/16 21:23:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022
|
||||
* Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Parser for roff(7) escape sequences.
|
||||
* To be used by all mandoc(1) parsers and formatters.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "roff_int.h"
|
||||
|
||||
/*
|
||||
* Traditional escape sequence interpreter for general use
|
||||
* including in high-level formatters. This function does not issue
|
||||
* diagnostics and is not usable for expansion in the roff(7) parser.
|
||||
* It is documented in the mandoc_escape(3) manual page.
|
||||
*/
|
||||
enum mandoc_esc
|
||||
mandoc_escape(const char **rendarg, const char **rarg, int *rargl)
|
||||
{
|
||||
int iarg, iendarg, iend;
|
||||
enum mandoc_esc rval;
|
||||
|
||||
rval = roff_escape(--*rendarg, 0, 0,
|
||||
NULL, NULL, &iarg, &iendarg, &iend);
|
||||
assert(rval != ESCAPE_EXPAND);
|
||||
if (rarg != NULL)
|
||||
*rarg = *rendarg + iarg;
|
||||
if (rargl != NULL)
|
||||
*rargl = iendarg - iarg;
|
||||
*rendarg += iend;
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Full-featured escape sequence parser.
|
||||
* If it encounters a nested escape sequence that requires expansion
|
||||
* by the parser and re-parsing, the positions of that inner escape
|
||||
* sequence are returned in *resc ... *rend.
|
||||
* Otherwise, *resc is set to aesc and the positions of the escape
|
||||
* sequence starting at aesc are returned.
|
||||
* Diagnostic messages are generated if and only if ln != 0,
|
||||
* that is, if and only if called by roff_expand().
|
||||
*/
|
||||
enum mandoc_esc
|
||||
roff_escape(const char *buf, const int ln, const int aesc,
|
||||
int *resc, int *rnam, int *rarg, int *rendarg, int *rend)
|
||||
{
|
||||
int iesc; /* index of leading escape char */
|
||||
int inam; /* index of escape name */
|
||||
int iarg; /* index beginning the argument */
|
||||
int iendarg; /* index right after the argument */
|
||||
int iend; /* index right after the sequence */
|
||||
int sesc, snam, sarg, sendarg, send; /* for sub-escape */
|
||||
int escterm; /* whether term is escaped */
|
||||
int maxl; /* expected length of the argument */
|
||||
int argl; /* actual length of the argument */
|
||||
int c, i; /* for \[char...] parsing */
|
||||
int valid_A; /* for \A parsing */
|
||||
enum mandoc_esc rval; /* return value */
|
||||
enum mandoc_esc stype; /* for sub-escape */
|
||||
enum mandocerr err; /* diagnostic code */
|
||||
char term; /* byte terminating the argument */
|
||||
|
||||
/*
|
||||
* Treat "\E" just like "\";
|
||||
* it only makes a difference in copy mode.
|
||||
*/
|
||||
|
||||
iesc = inam = aesc;
|
||||
do {
|
||||
inam++;
|
||||
} while (buf[inam] == 'E');
|
||||
|
||||
/*
|
||||
* Sort the following cases first by syntax category,
|
||||
* then by escape sequence type, and finally by ASCII code.
|
||||
*/
|
||||
|
||||
iarg = iendarg = iend = inam + 1;
|
||||
maxl = INT_MAX;
|
||||
term = '\0';
|
||||
err = MANDOCERR_OK;
|
||||
switch (buf[inam]) {
|
||||
|
||||
/* Escape sequences taking no arguments at all. */
|
||||
|
||||
case '!':
|
||||
case '?':
|
||||
case 'r':
|
||||
rval = ESCAPE_UNSUPP;
|
||||
goto out;
|
||||
|
||||
case '%':
|
||||
case '&':
|
||||
case ')':
|
||||
case ',':
|
||||
case '/':
|
||||
case '^':
|
||||
case 'a':
|
||||
case 'd':
|
||||
case 't':
|
||||
case 'u':
|
||||
case '{':
|
||||
case '|':
|
||||
case '}':
|
||||
rval = ESCAPE_IGNORE;
|
||||
goto out;
|
||||
|
||||
case '\0':
|
||||
iendarg = --iend;
|
||||
/* FALLTHROUGH */
|
||||
case '.':
|
||||
case '\\':
|
||||
default:
|
||||
iarg--;
|
||||
rval = ESCAPE_UNDEF;
|
||||
goto out;
|
||||
|
||||
case ' ':
|
||||
case '\'':
|
||||
case '-':
|
||||
case '0':
|
||||
case ':':
|
||||
case '_':
|
||||
case '`':
|
||||
case 'e':
|
||||
case '~':
|
||||
iarg--;
|
||||
argl = 1;
|
||||
rval = ESCAPE_SPECIAL;
|
||||
goto out;
|
||||
case 'p':
|
||||
rval = ESCAPE_BREAK;
|
||||
goto out;
|
||||
case 'c':
|
||||
rval = ESCAPE_NOSPACE;
|
||||
goto out;
|
||||
case 'z':
|
||||
rval = ESCAPE_SKIPCHAR;
|
||||
goto out;
|
||||
|
||||
/* Standard argument format. */
|
||||
|
||||
case '$':
|
||||
case '*':
|
||||
case 'V':
|
||||
case 'g':
|
||||
case 'n':
|
||||
rval = ESCAPE_EXPAND;
|
||||
break;
|
||||
case 'F':
|
||||
case 'M':
|
||||
case 'O':
|
||||
case 'Y':
|
||||
case 'k':
|
||||
case 'm':
|
||||
rval = ESCAPE_IGNORE;
|
||||
break;
|
||||
case '(':
|
||||
case '[':
|
||||
rval = ESCAPE_SPECIAL;
|
||||
iendarg = iend = --iarg;
|
||||
break;
|
||||
case 'f':
|
||||
rval = ESCAPE_FONT;
|
||||
break;
|
||||
|
||||
/* Quoted arguments */
|
||||
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'w':
|
||||
rval = ESCAPE_EXPAND;
|
||||
term = '\b';
|
||||
break;
|
||||
case 'D':
|
||||
case 'H':
|
||||
case 'L':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'X':
|
||||
case 'Z':
|
||||
case 'b':
|
||||
case 'v':
|
||||
case 'x':
|
||||
rval = ESCAPE_IGNORE;
|
||||
term = '\b';
|
||||
break;
|
||||
case 'C':
|
||||
rval = ESCAPE_SPECIAL;
|
||||
term = '\b';
|
||||
break;
|
||||
case 'N':
|
||||
rval = ESCAPE_NUMBERED;
|
||||
term = '\b';
|
||||
break;
|
||||
case 'h':
|
||||
rval = ESCAPE_HORIZ;
|
||||
term = '\b';
|
||||
break;
|
||||
case 'l':
|
||||
rval = ESCAPE_HLINE;
|
||||
term = '\b';
|
||||
break;
|
||||
case 'o':
|
||||
rval = ESCAPE_OVERSTRIKE;
|
||||
term = '\b';
|
||||
break;
|
||||
|
||||
/* Sizes support both forms, with additional peculiarities. */
|
||||
|
||||
case 's':
|
||||
rval = ESCAPE_IGNORE;
|
||||
if (buf[iarg] == '+' || buf[iarg] == '-'||
|
||||
buf[iarg] == ASCII_HYPH)
|
||||
iarg++;
|
||||
switch (buf[iarg]) {
|
||||
case '(':
|
||||
maxl = 2;
|
||||
iarg++;
|
||||
break;
|
||||
case '[':
|
||||
term = ']';
|
||||
iarg++;
|
||||
break;
|
||||
case '\'':
|
||||
term = '\'';
|
||||
iarg++;
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
if (buf[iarg - 1] == 's' &&
|
||||
isdigit((unsigned char)buf[iarg + 1])) {
|
||||
maxl = 2;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
maxl = 1;
|
||||
break;
|
||||
}
|
||||
iendarg = iend = iarg;
|
||||
}
|
||||
|
||||
/* Decide how to end the argument. */
|
||||
|
||||
escterm = 0;
|
||||
stype = ESCAPE_EXPAND;
|
||||
if ((term == '\b' || (term == '\0' && maxl == INT_MAX)) &&
|
||||
buf[iarg] == buf[iesc]) {
|
||||
stype = roff_escape(buf, ln, iendarg,
|
||||
&sesc, &snam, &sarg, &sendarg, &send);
|
||||
if (stype == ESCAPE_EXPAND)
|
||||
goto out_sub;
|
||||
}
|
||||
|
||||
if (term == '\b') {
|
||||
if (stype == ESCAPE_UNDEF)
|
||||
iarg++;
|
||||
if (stype != ESCAPE_EXPAND && stype != ESCAPE_UNDEF) {
|
||||
if (strchr("BHLRSNhlvx", buf[inam]) != NULL &&
|
||||
strchr(" ,.0DLOXYZ^abdhlortuvx|~",
|
||||
buf[snam]) != NULL) {
|
||||
err = MANDOCERR_ESC_DELIM;
|
||||
iend = send;
|
||||
iarg = iendarg = sesc;
|
||||
goto out;
|
||||
}
|
||||
escterm = 1;
|
||||
iarg = send;
|
||||
term = buf[snam];
|
||||
} else if (strchr("BDHLRSvxNhl", buf[inam]) != NULL &&
|
||||
strchr(" %&()*+-./0123456789:<=>", buf[iarg]) != NULL) {
|
||||
err = MANDOCERR_ESC_DELIM;
|
||||
if (rval != ESCAPE_EXPAND)
|
||||
rval = ESCAPE_ERROR;
|
||||
if (buf[inam] != 'D') {
|
||||
iendarg = iend = iarg + 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (term == '\b')
|
||||
term = buf[iarg++];
|
||||
} else if (term == '\0' && maxl == INT_MAX) {
|
||||
if (buf[inam] == 'n' && (buf[iarg] == '+' || buf[iarg] == '-'))
|
||||
iarg++;
|
||||
switch (buf[iarg]) {
|
||||
case '(':
|
||||
maxl = 2;
|
||||
iarg++;
|
||||
break;
|
||||
case '[':
|
||||
if (buf[++iarg] == ' ') {
|
||||
iendarg = iend = iarg + 1;
|
||||
err = MANDOCERR_ESC_ARG;
|
||||
rval = ESCAPE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
maxl = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to the end of the argument. */
|
||||
|
||||
valid_A = 1;
|
||||
iendarg = iarg;
|
||||
while (maxl > 0) {
|
||||
if (buf[iendarg] == '\0') {
|
||||
err = MANDOCERR_ESC_INCOMPLETE;
|
||||
if (rval != ESCAPE_EXPAND &&
|
||||
rval != ESCAPE_OVERSTRIKE)
|
||||
rval = ESCAPE_ERROR;
|
||||
/* Usually, ignore an incomplete argument. */
|
||||
if (strchr("Aow", buf[inam]) == NULL)
|
||||
iendarg = iarg;
|
||||
break;
|
||||
}
|
||||
if (escterm == 0 && buf[iendarg] == term) {
|
||||
iend = iendarg + 1;
|
||||
break;
|
||||
}
|
||||
if (buf[iendarg] == buf[iesc]) {
|
||||
stype = roff_escape(buf, ln, iendarg,
|
||||
&sesc, &snam, &sarg, &sendarg, &send);
|
||||
if (stype == ESCAPE_EXPAND)
|
||||
goto out_sub;
|
||||
iend = send;
|
||||
if (escterm == 1 &&
|
||||
(buf[snam] == term || buf[inam] == 'N'))
|
||||
break;
|
||||
if (stype != ESCAPE_UNDEF)
|
||||
valid_A = 0;
|
||||
iendarg = send;
|
||||
} else if (buf[inam] == 'N' &&
|
||||
isdigit((unsigned char)buf[iendarg]) == 0) {
|
||||
iend = iendarg + 1;
|
||||
break;
|
||||
} else {
|
||||
if (buf[iendarg] == ' ' || buf[iendarg] == '\t')
|
||||
valid_A = 0;
|
||||
if (maxl != INT_MAX)
|
||||
maxl--;
|
||||
iend = ++iendarg;
|
||||
}
|
||||
}
|
||||
|
||||
/* Post-process depending on the content of the argument. */
|
||||
|
||||
argl = iendarg - iarg;
|
||||
switch (buf[inam]) {
|
||||
case '*':
|
||||
if (resc == NULL && argl == 2 &&
|
||||
buf[iarg] == '.' && buf[iarg + 1] == 'T')
|
||||
rval = ESCAPE_DEVICE;
|
||||
break;
|
||||
case 'A':
|
||||
if (valid_A == 0)
|
||||
iendarg = iarg;
|
||||
break;
|
||||
case 'O':
|
||||
switch (buf[iarg]) {
|
||||
case '0':
|
||||
rval = ESCAPE_UNSUPP;
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
if (argl == 1)
|
||||
rval = ESCAPE_IGNORE;
|
||||
else {
|
||||
err = MANDOCERR_ESC_ARG;
|
||||
rval = ESCAPE_ERROR;
|
||||
}
|
||||
break;
|
||||
case '5':
|
||||
if (buf[iarg - 1] == '[')
|
||||
rval = ESCAPE_UNSUPP;
|
||||
else {
|
||||
err = MANDOCERR_ESC_ARG;
|
||||
rval = ESCAPE_ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = MANDOCERR_ESC_ARG;
|
||||
rval = ESCAPE_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rval) {
|
||||
case ESCAPE_FONT:
|
||||
rval = mandoc_font(buf + iarg, argl);
|
||||
if (rval == ESCAPE_ERROR)
|
||||
err = MANDOCERR_ESC_ARG;
|
||||
break;
|
||||
|
||||
case ESCAPE_SPECIAL:
|
||||
if (argl == 0) {
|
||||
err = MANDOCERR_ESC_BADCHAR;
|
||||
rval = ESCAPE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The file chars.c only provides one common list of
|
||||
* character names, but \[-] == \- is the only one of
|
||||
* the characters with one-byte names that allows
|
||||
* enclosing the name in brackets.
|
||||
*/
|
||||
|
||||
if (term != '\0' && argl == 1 && buf[iarg] != '-') {
|
||||
err = MANDOCERR_ESC_BADCHAR;
|
||||
rval = ESCAPE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Treat \[char...] as an alias for \N'...'. */
|
||||
|
||||
if (buf[iarg] == 'c') {
|
||||
if (argl < 6 || argl > 7 ||
|
||||
strncmp(buf + iarg, "char", 4) != 0 ||
|
||||
(int)strspn(buf + iarg + 4, "0123456789")
|
||||
+ 4 < argl)
|
||||
break;
|
||||
c = 0;
|
||||
for (i = iarg; i < iendarg; i++)
|
||||
c = 10 * c + (buf[i] - '0');
|
||||
if (c < 0x21 || (c > 0x7e && c < 0xa0) || c > 0xff) {
|
||||
err = MANDOCERR_ESC_BADCHAR;
|
||||
break;
|
||||
}
|
||||
iarg += 4;
|
||||
rval = ESCAPE_NUMBERED;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unicode escapes are defined in groff as \[u0000]
|
||||
* to \[u10FFFF], where the contained value must be
|
||||
* a valid Unicode codepoint.
|
||||
*/
|
||||
|
||||
if (buf[iarg] != 'u' || argl < 5 || argl > 7)
|
||||
break;
|
||||
if (argl == 7 && /* beyond the Unicode range */
|
||||
(buf[iarg + 1] != '1' || buf[iarg + 2] != '0')) {
|
||||
err = MANDOCERR_ESC_BADCHAR;
|
||||
break;
|
||||
}
|
||||
if (argl == 6 && buf[iarg + 1] == '0') {
|
||||
err = MANDOCERR_ESC_BADCHAR;
|
||||
break;
|
||||
}
|
||||
if (argl == 5 && /* UTF-16 surrogate */
|
||||
toupper((unsigned char)buf[iarg + 1]) == 'D' &&
|
||||
strchr("89ABCDEFabcdef", buf[iarg + 2]) != NULL) {
|
||||
err = MANDOCERR_ESC_BADCHAR;
|
||||
break;
|
||||
}
|
||||
if ((int)strspn(buf + iarg + 1, "0123456789ABCDEFabcdef")
|
||||
+ 1 == argl)
|
||||
rval = ESCAPE_UNICODE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
|
||||
out_sub:
|
||||
iesc = sesc;
|
||||
inam = snam;
|
||||
iarg = sarg;
|
||||
iendarg = sendarg;
|
||||
iend = send;
|
||||
rval = ESCAPE_EXPAND;
|
||||
|
||||
out:
|
||||
if (resc != NULL)
|
||||
*resc = iesc;
|
||||
if (rnam != NULL)
|
||||
*rnam = inam;
|
||||
if (rarg != NULL)
|
||||
*rarg = iarg;
|
||||
if (rendarg != NULL)
|
||||
*rendarg = iendarg;
|
||||
if (rend != NULL)
|
||||
*rend = iend;
|
||||
if (ln == 0)
|
||||
return rval;
|
||||
|
||||
/*
|
||||
* Diagnostic messages are only issued when called
|
||||
* from the parser, not when called from the formatters.
|
||||
*/
|
||||
|
||||
switch (rval) {
|
||||
case ESCAPE_UNSUPP:
|
||||
err = MANDOCERR_ESC_UNSUPP;
|
||||
break;
|
||||
case ESCAPE_UNDEF:
|
||||
if (buf[inam] != '\\' && buf[inam] != '.')
|
||||
err = MANDOCERR_ESC_UNDEF;
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (mchars_spec2cp(buf + iarg, argl) >= 0)
|
||||
err = MANDOCERR_OK;
|
||||
else if (err == MANDOCERR_OK)
|
||||
err = MANDOCERR_ESC_UNKCHAR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (err != MANDOCERR_OK)
|
||||
mandoc_msg(err, ln, iesc, "%.*s", iend - iesc, buf + iesc);
|
||||
return rval;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* $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) 2013-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -35,6 +35,7 @@ struct roff_man {
|
||||
struct ohash *mdocmac; /* Mdoc macro lookup table. */
|
||||
struct ohash *manmac; /* Man macro lookup table. */
|
||||
const char *os_s; /* Default operating system. */
|
||||
char *os_r; /* Operating system name at run time. */
|
||||
struct roff_node *last; /* The last node parsed. */
|
||||
struct roff_node *last_es; /* The most recent Es node. */
|
||||
int quick; /* Abort parse early. */
|
||||
@@ -81,6 +82,8 @@ struct ohash *roffhash_alloc(enum roff_tok, enum roff_tok);
|
||||
enum roff_tok roffhash_find(struct ohash *, const char *, size_t);
|
||||
void roffhash_free(struct ohash *);
|
||||
|
||||
enum mandoc_esc roff_escape(const char *, const int, const int,
|
||||
int *, int *, int *, int *, int *);
|
||||
void roff_state_reset(struct roff_man *);
|
||||
void roff_validate(struct roff_man *);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: roff_term.c,v 1.20 2020/09/03 17:37:06 schwarze Exp $ */
|
||||
/* $Id: roff_term.c,v 1.25 2023/04/28 19:11:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010,2014,2015,2017-2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@@ -175,7 +175,7 @@ roff_term_pre_po(ROFF_TERM_ARGS)
|
||||
} else
|
||||
ponew = polast;
|
||||
|
||||
/* Remeber both the previous and the newly requested offset. */
|
||||
/* Remember both the previous and the newly requested offset. */
|
||||
polast = po;
|
||||
po = ponew;
|
||||
|
||||
|
||||
+2
-3
@@ -1,4 +1,4 @@
|
||||
/* $Id: st.c,v 1.16 2018/12/14 01:18:26 schwarze Exp $ */
|
||||
/* $Id: st.c,v 1.18 2024/06/16 18:49:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@@ -37,9 +37,9 @@ LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2024", "IEEE Std 1003.1-2024 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2013", "IEEE Std 1003.1-2008, 2013 Edition (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1-2016", "IEEE Std 1003.1-2008, 2016 Edition (\\(LqPOSIX.1\\(Rq)")
|
||||
LINE("-p1003.1-2024", "IEEE Std 1003.1-2024 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)")
|
||||
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)")
|
||||
@@ -71,7 +71,6 @@ LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)")
|
||||
LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)")
|
||||
LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)")
|
||||
LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)")
|
||||
LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)")
|
||||
LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)")
|
||||
LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)")
|
||||
LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)")
|
||||
|
||||
+60
-14
@@ -1,6 +1,7 @@
|
||||
/* $Id: tag.c,v 1.36 2020/04/19 16:36:16 schwarze Exp $ */
|
||||
/* $Id: tag.c,v 1.38 2023/11/24 05:02:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2015, 2016, 2018, 2019, 2020, 2022, 2023
|
||||
* 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,11 +26,13 @@
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "roff_int.h"
|
||||
@@ -80,19 +83,34 @@ tag_free(void)
|
||||
|
||||
/*
|
||||
* Set a node where a term is defined,
|
||||
* unless it is already defined at a lower priority.
|
||||
* unless the term is already defined at a lower priority.
|
||||
*/
|
||||
void
|
||||
tag_put(const char *s, int prio, struct roff_node *n)
|
||||
{
|
||||
struct tag_entry *entry;
|
||||
struct roff_node *nold;
|
||||
const char *se;
|
||||
const char *se, *src;
|
||||
char *cpy;
|
||||
size_t len;
|
||||
unsigned int slot;
|
||||
int changed;
|
||||
|
||||
assert(prio <= TAG_FALLBACK);
|
||||
|
||||
/*
|
||||
* If the node is already tagged, the existing tag is
|
||||
* explicit and we are now about to add an implicit tag.
|
||||
* Don't do that; just skip implicit tagging if the author
|
||||
* specified an explicit tag.
|
||||
*/
|
||||
|
||||
if (n->flags & NODE_ID)
|
||||
return;
|
||||
|
||||
/* Determine the implicit tag. */
|
||||
|
||||
changed = 1;
|
||||
if (s == NULL) {
|
||||
if (n->child == NULL || n->child->type != ROFFT_TEXT)
|
||||
return;
|
||||
@@ -109,27 +127,53 @@ tag_put(const char *s, int prio, struct roff_node *n)
|
||||
s += 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
changed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate \- and ASCII_HYPH to plain '-'.
|
||||
* Skip whitespace and escapes and whatever follows,
|
||||
* and if there is any, downgrade the priority.
|
||||
*/
|
||||
|
||||
len = strcspn(s, " \t\\");
|
||||
cpy = mandoc_malloc(strlen(s) + 1);
|
||||
for (src = s, len = 0; *src != '\0'; src++, len++) {
|
||||
switch (*src) {
|
||||
case '\t':
|
||||
case ' ':
|
||||
changed = 1;
|
||||
break;
|
||||
case ASCII_HYPH:
|
||||
cpy[len] = '-';
|
||||
changed = 1;
|
||||
continue;
|
||||
case '\\':
|
||||
if (src[1] != '-')
|
||||
break;
|
||||
src++;
|
||||
changed = 1;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
cpy[len] = *src;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (len == 0)
|
||||
return;
|
||||
goto out;
|
||||
cpy[len] = '\0';
|
||||
|
||||
se = s + len;
|
||||
if (*se != '\0' && prio < TAG_WEAK)
|
||||
if (*src != '\0' && prio < TAG_WEAK)
|
||||
prio = TAG_WEAK;
|
||||
|
||||
s = cpy;
|
||||
se = cpy + len;
|
||||
slot = ohash_qlookupi(&tag_data, s, &se);
|
||||
entry = ohash_find(&tag_data, slot);
|
||||
|
||||
@@ -137,8 +181,7 @@ tag_put(const char *s, int prio, struct roff_node *n)
|
||||
|
||||
if (entry == NULL) {
|
||||
entry = mandoc_malloc(sizeof(*entry) + len + 1);
|
||||
memcpy(entry->s, s, len);
|
||||
entry->s[len] = '\0';
|
||||
memcpy(entry->s, s, len + 1);
|
||||
entry->nodes = NULL;
|
||||
entry->maxnodes = entry->nnodes = 0;
|
||||
ohash_insert(&tag_data, slot, entry);
|
||||
@@ -150,7 +193,7 @@ tag_put(const char *s, int prio, struct roff_node *n)
|
||||
*/
|
||||
|
||||
else if (entry->prio < prio)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If the existing entry is worse, clear it.
|
||||
@@ -167,7 +210,7 @@ tag_put(const char *s, int prio, struct roff_node *n)
|
||||
}
|
||||
if (prio == TAG_FALLBACK) {
|
||||
entry->prio = TAG_DELETE;
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,10 +224,13 @@ tag_put(const char *s, int prio, struct roff_node *n)
|
||||
entry->nodes[entry->nnodes++] = n;
|
||||
entry->prio = prio;
|
||||
n->flags |= NODE_ID;
|
||||
if (n->child == NULL || n->child->string != s || *se != '\0') {
|
||||
if (changed) {
|
||||
assert(n->tag == NULL);
|
||||
n->tag = mandoc_strndup(s, len);
|
||||
}
|
||||
|
||||
out:
|
||||
free(cpy);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $Id: tbl.7,v 1.37 2021/09/18 12:34:27 schwarze Exp $
|
||||
.\" $Id: tbl.7,v 1.39 2022/08/28 13:52:59 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <[email protected]>
|
||||
.\" Copyright (c) 2014,2015,2017,2018,2019 Ingo Schwarze <[email protected]>
|
||||
@@ -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: September 18 2021 $
|
||||
.Dd $Mdocdate: August 28 2022 $
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -333,7 +333,7 @@ Ruby:1.8.7.374
|
||||
TeX Live:2015
|
||||
.TE
|
||||
.Ed
|
||||
.sp 2v
|
||||
.Pp
|
||||
Spans and skipping width calculations:
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
@@ -357,7 +357,7 @@ l:center:
|
||||
:right
|
||||
.TE
|
||||
.Ed
|
||||
.sp 2v
|
||||
.Pp
|
||||
Text blocks, specifying spacings and specifying and equalizing
|
||||
column widths, putting lines into individual cells, and overriding
|
||||
.Cm allbox :
|
||||
@@ -367,7 +367,7 @@ allbox tab(:);
|
||||
le le||7 lw10.
|
||||
The fourth line:_:line 1
|
||||
of this column:=:line 2
|
||||
determines:\_:line 3
|
||||
determines:\e_:line 3
|
||||
the column width.:T{
|
||||
This text is too wide to fit into a column of width 17.
|
||||
T}:line 4
|
||||
@@ -391,7 +391,7 @@ No break here.
|
||||
T}::line 5
|
||||
.TE
|
||||
.Ed
|
||||
.sp 2v
|
||||
.Pp
|
||||
These examples were constructed to demonstrate many
|
||||
.Nm
|
||||
features in a compact way.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* $Id: tbl_html.c,v 1.38 2021/09/09 16:52:52 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.41 2022/04/23 14:02:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 2017, 2018, 2021, 2022
|
||||
* Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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
|
||||
@@ -24,6 +25,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "tbl.h"
|
||||
@@ -134,7 +138,7 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
*/
|
||||
|
||||
if (sp->pos != TBL_SPAN_DATA)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
/* Inhibit printing of spaces: we do padding ourselves. */
|
||||
|
||||
@@ -247,7 +251,9 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
if (dp->layout->pos == TBL_CELL_HORIZ ||
|
||||
dp->layout->pos == TBL_CELL_DHORIZ ||
|
||||
dp->pos == TBL_DATA_HORIZ ||
|
||||
dp->pos == TBL_DATA_DHORIZ)
|
||||
dp->pos == TBL_DATA_NHORIZ ||
|
||||
dp->pos == TBL_DATA_DHORIZ ||
|
||||
dp->pos == TBL_DATA_NDHORIZ)
|
||||
print_otag(h, TAG_HR, "");
|
||||
else if (dp->string != NULL) {
|
||||
save_font = h->metac;
|
||||
@@ -284,6 +290,7 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
|
||||
h->flags &= ~HTML_NONOSPACE;
|
||||
|
||||
out:
|
||||
if (sp->next == NULL) {
|
||||
assert(h->tbl.cols);
|
||||
free(h->tbl.cols);
|
||||
|
||||
+13
-10
@@ -1,7 +1,7 @@
|
||||
/* $Id: tbl_term.c,v 1.75 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.79 2022/08/28 10:58:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
#include "mandoc_dbg.h"
|
||||
#endif
|
||||
#include "mandoc.h"
|
||||
#include "tbl.h"
|
||||
#include "out.h"
|
||||
@@ -290,6 +293,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
}
|
||||
tp->tcol++;
|
||||
tp->col = 0;
|
||||
tp->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE);
|
||||
tbl_data(tp, sp->opts, cp, dp, tp->tbl.cols + ic);
|
||||
if (dp != NULL &&
|
||||
(ic || sp->layout->first->pos != TBL_CELL_SPAN)) {
|
||||
@@ -545,15 +549,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
tp->flags &= ~TERMP_MULTICOL;
|
||||
tp->tcol->rmargin = tp->maxrmargin;
|
||||
if (sp->next == NULL) {
|
||||
if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX)) {
|
||||
if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX))
|
||||
tbl_hrule(tp, sp, sp, NULL, TBL_OPT_BOX);
|
||||
tp->skipvsp = 1;
|
||||
}
|
||||
if (tp->enc == TERMENC_ASCII &&
|
||||
sp->opts->opts & TBL_OPT_DBOX) {
|
||||
sp->opts->opts & TBL_OPT_DBOX)
|
||||
tbl_hrule(tp, sp, sp, NULL, TBL_OPT_DBOX);
|
||||
tp->skipvsp = 2;
|
||||
}
|
||||
assert(tp->tbl.cols);
|
||||
free(tp->tbl.cols);
|
||||
tp->tbl.cols = NULL;
|
||||
@@ -820,8 +820,11 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
||||
width = col->width;
|
||||
ic = dp->layout->col;
|
||||
hspans = dp->hspans;
|
||||
while (hspans--)
|
||||
width += tp->tbl.cols[++ic].width + 3;
|
||||
while (hspans--) {
|
||||
width += tp->tbl.cols[ic].spacing;
|
||||
ic++;
|
||||
width += tp->tbl.cols[ic].width;
|
||||
}
|
||||
|
||||
padr = width > len ? width - len : 0;
|
||||
padl = 0;
|
||||
|
||||
+97
-40
@@ -1,7 +1,7 @@
|
||||
/* $Id: term.c,v 1.283 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.291 2023/04/28 19:11:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010-2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* 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
|
||||
@@ -58,6 +58,7 @@ term_setcol(struct termp *p, size_t maxtcol)
|
||||
void
|
||||
term_free(struct termp *p)
|
||||
{
|
||||
term_tab_free();
|
||||
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++)
|
||||
free(p->tcol->buf);
|
||||
free(p->tcols);
|
||||
@@ -156,6 +157,11 @@ term_flushln(struct termp *p)
|
||||
/* Finally, print the field content. */
|
||||
|
||||
term_field(p, vbl, nbr);
|
||||
if (vbr < vtarget)
|
||||
p->tcol->taboff += vbr;
|
||||
else
|
||||
p->tcol->taboff += vtarget;
|
||||
p->tcol->taboff += (*p->width)(p, ' ');
|
||||
|
||||
/*
|
||||
* If there is no text left in the field, exit the loop.
|
||||
@@ -175,7 +181,9 @@ term_flushln(struct termp *p)
|
||||
vbr += (*p->width)(p, ' ');
|
||||
continue;
|
||||
case '\n':
|
||||
case ASCII_NBRZW:
|
||||
case ASCII_BREAK:
|
||||
case ASCII_TABREF:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
@@ -186,7 +194,7 @@ term_flushln(struct termp *p)
|
||||
break;
|
||||
|
||||
/*
|
||||
* At the location of an automtic line break, input
|
||||
* At the location of an automatic line break, input
|
||||
* space characters are consumed by the line break.
|
||||
*/
|
||||
|
||||
@@ -206,7 +214,6 @@ term_flushln(struct termp *p)
|
||||
return;
|
||||
|
||||
endline(p);
|
||||
p->viscol = 0;
|
||||
|
||||
/*
|
||||
* Normally, start the next line at the same indentation
|
||||
@@ -257,9 +264,11 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
|
||||
size_t vn; /* Visual position of the next character. */
|
||||
int breakline; /* Break at the end of this word. */
|
||||
int graph; /* Last character was non-blank. */
|
||||
int taboff; /* Temporary offset for literal tabs. */
|
||||
|
||||
*nbr = *vbr = vis = 0;
|
||||
breakline = graph = 0;
|
||||
taboff = p->tcol->taboff;
|
||||
for (ic = p->tcol->col; ic < p->tcol->lastcol; ic++) {
|
||||
switch (p->tcol->buf[ic]) {
|
||||
case '\b': /* Escape \o (overstrike) or backspace markup. */
|
||||
@@ -267,22 +276,11 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
|
||||
vis -= (*p->width)(p, p->tcol->buf[ic - 1]);
|
||||
continue;
|
||||
|
||||
case '\t': /* Normal ASCII whitespace. */
|
||||
case ' ':
|
||||
case ASCII_BREAK: /* Escape \: (breakpoint). */
|
||||
switch (p->tcol->buf[ic]) {
|
||||
case '\t':
|
||||
vn = term_tab_next(vis);
|
||||
break;
|
||||
case ' ':
|
||||
vn = vis + (*p->width)(p, ' ');
|
||||
break;
|
||||
case ASCII_BREAK:
|
||||
vn = vis;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
vn = vis;
|
||||
if (p->tcol->buf[ic] == ' ')
|
||||
vn += (*p->width)(p, ' ');
|
||||
/* Can break at the end of a word. */
|
||||
if (breakline || vn > vtarget)
|
||||
break;
|
||||
@@ -316,12 +314,30 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
|
||||
*vbr = vis;
|
||||
continue;
|
||||
|
||||
case ASCII_NBRSP: /* Non-breakable space. */
|
||||
p->tcol->buf[ic] = ' ';
|
||||
/* FALLTHROUGH */
|
||||
default: /* Printable character. */
|
||||
case ASCII_TABREF:
|
||||
taboff = -vis - (*p->width)(p, ' ');
|
||||
continue;
|
||||
|
||||
default:
|
||||
switch (p->tcol->buf[ic]) {
|
||||
case '\t':
|
||||
if (taboff < 0 && (size_t)-taboff > vis)
|
||||
vis = 0;
|
||||
else
|
||||
vis += taboff;
|
||||
vis = term_tab_next(vis);
|
||||
vis -= taboff;
|
||||
break;
|
||||
case ASCII_NBRZW: /* Non-breakable zero-width. */
|
||||
break;
|
||||
case ASCII_NBRSP: /* Non-breakable space. */
|
||||
p->tcol->buf[ic] = ' ';
|
||||
/* FALLTHROUGH */
|
||||
default: /* Printable character. */
|
||||
vis += (*p->width)(p, p->tcol->buf[ic]);
|
||||
break;
|
||||
}
|
||||
graph = 1;
|
||||
vis += (*p->width)(p, p->tcol->buf[ic]);
|
||||
if (vis > vtarget && *nbr > 0)
|
||||
return;
|
||||
continue;
|
||||
@@ -351,10 +367,12 @@ 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. */
|
||||
size_t vt; /* Visual position including tab offset. */
|
||||
size_t dv; /* Visual width of the current character. */
|
||||
size_t vn; /* Visual position of the next character. */
|
||||
int taboff; /* Temporary offset for literal tabs. */
|
||||
|
||||
vis = 0;
|
||||
taboff = p->tcol->taboff;
|
||||
for (ic = p->tcol->col; ic < nbr; ic++) {
|
||||
|
||||
/*
|
||||
@@ -365,15 +383,22 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
|
||||
switch (p->tcol->buf[ic]) {
|
||||
case '\n':
|
||||
case ASCII_BREAK:
|
||||
case ASCII_NBRZW:
|
||||
continue;
|
||||
case ASCII_TABREF:
|
||||
taboff = -vis - (*p->width)(p, ' ');
|
||||
continue;
|
||||
case '\t':
|
||||
vn = term_tab_next(vis);
|
||||
vbl += vn - vis;
|
||||
vis = vn;
|
||||
continue;
|
||||
case ' ':
|
||||
case ASCII_NBRSP:
|
||||
dv = (*p->width)(p, ' ');
|
||||
if (p->tcol->buf[ic] == '\t') {
|
||||
if (taboff < 0 && (size_t)-taboff > vis)
|
||||
vt = 0;
|
||||
else
|
||||
vt = vis + taboff;
|
||||
dv = term_tab_next(vt) - vt;
|
||||
} else
|
||||
dv = (*p->width)(p, ' ');
|
||||
vbl += dv;
|
||||
vis += dv;
|
||||
continue;
|
||||
@@ -435,10 +460,10 @@ endline(struct termp *p)
|
||||
void
|
||||
term_newln(struct termp *p)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (p->tcol->lastcol || p->viscol)
|
||||
term_flushln(p);
|
||||
p->tcol->taboff = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -571,18 +596,23 @@ term_word(struct termp *p, const char *word)
|
||||
break;
|
||||
case ESCAPE_NUMBERED:
|
||||
uc = mchars_num2char(seq, sz);
|
||||
if (uc < 0)
|
||||
continue;
|
||||
break;
|
||||
if (uc >= 0)
|
||||
break;
|
||||
bufferc(p, ASCII_NBRZW);
|
||||
continue;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (p->enc == TERMENC_ASCII) {
|
||||
cp = mchars_spec2str(seq, sz, &ssz);
|
||||
if (cp != NULL)
|
||||
encode(p, cp, ssz);
|
||||
else
|
||||
bufferc(p, ASCII_NBRZW);
|
||||
} else {
|
||||
uc = mchars_spec2cp(seq, sz);
|
||||
if (uc > 0)
|
||||
encode1(p, uc);
|
||||
else
|
||||
bufferc(p, ASCII_NBRZW);
|
||||
}
|
||||
continue;
|
||||
case ESCAPE_UNDEF:
|
||||
@@ -627,6 +657,10 @@ term_word(struct termp *p, const char *word)
|
||||
encode(p, "utf8", 4);
|
||||
continue;
|
||||
case ESCAPE_HORIZ:
|
||||
if (p->flags & TERMP_BACKAFTER) {
|
||||
p->flags &= ~TERMP_BACKAFTER;
|
||||
continue;
|
||||
}
|
||||
if (*seq == '|') {
|
||||
seq++;
|
||||
uc = -p->col;
|
||||
@@ -635,12 +669,24 @@ term_word(struct termp *p, const char *word)
|
||||
if (a2roffsu(seq, &su, SCALE_EM) == NULL)
|
||||
continue;
|
||||
uc += term_hen(p, &su);
|
||||
if (uc > 0)
|
||||
while (uc-- > 0)
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
else if (p->col > (size_t)(-uc))
|
||||
if (uc >= 0) {
|
||||
while (uc > 0) {
|
||||
uc -= term_len(p, 1);
|
||||
if (p->flags & TERMP_BACKBEFORE)
|
||||
p->flags &= ~TERMP_BACKBEFORE;
|
||||
else
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (p->flags & TERMP_BACKBEFORE) {
|
||||
p->flags &= ~TERMP_BACKBEFORE;
|
||||
assert(p->col > 0);
|
||||
p->col--;
|
||||
}
|
||||
if (p->col >= (size_t)(-uc)) {
|
||||
p->col += uc;
|
||||
else {
|
||||
} else {
|
||||
uc += p->col;
|
||||
p->col = 0;
|
||||
if (p->tcol->offset > (size_t)(-uc)) {
|
||||
@@ -728,6 +774,9 @@ term_word(struct termp *p, const char *word)
|
||||
if (p->col > p->tcol->lastcol)
|
||||
p->col = p->tcol->lastcol;
|
||||
continue;
|
||||
case ESCAPE_IGNORE:
|
||||
bufferc(p, ASCII_NBRZW);
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -775,6 +824,14 @@ bufferc(struct termp *p, char c)
|
||||
p->tcol->lastcol = p->col;
|
||||
}
|
||||
|
||||
void
|
||||
term_tab_ref(struct termp *p)
|
||||
{
|
||||
if (p->tcol->lastcol && p->tcol->lastcol <= p->col &&
|
||||
(p->flags & TERMP_NOBUF) == 0)
|
||||
bufferc(p, ASCII_TABREF);
|
||||
}
|
||||
|
||||
/*
|
||||
* See encode().
|
||||
* Do this for a single (probably unicode) value.
|
||||
@@ -919,8 +976,8 @@ term_strlen(const struct termp *p, const char *cp)
|
||||
int ssz, skip, uc;
|
||||
const char *seq, *rhs;
|
||||
enum mandoc_esc esc;
|
||||
static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH,
|
||||
ASCII_BREAK, '\0' };
|
||||
static const char rej[] = { '\\', ASCII_NBRSP, ASCII_NBRZW,
|
||||
ASCII_BREAK, ASCII_HYPH, ASCII_TABREF, '\0' };
|
||||
|
||||
/*
|
||||
* Account for escaped sequences within string length
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: term.h,v 1.131 2019/01/04 03:21:02 schwarze Exp $ */
|
||||
/* $Id: term.h,v 1.134 2022/08/16 17:45:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2015,2017,2019,2022 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-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
|
||||
@@ -56,6 +56,7 @@ struct termp_col {
|
||||
size_t col; /* Byte in buf to be written. */
|
||||
size_t rmargin; /* Current right margin. */
|
||||
size_t offset; /* Current left margin. */
|
||||
size_t taboff; /* Offset for literal tabs. */
|
||||
};
|
||||
|
||||
struct termp {
|
||||
@@ -149,7 +150,9 @@ size_t term_len(const struct termp *, size_t);
|
||||
|
||||
void term_tab_set(const struct termp *, const char *);
|
||||
void term_tab_iset(size_t);
|
||||
void term_tab_ref(struct termp *);
|
||||
size_t term_tab_next(size_t);
|
||||
void term_tab_free(void);
|
||||
|
||||
void term_fontpush(struct termp *, enum termfont);
|
||||
void term_fontpop(struct termp *);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: term_ascii.c,v 1.66 2020/09/09 13:45:05 schwarze Exp $ */
|
||||
/* $Id: term_ascii.c,v 1.69 2023/11/13 19:13:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014,2015,2017,2018,2020 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -72,6 +72,7 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
|
||||
p->maxtcol = 1;
|
||||
|
||||
p->line = 1;
|
||||
p->defindent = 5;
|
||||
p->defrmargin = p->lastrmargin = 78;
|
||||
p->fontq = mandoc_reallocarray(NULL,
|
||||
(p->fontsz = 8), sizeof(*p->fontq));
|
||||
@@ -122,10 +123,8 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (outopts->mdoc) {
|
||||
if (outopts->mdoc)
|
||||
p->mdocstyle = 1;
|
||||
p->defindent = 5;
|
||||
}
|
||||
if (outopts->indent)
|
||||
p->defindent = outopts->indent;
|
||||
if (outopts->width)
|
||||
@@ -196,7 +195,7 @@ terminal_sepline(void *arg)
|
||||
static size_t
|
||||
ascii_width(const struct termp *p, int c)
|
||||
{
|
||||
return c != ASCII_BREAK;
|
||||
return c != ASCII_BREAK && c != ASCII_NBRZW && c != ASCII_TABREF;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* $Id: term_tab.c,v 1.6 2020/06/22 19:20:40 schwarze Exp $ */
|
||||
/* $Id: term_tab.c,v 1.7 2021/10/04 18:56:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 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
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "out.h"
|
||||
@@ -33,6 +35,7 @@ struct tablist {
|
||||
static struct {
|
||||
struct tablist a; /* All tab positions for lookup. */
|
||||
struct tablist p; /* Periodic tab positions to add. */
|
||||
struct tablist *r; /* Tablist currently being recorded. */
|
||||
size_t d; /* Default tab width in units of n. */
|
||||
} tabs;
|
||||
|
||||
@@ -40,8 +43,6 @@ static struct {
|
||||
void
|
||||
term_tab_set(const struct termp *p, const char *arg)
|
||||
{
|
||||
static int recording_period;
|
||||
|
||||
struct roffsu su;
|
||||
struct tablist *tl;
|
||||
size_t pos;
|
||||
@@ -51,7 +52,7 @@ term_tab_set(const struct termp *p, const char *arg)
|
||||
|
||||
if (arg == NULL) {
|
||||
tabs.a.n = tabs.p.n = 0;
|
||||
recording_period = 0;
|
||||
tabs.r = &tabs.a;
|
||||
if (tabs.d == 0) {
|
||||
a2roffsu(".8i", &su, SCALE_IN);
|
||||
tabs.d = term_hen(p, &su);
|
||||
@@ -59,7 +60,7 @@ term_tab_set(const struct termp *p, const char *arg)
|
||||
return;
|
||||
}
|
||||
if (arg[0] == 'T' && arg[1] == '\0') {
|
||||
recording_period = 1;
|
||||
tabs.r = &tabs.p;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ term_tab_set(const struct termp *p, const char *arg)
|
||||
|
||||
/* Select the list, and extend it if it is full. */
|
||||
|
||||
tl = recording_period ? &tabs.p : &tabs.a;
|
||||
tl = tabs.r;
|
||||
if (tl->n >= tl->s) {
|
||||
tl->s += 8;
|
||||
tl->t = mandoc_reallocarray(tl->t, tl->s, sizeof(*tl->t));
|
||||
@@ -128,3 +129,12 @@ term_tab_next(size_t prev)
|
||||
return tabs.a.t[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
term_tab_free(void)
|
||||
{
|
||||
free(tabs.a.t);
|
||||
free(tabs.p.t);
|
||||
memset(&tabs, 0, sizeof(tabs));
|
||||
tabs.r = &tabs.a;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/* $Id: tree.c,v 1.91 2021/09/07 10:59:18 schwarze Exp $ */
|
||||
/* $Id: tree.c,v 1.92 2022/01/12 04:54:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2015, 2017-2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013-2015, 2017-2022 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
|
||||
@@ -509,12 +509,16 @@ print_span(const struct tbl_span *sp, int indent)
|
||||
putchar('x');
|
||||
}
|
||||
switch (dp->pos) {
|
||||
case TBL_DATA_HORIZ:
|
||||
case TBL_DATA_NHORIZ:
|
||||
putchar('-');
|
||||
putchar('\\');
|
||||
/* FALLTHROUGH */
|
||||
case TBL_DATA_HORIZ:
|
||||
putchar('_');
|
||||
break;
|
||||
case TBL_DATA_DHORIZ:
|
||||
case TBL_DATA_NDHORIZ:
|
||||
putchar('\\');
|
||||
/* FALLTHROUGH */
|
||||
case TBL_DATA_DHORIZ:
|
||||
putchar('=');
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -33,6 +33,7 @@ LIBMDOC_SRCS= arch.c \
|
||||
|
||||
LIBROFF_SRCS= eqn.c \
|
||||
roff.c \
|
||||
roff_escape.c \
|
||||
roff_html.c \
|
||||
roff_term.c \
|
||||
roff_validate.c \
|
||||
@@ -47,6 +48,7 @@ LIB_SRCS= ${LIBMAN_SRCS} \
|
||||
chars.c \
|
||||
mandoc.c \
|
||||
mandoc_aux.c \
|
||||
mandoc_dbg.c \
|
||||
mandoc_msg.c \
|
||||
mandoc_ohash.c \
|
||||
mandoc_xr.c \
|
||||
|
||||
Reference in new issue
Block a user