MFHead @347527
Sponsored by: The FreeBSD Foundation
This commit is contained in:
commit
7648bc9fee
19
.cirrus.yml
Normal file
19
.cirrus.yml
Normal file
@ -0,0 +1,19 @@
|
||||
# $FreeBSD$
|
||||
|
||||
freebsd_instance:
|
||||
image: freebsd-12-0-release-amd64
|
||||
cpu: 8
|
||||
memory: 24G
|
||||
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
|
||||
task:
|
||||
timeout_in: 90m
|
||||
install_script:
|
||||
- pkg install -y qemu-devel
|
||||
- fetch https://people.freebsd.org/~emaste/OVMF.fd
|
||||
script:
|
||||
- make -j$(sysctl -n hw.ncpu) WITHOUT_TOOLCHAIN=yes buildworld buildkernel
|
||||
test_script:
|
||||
- OVMF=$(pwd)/OVMF.fd sh tools/boot/ci-qemu-test.sh
|
20
MAINTAINERS
20
MAINTAINERS
@ -35,17 +35,19 @@ makes a commit to the specified subtree.
|
||||
|
||||
subsystem login notes
|
||||
-----------------------------
|
||||
atf freebsd-testing,jmmv,ngie Pre-commit review requested.
|
||||
ath(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
|
||||
contrib/atf ngie,#test Pre-commit review requested.
|
||||
contrib/capsicum-test ngie,#capsicum,#test Pre-commit review requested.
|
||||
contrib/compiler-rt dim Pre-commit review preferred.
|
||||
contrib/googletest ngie,#test Pre-commit review requested.
|
||||
contrib/ipfilter cy Pre-commit review requested.
|
||||
contrib/libc++ dim Pre-commit review preferred.
|
||||
contrib/libcxxrt dim Pre-commit review preferred.
|
||||
contrib/libunwind dim,emaste,jhb Pre-commit review preferred.
|
||||
contrib/llvm dim Pre-commit review preferred.
|
||||
contrib/llvm/tools/lldb dim,emaste Pre-commit review preferred.
|
||||
contrib/netbsd-tests freebsd-testing,ngie Pre-commit review requested.
|
||||
contrib/pjdfstest freebsd-testing,asomers,ngie,pjd Pre-commit review requested.
|
||||
contrib/netbsd-tests ngie,#test Pre-commit review requested.
|
||||
contrib/pjdfstest asomers,ngie,pjd,#test Pre-commit review requested.
|
||||
*env(3) secteam Due to the problematic security history of this
|
||||
code, please have patches reviewed by secteam.
|
||||
etc/mail gshapiro Pre-commit review requested. Keep in sync with -STABLE.
|
||||
@ -86,10 +88,15 @@ sh(1) jilles Pre-commit review requested. This also applies
|
||||
to kill(1), printf(1) and test(1) which are
|
||||
compiled in as builtins.
|
||||
share/mk imp, bapt, bdrewery, emaste, sjg Make is hard.
|
||||
share/mk/*.test.mk freebsd-testing,ngie (same list as share/mk too) Pre-commit review requested.
|
||||
share/mk/*.test.mk imp,bapt,bdrewery, Pre-commit review requested.
|
||||
emaste,ngie,sjg,#test
|
||||
stand/forth dteske Pre-commit review requested.
|
||||
stand/lua kevans Pre-commit review requested
|
||||
sys/compat/linuxkpi hselasky If in doubt, ask.
|
||||
sys/compat/linuxkpi hselasky If in doubt, ask.
|
||||
zeising, johalun pre-commit review requested via
|
||||
#x11 phabricator group.
|
||||
(to avoid drm graphics drivers
|
||||
impact)
|
||||
sys/contrib/ipfilter cy Pre-commit review requested.
|
||||
sys/dev/e1000 erj Pre-commit phabricator review requested.
|
||||
sys/dev/ixgbe erj Pre-commit phabricator review requested.
|
||||
@ -101,7 +108,8 @@ sys/netinet/ip_carp.c glebius Pre-commit review recommended.
|
||||
sys/netpfil/pf kp,glebius Pre-commit review recommended.
|
||||
sys/x86/xen royger Pre-commit review recommended.
|
||||
sys/xen royger Pre-commit review recommended.
|
||||
tests freebsd-testing,ngie Pre-commit review requested.
|
||||
tests ngie,#test Pre-commit review requested.
|
||||
tools/build imp Pre-commit review requested, especially to fix bootstrap issues.
|
||||
top(1) eadler Pre-commit review requested.
|
||||
usr.sbin/bsdconfig dteske Pre-commit phabricator review requested.
|
||||
usr.sbin/dpv dteske Pre-commit review requested. Keep in sync with libdpv.
|
||||
|
2
Makefile
2
Makefile
@ -570,7 +570,7 @@ universe-toolchain: .PHONY universe_prologue
|
||||
false; \
|
||||
fi
|
||||
@if [ ! -e "${HOST_OBJTOP}/tmp/usr/bin/ld" ]; then \
|
||||
echo "Missing host linker at ${HOST_OBJTOP}/tmp/usr/bin/cc?" >&2; \
|
||||
echo "Missing host linker at ${HOST_OBJTOP}/tmp/usr/bin/ld?" >&2; \
|
||||
false; \
|
||||
fi
|
||||
@echo "--------------------------------------------------------------"
|
||||
|
@ -2570,6 +2570,7 @@ NXBDIRS+= \
|
||||
usr.bin/true \
|
||||
usr.bin/uniq \
|
||||
usr.bin/unzip \
|
||||
usr.bin/wc \
|
||||
usr.bin/xargs \
|
||||
usr.bin/xinstall \
|
||||
usr.bin/xz \
|
||||
@ -2601,6 +2602,7 @@ NXBMAKEARGS+= \
|
||||
-DNO_CPU_CFLAGS \
|
||||
-DNO_PIC \
|
||||
SSP_CFLAGS= \
|
||||
MK_CASPER=no \
|
||||
MK_CLANG_EXTRAS=no \
|
||||
MK_CLANG_FULL=no \
|
||||
MK_CTF=no \
|
||||
|
@ -38,6 +38,9 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20190509: tests/sys/opencrypto requires the net/py-dpkt package.
|
||||
OLD_FILES+=usr/tests/sys/opencrypto/dpkt.py
|
||||
OLD_FILES+=usr/tests/sys/opencrypto/dpkt.pyc
|
||||
# 20190304: new libc++ import which bumps version from 7.0.1 to 8.0.0.
|
||||
OLD_FILES+=usr/include/c++/v1/experimental/dynarray
|
||||
# 20190304: new clang import which bumps version from 7.0.1 to 8.0.0.
|
||||
|
73
UPDATING
73
UPDATING
@ -31,11 +31,68 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20190507:
|
||||
The IPSEC option has been removed from GENERIC. Users requiring
|
||||
ipsec(4) must now load the ipsec(4) kernel module.
|
||||
|
||||
20190507:
|
||||
The tap(4) driver has been folded into tun(4), and the module has been
|
||||
renamed to tuntap. You should update any kld_load="if_tap" or
|
||||
kld_load="if_tun" entries in /etc/rc.conf, if_tap_load="YES" or
|
||||
if_tun_load="YES" entries in /boot/loader.conf to load the if_tuntap
|
||||
module instead, and "device tap" or "device tun" entries in kernel
|
||||
config files to select the tuntap device instead.
|
||||
|
||||
20190418:
|
||||
The following knobs have been added related to tradeoffs between
|
||||
safe use of the random device and availability in the absence of
|
||||
entropy:
|
||||
|
||||
kern.random.initial_seeding.bypass_before_seeding: tunable; set
|
||||
non-zero to bypass the random device prior to seeding, or zero to
|
||||
block random requests until the random device is initially seeded.
|
||||
For now, set to 1 (unsafe) by default to restore pre-r346250 boot
|
||||
availability properties.
|
||||
|
||||
kern.random.initial_seeding.read_random_bypassed_before_seeding:
|
||||
read-only diagnostic sysctl that is set when bypass is enabled and
|
||||
read_random(9) is bypassed, to enable programmatic handling of this
|
||||
initial condition, if desired.
|
||||
|
||||
kern.random.initial_seeding.arc4random_bypassed_before_seeding:
|
||||
Similar to the above, but for for arc4random(9) initial seeding.
|
||||
|
||||
kern.random.initial_seeding.disable_bypass_warnings: tunable; set
|
||||
non-zero to disable warnings in dmesg when the same conditions are
|
||||
met as for the diagnostic sysctls above. Defaults to zero, i.e.,
|
||||
produce warnings in dmesg when the conditions are met.
|
||||
|
||||
20190416:
|
||||
The tunable "security.stack_protect.permit_nonrandom_cookies" may be
|
||||
set to a non-zero value to boot systems that do not provide early
|
||||
entropy. Otherwise, such systems may see the panic message:
|
||||
"cannot initialize stack cookies because random device is not yet
|
||||
seeded."
|
||||
|
||||
20190416:
|
||||
The loadable random module KPI has changed; the random_infra_init()
|
||||
routine now requires a 3rd function pointer for a bool (*)(void)
|
||||
method that returns true if the random device is seeded (and
|
||||
therefore unblocked).
|
||||
|
||||
20190404:
|
||||
r345895 reverts r320698. This implies that an nfsuserd(8) daemon
|
||||
built from head sources between r320757 (July 6, 2017) and
|
||||
r338192 (Aug. 22, 2018) will not work unless the "-use-udpsock"
|
||||
is added to the command line.
|
||||
nfsuserd daemons built from head sources that are post-r338192 are
|
||||
not affected and should continue to work.
|
||||
|
||||
20190320:
|
||||
The fuse(4) module has been renamed to fusefs(4) for consistency with
|
||||
other filesystems. You should update any kld_load="fuse" entries in
|
||||
/etc/rc.conf, fuse_load="YES" entries in /boot/loader.conf, and
|
||||
"options FUSE" enties in kernel config files.
|
||||
"options FUSE" entries in kernel config files.
|
||||
|
||||
20190304:
|
||||
Clang, llvm, lld, lldb, compiler-rt and libc++ have been upgraded to
|
||||
@ -99,7 +156,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
|
||||
20181211:
|
||||
Remove the timed and netdate programs from the base tree. Setting
|
||||
the time with these deamons has been obsolete for over a decade.
|
||||
the time with these daemons has been obsolete for over a decade.
|
||||
|
||||
20181126:
|
||||
On amd64, arm64 and armv7 (architectures that install LLVM's ld.lld
|
||||
@ -162,7 +219,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
|
||||
20181009:
|
||||
OpenSSL has been updated to version 1.1.1. This update included
|
||||
additional various API changes througout the base system. It is
|
||||
additional various API changes throughout the base system. It is
|
||||
important to rebuild third-party software after upgrading. The value
|
||||
of __FreeBSD_version has been bumped accordingly.
|
||||
|
||||
@ -259,13 +316,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
20180719:
|
||||
ARM64 now have efifb support, if you want to have serial console
|
||||
on your arm64 board when an screen is connected and the bootloader
|
||||
setup a framebuffer for us to use, just add :
|
||||
setup a frame buffer for us to use, just add :
|
||||
boot_serial=YES
|
||||
boot_multicons=YES
|
||||
in /boot/loader.conf
|
||||
For Raspberry Pi 3 (RPI) users, this is needed even if you don't have
|
||||
an screen connected as the firmware will setup a framebuffer are that
|
||||
u-boot will expose as an EFI framebuffer.
|
||||
an screen connected as the firmware will setup a frame buffer are that
|
||||
u-boot will expose as an EFI frame buffer.
|
||||
|
||||
20180719:
|
||||
New uid:gid added, ntpd:ntpd (123:123). Be sure to run mergemaster
|
||||
@ -364,7 +421,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
|
||||
20180508:
|
||||
The nxge(4) driver has been removed. This driver was for PCI-X 10g
|
||||
cards made by s2io/Neterion. The company was aquired by Exar and
|
||||
cards made by s2io/Neterion. The company was acquired by Exar and
|
||||
no longer sells or supports Ethernet products. If you have device
|
||||
nxge in your kernel config file it must be removed.
|
||||
|
||||
@ -455,7 +512,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
20180212:
|
||||
FreeBSD boot loader enhanced with Lua scripting. It's purely opt-in for
|
||||
now by building WITH_LOADER_LUA and WITHOUT_FORTH in /etc/src.conf.
|
||||
Co-existance for the transition period will come shortly. Booting is a
|
||||
Co-existence for the transition period will come shortly. Booting is a
|
||||
complex environment and test coverage for Lua-enabled loaders has been
|
||||
thin, so it would be prudent to assume it might not work and make
|
||||
provisions for backup boot methods.
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\" @(#)date.1 8.3 (Berkeley) 4/28/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 20, 2019
|
||||
.Dd April 23, 2019
|
||||
.Dt DATE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,7 +40,7 @@
|
||||
.Nd display or set date and time
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl jRu
|
||||
.Op Fl jnRu
|
||||
.Op Fl r Ar seconds | Ar filename
|
||||
.Oo
|
||||
.Fl v
|
||||
@ -142,6 +142,8 @@ This allows you to use the
|
||||
flag in addition to the
|
||||
.Cm +
|
||||
option to convert one date format to another.
|
||||
.It Fl n
|
||||
Obsolete flag, accepted and ignored for compatibility.
|
||||
.It Fl R
|
||||
Use RFC 2822 date and time output format.
|
||||
This is equivalent to using
|
||||
|
@ -108,7 +108,7 @@ main(int argc, char *argv[])
|
||||
(void) setlocale(LC_TIME, "");
|
||||
rflag = 0;
|
||||
Iflag = jflag = Rflag = 0;
|
||||
while ((ch = getopt(argc, argv, "f:I::jRr:uv:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "f:I::jnRr:uv:")) != -1)
|
||||
switch((char)ch) {
|
||||
case 'f':
|
||||
fmt = optarg;
|
||||
@ -132,6 +132,8 @@ main(int argc, char *argv[])
|
||||
case 'j':
|
||||
jflag = 1; /* don't set time */
|
||||
break;
|
||||
case 'n':
|
||||
break;
|
||||
case 'R': /* RFC 2822 datetime format */
|
||||
if (Iflag)
|
||||
multipleformats();
|
||||
|
@ -58,8 +58,26 @@ DIR=/var/tmp/dtest.$$
|
||||
|
||||
sctpport=1024
|
||||
bound=5000
|
||||
|
||||
mkdir $DIR
|
||||
cd $DIR
|
||||
|
||||
cat > client.pl <<-EOPERL
|
||||
use IO::Socket;
|
||||
my \$s = IO::Socket::INET->new(
|
||||
Type => SOCK_STREAM,
|
||||
Proto => "sctp",
|
||||
LocalAddr => "$local",
|
||||
PeerAddr => "$local",
|
||||
PeerPort => \$ARGV[0],
|
||||
Timeout => 3);
|
||||
die "Could not connect to host $local port \$ARGV[0] \$@" unless \$s;
|
||||
close \$s;
|
||||
sleep(\$ARGV[1]);
|
||||
EOPERL
|
||||
|
||||
while [ $sctpport -lt $bound ]; do
|
||||
ncat --sctp -z $local $sctpport > /dev/null || break
|
||||
perl client.pl $sctpport 0 2>&- || break
|
||||
sctpport=$(($sctpport + 1))
|
||||
done
|
||||
if [ $sctpport -eq $bound ]; then
|
||||
@ -67,27 +85,25 @@ if [ $sctpport -eq $bound ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir $DIR
|
||||
cd $DIR
|
||||
|
||||
# ncat will exit when the association is closed.
|
||||
ncat --sctp --listen $local $sctpport &
|
||||
|
||||
cat > test.pl <<-EOPERL
|
||||
cat > server.pl <<-EOPERL
|
||||
use IO::Socket;
|
||||
my \$s = IO::Socket::INET->new(
|
||||
my \$l = IO::Socket::INET->new(
|
||||
Type => SOCK_STREAM,
|
||||
Proto => "sctp",
|
||||
LocalAddr => "$local",
|
||||
PeerAddr => "$local",
|
||||
PeerPort => $sctpport,
|
||||
Timeout => 3);
|
||||
die "Could not connect to host $local port $sctpport \$@" unless \$s;
|
||||
close \$s;
|
||||
sleep(2);
|
||||
LocalPort => $sctpport,
|
||||
Listen => 1,
|
||||
Reuse => 1);
|
||||
die "Could not listen on $local port $sctpport \$@" unless \$l;
|
||||
my \$c = \$l->accept();
|
||||
close \$l;
|
||||
while (<\$c>) {};
|
||||
close \$c;
|
||||
EOPERL
|
||||
|
||||
$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
|
||||
perl server.pl &
|
||||
|
||||
$dtrace -c "perl client.pl $sctpport 2" -qs /dev/stdin <<EODTRACE
|
||||
BEGIN
|
||||
{
|
||||
ipsend = sctpsend = ipreceive = sctpreceive = 0;
|
||||
@ -122,10 +138,10 @@ sctp:::receive
|
||||
END
|
||||
{
|
||||
printf("Minimum SCTP events seen\n\n");
|
||||
printf("ip:::send (%d) - %s\n", ipsend, ipsend >= 7 ? "yes" : "no");
|
||||
printf("ip:::receive (%d) - %s\n", ipreceive, ipreceive >= 7 ? "yes" : "no");
|
||||
printf("sctp:::send (%d) - %s\n", sctpsend, sctpsend >= 7 ? "yes" : "no");
|
||||
printf("sctp:::receive (%d) - %s\n", sctpreceive, sctpreceive >= 7 ? "yes" : "no");
|
||||
printf("ip:::send - %s\n", ipsend >= 7 ? "yes" : "no");
|
||||
printf("ip:::receive - %s\n", ipreceive >= 7 ? "yes" : "no");
|
||||
printf("sctp:::send - %s\n", sctpsend >= 7 ? "yes" : "no");
|
||||
printf("sctp:::receive - %s\n", sctpreceive >= 7 ? "yes" : "no");
|
||||
}
|
||||
EODTRACE
|
||||
|
||||
|
@ -61,8 +61,26 @@ DIR=/var/tmp/dtest.$$
|
||||
|
||||
sctpport=1024
|
||||
bound=5000
|
||||
|
||||
mkdir $DIR
|
||||
cd $DIR
|
||||
|
||||
cat > client.pl <<-EOPERL
|
||||
use IO::Socket;
|
||||
my \$s = IO::Socket::INET->new(
|
||||
Type => SOCK_STREAM,
|
||||
Proto => "sctp",
|
||||
LocalAddr => "$local",
|
||||
PeerAddr => "$local",
|
||||
PeerPort => \$ARGV[0],
|
||||
Timeout => 3);
|
||||
die "Could not connect to host $local port \$ARGV[0] \$@" unless \$s;
|
||||
close \$s;
|
||||
sleep(\$ARGV[1]);
|
||||
EOPERL
|
||||
|
||||
while [ $sctpport -lt $bound ]; do
|
||||
ncat --sctp -z $local $sctpport > /dev/null || break
|
||||
perl client.pl $sctpport 0 2>&- || break
|
||||
sctpport=$(($sctpport + 1))
|
||||
done
|
||||
if [ $sctpport -eq $bound ]; then
|
||||
@ -70,27 +88,25 @@ if [ $sctpport -eq $bound ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir $DIR
|
||||
cd $DIR
|
||||
|
||||
# ncat will exit when the association is closed.
|
||||
ncat --sctp --listen $local $sctpport &
|
||||
|
||||
cat > test.pl <<-EOPERL
|
||||
cat > server.pl <<-EOPERL
|
||||
use IO::Socket;
|
||||
my \$s = IO::Socket::INET->new(
|
||||
my \$l = IO::Socket::INET->new(
|
||||
Type => SOCK_STREAM,
|
||||
Proto => "sctp",
|
||||
LocalAddr => "$local",
|
||||
PeerAddr => "$local",
|
||||
PeerPort => $sctpport,
|
||||
Timeout => 3);
|
||||
die "Could not connect to host $local port $sctpport \$@" unless \$s;
|
||||
close \$s;
|
||||
sleep(2);
|
||||
LocalPort => $sctpport,
|
||||
Listen => 1,
|
||||
Reuse => 1);
|
||||
die "Could not listen on $local port $sctpport \$@" unless \$l;
|
||||
my \$c = \$l->accept();
|
||||
close \$l;
|
||||
while (<\$c>) {};
|
||||
close \$c;
|
||||
EOPERL
|
||||
|
||||
$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
|
||||
perl server.pl &
|
||||
|
||||
$dtrace -c "perl client.pl $sctpport 2" -qs /dev/stdin <<EODTRACE
|
||||
BEGIN
|
||||
{
|
||||
ipsend = sctpsend = ipreceive = sctpreceive = 0;
|
||||
|
@ -10,3 +10,4 @@ sctp:::state-change to established - yes
|
||||
sctp:::state-change to shutdown-sent - yes
|
||||
sctp:::state-change to shutdown-received - yes
|
||||
sctp:::state-change to shutdown-ack-sent - yes
|
||||
|
||||
|
@ -225,7 +225,7 @@ zfs_compare(const void *larg, const void *rarg, void *unused)
|
||||
*rat = '\0';
|
||||
|
||||
ret = strcmp(lname, rname);
|
||||
if (ret == 0) {
|
||||
if (ret == 0 && (lat != NULL || rat != NULL)) {
|
||||
/*
|
||||
* If we're comparing a dataset to one of its snapshots, we
|
||||
* always make the full dataset first.
|
||||
|
@ -30,7 +30,7 @@ INCFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
|
||||
INCFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
INCFLAGS+= -I${SRCTOP}/cddl/usr.sbin
|
||||
|
||||
CFLAGS= -g -DNEED_SOLARIS_BOOLEAN ${INCFLAGS}
|
||||
CFLAGS+= -DNEED_SOLARIS_BOOLEAN ${INCFLAGS}
|
||||
|
||||
LIBADD+= devdctl zfs zfs_core util geom bsdxml sbuf nvpair uutil
|
||||
|
||||
|
@ -225,6 +225,15 @@ struct flag_desc {
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
struct loc_at {
|
||||
Dwarf_Attribute la_at;
|
||||
Dwarf_Unsigned la_off;
|
||||
Dwarf_Unsigned la_lowpc;
|
||||
Dwarf_Half la_cu_psize;
|
||||
Dwarf_Half la_cu_osize;
|
||||
Dwarf_Half la_cu_ver;
|
||||
};
|
||||
|
||||
static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op,
|
||||
int t);
|
||||
static const char *aeabi_adv_simd_arch(uint64_t simd);
|
||||
@ -341,6 +350,7 @@ static const char *get_string(struct readelf *re, int strtab, size_t off);
|
||||
static const char *get_symbol_name(struct readelf *re, int symtab, int i);
|
||||
static uint64_t get_symbol_value(struct readelf *re, int symtab, int i);
|
||||
static void load_sections(struct readelf *re);
|
||||
static int loc_at_comparator(const void *la1, const void *la2);
|
||||
static const char *mips_abi_fp(uint64_t fp);
|
||||
static const char *note_type(const char *note_name, unsigned int et,
|
||||
unsigned int nt);
|
||||
@ -359,7 +369,8 @@ static const char *ppc_abi_vector(uint64_t vec);
|
||||
static void readelf_usage(int status);
|
||||
static void readelf_version(void);
|
||||
static void search_loclist_at(struct readelf *re, Dwarf_Die die,
|
||||
Dwarf_Unsigned lowpc);
|
||||
Dwarf_Unsigned lowpc, struct loc_at **la_list,
|
||||
size_t *la_list_len, size_t *la_list_cap);
|
||||
static void search_ver(struct readelf *re);
|
||||
static const char *section_type(unsigned int mach, unsigned int stype);
|
||||
static void set_cu_context(struct readelf *re, Dwarf_Half psize,
|
||||
@ -6034,21 +6045,27 @@ dump_dwarf_str(struct readelf *re)
|
||||
}
|
||||
}
|
||||
|
||||
struct loc_at {
|
||||
Dwarf_Attribute la_at;
|
||||
Dwarf_Unsigned la_off;
|
||||
Dwarf_Unsigned la_lowpc;
|
||||
Dwarf_Half la_cu_psize;
|
||||
Dwarf_Half la_cu_osize;
|
||||
Dwarf_Half la_cu_ver;
|
||||
TAILQ_ENTRY(loc_at) la_next;
|
||||
};
|
||||
static int
|
||||
loc_at_comparator(const void *la1, const void *la2)
|
||||
{
|
||||
const struct loc_at *left, *right;
|
||||
|
||||
static TAILQ_HEAD(, loc_at) lalist = TAILQ_HEAD_INITIALIZER(lalist);
|
||||
left = (const struct loc_at *)la1;
|
||||
right = (const struct loc_at *)la2;
|
||||
|
||||
if (left->la_off > right->la_off)
|
||||
return (1);
|
||||
else if (left->la_off < right->la_off)
|
||||
return (-1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc)
|
||||
search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc,
|
||||
struct loc_at **la_list, size_t *la_list_len, size_t *la_list_cap)
|
||||
{
|
||||
struct loc_at *la;
|
||||
Dwarf_Attribute *attr_list;
|
||||
Dwarf_Die ret_die;
|
||||
Dwarf_Unsigned off;
|
||||
@ -6057,7 +6074,6 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc)
|
||||
Dwarf_Half attr, form;
|
||||
Dwarf_Bool is_info;
|
||||
Dwarf_Error de;
|
||||
struct loc_at *la, *nla;
|
||||
int i, ret;
|
||||
|
||||
is_info = dwarf_get_die_infotypes_flag(die);
|
||||
@ -6105,33 +6121,21 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc)
|
||||
} else
|
||||
continue;
|
||||
|
||||
TAILQ_FOREACH(la, &lalist, la_next) {
|
||||
if (off == la->la_off)
|
||||
break;
|
||||
if (off < la->la_off) {
|
||||
if ((nla = malloc(sizeof(*nla))) == NULL)
|
||||
err(EXIT_FAILURE, "malloc failed");
|
||||
nla->la_at = attr_list[i];
|
||||
nla->la_off = off;
|
||||
nla->la_lowpc = lowpc;
|
||||
nla->la_cu_psize = re->cu_psize;
|
||||
nla->la_cu_osize = re->cu_osize;
|
||||
nla->la_cu_ver = re->cu_ver;
|
||||
TAILQ_INSERT_BEFORE(la, nla, la_next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (la == NULL) {
|
||||
if ((nla = malloc(sizeof(*nla))) == NULL)
|
||||
err(EXIT_FAILURE, "malloc failed");
|
||||
nla->la_at = attr_list[i];
|
||||
nla->la_off = off;
|
||||
nla->la_lowpc = lowpc;
|
||||
nla->la_cu_psize = re->cu_psize;
|
||||
nla->la_cu_osize = re->cu_osize;
|
||||
nla->la_cu_ver = re->cu_ver;
|
||||
TAILQ_INSERT_TAIL(&lalist, nla, la_next);
|
||||
if (*la_list_cap == *la_list_len) {
|
||||
*la_list = realloc(*la_list,
|
||||
*la_list_cap * 2 * sizeof(**la_list));
|
||||
if (la_list == NULL)
|
||||
errx(EXIT_FAILURE, "realloc failed");
|
||||
*la_list_cap *= 2;
|
||||
}
|
||||
la = &((*la_list)[*la_list_len]);
|
||||
la->la_at = attr_list[i];
|
||||
la->la_off = off;
|
||||
la->la_lowpc = lowpc;
|
||||
la->la_cu_psize = re->cu_psize;
|
||||
la->la_cu_osize = re->cu_osize;
|
||||
la->la_cu_ver = re->cu_ver;
|
||||
(*la_list_len)++;
|
||||
}
|
||||
|
||||
cont_search:
|
||||
@ -6140,14 +6144,16 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc)
|
||||
if (ret == DW_DLV_ERROR)
|
||||
warnx("dwarf_child: %s", dwarf_errmsg(de));
|
||||
else if (ret == DW_DLV_OK)
|
||||
search_loclist_at(re, ret_die, lowpc);
|
||||
search_loclist_at(re, ret_die, lowpc, la_list,
|
||||
la_list_len, la_list_cap);
|
||||
|
||||
/* Search sibling. */
|
||||
ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de);
|
||||
if (ret == DW_DLV_ERROR)
|
||||
warnx("dwarf_siblingof: %s", dwarf_errmsg(de));
|
||||
else if (ret == DW_DLV_OK)
|
||||
search_loclist_at(re, ret_die, lowpc);
|
||||
search_loclist_at(re, ret_die, lowpc, la_list,
|
||||
la_list_len, la_list_cap);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6430,9 +6436,15 @@ dump_dwarf_loclist(struct readelf *re)
|
||||
Dwarf_Signed lcnt;
|
||||
Dwarf_Half tag, version, pointer_size, off_size;
|
||||
Dwarf_Error de;
|
||||
struct loc_at *la;
|
||||
struct loc_at *la_list, *left, *right, *la;
|
||||
size_t la_list_len, la_list_cap;
|
||||
unsigned int duplicates, k;
|
||||
int i, j, ret, has_content;
|
||||
|
||||
la_list_len = 0;
|
||||
la_list_cap = 200;
|
||||
if ((la_list = calloc(la_list_cap, sizeof(struct loc_at))) == NULL)
|
||||
errx(EXIT_FAILURE, "calloc failed");
|
||||
/* Search .debug_info section. */
|
||||
while ((ret = dwarf_next_cu_header_b(re->dbg, NULL, &version, NULL,
|
||||
&pointer_size, &off_size, NULL, NULL, &de)) == DW_DLV_OK) {
|
||||
@ -6453,7 +6465,8 @@ dump_dwarf_loclist(struct readelf *re)
|
||||
}
|
||||
|
||||
/* Search attributes for reference to .debug_loc section. */
|
||||
search_loclist_at(re, die, lowpc);
|
||||
search_loclist_at(re, die, lowpc, &la_list,
|
||||
&la_list_len, &la_list_cap);
|
||||
}
|
||||
if (ret == DW_DLV_ERROR)
|
||||
warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de));
|
||||
@ -6485,17 +6498,37 @@ dump_dwarf_loclist(struct readelf *re)
|
||||
* Search attributes for reference to .debug_loc
|
||||
* section.
|
||||
*/
|
||||
search_loclist_at(re, die, lowpc);
|
||||
search_loclist_at(re, die, lowpc, &la_list,
|
||||
&la_list_len, &la_list_cap);
|
||||
}
|
||||
if (ret == DW_DLV_ERROR)
|
||||
warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de));
|
||||
} while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK);
|
||||
|
||||
if (TAILQ_EMPTY(&lalist))
|
||||
if (la_list_len == 0) {
|
||||
free(la_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sort la_list using loc_at_comparator. */
|
||||
qsort(la_list, la_list_len, sizeof(struct loc_at), loc_at_comparator);
|
||||
|
||||
/* Get rid of the duplicates in la_list. */
|
||||
duplicates = 0;
|
||||
for (k = 1; k < la_list_len; ++k) {
|
||||
left = &la_list[k - 1 - duplicates];
|
||||
right = &la_list[k];
|
||||
|
||||
if (left->la_off == right->la_off)
|
||||
duplicates++;
|
||||
else
|
||||
la_list[k - duplicates] = *right;
|
||||
}
|
||||
la_list_len -= duplicates;
|
||||
|
||||
has_content = 0;
|
||||
TAILQ_FOREACH(la, &lalist, la_next) {
|
||||
for (k = 0; k < la_list_len; ++k) {
|
||||
la = &la_list[k];
|
||||
if ((ret = dwarf_loclist_n(la->la_at, &llbuf, &lcnt, &de)) !=
|
||||
DW_DLV_OK) {
|
||||
if (ret != DW_DLV_NO_ENTRY)
|
||||
@ -6545,6 +6578,8 @@ dump_dwarf_loclist(struct readelf *re)
|
||||
|
||||
if (!has_content)
|
||||
printf("\nSection '.debug_loc' has no debugging data.\n");
|
||||
|
||||
free(la_list);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6892,7 +6927,6 @@ dump_elf(struct readelf *re)
|
||||
static void
|
||||
dump_dwarf(struct readelf *re)
|
||||
{
|
||||
struct loc_at *la, *_la;
|
||||
Dwarf_Error de;
|
||||
int error;
|
||||
|
||||
@ -6930,11 +6964,6 @@ dump_dwarf(struct readelf *re)
|
||||
if (re->dop & DW_O)
|
||||
dump_dwarf_loclist(re);
|
||||
|
||||
TAILQ_FOREACH_SAFE(la, &lalist, la_next, _la) {
|
||||
TAILQ_REMOVE(&lalist, la, la_next);
|
||||
free(la);
|
||||
}
|
||||
|
||||
dwarf_finish(re->dbg, &de);
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ main(int argc, char **argv)
|
||||
argv += optind;
|
||||
|
||||
cap_rights_init(&rights, CAP_READ, CAP_SEEK, CAP_FSTAT, CAP_FCNTL);
|
||||
fa = fileargs_init(argc, argv, O_RDONLY, 0, &rights);
|
||||
fa = fileargs_init(argc, argv, O_RDONLY, 0, &rights, FA_OPEN);
|
||||
if (fa == NULL)
|
||||
err(1, "Unable to initialize casper fileargs");
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#
|
||||
|
||||
AC_PREREQ(2.2)
|
||||
AC_INIT([libxo], [1.0.2], [phil@juniper.net])
|
||||
AC_INIT([libxo], [1.0.4], [phil@juniper.net])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
|
||||
|
||||
# Support silent build rules. Requires at least automake-1.11.
|
||||
|
@ -22011,7 +22011,7 @@ jQuery(function ($) {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="header left"></td>
|
||||
<td class="header right">April 2, 2019</td>
|
||||
<td class="header right">April 24, 2019</td>
|
||||
</tr>
|
||||
</table></div>
|
||||
<p id="title" class="title">libxo: The Easy Way to Generate text, XML, JSON, and HTML output<br><span class="filename">libxo-manual</span></p>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Juniper Networks, Inc.
|
||||
* Copyright (c) 2014-2019, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
@ -600,7 +600,7 @@ xo_no_setlocale (void)
|
||||
static const char *
|
||||
xo_xml_leader_len (xo_handle_t *xop, const char *name, xo_ssize_t nlen)
|
||||
{
|
||||
if (isalpha(name[0]) || name[0] == '_')
|
||||
if (name == NULL || isalpha(name[0]) || name[0] == '_')
|
||||
return "";
|
||||
|
||||
xo_failure(xop, "invalid XML tag name: '%.*s'", nlen, name);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Juniper Networks, Inc.
|
||||
* Copyright (c) 2019, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,6 +1,10 @@
|
||||
op create: [] [] [0]
|
||||
op open_container: [top] [] [0x40010]
|
||||
op open_container: [data] [] [0x40010]
|
||||
op string: [name] [em0] [0x1080]
|
||||
op string: [flags] [0x8843] [0x18]
|
||||
op string: [name] [em0] [0x1088]
|
||||
op string: [flags] [0x8843] [0x18]
|
||||
op string: [what] [braces] [0]
|
||||
op string: [length] [abcdef] [0]
|
||||
op content: [fd] [-1] [0]
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,4 +1,4 @@
|
||||
<div class="line"><div class="text">We are </div><div class="text">{emit}</div><div class="text">{ting}</div><div class="text"> some </div><div class="data" data-tag="what">braces</div></div><div class="line"><div class="message">abcdef
|
||||
<div class="line"><div class="data" data-tag="name">em0 </div><div class="data">em0 </div><div class="text">We are </div><div class="text">{emit}</div><div class="text">{ting}</div><div class="text"> some </div><div class="data" data-tag="what">braces</div></div><div class="line"><div class="message">abcdef
|
||||
</div></div><div class="line"><div class="message">abcdef: Bad file descriptor
|
||||
</div></div><div class="line"><div class="message">improper use of profanity; ten yard penalty; first down
|
||||
</div></div><div class="line"><div class="text">length </div><div class="data" data-tag="length">abcdef</div></div><div class="line"><div class="text">close </div><div class="data" data-tag="fd">-1</div><div class="text"> returned </div><div class="data" data-tag="error">Bad file descriptor</div><div class="text"> </div><div class="data" data-tag="test">good</div></div><div class="line"><div class="text">close </div><div class="data" data-tag="fd">-1</div><div class="text"> returned </div><div class="data" data-tag="error">Bad fi</div><div class="text"> </div><div class="data" data-tag="test">good</div></div><div class="line"><div class="message">improper use of profanity; ten yard penalty; first down
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,9 +1,11 @@
|
||||
<div class="line">
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/name">em0 </div>
|
||||
<div class="data">em0 </div>
|
||||
<div class="text">We are </div>
|
||||
<div class="text">{emit}</div>
|
||||
<div class="text">{ting}</div>
|
||||
<div class="text"> some </div>
|
||||
<div class="data" data-tag="what" data-xpath="/top/data/what">braces</div>
|
||||
<div class="data" data-tag="what" data-xpath="/top/data[name = 'em0 '][name = 'em0']/what">braces</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="message">abcdef
|
||||
@ -19,23 +21,23 @@
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">length </div>
|
||||
<div class="data" data-tag="length" data-xpath="/top/data/length">abcdef</div>
|
||||
<div class="data" data-tag="length" data-xpath="/top/data[name = 'em0 '][name = 'em0']/length">abcdef</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">close </div>
|
||||
<div class="data" data-tag="fd" data-xpath="/top/data/fd">-1</div>
|
||||
<div class="data" data-tag="fd" data-xpath="/top/data[name = 'em0 '][name = 'em0']/fd">-1</div>
|
||||
<div class="text"> returned </div>
|
||||
<div class="data" data-tag="error" data-xpath="/top/data/error">Bad file descriptor</div>
|
||||
<div class="data" data-tag="error" data-xpath="/top/data[name = 'em0 '][name = 'em0']/error">Bad file descriptor</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="test" data-xpath="/top/data/test">good</div>
|
||||
<div class="data" data-tag="test" data-xpath="/top/data[name = 'em0 '][name = 'em0']/test">good</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">close </div>
|
||||
<div class="data" data-tag="fd" data-xpath="/top/data/fd">-1</div>
|
||||
<div class="data" data-tag="fd" data-xpath="/top/data[name = 'em0 '][name = 'em0']/fd">-1</div>
|
||||
<div class="text"> returned </div>
|
||||
<div class="data" data-tag="error" data-xpath="/top/data/error">Bad fi</div>
|
||||
<div class="data" data-tag="error" data-xpath="/top/data[name = 'em0 '][name = 'em0']/error">Bad fi</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="test" data-xpath="/top/data/test">good</div>
|
||||
<div class="data" data-tag="test" data-xpath="/top/data[name = 'em0 '][name = 'em0']/test">good</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="message">improper use of profanity; ten yard penalty; first down
|
||||
@ -43,155 +45,155 @@
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="lines" data-xpath="/top/data/lines"> 20</div>
|
||||
<div class="data" data-tag="lines" data-xpath="/top/data[name = 'em0 '][name = 'em0']/lines"> 20</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="words" data-xpath="/top/data/words"> 30</div>
|
||||
<div class="data" data-tag="words" data-xpath="/top/data[name = 'em0 '][name = 'em0']/words"> 30</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="characters" data-xpath="/top/data/characters"> 40</div>
|
||||
<div class="data" data-tag="characters" data-xpath="/top/data[name = 'em0 '][name = 'em0']/characters"> 40</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="filename" data-xpath="/top/data/filename">file</div>
|
||||
<div class="data" data-tag="filename" data-xpath="/top/data[name = 'em0 '][name = 'em0']/filename">file</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">0</div>
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data[name = 'em0 '][name = 'em0']/bytes">0</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="note">bytes</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">1</div>
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data[name = 'em0 '][name = 'em0']/bytes">1</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="note">byte</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">2</div>
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data[name = 'em0 '][name = 'em0']/bytes">2</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="note">bytes</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">3</div>
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data[name = 'em0 '][name = 'em0']/bytes">3</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="note">bytes</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data/bytes">4</div>
|
||||
<div class="data" data-tag="bytes" data-xpath="/top/data[name = 'em0 '][name = 'em0']/bytes">4</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="note">bytes</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="mbuf-current" data-xpath="/top/data/mbuf-current">10</div>
|
||||
<div class="data" data-tag="mbuf-current" data-xpath="/top/data[name = 'em0 '][name = 'em0']/mbuf-current">10</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="mbuf-cache" data-xpath="/top/data/mbuf-cache">20</div>
|
||||
<div class="data" data-tag="mbuf-cache" data-xpath="/top/data[name = 'em0 '][name = 'em0']/mbuf-cache">20</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="mbuf-total" data-xpath="/top/data/mbuf-total">30</div>
|
||||
<div class="data" data-tag="mbuf-total" data-xpath="/top/data[name = 'em0 '][name = 'em0']/mbuf-total">30</div>
|
||||
<div class="text"> </div>
|
||||
<div class="note">mbufs <&> in use (current/cache/total)</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="distance" data-units="miles" data-xpath="/top/data/distance">50</div>
|
||||
<div class="data" data-tag="distance" data-units="miles" data-xpath="/top/data[name = 'em0 '][name = 'em0']/distance">50</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="text"> from </div>
|
||||
<div class="data" data-tag="location" data-xpath="/top/data/location">Boston</div>
|
||||
<div class="data" data-tag="location" data-xpath="/top/data[name = 'em0 '][name = 'em0']/location">Boston</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="memory" data-units="k" data-xpath="/top/data/memory">64</div>
|
||||
<div class="data" data-tag="memory" data-units="k" data-xpath="/top/data[name = 'em0 '][name = 'em0']/memory">64</div>
|
||||
<div class="text"> left out of </div>
|
||||
<div class="data" data-tag="total" data-units="kb" data-xpath="/top/data/total">640</div>
|
||||
<div class="data" data-tag="total" data-units="kb" data-xpath="/top/data[name = 'em0 '][name = 'em0']/total">640</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="memory" data-units="k" data-xpath="/top/data/memory">64</div>
|
||||
<div class="data" data-tag="memory" data-units="k" data-xpath="/top/data[name = 'em0 '][name = 'em0']/memory">64</div>
|
||||
<div class="text"> left out of </div>
|
||||
<div class="data" data-tag="total" data-units="kilobytes" data-xpath="/top/data/total">640</div>
|
||||
<div class="data" data-tag="total" data-units="kilobytes" data-xpath="/top/data[name = 'em0 '][name = 'em0']/total">640</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="title">beforeworkingafter:</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="some" data-xpath="/top/data/some">string</div>
|
||||
<div class="data" data-tag="some" data-xpath="/top/data[name = 'em0 '][name = 'em0']/some">string</div>
|
||||
<div class="decoration">:</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="data" data-tag="ten" data-xpath="/top/data/ten">10</div>
|
||||
<div class="data" data-tag="eleven" data-xpath="/top/data/eleven">11</div>
|
||||
<div class="data" data-tag="ten" data-xpath="/top/data[name = 'em0 '][name = 'em0']/ten">10</div>
|
||||
<div class="data" data-tag="eleven" data-xpath="/top/data[name = 'em0 '][name = 'em0']/eleven">11</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="unknown" data-xpath="/top/data/unknown">1010</div>
|
||||
<div class="data" data-tag="unknown" data-xpath="/top/data[name = 'em0 '][name = 'em0']/unknown">1010</div>
|
||||
<div class="text"> </div>
|
||||
<div class="note">packets here/there/everywhere</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="unknown" data-xpath="/top/data/unknown">1010</div>
|
||||
<div class="data" data-tag="unknown" data-xpath="/top/data[name = 'em0 '][name = 'em0']/unknown">1010</div>
|
||||
<div class="text"> </div>
|
||||
<div class="note">packets here/there/everywhere</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">(</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data/min">15</div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data[name = 'em0 '][name = 'em0']/min">15</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data[name = 'em0 '][name = 'em0']/cur">20</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data/max">125</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data[name = 'em0 '][name = 'em0']/max">125</div>
|
||||
<div class="text">)</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">(</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data/min">15</div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data[name = 'em0 '][name = 'em0']/min">15</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data[name = 'em0 '][name = 'em0']/cur">20</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data/max">125</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data[name = 'em0 '][name = 'em0']/max">125</div>
|
||||
<div class="text">)</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">(</div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data/min">15</div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data[name = 'em0 '][name = 'em0']/min">15</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data[name = 'em0 '][name = 'em0']/cur">20</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data/max">125</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data[name = 'em0 '][name = 'em0']/max">125</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="text">)</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">(</div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data/min">15</div>
|
||||
<div class="data" data-tag="min" data-xpath="/top/data[name = 'em0 '][name = 'em0']/min">15</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div>
|
||||
<div class="data" data-tag="cur" data-xpath="/top/data[name = 'em0 '][name = 'em0']/cur">20</div>
|
||||
<div class="text">/</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data/max">125</div>
|
||||
<div class="data" data-tag="max" data-xpath="/top/data[name = 'em0 '][name = 'em0']/max">125</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="text">)</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">Humanize: </div>
|
||||
<div class="data" data-tag="val1" data-xpath="/top/data/val1" data-number="21">21</div>
|
||||
<div class="data" data-tag="val1" data-xpath="/top/data[name = 'em0 '][name = 'em0']/val1" data-number="21">21</div>
|
||||
<div class="text">, </div>
|
||||
<div class="data" data-tag="val2" data-xpath="/top/data/val2" data-number="58368">57 K</div>
|
||||
<div class="data" data-tag="val2" data-xpath="/top/data[name = 'em0 '][name = 'em0']/val2" data-number="58368">57 K</div>
|
||||
<div class="text">, </div>
|
||||
<div class="data" data-tag="val3" data-xpath="/top/data/val3" data-number="100663296">96M</div>
|
||||
<div class="data" data-tag="val3" data-xpath="/top/data[name = 'em0 '][name = 'em0']/val3" data-number="100663296">96M</div>
|
||||
<div class="text">, </div>
|
||||
<div class="data" data-tag="val4" data-xpath="/top/data/val4" data-number="44470272">44M</div>
|
||||
<div class="data" data-tag="val4" data-xpath="/top/data[name = 'em0 '][name = 'em0']/val4" data-number="44470272">44M</div>
|
||||
<div class="text">, </div>
|
||||
<div class="data" data-tag="val5" data-xpath="/top/data/val5" data-number="1342172800">1.2G</div>
|
||||
<div class="data" data-tag="val5" data-xpath="/top/data[name = 'em0 '][name = 'em0']/val5" data-number="1342172800">1.2G</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="flag" data-xpath="/top/data/flag">one</div>
|
||||
<div class="data" data-tag="flag" data-xpath="/top/data[name = 'em0 '][name = 'em0']/flag">one</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="flag" data-xpath="/top/data/flag">two</div>
|
||||
<div class="data" data-tag="flag" data-xpath="/top/data[name = 'em0 '][name = 'em0']/flag">two</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="flag" data-xpath="/top/data/flag">three</div>
|
||||
<div class="data" data-tag="flag" data-xpath="/top/data[name = 'em0 '][name = 'em0']/flag">three</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="works" data-xpath="/top/data/works">(null)</div>
|
||||
<div class="data" data-tag="works" data-xpath="/top/data[name = 'em0 '][name = 'em0']/works">(null)</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">1:</div>
|
||||
<div class="data" data-tag="t1" data-xpath="/top/data/t1"> 1000</div>
|
||||
<div class="data" data-tag="t1" data-xpath="/top/data[name = 'em0 '][name = 'em0']/t1"> 1000</div>
|
||||
<div class="text"> 2:</div>
|
||||
<div class="data" data-tag="t2" data-xpath="/top/data/t2">test5000 </div>
|
||||
<div class="data" data-tag="t2" data-xpath="/top/data[name = 'em0 '][name = 'em0']/t2">test5000 </div>
|
||||
<div class="text"> 3:</div>
|
||||
<div class="data" data-tag="t3" data-xpath="/top/data/t3"> ten-longx</div>
|
||||
<div class="data" data-tag="t3" data-xpath="/top/data[name = 'em0 '][name = 'em0']/t3"> ten-longx</div>
|
||||
<div class="text"> 4:</div>
|
||||
<div class="data" data-tag="t4" data-xpath="/top/data/t4">xtest </div>
|
||||
<div class="data" data-tag="t4" data-xpath="/top/data[name = 'em0 '][name = 'em0']/t4">xtest </div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="error">this is an error</div>
|
||||
@ -208,10 +210,10 @@
|
||||
<div class="line">
|
||||
<div class="label">V1/V2 packets</div>
|
||||
<div class="text">: </div>
|
||||
<div class="data" data-tag="count" data-xpath="/top/data/count">10</div>
|
||||
<div class="data" data-tag="count" data-xpath="/top/data[name = 'em0 '][name = 'em0']/count">10</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="test" data-xpath="/top/data/test">0004</div>
|
||||
<div class="data" data-tag="test" data-xpath="/top/data[name = 'em0 '][name = 'em0']/test">0004</div>
|
||||
<div class="text"> </div>
|
||||
<div class="label">tries</div>
|
||||
</div>
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,4 +1,6 @@
|
||||
<div class="line">
|
||||
<div class="data" data-tag="name">em0 </div>
|
||||
<div class="data">em0 </div>
|
||||
<div class="text">We are </div>
|
||||
<div class="text">{emit}</div>
|
||||
<div class="text">{ting}</div>
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1 +1 @@
|
||||
{"top": {"data": {"what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}}
|
||||
{"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}}
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,6 +1,10 @@
|
||||
{
|
||||
"top": {
|
||||
"data": {
|
||||
"name": "em0",
|
||||
"flags": "0x8843",
|
||||
"name": "em0",
|
||||
"flags": "0x8843",
|
||||
"what": "braces",
|
||||
"length": "abcdef",
|
||||
"fd": -1,
|
||||
|
@ -1 +1,2 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
||||
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||
|
@ -1,4 +1,4 @@
|
||||
We are {emit}{ting} some braces
|
||||
em0 em0 We are {emit}{ting} some braces
|
||||
abcdef
|
||||
abcdef: Bad file descriptor
|
||||
improper use of profanity; ten yard penalty; first down
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,4 +1,4 @@
|
||||
<top><data><what>braces</what><message>abcdef
|
||||
<top><data><name>em0</name><flags>0x8843</flags><name>em0</name><flags>0x8843</flags><what>braces</what><message>abcdef
|
||||
</message><message>abcdef: Bad file descriptor
|
||||
</message><message>improper use of profanity; ten yard penalty; first down
|
||||
</message><length>abcdef</length><fd>-1</fd><error>Bad file descriptor</error><test>good</test><fd>-1</fd><error>Bad fi</error><test>good</test><message>improper use of profanity; ten yard penalty; first down
|
||||
|
@ -0,0 +1 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
@ -1,5 +1,9 @@
|
||||
<top>
|
||||
<data>
|
||||
<name>em0</name>
|
||||
<flags>0x8843</flags>
|
||||
<name>em0</name>
|
||||
<flags>0x8843</flags>
|
||||
<what>braces</what>
|
||||
<message>abcdef
|
||||
</message>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Juniper Networks, Inc.
|
||||
* Copyright (c) 2014-2019, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Juniper Networks, Inc.
|
||||
* Copyright (c) 2014-2019, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
@ -48,6 +48,12 @@ main (int argc, char **argv)
|
||||
|
||||
xo_open_container("data");
|
||||
|
||||
xo_emit("{kt:name/%-*.*s}{eq:flags/0x%x}",
|
||||
5, 5, "em0", 34883);
|
||||
|
||||
xo_emit("{d:/%-*.*s}{etk:name}{eq:flags/0x%x}",
|
||||
5, 5, "em0", "em0", 34883);
|
||||
|
||||
xo_emit("We are {{emit}}{{ting}} some {:what}\n", "braces");
|
||||
|
||||
xo_message("abcdef");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Juniper Networks, Inc.
|
||||
* Copyright (c) 2014-2019, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
|
@ -1984,32 +1984,10 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
// Build a sequence of copy-to-reg nodes chained together with token chain
|
||||
// and flag operands which copy the outgoing args into the appropriate regs.
|
||||
SDValue InFlag;
|
||||
// Tail call byval lowering might overwrite argument registers so in case of
|
||||
// tail call optimization the copies to registers are lowered later.
|
||||
if (!isTailCall)
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
// For tail calls lower the arguments to the 'real' stack slot.
|
||||
if (isTailCall) {
|
||||
// Force all the incoming stack arguments to be loaded from the stack
|
||||
// before any new outgoing arguments are stored to the stack, because the
|
||||
// outgoing stack slots may alias the incoming argument stack slots, and
|
||||
// the alias isn't otherwise explicit. This is slightly more conservative
|
||||
// than necessary, because it means that each store effectively depends
|
||||
// on every argument instead of just those arguments it would clobber.
|
||||
|
||||
// Do not flag preceding copytoreg stuff together with the following stuff.
|
||||
InFlag = SDValue();
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
InFlag = SDValue();
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
|
||||
|
@ -1,4 +1,4 @@
|
||||
$Id: INSTALL,v 1.22 2018/07/31 15:34:00 schwarze Exp $
|
||||
$Id: INSTALL,v 1.23 2019/03/06 15:58:10 schwarze Exp $
|
||||
|
||||
About the portable mandoc distribution
|
||||
--------------------------------------
|
||||
@ -18,7 +18,7 @@ tech@ mailing list, too.
|
||||
|
||||
Enjoy using the mandoc toolset!
|
||||
|
||||
Ingo Schwarze, Karlsruhe, August 2018
|
||||
Ingo Schwarze, Karlsruhe, March 2019
|
||||
|
||||
|
||||
Installation
|
||||
@ -67,7 +67,8 @@ variables into "configure.local" and go back to step 4.
|
||||
7. Optionally run the regression suite.
|
||||
Basically, that amounts to "cd regress && ./regress.pl".
|
||||
But you should probably look at "./mandoc -l regress/regress.pl.1"
|
||||
first.
|
||||
first. In particular, regarding Solaris systems, look at the BUGS
|
||||
section of that manual page.
|
||||
|
||||
8. Run "sudo make install". If you intend to build a binary
|
||||
package using some kind of fake root mechanism, you may need a
|
||||
|
@ -1,8 +1,8 @@
|
||||
$Id: LICENSE,v 1.19 2018/07/31 10:18:15 schwarze Exp $
|
||||
$Id: LICENSE,v 1.21 2018/11/26 17:11:11 schwarze Exp $
|
||||
|
||||
With the exceptions noted below, all code and documentation
|
||||
contained in the mandoc toolkit is protected by the Copyright
|
||||
of the following developers:
|
||||
With the exceptions noted below, all non-trivial files contained
|
||||
in the mandoc toolkit are protected by the Copyright of the following
|
||||
developers:
|
||||
|
||||
Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -12,13 +12,14 @@ Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
Copyright (c) 2014 Baptiste Daroussin <bapt@freebsd.org>
|
||||
Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
Copyright (c) 2017 Anthony Bentley <bentley@openbsd.org>
|
||||
Copyright (c) 1998, 2004, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
|
||||
Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
|
||||
Copyright (c) 1994 Christos Zoulas <christos@netbsd.org>
|
||||
Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
|
||||
|
||||
See the individual source files for information about who contributed
|
||||
See the individual files for information about who contributed
|
||||
to which file during which years.
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: Makefile,v 1.519 2018/07/31 15:34:00 schwarze Exp $
|
||||
# $Id: Makefile,v 1.530 2019/03/06 16:08:41 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
# Copyright (c) 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2011, 2013-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
VERSION = 1.14.4
|
||||
VERSION = 1.14.5
|
||||
|
||||
# === LIST OF FILES ====================================================
|
||||
|
||||
@ -37,9 +37,9 @@ TESTSRCS = test-be32toh.c \
|
||||
test-PATH_MAX.c \
|
||||
test-pledge.c \
|
||||
test-progname.c \
|
||||
test-recvmsg.c \
|
||||
test-reallocarray.c \
|
||||
test-recallocarray.c \
|
||||
test-recvmsg.c \
|
||||
test-rewb-bsd.c \
|
||||
test-rewb-sysv.c \
|
||||
test-sandbox_init.c \
|
||||
@ -54,7 +54,8 @@ TESTSRCS = test-be32toh.c \
|
||||
test-vasprintf.c \
|
||||
test-wchar.c
|
||||
|
||||
SRCS = att.c \
|
||||
SRCS = arch.c \
|
||||
att.c \
|
||||
catman.c \
|
||||
cgi.c \
|
||||
chars.c \
|
||||
@ -96,6 +97,7 @@ SRCS = att.c \
|
||||
man_validate.c \
|
||||
mandoc.c \
|
||||
mandoc_aux.c \
|
||||
mandoc_msg.c \
|
||||
mandoc_ohash.c \
|
||||
mandoc_xr.c \
|
||||
mandocd.c \
|
||||
@ -155,13 +157,14 @@ DISTFILES = INSTALL \
|
||||
dbm_map.h \
|
||||
demandoc.1 \
|
||||
eqn.7 \
|
||||
eqn.h \
|
||||
eqn_parse.h \
|
||||
gmdiff \
|
||||
html.h \
|
||||
lib.in \
|
||||
libman.h \
|
||||
libmandoc.h \
|
||||
libmdoc.h \
|
||||
libroff.h \
|
||||
main.h \
|
||||
makewhatis.8 \
|
||||
man.1 \
|
||||
@ -184,6 +187,7 @@ DISTFILES = INSTALL \
|
||||
mandoc_html.3 \
|
||||
mandoc_malloc.3 \
|
||||
mandoc_ohash.h \
|
||||
mandoc_parse.h \
|
||||
mandoc_xr.h \
|
||||
mandocd.8 \
|
||||
mansearch.3 \
|
||||
@ -198,10 +202,12 @@ DISTFILES = INSTALL \
|
||||
roff.h \
|
||||
roff_int.h \
|
||||
soelim.1 \
|
||||
st.in \
|
||||
tag.h \
|
||||
tbl.3 \
|
||||
tbl.7 \
|
||||
tbl.h \
|
||||
tbl_int.h \
|
||||
tbl_parse.h \
|
||||
term.h \
|
||||
$(SRCS) \
|
||||
$(TESTSRCS)
|
||||
@ -230,9 +236,11 @@ LIBROFF_OBJS = eqn.o \
|
||||
LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
||||
$(LIBMDOC_OBJS) \
|
||||
$(LIBROFF_OBJS) \
|
||||
arch.o \
|
||||
chars.o \
|
||||
mandoc.o \
|
||||
mandoc_aux.o \
|
||||
mandoc_msg.o \
|
||||
mandoc_ohash.o \
|
||||
mandoc_xr.o \
|
||||
msec.o \
|
||||
@ -320,6 +328,7 @@ SOELIM_OBJS = soelim.o \
|
||||
WWW_MANS = apropos.1.html \
|
||||
demandoc.1.html \
|
||||
man.1.html \
|
||||
man.options.1.html \
|
||||
mandoc.1.html \
|
||||
soelim.1.html \
|
||||
man.cgi.3.html \
|
||||
@ -336,20 +345,27 @@ WWW_MANS = apropos.1.html \
|
||||
eqn.7.html \
|
||||
man.7.html \
|
||||
mandoc_char.7.html \
|
||||
mandocd.8.html \
|
||||
mdoc.7.html \
|
||||
roff.7.html \
|
||||
tbl.7.html \
|
||||
catman.8.html \
|
||||
makewhatis.8.html \
|
||||
man.cgi.8.html \
|
||||
mandocd.8.html
|
||||
|
||||
WWW_INCS = eqn.h.html \
|
||||
html.h.html \
|
||||
man.h.html \
|
||||
manconf.h.html \
|
||||
mandoc.h.html \
|
||||
mandoc_aux.h.html \
|
||||
mandoc_parse.h.html \
|
||||
mansearch.h.html \
|
||||
mdoc.h.html \
|
||||
roff.h.html
|
||||
roff.h.html \
|
||||
tbl.h.html \
|
||||
tbl_int.h.html \
|
||||
tbl_parse.h.html
|
||||
|
||||
# === USER CONFIGURATION ===============================================
|
||||
|
||||
@ -361,9 +377,9 @@ all: mandoc demandoc soelim $(BUILD_TARGETS) Makefile.local
|
||||
|
||||
install: base-install $(INSTALL_TARGETS)
|
||||
|
||||
www: $(WWW_MANS)
|
||||
www: $(WWW_MANS) $(WWW_INCS)
|
||||
|
||||
$(WWW_MANS): mandoc
|
||||
$(WWW_MANS) $(WWW_INCS): mandoc
|
||||
|
||||
.PHONY: base-install cgi-install install www-install
|
||||
.PHONY: clean distclean depend
|
||||
@ -382,7 +398,7 @@ clean:
|
||||
rm -f mandocd catman catman.o $(MANDOCD_OBJS)
|
||||
rm -f demandoc $(DEMANDOC_OBJS)
|
||||
rm -f soelim $(SOELIM_OBJS)
|
||||
rm -f $(WWW_MANS) mandoc.tar.gz mandoc.sha256
|
||||
rm -f $(WWW_MANS) $(WWW_INCS) mandoc*.tar.gz mandoc*.sha256
|
||||
rm -rf *.dSYM
|
||||
|
||||
base-install: mandoc demandoc soelim
|
||||
@ -420,8 +436,8 @@ lib-install: libmandoc.a
|
||||
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h roff.h \
|
||||
$(DESTDIR)$(INCLUDEDIR)
|
||||
$(INSTALL_LIB) eqn.h man.h mandoc.h mandoc_aux.h mandoc_parse.h \
|
||||
mdoc.h roff.h tbl.h $(DESTDIR)$(INCLUDEDIR)
|
||||
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
|
||||
mansearch.3 mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
|
||||
|
||||
@ -475,11 +491,14 @@ uninstall:
|
||||
rm -f $(DESTDIR)$(MANDIR)/man3/mansearch.3
|
||||
rm -f $(DESTDIR)$(MANDIR)/man3/mchars_alloc.3
|
||||
rm -f $(DESTDIR)$(MANDIR)/man3/tbl.3
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/eqn.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/man.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/mandoc.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/mandoc_aux.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/mandoc_parse.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/mdoc.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/roff.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/tbl.h
|
||||
[ ! -e $(DESTDIR)$(INCLUDEDIR) ] || rmdir $(DESTDIR)$(INCLUDEDIR)
|
||||
|
||||
regress: all
|
||||
@ -516,7 +535,9 @@ soelim: $(SOELIM_OBJS)
|
||||
# --- maintainer targets ---
|
||||
|
||||
www-install: www
|
||||
$(INSTALL_DATA) $(WWW_MANS) mandoc.css $(HTDOCDIR)
|
||||
$(INSTALL_DATA) mandoc.css $(HTDOCDIR)
|
||||
$(INSTALL_DATA) $(WWW_MANS) $(HTDOCDIR)/man
|
||||
$(INSTALL_DATA) $(WWW_INCS) $(HTDOCDIR)/includes
|
||||
|
||||
depend: config.h
|
||||
mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
|
||||
@ -564,6 +585,10 @@ mandoc-$(VERSION).tar.gz: $(DISTFILES)
|
||||
( cd .dist/ && tar zcf ../$@ mandoc-$(VERSION) )
|
||||
rm -rf .dist/
|
||||
|
||||
dist-install: dist
|
||||
$(INSTALL_DATA) mandoc-$(VERSION).tar.gz mandoc-$(VERSION).sha256 \
|
||||
$(HTDOCDIR)/snapshots
|
||||
|
||||
# === SUFFIX RULES =====================================================
|
||||
|
||||
.SUFFIXES: .1 .3 .5 .7 .8 .h
|
||||
@ -573,5 +598,6 @@ mandoc-$(VERSION).tar.gz: $(DISTFILES)
|
||||
highlight -I $< > $@
|
||||
|
||||
.1.1.html .3.3.html .5.5.html .7.7.html .8.8.html: mandoc
|
||||
./mandoc -Thtml -Wall,stop \
|
||||
-Ostyle=mandoc.css,man=%N.%S.html,includes=%I.html $< > $@
|
||||
mandoc -Thtml -Wwarning,stop \
|
||||
-O 'style=/mandoc.css,man=/man/%N.%S.html;https://man.openbsd.org/%N.%S,includes=/includes/%I.html' \
|
||||
$< > $@
|
||||
|
@ -1,6 +1,7 @@
|
||||
att.o: att.c config.h mandoc.h roff.h mdoc.h libmdoc.h
|
||||
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 main.h manconf.h mansearch.h cgi.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
|
||||
compat_err.o: compat_err.c config.h
|
||||
compat_fts.o: compat_fts.c config.h compat_fts.h
|
||||
@ -26,54 +27,55 @@ dba_read.o: dba_read.c mandoc_aux.h mansearch.h dba_array.h dba.h dbm.h
|
||||
dba_write.o: dba_write.c config.h dba_write.h
|
||||
dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h
|
||||
dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h
|
||||
demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h
|
||||
eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h libroff.h
|
||||
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
|
||||
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
|
||||
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
|
||||
eqn_html.o: eqn_html.c config.h mandoc.h eqn.h out.h html.h
|
||||
eqn_term.o: eqn_term.c config.h eqn.h out.h term.h
|
||||
html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h
|
||||
lib.o: lib.c config.h mandoc.h roff.h mdoc.h libmdoc.h lib.in
|
||||
main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
|
||||
lib.o: lib.c config.h roff.h libmdoc.h lib.in
|
||||
main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h mandoc_parse.h tag.h main.h manconf.h mansearch.h
|
||||
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 main.h
|
||||
man_term.o: man_term.c config.h mandoc_aux.h roff.h man.h out.h term.h main.h
|
||||
man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h
|
||||
mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h roff_int.h
|
||||
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||
mandoc_msg.o: mandoc_msg.c mandoc.h
|
||||
mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h
|
||||
mandoc_xr.o: mandoc_xr.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.h
|
||||
mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h main.h manconf.h
|
||||
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h dba_array.h dba.h
|
||||
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 manconf.h
|
||||
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
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 mandoc_aux.h mandoc.h roff.h mdoc.h main.h
|
||||
mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
|
||||
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h term.h tag.h main.h
|
||||
mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h roff.h mdoc.h out.h term.h tag.h main.h
|
||||
mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
||||
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
|
||||
preconv.o: preconv.c config.h mandoc.h libmandoc.h
|
||||
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h
|
||||
roff.o: roff.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h libmandoc.h roff_int.h libroff.h predefs.in
|
||||
out.o: out.c config.h mandoc_aux.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
|
||||
roff.o: roff.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mandoc_parse.h libmandoc.h roff_int.h tbl_parse.h eqn_parse.h predefs.in
|
||||
roff_html.o: roff_html.c mandoc.h roff.h out.h html.h
|
||||
roff_term.o: roff_term.c mandoc.h roff.h out.h term.h
|
||||
roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h
|
||||
soelim.o: soelim.c config.h compat_stringlist.h
|
||||
st.o: st.c config.h mandoc.h roff.h mdoc.h libmdoc.h st.in
|
||||
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 tag.h
|
||||
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
tbl_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
tbl_html.o: tbl_html.c config.h mandoc.h out.h html.h
|
||||
tbl_layout.o: tbl_layout.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
tbl_opts.o: tbl_opts.c config.h mandoc.h libmandoc.h libroff.h
|
||||
tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h
|
||||
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 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
|
||||
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 mandoc_aux.h out.h term.h
|
||||
tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h main.h
|
||||
tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h tbl.h eqn.h main.h
|
||||
|
@ -1,7 +1,81 @@
|
||||
$Id: NEWS,v 1.32 2018/08/08 14:47:38 schwarze Exp $
|
||||
$Id: NEWS,v 1.34 2019/03/10 09:32:00 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mandoc.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.14.5, released on March 10, 2019
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
* apropos(1): improve POSIX compliance by accepting case-insensitive
|
||||
extended regular expressions by default
|
||||
* new -O tag[=term] output option (open a page at the definition of a term)
|
||||
* tbl(7) -T html: spanning and horizontal and vertical alignment of cells
|
||||
* tbl(7) -T html: draw lines on the edges of table cells
|
||||
* tbl(7) -T utf8: render lines with the Unicode box drawing characters
|
||||
* mandoc is now able to handle the manual pages of the groff package.
|
||||
--- MINOR NEW FEATURES ---
|
||||
* -T html: new option -O toc (table of contents)
|
||||
* -T html: second argument to -O man to support local and remote links
|
||||
* mdoc(7) .Bd -centered now fills the text contained in it
|
||||
* man-ext .SY and .YS macros (synopsis block)
|
||||
* man-ext .TQ macro (tagged paragraph without vertical space before it)
|
||||
* tbl(7) \& explicit alignment indicator
|
||||
* roff(7) .shift, .while, and .return requests
|
||||
* roff(7) .char request (output glyph definition)
|
||||
* roff(7) .nop request (no operation)
|
||||
* roff(7) .ft request: handle the CB, CI, and CR fonts
|
||||
* roff(7) .if c conditional (character available)
|
||||
* roff(7) \\$@ escape sequence (insert all macro arguments, quoted)
|
||||
* roff(7) \*(.T predefined string (interpolate output device name)
|
||||
* roff(7) \[charNNN] escape sequence (for printable ASCII characters)
|
||||
* roff(7) \# escape sequence (line continuation with comment)
|
||||
--- HTML OUTPUT SYNTAX CORRECTIONS ---
|
||||
* Render .br and \p as <br/>, not as an empty <div>.
|
||||
* Render .Pp and .PP as <p> and automatically close it when needed.
|
||||
* Stop writing empty list elements for non-compact .Bl -tag lists.
|
||||
* Do not put <p> inside <a> if .UR or .MT contain .PP.
|
||||
* Implement tooltips purely in CSS rather than abusing title= attributes.
|
||||
--- MINOR FUNCTIONAL IMPROVEMENTS ---
|
||||
* many improvements to the handling of fill and no-fill mode
|
||||
* tbl(7): better column widths in the presence of horizontal spans
|
||||
* several minor improvements to escape sequence handling
|
||||
* several minor improvements to manual font handling
|
||||
* portability: autodetect need for _GNU_SOURCE or _OPENBSD_SOURCE
|
||||
* portability: autodetect whether less(1) supports the -T option
|
||||
* large numbers of bugfixes of diverse kinds
|
||||
--- STRUCTURAL IMPROVEMENTS ---
|
||||
* Disentangle eqn(7) and tbl(7) from other parser header files,
|
||||
and clean up some parser data structures.
|
||||
* Substantially simplify error and warning message infrastructure.
|
||||
--- THANKS TO ---
|
||||
* John Gardner for crucial help implementing tooltips in CSS.
|
||||
* Alexander Bluhm, Raphael Graf, Ted Unangst (OpenBSD)
|
||||
and Daniel Sabogal (Alpine Linux) for patches.
|
||||
* Anthony Bentley and Jason McIntyre (OpenBSD) for documentation patches,
|
||||
suggesting new features, bug reports, and useful discussions.
|
||||
* Kyle Evans and Baptiste Daroussin (FreeBSD) for minor patches.
|
||||
* Pali Rohar for suggesting multiple new features and for reporting
|
||||
several bugs and missing features.
|
||||
* Klemens Nanni (OpenBSD) for suggesting multiple new features.
|
||||
* Kristaps Dzonsons (bsd.lv), Marc Espie (OpenBSD), Adam Kalisz,
|
||||
and Laura Morales for suggesting new features.
|
||||
* Wolfram Schneider and Yuri Pankov (FreeBSD) for reporting missing features.
|
||||
* Edward Tomasz Napierala (FreeBSD) for suggesting a feature improvement.
|
||||
* Thomas Klausner (NetBSD) and Sevan Janiyan (SmartOS)
|
||||
for bug reports and release testing.
|
||||
* Bryan Steele, Janne Johansson, Kurt Mosiejczuk, Mike Belopuhov, Theo
|
||||
Buehler, Todd Miller (OpenBSD), Andreas Gustafsson, Christos Zoulas,
|
||||
Robert Elz (NetBSD), Kurt Jaeger (FreeBSD), Fabio Scotoni, Kelvin
|
||||
Sherlock, Mark Harris, Orestis Ioannou, Raf Czlonka, and Sean Farrell
|
||||
for bug reports.
|
||||
* Ulrich Spoerlein (FreeBSD), Leah Neukirchen (Void Linux),
|
||||
Matej Cepl (openSUSE), and Jan Stary (MacOS X) for release testing.
|
||||
* Brian Callahan and Stuart Henderson (OpenBSD) for help
|
||||
with the OpenBSD groff port.
|
||||
* Bertrand Garrigues, Branden Robinson, Ralph Corderoy, and Werner
|
||||
Lemberg (GNU troff) for checking groff patches.
|
||||
* Scott Cheloha, Theo de Raadt (OpenBSD)
|
||||
and Natanael Copa (Alpine Linux) for useful discussions.
|
||||
|
||||
Changes in version 1.14.4, released on August 8, 2018
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
|
@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.258 2018/08/06 14:16:30 schwarze Exp $
|
||||
* $Id: TODO,v 1.289 2019/03/04 13:01:57 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@ -38,18 +38,6 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- missing roff features ----------------------------------------------
|
||||
|
||||
- .nop prints its arguments as text,
|
||||
see groff(7) for an example
|
||||
|
||||
- .ft CB selects constant-width bold font
|
||||
see groff_out(7) for examples
|
||||
|
||||
- \*(.T prints the device being used,
|
||||
see groff_char(7) for an example
|
||||
|
||||
- \[charNN], \[charNNN] prints a single-byte codepoint
|
||||
see groff_char(7) for examples
|
||||
|
||||
- .ad (adjust margins)
|
||||
.ad l -- adjust left margin only (flush left)
|
||||
.ad r -- adjust right margin only (flush right)
|
||||
@ -69,34 +57,11 @@ are mere guesses, and some may be wrong.
|
||||
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
||||
loc *** exist *** algo *** size ** imp *
|
||||
|
||||
- .while and .shift
|
||||
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
||||
loc * exist ** algo ** size ** imp **
|
||||
|
||||
- \w'' improve width measurements
|
||||
would not be very useful without an expression parser, see below
|
||||
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
||||
loc ** exist *** algo *** size * imp ***
|
||||
|
||||
- \\ in high-level macro arguments
|
||||
Currently, \\ is expanded in two situations:
|
||||
1) macro and string definition (roff.c setstrn())
|
||||
2) macro argument parsing (mandoc.c mandoc_getarg())
|
||||
For user defined macros, the second happens in time because of ROFF_REPARSE.
|
||||
But for standard high-level macros, it only happens after entering the
|
||||
high level parsers, which is too late because the code doesn't get
|
||||
back to roff.c roff_res() from that point. Because this requires
|
||||
distinguishing requests, user-defined macros and standard macros
|
||||
on the roff_res() level, it is hard to solve without the parser reorg.
|
||||
Found by naddy@ in devel/cutils cobfusc(1) Mon, 16 Feb 2015 19:10:52 +0100
|
||||
loc *** exist *** algo *** size ** imp *
|
||||
|
||||
- check for missing roff escape sequences, implement those that are
|
||||
trivial even if not usually appearing in manual pages, gracefully
|
||||
ignore the non-trivial ones, document what they are supposed to do
|
||||
and what mandoc does instead
|
||||
loc * exist ** algo * size * imp *
|
||||
|
||||
--- missing mdoc features ----------------------------------------------
|
||||
|
||||
- .Bl -column .Xo support is missing
|
||||
@ -112,13 +77,6 @@ are mere guesses, and some may be wrong.
|
||||
from jmc@ Wed, 14 Jul 2010 18:10:32 +0100
|
||||
loc * exist *** algo *** size ** imp **
|
||||
|
||||
- .Bd -centered implies -filled, not -unfilled, which is not
|
||||
easy to implement; it requires code similar to .ce, which
|
||||
we don't have either.
|
||||
Besides, groff has bug causing text right *before* .Bd -centered
|
||||
to be centered as well.
|
||||
loc *** exist *** algo ** size ** imp ** (parser reorg would help)
|
||||
|
||||
- .Bd -filled should not be the same as .Bd -ragged, but align both
|
||||
the left and right margin. In groff, it is implemented in terms
|
||||
of .ad b, which we don't have either. Found in cksum(1).
|
||||
@ -174,15 +132,6 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- missing man features -----------------------------------------------
|
||||
|
||||
- .SY and .YS,
|
||||
used by many groff manual pages
|
||||
|
||||
- preserve punctuation following .ME,
|
||||
see ditroff(7) for an example
|
||||
|
||||
- .TQ tagged paragraph continuation,
|
||||
see groff_diff(7) for examples
|
||||
|
||||
- groff_www(7) .MTO and .URL
|
||||
These macros were used by the GNU grep(1) man page.
|
||||
The groff_www(7) manual page itself uses them, too.
|
||||
@ -193,18 +142,10 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- missing tbl features -----------------------------------------------
|
||||
|
||||
- the "s" layout column specifier is used for placement of data
|
||||
into columns, but ignored during column width calculations
|
||||
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
|
||||
loc * exist ** algo *** size * imp **
|
||||
|
||||
- vertical centering in cells vertically spanned with ^
|
||||
pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
|
||||
loc * exist *** algo *** size ** imp *
|
||||
|
||||
- support .ds requests inside tbl(7) code,
|
||||
see tbl(1) for an example
|
||||
|
||||
- support mdoc(7) and man(7) macros inside tbl(7) code;
|
||||
probably requires the parser reorg and letting tbl(7)
|
||||
use roff_node such that macro sets can mix;
|
||||
@ -212,35 +153,24 @@ are mere guesses, and some may be wrong.
|
||||
loc *** exist ** algo *** size ** imp ***
|
||||
|
||||
- look at the POSIX manuals in the books/man-pages-posix port,
|
||||
they use some unsupported tbl(7) features.
|
||||
they use some unsupported tbl(7) features, mostly macros in tbl(7).
|
||||
loc * exist ** algo ** size ** imp ***
|
||||
|
||||
- look what Joerg Schilling manual pages use
|
||||
Thu, 19 Mar 2015 18:31:48 +0100
|
||||
|
||||
- use Unicode U+2500 to U+256C for table borders
|
||||
in tbl(7) -Tutf-8 output
|
||||
suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600
|
||||
loc * exist ** algo * size * imp **
|
||||
|
||||
- implement horizontal and vertical alignment in HTML output
|
||||
pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
|
||||
loc * exist * algo * size * imp ***
|
||||
|
||||
- implement cell spanning in HTML output
|
||||
pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
|
||||
loc * exist * algo ** size ** imp **
|
||||
|
||||
- implement table borders in HTML output
|
||||
pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
|
||||
loc * exist * algo ** size ** imp **
|
||||
|
||||
--- missing eqn features -----------------------------------------------
|
||||
|
||||
- In a matrix, break the output line after each matrix line.
|
||||
Found in the discussion at CDBUG 2015.
|
||||
Suggested by Avi Weinstock.
|
||||
loc * exist * algo * size * imp **
|
||||
Found in the discussion at CDBUG 2015. Suggested by Avi Weinstock.
|
||||
This may not be the ideal solution after all: eqn(7) matrices
|
||||
are lists of columns, so Avi's proposal would show each *column*
|
||||
on its own *line*, which is likely to cause confusion.
|
||||
A better solution, but much harder to implement, would be to
|
||||
actually show the coordinates of column vectors on different
|
||||
terminal output lines, using the clumnated output facilities
|
||||
developed for .Bl -tag, .Bl -column, and also used for tbl(7).
|
||||
loc * exist * algo ** size ** imp **
|
||||
|
||||
- The "size" keyword is parsed, but ignored by the formatter.
|
||||
loc * exist * algo * size * imp *
|
||||
@ -341,9 +271,6 @@ are mere guesses, and some may be wrong.
|
||||
* formatting issues: ugly output
|
||||
************************************************************************
|
||||
|
||||
- .UR can nest inside .TP,
|
||||
see roff(7) for examples
|
||||
|
||||
- revisit empty in-line macros
|
||||
look at the difference between "Em x Em ." and "Sq x Em ."
|
||||
Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100
|
||||
@ -400,6 +327,8 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
- 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
|
||||
by syntax tree nodes.
|
||||
loc ** exist * algo ** size * imp **
|
||||
|
||||
- formatting /usr/local/man/man1/latex2man.1 with groff and mandoc
|
||||
@ -421,17 +350,6 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
--- HTML issues --------------------------------------------------------
|
||||
|
||||
- wrap Sh and Ss content into <div>
|
||||
Laura Morales <lauretas at mail dot com> 21 Apr 2018 18:10:48 +0200
|
||||
(Evaluate whether this is really useful and has no adverse
|
||||
side effects before implementing; if it is possible,
|
||||
it does seem cleaner.)
|
||||
loc ** exist ** algo * size * imp ***
|
||||
|
||||
- format ".IP *" etc. as <ul> rather than <dl>
|
||||
https://github.com/Debian/debiman/issues/67
|
||||
loc ** exist ** algo ** size * imp ***
|
||||
|
||||
- .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal
|
||||
space, see for example random(3). Introduced in
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92
|
||||
@ -558,18 +476,11 @@ are mere guesses, and some may be wrong.
|
||||
all over mdoc_macro.c and all subtly different.
|
||||
loc ** exist ** algo ** size ** imp **
|
||||
|
||||
- style message about suspicious uses of - vs. \- vs. \(mi
|
||||
e.g. -1 is likely wrong (from the mdoclint TODO)
|
||||
|
||||
- warn about punctuation - e.g. ',' and ';' - at the beginning
|
||||
of a text line, if it is likely intended to follow the preceding
|
||||
output without intervening whitespace, in particular after a
|
||||
macro line (from the mdoclint TODO)
|
||||
|
||||
- mandoc_special does not really check the escape sequence,
|
||||
but just the overall format
|
||||
loc ** exist ** algo *** size ** imp **
|
||||
|
||||
- makewhatis -p complains about language subdirectories:
|
||||
/usr/local/man//ru: Unknown directory part
|
||||
|
||||
@ -578,9 +489,6 @@ are mere guesses, and some may be wrong.
|
||||
* documentation issues
|
||||
************************************************************************
|
||||
|
||||
- dashes, hyphens, and minus signs in manual pages
|
||||
jmc@ Fri, 28 Mar 2014 07:19:27 +0000
|
||||
|
||||
- mark macros as: page structure domain, manual domain, general text domain
|
||||
is this useful?
|
||||
|
||||
@ -606,10 +514,6 @@ are mere guesses, and some may be wrong.
|
||||
Found by Aaron M. Ucko in the GNU Hurd via Bdale Garbee,
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=829624
|
||||
|
||||
- We use the input line number at several places to distinguish
|
||||
same-line from different-line input. That plainly doesn't work
|
||||
with user-defined macros, leading to random breakage.
|
||||
|
||||
- Is it possible to further simplify ENDBODY_SPACE?
|
||||
|
||||
- Find better ways to prevent endless loops
|
||||
@ -629,8 +533,6 @@ are mere guesses, and some may be wrong.
|
||||
output through libz.
|
||||
- Privilege separation (see OpenSSH).
|
||||
- Enable caching support via HTTP 304 and If-Modified-Since.
|
||||
- Have Mac OSX systems automatically disable -static compilation of the
|
||||
CGI: -static isn't supported.
|
||||
|
||||
************************************************************************
|
||||
* to improve in the groff_mdoc(7) macros
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: apropos.1,v 1.47 2018/02/23 18:54:02 schwarze Exp $
|
||||
.\" $Id: apropos.1,v 1.49 2018/11/22 12:33:52 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011,2012,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
|
||||
@ -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: February 23 2018 $
|
||||
.Dd $Mdocdate: November 22 2018 $
|
||||
.Dt APROPOS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -51,8 +51,7 @@ searches for
|
||||
.Xr makewhatis 8
|
||||
databases in the default paths stipulated by
|
||||
.Xr man 1
|
||||
and uses case-insensitive substring matching
|
||||
.Pq the Cm = No operator
|
||||
and uses case-insensitive extended regular expression matching
|
||||
over manual names and descriptions
|
||||
.Pq the Li \&Nm No and Li \&Nd No macro keys .
|
||||
Multiple terms imply pairwise
|
||||
@ -93,7 +92,7 @@ format.
|
||||
Search for all words in
|
||||
.Ar expression
|
||||
in manual page names only.
|
||||
The search is case insensitive and matches whole words only.
|
||||
The search is case-insensitive and matches whole words only.
|
||||
In this mode, macro keys, comparison operators, and logical operators
|
||||
are not available.
|
||||
.It Fl k
|
||||
@ -123,7 +122,7 @@ Restrict the search to pages for the specified
|
||||
.Xr machine 1
|
||||
architecture.
|
||||
.Ar arch
|
||||
is case insensitive.
|
||||
is case-insensitive.
|
||||
By default, pages for all architectures are shown.
|
||||
.It Fl s Ar section
|
||||
Restrict the search to the specified section of the manual.
|
||||
@ -199,7 +198,7 @@ Operator
|
||||
.Cm =
|
||||
evaluates a substring, while
|
||||
.Cm \(ti
|
||||
evaluates a regular expression.
|
||||
evaluates a case-sensitive extended regular expression.
|
||||
.It Fl i Ar term
|
||||
If
|
||||
.Ar term
|
||||
@ -208,26 +207,10 @@ is evaluated case-insensitively.
|
||||
Has no effect on substring terms.
|
||||
.El
|
||||
.Pp
|
||||
Results are sorted according to the following criteria:
|
||||
.Bl -enum
|
||||
.It
|
||||
The manpath directory tree the page is found in, according to the
|
||||
order specified with
|
||||
.Fl M ,
|
||||
.Fl m ,
|
||||
the
|
||||
.Ev MANPATH
|
||||
environment variable, the
|
||||
.Xr man.conf 5
|
||||
configuration file, or the default documented in
|
||||
.Xr man.conf 5 .
|
||||
.It
|
||||
The section number in ascending numerical order.
|
||||
.It
|
||||
The page name in ascending
|
||||
Results are sorted first according to the section number in ascending
|
||||
numerical order, then by the page name in ascending
|
||||
.Xr ascii 7
|
||||
alphabetical order, case-insensitive.
|
||||
.El
|
||||
.Pp
|
||||
Each output line is formatted as
|
||||
.Pp
|
||||
@ -339,7 +322,7 @@ function arguments appearing on
|
||||
.Ic \&Fn
|
||||
lines
|
||||
.It Li \&Fn
|
||||
fuction names marked up with
|
||||
function names marked up with
|
||||
.Ic \&Fo
|
||||
macros
|
||||
.It Li \&In
|
||||
@ -407,7 +390,7 @@ Search for
|
||||
.Qq .cf
|
||||
as a substring of manual names and descriptions:
|
||||
.Pp
|
||||
.Dl $ apropos .cf
|
||||
.Dl $ apropos =.cf
|
||||
.Pp
|
||||
Include matches for
|
||||
.Qq .cnf
|
||||
@ -415,9 +398,9 @@ and
|
||||
.Qq .conf
|
||||
as well:
|
||||
.Pp
|
||||
.Dl $ apropos .cf .cnf .conf
|
||||
.Dl $ apropos =.cf =.cnf =.conf
|
||||
.Pp
|
||||
Search in names and descriptions using a regular expression:
|
||||
Search in names and descriptions using a case-sensitive regular expression:
|
||||
.Pp
|
||||
.Dl $ apropos \(aq\(tiset.?[ug]id\(aq
|
||||
.Pp
|
||||
@ -448,6 +431,24 @@ The following two invocations are equivalent:
|
||||
.Xr man 1 ,
|
||||
.Xr re_format 7 ,
|
||||
.Xr makewhatis 8
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is compliant with the
|
||||
.St -p1003.1-2008
|
||||
specification of
|
||||
.Xr man 1
|
||||
.Fl k .
|
||||
.Pp
|
||||
All options, the
|
||||
.Nm whatis
|
||||
command, support for logical operators, macro keys,
|
||||
substring matching, sorting of results, the environment variables
|
||||
.Ev MANPAGER
|
||||
and
|
||||
.Ev MANPATH ,
|
||||
the database format, and the configuration file
|
||||
are extensions to that specification.
|
||||
.Sh HISTORY
|
||||
Part of the functionality of
|
||||
.Nm whatis
|
||||
|
54
contrib/mandoc/arch.c
Normal file
54
contrib/mandoc/arch.c
Normal file
@ -0,0 +1,54 @@
|
||||
/* $Id: arch.c,v 1.14 2019/03/04 13:01:57 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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 <string.h>
|
||||
|
||||
#include "roff.h"
|
||||
|
||||
int
|
||||
arch_valid(const char *arch, enum mandoc_os os)
|
||||
{
|
||||
const char *openbsd_arch[] = {
|
||||
"alpha", "amd64", "arm64", "armv7", "hppa", "i386",
|
||||
"landisk", "loongson", "luna88k", "macppc", "mips64",
|
||||
"octeon", "sgi", "socppc", "sparc64", NULL
|
||||
};
|
||||
const char *netbsd_arch[] = {
|
||||
"acorn26", "acorn32", "algor", "alpha", "amiga",
|
||||
"arc", "atari",
|
||||
"bebox", "cats", "cesfic", "cobalt", "dreamcast",
|
||||
"emips", "evbarm", "evbmips", "evbppc", "evbsh3", "evbsh5",
|
||||
"hp300", "hpcarm", "hpcmips", "hpcsh", "hppa",
|
||||
"i386", "ibmnws", "luna68k",
|
||||
"mac68k", "macppc", "mipsco", "mmeye", "mvme68k", "mvmeppc",
|
||||
"netwinder", "news68k", "newsmips", "next68k",
|
||||
"pc532", "playstation2", "pmax", "pmppc", "prep",
|
||||
"sandpoint", "sbmips", "sgimips", "shark",
|
||||
"sparc", "sparc64", "sun2", "sun3",
|
||||
"vax", "walnut", "x68k", "x86", "x86_64", "xen", NULL
|
||||
};
|
||||
const char **arches[] = { NULL, netbsd_arch, openbsd_arch };
|
||||
const char **arch_p;
|
||||
|
||||
if ((arch_p = arches[os]) == NULL)
|
||||
return 1;
|
||||
for (; *arch_p != NULL; arch_p++)
|
||||
if (strcmp(*arch_p, arch) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $Id: att.c,v 1.16 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/* $Id: att.c,v 1.18 2018/12/13 11:55:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -19,9 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: cgi.c,v 1.158 2018/05/29 20:32:45 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.166 2019/03/06 12:32:41 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@usta.de>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017, 2018 Ingo Schwarze <schwarze@usta.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -38,6 +38,7 @@
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "mandoc_parse.h"
|
||||
#include "main.h"
|
||||
#include "manconf.h"
|
||||
#include "mansearch.h"
|
||||
@ -69,6 +70,7 @@ enum focus {
|
||||
static void html_print(const char *);
|
||||
static void html_putchar(char);
|
||||
static int http_decode(char *);
|
||||
static void http_encode(const char *p);
|
||||
static void parse_manpath_conf(struct req *);
|
||||
static void parse_path_info(struct req *req, const char *path);
|
||||
static void parse_query_string(struct req *, const char *);
|
||||
@ -90,6 +92,7 @@ static void resp_format(const struct req *, const char *);
|
||||
static void resp_searchform(const struct req *, enum focus);
|
||||
static void resp_show(const struct req *, const char *);
|
||||
static void set_query_attr(char **, char **);
|
||||
static int validate_arch(const char *);
|
||||
static int validate_filename(const char *);
|
||||
static int validate_manpath(const struct req *, const char *);
|
||||
static int validate_urifrag(const char *);
|
||||
@ -315,6 +318,18 @@ http_decode(char *p)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
http_encode(const char *p)
|
||||
{
|
||||
for (; *p != '\0'; p++) {
|
||||
if (isalnum((unsigned char)*p) == 0 &&
|
||||
strchr("-._~", *p) == NULL)
|
||||
printf("%%%2.2X", (unsigned char)*p);
|
||||
else
|
||||
putchar(*p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
resp_begin_http(int code, const char *msg)
|
||||
{
|
||||
@ -489,6 +504,18 @@ validate_manpath(const struct req *req, const char* manpath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_arch(const char *arch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < arch_MAX; i++)
|
||||
if (strcmp(arch, arch_names[i]) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_filename(const char *file)
|
||||
{
|
||||
@ -562,9 +589,11 @@ pg_redirect(const struct req *req, const char *name)
|
||||
printf("%s/", req->q.manpath);
|
||||
if (req->q.arch != NULL)
|
||||
printf("%s/", req->q.arch);
|
||||
printf("%s", name);
|
||||
if (req->q.sec != NULL)
|
||||
printf(".%s", req->q.sec);
|
||||
http_encode(name);
|
||||
if (req->q.sec != NULL) {
|
||||
putchar('.');
|
||||
http_encode(req->q.sec);
|
||||
}
|
||||
printf("\r\nContent-Type: text/html; charset=utf-8\r\n\r\n");
|
||||
}
|
||||
|
||||
@ -820,7 +849,7 @@ resp_format(const struct req *req, const char *file)
|
||||
{
|
||||
struct manoutput conf;
|
||||
struct mparse *mp;
|
||||
struct roff_man *man;
|
||||
struct roff_meta *meta;
|
||||
void *vp;
|
||||
int fd;
|
||||
int usepath;
|
||||
@ -831,37 +860,26 @@ resp_format(const struct req *req, const char *file)
|
||||
}
|
||||
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1,
|
||||
MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, req->q.manpath);
|
||||
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1 |
|
||||
MPARSE_VALIDATE, MANDOC_OS_OTHER, req->q.manpath);
|
||||
mparse_readfd(mp, fd, file);
|
||||
close(fd);
|
||||
meta = mparse_result(mp);
|
||||
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
conf.fragment = 1;
|
||||
conf.style = mandoc_strdup(CSS_DIR "/mandoc.css");
|
||||
conf.toc = 1;
|
||||
usepath = strcmp(req->q.manpath, req->p[0]);
|
||||
mandoc_asprintf(&conf.man, "/%s%s%s%s%%N.%%S",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
usepath ? req->q.manpath : "", usepath ? "/" : "");
|
||||
|
||||
mparse_result(mp, &man, NULL);
|
||||
if (man == NULL) {
|
||||
warnx("fatal mandoc error: %s/%s", req->q.manpath, file);
|
||||
pg_error_internal();
|
||||
mparse_free(mp);
|
||||
mchars_free();
|
||||
return;
|
||||
}
|
||||
|
||||
vp = html_alloc(&conf);
|
||||
|
||||
if (man->macroset == MACROSET_MDOC) {
|
||||
mdoc_validate(man);
|
||||
html_mdoc(vp, man);
|
||||
} else {
|
||||
man_validate(man);
|
||||
html_man(vp, man);
|
||||
}
|
||||
if (meta->macroset == MACROSET_MDOC)
|
||||
html_mdoc(vp, meta);
|
||||
else
|
||||
html_man(vp, meta);
|
||||
|
||||
html_free(vp);
|
||||
mparse_free(mp);
|
||||
@ -1089,7 +1107,7 @@ main(void)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) {
|
||||
if (req.q.arch != NULL && validate_arch(req.q.arch) == 0) {
|
||||
pg_error_badrequest(
|
||||
"You specified an invalid architecture.");
|
||||
return EXIT_FAILURE;
|
||||
@ -1115,80 +1133,74 @@ main(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* If PATH_INFO is not a file name, translate it to a query.
|
||||
* Translate PATH_INFO to a query.
|
||||
*/
|
||||
static void
|
||||
parse_path_info(struct req *req, const char *path)
|
||||
{
|
||||
char *dir[4];
|
||||
int i;
|
||||
const char *name, *sec, *end;
|
||||
|
||||
req->isquery = 0;
|
||||
req->q.equal = 1;
|
||||
req->q.manpath = mandoc_strdup(path);
|
||||
req->q.manpath = NULL;
|
||||
req->q.arch = NULL;
|
||||
|
||||
/* Mandatory manual page name. */
|
||||
if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) {
|
||||
req->q.query = req->q.manpath;
|
||||
req->q.manpath = NULL;
|
||||
} else
|
||||
*req->q.query++ = '\0';
|
||||
if ((name = strrchr(path, '/')) == NULL)
|
||||
name = path;
|
||||
else
|
||||
name++;
|
||||
|
||||
/* Optional trailing section. */
|
||||
if ((req->q.sec = strrchr(req->q.query, '.')) != NULL) {
|
||||
if(isdigit((unsigned char)req->q.sec[1])) {
|
||||
*req->q.sec++ = '\0';
|
||||
req->q.sec = mandoc_strdup(req->q.sec);
|
||||
} else
|
||||
req->q.sec = NULL;
|
||||
sec = strrchr(name, '.');
|
||||
if (sec != NULL && isdigit((unsigned char)*++sec)) {
|
||||
req->q.query = mandoc_strndup(name, sec - name - 1);
|
||||
req->q.sec = mandoc_strdup(sec);
|
||||
} else {
|
||||
req->q.query = mandoc_strdup(name);
|
||||
req->q.sec = NULL;
|
||||
}
|
||||
|
||||
/* Handle the case of name[.section] only. */
|
||||
if (req->q.manpath == NULL)
|
||||
if (name == path)
|
||||
return;
|
||||
req->q.query = mandoc_strdup(req->q.query);
|
||||
|
||||
/* Split directory components. */
|
||||
dir[i = 0] = req->q.manpath;
|
||||
while ((dir[i + 1] = strchr(dir[i], '/')) != NULL) {
|
||||
if (++i == 3) {
|
||||
pg_error_badrequest(
|
||||
"You specified too many directory components.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*dir[i]++ = '\0';
|
||||
}
|
||||
|
||||
/* Optional manpath. */
|
||||
if ((i = validate_manpath(req, req->q.manpath)) == 0)
|
||||
end = strchr(path, '/');
|
||||
req->q.manpath = mandoc_strndup(path, end - path);
|
||||
if (validate_manpath(req, req->q.manpath)) {
|
||||
path = end + 1;
|
||||
if (name == path)
|
||||
return;
|
||||
} else {
|
||||
free(req->q.manpath);
|
||||
req->q.manpath = NULL;
|
||||
else if (dir[1] == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Optional section. */
|
||||
if (strncmp(dir[i], "man", 3) == 0) {
|
||||
if (strncmp(path, "man", 3) == 0 || strncmp(path, "cat", 3) == 0) {
|
||||
path += 3;
|
||||
end = strchr(path, '/');
|
||||
free(req->q.sec);
|
||||
req->q.sec = mandoc_strdup(dir[i++] + 3);
|
||||
req->q.sec = mandoc_strndup(path, end - path);
|
||||
path = end + 1;
|
||||
if (name == path)
|
||||
return;
|
||||
}
|
||||
if (dir[i] == NULL) {
|
||||
if (req->q.manpath == NULL)
|
||||
free(dir[0]);
|
||||
return;
|
||||
|
||||
/* Optional architecture. */
|
||||
end = strchr(path, '/');
|
||||
if (end + 1 != name) {
|
||||
pg_error_badrequest(
|
||||
"You specified too many directory components.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (dir[i + 1] != NULL) {
|
||||
req->q.arch = mandoc_strndup(path, end - path);
|
||||
if (validate_arch(req->q.arch) == 0) {
|
||||
pg_error_badrequest(
|
||||
"You specified an invalid directory component.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Optional architecture. */
|
||||
if (i) {
|
||||
req->q.arch = mandoc_strdup(dir[i]);
|
||||
if (req->q.manpath == NULL)
|
||||
free(dir[0]);
|
||||
} else
|
||||
req->q.arch = dir[0];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: chars.c,v 1.73 2017/08/23 13:01:29 schwarze Exp $ */
|
||||
/* $Id: chars.c,v 1.78 2018/12/15 19:30:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -23,6 +23,7 @@
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -47,20 +48,13 @@ static struct ln lines[] = {
|
||||
{ " ", ascii_nbrsp, 0x00a0 },
|
||||
{ "~", ascii_nbrsp, 0x00a0 },
|
||||
{ "0", " ", 0x2002 },
|
||||
{ "|", "", 0 },
|
||||
{ "^", "", 0 },
|
||||
{ "&", "", 0 },
|
||||
{ "%", "", 0 },
|
||||
{ ":", ascii_break, 0 },
|
||||
/* XXX The following three do not really belong here. */
|
||||
{ "t", "", 0 },
|
||||
{ "c", "", 0 },
|
||||
{ "}", "", 0 },
|
||||
|
||||
/* Lines. */
|
||||
{ "ba", "|", 0x007c },
|
||||
{ "br", "|", 0x2502 },
|
||||
{ "ul", "_", 0x005f },
|
||||
{ "_", "_", 0x005f },
|
||||
{ "ru", "_", 0x005f },
|
||||
{ "rn", "-", 0x203e },
|
||||
{ "bb", "|", 0x00a6 },
|
||||
@ -82,10 +76,10 @@ static struct ln lines[] = {
|
||||
{ "sh", "#", 0x0023 },
|
||||
{ "CR", "<cr>", 0x21b5 },
|
||||
{ "OK", "\\/", 0x2713 },
|
||||
{ "CL", "<club>", 0x2663 },
|
||||
{ "SP", "<spade>", 0x2660 },
|
||||
{ "HE", "<heart>", 0x2665 },
|
||||
{ "DI", "<diamond>", 0x2666 },
|
||||
{ "CL", "C", 0x2663 },
|
||||
{ "SP", "S", 0x2660 },
|
||||
{ "HE", "H", 0x2665 },
|
||||
{ "DI", "D", 0x2666 },
|
||||
|
||||
/* Legal symbols. */
|
||||
{ "co", "(C)", 0x00a9 },
|
||||
@ -240,7 +234,7 @@ static struct ln lines[] = {
|
||||
{ "Ah", "<Aleph>", 0x2135 },
|
||||
{ "Im", "<Im>", 0x2111 },
|
||||
{ "Re", "<Re>", 0x211c },
|
||||
{ "wp", "P", 0x2118 },
|
||||
{ "wp", "p", 0x2118 },
|
||||
{ "pd", "<del>", 0x2202 },
|
||||
{ "-h", "/h", 0x210f },
|
||||
{ "hbar", "/h", 0x210f },
|
||||
@ -287,6 +281,7 @@ static struct ln lines[] = {
|
||||
{ "ho", ",", 0x02db },
|
||||
{ "ha", "^", 0x005e },
|
||||
{ "ti", "~", 0x007e },
|
||||
{ "u02DC", "~", 0x02dc },
|
||||
|
||||
/* Accented letters. */
|
||||
{ "'A", "'\bA", 0x00c1 },
|
||||
@ -294,11 +289,13 @@ static struct ln lines[] = {
|
||||
{ "'I", "'\bI", 0x00cd },
|
||||
{ "'O", "'\bO", 0x00d3 },
|
||||
{ "'U", "'\bU", 0x00da },
|
||||
{ "'Y", "'\bY", 0x00dd },
|
||||
{ "'a", "'\ba", 0x00e1 },
|
||||
{ "'e", "'\be", 0x00e9 },
|
||||
{ "'i", "'\bi", 0x00ed },
|
||||
{ "'o", "'\bo", 0x00f3 },
|
||||
{ "'u", "'\bu", 0x00fa },
|
||||
{ "'y", "'\by", 0x00fd },
|
||||
{ "`A", "`\bA", 0x00c0 },
|
||||
{ "`E", "`\bE", 0x00c8 },
|
||||
{ "`I", "`\bI", 0x00cc },
|
||||
@ -359,7 +356,7 @@ static struct ln lines[] = {
|
||||
{ "Eu", "EUR", 0x20ac },
|
||||
{ "eu", "EUR", 0x20ac },
|
||||
{ "Ye", "=\bY", 0x00a5 },
|
||||
{ "Po", "GBP", 0x00a3 },
|
||||
{ "Po", "-\bL", 0x00a3 },
|
||||
{ "Cs", "o\bx", 0x00a4 },
|
||||
{ "Fn", ",\bf", 0x0192 },
|
||||
|
||||
@ -460,7 +457,7 @@ mchars_spec2cp(const char *p, size_t sz)
|
||||
|
||||
end = p + sz;
|
||||
ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
|
||||
return ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1;
|
||||
return ln != NULL ? ln->unicode : -1;
|
||||
}
|
||||
|
||||
int
|
||||
@ -490,10 +487,8 @@ mchars_spec2str(const char *p, size_t sz, size_t *rsz)
|
||||
|
||||
end = p + sz;
|
||||
ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
|
||||
if (ln == NULL) {
|
||||
*rsz = 1;
|
||||
return sz == 1 ? p : NULL;
|
||||
}
|
||||
if (ln == NULL)
|
||||
return NULL;
|
||||
|
||||
*rsz = strlen(ln->ascii);
|
||||
return ln->ascii;
|
||||
|
@ -6,15 +6,12 @@
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__MINT__)
|
||||
#define _GNU_SOURCE /* See test-*.c what needs this. */
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MAN_CONF_FILE "/etc/man.conf"
|
||||
#define MANPATH_BASE "/usr/share/man"
|
||||
#define MANPATH_DEFAULT "/usr/share/man:/usr/local/man"
|
||||
#define OSENUM MANDOC_OS_OTHER
|
||||
#define UTF8_LOCALE "en_US.UTF-8"
|
||||
#define HAVE_CMSG_XPG42 0
|
||||
#define HAVE_DIRENT_NAMLEN 1
|
||||
@ -25,6 +22,7 @@
|
||||
#define HAVE_GETLINE 1
|
||||
#define HAVE_GETSUBOPT 1
|
||||
#define HAVE_ISBLANK 1
|
||||
#define HAVE_LESS_T 1
|
||||
#define HAVE_MKDTEMP 1
|
||||
#define HAVE_NTOHL 1
|
||||
#define HAVE_PLEDGE 0
|
||||
|
142
contrib/mandoc/configure
vendored
142
contrib/mandoc/configure
vendored
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.66 2018/07/31 15:34:00 schwarze Exp $
|
||||
# $Id: configure,v 1.70 2019/03/06 16:04:31 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@ -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"
|
||||
OSENUM=
|
||||
OSNAME=
|
||||
UTF8_LOCALE=
|
||||
|
||||
@ -64,6 +65,7 @@ HAVE_FTS_COMPARE_CONST=
|
||||
HAVE_GETLINE=
|
||||
HAVE_GETSUBOPT=
|
||||
HAVE_ISBLANK=
|
||||
HAVE_LESS_T=
|
||||
HAVE_MKDTEMP=
|
||||
HAVE_NANOSLEEP=
|
||||
HAVE_NTOHL=
|
||||
@ -90,6 +92,9 @@ HAVE_SYS_ENDIAN=
|
||||
HAVE_VASPRINTF=
|
||||
HAVE_WCHAR=
|
||||
|
||||
NEED_GNU_SOURCE=0
|
||||
NEED_OPENBSD_SOURCE=0
|
||||
|
||||
PREFIX="/usr/local"
|
||||
BINDIR=
|
||||
SBINDIR=
|
||||
@ -154,31 +159,34 @@ ismanual() {
|
||||
# In case of failure, do not decide anything yet.
|
||||
# Arguments: test file name, test var name, additional CFLAGS
|
||||
singletest() {
|
||||
n=${1}${3}${4}
|
||||
cat 1>&3 << __HEREDOC__
|
||||
testing ${1}${3} ...
|
||||
${COMP} -o test-${1} test-${1}.c ${3}
|
||||
testing ${n} ...
|
||||
${COMP} -o test-${1} test-${1}.c ${3} ${4}
|
||||
__HEREDOC__
|
||||
|
||||
if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} 1>&3 2>&3
|
||||
if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} ${4} 1>&3 2>&3
|
||||
then
|
||||
echo "partial result of ${1}${3}: ${CC} succeeded" 1>&3
|
||||
echo "partial result of ${n}: ${CC} succeeded" 1>&3
|
||||
else
|
||||
echo "result of ${1}${3}: ${CC} failed with exit status $?" 1>&3
|
||||
echo "result of compiling ${1}${3}: no" 1>&3
|
||||
echo "result of ${n}: ${CC} failed with exit status $?" 1>&3
|
||||
echo "result of compiling ${n}: no" 1>&3
|
||||
echo 1>&3
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ./test-${1} 1>&3 2>&3; then
|
||||
echo "tested ${1}${3}: yes" 1>&2
|
||||
echo "result of running ${1}${3}: yes" 1>&3
|
||||
echo "tested ${n}: yes" 1>&2
|
||||
echo "result of running ${n}: yes" 1>&3
|
||||
echo 1>&3
|
||||
eval HAVE_${2}=1
|
||||
[ "X$3" = "X-D_GNU_SOURCE" ] && NEED_GNU_SOURCE=1
|
||||
[ "X$3" = "X-D_OPENBSD_SOURCE" ] && NEED_OPENBSD_SOURCE=1
|
||||
rm "test-${1}"
|
||||
return 0
|
||||
else
|
||||
echo "result of ${1}${3}: execution failed with exit status $?" 1>&3
|
||||
echo "result of running ${1}${3}: no" 1>&3
|
||||
echo "result of ${n}: execution failed with exit status $?" 1>&3
|
||||
echo "result of running ${n}: no" 1>&3
|
||||
echo 1>&3
|
||||
rm "test-${1}"
|
||||
return 1
|
||||
@ -191,8 +199,8 @@ __HEREDOC__
|
||||
runtest() {
|
||||
eval _manual=\${HAVE_${2}}
|
||||
ismanual "${1}" "${2}" "${_manual}" && return 0
|
||||
singletest "${1}" "${2}" "${3}" && return 0
|
||||
echo "tested ${1}${3}: no" 1>&2
|
||||
singletest "${1}" "${2}" "${3}" "${4}" && return 0
|
||||
echo "tested ${1}${3}${4}: no" 1>&2
|
||||
eval HAVE_${2}=0
|
||||
return 1
|
||||
}
|
||||
@ -213,28 +221,52 @@ get_locale() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
# --- operating system -------------------------------------------------
|
||||
|
||||
if [ -n "${OSENUM}" ]; then
|
||||
echo "OSENUM specified manually: ${OSENUM}" 1>&2
|
||||
echo "OSENUM specified manually: ${OSENUM}" 1>&3
|
||||
else
|
||||
OSDETECT=`uname`
|
||||
if [ "X${OSDETECT}" = "XNetBSD" ]; then
|
||||
OSENUM=MANDOC_OS_NETBSD
|
||||
elif [ "X${OSDETECT}" = "XOpenBSD" ]; then
|
||||
OSENUM=MANDOC_OS_OPENBSD
|
||||
else
|
||||
OSENUM=MANDOC_OS_OTHER
|
||||
fi
|
||||
echo "tested operating system: ${OSDETECT} -> OSENUM=${OSENUM}" 1>&2
|
||||
echo "tested operating system: ${OSDETECT} -> OSENUM=${OSENUM}" 1>&3
|
||||
unset OSDETECT
|
||||
fi
|
||||
echo 1>&3
|
||||
|
||||
# --- compiler options -------------------------------------------------
|
||||
|
||||
DEFCFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -Wno-unused-parameter"
|
||||
|
||||
if [ -n "${CFLAGS}" ]; then
|
||||
COMP="${CC} ${CFLAGS}"
|
||||
echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&2
|
||||
echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&3
|
||||
echo 1>&3
|
||||
else
|
||||
CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes"
|
||||
CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter"
|
||||
COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
|
||||
echo -n "tested ${CC} -W: " 1>&2
|
||||
echo -n "testing ${CC} -W: " 1>&3
|
||||
runtest noop WFLAG || true
|
||||
if [ "${HAVE_WFLAG}" -eq 0 ]; then
|
||||
CFLAGS="-g"
|
||||
COMP="${CC} ${CFLAGS}"
|
||||
fi
|
||||
echo "selected CFLAGS=\"${CFLAGS}\"" 1>&2
|
||||
echo "selected CFLAGS=\"${CFLAGS}\"" 1>&3
|
||||
echo 1>&3
|
||||
else
|
||||
COMP="${CC} ${DEFCFLAGS} -Wno-unused -Werror"
|
||||
fi
|
||||
echo -n "tested ${CC} -W: " 1>&2
|
||||
echo -n "testing ${CC} -W: " 1>&3
|
||||
runtest noop WFLAG || true
|
||||
|
||||
if [ -n "${CFLAGS}" ]; then
|
||||
echo "CFLAGS specified manually:" 1>&3
|
||||
elif [ ${HAVE_WFLAG} -eq 0 ]; then
|
||||
CFLAGS="-g"
|
||||
else
|
||||
CFLAGS="${DEFCFLAGS}"
|
||||
fi
|
||||
echo "selected CFLAGS=\"${CFLAGS}\"" 1>&2
|
||||
echo "selected CFLAGS=\"${CFLAGS}\"" 1>&3
|
||||
echo 1>&3
|
||||
|
||||
COMP="${CC} ${CFLAGS}"
|
||||
[ ${HAVE_WFLAG} -eq 0 ] || COMP="${COMP} -Wno-unused -Werror"
|
||||
|
||||
if [ -n "${STATIC}" ]; then
|
||||
echo "selected STATIC=\"${STATIC}\" (manual)" 1>&2
|
||||
@ -257,7 +289,8 @@ runtest be32toh SYS_ENDIAN -DSYS_ENDIAN || true
|
||||
runtest EFTYPE EFTYPE || true
|
||||
runtest err ERR || true
|
||||
runtest getline GETLINE || true
|
||||
runtest getsubopt GETSUBOPT || true
|
||||
singletest getsubopt GETSUBOPT || \
|
||||
runtest getsubopt GETSUBOPT -D_GNU_SOURCE || true
|
||||
runtest isblank ISBLANK || true
|
||||
runtest mkdtemp MKDTEMP || true
|
||||
runtest ntohl NTOHL || true
|
||||
@ -266,19 +299,25 @@ runtest PATH_MAX PATH_MAX || true
|
||||
runtest pledge PLEDGE || true
|
||||
runtest sandbox_init SANDBOX_INIT || true
|
||||
runtest progname PROGNAME || true
|
||||
runtest reallocarray REALLOCARRAY || true
|
||||
runtest recallocarray RECALLOCARRAY || true
|
||||
singletest reallocarray REALLOCARRAY || \
|
||||
runtest reallocarray REALLOCARRAY -D_OPENBSD_SOURCE || true
|
||||
singletest recallocarray RECALLOCARRAY || \
|
||||
runtest recallocarray RECALLOCARRAY -D_OPENBSD_SOURCE || true
|
||||
runtest rewb-bsd REWB_BSD || true
|
||||
runtest rewb-sysv REWB_SYSV || true
|
||||
runtest strcasestr STRCASESTR || true
|
||||
singletest strcasestr STRCASESTR || \
|
||||
runtest strcasestr STRCASESTR -D_GNU_SOURCE || true
|
||||
runtest stringlist STRINGLIST || true
|
||||
runtest strlcat STRLCAT || true
|
||||
runtest strlcpy STRLCPY || true
|
||||
runtest strndup STRNDUP || true
|
||||
runtest strptime STRPTIME || true
|
||||
singletest strptime STRPTIME || \
|
||||
runtest strptime STRPTIME -D_GNU_SOURCE || true
|
||||
runtest strsep STRSEP || true
|
||||
runtest strtonum STRTONUM || true
|
||||
runtest vasprintf VASPRINTF || true
|
||||
singletest strtonum STRTONUM || \
|
||||
runtest strtonum STRTONUM -D_OPENBSD_SOURCE || true
|
||||
singletest vasprintf VASPRINTF || \
|
||||
runtest vasprintf VASPRINTF -D_GNU_SOURCE || true
|
||||
|
||||
if [ ${HAVE_ENDIAN} -eq 0 -a \
|
||||
${HAVE_SYS_ENDIAN} -eq 0 -a \
|
||||
@ -296,9 +335,25 @@ else
|
||||
runtest fts FTS || true
|
||||
fi
|
||||
|
||||
if ismanual "less -T" LESS_T ${HAVE_LESS_T}; then
|
||||
:
|
||||
elif less -ET /dev/null test-noop.c 1>/dev/null 2>&3; then
|
||||
HAVE_LESS_T=1
|
||||
echo "tested less -T: yes" 1>&2
|
||||
echo "tested less -T: yes" 1>&3
|
||||
echo 1>&3
|
||||
else
|
||||
HAVE_LESS_T=0
|
||||
echo "tested less -T: no" 1>&2
|
||||
echo "tested less -T: no" 1>&3
|
||||
echo 1>&3
|
||||
fi
|
||||
|
||||
# --- wide character and locale support ---
|
||||
if get_locale; then
|
||||
runtest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true
|
||||
singletest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || \
|
||||
runtest wchar WCHAR -D_GNU_SOURCE \
|
||||
-DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true
|
||||
else
|
||||
HAVE_WCHAR=0
|
||||
echo "tested wchar: no (no UTF8_LOCALE)" 1>&2
|
||||
@ -383,12 +438,11 @@ cat << __HEREDOC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__MINT__)
|
||||
#define _GNU_SOURCE /* See test-*.c what needs this. */
|
||||
#endif
|
||||
|
||||
__HEREDOC__
|
||||
|
||||
[ ${NEED_GNU_SOURCE} -eq 0 ] || echo "#define _GNU_SOURCE"
|
||||
[ ${NEED_OPENBSD_SOURCE} -eq 0 ] || echo "#define _OPENBSD_SOURCE"
|
||||
|
||||
[ ${HAVE_GETLINE} -eq 0 -o \
|
||||
${HAVE_REALLOCARRAY} -eq 0 -o ${HAVE_RECALLOCARRAY} -eq 0 -o \
|
||||
${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 -o \
|
||||
@ -401,6 +455,7 @@ echo
|
||||
echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\""
|
||||
echo "#define MANPATH_BASE \"${MANPATH_BASE}\""
|
||||
echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\""
|
||||
echo "#define OSENUM ${OSENUM}"
|
||||
[ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\""
|
||||
[ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\""
|
||||
[ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\""
|
||||
@ -422,6 +477,7 @@ cat << __HEREDOC__
|
||||
#define HAVE_GETLINE ${HAVE_GETLINE}
|
||||
#define HAVE_GETSUBOPT ${HAVE_GETSUBOPT}
|
||||
#define HAVE_ISBLANK ${HAVE_ISBLANK}
|
||||
#define HAVE_LESS_T ${HAVE_LESS_T}
|
||||
#define HAVE_MKDTEMP ${HAVE_MKDTEMP}
|
||||
#define HAVE_NTOHL ${HAVE_NTOHL}
|
||||
#define HAVE_PLEDGE ${HAVE_PLEDGE}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $Id: configure.local.example,v 1.34 2018/07/31 15:34:00 schwarze Exp $
|
||||
# $Id: configure.local.example,v 1.36 2019/03/06 10:18:58 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@ -67,6 +67,17 @@ MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man"
|
||||
|
||||
MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
|
||||
|
||||
# When man(1) is called with the -S option and no manual page is
|
||||
# found matching the requested name and the requested architecture,
|
||||
# it tries to figure out whether the requested architecture is valid
|
||||
# for the present operating system. Normally, ./configure detects
|
||||
# the operating system using uname(1). If that fails or is not
|
||||
# desired, either of the following lines can be used:
|
||||
|
||||
OSENUM=MANDOC_OS_NETBSD
|
||||
OSENUM=MANDOC_OS_OPENBSD
|
||||
OSENUM=MANDOC_OS_OTHER
|
||||
|
||||
# In manual pages written in the mdoc(7) language, the operating system
|
||||
# version is displayed in the page footer line. If an operating system
|
||||
# is specified as an argument to the .Os macro, that is always used.
|
||||
@ -77,7 +88,7 @@ MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
|
||||
# If you do not want uname(3) to be called but instead want a fixed
|
||||
# string to be used, use the following line:
|
||||
|
||||
OSNAME="OpenBSD 6.3"
|
||||
OSNAME="OpenBSD 6.5"
|
||||
|
||||
# The following installation directories are used.
|
||||
# It is possible to set only one or a few of these variables,
|
||||
@ -293,6 +304,7 @@ HAVE_FTS_COMPARE_CONST=0 # Setting this implies HAVE_FTS=1.
|
||||
HAVE_GETLINE=0
|
||||
HAVE_GETSUBOPT=0
|
||||
HAVE_ISBLANK=0
|
||||
HAVE_LESS_T=0
|
||||
HAVE_MKDTEMP=0
|
||||
HAVE_NTOHL=0
|
||||
HAVE_O_DIRECTORY=0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: dbm.c,v 1.5 2016/10/18 22:27:25 schwarze Exp $ */
|
||||
/* $Id: dbm.c,v 1.6 2018/11/19 19:22:07 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -151,17 +151,17 @@ dbm_page_get(int32_t ip)
|
||||
assert(ip < npages);
|
||||
res.name = dbm_get(pages[ip].name);
|
||||
if (res.name == NULL)
|
||||
res.name = "(NULL)";
|
||||
res.name = "(NULL)\0";
|
||||
res.sect = dbm_get(pages[ip].sect);
|
||||
if (res.sect == NULL)
|
||||
res.sect = "(NULL)";
|
||||
res.sect = "(NULL)\0";
|
||||
res.arch = pages[ip].arch ? dbm_get(pages[ip].arch) : NULL;
|
||||
res.desc = dbm_get(pages[ip].desc);
|
||||
if (res.desc == NULL)
|
||||
res.desc = "(NULL)";
|
||||
res.file = dbm_get(pages[ip].file);
|
||||
if (res.file == NULL)
|
||||
res.file = " (NULL)";
|
||||
res.file = " (NULL)\0";
|
||||
res.addr = dbm_addr(pages + ip);
|
||||
return &res;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: demandoc.c,v 1.29 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/* $Id: demandoc.c,v 1.33 2019/03/03 11:01:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -29,6 +29,7 @@
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "mdoc.h"
|
||||
#include "mandoc_parse.h"
|
||||
|
||||
static void pline(int, int *, int *, int);
|
||||
static void pman(const struct roff_node *, int *, int *, int);
|
||||
@ -78,8 +79,8 @@ main(int argc, char *argv[])
|
||||
argv += optind;
|
||||
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(MPARSE_SO, MANDOCERR_MAX, NULL,
|
||||
MANDOC_OS_OTHER, NULL);
|
||||
mp = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1 |
|
||||
MPARSE_VALIDATE, MANDOC_OS_OTHER, NULL);
|
||||
assert(mp);
|
||||
|
||||
if (argc < 1)
|
||||
@ -109,24 +110,19 @@ usage(void)
|
||||
static void
|
||||
pmandoc(struct mparse *mp, int fd, const char *fn, int list)
|
||||
{
|
||||
struct roff_man *man;
|
||||
struct roff_meta *meta;
|
||||
int line, col;
|
||||
|
||||
mparse_readfd(mp, fd, fn);
|
||||
close(fd);
|
||||
mparse_result(mp, &man, NULL);
|
||||
meta = mparse_result(mp);
|
||||
line = 1;
|
||||
col = 0;
|
||||
|
||||
if (man == NULL)
|
||||
return;
|
||||
if (man->macroset == MACROSET_MDOC) {
|
||||
mdoc_validate(man);
|
||||
pmdoc(man->first->child, &line, &col, list);
|
||||
} else {
|
||||
man_validate(man);
|
||||
pman(man->first->child, &line, &col, list);
|
||||
}
|
||||
if (meta->macroset == MACROSET_MDOC)
|
||||
pmdoc(meta->first->child, &line, &col, list);
|
||||
else
|
||||
pman(meta->first->child, &line, &col, list);
|
||||
|
||||
if ( ! list)
|
||||
putchar('\n');
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: eqn.c,v 1.78 2017/07/15 16:26:17 schwarze Exp $ */
|
||||
/* $Id: eqn.c,v 1.83 2018/12/14 06:33:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -30,8 +30,9 @@
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "eqn.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
#include "eqn_parse.h"
|
||||
|
||||
#define EQN_NEST_MAX 128 /* maximum nesting of defines */
|
||||
#define STRNEQ(p1, sz1, p2, sz2) \
|
||||
@ -284,6 +285,13 @@ enum parse_mode {
|
||||
MODE_TOK
|
||||
};
|
||||
|
||||
struct eqn_def {
|
||||
char *key;
|
||||
size_t keysz;
|
||||
char *val;
|
||||
size_t valsz;
|
||||
};
|
||||
|
||||
static struct eqn_box *eqn_box_alloc(struct eqn_node *, struct eqn_box *);
|
||||
static struct eqn_box *eqn_box_makebinary(struct eqn_node *,
|
||||
struct eqn_box *);
|
||||
@ -295,12 +303,11 @@ static void eqn_undef(struct eqn_node *);
|
||||
|
||||
|
||||
struct eqn_node *
|
||||
eqn_alloc(struct mparse *parse)
|
||||
eqn_alloc(void)
|
||||
{
|
||||
struct eqn_node *ep;
|
||||
|
||||
ep = mandoc_calloc(1, sizeof(*ep));
|
||||
ep->parse = parse;
|
||||
ep->gsize = EQN_DEFSIZE;
|
||||
return ep;
|
||||
}
|
||||
@ -399,7 +406,7 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
||||
ep->end = strchr(ep->start + 1, *ep->start);
|
||||
ep->start++; /* Skip opening quote. */
|
||||
if (ep->end == NULL) {
|
||||
mandoc_msg(MANDOCERR_ARG_QUOTE, ep->parse,
|
||||
mandoc_msg(MANDOCERR_ARG_QUOTE,
|
||||
ep->node->line, ep->node->pos, NULL);
|
||||
ep->end = strchr(ep->start, '\0');
|
||||
}
|
||||
@ -420,7 +427,7 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
||||
if ((def = eqn_def_find(ep)) == NULL)
|
||||
break;
|
||||
if (++lim > EQN_NEST_MAX) {
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP, ep->parse,
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP,
|
||||
ep->node->line, ep->node->pos, NULL);
|
||||
return EQN_TOK_EOF;
|
||||
}
|
||||
@ -468,6 +475,8 @@ eqn_next(struct eqn_node *ep, enum parse_mode mode)
|
||||
void
|
||||
eqn_box_free(struct eqn_box *bp)
|
||||
{
|
||||
if (bp == NULL)
|
||||
return;
|
||||
|
||||
if (bp->first)
|
||||
eqn_box_free(bp->first);
|
||||
@ -482,6 +491,16 @@ eqn_box_free(struct eqn_box *bp)
|
||||
free(bp);
|
||||
}
|
||||
|
||||
struct eqn_box *
|
||||
eqn_box_new(void)
|
||||
{
|
||||
struct eqn_box *bp;
|
||||
|
||||
bp = mandoc_calloc(1, sizeof(*bp));
|
||||
bp->expectargs = UINT_MAX;
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a box as the last child of the parent node.
|
||||
*/
|
||||
@ -490,10 +509,9 @@ eqn_box_alloc(struct eqn_node *ep, struct eqn_box *parent)
|
||||
{
|
||||
struct eqn_box *bp;
|
||||
|
||||
bp = mandoc_calloc(1, sizeof(struct eqn_box));
|
||||
bp = eqn_box_new();
|
||||
bp->parent = parent;
|
||||
bp->parent->args++;
|
||||
bp->expectargs = UINT_MAX;
|
||||
bp->font = bp->parent->font;
|
||||
bp->size = ep->gsize;
|
||||
|
||||
@ -542,7 +560,7 @@ static void
|
||||
eqn_delim(struct eqn_node *ep)
|
||||
{
|
||||
if (ep->end[0] == '\0' || ep->end[1] == '\0') {
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY,
|
||||
ep->node->line, ep->node->pos, "delim");
|
||||
if (ep->end[0] != '\0')
|
||||
ep->end++;
|
||||
@ -569,7 +587,7 @@ eqn_undef(struct eqn_node *ep)
|
||||
struct eqn_def *def;
|
||||
|
||||
if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY,
|
||||
ep->node->line, ep->node->pos, "undef");
|
||||
return;
|
||||
}
|
||||
@ -588,7 +606,7 @@ eqn_def(struct eqn_node *ep)
|
||||
int i;
|
||||
|
||||
if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY,
|
||||
ep->node->line, ep->node->pos, "define");
|
||||
return;
|
||||
}
|
||||
@ -617,7 +635,7 @@ eqn_def(struct eqn_node *ep)
|
||||
}
|
||||
|
||||
if (eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF) {
|
||||
mandoc_vmsg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY,
|
||||
ep->node->line, ep->node->pos, "define %s", def->key);
|
||||
free(def->key);
|
||||
free(def->val);
|
||||
@ -666,7 +684,7 @@ eqn_parse(struct eqn_node *ep)
|
||||
case EQN_TOK_TDEFINE:
|
||||
if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF ||
|
||||
eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF)
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY,
|
||||
ep->node->line, ep->node->pos, "tdefine");
|
||||
break;
|
||||
case EQN_TOK_DELIM:
|
||||
@ -674,8 +692,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
break;
|
||||
case EQN_TOK_GFONT:
|
||||
if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
case EQN_TOK_MARK:
|
||||
case EQN_TOK_LINEUP:
|
||||
@ -690,8 +708,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
case EQN_TOK_DOT:
|
||||
case EQN_TOK_DOTDOT:
|
||||
if (parent->last == NULL) {
|
||||
mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_EQN_NOBOX, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
cur = eqn_box_alloc(ep, parent);
|
||||
cur->type = EQN_TEXT;
|
||||
cur->text = mandoc_strdup("");
|
||||
@ -735,8 +753,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
case EQN_TOK_DOWN:
|
||||
case EQN_TOK_UP:
|
||||
if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
case EQN_TOK_FAT:
|
||||
case EQN_TOK_ROMAN:
|
||||
@ -773,14 +791,14 @@ eqn_parse(struct eqn_node *ep)
|
||||
case EQN_TOK_GSIZE:
|
||||
/* Accept two values: integral size and a single. */
|
||||
if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
}
|
||||
size = mandoc_strntoi(ep->start, ep->toksz, 10);
|
||||
if (-1 == size) {
|
||||
mandoc_msg(MANDOCERR_IT_NONUM, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_IT_NONUM, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
}
|
||||
if (EQN_TOK_GSIZE == tok) {
|
||||
@ -804,8 +822,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
* and keep on reading.
|
||||
*/
|
||||
if (parent->last == NULL) {
|
||||
mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_EQN_NOBOX, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
cur = eqn_box_alloc(ep, parent);
|
||||
cur->type = EQN_TEXT;
|
||||
cur->text = mandoc_strdup("");
|
||||
@ -871,8 +889,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
* rebalance and continue reading.
|
||||
*/
|
||||
if (parent->last == NULL) {
|
||||
mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_EQN_NOBOX, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
cur = eqn_box_alloc(ep, parent);
|
||||
cur->type = EQN_TEXT;
|
||||
cur->text = mandoc_strdup("");
|
||||
@ -898,16 +916,16 @@ eqn_parse(struct eqn_node *ep)
|
||||
cur->left != NULL))
|
||||
break;
|
||||
if (cur == NULL) {
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
}
|
||||
parent = cur;
|
||||
if (EQN_TOK_RIGHT == tok) {
|
||||
if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY,
|
||||
ep->parse, ep->node->line,
|
||||
ep->node->pos, eqn_toks[tok]);
|
||||
ep->node->line, ep->node->pos,
|
||||
"%s", eqn_toks[tok]);
|
||||
break;
|
||||
}
|
||||
/* Handling depends on right/left. */
|
||||
@ -941,8 +959,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
parent = parent->parent;
|
||||
if (EQN_TOK_LEFT == tok &&
|
||||
eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
}
|
||||
parent = eqn_box_alloc(ep, parent);
|
||||
@ -975,8 +993,8 @@ eqn_parse(struct eqn_node *ep)
|
||||
if (cur->type == EQN_PILE)
|
||||
break;
|
||||
if (cur == NULL) {
|
||||
mandoc_msg(MANDOCERR_IT_STRAY, ep->parse,
|
||||
ep->node->line, ep->node->pos, eqn_toks[tok]);
|
||||
mandoc_msg(MANDOCERR_IT_STRAY, ep->node->line,
|
||||
ep->node->pos, "%s", eqn_toks[tok]);
|
||||
break;
|
||||
}
|
||||
parent = eqn_box_alloc(ep, cur);
|
||||
@ -1092,6 +1110,9 @@ eqn_free(struct eqn_node *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < (int)p->defsz; i++) {
|
||||
free(p->defs[i].key);
|
||||
free(p->defs[i].val);
|
||||
|
72
contrib/mandoc/eqn.h
Normal file
72
contrib/mandoc/eqn.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* $Id: eqn.h,v 1.1 2018/12/13 05:23:38 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 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.
|
||||
*
|
||||
* Public data types for eqn(7) syntax trees.
|
||||
*/
|
||||
|
||||
enum eqn_boxt {
|
||||
EQN_TEXT, /* Text, e.g. number, variable, operator, ... */
|
||||
EQN_SUBEXPR, /* Nested eqn(7) subexpression. */
|
||||
EQN_LIST, /* List, for example in braces. */
|
||||
EQN_PILE, /* Vertical pile. */
|
||||
EQN_MATRIX /* List of columns. */
|
||||
};
|
||||
|
||||
enum eqn_fontt {
|
||||
EQNFONT_NONE = 0,
|
||||
EQNFONT_ROMAN,
|
||||
EQNFONT_BOLD,
|
||||
EQNFONT_FAT,
|
||||
EQNFONT_ITALIC,
|
||||
EQNFONT__MAX
|
||||
};
|
||||
|
||||
enum eqn_post {
|
||||
EQNPOS_NONE = 0,
|
||||
EQNPOS_SUP,
|
||||
EQNPOS_SUBSUP,
|
||||
EQNPOS_SUB,
|
||||
EQNPOS_TO,
|
||||
EQNPOS_FROM,
|
||||
EQNPOS_FROMTO,
|
||||
EQNPOS_OVER,
|
||||
EQNPOS_SQRT,
|
||||
EQNPOS__MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* A "box" is a parsed mathematical expression as defined by the eqn.7
|
||||
* grammar.
|
||||
*/
|
||||
struct eqn_box {
|
||||
struct eqn_box *parent;
|
||||
struct eqn_box *prev;
|
||||
struct eqn_box *next;
|
||||
struct eqn_box *first; /* First child node. */
|
||||
struct eqn_box *last; /* Last child node. */
|
||||
char *text; /* Text (or NULL). */
|
||||
char *left; /* Left-hand fence. */
|
||||
char *right; /* Right-hand fence. */
|
||||
char *top; /* Symbol above. */
|
||||
char *bottom; /* Symbol below. */
|
||||
size_t expectargs; /* Maximal number of arguments. */
|
||||
size_t args; /* Actual number of arguments. */
|
||||
int size; /* Font size. */
|
||||
#define EQN_DEFSIZE INT_MIN
|
||||
enum eqn_boxt type; /* Type of node. */
|
||||
enum eqn_fontt font; /* Font in this box. */
|
||||
enum eqn_post pos; /* Position of the next box. */
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
/* $Id: eqn_html.c,v 1.17 2017/07/14 13:32:35 schwarze Exp $ */
|
||||
/* $Id: eqn_html.c,v 1.18 2018/12/13 05:23:38 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "eqn.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
||||
|
48
contrib/mandoc/eqn_parse.h
Normal file
48
contrib/mandoc/eqn_parse.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* $Id: eqn_parse.h,v 1.3 2018/12/14 06:33:14 schwarze Exp $ */
|
||||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* External interface of the eqn(7) parser.
|
||||
* For use in the roff(7) and eqn(7) parsers only.
|
||||
*/
|
||||
|
||||
struct roff_node;
|
||||
struct eqn_box;
|
||||
struct eqn_def;
|
||||
|
||||
struct eqn_node {
|
||||
struct roff_node *node; /* Syntax tree of this equation. */
|
||||
struct eqn_def *defs; /* Array of definitions. */
|
||||
char *data; /* Source code of this equation. */
|
||||
char *start; /* First byte of the current token. */
|
||||
char *end; /* First byte of the next token. */
|
||||
size_t defsz; /* Number of definitions. */
|
||||
size_t sz; /* Length of the source code. */
|
||||
size_t toksz; /* Length of the current token. */
|
||||
int gsize; /* Default point size. */
|
||||
int delim; /* In-line delimiters enabled. */
|
||||
char odelim; /* In-line opening delimiter. */
|
||||
char cdelim; /* In-line closing delimiter. */
|
||||
};
|
||||
|
||||
|
||||
struct eqn_node *eqn_alloc(void);
|
||||
struct eqn_box *eqn_box_new(void);
|
||||
void eqn_box_free(struct eqn_box *);
|
||||
void eqn_free(struct eqn_node *);
|
||||
void eqn_parse(struct eqn_node *);
|
||||
void eqn_read(struct eqn_node *, const char *);
|
||||
void eqn_reset(struct eqn_node *);
|
@ -1,4 +1,4 @@
|
||||
/* $Id: eqn_term.c,v 1.17 2017/08/23 21:56:20 schwarze Exp $ */
|
||||
/* $Id: eqn_term.c,v 1.19 2018/12/13 05:23:38 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -25,7 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "eqn.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
@ -106,7 +106,7 @@ eqn_box(struct termp *p, const struct eqn_box *bp)
|
||||
/* Special box types. */
|
||||
|
||||
if (bp->pos == EQNPOS_SQRT) {
|
||||
term_word(p, "sqrt");
|
||||
term_word(p, "\\(sr");
|
||||
if (bp->first != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
eqn_box(p, bp->first);
|
||||
|
@ -36,7 +36,7 @@ elif [ "X$1" = "X-u" ]; then
|
||||
MOPT="-Ios=OpenBSD -Wall -Tutf8 $MOPT"
|
||||
COLPIPE="cat"
|
||||
else
|
||||
ROFF="groff -et -ww -mtty-char -Tascii -P -c"
|
||||
ROFF="groff -ket -ww -mtty-char -Tascii -P -c"
|
||||
MOPT="-Ios=OpenBSD -Wall -Tascii $MOPT"
|
||||
COLPIPE="cat"
|
||||
fi
|
||||
@ -51,7 +51,7 @@ while [ -n "$1" ]; do
|
||||
for i in roff mandoc; do
|
||||
[ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err
|
||||
done
|
||||
diff -au /tmp/roff.out /tmp/mandoc.out 2>&1
|
||||
diff -au $DIFFOPT /tmp/roff.out /tmp/mandoc.out 2>&1
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: html.c,v 1.238 2018/06/25 16:54:59 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.254 2019/03/03 13:02:11 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2015, 2017-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
|
||||
@ -18,6 +18,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
@ -62,6 +63,7 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"title", HTML_NLAROUND},
|
||||
{"div", HTML_NLAROUND},
|
||||
{"div", 0},
|
||||
{"section", HTML_NLALL},
|
||||
{"h1", HTML_NLAROUND},
|
||||
{"h2", HTML_NLAROUND},
|
||||
{"span", 0},
|
||||
@ -77,6 +79,7 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"dl", HTML_NLALL | HTML_INDENT},
|
||||
{"dt", HTML_NLAROUND},
|
||||
{"dd", HTML_NLAROUND | HTML_INDENT},
|
||||
{"p", HTML_NLAROUND | HTML_INDENT},
|
||||
{"pre", HTML_NLALL | HTML_NOINDENT},
|
||||
{"var", 0},
|
||||
{"cite", 0},
|
||||
@ -107,6 +110,7 @@ static const struct htmldata htmltags[TAG_MAX] = {
|
||||
/* Avoid duplicate HTML id= attributes. */
|
||||
static struct ohash id_unique;
|
||||
|
||||
static void html_reset_internal(struct html *);
|
||||
static void print_byte(struct html *, char);
|
||||
static void print_endword(struct html *);
|
||||
static void print_indent(struct html *);
|
||||
@ -116,7 +120,6 @@ static void print_ctag(struct html *, struct tag *);
|
||||
static int print_escape(struct html *, char);
|
||||
static int print_encode(struct html *, const char *, const char *, int);
|
||||
static void print_href(struct html *, const char *, const char *, int);
|
||||
static void print_metaf(struct html *, enum mandoc_esc);
|
||||
|
||||
|
||||
void *
|
||||
@ -128,31 +131,32 @@ html_alloc(const struct manoutput *outopts)
|
||||
|
||||
h->tag = NULL;
|
||||
h->style = outopts->style;
|
||||
h->base_man = outopts->man;
|
||||
if ((h->base_man1 = outopts->man) == NULL)
|
||||
h->base_man2 = NULL;
|
||||
else if ((h->base_man2 = strchr(h->base_man1, ';')) != NULL)
|
||||
*h->base_man2++ = '\0';
|
||||
h->base_includes = outopts->includes;
|
||||
if (outopts->fragment)
|
||||
h->oflags |= HTML_FRAGMENT;
|
||||
if (outopts->toc)
|
||||
h->oflags |= HTML_TOC;
|
||||
|
||||
mandoc_ohash_init(&id_unique, 4, 0);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
void
|
||||
html_free(void *p)
|
||||
static void
|
||||
html_reset_internal(struct html *h)
|
||||
{
|
||||
struct tag *tag;
|
||||
struct html *h;
|
||||
char *cp;
|
||||
unsigned int slot;
|
||||
|
||||
h = (struct html *)p;
|
||||
while ((tag = h->tag) != NULL) {
|
||||
h->tag = tag->next;
|
||||
free(tag);
|
||||
}
|
||||
free(h);
|
||||
|
||||
cp = ohash_first(&id_unique, &slot);
|
||||
while (cp != NULL) {
|
||||
free(cp);
|
||||
@ -161,6 +165,20 @@ html_free(void *p)
|
||||
ohash_delete(&id_unique);
|
||||
}
|
||||
|
||||
void
|
||||
html_reset(void *p)
|
||||
{
|
||||
html_reset_internal(p);
|
||||
mandoc_ohash_init(&id_unique, 4, 0);
|
||||
}
|
||||
|
||||
void
|
||||
html_free(void *p)
|
||||
{
|
||||
html_reset_internal(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
void
|
||||
print_gen_head(struct html *h)
|
||||
{
|
||||
@ -204,7 +222,7 @@ print_gen_head(struct html *h)
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
{
|
||||
enum htmlfont font;
|
||||
@ -222,12 +240,15 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
case ESCAPE_FONTBI:
|
||||
font = HTMLFONT_BI;
|
||||
break;
|
||||
case ESCAPE_FONTCW:
|
||||
font = HTMLFONT_CW;
|
||||
break;
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTROMAN:
|
||||
font = HTMLFONT_NONE;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (h->metaf) {
|
||||
@ -249,11 +270,69 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_CW:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
html_close_paragraph(struct html *h)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
for (t = h->tag; t != NULL && t->closed == 0; t = t->next) {
|
||||
switch(t->tag) {
|
||||
case TAG_P:
|
||||
case TAG_PRE:
|
||||
print_tagq(h, t);
|
||||
break;
|
||||
case TAG_A:
|
||||
print_tagq(h, t);
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ROFF_nf switches to no-fill mode, ROFF_fi to fill mode.
|
||||
* TOKEN_NONE does not switch. The old mode is returned.
|
||||
*/
|
||||
enum roff_tok
|
||||
html_fillmode(struct html *h, enum roff_tok want)
|
||||
{
|
||||
struct tag *t;
|
||||
enum roff_tok had;
|
||||
|
||||
for (t = h->tag; t != NULL; t = t->next)
|
||||
if (t->tag == TAG_PRE)
|
||||
break;
|
||||
|
||||
had = t == NULL ? ROFF_fi : ROFF_nf;
|
||||
|
||||
if (want != had) {
|
||||
switch (want) {
|
||||
case ROFF_fi:
|
||||
print_tagq(h, t);
|
||||
break;
|
||||
case ROFF_nf:
|
||||
html_close_paragraph(h);
|
||||
print_otag(h, TAG_PRE, "");
|
||||
break;
|
||||
case TOKEN_NONE:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return had;
|
||||
}
|
||||
|
||||
char *
|
||||
html_make_id(const struct roff_node *n, int unique)
|
||||
{
|
||||
@ -345,7 +424,6 @@ static int
|
||||
print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
{
|
||||
char numbuf[16];
|
||||
struct tag *t;
|
||||
const char *seq;
|
||||
size_t sz;
|
||||
int c, len, breakline, nospace;
|
||||
@ -371,9 +449,7 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
|
||||
if (breakline &&
|
||||
(p >= pend || *p == ' ' || *p == ASCII_NBRSP)) {
|
||||
t = print_otag(h, TAG_DIV, "");
|
||||
print_text(h, "\\~");
|
||||
print_tagq(h, t);
|
||||
print_otag(h, TAG_BR, "");
|
||||
breakline = 0;
|
||||
while (p < pend && (*p == ' ' || *p == ASCII_NBRSP))
|
||||
p++;
|
||||
@ -393,22 +469,25 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
continue;
|
||||
|
||||
esc = mandoc_escape(&p, &seq, &len);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
break;
|
||||
|
||||
switch (esc) {
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTPREV:
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBI:
|
||||
case ESCAPE_FONTCW:
|
||||
case ESCAPE_FONTROMAN:
|
||||
if (0 == norecurse)
|
||||
if (0 == norecurse) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_metaf(h, esc);
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
}
|
||||
continue;
|
||||
case ESCAPE_SKIPCHAR:
|
||||
h->flags |= HTML_SKIPCHAR;
|
||||
continue;
|
||||
case ESCAPE_ERROR:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -433,6 +512,12 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
if (c <= 0)
|
||||
continue;
|
||||
break;
|
||||
case ESCAPE_UNDEF:
|
||||
c = *seq;
|
||||
break;
|
||||
case ESCAPE_DEVICE:
|
||||
print_word(h, "html");
|
||||
continue;
|
||||
case ESCAPE_BREAK:
|
||||
breakline = 1;
|
||||
continue;
|
||||
@ -464,9 +549,21 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
static void
|
||||
print_href(struct html *h, const char *name, const char *sec, int man)
|
||||
{
|
||||
struct stat sb;
|
||||
const char *p, *pp;
|
||||
char *filename;
|
||||
|
||||
if (man) {
|
||||
pp = h->base_man1;
|
||||
if (h->base_man2 != NULL) {
|
||||
mandoc_asprintf(&filename, "%s.%s", name, sec);
|
||||
if (stat(filename, &sb) == -1)
|
||||
pp = h->base_man2;
|
||||
free(filename);
|
||||
}
|
||||
} else
|
||||
pp = h->base_includes;
|
||||
|
||||
pp = man ? h->base_man : h->base_includes;
|
||||
while ((p = strchr(pp, '%')) != NULL) {
|
||||
print_encode(h, pp, p, 1);
|
||||
if (man && p[1] == 'S') {
|
||||
@ -492,7 +589,7 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
struct tag *t;
|
||||
const char *attr;
|
||||
char *arg1, *arg2;
|
||||
int tflags;
|
||||
int style_written, tflags;
|
||||
|
||||
tflags = htmltags[tag].flags;
|
||||
|
||||
@ -502,6 +599,8 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
t = mandoc_malloc(sizeof(struct tag));
|
||||
t->tag = tag;
|
||||
t->next = h->tag;
|
||||
t->refcnt = 0;
|
||||
t->closed = 0;
|
||||
h->tag = t;
|
||||
} else
|
||||
t = NULL;
|
||||
@ -532,7 +631,7 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
while (*fmt != '\0') {
|
||||
while (*fmt != '\0' && *fmt != 's') {
|
||||
|
||||
/* Parse attributes and arguments. */
|
||||
|
||||
@ -548,10 +647,6 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
case 'i':
|
||||
attr = "id";
|
||||
break;
|
||||
case 's':
|
||||
attr = "style";
|
||||
arg2 = va_arg(ap, char *);
|
||||
break;
|
||||
case '?':
|
||||
attr = arg1;
|
||||
arg1 = va_arg(ap, char *);
|
||||
@ -584,26 +679,33 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
fmt++;
|
||||
break;
|
||||
case 'T':
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
print_word(h, "\" title=\"");
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
fmt++;
|
||||
break;
|
||||
default:
|
||||
if (arg2 == NULL)
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
else {
|
||||
print_word(h, arg1);
|
||||
print_byte(h, ':');
|
||||
print_byte(h, ' ');
|
||||
print_word(h, arg2);
|
||||
print_byte(h, ';');
|
||||
}
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
break;
|
||||
}
|
||||
print_byte(h, '"');
|
||||
}
|
||||
|
||||
style_written = 0;
|
||||
while (*fmt++ == 's') {
|
||||
arg1 = va_arg(ap, char *);
|
||||
arg2 = va_arg(ap, char *);
|
||||
if (arg2 == NULL)
|
||||
continue;
|
||||
print_byte(h, ' ');
|
||||
if (style_written == 0) {
|
||||
print_word(h, "style=\"");
|
||||
style_written = 1;
|
||||
}
|
||||
print_word(h, arg1);
|
||||
print_byte(h, ':');
|
||||
print_byte(h, ' ');
|
||||
print_word(h, arg2);
|
||||
print_byte(h, ';');
|
||||
}
|
||||
if (style_written)
|
||||
print_byte(h, '"');
|
||||
|
||||
va_end(ap);
|
||||
|
||||
/* Accommodate for "well-formed" singleton escaping. */
|
||||
@ -631,33 +733,32 @@ print_ctag(struct html *h, struct tag *tag)
|
||||
{
|
||||
int tflags;
|
||||
|
||||
/*
|
||||
* Remember to close out and nullify the current
|
||||
* meta-font and table, if applicable.
|
||||
*/
|
||||
if (tag == h->metaf)
|
||||
h->metaf = NULL;
|
||||
if (tag == h->tblt)
|
||||
h->tblt = NULL;
|
||||
if (tag->closed == 0) {
|
||||
tag->closed = 1;
|
||||
if (tag == h->metaf)
|
||||
h->metaf = NULL;
|
||||
if (tag == h->tblt)
|
||||
h->tblt = NULL;
|
||||
|
||||
tflags = htmltags[tag->tag].flags;
|
||||
|
||||
if (tflags & HTML_INDENT)
|
||||
h->indent--;
|
||||
if (tflags & HTML_NOINDENT)
|
||||
h->noindent--;
|
||||
if (tflags & HTML_NLEND)
|
||||
print_endline(h);
|
||||
print_indent(h);
|
||||
print_byte(h, '<');
|
||||
print_byte(h, '/');
|
||||
print_word(h, htmltags[tag->tag].name);
|
||||
print_byte(h, '>');
|
||||
if (tflags & HTML_NLAFTER)
|
||||
print_endline(h);
|
||||
|
||||
h->tag = tag->next;
|
||||
free(tag);
|
||||
tflags = htmltags[tag->tag].flags;
|
||||
if (tflags & HTML_INDENT)
|
||||
h->indent--;
|
||||
if (tflags & HTML_NOINDENT)
|
||||
h->noindent--;
|
||||
if (tflags & HTML_NLEND)
|
||||
print_endline(h);
|
||||
print_indent(h);
|
||||
print_byte(h, '<');
|
||||
print_byte(h, '/');
|
||||
print_word(h, htmltags[tag->tag].name);
|
||||
print_byte(h, '>');
|
||||
if (tflags & HTML_NLAFTER)
|
||||
print_endline(h);
|
||||
}
|
||||
if (tag->refcnt == 0) {
|
||||
h->tag = tag->next;
|
||||
free(tag);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -717,6 +818,9 @@ print_text(struct html *h, const char *word)
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_CW:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
break;
|
||||
default:
|
||||
print_indent(h);
|
||||
break;
|
||||
@ -741,36 +845,33 @@ print_text(struct html *h, const char *word)
|
||||
void
|
||||
print_tagq(struct html *h, const struct tag *until)
|
||||
{
|
||||
struct tag *tag;
|
||||
struct tag *this, *next;
|
||||
|
||||
while ((tag = h->tag) != NULL) {
|
||||
print_ctag(h, tag);
|
||||
if (until && tag == until)
|
||||
return;
|
||||
for (this = h->tag; this != NULL; this = next) {
|
||||
next = this == until ? NULL : this->next;
|
||||
print_ctag(h, this);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close out all open elements up to but excluding suntil.
|
||||
* Note that a paragraph just inside stays open together with it
|
||||
* because paragraphs include subsequent phrasing content.
|
||||
*/
|
||||
void
|
||||
print_stagq(struct html *h, const struct tag *suntil)
|
||||
{
|
||||
struct tag *tag;
|
||||
struct tag *this, *next;
|
||||
|
||||
while ((tag = h->tag) != NULL) {
|
||||
if (suntil && tag == suntil)
|
||||
return;
|
||||
print_ctag(h, tag);
|
||||
for (this = h->tag; this != NULL; this = next) {
|
||||
next = this->next;
|
||||
if (this == suntil || (next == suntil &&
|
||||
(this->tag == TAG_P || this->tag == TAG_PRE)))
|
||||
break;
|
||||
print_ctag(h, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_paragraph(struct html *h)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
t = print_otag(h, TAG_DIV, "c", "Pp");
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Low level output functions.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: html.h,v 1.92 2018/06/25 16:54:59 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.102 2019/03/01 10:57:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -24,6 +24,7 @@ enum htmltag {
|
||||
TAG_TITLE,
|
||||
TAG_DIV,
|
||||
TAG_IDIV,
|
||||
TAG_SECTION,
|
||||
TAG_H1,
|
||||
TAG_H2,
|
||||
TAG_SPAN,
|
||||
@ -39,6 +40,7 @@ enum htmltag {
|
||||
TAG_DL,
|
||||
TAG_DT,
|
||||
TAG_DD,
|
||||
TAG_P,
|
||||
TAG_PRE,
|
||||
TAG_VAR,
|
||||
TAG_CITE,
|
||||
@ -72,11 +74,14 @@ enum htmlfont {
|
||||
HTMLFONT_BOLD,
|
||||
HTMLFONT_ITALIC,
|
||||
HTMLFONT_BI,
|
||||
HTMLFONT_CW,
|
||||
HTMLFONT_MAX
|
||||
};
|
||||
|
||||
struct tag {
|
||||
struct tag *next;
|
||||
int refcnt;
|
||||
int closed;
|
||||
enum htmltag tag;
|
||||
};
|
||||
|
||||
@ -87,12 +92,12 @@ struct html {
|
||||
#define HTML_KEEP (1 << 2)
|
||||
#define HTML_PREKEEP (1 << 3)
|
||||
#define HTML_NONOSPACE (1 << 4) /* never add spaces */
|
||||
#define HTML_LITERAL (1 << 5) /* literal (e.g., <PRE>) context */
|
||||
#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
|
||||
#define HTML_NOSPLIT (1 << 7) /* do not break line before .An */
|
||||
#define HTML_SPLIT (1 << 8) /* break line before .An */
|
||||
#define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */
|
||||
#define HTML_BUFFER (1 << 10) /* Collect a word to see if it fits. */
|
||||
#define HTML_TOCDONE (1 << 11) /* The TOC was already written. */
|
||||
size_t indent; /* current output indentation level */
|
||||
int noindent; /* indent disabled by <pre> */
|
||||
size_t col; /* current output byte position */
|
||||
@ -101,7 +106,8 @@ struct html {
|
||||
struct tag *tag; /* last open tag */
|
||||
struct rofftbl tbl; /* current table */
|
||||
struct tag *tblt; /* current open table scope */
|
||||
char *base_man; /* base for manpage href */
|
||||
char *base_man1; /* bases for manpage href */
|
||||
char *base_man2;
|
||||
char *base_includes; /* base for include href */
|
||||
char *style; /* style-sheet URI */
|
||||
struct tag *metaf; /* current open font scope */
|
||||
@ -109,6 +115,7 @@ struct html {
|
||||
enum htmlfont metac; /* current font mode */
|
||||
int oflags; /* output options */
|
||||
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
|
||||
#define HTML_TOC (1 << 1) /* emit a table of contents */
|
||||
};
|
||||
|
||||
|
||||
@ -121,6 +128,7 @@ void roff_html_pre(struct html *, const struct roff_node *);
|
||||
void print_gen_comment(struct html *, struct roff_node *);
|
||||
void print_gen_decls(struct html *);
|
||||
void print_gen_head(struct html *);
|
||||
void print_metaf(struct html *, enum mandoc_esc);
|
||||
struct tag *print_otag(struct html *, enum htmltag, const char *, ...);
|
||||
void print_tagq(struct html *, const struct tag *);
|
||||
void print_stagq(struct html *, const struct tag *);
|
||||
@ -128,7 +136,8 @@ void print_text(struct html *, const char *);
|
||||
void print_tblclose(struct html *);
|
||||
void print_tbl(struct html *, const struct tbl_span *);
|
||||
void print_eqn(struct html *, const struct eqn_box *);
|
||||
void print_paragraph(struct html *);
|
||||
void print_endline(struct html *);
|
||||
|
||||
void html_close_paragraph(struct html *);
|
||||
enum roff_tok html_fillmode(struct html *, enum roff_tok);
|
||||
char *html_make_id(const struct roff_node *, int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: lib.c,v 1.14 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/* $Id: lib.c,v 1.15 2018/12/13 11:55:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -17,12 +17,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: lib.in,v 1.20 2017/08/20 02:30:27 schwarze Exp $ */
|
||||
/* $Id: lib.in,v 1.21 2019/03/04 17:35:21 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: libman.h,v 1.81 2017/04/29 12:45:41 schwarze Exp $ */
|
||||
/* $Id: libman.h,v 1.86 2018/12/31 10:04:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 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
|
||||
@ -16,6 +16,9 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct roff_node;
|
||||
struct roff_man;
|
||||
|
||||
#define MACRO_PROT_ARGS struct roff_man *man, \
|
||||
enum roff_tok tok, \
|
||||
int line, \
|
||||
@ -26,15 +29,14 @@
|
||||
struct man_macro {
|
||||
void (*fp)(MACRO_PROT_ARGS);
|
||||
int flags;
|
||||
#define MAN_SCOPED (1 << 0) /* Optional next-line scope. */
|
||||
#define MAN_NSCOPED (1 << 1) /* Allowed in next-line element scope. */
|
||||
#define MAN_BSCOPE (1 << 2) /* Break next-line block scope. */
|
||||
#define MAN_JOIN (1 << 3) /* Join arguments together. */
|
||||
#define MAN_BSCOPED (1 << 0) /* Optional next-line block scope. */
|
||||
#define MAN_ESCOPED (1 << 1) /* Optional next-line element scope. */
|
||||
#define MAN_NSCOPED (1 << 2) /* Allowed in next-line element scope. */
|
||||
#define MAN_XSCOPE (1 << 3) /* Exit next-line block scope. */
|
||||
#define MAN_JOIN (1 << 4) /* Join arguments together. */
|
||||
};
|
||||
|
||||
extern const struct man_macro *const man_macros;
|
||||
const struct man_macro *man_macro(enum roff_tok);
|
||||
|
||||
|
||||
void man_node_validate(struct roff_man *);
|
||||
void man_state(struct roff_man *, struct roff_node *);
|
||||
void man_descope(struct roff_man *, int, int, char *);
|
||||
void man_unscope(struct roff_man *, const struct roff_node *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: libmandoc.h,v 1.71 2018/04/09 22:27:04 schwarze Exp $ */
|
||||
/* $Id: libmandoc.h,v 1.77 2018/12/21 17:15:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,31 +16,38 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
enum rofferr {
|
||||
ROFF_CONT, /* continue processing line */
|
||||
ROFF_RERUN, /* re-run roff interpreter with offset */
|
||||
ROFF_APPEND, /* re-run main parser, appending next line */
|
||||
ROFF_REPARSE, /* re-run main parser on the result */
|
||||
ROFF_SO, /* include another file */
|
||||
ROFF_IGN, /* ignore current line */
|
||||
};
|
||||
/*
|
||||
* Return codes passed from the roff parser to the main parser.
|
||||
*/
|
||||
|
||||
/* Main instruction: what to do with the returned line. */
|
||||
#define ROFF_IGN 0x000 /* Don't do anything with it. */
|
||||
#define ROFF_CONT 0x001 /* Give it to the high-level parser. */
|
||||
#define ROFF_RERUN 0x002 /* Re-run the roff parser with an offset. */
|
||||
#define ROFF_REPARSE 0x004 /* Recursively run the main parser on it. */
|
||||
#define ROFF_SO 0x008 /* Include the named file. */
|
||||
#define ROFF_MASK 0x00f /* Only one of these bits should be set. */
|
||||
|
||||
/* Options for further parsing, to be OR'ed with the above. */
|
||||
#define ROFF_APPEND 0x010 /* Append the next line to this one. */
|
||||
#define ROFF_USERCALL 0x020 /* Start execution of a new macro. */
|
||||
#define ROFF_USERRET 0x040 /* Abort execution of the current macro. */
|
||||
#define ROFF_WHILE 0x100 /* Start a new .while loop. */
|
||||
#define ROFF_LOOPCONT 0x200 /* Iterate the current .while loop. */
|
||||
#define ROFF_LOOPEXIT 0x400 /* Exit the current .while loop. */
|
||||
#define ROFF_LOOPMASK 0xf00
|
||||
|
||||
|
||||
struct buf {
|
||||
char *buf;
|
||||
size_t sz;
|
||||
char *buf;
|
||||
size_t sz;
|
||||
struct buf *next;
|
||||
};
|
||||
|
||||
|
||||
struct mparse;
|
||||
struct roff;
|
||||
struct roff_man;
|
||||
|
||||
void mandoc_msg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *);
|
||||
void mandoc_vmsg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 5, 6)));
|
||||
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
||||
char *mandoc_normdate(struct roff_man *, char *, int, int);
|
||||
int mandoc_eos(const char *, size_t);
|
||||
int mandoc_strntoi(const char *, size_t, int);
|
||||
@ -57,17 +64,18 @@ int preconv_encode(const struct buf *, size_t *,
|
||||
struct buf *, size_t *, int *);
|
||||
|
||||
void roff_free(struct roff *);
|
||||
struct roff *roff_alloc(struct mparse *, int);
|
||||
struct roff *roff_alloc(int);
|
||||
void roff_reset(struct roff *);
|
||||
void roff_man_free(struct roff_man *);
|
||||
struct roff_man *roff_man_alloc(struct roff *, struct mparse *,
|
||||
const char *, int);
|
||||
struct roff_man *roff_man_alloc(struct roff *, const char *, int);
|
||||
void roff_man_reset(struct roff_man *);
|
||||
enum rofferr roff_parseln(struct roff *, int, struct buf *, int *);
|
||||
int roff_parseln(struct roff *, int, struct buf *, int *);
|
||||
void roff_userret(struct roff *);
|
||||
void roff_endparse(struct roff *);
|
||||
void roff_setreg(struct roff *, const char *, int, char sign);
|
||||
int roff_getreg(struct roff *, const char *);
|
||||
char *roff_strdup(const struct roff *, const char *);
|
||||
char *roff_getarg(struct roff *, char **, int, int *);
|
||||
int roff_getcontrol(const struct roff *,
|
||||
const char *, int *);
|
||||
int roff_getformat(const struct roff *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: libmdoc.h,v 1.112 2017/05/30 16:22:03 schwarze Exp $ */
|
||||
/* $Id: libmdoc.h,v 1.117 2018/12/31 04:55:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,6 +16,10 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct roff_node;
|
||||
struct roff_man;
|
||||
struct mdoc_arg;
|
||||
|
||||
#define MACRO_PROT_ARGS struct roff_man *mdoc, \
|
||||
enum roff_tok tok, \
|
||||
int line, \
|
||||
@ -38,6 +42,7 @@ enum margserr {
|
||||
ARGS_ERROR,
|
||||
ARGS_EOLN, /* end-of-line */
|
||||
ARGS_WORD, /* normal word */
|
||||
ARGS_ALLOC, /* normal word from roff_getarg() */
|
||||
ARGS_PUNCT, /* series of punctuation */
|
||||
ARGS_PHRASE /* Bl -column phrase */
|
||||
};
|
||||
@ -59,10 +64,8 @@ enum mdelim {
|
||||
DELIM_MAX
|
||||
};
|
||||
|
||||
extern const struct mdoc_macro *const mdoc_macros;
|
||||
const struct mdoc_macro *mdoc_macro(enum roff_tok);
|
||||
|
||||
|
||||
void mdoc_macro(MACRO_PROT_ARGS);
|
||||
void mdoc_elem_alloc(struct roff_man *, int, int,
|
||||
enum roff_tok, struct mdoc_arg *);
|
||||
struct roff_node *mdoc_block_alloc(struct roff_man *, int, int,
|
||||
@ -71,10 +74,7 @@ void mdoc_tail_alloc(struct roff_man *, int, int,
|
||||
enum roff_tok);
|
||||
struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int,
|
||||
enum roff_tok, struct roff_node *);
|
||||
void mdoc_node_relink(struct roff_man *, struct roff_node *);
|
||||
void mdoc_node_validate(struct roff_man *);
|
||||
void mdoc_state(struct roff_man *, struct roff_node *);
|
||||
void mdoc_state_reset(struct roff_man *);
|
||||
const char *mdoc_a2arch(const char *);
|
||||
const char *mdoc_a2att(const char *);
|
||||
const char *mdoc_a2lib(const char *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: main.c,v 1.306 2018/05/14 14:10:23 schwarze Exp $ */
|
||||
/* $Id: main.c,v 1.322 2019/03/06 10:18:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -49,6 +49,7 @@
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "mandoc_parse.h"
|
||||
#include "tag.h"
|
||||
#include "main.h"
|
||||
#include "manconf.h"
|
||||
@ -81,7 +82,6 @@ struct curparse {
|
||||
void *outdata; /* data for output */
|
||||
char *os_s; /* operating system for display */
|
||||
int wstop; /* stop after a file with a warning */
|
||||
enum mandocerr mmin; /* ignore messages below this */
|
||||
enum mandoc_os os_e; /* check base system conventions */
|
||||
enum outt outtype; /* which output to use */
|
||||
};
|
||||
@ -89,7 +89,7 @@ struct curparse {
|
||||
|
||||
int mandocdb(int, char *[]);
|
||||
|
||||
static void check_xr(const char *);
|
||||
static void check_xr(void);
|
||||
static int fs_lookup(const struct manpaths *,
|
||||
size_t ipath, const char *,
|
||||
const char *, const char *,
|
||||
@ -99,8 +99,6 @@ static int fs_search(const struct mansearch *,
|
||||
struct manpage **, size_t *);
|
||||
static int koptions(int *, char *);
|
||||
static void moptions(int *, char *);
|
||||
static void mmsg(enum mandocerr, enum mandoclevel,
|
||||
const char *, int, int, const char *);
|
||||
static void outdata_alloc(struct curparse *);
|
||||
static void parse(struct curparse *, int, const char *);
|
||||
static void passthrough(const char *, int, int);
|
||||
@ -112,8 +110,6 @@ static int woptions(struct curparse *, char *);
|
||||
static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
|
||||
static char help_arg[] = "help";
|
||||
static char *help_argv[] = {help_arg, NULL};
|
||||
static enum mandoclevel rc;
|
||||
static FILE *mmsg_stream;
|
||||
|
||||
|
||||
int
|
||||
@ -127,7 +123,7 @@ main(int argc, char *argv[])
|
||||
struct manpage *res, *resp;
|
||||
const char *progname, *sec, *thisarg;
|
||||
char *conf_file, *defpaths, *auxpaths;
|
||||
char *oarg;
|
||||
char *oarg, *tagarg;
|
||||
unsigned char *uc;
|
||||
size_t i, sz;
|
||||
int prio, best_prio;
|
||||
@ -152,6 +148,7 @@ main(int argc, char *argv[])
|
||||
setprogname(progname);
|
||||
#endif
|
||||
|
||||
mandoc_msg_setoutfile(stderr);
|
||||
if (strncmp(progname, "mandocdb", 8) == 0 ||
|
||||
strcmp(progname, BINM_MAKEWHATIS) == 0)
|
||||
return mandocdb(argc, argv);
|
||||
@ -191,10 +188,8 @@ main(int argc, char *argv[])
|
||||
|
||||
memset(&curp, 0, sizeof(struct curparse));
|
||||
curp.outtype = OUTT_LOCALE;
|
||||
curp.mmin = MANDOCERR_MAX;
|
||||
curp.outopts = &conf.output;
|
||||
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
|
||||
mmsg_stream = stderr;
|
||||
|
||||
use_pager = 1;
|
||||
tag_files = NULL;
|
||||
@ -320,6 +315,9 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (curp.outtype != OUTT_TREE || !curp.outopts->noval)
|
||||
options |= MPARSE_VALIDATE;
|
||||
|
||||
if (outmode == OUTMODE_FLN ||
|
||||
outmode == OUTMODE_LST ||
|
||||
!isatty(STDOUT_FILENO))
|
||||
@ -377,7 +375,16 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = MANDOCLEVEL_OK;
|
||||
/*
|
||||
* Use the first argument for -O tag in addition to
|
||||
* using it as a search term for man(1) or apropos(1).
|
||||
*/
|
||||
|
||||
if (conf.output.tag != NULL && *conf.output.tag == '\0') {
|
||||
tagarg = argc > 0 && search.argmode == ARG_EXPR ?
|
||||
strchr(*argv, '=') : NULL;
|
||||
conf.output.tag = tagarg == NULL ? *argv : tagarg + 1;
|
||||
}
|
||||
|
||||
/* man(1), whatis(1), apropos(1) */
|
||||
|
||||
@ -436,7 +443,6 @@ main(int argc, char *argv[])
|
||||
res[sz].names = NULL;
|
||||
res[sz].output = NULL;
|
||||
res[sz].ipath = SIZE_MAX;
|
||||
res[sz].bits = 0;
|
||||
res[sz].sec = 10;
|
||||
res[sz].form = FORM_SRC;
|
||||
sz++;
|
||||
@ -446,7 +452,7 @@ main(int argc, char *argv[])
|
||||
if (sz == 0) {
|
||||
if (search.argmode != ARG_NAME)
|
||||
warnx("nothing appropriate");
|
||||
rc = MANDOCLEVEL_BADARG;
|
||||
mandoc_msg_setrc(MANDOCLEVEL_BADARG);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -514,19 +520,17 @@ main(int argc, char *argv[])
|
||||
moptions(&options, auxpaths);
|
||||
|
||||
mchars_alloc();
|
||||
curp.mp = mparse_alloc(options, curp.mmin, mmsg,
|
||||
curp.os_e, curp.os_s);
|
||||
|
||||
/*
|
||||
* Conditionally start up the lookaside buffer before parsing.
|
||||
*/
|
||||
if (OUTT_MAN == curp.outtype)
|
||||
mparse_keep(curp.mp);
|
||||
curp.mp = mparse_alloc(options, curp.os_e, curp.os_s);
|
||||
|
||||
if (argc < 1) {
|
||||
if (use_pager)
|
||||
if (use_pager) {
|
||||
tag_files = tag_init();
|
||||
parse(&curp, STDIN_FILENO, "<stdin>");
|
||||
tag_files->tagname = conf.output.tag;
|
||||
}
|
||||
thisarg = "<stdin>";
|
||||
mandoc_msg_setinfilename(thisarg);
|
||||
parse(&curp, STDIN_FILENO, thisarg);
|
||||
mandoc_msg_setinfilename(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -550,22 +554,25 @@ main(int argc, char *argv[])
|
||||
(void)chdir(conf.manpath.paths[resp->ipath]);
|
||||
else if (startdir != -1)
|
||||
(void)fchdir(startdir);
|
||||
}
|
||||
thisarg = resp->file;
|
||||
} else
|
||||
thisarg = *argv;
|
||||
|
||||
fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv);
|
||||
fd = mparse_open(curp.mp, thisarg);
|
||||
if (fd != -1) {
|
||||
if (use_pager) {
|
||||
tag_files = tag_init();
|
||||
use_pager = 0;
|
||||
tag_files = tag_init();
|
||||
tag_files->tagname = conf.output.tag;
|
||||
}
|
||||
|
||||
if (resp == NULL)
|
||||
parse(&curp, fd, *argv);
|
||||
else if (resp->form == FORM_SRC)
|
||||
parse(&curp, fd, resp->file);
|
||||
mandoc_msg_setinfilename(thisarg);
|
||||
if (resp == NULL || resp->form == FORM_SRC)
|
||||
parse(&curp, fd, thisarg);
|
||||
else
|
||||
passthrough(resp->file, fd,
|
||||
conf.output.synopsisonly);
|
||||
mandoc_msg_setinfilename(NULL);
|
||||
|
||||
if (ferror(stdout)) {
|
||||
if (tag_files != NULL) {
|
||||
@ -574,7 +581,7 @@ main(int argc, char *argv[])
|
||||
tag_files = NULL;
|
||||
} else
|
||||
warn("stdout");
|
||||
rc = MANDOCLEVEL_SYSERR;
|
||||
mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -583,10 +590,11 @@ main(int argc, char *argv[])
|
||||
outdata_alloc(&curp);
|
||||
terminal_sepline(curp.outdata);
|
||||
}
|
||||
} else if (rc < MANDOCLEVEL_ERROR)
|
||||
rc = MANDOCLEVEL_ERROR;
|
||||
} else
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0,
|
||||
"%s: %s", thisarg, strerror(errno));
|
||||
|
||||
if (MANDOCLEVEL_OK != rc && curp.wstop)
|
||||
if (curp.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK)
|
||||
break;
|
||||
|
||||
if (resp != NULL)
|
||||
@ -677,7 +685,7 @@ main(int argc, char *argv[])
|
||||
|
||||
if (pid == -1) {
|
||||
warn("wait");
|
||||
rc = MANDOCLEVEL_SYSERR;
|
||||
mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
|
||||
break;
|
||||
}
|
||||
if (!WIFSTOPPED(status))
|
||||
@ -687,8 +695,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
tag_unlink();
|
||||
}
|
||||
|
||||
return (int)rc;
|
||||
return (int)mandoc_msg_getrc();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -786,7 +793,6 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
page->names = NULL;
|
||||
page->output = NULL;
|
||||
page->ipath = ipath;
|
||||
page->bits = NAME_FILE & NAME_MASK;
|
||||
page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
|
||||
page->form = form;
|
||||
return 1;
|
||||
@ -821,8 +827,18 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
return 1;
|
||||
}
|
||||
if (res != NULL && *ressz == lastsz &&
|
||||
strchr(*argv, '/') == NULL)
|
||||
warnx("No entry for %s in the manual.", *argv);
|
||||
strchr(*argv, '/') == NULL) {
|
||||
if (cfg->arch != NULL &&
|
||||
arch_valid(cfg->arch, OSENUM) == 0)
|
||||
warnx("Unknown architecture \"%s\".",
|
||||
cfg->arch);
|
||||
else if (cfg->sec == NULL)
|
||||
warnx("No entry for %s in the manual.",
|
||||
*argv);
|
||||
else
|
||||
warnx("No entry for %s in section %s "
|
||||
"of the manual.", *argv, cfg->sec);
|
||||
}
|
||||
lastsz = *ressz;
|
||||
argv++;
|
||||
argc--;
|
||||
@ -833,101 +849,92 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
static void
|
||||
parse(struct curparse *curp, int fd, const char *file)
|
||||
{
|
||||
enum mandoclevel rctmp;
|
||||
struct roff_man *man;
|
||||
struct roff_meta *meta;
|
||||
|
||||
/* Begin by parsing the file itself. */
|
||||
|
||||
assert(file);
|
||||
assert(fd >= 0);
|
||||
|
||||
rctmp = mparse_readfd(curp->mp, fd, file);
|
||||
mparse_readfd(curp->mp, fd, file);
|
||||
if (fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
if (rc < rctmp)
|
||||
rc = rctmp;
|
||||
|
||||
/*
|
||||
* With -Wstop and warnings or errors of at least the requested
|
||||
* level, do not produce output.
|
||||
*/
|
||||
|
||||
if (rctmp != MANDOCLEVEL_OK && curp->wstop)
|
||||
if (curp->wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK)
|
||||
return;
|
||||
|
||||
if (curp->outdata == NULL)
|
||||
outdata_alloc(curp);
|
||||
else if (curp->outtype == OUTT_HTML)
|
||||
html_reset(curp);
|
||||
|
||||
mparse_result(curp->mp, &man, NULL);
|
||||
mandoc_xr_reset();
|
||||
meta = mparse_result(curp->mp);
|
||||
|
||||
/* Execute the out device, if it exists. */
|
||||
|
||||
if (man == NULL)
|
||||
return;
|
||||
mandoc_xr_reset();
|
||||
if (man->macroset == MACROSET_MDOC) {
|
||||
if (curp->outtype != OUTT_TREE || !curp->outopts->noval)
|
||||
mdoc_validate(man);
|
||||
if (meta->macroset == MACROSET_MDOC) {
|
||||
switch (curp->outtype) {
|
||||
case OUTT_HTML:
|
||||
html_mdoc(curp->outdata, man);
|
||||
html_mdoc(curp->outdata, meta);
|
||||
break;
|
||||
case OUTT_TREE:
|
||||
tree_mdoc(curp->outdata, man);
|
||||
tree_mdoc(curp->outdata, meta);
|
||||
break;
|
||||
case OUTT_MAN:
|
||||
man_mdoc(curp->outdata, man);
|
||||
man_mdoc(curp->outdata, meta);
|
||||
break;
|
||||
case OUTT_PDF:
|
||||
case OUTT_ASCII:
|
||||
case OUTT_UTF8:
|
||||
case OUTT_LOCALE:
|
||||
case OUTT_PS:
|
||||
terminal_mdoc(curp->outdata, man);
|
||||
terminal_mdoc(curp->outdata, meta);
|
||||
break;
|
||||
case OUTT_MARKDOWN:
|
||||
markdown_mdoc(curp->outdata, man);
|
||||
markdown_mdoc(curp->outdata, meta);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (man->macroset == MACROSET_MAN) {
|
||||
if (curp->outtype != OUTT_TREE || !curp->outopts->noval)
|
||||
man_validate(man);
|
||||
if (meta->macroset == MACROSET_MAN) {
|
||||
switch (curp->outtype) {
|
||||
case OUTT_HTML:
|
||||
html_man(curp->outdata, man);
|
||||
html_man(curp->outdata, meta);
|
||||
break;
|
||||
case OUTT_TREE:
|
||||
tree_man(curp->outdata, man);
|
||||
tree_man(curp->outdata, meta);
|
||||
break;
|
||||
case OUTT_MAN:
|
||||
man_man(curp->outdata, man);
|
||||
mparse_copy(curp->mp);
|
||||
break;
|
||||
case OUTT_PDF:
|
||||
case OUTT_ASCII:
|
||||
case OUTT_UTF8:
|
||||
case OUTT_LOCALE:
|
||||
case OUTT_PS:
|
||||
terminal_man(curp->outdata, man);
|
||||
terminal_man(curp->outdata, meta);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curp->mmin < MANDOCERR_STYLE)
|
||||
check_xr(file);
|
||||
mparse_updaterc(curp->mp, &rc);
|
||||
if (mandoc_msg_getmin() < MANDOCERR_STYLE)
|
||||
check_xr();
|
||||
}
|
||||
|
||||
static void
|
||||
check_xr(const char *file)
|
||||
check_xr(void)
|
||||
{
|
||||
static struct manpaths paths;
|
||||
struct mansearch search;
|
||||
struct mandoc_xr *xr;
|
||||
char *cp;
|
||||
size_t sz;
|
||||
|
||||
if (paths.sz == 0)
|
||||
@ -946,13 +953,12 @@ check_xr(const char *file)
|
||||
if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz))
|
||||
continue;
|
||||
if (xr->count == 1)
|
||||
mandoc_asprintf(&cp, "Xr %s %s", xr->name, xr->sec);
|
||||
mandoc_msg(MANDOCERR_XR_BAD, xr->line,
|
||||
xr->pos + 1, "Xr %s %s", xr->name, xr->sec);
|
||||
else
|
||||
mandoc_asprintf(&cp, "Xr %s %s (%d times)",
|
||||
mandoc_msg(MANDOCERR_XR_BAD, xr->line,
|
||||
xr->pos + 1, "Xr %s %s (%d times)",
|
||||
xr->name, xr->sec, xr->count);
|
||||
mmsg(MANDOCERR_XR_BAD, MANDOCLEVEL_STYLE,
|
||||
file, xr->line, xr->pos + 1, cp);
|
||||
free(cp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1051,8 +1057,7 @@ passthrough(const char *file, int fd, int synopsis_only)
|
||||
fail:
|
||||
free(line);
|
||||
warn("%s: SYSERR: %s", file, syscall);
|
||||
if (rc < MANDOCLEVEL_SYSERR)
|
||||
rc = MANDOCLEVEL_SYSERR;
|
||||
mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1094,8 +1099,8 @@ toptions(struct curparse *curp, char *arg)
|
||||
curp->outtype = OUTT_ASCII;
|
||||
else if (0 == strcmp(arg, "lint")) {
|
||||
curp->outtype = OUTT_LINT;
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
mmsg_stream = stdout;
|
||||
mandoc_msg_setoutfile(stdout);
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
} else if (0 == strcmp(arg, "tree"))
|
||||
curp->outtype = OUTT_TREE;
|
||||
else if (0 == strcmp(arg, "man"))
|
||||
@ -1146,29 +1151,29 @@ woptions(struct curparse *curp, char *arg)
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
break;
|
||||
case 3:
|
||||
curp->mmin = MANDOCERR_STYLE;
|
||||
mandoc_msg_setmin(MANDOCERR_STYLE);
|
||||
break;
|
||||
case 4:
|
||||
curp->mmin = MANDOCERR_WARNING;
|
||||
mandoc_msg_setmin(MANDOCERR_WARNING);
|
||||
break;
|
||||
case 5:
|
||||
curp->mmin = MANDOCERR_ERROR;
|
||||
mandoc_msg_setmin(MANDOCERR_ERROR);
|
||||
break;
|
||||
case 6:
|
||||
curp->mmin = MANDOCERR_UNSUPP;
|
||||
mandoc_msg_setmin(MANDOCERR_UNSUPP);
|
||||
break;
|
||||
case 7:
|
||||
curp->mmin = MANDOCERR_MAX;
|
||||
mandoc_msg_setmin(MANDOCERR_MAX);
|
||||
break;
|
||||
case 8:
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
curp->os_e = MANDOC_OS_OPENBSD;
|
||||
break;
|
||||
case 9:
|
||||
curp->mmin = MANDOCERR_BASE;
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
curp->os_e = MANDOC_OS_NETBSD;
|
||||
break;
|
||||
default:
|
||||
@ -1179,29 +1184,6 @@ woptions(struct curparse *curp, char *arg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
mmsg(enum mandocerr t, enum mandoclevel lvl,
|
||||
const char *file, int line, int col, const char *msg)
|
||||
{
|
||||
const char *mparse_msg;
|
||||
|
||||
fprintf(mmsg_stream, "%s: %s:", getprogname(),
|
||||
file == NULL ? "<stdin>" : file);
|
||||
|
||||
if (line)
|
||||
fprintf(mmsg_stream, "%d:%d:", line, col + 1);
|
||||
|
||||
fprintf(mmsg_stream, " %s", mparse_strlevel(lvl));
|
||||
|
||||
if ((mparse_msg = mparse_strerror(t)) != NULL)
|
||||
fprintf(mmsg_stream, ": %s", mparse_msg);
|
||||
|
||||
if (msg)
|
||||
fprintf(mmsg_stream, ": %s", msg);
|
||||
|
||||
fputc('\n', mmsg_stream);
|
||||
}
|
||||
|
||||
static pid_t
|
||||
spawn_pager(struct tag_files *tag_files)
|
||||
{
|
||||
@ -1210,8 +1192,10 @@ spawn_pager(struct tag_files *tag_files)
|
||||
char *argv[MAX_PAGER_ARGS];
|
||||
const char *pager;
|
||||
char *cp;
|
||||
#if HAVE_LESS_T
|
||||
size_t cmdlen;
|
||||
int argc;
|
||||
#endif
|
||||
int argc, use_ofn;
|
||||
pid_t pager_pid;
|
||||
|
||||
pager = getenv("MANPAGER");
|
||||
@ -1227,7 +1211,7 @@ spawn_pager(struct tag_files *tag_files)
|
||||
*/
|
||||
|
||||
argc = 0;
|
||||
while (argc + 4 < MAX_PAGER_ARGS) {
|
||||
while (argc + 5 < MAX_PAGER_ARGS) {
|
||||
argv[argc++] = cp;
|
||||
cp = strchr(cp, ' ');
|
||||
if (cp == NULL)
|
||||
@ -1241,14 +1225,23 @@ spawn_pager(struct tag_files *tag_files)
|
||||
|
||||
/* For less(1), use the tag file. */
|
||||
|
||||
use_ofn = 1;
|
||||
#if HAVE_LESS_T
|
||||
if ((cmdlen = strlen(argv[0])) >= 4) {
|
||||
cp = argv[0] + cmdlen - 4;
|
||||
if (strcmp(cp, "less") == 0) {
|
||||
argv[argc++] = mandoc_strdup("-T");
|
||||
argv[argc++] = tag_files->tfn;
|
||||
if (tag_files->tagname != NULL) {
|
||||
argv[argc++] = mandoc_strdup("-t");
|
||||
argv[argc++] = tag_files->tagname;
|
||||
use_ofn = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
argv[argc++] = tag_files->ofn;
|
||||
#endif
|
||||
if (use_ofn)
|
||||
argv[argc++] = tag_files->ofn;
|
||||
argv[argc] = NULL;
|
||||
|
||||
switch (pager_pid = fork()) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: main.h,v 1.27 2017/03/03 14:23:23 schwarze Exp $ */
|
||||
/* $Id: main.h,v 1.30 2019/03/03 13:02:11 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,7 +16,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct roff_man;
|
||||
struct roff_meta;
|
||||
struct manoutput;
|
||||
|
||||
/*
|
||||
@ -27,15 +27,15 @@ struct manoutput;
|
||||
*/
|
||||
|
||||
void *html_alloc(const struct manoutput *);
|
||||
void html_mdoc(void *, const struct roff_man *);
|
||||
void html_man(void *, const struct roff_man *);
|
||||
void html_mdoc(void *, const struct roff_meta *);
|
||||
void html_man(void *, const struct roff_meta *);
|
||||
void html_reset(void *);
|
||||
void html_free(void *);
|
||||
|
||||
void tree_mdoc(void *, const struct roff_man *);
|
||||
void tree_man(void *, const struct roff_man *);
|
||||
void tree_mdoc(void *, const struct roff_meta *);
|
||||
void tree_man(void *, const struct roff_meta *);
|
||||
|
||||
void man_mdoc(void *, const struct roff_man *);
|
||||
void man_man(void *, const struct roff_man *);
|
||||
void man_mdoc(void *, const struct roff_meta *);
|
||||
|
||||
void *locale_alloc(const struct manoutput *);
|
||||
void *utf8_alloc(const struct manoutput *);
|
||||
@ -46,8 +46,8 @@ void *pdf_alloc(const struct manoutput *);
|
||||
void *ps_alloc(const struct manoutput *);
|
||||
void pspdf_free(void *);
|
||||
|
||||
void terminal_mdoc(void *, const struct roff_man *);
|
||||
void terminal_man(void *, const struct roff_man *);
|
||||
void terminal_mdoc(void *, const struct roff_meta *);
|
||||
void terminal_man(void *, const struct roff_meta *);
|
||||
void terminal_sepline(void *);
|
||||
|
||||
void markdown_mdoc(void *, const struct roff_man *);
|
||||
void markdown_mdoc(void *, const struct roff_meta *);
|
||||
|
@ -1,9 +1,9 @@
|
||||
.\" $Id: man.1,v 1.33 2018/04/19 23:41:16 schwarze Exp $
|
||||
.\" $Id: man.1,v 1.35 2019/03/09 15:55:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\" Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
|
||||
.\"
|
||||
.Dd $Mdocdate: April 19 2018 $
|
||||
.Dd $Mdocdate: March 9 2019 $
|
||||
.Dt MAN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -218,12 +218,24 @@ Guidelines for writing
|
||||
man pages can be found in
|
||||
.Xr mdoc 7 .
|
||||
.Pp
|
||||
The
|
||||
.Xr mandoc.db 5
|
||||
database is used for looking up manual page entries.
|
||||
In cases where the database is absent, outdated, or corrupt,
|
||||
.Nm
|
||||
falls back to looking for files called
|
||||
.Ar name . Ns Ar section .
|
||||
If both a formatted and an unformatted version of the same manual page,
|
||||
for example
|
||||
.Pa cat1/foo.0
|
||||
and
|
||||
.Pa man1/foo.1 ,
|
||||
exist in the same directory, only the unformatted version is used.
|
||||
The database is kept up to date with
|
||||
.Xr makewhatis 8 ,
|
||||
which is run by the
|
||||
.Xr weekly 8
|
||||
maintenance script.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width MANPATHX
|
||||
.It Ev MACHINE
|
||||
@ -266,6 +278,13 @@ and
|
||||
can be used to move to the next and to the previous place providing
|
||||
information about the term last searched for with
|
||||
.Ic :t .
|
||||
The
|
||||
.Fl O Cm tag Ns Op = Ns Ar term
|
||||
option documented in the
|
||||
.Xr mandoc 1
|
||||
manual opens a manual page at the definition of a specific
|
||||
.Ar term
|
||||
rather than at the beginning.
|
||||
.It Ev MANPATH
|
||||
The standard search path used by
|
||||
.Nm
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* $Id: man.c,v 1.176 2017/06/28 12:52:45 schwarze Exp $ */
|
||||
/* $Id: man.c,v 1.187 2019/01/05 00:36:50 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* 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
|
||||
@ -35,7 +35,7 @@
|
||||
#include "roff_int.h"
|
||||
#include "libman.h"
|
||||
|
||||
static void man_descope(struct roff_man *, int, int);
|
||||
static char *man_hasc(char *);
|
||||
static int man_ptext(struct roff_man *, int, char *, int);
|
||||
static int man_pmacro(struct roff_man *, int, char *, int);
|
||||
|
||||
@ -52,38 +52,62 @@ man_parseln(struct roff_man *man, int ln, char *buf, int offs)
|
||||
man_ptext(man, ln, buf, offs);
|
||||
}
|
||||
|
||||
static void
|
||||
man_descope(struct roff_man *man, int line, int offs)
|
||||
/*
|
||||
* If the string ends with \c, return a pointer to the backslash.
|
||||
* Otherwise, return NULL.
|
||||
*/
|
||||
static char *
|
||||
man_hasc(char *start)
|
||||
{
|
||||
char *cp, *ep;
|
||||
|
||||
ep = strchr(start, '\0') - 2;
|
||||
if (ep < start || ep[0] != '\\' || ep[1] != 'c')
|
||||
return NULL;
|
||||
for (cp = ep; cp > start; cp--)
|
||||
if (cp[-1] != '\\')
|
||||
break;
|
||||
return (ep - cp) % 2 ? NULL : ep;
|
||||
}
|
||||
|
||||
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 scope (if applicable), then close
|
||||
* out the block scope (also if applicable).
|
||||
* first close out the element scopes (if applicable),
|
||||
* then close out the block scope (also if applicable).
|
||||
*/
|
||||
|
||||
if (man->flags & MAN_ELINE) {
|
||||
while (man->last->parent->type != ROFFT_ROOT &&
|
||||
man_macro(man->last->parent->tok)->flags & MAN_ESCOPED)
|
||||
man_unscope(man, man->last->parent);
|
||||
man->flags &= ~MAN_ELINE;
|
||||
man_unscope(man, man->last->parent);
|
||||
}
|
||||
if ( ! (man->flags & MAN_BLINE))
|
||||
return;
|
||||
man->flags &= ~MAN_BLINE;
|
||||
man_unscope(man, man->last->parent);
|
||||
roff_body_alloc(man, line, offs, man->last->tok);
|
||||
man->flags &= ~(MAN_BLINE | ROFF_NONOFILL);
|
||||
}
|
||||
|
||||
static int
|
||||
man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
{
|
||||
int i;
|
||||
const char *cp, *sp;
|
||||
char *ep;
|
||||
|
||||
/* Literal free-form text whitespace is preserved. */
|
||||
/* In no-fill mode, whitespace is preserved on text lines. */
|
||||
|
||||
if (man->flags & MAN_LITERAL) {
|
||||
if (man->flags & ROFF_NOFILL) {
|
||||
roff_word_alloc(man, line, offs, buf + offs);
|
||||
man_descope(man, line, offs);
|
||||
man_descope(man, line, offs, buf + offs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -98,26 +122,15 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
|
||||
if (buf[i] == '\0') {
|
||||
if (man->flags & (MAN_ELINE | MAN_BLINE)) {
|
||||
mandoc_msg(MANDOCERR_BLK_BLANK, man->parse,
|
||||
line, 0, NULL);
|
||||
mandoc_msg(MANDOCERR_BLK_BLANK, line, 0, NULL);
|
||||
return 1;
|
||||
}
|
||||
if (man->last->tok == MAN_SH || man->last->tok == MAN_SS)
|
||||
return 1;
|
||||
switch (man->last->type) {
|
||||
case ROFFT_TEXT:
|
||||
sp = man->last->string;
|
||||
cp = ep = strchr(sp, '\0') - 2;
|
||||
if (cp < sp || cp[0] != '\\' || cp[1] != 'c')
|
||||
break;
|
||||
while (cp > sp && cp[-1] == '\\')
|
||||
cp--;
|
||||
if ((ep - cp) % 2)
|
||||
break;
|
||||
if (man->last->type == ROFFT_TEXT &&
|
||||
((ep = man_hasc(man->last->string)) != NULL)) {
|
||||
*ep = '\0';
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
roff_elem_alloc(man, line, offs, ROFF_sp);
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
@ -134,8 +147,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
|
||||
if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
|
||||
if (i > 1 && '\\' != buf[i - 2])
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, man->parse,
|
||||
line, i - 1, NULL);
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, line, i - 1, NULL);
|
||||
|
||||
for (--i; i && ' ' == buf[i]; i--)
|
||||
/* Spin back to non-space. */ ;
|
||||
@ -157,7 +169,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
if (mandoc_eos(buf, (size_t)i))
|
||||
man->last->flags |= NODE_EOS;
|
||||
|
||||
man_descope(man, line, offs);
|
||||
man_descope(man, line, offs, buf + offs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -180,8 +192,7 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
if (sz > 0 && sz < 4)
|
||||
tok = roffhash_find(man->manmac, buf + ppos, sz);
|
||||
if (tok == TOKEN_NONE) {
|
||||
mandoc_msg(MANDOCERR_MACRO, man->parse,
|
||||
ln, ppos, buf + ppos - 1);
|
||||
mandoc_msg(MANDOCERR_MACRO, ln, ppos, "%s", buf + ppos - 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -211,8 +222,7 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
*/
|
||||
|
||||
if (buf[offs] == '\0' && buf[offs - 1] == ' ')
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, man->parse,
|
||||
ln, offs - 1, NULL);
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, ln, offs - 1, NULL);
|
||||
|
||||
/*
|
||||
* Some macros break next-line scopes; otherwise, remember
|
||||
@ -230,16 +240,12 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
* page, that's very likely what the author intended.
|
||||
*/
|
||||
|
||||
if (bline) {
|
||||
cp = strchr(buf + offs, '\0') - 2;
|
||||
if (cp >= buf && cp[0] == '\\' && cp[1] == 'c')
|
||||
bline = 0;
|
||||
}
|
||||
if (bline && man_hasc(buf + offs))
|
||||
bline = 0;
|
||||
|
||||
/* Call to handler... */
|
||||
|
||||
assert(man_macros[tok].fp);
|
||||
(*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf);
|
||||
(*man_macro(tok)->fp)(man, tok, ln, ppos, &offs, buf);
|
||||
|
||||
/* In quick mode (for mandocdb), abort after the NAME section. */
|
||||
|
||||
@ -256,15 +262,15 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
* unless the next-line scope is allowed to continue.
|
||||
*/
|
||||
|
||||
if ( ! bline || man->flags & MAN_ELINE ||
|
||||
man_macros[tok].flags & MAN_NSCOPED)
|
||||
if (bline == 0 ||
|
||||
(man->flags & MAN_BLINE) == 0 ||
|
||||
man->flags & MAN_ELINE ||
|
||||
man_macro(tok)->flags & MAN_NSCOPED)
|
||||
return 1;
|
||||
|
||||
assert(man->flags & MAN_BLINE);
|
||||
man->flags &= ~MAN_BLINE;
|
||||
|
||||
man_unscope(man, man->last->parent);
|
||||
roff_body_alloc(man, ln, ppos, man->last->tok);
|
||||
man->flags &= ~(MAN_BLINE | ROFF_NONOFILL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -280,17 +286,17 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
*/
|
||||
|
||||
if (man->flags & MAN_ELINE && (tok < MAN_TH ||
|
||||
! (man_macros[tok].flags & MAN_NSCOPED))) {
|
||||
(man_macro(tok)->flags & MAN_NSCOPED) == 0)) {
|
||||
n = man->last;
|
||||
if (n->type == ROFFT_TEXT)
|
||||
n = n->parent;
|
||||
if (n->tok < MAN_TH ||
|
||||
man_macros[n->tok].flags & MAN_NSCOPED)
|
||||
(man_macro(n->tok)->flags & (MAN_NSCOPED | MAN_ESCOPED))
|
||||
== MAN_NSCOPED)
|
||||
n = n->parent;
|
||||
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
|
||||
n->line, n->pos, "%s breaks %s",
|
||||
roff_name[tok], roff_name[n->tok]);
|
||||
mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos,
|
||||
"%s breaks %s", roff_name[tok], roff_name[n->tok]);
|
||||
|
||||
roff_node_delete(man, n);
|
||||
man->flags &= ~MAN_ELINE;
|
||||
@ -302,12 +308,12 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
*/
|
||||
|
||||
if (man->flags & MAN_BLINE &&
|
||||
(tok == MAN_nf || tok == MAN_fi) &&
|
||||
(tok == ROFF_nf || tok == ROFF_fi) &&
|
||||
(man->last->tok == MAN_SH || man->last->tok == MAN_SS)) {
|
||||
n = man->last;
|
||||
man_unscope(man, n);
|
||||
roff_body_alloc(man, n->line, n->pos, n->tok);
|
||||
man->flags &= ~MAN_BLINE;
|
||||
man->flags &= ~(MAN_BLINE | ROFF_NONOFILL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -316,68 +322,24 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
* Delete the block that is being broken.
|
||||
*/
|
||||
|
||||
if (man->flags & MAN_BLINE && (tok < MAN_TH ||
|
||||
man_macros[tok].flags & MAN_BSCOPE)) {
|
||||
if (man->flags & MAN_BLINE && tok != ROFF_nf && tok != ROFF_fi &&
|
||||
(tok < MAN_TH || man_macro(tok)->flags & MAN_XSCOPE)) {
|
||||
n = man->last;
|
||||
if (n->type == ROFFT_TEXT)
|
||||
n = n->parent;
|
||||
if (n->tok < MAN_TH ||
|
||||
(man_macros[n->tok].flags & MAN_BSCOPE) == 0)
|
||||
(man_macro(n->tok)->flags & MAN_XSCOPE) == 0)
|
||||
n = n->parent;
|
||||
|
||||
assert(n->type == ROFFT_HEAD);
|
||||
n = n->parent;
|
||||
assert(n->type == ROFFT_BLOCK);
|
||||
assert(man_macros[n->tok].flags & MAN_SCOPED);
|
||||
assert(man_macro(n->tok)->flags & MAN_BSCOPED);
|
||||
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
|
||||
n->line, n->pos, "%s breaks %s",
|
||||
roff_name[tok], roff_name[n->tok]);
|
||||
mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos,
|
||||
"%s breaks %s", roff_name[tok], roff_name[n->tok]);
|
||||
|
||||
roff_node_delete(man, n);
|
||||
man->flags &= ~MAN_BLINE;
|
||||
man->flags &= ~(MAN_BLINE | ROFF_NONOFILL);
|
||||
}
|
||||
}
|
||||
|
||||
const struct mparse *
|
||||
man_mparse(const struct roff_man *man)
|
||||
{
|
||||
|
||||
assert(man && man->parse);
|
||||
return man->parse;
|
||||
}
|
||||
|
||||
void
|
||||
man_state(struct roff_man *man, struct roff_node *n)
|
||||
{
|
||||
|
||||
switch(n->tok) {
|
||||
case MAN_nf:
|
||||
case MAN_EX:
|
||||
if (man->flags & MAN_LITERAL && ! (n->flags & NODE_VALID))
|
||||
mandoc_msg(MANDOCERR_NF_SKIP, man->parse,
|
||||
n->line, n->pos, "nf");
|
||||
man->flags |= MAN_LITERAL;
|
||||
break;
|
||||
case MAN_fi:
|
||||
case MAN_EE:
|
||||
if ( ! (man->flags & MAN_LITERAL) &&
|
||||
! (n->flags & NODE_VALID))
|
||||
mandoc_msg(MANDOCERR_FI_SKIP, man->parse,
|
||||
n->line, n->pos, "fi");
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
man->last->flags |= NODE_VALID;
|
||||
}
|
||||
|
||||
void
|
||||
man_validate(struct roff_man *man)
|
||||
{
|
||||
|
||||
man->last = man->first;
|
||||
man_node_validate(man);
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" $Id: man.conf.5,v 1.5 2017/08/22 18:17:52 schwarze Exp $
|
||||
.\" $Id: man.conf.5,v 1.6 2018/10/02 14:56:47 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 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
|
||||
@ -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 22 2017 $
|
||||
.Dd $Mdocdate: October 2 2018 $
|
||||
.Dt MAN.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -98,6 +98,7 @@ manual.
|
||||
.It Ic man Ta string Ta Cm html Ta path for \&Xr links
|
||||
.It Ic paper Ta string Ta Cm ps , pdf Ta paper size
|
||||
.It Ic style Ta string Ta Cm html Ta CSS file
|
||||
.It Ic toc Ta none Ta Cm html Ta print table of contents
|
||||
.It Ic width Ta integer Ta Cm ascii , utf8 Ta right margin
|
||||
.El
|
||||
.It Ic _whatdb Ar path Ns Cm /whatis.db
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man.h,v 1.78 2017/04/24 23:06:18 schwarze Exp $ */
|
||||
/* $Id: man.h,v 1.79 2018/08/23 19:33:27 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -18,5 +18,4 @@
|
||||
|
||||
struct roff_man;
|
||||
|
||||
const struct mparse *man_mparse(const struct roff_man *);
|
||||
void man_validate(struct roff_man *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: man_html.c,v 1.153 2018/07/27 17:49:31 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.173 2019/03/02 16:30:53 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -33,26 +33,22 @@
|
||||
#include "html.h"
|
||||
#include "main.h"
|
||||
|
||||
/* FIXME: have PD set the default vspace width. */
|
||||
|
||||
#define MAN_ARGS const struct roff_meta *man, \
|
||||
const struct roff_node *n, \
|
||||
struct html *h
|
||||
|
||||
struct htmlman {
|
||||
struct man_html_act {
|
||||
int (*pre)(MAN_ARGS);
|
||||
int (*post)(MAN_ARGS);
|
||||
};
|
||||
|
||||
static void print_bvspace(struct html *,
|
||||
const struct roff_node *);
|
||||
static void print_man_head(const struct roff_meta *,
|
||||
struct html *);
|
||||
static void print_man_nodelist(MAN_ARGS);
|
||||
static void print_man_node(MAN_ARGS);
|
||||
static int fillmode(struct html *, int);
|
||||
static char list_continues(const struct roff_node *,
|
||||
const struct roff_node *);
|
||||
static int man_B_pre(MAN_ARGS);
|
||||
static int man_HP_pre(MAN_ARGS);
|
||||
static int man_IP_pre(MAN_ARGS);
|
||||
static int man_I_pre(MAN_ARGS);
|
||||
static int man_OP_pre(MAN_ARGS);
|
||||
@ -60,8 +56,9 @@ static int man_PP_pre(MAN_ARGS);
|
||||
static int man_RS_pre(MAN_ARGS);
|
||||
static int man_SH_pre(MAN_ARGS);
|
||||
static int man_SM_pre(MAN_ARGS);
|
||||
static int man_SS_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);
|
||||
@ -70,16 +67,17 @@ static void man_root_post(const struct roff_meta *,
|
||||
static void man_root_pre(const struct roff_meta *,
|
||||
struct html *);
|
||||
|
||||
static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
|
||||
static const struct man_html_act man_html_acts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL }, /* TH */
|
||||
{ man_SH_pre, NULL }, /* SH */
|
||||
{ man_SS_pre, NULL }, /* SS */
|
||||
{ man_SH_pre, NULL }, /* SS */
|
||||
{ man_IP_pre, NULL }, /* TP */
|
||||
{ man_PP_pre, NULL }, /* LP */
|
||||
{ man_IP_pre, NULL }, /* TQ */
|
||||
{ man_abort_pre, NULL }, /* LP */
|
||||
{ man_PP_pre, NULL }, /* PP */
|
||||
{ man_PP_pre, NULL }, /* P */
|
||||
{ man_abort_pre, NULL }, /* P */
|
||||
{ man_IP_pre, NULL }, /* IP */
|
||||
{ man_HP_pre, NULL }, /* HP */
|
||||
{ man_PP_pre, NULL }, /* HP */
|
||||
{ man_SM_pre, NULL }, /* SM */
|
||||
{ man_SM_pre, NULL }, /* SB */
|
||||
{ man_alt_pre, NULL }, /* BI */
|
||||
@ -91,8 +89,6 @@ static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
|
||||
{ man_I_pre, NULL }, /* I */
|
||||
{ man_alt_pre, NULL }, /* IR */
|
||||
{ man_alt_pre, NULL }, /* RI */
|
||||
{ NULL, NULL }, /* nf */
|
||||
{ NULL, NULL }, /* fi */
|
||||
{ NULL, NULL }, /* RE */
|
||||
{ man_RS_pre, NULL }, /* RS */
|
||||
{ man_ign_pre, NULL }, /* DT */
|
||||
@ -100,6 +96,8 @@ static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
|
||||
{ man_ign_pre, NULL }, /* PD */
|
||||
{ man_ign_pre, NULL }, /* AT */
|
||||
{ man_in_pre, NULL }, /* in */
|
||||
{ man_SY_pre, NULL }, /* SY */
|
||||
{ NULL, NULL }, /* YS */
|
||||
{ man_OP_pre, NULL }, /* OP */
|
||||
{ NULL, NULL }, /* EX */
|
||||
{ NULL, NULL }, /* EE */
|
||||
@ -108,34 +106,10 @@ static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
|
||||
{ man_UR_pre, NULL }, /* MT */
|
||||
{ NULL, NULL }, /* ME */
|
||||
};
|
||||
static const struct htmlman *const mans = __mans - MAN_TH;
|
||||
|
||||
|
||||
/*
|
||||
* Printing leading vertical space before a block.
|
||||
* This is used for the paragraph macros.
|
||||
* The rules are pretty simple, since there's very little nesting going
|
||||
* on here. Basically, if we're the first within another block (SS/SH),
|
||||
* then don't emit vertical space. If we are (RS), then do. If not the
|
||||
* first, print it.
|
||||
*/
|
||||
static void
|
||||
print_bvspace(struct html *h, const struct roff_node *n)
|
||||
{
|
||||
|
||||
if (n->body && n->body->child)
|
||||
if (n->body->child->type == ROFFT_TBL)
|
||||
return;
|
||||
|
||||
if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
|
||||
if (NULL == n->prev)
|
||||
return;
|
||||
|
||||
print_paragraph(h);
|
||||
}
|
||||
|
||||
void
|
||||
html_man(void *arg, const struct roff_man *man)
|
||||
html_man(void *arg, const struct roff_meta *man)
|
||||
{
|
||||
struct html *h;
|
||||
struct roff_node *n;
|
||||
@ -147,19 +121,19 @@ html_man(void *arg, const struct roff_man *man)
|
||||
if ((h->oflags & HTML_FRAGMENT) == 0) {
|
||||
print_gen_decls(h);
|
||||
print_otag(h, TAG_HTML, "");
|
||||
if (n->type == ROFFT_COMMENT)
|
||||
if (n != NULL && n->type == ROFFT_COMMENT)
|
||||
print_gen_comment(h, n);
|
||||
t = print_otag(h, TAG_HEAD, "");
|
||||
print_man_head(&man->meta, h);
|
||||
print_man_head(man, h);
|
||||
print_tagq(h, t);
|
||||
print_otag(h, TAG_BODY, "");
|
||||
}
|
||||
|
||||
man_root_pre(&man->meta, h);
|
||||
man_root_pre(man, h);
|
||||
t = print_otag(h, TAG_DIV, "c", "manual-text");
|
||||
print_man_nodelist(&man->meta, n, h);
|
||||
print_man_nodelist(man, n, h);
|
||||
print_tagq(h, t);
|
||||
man_root_post(&man->meta, h);
|
||||
man_root_post(man, h);
|
||||
print_tagq(h, NULL);
|
||||
}
|
||||
|
||||
@ -178,7 +152,6 @@ print_man_head(const struct roff_meta *man, struct html *h)
|
||||
static void
|
||||
print_man_nodelist(MAN_ARGS)
|
||||
{
|
||||
|
||||
while (n != NULL) {
|
||||
print_man_node(man, n, h);
|
||||
n = n->next;
|
||||
@ -188,99 +161,33 @@ print_man_nodelist(MAN_ARGS)
|
||||
static void
|
||||
print_man_node(MAN_ARGS)
|
||||
{
|
||||
static int want_fillmode = MAN_fi;
|
||||
static int save_fillmode;
|
||||
|
||||
struct tag *t;
|
||||
int child;
|
||||
|
||||
/*
|
||||
* Handle fill mode switch requests up front,
|
||||
* they would just cause trouble in the subsequent code.
|
||||
*/
|
||||
|
||||
switch (n->tok) {
|
||||
case MAN_nf:
|
||||
case MAN_EX:
|
||||
want_fillmode = MAN_nf;
|
||||
if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
|
||||
return;
|
||||
case MAN_fi:
|
||||
case MAN_EE:
|
||||
want_fillmode = MAN_fi;
|
||||
if (fillmode(h, 0) == MAN_fi)
|
||||
print_otag(h, TAG_BR, "");
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up fill mode for the upcoming node. */
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
save_fillmode = 0;
|
||||
/* Some block macros suspend or cancel .nf. */
|
||||
switch (n->tok) {
|
||||
case MAN_TP: /* Tagged paragraphs */
|
||||
case MAN_IP: /* temporarily disable .nf */
|
||||
case MAN_HP: /* for the head. */
|
||||
save_fillmode = want_fillmode;
|
||||
/* FALLTHROUGH */
|
||||
case MAN_SH: /* Section headers */
|
||||
case MAN_SS: /* permanently cancel .nf. */
|
||||
want_fillmode = MAN_fi;
|
||||
/* FALLTHROUGH */
|
||||
case MAN_PP: /* These have no head. */
|
||||
case MAN_LP: /* They will simply */
|
||||
case MAN_P: /* reopen .nf in the body. */
|
||||
case MAN_RS:
|
||||
case MAN_UR:
|
||||
case MAN_MT:
|
||||
fillmode(h, MAN_fi);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ROFFT_TBL:
|
||||
fillmode(h, MAN_fi);
|
||||
break;
|
||||
case ROFFT_ELEM:
|
||||
/*
|
||||
* Some in-line macros produce tags and/or text
|
||||
* in the handler, so they require fill mode to be
|
||||
* configured up front just like for text nodes.
|
||||
* For the others, keep the traditional approach
|
||||
* of doing the same, for now.
|
||||
*/
|
||||
fillmode(h, want_fillmode);
|
||||
break;
|
||||
case ROFFT_TEXT:
|
||||
if (fillmode(h, want_fillmode) == MAN_fi &&
|
||||
want_fillmode == MAN_fi &&
|
||||
n->flags & NODE_LINE && *n->string == ' ' &&
|
||||
(h->flags & HTML_NONEWLINE) == 0)
|
||||
print_otag(h, TAG_BR, "");
|
||||
if (*n->string != '\0')
|
||||
break;
|
||||
print_paragraph(h);
|
||||
return;
|
||||
case ROFFT_COMMENT:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Produce output for this node. */
|
||||
html_fillmode(h, n->flags & NODE_NOFILL ? ROFF_nf : ROFF_fi);
|
||||
|
||||
child = 1;
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
if (*n->string == '\0') {
|
||||
print_endline(h);
|
||||
return;
|
||||
}
|
||||
if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(h->flags & HTML_NONEWLINE) == 0)
|
||||
print_endline(h);
|
||||
else if (n->flags & NODE_DELIMC)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
t = h->tag;
|
||||
t->refcnt++;
|
||||
print_text(h, n->string);
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
t = h->tag;
|
||||
t->refcnt++;
|
||||
print_eqn(h, n->eqn);
|
||||
break;
|
||||
case ROFFT_TBL:
|
||||
@ -306,62 +213,51 @@ print_man_node(MAN_ARGS)
|
||||
* the "meta" table state. This will be reopened on the
|
||||
* next table element.
|
||||
*/
|
||||
if (h->tblt)
|
||||
if (h->tblt != NULL)
|
||||
print_tblclose(h);
|
||||
|
||||
t = h->tag;
|
||||
t->refcnt++;
|
||||
if (n->tok < ROFF_MAX) {
|
||||
roff_html_pre(h, n);
|
||||
child = 0;
|
||||
break;
|
||||
t->refcnt--;
|
||||
print_stagq(h, t);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
|
||||
if (mans[n->tok].pre)
|
||||
child = (*mans[n->tok].pre)(man, n, h);
|
||||
|
||||
/* Some block macros resume .nf in the body. */
|
||||
if (save_fillmode && n->type == ROFFT_BODY)
|
||||
want_fillmode = save_fillmode;
|
||||
|
||||
if (man_html_acts[n->tok - MAN_TH].pre != NULL)
|
||||
child = (*man_html_acts[n->tok - MAN_TH].pre)(man,
|
||||
n, h);
|
||||
break;
|
||||
}
|
||||
|
||||
if (child && n->child)
|
||||
if (child && n->child != NULL)
|
||||
print_man_nodelist(man, n->child, h);
|
||||
|
||||
/* This will automatically close out any font scope. */
|
||||
print_stagq(h, t);
|
||||
|
||||
if (fillmode(h, 0) == MAN_nf &&
|
||||
n->next != NULL && n->next->flags & NODE_LINE)
|
||||
print_endline(h);
|
||||
}
|
||||
|
||||
/*
|
||||
* MAN_nf switches to no-fill mode, MAN_fi to fill mode.
|
||||
* Other arguments do not switch.
|
||||
* The old mode is returned.
|
||||
*/
|
||||
static int
|
||||
fillmode(struct html *h, int want)
|
||||
{
|
||||
struct tag *pre;
|
||||
int had;
|
||||
|
||||
for (pre = h->tag; pre != NULL; pre = pre->next)
|
||||
if (pre->tag == TAG_PRE)
|
||||
break;
|
||||
|
||||
had = pre == NULL ? MAN_fi : MAN_nf;
|
||||
|
||||
if (want && want != had) {
|
||||
if (want == MAN_nf)
|
||||
print_otag(h, TAG_PRE, "");
|
||||
else
|
||||
print_tagq(h, pre);
|
||||
t->refcnt--;
|
||||
if (n->type == ROFFT_BLOCK &&
|
||||
(n->tok == MAN_IP || n->tok == MAN_TP || n->tok == MAN_TQ)) {
|
||||
t = h->tag;
|
||||
while (t->tag != TAG_DL && t->tag != TAG_UL)
|
||||
t = t->next;
|
||||
/*
|
||||
* Close the list if no further item of the same type
|
||||
* follows; otherwise, close the item only.
|
||||
*/
|
||||
if (list_continues(n, n->next) == '\0') {
|
||||
print_tagq(h, t);
|
||||
t = NULL;
|
||||
}
|
||||
}
|
||||
if (t != NULL)
|
||||
print_stagq(h, t);
|
||||
|
||||
if (n->flags & NODE_NOFILL && n->tok != MAN_YS &&
|
||||
(n->next != NULL && n->next->flags & NODE_LINE)) {
|
||||
/* In .nf = <pre>, print even empty lines. */
|
||||
h->col++;
|
||||
print_endline(h);
|
||||
}
|
||||
return had;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -382,7 +278,7 @@ man_root_pre(const struct roff_meta *man, struct html *h)
|
||||
print_stagq(h, tt);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "head-vol");
|
||||
if (NULL != man->vol)
|
||||
if (man->vol != NULL)
|
||||
print_text(h, man->vol);
|
||||
print_stagq(h, tt);
|
||||
|
||||
@ -405,7 +301,7 @@ man_root_post(const struct roff_meta *man, struct html *h)
|
||||
print_stagq(h, tt);
|
||||
|
||||
print_otag(h, TAG_TD, "c", "foot-os");
|
||||
if (man->os)
|
||||
if (man->os != NULL)
|
||||
print_text(h, man->os);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
@ -413,13 +309,32 @@ man_root_post(const struct roff_meta *man, struct html *h)
|
||||
static int
|
||||
man_SH_pre(MAN_ARGS)
|
||||
{
|
||||
char *id;
|
||||
const char *class;
|
||||
char *id;
|
||||
enum htmltag tag;
|
||||
|
||||
if (n->type == ROFFT_HEAD) {
|
||||
if (n->tok == MAN_SH) {
|
||||
tag = TAG_H1;
|
||||
class = "Sh";
|
||||
} else {
|
||||
tag = TAG_H2;
|
||||
class = "Ss";
|
||||
}
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
print_otag(h, TAG_SECTION, "c", class);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
id = html_make_id(n, 1);
|
||||
print_otag(h, TAG_H1, "cTi", "Sh", id);
|
||||
print_otag(h, tag, "ci", class, id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -428,11 +343,11 @@ static int
|
||||
man_alt_pre(MAN_ARGS)
|
||||
{
|
||||
const struct roff_node *nn;
|
||||
struct tag *t;
|
||||
int i;
|
||||
enum htmltag fp;
|
||||
struct tag *t;
|
||||
|
||||
for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
|
||||
for (i = 0, nn = n->child; nn != NULL; nn = nn->next, i++) {
|
||||
switch (n->tok) {
|
||||
case MAN_BI:
|
||||
fp = i % 2 ? TAG_I : TAG_B;
|
||||
@ -474,87 +389,134 @@ static int
|
||||
man_SM_pre(MAN_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_SMALL, "");
|
||||
if (MAN_SB == n->tok)
|
||||
if (n->tok == MAN_SB)
|
||||
print_otag(h, TAG_B, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_SS_pre(MAN_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
if (n->type == ROFFT_HEAD) {
|
||||
id = html_make_id(n, 1);
|
||||
print_otag(h, TAG_H2, "cTi", "Ss", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "permalink", id);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_PP_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_HEAD)
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
else if (n->type == ROFFT_BLOCK)
|
||||
print_bvspace(h, n);
|
||||
|
||||
case ROFFT_BODY:
|
||||
if (n->child != NULL &&
|
||||
(n->child->flags & NODE_NOFILL) == 0)
|
||||
print_otag(h, TAG_P, "c",
|
||||
n->tok == MAN_PP ? "Pp" : "Pp HP");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char
|
||||
list_continues(const struct roff_node *n1, const struct roff_node *n2)
|
||||
{
|
||||
const char *s1, *s2;
|
||||
char c1, c2;
|
||||
|
||||
if (n1 == NULL || n1->type != ROFFT_BLOCK ||
|
||||
n2 == NULL || n2->type != ROFFT_BLOCK)
|
||||
return '\0';
|
||||
if ((n1->tok == MAN_TP || n1->tok == MAN_TQ) &&
|
||||
(n2->tok == MAN_TP || n2->tok == MAN_TQ))
|
||||
return ' ';
|
||||
if (n1->tok != MAN_IP || n2->tok != MAN_IP)
|
||||
return '\0';
|
||||
n1 = n1->head->child;
|
||||
n2 = n2->head->child;
|
||||
s1 = n1 == NULL ? "" : n1->string;
|
||||
s2 = n2 == NULL ? "" : n2->string;
|
||||
c1 = strcmp(s1, "*") == 0 ? '*' :
|
||||
strcmp(s1, "\\-") == 0 ? '-' :
|
||||
strcmp(s1, "\\(bu") == 0 ? 'b' : ' ';
|
||||
c2 = strcmp(s2, "*") == 0 ? '*' :
|
||||
strcmp(s2, "\\-") == 0 ? '-' :
|
||||
strcmp(s2, "\\(bu") == 0 ? 'b' : ' ';
|
||||
return c1 != c2 ? '\0' : c1 == 'b' ? '*' : c1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_IP_pre(MAN_ARGS)
|
||||
{
|
||||
const struct roff_node *nn;
|
||||
const char *list_class;
|
||||
enum htmltag list_elem, body_elem;
|
||||
char list_type;
|
||||
|
||||
if (n->type == ROFFT_BODY) {
|
||||
print_otag(h, TAG_DD, "");
|
||||
nn = n->type == ROFFT_BLOCK ? n : n->parent;
|
||||
if ((list_type = list_continues(nn->prev, nn)) == '\0') {
|
||||
/* Start a new list. */
|
||||
if ((list_type = list_continues(nn, nn->next)) == '\0')
|
||||
list_type = ' ';
|
||||
switch (list_type) {
|
||||
case ' ':
|
||||
list_class = "Bl-tag";
|
||||
list_elem = TAG_DL;
|
||||
break;
|
||||
case '*':
|
||||
list_class = "Bl-bullet";
|
||||
list_elem = TAG_UL;
|
||||
break;
|
||||
case '-':
|
||||
list_class = "Bl-dash";
|
||||
list_elem = TAG_UL;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
/* Continue a list that was started earlier. */
|
||||
list_class = NULL;
|
||||
list_elem = TAG_MAX;
|
||||
}
|
||||
body_elem = list_type == ' ' ? TAG_DD : TAG_LI;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
if (list_elem != TAG_MAX)
|
||||
print_otag(h, list_elem, "c", list_class);
|
||||
return 1;
|
||||
} else if (n->type != ROFFT_HEAD) {
|
||||
print_otag(h, TAG_DL, "c", "Bl-tag");
|
||||
case ROFFT_HEAD:
|
||||
if (body_elem == TAG_LI)
|
||||
return 0;
|
||||
print_otag(h, TAG_DT, "");
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, body_elem, "");
|
||||
return 1;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* FIXME: width specification. */
|
||||
|
||||
print_otag(h, TAG_DT, "");
|
||||
|
||||
/* For IP, only print the first header element. */
|
||||
|
||||
if (MAN_IP == n->tok && n->child)
|
||||
print_man_node(man, n->child, h);
|
||||
|
||||
/* For TP, only print next-line header elements. */
|
||||
|
||||
if (MAN_TP == n->tok) {
|
||||
switch(n->tok) {
|
||||
case MAN_IP: /* Only print the first header element. */
|
||||
if (n->child != NULL)
|
||||
print_man_node(man, n->child, h);
|
||||
break;
|
||||
case MAN_TP: /* Only print next-line header elements. */
|
||||
case MAN_TQ:
|
||||
nn = n->child;
|
||||
while (NULL != nn && 0 == (NODE_LINE & nn->flags))
|
||||
while (nn != NULL && (NODE_LINE & nn->flags) == 0)
|
||||
nn = nn->next;
|
||||
while (NULL != nn) {
|
||||
while (nn != NULL) {
|
||||
print_man_node(man, nn, h);
|
||||
nn = nn->next;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
man_HP_pre(MAN_ARGS)
|
||||
{
|
||||
if (n->type == ROFFT_HEAD)
|
||||
return 0;
|
||||
|
||||
if (n->type == ROFFT_BLOCK) {
|
||||
print_bvspace(h, n);
|
||||
print_otag(h, TAG_DIV, "c", "HP");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_OP_pre(MAN_ARGS)
|
||||
{
|
||||
@ -564,14 +526,14 @@ man_OP_pre(MAN_ARGS)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
tt = print_otag(h, TAG_SPAN, "c", "Op");
|
||||
|
||||
if (NULL != (n = n->child)) {
|
||||
if ((n = n->child) != NULL) {
|
||||
print_otag(h, TAG_B, "");
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
print_stagq(h, tt);
|
||||
|
||||
if (NULL != n && NULL != n->next) {
|
||||
if (n != NULL && n->next != NULL) {
|
||||
print_otag(h, TAG_I, "");
|
||||
print_text(h, n->next->string);
|
||||
}
|
||||
@ -606,17 +568,46 @@ man_in_pre(MAN_ARGS)
|
||||
static int
|
||||
man_ign_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
man_RS_pre(MAN_ARGS)
|
||||
{
|
||||
if (n->type == ROFFT_HEAD)
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
if (n->type == ROFFT_BLOCK)
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, TAG_DIV, "c", "Bd-indent");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
man_SY_pre(MAN_ARGS)
|
||||
{
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
html_close_paragraph(h);
|
||||
print_otag(h, TAG_TABLE, "c", "Nm");
|
||||
print_otag(h, TAG_TR, "");
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
print_otag(h, TAG_TD, "");
|
||||
print_otag(h, TAG_CODE, "c", "Nm");
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, TAG_TD, "");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -624,16 +615,17 @@ static int
|
||||
man_UR_pre(MAN_ARGS)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
n = n->child;
|
||||
assert(n->type == ROFFT_HEAD);
|
||||
if (n->child != NULL) {
|
||||
assert(n->child->type == ROFFT_TEXT);
|
||||
if (n->tok == MAN_MT) {
|
||||
mandoc_asprintf(&cp, "mailto:%s", n->child->string);
|
||||
print_otag(h, TAG_A, "cTh", "Mt", cp);
|
||||
print_otag(h, TAG_A, "ch", "Mt", cp);
|
||||
free(cp);
|
||||
} else
|
||||
print_otag(h, TAG_A, "cTh", "Lk", n->child->string);
|
||||
print_otag(h, TAG_A, "ch", "Lk", n->child->string);
|
||||
}
|
||||
|
||||
assert(n->next->type == ROFFT_BODY);
|
||||
@ -641,6 +633,11 @@ man_UR_pre(MAN_ARGS)
|
||||
n = n->next;
|
||||
|
||||
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.123 2017/06/25 11:45:37 schwarze Exp $ */
|
||||
/* $Id: man_macro.c,v 1.144 2019/01/05 18:59:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -40,47 +41,54 @@ static int man_args(struct roff_man *, int,
|
||||
int *, char *, char **);
|
||||
static void rew_scope(struct roff_man *, enum roff_tok);
|
||||
|
||||
const struct man_macro __man_macros[MAN_MAX - MAN_TH] = {
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* TH */
|
||||
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SH */
|
||||
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SS */
|
||||
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* TP */
|
||||
{ blk_imp, MAN_BSCOPE }, /* LP */
|
||||
{ blk_imp, MAN_BSCOPE }, /* PP */
|
||||
{ blk_imp, MAN_BSCOPE }, /* P */
|
||||
{ blk_imp, MAN_BSCOPE }, /* IP */
|
||||
{ blk_imp, MAN_BSCOPE }, /* HP */
|
||||
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* SM */
|
||||
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* SB */
|
||||
static const struct man_macro man_macros[MAN_MAX - MAN_TH] = {
|
||||
{ in_line_eoln, MAN_XSCOPE }, /* TH */
|
||||
{ blk_imp, MAN_XSCOPE | MAN_BSCOPED }, /* SH */
|
||||
{ blk_imp, MAN_XSCOPE | MAN_BSCOPED }, /* SS */
|
||||
{ blk_imp, MAN_XSCOPE | MAN_BSCOPED }, /* TP */
|
||||
{ blk_imp, MAN_XSCOPE | MAN_BSCOPED }, /* TQ */
|
||||
{ blk_imp, MAN_XSCOPE }, /* LP */
|
||||
{ blk_imp, MAN_XSCOPE }, /* PP */
|
||||
{ blk_imp, MAN_XSCOPE }, /* P */
|
||||
{ blk_imp, MAN_XSCOPE }, /* IP */
|
||||
{ blk_imp, MAN_XSCOPE }, /* HP */
|
||||
{ in_line_eoln, MAN_NSCOPED | MAN_ESCOPED | MAN_JOIN }, /* SM */
|
||||
{ in_line_eoln, MAN_NSCOPED | MAN_ESCOPED | MAN_JOIN }, /* SB */
|
||||
{ in_line_eoln, 0 }, /* BI */
|
||||
{ in_line_eoln, 0 }, /* IB */
|
||||
{ in_line_eoln, 0 }, /* BR */
|
||||
{ in_line_eoln, 0 }, /* RB */
|
||||
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* R */
|
||||
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* B */
|
||||
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* I */
|
||||
{ in_line_eoln, MAN_NSCOPED | MAN_ESCOPED | MAN_JOIN }, /* R */
|
||||
{ in_line_eoln, MAN_NSCOPED | MAN_ESCOPED | MAN_JOIN }, /* B */
|
||||
{ in_line_eoln, MAN_NSCOPED | MAN_ESCOPED | MAN_JOIN }, /* I */
|
||||
{ in_line_eoln, 0 }, /* IR */
|
||||
{ in_line_eoln, 0 }, /* RI */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* nf */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* fi */
|
||||
{ blk_close, MAN_BSCOPE }, /* RE */
|
||||
{ blk_exp, MAN_BSCOPE }, /* RS */
|
||||
{ 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 }, /* PD */
|
||||
{ in_line_eoln, 0 }, /* AT */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* in */
|
||||
{ blk_imp, MAN_XSCOPE }, /* SY */
|
||||
{ blk_close, MAN_XSCOPE }, /* YS */
|
||||
{ in_line_eoln, 0 }, /* OP */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EX */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EE */
|
||||
{ blk_exp, MAN_BSCOPE }, /* UR */
|
||||
{ blk_close, MAN_BSCOPE }, /* UE */
|
||||
{ blk_exp, MAN_BSCOPE }, /* MT */
|
||||
{ blk_close, MAN_BSCOPE }, /* ME */
|
||||
{ in_line_eoln, MAN_XSCOPE }, /* EX */
|
||||
{ in_line_eoln, MAN_XSCOPE }, /* EE */
|
||||
{ blk_exp, MAN_XSCOPE }, /* UR */
|
||||
{ blk_close, MAN_XSCOPE }, /* UE */
|
||||
{ blk_exp, MAN_XSCOPE }, /* MT */
|
||||
{ blk_close, MAN_XSCOPE }, /* ME */
|
||||
};
|
||||
const struct man_macro *const man_macros = __man_macros - MAN_TH;
|
||||
|
||||
|
||||
const struct man_macro *
|
||||
man_macro(enum roff_tok tok)
|
||||
{
|
||||
assert(tok >= MAN_TH && tok <= MAN_MAX);
|
||||
return man_macros + (tok - MAN_TH);
|
||||
}
|
||||
|
||||
void
|
||||
man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
{
|
||||
@ -94,9 +102,10 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
|
||||
if (to == NULL && ! (n->flags & NODE_VALID)) {
|
||||
if (man->flags & (MAN_BLINE | MAN_ELINE) &&
|
||||
man_macros[n->tok].flags & MAN_SCOPED) {
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE,
|
||||
man->parse, n->line, n->pos,
|
||||
man_macro(n->tok)->flags &
|
||||
(MAN_BSCOPED | MAN_NSCOPED)) {
|
||||
mandoc_msg(MANDOCERR_BLK_LINE,
|
||||
n->line, n->pos,
|
||||
"EOF breaks %s", roff_name[n->tok]);
|
||||
if (man->flags & MAN_ELINE)
|
||||
man->flags &= ~MAN_ELINE;
|
||||
@ -111,9 +120,9 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
continue;
|
||||
}
|
||||
if (n->type == ROFFT_BLOCK &&
|
||||
man_macros[n->tok].fp == blk_exp)
|
||||
man_macro(n->tok)->fp == blk_exp)
|
||||
mandoc_msg(MANDOCERR_BLK_NOEND,
|
||||
man->parse, n->line, n->pos,
|
||||
n->line, n->pos, "%s",
|
||||
roff_name[n->tok]);
|
||||
}
|
||||
|
||||
@ -175,7 +184,7 @@ rew_scope(struct roff_man *man, enum roff_tok tok)
|
||||
}
|
||||
if (tok != MAN_SH && (n->tok == MAN_SH ||
|
||||
(tok != MAN_SS && (n->tok == MAN_SS ||
|
||||
man_macros[n->tok].fp == blk_exp))))
|
||||
man_macro(n->tok)->fp == blk_exp))))
|
||||
return;
|
||||
man_unscope(man, n);
|
||||
n = man->last;
|
||||
@ -189,33 +198,39 @@ rew_scope(struct roff_man *man, enum roff_tok tok)
|
||||
void
|
||||
blk_close(MACRO_PROT_ARGS)
|
||||
{
|
||||
enum roff_tok ntok;
|
||||
enum roff_tok ctok, ntok;
|
||||
const struct roff_node *nn;
|
||||
char *p;
|
||||
int nrew, target;
|
||||
char *p, *ep;
|
||||
int cline, cpos, la, nrew, target;
|
||||
|
||||
nrew = 1;
|
||||
switch (tok) {
|
||||
case MAN_RE:
|
||||
ntok = MAN_RS;
|
||||
la = *pos;
|
||||
if ( ! man_args(man, line, pos, buf, &p))
|
||||
break;
|
||||
for (nn = man->last->parent; nn; nn = nn->parent)
|
||||
if (nn->tok == ntok && nn->type == ROFFT_BLOCK)
|
||||
nrew++;
|
||||
target = strtol(p, &p, 10);
|
||||
if (*p != '\0')
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse,
|
||||
line, p - buf, "RE ... %s", p);
|
||||
target = strtol(p, &ep, 10);
|
||||
if (*ep != '\0')
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS, line,
|
||||
la + (buf[la] == '"') + (int)(ep - p),
|
||||
"RE ... %s", ep);
|
||||
free(p);
|
||||
if (target == 0)
|
||||
target = 1;
|
||||
nrew -= target;
|
||||
if (nrew < 1) {
|
||||
mandoc_vmsg(MANDOCERR_RE_NOTOPEN, man->parse,
|
||||
mandoc_msg(MANDOCERR_RE_NOTOPEN,
|
||||
line, ppos, "RE %d", target);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MAN_YS:
|
||||
ntok = MAN_SY;
|
||||
break;
|
||||
case MAN_UE:
|
||||
ntok = MAN_UR;
|
||||
break;
|
||||
@ -231,25 +246,47 @@ blk_close(MACRO_PROT_ARGS)
|
||||
break;
|
||||
|
||||
if (nn == NULL) {
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse,
|
||||
line, ppos, roff_name[tok]);
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN,
|
||||
line, ppos, "%s", roff_name[tok]);
|
||||
rew_scope(man, MAN_PP);
|
||||
} else {
|
||||
line = man->last->line;
|
||||
ppos = man->last->pos;
|
||||
ntok = man->last->tok;
|
||||
man_unscope(man, nn);
|
||||
|
||||
if (tok == MAN_RE && nn->head->aux > 0)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
nn->head->aux, '-');
|
||||
|
||||
/* Move a trailing paragraph behind the block. */
|
||||
|
||||
if (ntok == MAN_LP || ntok == MAN_PP || ntok == MAN_P) {
|
||||
*pos = strlen(buf);
|
||||
blk_imp(man, ntok, line, ppos, pos, buf);
|
||||
if (tok == MAN_RE) {
|
||||
roff_elem_alloc(man, line, ppos, ROFF_br);
|
||||
man->last->flags |= NODE_LINE |
|
||||
NODE_VALID | NODE_ENDED;
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cline = man->last->line;
|
||||
cpos = man->last->pos;
|
||||
ctok = man->last->tok;
|
||||
man_unscope(man, nn);
|
||||
|
||||
if (tok == MAN_RE && nn->head->aux > 0)
|
||||
roff_setreg(man->roff, "an-margin", nn->head->aux, '-');
|
||||
|
||||
/* Trailing text. */
|
||||
|
||||
if (buf[*pos] != '\0') {
|
||||
roff_word_alloc(man, line, ppos, buf + *pos);
|
||||
man->last->flags |= NODE_DELIMC;
|
||||
if (mandoc_eos(man->last->string, strlen(man->last->string)))
|
||||
man->last->flags |= NODE_EOS;
|
||||
}
|
||||
|
||||
/* Move a trailing paragraph behind the block. */
|
||||
|
||||
if (ctok == MAN_LP || ctok == MAN_PP || ctok == MAN_P) {
|
||||
*pos = strlen(buf);
|
||||
blk_imp(man, ctok, cline, cpos, pos, buf);
|
||||
}
|
||||
|
||||
/* Synopsis blocks need an explicit end marker for spacing. */
|
||||
|
||||
if (tok == MAN_YS && man->last == nn) {
|
||||
roff_elem_alloc(man, line, ppos, tok);
|
||||
man_unscope(man, man->last);
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,7 +297,10 @@ blk_exp(MACRO_PROT_ARGS)
|
||||
char *p;
|
||||
int la;
|
||||
|
||||
rew_scope(man, tok);
|
||||
if (tok == MAN_RS) {
|
||||
rew_scope(man, tok);
|
||||
man->flags |= ROFF_NONOFILL;
|
||||
}
|
||||
roff_block_alloc(man, line, ppos, tok);
|
||||
head = roff_head_alloc(man, line, ppos, tok);
|
||||
|
||||
@ -275,14 +315,16 @@ blk_exp(MACRO_PROT_ARGS)
|
||||
roff_setreg(man->roff, "an-margin",
|
||||
head->aux, '+');
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (buf[*pos] != '\0')
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, line,
|
||||
*pos, "%s ... %s", roff_name[tok], buf + *pos);
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS, line, *pos,
|
||||
"%s ... %s", roff_name[tok], buf + *pos);
|
||||
|
||||
man_unscope(man, head);
|
||||
roff_body_alloc(man, line, ppos, tok);
|
||||
man->flags &= ~ROFF_NONOFILL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -299,9 +341,10 @@ blk_imp(MACRO_PROT_ARGS)
|
||||
struct roff_node *n;
|
||||
|
||||
rew_scope(man, tok);
|
||||
n = roff_block_alloc(man, line, ppos, tok);
|
||||
if (n->tok == MAN_SH || n->tok == MAN_SS)
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
man->flags |= ROFF_NONOFILL;
|
||||
if (tok == MAN_SH || tok == MAN_SS)
|
||||
man->flags &= ~ROFF_NOFILL;
|
||||
roff_block_alloc(man, line, ppos, tok);
|
||||
n = roff_head_alloc(man, line, ppos, tok);
|
||||
|
||||
/* Add line arguments. */
|
||||
@ -311,16 +354,17 @@ blk_imp(MACRO_PROT_ARGS)
|
||||
if ( ! man_args(man, line, pos, buf, &p))
|
||||
break;
|
||||
roff_word_alloc(man, line, la, p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* For macros having optional next-line scope,
|
||||
* keep the head open if there were no arguments.
|
||||
* For `TP', always keep the head open.
|
||||
* For `TP' and `TQ', always keep the head open.
|
||||
*/
|
||||
|
||||
if (man_macros[tok].flags & MAN_SCOPED &&
|
||||
(tok == MAN_TP || n == man->last)) {
|
||||
if (man_macro(tok)->flags & MAN_BSCOPED &&
|
||||
(tok == MAN_TP || tok == MAN_TQ || n == man->last)) {
|
||||
man->flags |= MAN_BLINE;
|
||||
return;
|
||||
}
|
||||
@ -329,6 +373,7 @@ blk_imp(MACRO_PROT_ARGS)
|
||||
|
||||
man_unscope(man, n);
|
||||
roff_body_alloc(man, line, ppos, tok);
|
||||
man->flags &= ~ROFF_NONOFILL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -341,27 +386,26 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
roff_elem_alloc(man, line, ppos, tok);
|
||||
n = man->last;
|
||||
|
||||
if (tok == MAN_EX)
|
||||
man->flags |= ROFF_NOFILL;
|
||||
else if (tok == MAN_EE)
|
||||
man->flags &= ~ROFF_NOFILL;
|
||||
|
||||
for (;;) {
|
||||
if (buf[*pos] != '\0' && (tok == MAN_fi || tok == MAN_nf)) {
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
man->parse, line, *pos, "%s %s",
|
||||
roff_name[tok], buf + *pos);
|
||||
break;
|
||||
}
|
||||
if (buf[*pos] != '\0' && man->last != n && tok == MAN_PD) {
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS,
|
||||
man->parse, line, *pos, "%s ... %s",
|
||||
roff_name[tok], buf + *pos);
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS, line, *pos,
|
||||
"%s ... %s", roff_name[tok], buf + *pos);
|
||||
break;
|
||||
}
|
||||
la = *pos;
|
||||
if ( ! man_args(man, line, pos, buf, &p))
|
||||
break;
|
||||
if (man_macros[tok].flags & MAN_JOIN &&
|
||||
if (man_macro(tok)->flags & MAN_JOIN &&
|
||||
man->last->type == ROFFT_TEXT)
|
||||
roff_word_append(man, p);
|
||||
else
|
||||
roff_word_alloc(man, line, la, p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -374,13 +418,12 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
man->last->flags |= NODE_EOS;
|
||||
|
||||
/*
|
||||
* If no arguments are specified and this is MAN_SCOPED (i.e.,
|
||||
* If no arguments are specified and this is MAN_ESCOPED (i.e.,
|
||||
* next-line scoped), then set our mode to indicate that we're
|
||||
* waiting for terms to load into our context.
|
||||
*/
|
||||
|
||||
if (n == man->last && man_macros[tok].flags & MAN_SCOPED) {
|
||||
assert( ! (man_macros[tok].flags & MAN_NSCOPED));
|
||||
if (n == man->last && man_macro(tok)->flags & MAN_ESCOPED) {
|
||||
man->flags |= MAN_ELINE;
|
||||
return;
|
||||
}
|
||||
@ -391,18 +434,21 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
/* Rewind our element scope. */
|
||||
|
||||
for ( ; man->last; man->last = man->last->parent) {
|
||||
man_state(man, man->last);
|
||||
man->last->flags |= NODE_VALID;
|
||||
if (man->last == n)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rewind next-line scoped ancestors, if any. */
|
||||
|
||||
if (man_macro(tok)->flags & MAN_ESCOPED)
|
||||
man_descope(man, line, ppos, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
man_endparse(struct roff_man *man)
|
||||
{
|
||||
|
||||
man_unscope(man, man->first);
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
man_unscope(man, man->meta.first);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -417,6 +463,6 @@ man_args(struct roff_man *man, int line, int *pos, char *buf, char **v)
|
||||
if ('\0' == *start)
|
||||
return 0;
|
||||
|
||||
*v = mandoc_getarg(man->parse, v, line, pos);
|
||||
*v = roff_getarg(man->roff, v, line, pos);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: man_term.c,v 1.211 2018/06/10 15:12:35 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.228 2019/01/05 21:18:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -27,7 +27,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "out.h"
|
||||
@ -37,8 +36,6 @@
|
||||
#define MAXMARGINS 64 /* maximum number of indented scopes */
|
||||
|
||||
struct mtermp {
|
||||
int fl;
|
||||
#define MANT_LITERAL (1 << 0)
|
||||
int lmargin[MAXMARGINS]; /* margins (incl. vis. page) */
|
||||
int lmargincur; /* index of current margin */
|
||||
int lmarginsz; /* actual number of nested margins */
|
||||
@ -51,7 +48,7 @@ struct mtermp {
|
||||
struct roff_node *n, \
|
||||
const struct roff_meta *meta
|
||||
|
||||
struct termact {
|
||||
struct man_term_act {
|
||||
int (*pre)(DECL_ARGS);
|
||||
void (*post)(DECL_ARGS);
|
||||
int flags;
|
||||
@ -78,8 +75,10 @@ static int pre_PP(DECL_ARGS);
|
||||
static int pre_RS(DECL_ARGS);
|
||||
static int pre_SH(DECL_ARGS);
|
||||
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);
|
||||
@ -89,18 +88,19 @@ static void post_IP(DECL_ARGS);
|
||||
static void post_HP(DECL_ARGS);
|
||||
static void post_RS(DECL_ARGS);
|
||||
static void post_SH(DECL_ARGS);
|
||||
static void post_SS(DECL_ARGS);
|
||||
static void post_SY(DECL_ARGS);
|
||||
static void post_TP(DECL_ARGS);
|
||||
static void post_UR(DECL_ARGS);
|
||||
|
||||
static const struct termact __termacts[MAN_MAX - MAN_TH] = {
|
||||
static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL, 0 }, /* TH */
|
||||
{ pre_SH, post_SH, 0 }, /* SH */
|
||||
{ pre_SS, post_SS, 0 }, /* SS */
|
||||
{ pre_SS, post_SH, 0 }, /* SS */
|
||||
{ pre_TP, post_TP, 0 }, /* TP */
|
||||
{ pre_PP, NULL, 0 }, /* LP */
|
||||
{ pre_TP, post_TP, 0 }, /* TQ */
|
||||
{ pre_abort, NULL, 0 }, /* LP */
|
||||
{ pre_PP, NULL, 0 }, /* PP */
|
||||
{ pre_PP, NULL, 0 }, /* P */
|
||||
{ pre_abort, NULL, 0 }, /* P */
|
||||
{ pre_IP, post_IP, 0 }, /* IP */
|
||||
{ pre_HP, post_HP, 0 }, /* HP */
|
||||
{ NULL, NULL, 0 }, /* SM */
|
||||
@ -114,8 +114,6 @@ static const struct termact __termacts[MAN_MAX - MAN_TH] = {
|
||||
{ pre_I, NULL, 0 }, /* I */
|
||||
{ pre_alternate, NULL, 0 }, /* IR */
|
||||
{ pre_alternate, NULL, 0 }, /* RI */
|
||||
{ pre_literal, NULL, 0 }, /* nf */
|
||||
{ pre_literal, NULL, 0 }, /* fi */
|
||||
{ NULL, NULL, 0 }, /* RE */
|
||||
{ pre_RS, post_RS, 0 }, /* RS */
|
||||
{ pre_DT, NULL, 0 }, /* DT */
|
||||
@ -123,6 +121,8 @@ static const struct termact __termacts[MAN_MAX - MAN_TH] = {
|
||||
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
|
||||
{ pre_ign, NULL, 0 }, /* AT */
|
||||
{ pre_in, NULL, MAN_NOTEXT }, /* in */
|
||||
{ pre_SY, post_SY, 0 }, /* SY */
|
||||
{ NULL, NULL, 0 }, /* YS */
|
||||
{ pre_OP, NULL, 0 }, /* OP */
|
||||
{ pre_literal, NULL, 0 }, /* EX */
|
||||
{ pre_literal, NULL, 0 }, /* EE */
|
||||
@ -131,15 +131,22 @@ static const struct termact __termacts[MAN_MAX - MAN_TH] = {
|
||||
{ pre_UR, post_UR, 0 }, /* MT */
|
||||
{ NULL, NULL, 0 }, /* ME */
|
||||
};
|
||||
static const struct termact *termacts = __termacts - MAN_TH;
|
||||
static const struct man_term_act *man_term_act(enum roff_tok);
|
||||
|
||||
|
||||
static const struct man_term_act *
|
||||
man_term_act(enum roff_tok tok)
|
||||
{
|
||||
assert(tok >= MAN_TH && tok <= MAN_MAX);
|
||||
return man_term_acts + (tok - MAN_TH);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_man(void *arg, const struct roff_man *man)
|
||||
terminal_man(void *arg, const struct roff_meta *man)
|
||||
{
|
||||
struct mtermp mt;
|
||||
struct termp *p;
|
||||
struct roff_node *n;
|
||||
struct mtermp mt;
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
@ -151,7 +158,7 @@ terminal_man(void *arg, const struct roff_man *man)
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
|
||||
memset(&mt, 0, sizeof(struct mtermp));
|
||||
memset(&mt, 0, sizeof(mt));
|
||||
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
||||
mt.offset = term_len(p, p->defindent);
|
||||
mt.pardist = 1;
|
||||
@ -164,18 +171,17 @@ terminal_man(void *arg, const struct roff_man *man)
|
||||
!strcmp(n->child->child->string, "SYNOPSIS")) {
|
||||
if (n->child->next->child != NULL)
|
||||
print_man_nodelist(p, &mt,
|
||||
n->child->next->child,
|
||||
&man->meta);
|
||||
n->child->next->child, man);
|
||||
term_newln(p);
|
||||
break;
|
||||
}
|
||||
n = n->next;
|
||||
}
|
||||
} else {
|
||||
term_begin(p, print_man_head, print_man_foot, &man->meta);
|
||||
term_begin(p, print_man_head, print_man_foot, man);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (n != NULL)
|
||||
print_man_nodelist(p, &mt, n, &man->meta);
|
||||
print_man_nodelist(p, &mt, n, man);
|
||||
term_end(p);
|
||||
}
|
||||
p->defindent = save_defindent;
|
||||
@ -196,12 +202,12 @@ print_bvspace(struct termp *p, const struct roff_node *n, int pardist)
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (n->body && n->body->child)
|
||||
if (n->body != NULL && n->body->child != NULL)
|
||||
if (n->body->child->type == ROFFT_TBL)
|
||||
return;
|
||||
|
||||
if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
|
||||
if (NULL == n->prev)
|
||||
if (n->prev == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pardist; i++)
|
||||
@ -209,17 +215,21 @@ print_bvspace(struct termp *p, const struct roff_node *n, int pardist)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pre_abort(DECL_ARGS)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ign(DECL_ARGS)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_I(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
return 1;
|
||||
}
|
||||
@ -227,14 +237,8 @@ pre_I(DECL_ARGS)
|
||||
static int
|
||||
pre_literal(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (n->tok == MAN_nf || n->tok == MAN_EX)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
else
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
||||
/*
|
||||
* Unlike .IP and .TP, .HP does not have a HEAD.
|
||||
* So in case a second call to term_flushln() is needed,
|
||||
@ -247,7 +251,6 @@ pre_literal(DECL_ARGS)
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -272,7 +275,7 @@ pre_alternate(DECL_ARGS)
|
||||
{
|
||||
enum termfont font[2];
|
||||
struct roff_node *nn;
|
||||
int savelit, i;
|
||||
int i;
|
||||
|
||||
switch (n->tok) {
|
||||
case MAN_RB:
|
||||
@ -302,29 +305,21 @@ pre_alternate(DECL_ARGS)
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
savelit = MANT_LITERAL & mt->fl;
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
||||
for (i = 0, nn = n->child; nn; nn = nn->next, i = 1 - i) {
|
||||
for (i = 0, nn = n->child; nn != NULL; nn = nn->next, i = 1 - i) {
|
||||
term_fontrepl(p, font[i]);
|
||||
if (savelit && NULL == nn->next)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
assert(nn->type == ROFFT_TEXT);
|
||||
term_word(p, nn->string);
|
||||
if (nn->flags & NODE_EOS)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
if (nn->next)
|
||||
if (nn->next != NULL)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_B(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
return 1;
|
||||
}
|
||||
@ -332,20 +327,19 @@ pre_B(DECL_ARGS)
|
||||
static int
|
||||
pre_OP(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_word(p, "[");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->flags |= TERMP_KEEP | TERMP_NOSPACE;
|
||||
|
||||
if (NULL != (n = n->child)) {
|
||||
if ((n = n->child) != NULL) {
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
term_word(p, n->string);
|
||||
}
|
||||
if (NULL != n && NULL != n->next) {
|
||||
if (n != NULL && n->next != NULL) {
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
term_word(p, n->next->string);
|
||||
}
|
||||
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
p->flags &= ~TERMP_KEEP;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "]");
|
||||
return 0;
|
||||
@ -369,9 +363,9 @@ pre_in(DECL_ARGS)
|
||||
cp = n->child->string;
|
||||
less = 0;
|
||||
|
||||
if ('-' == *cp)
|
||||
if (*cp == '-')
|
||||
less = -1;
|
||||
else if ('+' == *cp)
|
||||
else if (*cp == '+')
|
||||
less = 1;
|
||||
else
|
||||
cp--;
|
||||
@ -413,13 +407,18 @@ pre_HP(DECL_ARGS)
|
||||
case ROFFT_BLOCK:
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
if ( ! (MANT_LITERAL & mt->fl)) {
|
||||
if (n->child == NULL)
|
||||
return 0;
|
||||
|
||||
if ((n->child->flags & NODE_NOFILL) == 0) {
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND;
|
||||
p->trailspace = 2;
|
||||
}
|
||||
@ -445,8 +444,10 @@ pre_HP(DECL_ARGS)
|
||||
static void
|
||||
post_HP(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
case ROFFT_HEAD:
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
|
||||
@ -466,25 +467,27 @@ post_HP(DECL_ARGS)
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pre_PP(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
break;
|
||||
default:
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return n->type != ROFFT_HEAD;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -492,21 +495,21 @@ pre_IP(DECL_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
const struct roff_node *nn;
|
||||
int len, savelit;
|
||||
int len;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BODY:
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case ROFFT_BLOCK:
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case ROFFT_BLOCK:
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
/* FALLTHROUGH */
|
||||
case ROFFT_BODY:
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Calculate the offset from the optional second argument. */
|
||||
@ -526,33 +529,25 @@ pre_IP(DECL_ARGS)
|
||||
case ROFFT_HEAD:
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
|
||||
savelit = MANT_LITERAL & mt->fl;
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
||||
if (n->child)
|
||||
if (n->child != NULL)
|
||||
print_man_node(p, mt, n->child, meta);
|
||||
|
||||
if (savelit)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = mt->offset + len;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
post_IP(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
@ -564,7 +559,7 @@ post_IP(DECL_ARGS)
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,9 +568,13 @@ pre_TP(DECL_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
struct roff_node *nn;
|
||||
int len, savelit;
|
||||
int len;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
if (n->tok == MAN_TP)
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRTRSP;
|
||||
p->trailspace = 1;
|
||||
@ -583,11 +582,8 @@ pre_TP(DECL_ARGS)
|
||||
case ROFFT_BODY:
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case ROFFT_BLOCK:
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
return 1;
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Calculate offset. */
|
||||
@ -609,21 +605,15 @@ pre_TP(DECL_ARGS)
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
|
||||
savelit = MANT_LITERAL & mt->fl;
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
||||
/* Don't print same-line elements. */
|
||||
nn = n->child;
|
||||
while (NULL != nn && 0 == (NODE_LINE & nn->flags))
|
||||
while (nn != NULL && (nn->flags & NODE_LINE) == 0)
|
||||
nn = nn->next;
|
||||
|
||||
while (NULL != nn) {
|
||||
while (nn != NULL) {
|
||||
print_man_node(p, mt, nn, meta);
|
||||
nn = nn->next;
|
||||
}
|
||||
|
||||
if (savelit)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = mt->offset + len;
|
||||
@ -632,17 +622,17 @@ pre_TP(DECL_ARGS)
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
post_TP(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_flushln(p);
|
||||
break;
|
||||
@ -651,7 +641,7 @@ post_TP(DECL_ARGS)
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,7 +652,6 @@ pre_SS(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->offset = term_len(p, p->defindent);
|
||||
|
||||
@ -674,7 +663,7 @@ pre_SS(DECL_ARGS)
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (n != NULL && n->tok >= MAN_TH &&
|
||||
termacts[n->tok].flags & MAN_NOTEXT);
|
||||
man_term_act(n->tok)->flags & MAN_NOTEXT);
|
||||
if (n == NULL || n->type == ROFFT_COMMENT ||
|
||||
(n->tok == MAN_SS && n->body->child == NULL))
|
||||
break;
|
||||
@ -698,26 +687,9 @@ pre_SS(DECL_ARGS)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
post_SS(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
term_newln(p);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pre_SH(DECL_ARGS)
|
||||
{
|
||||
@ -725,7 +697,6 @@ pre_SH(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->offset = term_len(p, p->defindent);
|
||||
|
||||
@ -737,7 +708,7 @@ pre_SH(DECL_ARGS)
|
||||
do {
|
||||
n = n->prev;
|
||||
} while (n != NULL && n->tok >= MAN_TH &&
|
||||
termacts[n->tok].flags & MAN_NOTEXT);
|
||||
man_term_act(n->tok)->flags & MAN_NOTEXT);
|
||||
if (n == NULL || n->type == ROFFT_COMMENT ||
|
||||
(n->tok == MAN_SH && n->body->child == NULL))
|
||||
break;
|
||||
@ -759,25 +730,23 @@ pre_SH(DECL_ARGS)
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
post_SH(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
term_newln(p);
|
||||
case ROFFT_BLOCK:
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -792,8 +761,10 @@ pre_RS(DECL_ARGS)
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
return 0;
|
||||
default:
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
n = n->parent->head;
|
||||
@ -821,42 +792,99 @@ pre_RS(DECL_ARGS)
|
||||
static void
|
||||
post_RS(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
return;
|
||||
case ROFFT_HEAD:
|
||||
return;
|
||||
default:
|
||||
term_newln(p);
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
term_newln(p);
|
||||
mt->offset -= n->parent->head->aux;
|
||||
p->tcol->offset = mt->offset;
|
||||
|
||||
if (--mt->lmarginsz < MAXMARGINS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_SY(DECL_ARGS)
|
||||
{
|
||||
const struct roff_node *nn;
|
||||
int len;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
if (n->prev == NULL || n->prev->tok != MAN_SY)
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
return 1;
|
||||
case ROFFT_HEAD:
|
||||
case ROFFT_BODY:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
nn = n->parent->head->child;
|
||||
len = nn == NULL ? 1 : term_strlen(p, nn->string) + 1;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
if (n->next->child == NULL ||
|
||||
(n->next->child->flags & NODE_NOFILL) == 0)
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
mt->lmargin[mt->lmargincur] = len;
|
||||
p->tcol->offset = mt->offset + len;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
post_SY(DECL_ARGS)
|
||||
{
|
||||
switch (n->type) {
|
||||
case ROFFT_BLOCK:
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pre_UR(DECL_ARGS)
|
||||
{
|
||||
|
||||
return n->type != ROFFT_HEAD;
|
||||
}
|
||||
|
||||
static void
|
||||
post_UR(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_BLOCK)
|
||||
return;
|
||||
|
||||
term_word(p, "<");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
if (NULL != n->child->child)
|
||||
if (n->child->child != NULL)
|
||||
print_man_node(p, mt, n->child->child, meta);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -866,7 +894,8 @@ post_UR(DECL_ARGS)
|
||||
static void
|
||||
print_man_node(DECL_ARGS)
|
||||
{
|
||||
int c;
|
||||
const struct man_term_act *act;
|
||||
int c;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
@ -884,6 +913,8 @@ print_man_node(DECL_ARGS)
|
||||
} else if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(p->flags & TERMP_NONEWLINE) == 0)
|
||||
term_newln(p);
|
||||
else if (n->flags & NODE_DELIMC)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, n->string);
|
||||
goto out;
|
||||
@ -910,20 +941,20 @@ print_man_node(DECL_ARGS)
|
||||
return;
|
||||
}
|
||||
|
||||
assert(n->tok >= MAN_TH && n->tok <= MAN_MAX);
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
act = man_term_act(n->tok);
|
||||
if ((act->flags & MAN_NOTEXT) == 0 && n->tok != MAN_SM)
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
c = 1;
|
||||
if (termacts[n->tok].pre)
|
||||
c = (*termacts[n->tok].pre)(p, mt, n, meta);
|
||||
if (act->pre != NULL)
|
||||
c = (*act->pre)(p, mt, n, meta);
|
||||
|
||||
if (c && n->child)
|
||||
if (c && n->child != NULL)
|
||||
print_man_nodelist(p, mt, n->child, meta);
|
||||
|
||||
if (termacts[n->tok].post)
|
||||
(*termacts[n->tok].post)(p, mt, n, meta);
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
if (act->post != NULL)
|
||||
(*act->post)(p, mt, n, meta);
|
||||
if ((act->flags & MAN_NOTEXT) == 0 && n->tok != MAN_SM)
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
out:
|
||||
@ -934,7 +965,7 @@ print_man_node(DECL_ARGS)
|
||||
* -man doesn't have nested macros, we don't need to be
|
||||
* more specific than this.
|
||||
*/
|
||||
if (mt->fl & MANT_LITERAL &&
|
||||
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;
|
||||
@ -949,15 +980,13 @@ print_man_node(DECL_ARGS)
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
}
|
||||
}
|
||||
if (NODE_EOS & n->flags)
|
||||
if (n->flags & NODE_EOS)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_man_nodelist(DECL_ARGS)
|
||||
{
|
||||
|
||||
while (n != NULL) {
|
||||
print_man_node(p, mt, n, meta);
|
||||
n = n->next;
|
||||
@ -992,7 +1021,7 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
|
||||
}
|
||||
mandoc_asprintf(&title, "%s(%s)",
|
||||
meta->title, meta->msec);
|
||||
} else if (meta->os) {
|
||||
} else if (meta->os != NULL) {
|
||||
title = mandoc_strdup(meta->os);
|
||||
} else {
|
||||
title = mandoc_strdup("");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD$ */
|
||||
/* $Id: man_validate.c,v 1.146 2018/12/31 10:04:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -24,6 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -40,28 +41,32 @@
|
||||
|
||||
typedef void (*v_check)(CHKARGS);
|
||||
|
||||
static void check_abort(CHKARGS);
|
||||
static void check_par(CHKARGS);
|
||||
static void check_part(CHKARGS);
|
||||
static void check_root(CHKARGS);
|
||||
static void check_text(CHKARGS);
|
||||
|
||||
static void post_AT(CHKARGS);
|
||||
static void post_EE(CHKARGS);
|
||||
static void post_EX(CHKARGS);
|
||||
static void post_IP(CHKARGS);
|
||||
static void post_OP(CHKARGS);
|
||||
static void post_SH(CHKARGS);
|
||||
static void post_TH(CHKARGS);
|
||||
static void post_UC(CHKARGS);
|
||||
static void post_UR(CHKARGS);
|
||||
static void post_in(CHKARGS);
|
||||
static void post_vs(CHKARGS);
|
||||
|
||||
static const v_check __man_valids[MAN_MAX - MAN_TH] = {
|
||||
static const v_check man_valids[MAN_MAX - MAN_TH] = {
|
||||
post_TH, /* TH */
|
||||
NULL, /* SH */
|
||||
NULL, /* SS */
|
||||
post_SH, /* SH */
|
||||
post_SH, /* SS */
|
||||
NULL, /* TP */
|
||||
check_par, /* LP */
|
||||
NULL, /* TQ */
|
||||
check_abort,/* LP */
|
||||
check_par, /* PP */
|
||||
check_par, /* P */
|
||||
check_abort,/* P */
|
||||
post_IP, /* IP */
|
||||
NULL, /* HP */
|
||||
NULL, /* SM */
|
||||
@ -75,8 +80,6 @@ static const v_check __man_valids[MAN_MAX - MAN_TH] = {
|
||||
NULL, /* I */
|
||||
NULL, /* IR */
|
||||
NULL, /* RI */
|
||||
NULL, /* nf */
|
||||
NULL, /* fi */
|
||||
NULL, /* RE */
|
||||
check_part, /* RS */
|
||||
NULL, /* DT */
|
||||
@ -84,33 +87,56 @@ static const v_check __man_valids[MAN_MAX - MAN_TH] = {
|
||||
NULL, /* PD */
|
||||
post_AT, /* AT */
|
||||
post_in, /* in */
|
||||
NULL, /* SY */
|
||||
NULL, /* YS */
|
||||
post_OP, /* OP */
|
||||
NULL, /* EX */
|
||||
NULL, /* EE */
|
||||
post_EX, /* EX */
|
||||
post_EE, /* EE */
|
||||
post_UR, /* UR */
|
||||
NULL, /* UE */
|
||||
post_UR, /* MT */
|
||||
NULL, /* ME */
|
||||
};
|
||||
static const v_check *man_valids = __man_valids - MAN_TH;
|
||||
|
||||
|
||||
/* Validate the subtree rooted at man->last. */
|
||||
void
|
||||
man_node_validate(struct roff_man *man)
|
||||
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.
|
||||
*/
|
||||
|
||||
man->last = man->last->child;
|
||||
while (man->last != NULL) {
|
||||
man_node_validate(man);
|
||||
man_validate(man);
|
||||
if (man->last == n)
|
||||
man->last = man->last->child;
|
||||
else
|
||||
man->last = man->last->next;
|
||||
}
|
||||
|
||||
/* Finally validate the macro itself. */
|
||||
|
||||
man->last = n;
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
switch (n->type) {
|
||||
@ -126,23 +152,15 @@ man_node_validate(struct roff_man *man)
|
||||
break;
|
||||
default:
|
||||
if (n->tok < ROFF_MAX) {
|
||||
switch (n->tok) {
|
||||
case ROFF_br:
|
||||
case ROFF_sp:
|
||||
post_vs(man, n);
|
||||
break;
|
||||
default:
|
||||
roff_validate(man);
|
||||
break;
|
||||
}
|
||||
roff_validate(man);
|
||||
break;
|
||||
}
|
||||
assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
|
||||
cp = man_valids + n->tok;
|
||||
cp = man_valids + (n->tok - MAN_TH);
|
||||
if (*cp)
|
||||
(*cp)(man, n);
|
||||
if (man->last == n)
|
||||
man_state(man, n);
|
||||
n->flags |= NODE_VALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -153,14 +171,12 @@ check_root(CHKARGS)
|
||||
assert((man->flags & (MAN_BLINE | MAN_ELINE)) == 0);
|
||||
|
||||
if (n->last == NULL || n->last->type == ROFFT_COMMENT)
|
||||
mandoc_msg(MANDOCERR_DOC_EMPTY, man->parse,
|
||||
n->line, n->pos, NULL);
|
||||
mandoc_msg(MANDOCERR_DOC_EMPTY, n->line, n->pos, NULL);
|
||||
else
|
||||
man->meta.hasbody = 1;
|
||||
|
||||
if (NULL == man->meta.title) {
|
||||
mandoc_msg(MANDOCERR_TH_NOTITLE, man->parse,
|
||||
n->line, n->pos, NULL);
|
||||
mandoc_msg(MANDOCERR_TH_NOTITLE, n->line, n->pos, NULL);
|
||||
|
||||
/*
|
||||
* If a title hasn't been set, do so now (by
|
||||
@ -175,23 +191,43 @@ check_root(CHKARGS)
|
||||
|
||||
if (man->meta.os_e &&
|
||||
(man->meta.rcsids & (1 << man->meta.os_e)) == 0)
|
||||
mandoc_msg(MANDOCERR_RCS_MISSING, man->parse, 0, 0,
|
||||
mandoc_msg(MANDOCERR_RCS_MISSING, 0, 0,
|
||||
man->meta.os_e == MANDOC_OS_OPENBSD ?
|
||||
"(OpenBSD)" : "(NetBSD)");
|
||||
}
|
||||
|
||||
static void
|
||||
check_abort(CHKARGS)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static void
|
||||
check_text(CHKARGS)
|
||||
{
|
||||
char *cp, *p;
|
||||
|
||||
if (MAN_LITERAL & man->flags)
|
||||
if (n->flags & NODE_NOFILL)
|
||||
return;
|
||||
|
||||
cp = n->string;
|
||||
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
||||
mandoc_msg(MANDOCERR_FI_TAB, man->parse,
|
||||
n->line, n->pos + (p - cp), NULL);
|
||||
mandoc_msg(MANDOCERR_FI_TAB,
|
||||
n->line, n->pos + (int)(p - cp), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
post_EE(CHKARGS)
|
||||
{
|
||||
if ((n->flags & NODE_NOFILL) == 0)
|
||||
mandoc_msg(MANDOCERR_FI_SKIP, n->line, n->pos, "EE");
|
||||
}
|
||||
|
||||
static void
|
||||
post_EX(CHKARGS)
|
||||
{
|
||||
if (n->flags & NODE_NOFILL)
|
||||
mandoc_msg(MANDOCERR_NF_SKIP, n->line, n->pos, "EX");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -199,21 +235,55 @@ post_OP(CHKARGS)
|
||||
{
|
||||
|
||||
if (n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_OP_EMPTY, man->parse,
|
||||
n->line, n->pos, "OP");
|
||||
mandoc_msg(MANDOCERR_OP_EMPTY, n->line, n->pos, "OP");
|
||||
else if (n->child->next != NULL && n->child->next->next != NULL) {
|
||||
n = n->child->next->next;
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse,
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS,
|
||||
n->line, n->pos, "OP ... %s", n->string);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_SH(CHKARGS)
|
||||
{
|
||||
struct roff_node *nc;
|
||||
|
||||
if (n->type != ROFFT_BODY || (nc = n->child) == NULL)
|
||||
return;
|
||||
|
||||
if (nc->tok == MAN_PP && nc->body->child != NULL) {
|
||||
while (nc->body->last != NULL) {
|
||||
man->next = ROFF_NEXT_CHILD;
|
||||
roff_node_relink(man, nc->body->last);
|
||||
man->last = n;
|
||||
}
|
||||
}
|
||||
|
||||
if (nc->tok == MAN_PP || 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Trailing PP is empty, so it is deleted by check_par().
|
||||
* Trailing sp is significant.
|
||||
*/
|
||||
|
||||
if ((nc = n->last) != NULL && nc->tok == ROFF_br) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP,
|
||||
nc->line, nc->pos, "%s at the end of %s",
|
||||
roff_name[nc->tok], roff_name[n->tok]);
|
||||
roff_node_delete(man, nc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_UR(CHKARGS)
|
||||
{
|
||||
if (n->type == ROFFT_HEAD && n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_UR_NOHEAD, man->parse,
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
mandoc_msg(MANDOCERR_UR_NOHEAD, n->line, n->pos,
|
||||
"%s", roff_name[n->tok]);
|
||||
check_part(man, n);
|
||||
}
|
||||
|
||||
@ -222,8 +292,8 @@ check_part(CHKARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BODY && n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY, man->parse,
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY, n->line, n->pos,
|
||||
"%s", roff_name[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -236,15 +306,22 @@ check_par(CHKARGS)
|
||||
roff_node_delete(man, n);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->child != NULL &&
|
||||
(n->child->tok == ROFF_sp || n->child->tok == ROFF_br)) {
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP,
|
||||
n->child->line, n->child->pos,
|
||||
"%s after %s", roff_name[n->child->tok],
|
||||
roff_name[n->tok]);
|
||||
roff_node_delete(man, n->child);
|
||||
}
|
||||
if (n->child == NULL)
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||
man->parse, n->line, n->pos,
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos,
|
||||
"%s empty", roff_name[n->tok]);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
if (n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
man->parse, n->line, n->pos, "%s %s%s",
|
||||
mandoc_msg(MANDOCERR_ARG_SKIP,
|
||||
n->line, n->pos, "%s %s%s",
|
||||
roff_name[n->tok], n->child->string,
|
||||
n->child->next != NULL ? " ..." : "");
|
||||
break;
|
||||
@ -264,8 +341,7 @@ post_IP(CHKARGS)
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
if (n->parent->head->child == NULL && n->child == NULL)
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||
man->parse, n->line, n->pos,
|
||||
mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos,
|
||||
"%s empty", roff_name[n->tok]);
|
||||
break;
|
||||
default:
|
||||
@ -298,9 +374,8 @@ post_TH(CHKARGS)
|
||||
/* Only warn about this once... */
|
||||
if (isalpha((unsigned char)*p) &&
|
||||
! isupper((unsigned char)*p)) {
|
||||
mandoc_vmsg(MANDOCERR_TITLE_CASE,
|
||||
man->parse, n->line,
|
||||
n->pos + (p - n->string),
|
||||
mandoc_msg(MANDOCERR_TITLE_CASE, n->line,
|
||||
n->pos + (int)(p - n->string),
|
||||
"TH %s", n->string);
|
||||
break;
|
||||
}
|
||||
@ -308,8 +383,7 @@ post_TH(CHKARGS)
|
||||
man->meta.title = mandoc_strdup(n->string);
|
||||
} else {
|
||||
man->meta.title = mandoc_strdup("");
|
||||
mandoc_msg(MANDOCERR_TH_NOTITLE, man->parse,
|
||||
nb->line, nb->pos, "TH");
|
||||
mandoc_msg(MANDOCERR_TH_NOTITLE, nb->line, nb->pos, "TH");
|
||||
}
|
||||
|
||||
/* TITLE ->MSEC<- DATE OS VOL */
|
||||
@ -320,7 +394,7 @@ post_TH(CHKARGS)
|
||||
man->meta.msec = mandoc_strdup(n->string);
|
||||
else {
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
mandoc_vmsg(MANDOCERR_MSEC_MISSING, man->parse,
|
||||
mandoc_msg(MANDOCERR_MSEC_MISSING,
|
||||
nb->line, nb->pos, "TH %s", man->meta.title);
|
||||
}
|
||||
|
||||
@ -334,7 +408,7 @@ post_TH(CHKARGS)
|
||||
mandoc_normdate(man, n->string, n->line, n->pos);
|
||||
} else {
|
||||
man->meta.date = mandoc_strdup("");
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, man->parse,
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING,
|
||||
n ? n->line : nb->line,
|
||||
n ? n->pos : nb->pos, "TH");
|
||||
}
|
||||
@ -362,7 +436,7 @@ post_TH(CHKARGS)
|
||||
man->meta.vol = mandoc_strdup(p);
|
||||
|
||||
if (n != NULL && (n = n->next) != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse,
|
||||
mandoc_msg(MANDOCERR_ARG_EXCESS,
|
||||
n->line, n->pos, "TH ... %s", n->string);
|
||||
|
||||
/*
|
||||
@ -463,32 +537,3 @@ post_in(CHKARGS)
|
||||
free(n->child->string);
|
||||
n->child->string = s;
|
||||
}
|
||||
|
||||
static void
|
||||
post_vs(CHKARGS)
|
||||
{
|
||||
|
||||
if (NULL != n->prev)
|
||||
return;
|
||||
|
||||
switch (n->parent->tok) {
|
||||
case MAN_SH:
|
||||
case MAN_SS:
|
||||
case MAN_PP:
|
||||
case MAN_LP:
|
||||
case MAN_P:
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos,
|
||||
"%s after %s", roff_name[n->tok],
|
||||
roff_name[n->parent->tok]);
|
||||
/* FALLTHROUGH */
|
||||
case TOKEN_NONE:
|
||||
/*
|
||||
* Don't warn about this because it occurs in pod2man
|
||||
* and would cause considerable (unfixable) warnage.
|
||||
*/
|
||||
roff_node_delete(man, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* $Id: manconf.h,v 1.5 2017/07/01 09:47:30 schwarze Exp $ */
|
||||
/* $Id: manconf.h,v 1.7 2018/11/22 11:30:23 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -30,12 +30,14 @@ struct manoutput {
|
||||
char *man;
|
||||
char *paper;
|
||||
char *style;
|
||||
char *tag;
|
||||
size_t indent;
|
||||
size_t width;
|
||||
int fragment;
|
||||
int mdoc;
|
||||
int synopsisonly;
|
||||
int noval;
|
||||
int synopsisonly;
|
||||
int toc;
|
||||
};
|
||||
|
||||
struct manconf {
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.1,v 1.226 2018/07/28 18:34:15 schwarze Exp $
|
||||
.\" $Id: mandoc.1,v 1.237 2019/02/23 18:53:54 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 28 2018 $
|
||||
.Dd $Mdocdate: February 23 2019 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -256,10 +256,28 @@ where
|
||||
is the back-space character number 8.
|
||||
Emboldened characters are rendered as
|
||||
.Sq c Ns \e[bs] Ns c .
|
||||
This markup is typically converted to appropriate terminal sequences by
|
||||
the pager or
|
||||
.Xr ul 1 .
|
||||
To remove the markup, pipe the output to
|
||||
.Xr col 1
|
||||
.Fl b
|
||||
instead.
|
||||
.Pp
|
||||
The special characters documented in
|
||||
.Xr mandoc_char 7
|
||||
are rendered best-effort in an ASCII equivalent.
|
||||
In particular, opening and closing
|
||||
.Sq single quotes
|
||||
are represented as characters number 0x60 and 0x27, respectively,
|
||||
which agrees with all ASCII standards from 1965 to the latest
|
||||
revision (2012) and which matches the traditional way in which
|
||||
.Xr roff 7
|
||||
formatters represent single quotes in ASCII output.
|
||||
This correct ASCII rendering may look strange with modern
|
||||
Unicode-compatible fonts because contrary to ASCII, Unicode uses
|
||||
the code point U+0060 for the grave accent only, never for an opening
|
||||
quote.
|
||||
.Pp
|
||||
The following
|
||||
.Fl O
|
||||
@ -290,6 +308,26 @@ One useful application is for checking that
|
||||
output formats in the same way as the
|
||||
.Xr mdoc 7
|
||||
source it was generated from.
|
||||
.It Cm tag Ns Op = Ns Ar term
|
||||
If the formatted manual page is opened in a pager,
|
||||
go to the definition of the
|
||||
.Ar term
|
||||
rather than showing the manual page from the beginning.
|
||||
If no
|
||||
.Ar term
|
||||
is specified, reuse the first command line argument that is not a
|
||||
.Ar section
|
||||
number.
|
||||
If that argument is in
|
||||
.Xr apropos 1
|
||||
.Ar key Ns = Ns Ar val
|
||||
format, only the
|
||||
.Ar val
|
||||
is used rather than the argument as a whole.
|
||||
This is useful for commands like
|
||||
.Ql man -akO tag Ic=ulimit
|
||||
to search for a keyword and jump right to its definition
|
||||
in the matching manual pages.
|
||||
.It Cm width Ns = Ns Ar width
|
||||
The output width is set to
|
||||
.Ar width
|
||||
@ -308,9 +346,9 @@ Equations rendered from
|
||||
.Xr eqn 7
|
||||
blocks use MathML.
|
||||
.Pp
|
||||
The
|
||||
.Pa mandoc.css
|
||||
file documents style-sheet classes available for customising output.
|
||||
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
|
||||
@ -345,7 +383,7 @@ Instances of
|
||||
are replaced with the include filename.
|
||||
The default is not to present a
|
||||
hyperlink.
|
||||
.It Cm man Ns = Ns Ar fmt
|
||||
.It Cm man Ns = Ns Ar fmt Ns Op ; Ns Ar fmt
|
||||
The string
|
||||
.Ar fmt ,
|
||||
for example,
|
||||
@ -361,12 +399,19 @@ are replaced with the linked manual's name and section, respectively.
|
||||
If no section is included, section 1 is assumed.
|
||||
The default is not to
|
||||
present a hyperlink.
|
||||
If two formats are given and a file
|
||||
.Ar %N.%S
|
||||
exists in the current directory, the first format is used;
|
||||
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.
|
||||
This must be a valid absolute or
|
||||
relative URI.
|
||||
.It Cm toc
|
||||
If an input file contains at least two non-standard sections,
|
||||
print a table of contents near the beginning of the output.
|
||||
.El
|
||||
.Ss Locale Output
|
||||
By default,
|
||||
@ -667,10 +712,10 @@ To page manuals to the terminal:
|
||||
.Dl $ mandoc -l mandoc.1 man.1 apropos.1 makewhatis.8
|
||||
.Pp
|
||||
To produce HTML manuals with
|
||||
.Pa mandoc.css
|
||||
.Pa /usr/share/misc/mandoc.css
|
||||
as the style-sheet:
|
||||
.Pp
|
||||
.Dl $ mandoc \-T html -O style=mandoc.css mdoc.7 \*(Gt mdoc.7.html
|
||||
.Dl $ mandoc \-T html -O style=/usr/share/misc/mandoc.css mdoc.7 > mdoc.7.html
|
||||
.Pp
|
||||
To check over a large set of manuals:
|
||||
.Pp
|
||||
@ -678,7 +723,7 @@ To check over a large set of manuals:
|
||||
.Pp
|
||||
To produce a series of PostScript manuals for A4 paper:
|
||||
.Pp
|
||||
.Dl $ mandoc \-T ps \-O paper=a4 mdoc.7 man.7 \*(Gt manuals.ps
|
||||
.Dl $ mandoc \-T ps \-O paper=a4 mdoc.7 man.7 > manuals.ps
|
||||
.Pp
|
||||
Convert a modern
|
||||
.Xr mdoc 7
|
||||
@ -688,20 +733,36 @@ format, for use on systems lacking an
|
||||
.Xr mdoc 7
|
||||
parser:
|
||||
.Pp
|
||||
.Dl $ mandoc \-T man foo.mdoc \*(Gt foo.man
|
||||
.Dl $ mandoc \-T man foo.mdoc > foo.man
|
||||
.Sh DIAGNOSTICS
|
||||
Messages displayed by
|
||||
.Nm
|
||||
follow this format:
|
||||
.Bd -ragged -offset indent
|
||||
.Nm :
|
||||
.Ar file : Ns Ar line : Ns Ar column : level : message : macro args
|
||||
.Ar file : Ns Ar line : Ns Ar column : level : message : macro arguments
|
||||
.Pq Ar os
|
||||
.Ed
|
||||
.Pp
|
||||
Line and column numbers start at 1.
|
||||
The first three fields identify the
|
||||
.Ar file
|
||||
name,
|
||||
.Ar line
|
||||
number, and
|
||||
.Ar column
|
||||
number of the input file where the message was triggered.
|
||||
The line and column numbers start at 1.
|
||||
Both are omitted for messages referring to an input file as a whole.
|
||||
Macro names and arguments are omitted where meaningless.
|
||||
All
|
||||
.Ar level
|
||||
and
|
||||
.Ar message
|
||||
strings are explained below.
|
||||
The name of the
|
||||
.Ar macro
|
||||
triggering the message and its
|
||||
.Ar arguments
|
||||
are omitted where meaningless.
|
||||
The
|
||||
.Ar os
|
||||
operating system specifier is omitted for messages that are relevant
|
||||
@ -1606,6 +1667,12 @@ or
|
||||
.Cm off .
|
||||
The invalid argument is moved out of the macro, which leaves the macro
|
||||
empty, causing it to toggle the spacing mode.
|
||||
.It Sy "argument contains two font escapes"
|
||||
.Pq roff
|
||||
The second argument of a
|
||||
.Ic char
|
||||
request contains more than one font escape sequence.
|
||||
A wrong font may remain active after using the character.
|
||||
.It Sy "unknown font, skipping request"
|
||||
.Pq man , tbl
|
||||
A
|
||||
@ -1651,7 +1718,8 @@ Start it on a new input line to help formatters produce correct spacing.
|
||||
.It Sy "invalid escape sequence"
|
||||
.Pq roff
|
||||
An escape sequence has an invalid opening argument delimiter, lacks the
|
||||
closing argument delimiter, or the argument has too few characters.
|
||||
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
|
||||
@ -1664,6 +1732,12 @@ and
|
||||
.Ic \ew
|
||||
to the length of the incomplete argument.
|
||||
All other invalid escape sequences are ignored.
|
||||
.It Sy "undefined escape, printing literally"
|
||||
.Pq roff
|
||||
In an escape sequence, the first character
|
||||
right after the leading backslash is invalid.
|
||||
That character is printed literally,
|
||||
which is equivalent to ignoring the backslash.
|
||||
.It Sy "undefined string, using \(dq\(dq"
|
||||
.Pq roff
|
||||
If a string is used without being defined before,
|
||||
@ -1807,6 +1881,13 @@ or
|
||||
macro.
|
||||
It may be mistyped or unsupported.
|
||||
The request or macro is discarded including its arguments.
|
||||
.It Sy "skipping request outside macro"
|
||||
.Pq roff
|
||||
A
|
||||
.Ic shift
|
||||
or
|
||||
.Ic return
|
||||
request occurs outside any macro definition and has no effect.
|
||||
.It Sy "skipping insecure request"
|
||||
.Pq roff
|
||||
An input file attempted to run a shell command
|
||||
@ -1916,6 +1997,14 @@ When parsing for a request or a user-defined macro name to be called,
|
||||
only the escape sequence is discarded.
|
||||
The characters preceding it are used as the request or macro name,
|
||||
the characters following it are used as the arguments to the request or macro.
|
||||
.It Sy "using macro argument outside macro"
|
||||
.Pq roff
|
||||
The escape sequence \e$ occurs outside any macro definition
|
||||
and expands to the empty string.
|
||||
.It Sy "argument number is not numeric"
|
||||
.Pq roff
|
||||
The argument of the escape sequence \e$ is not a digit;
|
||||
the escape sequence expands to the empty string.
|
||||
.It Sy "NOT IMPLEMENTED: Bd -file"
|
||||
.Pq mdoc
|
||||
For security reasons, the
|
||||
@ -1944,6 +2033,13 @@ macro fails to specify the list type.
|
||||
The argument of a
|
||||
.Ic \&ce
|
||||
request is not a number.
|
||||
.It Sy "argument is not a character"
|
||||
.Pq roff
|
||||
The first argument of a
|
||||
.Ic char
|
||||
request is neither a single ASCII character
|
||||
nor a single character escape sequence.
|
||||
The request is ignored including all its arguments.
|
||||
.It Sy "missing manual name, using \(dq\(dq"
|
||||
.Pq mdoc
|
||||
The first call to
|
||||
@ -1978,6 +2074,13 @@ or
|
||||
.Ic \&gsize
|
||||
statement has a non-numeric or negative argument or no argument at all.
|
||||
The invalid request or statement is ignored.
|
||||
.It Sy "excessive shift"
|
||||
.Pq roff
|
||||
The argument of a
|
||||
.Ic shift
|
||||
request is larger than the number of arguments of the macro that is
|
||||
currently being executed.
|
||||
All macro arguments are deleted and \en(.$ is set to zero.
|
||||
.It Sy "NOT IMPLEMENTED: .so with absolute path or \(dq..\(dq"
|
||||
.Pq roff
|
||||
For security reasons,
|
||||
@ -2100,6 +2203,13 @@ implementations but not by
|
||||
.Nm
|
||||
was found in an input file.
|
||||
It is replaced by a question mark.
|
||||
.It Sy "unsupported escape sequence"
|
||||
.Pq roff
|
||||
An input file contains an escape sequence supported by GNU troff
|
||||
or Heirloom troff but not by
|
||||
.Nm ,
|
||||
and it is likely that this will cause information loss
|
||||
or considerable misformatting.
|
||||
.It Sy "unsupported roff request"
|
||||
.Pq roff
|
||||
An input file contains a
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.3,v 1.41 2017/07/04 23:40:01 schwarze Exp $
|
||||
.\" $Id: mandoc.3,v 1.44 2018/12/30 00:49:55 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,30 +15,23 @@
|
||||
.\" 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: December 30 2018 $
|
||||
.Dt MANDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc ,
|
||||
.Nm deroff ,
|
||||
.Nm mandocmsg ,
|
||||
.Nm man_mparse ,
|
||||
.Nm man_validate ,
|
||||
.Nm mdoc_validate ,
|
||||
.Nm mparse_alloc ,
|
||||
.Nm mparse_copy ,
|
||||
.Nm mparse_free ,
|
||||
.Nm mparse_getkeep ,
|
||||
.Nm mparse_keep ,
|
||||
.Nm mparse_open ,
|
||||
.Nm mparse_readfd ,
|
||||
.Nm mparse_reset ,
|
||||
.Nm mparse_result ,
|
||||
.Nm mparse_strerror ,
|
||||
.Nm mparse_strlevel ,
|
||||
.Nm mparse_updaterc
|
||||
.Nm mparse_result
|
||||
.Nd mandoc macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In stdio.h
|
||||
.In mandoc.h
|
||||
.Pp
|
||||
.Fd "#define ASCII_NBRSP"
|
||||
@ -47,38 +40,23 @@
|
||||
.Ft struct mparse *
|
||||
.Fo mparse_alloc
|
||||
.Fa "int options"
|
||||
.Fa "enum mandocerr mmin"
|
||||
.Fa "mandocmsg mmsg"
|
||||
.Fa "enum mandoc_os oe_e"
|
||||
.Fa "char *os_s"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo (*mandocmsg)
|
||||
.Fa "enum mandocerr errtype"
|
||||
.Fa "enum mandoclevel level"
|
||||
.Fa "const char *file"
|
||||
.Fa "int line"
|
||||
.Fa "int col"
|
||||
.Fa "const char *msg"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_free
|
||||
.Fa "struct mparse *parse"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fo mparse_getkeep
|
||||
.Fa "const struct mparse *parse"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_keep
|
||||
.Fa "struct mparse *parse"
|
||||
.Fo mparse_copy
|
||||
.Fa "const struct mparse *parse"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo mparse_open
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "const char *fname"
|
||||
.Fc
|
||||
.Ft "enum mandoclevel"
|
||||
.Ft void
|
||||
.Fo mparse_readfd
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "int fd"
|
||||
@ -88,24 +66,9 @@
|
||||
.Fo mparse_reset
|
||||
.Fa "struct mparse *parse"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Ft struct roff_meta *
|
||||
.Fo mparse_result
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "struct roff_man **man"
|
||||
.Fa "char **sodest"
|
||||
.Fc
|
||||
.Ft "const char *"
|
||||
.Fo mparse_strerror
|
||||
.Fa "enum mandocerr"
|
||||
.Fc
|
||||
.Ft "const char *"
|
||||
.Fo mparse_strlevel
|
||||
.Fa "enum mandoclevel"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_updaterc
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "enum mandoclevel *rc"
|
||||
.Fc
|
||||
.In roff.h
|
||||
.Ft void
|
||||
@ -118,22 +81,10 @@
|
||||
.In mdoc.h
|
||||
.Vt extern const char * const * mdoc_argnames;
|
||||
.Vt extern const char * const * mdoc_macronames;
|
||||
.Ft void
|
||||
.Fo mdoc_validate
|
||||
.Fa "struct roff_man *mdoc"
|
||||
.Fc
|
||||
.In sys/types.h
|
||||
.In mandoc.h
|
||||
.In man.h
|
||||
.Vt extern const char * const * man_macronames;
|
||||
.Ft "const struct mparse *"
|
||||
.Fo man_mparse
|
||||
.Fa "const struct roff_man *man"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo man_validate
|
||||
.Fa "struct roff_man *man"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mandoc
|
||||
@ -174,27 +125,13 @@ close it with
|
||||
retrieve the syntax tree with
|
||||
.Fn mparse_result ;
|
||||
.It
|
||||
depending on whether the
|
||||
.Fa macroset
|
||||
member of the returned
|
||||
.Vt struct roff_man
|
||||
is
|
||||
.Dv MACROSET_MDOC
|
||||
or
|
||||
.Dv MACROSET_MAN ,
|
||||
validate it with
|
||||
.Fn mdoc_validate
|
||||
or
|
||||
.Fn man_validate ,
|
||||
respectively;
|
||||
.It
|
||||
if information about the validity of the input is needed, fetch it with
|
||||
.Fn mparse_updaterc ;
|
||||
.It
|
||||
iterate over parse nodes with starting from the
|
||||
.Fa first
|
||||
member of the returned
|
||||
.Vt struct roff_man ;
|
||||
.Vt struct roff_meta ;
|
||||
.It
|
||||
free all allocated memory with
|
||||
.Fn mparse_free
|
||||
@ -232,9 +169,6 @@ and freed with
|
||||
This may be used across parsed input if
|
||||
.Fn mparse_reset
|
||||
is called between parses.
|
||||
.It Vt "mandocmsg"
|
||||
A prototype for a function to handle error and warning
|
||||
messages emitted by the parser.
|
||||
.El
|
||||
.Ss Functions
|
||||
.Bl -ohang
|
||||
@ -245,35 +179,11 @@ including text contained in its child nodes.
|
||||
To be used on children of the
|
||||
.Fa first
|
||||
member of
|
||||
.Vt struct roff_man .
|
||||
.Vt struct roff_meta .
|
||||
When it is no longer needed, the pointer returned from
|
||||
.Fn deroff
|
||||
can be passed to
|
||||
.Xr free 3 .
|
||||
.It Fn man_mparse
|
||||
Get the parser used for the current output.
|
||||
Declared in
|
||||
.In man.h ,
|
||||
implemented in
|
||||
.Pa man.c .
|
||||
.It Fn man_validate
|
||||
Validate the
|
||||
.Dv MACROSET_MAN
|
||||
parse tree obtained with
|
||||
.Fn mparse_result .
|
||||
Declared in
|
||||
.In man.h ,
|
||||
implemented in
|
||||
.Pa man.c .
|
||||
.It Fn mdoc_validate
|
||||
Validate the
|
||||
.Dv MACROSET_MDOC
|
||||
parse tree obtained with
|
||||
.Fn mparse_result .
|
||||
Declared in
|
||||
.In mdoc.h ,
|
||||
implemented in
|
||||
.Pa mdoc.c .
|
||||
.It Fn mparse_alloc
|
||||
Allocate a parser.
|
||||
The arguments have the following effect:
|
||||
@ -295,8 +205,8 @@ file inclusion requests are always honoured.
|
||||
Otherwise, if the request is the only content in an input file,
|
||||
only the file name is remembered, to be returned in the
|
||||
.Fa sodest
|
||||
argument of
|
||||
.Fn mparse_result .
|
||||
field of
|
||||
.Vt struct roff_meta .
|
||||
.Pp
|
||||
When the
|
||||
.Dv MPARSE_QUICK
|
||||
@ -305,24 +215,14 @@ This is for example useful in
|
||||
.Xr makewhatis 8
|
||||
.Fl Q
|
||||
to quickly build minimal databases.
|
||||
.It Ar mmin
|
||||
Can be set to
|
||||
.Dv MANDOCERR_BASE ,
|
||||
.Dv MANDOCERR_STYLE ,
|
||||
.Dv MANDOCERR_WARNING ,
|
||||
.Dv MANDOCERR_ERROR ,
|
||||
.Dv MANDOCERR_UNSUPP ,
|
||||
or
|
||||
.Dv MANDOCERR_MAX .
|
||||
Messages below the selected level will be suppressed.
|
||||
.It Ar mmsg
|
||||
A callback function to handle errors and warnings.
|
||||
See
|
||||
.Pa main.c
|
||||
for an example.
|
||||
If printing of error messages is not desired,
|
||||
.Dv NULL
|
||||
may be passed.
|
||||
.Pp
|
||||
When the
|
||||
.Dv MARSE_VALIDATE
|
||||
bit is set,
|
||||
.Fn mparse_result
|
||||
runs the validation functions before returning the syntax tree.
|
||||
This is almost always required, except in certain debugging scenarios,
|
||||
for example to dump unvalidated syntax trees.
|
||||
.It Ar os_e
|
||||
Operating system to check base system conventions for.
|
||||
If
|
||||
@ -361,19 +261,9 @@ Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_getkeep
|
||||
Acquire the keep buffer.
|
||||
Must follow a call of
|
||||
.Fn mparse_keep .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_keep
|
||||
Instruct the parser to retain a copy of its parsed input.
|
||||
This can be acquired with subsequent
|
||||
.Fn mparse_getkeep
|
||||
calls.
|
||||
.It Fn mparse_copy
|
||||
Dump a copy of the input to the standard output; used for
|
||||
.Fl man T Ns Cm man .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
@ -421,35 +311,6 @@ implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_result
|
||||
Obtain the result of a parse.
|
||||
One of the two pointers will be filled in.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_strerror
|
||||
Return a statically-allocated string representation of an error code.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_strlevel
|
||||
Return a statically-allocated string representation of a level code.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_updaterc
|
||||
If the highest warning or error level that occurred during the current
|
||||
.Fa parse
|
||||
is higher than
|
||||
.Pf * Fa rc ,
|
||||
update
|
||||
.Pf * Fa rc
|
||||
accordingly.
|
||||
This is useful after calling
|
||||
.Fn mdoc_validate
|
||||
or
|
||||
.Fn man_validate .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.c,v 1.104 2018/07/28 18:34:15 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.114 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -32,16 +32,70 @@
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
|
||||
static int a2time(time_t *, const char *, const char *);
|
||||
static char *time2a(time_t);
|
||||
|
||||
|
||||
enum mandoc_esc
|
||||
mandoc_font(const char *cp, int sz)
|
||||
{
|
||||
switch (sz) {
|
||||
case 0:
|
||||
return ESCAPE_FONTPREV;
|
||||
case 1:
|
||||
switch (cp[0]) {
|
||||
case 'B':
|
||||
case '3':
|
||||
return ESCAPE_FONTBOLD;
|
||||
case 'I':
|
||||
case '2':
|
||||
return ESCAPE_FONTITALIC;
|
||||
case 'P':
|
||||
return ESCAPE_FONTPREV;
|
||||
case 'R':
|
||||
case '1':
|
||||
return ESCAPE_FONTROMAN;
|
||||
case '4':
|
||||
return ESCAPE_FONTBI;
|
||||
default:
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
case 2:
|
||||
switch (cp[0]) {
|
||||
case 'B':
|
||||
switch (cp[1]) {
|
||||
case 'I':
|
||||
return ESCAPE_FONTBI;
|
||||
default:
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
case 'C':
|
||||
switch (cp[1]) {
|
||||
case 'B':
|
||||
return ESCAPE_FONTBOLD;
|
||||
case 'I':
|
||||
return ESCAPE_FONTITALIC;
|
||||
case 'R':
|
||||
case 'W':
|
||||
return ESCAPE_FONTCW;
|
||||
default:
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
default:
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
default:
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
enum mandoc_esc
|
||||
mandoc_escape(const char **end, const char **start, int *sz)
|
||||
{
|
||||
const char *local_start;
|
||||
int local_sz;
|
||||
int local_sz, c, i;
|
||||
char term;
|
||||
enum mandoc_esc gly;
|
||||
|
||||
@ -55,6 +109,14 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
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
|
||||
@ -77,6 +139,10 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
*sz = 2;
|
||||
break;
|
||||
case '[':
|
||||
if (**start == ' ') {
|
||||
++*end;
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
gly = ESCAPE_SPECIAL;
|
||||
term = ']';
|
||||
break;
|
||||
@ -91,11 +157,26 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
/*
|
||||
* Escapes taking no arguments at all.
|
||||
*/
|
||||
case 'd':
|
||||
case 'u':
|
||||
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;
|
||||
|
||||
@ -113,32 +194,57 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
* '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':
|
||||
gly = ESCAPE_IGNORE;
|
||||
/* FALLTHROUGH */
|
||||
case 'f':
|
||||
if (ESCAPE_ERROR == gly)
|
||||
gly = ESCAPE_FONT;
|
||||
gly = (*start)[-1] == 'f' ? ESCAPE_FONT : ESCAPE_IGNORE;
|
||||
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;
|
||||
case '*':
|
||||
if (strncmp(*start, "(.T", 3) != 0)
|
||||
abort();
|
||||
gly = ESCAPE_DEVICE;
|
||||
*start = ++*end;
|
||||
*sz = 2;
|
||||
break;
|
||||
|
||||
/*
|
||||
* These escapes are of the form \X'Y', where 'X' is the trigger
|
||||
@ -250,18 +356,29 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Anything else is assumed to be a glyph.
|
||||
* In this case, pass back the character after the backslash.
|
||||
* Several special characters can be encoded as
|
||||
* one-byte escape sequences without using \[].
|
||||
*/
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
assert(ESCAPE_ERROR != gly);
|
||||
|
||||
/*
|
||||
* Read up to the terminating character,
|
||||
* paying attention to nested escapes.
|
||||
@ -284,6 +401,15 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
}
|
||||
}
|
||||
*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))
|
||||
@ -295,43 +421,25 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
|
||||
switch (gly) {
|
||||
case ESCAPE_FONT:
|
||||
if (2 == *sz) {
|
||||
if ('C' == **start) {
|
||||
/*
|
||||
* Treat constant-width font modes
|
||||
* just like regular font modes.
|
||||
*/
|
||||
(*start)++;
|
||||
(*sz)--;
|
||||
} else {
|
||||
if ('B' == (*start)[0] && 'I' == (*start)[1])
|
||||
gly = ESCAPE_FONTBI;
|
||||
break;
|
||||
}
|
||||
} else if (1 != *sz)
|
||||
break;
|
||||
|
||||
switch (**start) {
|
||||
case '3':
|
||||
case 'B':
|
||||
gly = ESCAPE_FONTBOLD;
|
||||
break;
|
||||
case '2':
|
||||
case 'I':
|
||||
gly = ESCAPE_FONTITALIC;
|
||||
break;
|
||||
case 'P':
|
||||
gly = ESCAPE_FONTPREV;
|
||||
break;
|
||||
case '1':
|
||||
case 'R':
|
||||
gly = ESCAPE_FONTROMAN;
|
||||
break;
|
||||
}
|
||||
gly = mandoc_font(*start, *sz);
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (1 == *sz && 'c' == **start)
|
||||
gly = ESCAPE_NOSPACE;
|
||||
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
|
||||
@ -358,101 +466,6 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
return gly;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a quoted or unquoted roff-style request or macro argument.
|
||||
* Return a pointer to the parsed argument, which is either the original
|
||||
* pointer or advanced by one byte in case the argument is quoted.
|
||||
* NUL-terminate the argument in place.
|
||||
* Collapse pairs of quotes inside quoted arguments.
|
||||
* Advance the argument pointer to the next argument,
|
||||
* or to the NUL byte terminating the argument line.
|
||||
*/
|
||||
char *
|
||||
mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
||||
{
|
||||
char *start, *cp;
|
||||
int quoted, pairs, white;
|
||||
|
||||
/* Quoting can only start with a new word. */
|
||||
start = *cpp;
|
||||
quoted = 0;
|
||||
if ('"' == *start) {
|
||||
quoted = 1;
|
||||
start++;
|
||||
}
|
||||
|
||||
pairs = 0;
|
||||
white = 0;
|
||||
for (cp = start; '\0' != *cp; cp++) {
|
||||
|
||||
/*
|
||||
* Move the following text left
|
||||
* after quoted quotes and after "\\" and "\t".
|
||||
*/
|
||||
if (pairs)
|
||||
cp[-pairs] = cp[0];
|
||||
|
||||
if ('\\' == cp[0]) {
|
||||
/*
|
||||
* In copy mode, translate double to single
|
||||
* backslashes and backslash-t to literal tabs.
|
||||
*/
|
||||
switch (cp[1]) {
|
||||
case 't':
|
||||
cp[0] = '\t';
|
||||
/* FALLTHROUGH */
|
||||
case '\\':
|
||||
pairs++;
|
||||
cp++;
|
||||
break;
|
||||
case ' ':
|
||||
/* Skip escaped blanks. */
|
||||
if (0 == quoted)
|
||||
cp++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (0 == quoted) {
|
||||
if (' ' == cp[0]) {
|
||||
/* Unescaped blanks end unquoted args. */
|
||||
white = 1;
|
||||
break;
|
||||
}
|
||||
} else if ('"' == cp[0]) {
|
||||
if ('"' == cp[1]) {
|
||||
/* Quoted quotes collapse. */
|
||||
pairs++;
|
||||
cp++;
|
||||
} else {
|
||||
/* Unquoted quotes end quoted args. */
|
||||
quoted = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Quoted argument without a closing quote. */
|
||||
if (1 == quoted)
|
||||
mandoc_msg(MANDOCERR_ARG_QUOTE, parse, ln, *pos, NULL);
|
||||
|
||||
/* NUL-terminate this argument and move to the next one. */
|
||||
if (pairs)
|
||||
cp[-pairs] = '\0';
|
||||
if ('\0' != *cp) {
|
||||
*cp++ = '\0';
|
||||
while (' ' == *cp)
|
||||
cp++;
|
||||
}
|
||||
*pos += (int)(cp - start) + (quoted ? 1 : 0);
|
||||
*cpp = cp;
|
||||
|
||||
if ('\0' == *cp && (white || ' ' == cp[-1]))
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, parse, ln, *pos, NULL);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
static int
|
||||
a2time(time_t *t, const char *fmt, const char *p)
|
||||
{
|
||||
@ -529,7 +542,7 @@ mandoc_normdate(struct roff_man *man, char *in, int ln, int pos)
|
||||
/* No date specified: use today's date. */
|
||||
|
||||
if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0) {
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, man->parse, ln, pos, NULL);
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, ln, pos, NULL);
|
||||
return time2a(time(NULL));
|
||||
}
|
||||
|
||||
@ -539,23 +552,20 @@ mandoc_normdate(struct roff_man *man, char *in, int ln, int pos)
|
||||
a2time(&t, "%b %d, %Y", in)) {
|
||||
cp = time2a(t);
|
||||
if (t > time(NULL) + 86400)
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, man->parse,
|
||||
ln, pos, cp);
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, ln, pos, "%s", cp);
|
||||
else if (*in != '$' && strcmp(in, cp) != 0)
|
||||
mandoc_msg(MANDOCERR_DATE_NORM, man->parse,
|
||||
ln, pos, cp);
|
||||
mandoc_msg(MANDOCERR_DATE_NORM, ln, pos, "%s", cp);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* In man(7), do not warn about the legacy format. */
|
||||
|
||||
if (a2time(&t, "%Y-%m-%d", in) == 0)
|
||||
mandoc_msg(MANDOCERR_DATE_BAD, man->parse, ln, pos, in);
|
||||
mandoc_msg(MANDOCERR_DATE_BAD, ln, pos, "%s", in);
|
||||
else if (t > time(NULL) + 86400)
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, man->parse, ln, pos, in);
|
||||
else if (man->macroset == MACROSET_MDOC)
|
||||
mandoc_vmsg(MANDOCERR_DATE_LEGACY, man->parse,
|
||||
ln, pos, "Dd %s", in);
|
||||
mandoc_msg(MANDOCERR_DATE_FUTURE, ln, pos, "%s", in);
|
||||
else if (man->meta.macroset == MACROSET_MDOC)
|
||||
mandoc_msg(MANDOCERR_DATE_LEGACY, ln, pos, "Dd %s", in);
|
||||
|
||||
/* Use any non-mdoc(7) date verbatim. */
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
/* $Id: mandoc.css,v 1.36 2018/07/23 22:51:26 schwarze Exp $ */
|
||||
/* $Id: mandoc.css,v 1.45 2019/03/01 10:57:18 schwarze Exp $ */
|
||||
/*
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*
|
||||
* Written by Ingo Schwarze <schwarze@openbsd.org>.
|
||||
* I place this file into the public domain.
|
||||
* Permission to use, copy, modify, and distribute it for any purpose
|
||||
* with or without fee is hereby granted, without any conditions.
|
||||
*/
|
||||
|
||||
/* Global defaults. */
|
||||
@ -8,8 +13,16 @@
|
||||
html { max-width: 65em; }
|
||||
body { font-family: Helvetica,Arial,sans-serif; }
|
||||
table { margin-top: 0em;
|
||||
margin-bottom: 0em; }
|
||||
td { vertical-align: top; }
|
||||
margin-bottom: 0em;
|
||||
border-collapse: collapse; }
|
||||
/* Some browsers set border-color in a browser style for tbody,
|
||||
* but not for table, resulting in inconsistent border styling. */
|
||||
tbody { border-color: inherit; }
|
||||
tr { border-color: inherit; }
|
||||
td { vertical-align: top;
|
||||
padding-left: 0.2em;
|
||||
padding-right: 0.2em;
|
||||
border-color: inherit; }
|
||||
ul, ol, dl { margin-top: 0em;
|
||||
margin-bottom: 0em; }
|
||||
li, dt { margin-top: 1em; }
|
||||
@ -52,12 +65,14 @@ td.foot-os { text-align: right; }
|
||||
|
||||
.manual-text {
|
||||
margin-left: 3.8em; }
|
||||
.Nd { display: inline; }
|
||||
.Sh { margin-top: 1.2em;
|
||||
.Nd { }
|
||||
section.Sh { }
|
||||
h1.Sh { margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: -3.2em;
|
||||
font-size: 110%; }
|
||||
.Ss { margin-top: 1.2em;
|
||||
section.Ss { }
|
||||
h2.Ss { margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: -1.2em;
|
||||
font-size: 105%; }
|
||||
@ -106,20 +121,25 @@ td.foot-os { text-align: right; }
|
||||
.Bl-ohang > dt { }
|
||||
.Bl-ohang > dd {
|
||||
margin-left: 0em; }
|
||||
.Bl-tag { margin-left: 5.5em; }
|
||||
.Bl-tag { margin-top: 0.6em;
|
||||
margin-left: 5.5em; }
|
||||
.Bl-tag > dt {
|
||||
float: left;
|
||||
margin-top: 0em;
|
||||
margin-left: -5.5em;
|
||||
padding-right: 1.2em;
|
||||
padding-right: 0.5em;
|
||||
vertical-align: top; }
|
||||
.Bl-tag > dd {
|
||||
clear: right;
|
||||
width: 100%;
|
||||
margin-top: 0em;
|
||||
margin-left: 0em;
|
||||
margin-bottom: 0.6em;
|
||||
vertical-align: top;
|
||||
overflow: auto; }
|
||||
.Bl-compact { margin-top: 0em; }
|
||||
.Bl-compact > dd {
|
||||
margin-bottom: 0em; }
|
||||
.Bl-compact > dt {
|
||||
margin-top: 0em; }
|
||||
|
||||
@ -151,7 +171,7 @@ td.foot-os { text-align: right; }
|
||||
.RsV { }
|
||||
|
||||
.eqn { }
|
||||
.tbl { }
|
||||
.tbl td { vertical-align: middle; }
|
||||
|
||||
.HP { margin-left: 3.8em;
|
||||
text-indent: -3.8em; }
|
||||
@ -236,12 +256,86 @@ a.In { }
|
||||
font-weight: normal;
|
||||
font-family: monospace; }
|
||||
|
||||
/* Tooltip support. */
|
||||
|
||||
h1.Sh, h2.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;
|
||||
position: relative; }
|
||||
|
||||
.An::before { content: "An"; }
|
||||
.Ar::before { content: "Ar"; }
|
||||
.Cd::before { content: "Cd"; }
|
||||
.Cm::before { content: "Cm"; }
|
||||
.Dv::before { content: "Dv"; }
|
||||
.Em::before { content: "Em"; }
|
||||
.Er::before { content: "Er"; }
|
||||
.Ev::before { content: "Ev"; }
|
||||
.Fa::before { content: "Fa"; }
|
||||
.Fd::before { content: "Fd"; }
|
||||
.Fl::before { content: "Fl"; }
|
||||
.Fn::before { content: "Fn"; }
|
||||
.Ft::before { content: "Ft"; }
|
||||
.Ic::before { content: "Ic"; }
|
||||
code.In::before { content: "In"; }
|
||||
.Lb::before { content: "Lb"; }
|
||||
.Lk::before { content: "Lk"; }
|
||||
.Ms::before { content: "Ms"; }
|
||||
.Mt::before { content: "Mt"; }
|
||||
.Nd::before { content: "Nd"; }
|
||||
code.Nm::before { content: "Nm"; }
|
||||
.Pa::before { content: "Pa"; }
|
||||
.Rs::before { content: "Rs"; }
|
||||
h1.Sh::before { content: "Sh"; }
|
||||
h2.Ss::before { content: "Ss"; }
|
||||
.St::before { content: "St"; }
|
||||
.Sx::before { content: "Sx"; }
|
||||
.Sy::before { content: "Sy"; }
|
||||
.Va::before { content: "Va"; }
|
||||
.Vt::before { content: "Vt"; }
|
||||
.Xr::before { content: "Xr"; }
|
||||
|
||||
.An::before, .Ar::before, .Cd::before, .Cm::before,
|
||||
.Dv::before, .Em::before, .Er::before, .Ev::before,
|
||||
.Fa::before, .Fd::before, .Fl::before, .Fn::before, .Ft::before,
|
||||
.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,
|
||||
.Va::before, .Vt::before, .Xr::before {
|
||||
opacity: 0;
|
||||
transition: .15s ease opacity;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
box-shadow: 0 0 .35em #000;
|
||||
padding: .15em .25em;
|
||||
white-space: nowrap;
|
||||
font-family: Helvetica,Arial,sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
background: #fff; }
|
||||
.An:hover::before, .Ar:hover::before, .Cd:hover::before, .Cm:hover::before,
|
||||
.Dv:hover::before, .Em:hover::before, .Er:hover::before, .Ev:hover::before,
|
||||
.Fa:hover::before, .Fd:hover::before, .Fl:hover::before, .Fn:hover::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,
|
||||
.Sx:hover::before, .Sy:hover::before, .Va:hover::before, .Vt:hover::before,
|
||||
.Xr:hover::before {
|
||||
opacity: 1;
|
||||
pointer-events: inherit; }
|
||||
|
||||
/* Overrides to avoid excessive margins on small devices. */
|
||||
|
||||
@media (max-width: 37.5em) {
|
||||
.manual-text {
|
||||
margin-left: 0.5em; }
|
||||
.Sh, .Ss { margin-left: 0em; }
|
||||
h1.Sh, h2.Ss { margin-left: 0em; }
|
||||
.Bd-indent { margin-left: 2em; }
|
||||
.Bl-hang > dd {
|
||||
margin-left: 2em; }
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc.h,v 1.248 2018/07/28 18:34:15 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.262 2018/12/16 00:17:02 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -14,6 +14,8 @@
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Error handling, escape sequence, and character utilities.
|
||||
*/
|
||||
|
||||
#define ASCII_NBRSP 31 /* non-breaking space */
|
||||
@ -158,6 +160,7 @@ enum mandocerr {
|
||||
MANDOCERR_LB_BAD, /* unknown library name: Lb ... */
|
||||
MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */
|
||||
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_TR_ODD, /* odd number of characters in request: tr char */
|
||||
|
||||
@ -166,6 +169,7 @@ enum mandocerr {
|
||||
MANDOCERR_FI_TAB, /* tab in filled text */
|
||||
MANDOCERR_EOS, /* new sentence, new line */
|
||||
MANDOCERR_ESC_BAD, /* invalid escape sequence: esc */
|
||||
MANDOCERR_ESC_UNDEF, /* undefined escape, printing literally: char */
|
||||
MANDOCERR_STR_UNDEF, /* undefined string, using "": name */
|
||||
|
||||
/* related to tables */
|
||||
@ -195,6 +199,7 @@ enum mandocerr {
|
||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||
MANDOCERR_CHAR_BAD, /* skipping bad character: number */
|
||||
MANDOCERR_MACRO, /* skipping unknown macro: macro */
|
||||
MANDOCERR_REQ_NOMAC, /* skipping request outside macro: ... */
|
||||
MANDOCERR_REQ_INSEC, /* skipping insecure request: request */
|
||||
MANDOCERR_IT_STRAY, /* skipping item outside list: It ... */
|
||||
MANDOCERR_TA_STRAY, /* skipping column outside column list: Ta */
|
||||
@ -205,14 +210,18 @@ enum mandocerr {
|
||||
|
||||
/* related to request and macro arguments */
|
||||
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_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_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 */
|
||||
MANDOCERR_IT_NONUM, /* skipping request without numeric argument */
|
||||
MANDOCERR_SHIFT, /* excessive shift: ..., but max is ... */
|
||||
MANDOCERR_SO_PATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
||||
MANDOCERR_SO_FAIL, /* .so request failed */
|
||||
MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */
|
||||
@ -223,7 +232,12 @@ enum mandocerr {
|
||||
|
||||
MANDOCERR_TOOLARGE, /* input too large */
|
||||
MANDOCERR_CHAR_UNSUPP, /* unsupported control character: number */
|
||||
MANDOCERR_ESC_UNSUPP, /* unsupported escape sequence: escape */
|
||||
MANDOCERR_REQ_UNSUPP, /* unsupported roff request: request */
|
||||
MANDOCERR_WHILE_NEST, /* nested .while loops */
|
||||
MANDOCERR_WHILE_OUTOF, /* end of scope with open .while loop */
|
||||
MANDOCERR_WHILE_INTO, /* end of .while loop in inner scope */
|
||||
MANDOCERR_WHILE_FAIL, /* cannot continue this .while loop */
|
||||
MANDOCERR_TBLOPT_EQN, /* eqn delim option in tbl: arg */
|
||||
MANDOCERR_TBLLAYOUT_MOD, /* unsupported tbl layout modifier: m */
|
||||
MANDOCERR_TBLMACRO, /* ignoring macro in table: macro */
|
||||
@ -231,206 +245,22 @@ enum mandocerr {
|
||||
MANDOCERR_MAX
|
||||
};
|
||||
|
||||
struct tbl_opts {
|
||||
char tab; /* cell-separator */
|
||||
char decimal; /* decimal point */
|
||||
int opts;
|
||||
#define TBL_OPT_CENTRE (1 << 0)
|
||||
#define TBL_OPT_EXPAND (1 << 1)
|
||||
#define TBL_OPT_BOX (1 << 2)
|
||||
#define TBL_OPT_DBOX (1 << 3)
|
||||
#define TBL_OPT_ALLBOX (1 << 4)
|
||||
#define TBL_OPT_NOKEEP (1 << 5)
|
||||
#define TBL_OPT_NOSPACE (1 << 6)
|
||||
#define TBL_OPT_NOWARN (1 << 7)
|
||||
int cols; /* number of columns */
|
||||
int lvert; /* width of left vertical line */
|
||||
int rvert; /* width of right vertical line */
|
||||
};
|
||||
|
||||
enum tbl_cellt {
|
||||
TBL_CELL_CENTRE, /* c, C */
|
||||
TBL_CELL_RIGHT, /* r, R */
|
||||
TBL_CELL_LEFT, /* l, L */
|
||||
TBL_CELL_NUMBER, /* n, N */
|
||||
TBL_CELL_SPAN, /* s, S */
|
||||
TBL_CELL_LONG, /* a, A */
|
||||
TBL_CELL_DOWN, /* ^ */
|
||||
TBL_CELL_HORIZ, /* _, - */
|
||||
TBL_CELL_DHORIZ, /* = */
|
||||
TBL_CELL_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* A cell in a layout row.
|
||||
*/
|
||||
struct tbl_cell {
|
||||
struct tbl_cell *next;
|
||||
char *wstr; /* min width represented as a string */
|
||||
size_t width; /* minimum column width */
|
||||
size_t spacing; /* to the right of the column */
|
||||
int vert; /* width of subsequent vertical line */
|
||||
int col; /* column number, starting from 0 */
|
||||
int flags;
|
||||
#define TBL_CELL_TALIGN (1 << 0) /* t, T */
|
||||
#define TBL_CELL_BALIGN (1 << 1) /* d, D */
|
||||
#define TBL_CELL_BOLD (1 << 2) /* fB, B, b */
|
||||
#define TBL_CELL_ITALIC (1 << 3) /* fI, I, i */
|
||||
#define TBL_CELL_EQUAL (1 << 4) /* e, E */
|
||||
#define TBL_CELL_UP (1 << 5) /* u, U */
|
||||
#define TBL_CELL_WIGN (1 << 6) /* z, Z */
|
||||
#define TBL_CELL_WMAX (1 << 7) /* x, X */
|
||||
enum tbl_cellt pos;
|
||||
};
|
||||
|
||||
/*
|
||||
* A layout row.
|
||||
*/
|
||||
struct tbl_row {
|
||||
struct tbl_row *next;
|
||||
struct tbl_cell *first;
|
||||
struct tbl_cell *last;
|
||||
int vert; /* width of left vertical line */
|
||||
};
|
||||
|
||||
enum tbl_datt {
|
||||
TBL_DATA_NONE, /* has no data */
|
||||
TBL_DATA_DATA, /* consists of data/string */
|
||||
TBL_DATA_HORIZ, /* horizontal line */
|
||||
TBL_DATA_DHORIZ, /* double-horizontal line */
|
||||
TBL_DATA_NHORIZ, /* squeezed horizontal line */
|
||||
TBL_DATA_NDHORIZ /* squeezed double-horizontal line */
|
||||
};
|
||||
|
||||
/*
|
||||
* A cell within a row of data. The "string" field contains the actual
|
||||
* string value that's in the cell. The rest is layout.
|
||||
*/
|
||||
struct tbl_dat {
|
||||
struct tbl_cell *layout; /* layout cell */
|
||||
struct tbl_dat *next;
|
||||
char *string; /* data (NULL if not TBL_DATA_DATA) */
|
||||
int spans; /* how many spans follow */
|
||||
int block; /* T{ text block T} */
|
||||
enum tbl_datt pos;
|
||||
};
|
||||
|
||||
enum tbl_spant {
|
||||
TBL_SPAN_DATA, /* span consists of data */
|
||||
TBL_SPAN_HORIZ, /* span is horizontal line */
|
||||
TBL_SPAN_DHORIZ /* span is double horizontal line */
|
||||
};
|
||||
|
||||
/*
|
||||
* A row of data in a table.
|
||||
*/
|
||||
struct tbl_span {
|
||||
struct tbl_opts *opts;
|
||||
struct tbl_row *layout; /* layout row */
|
||||
struct tbl_dat *first;
|
||||
struct tbl_dat *last;
|
||||
struct tbl_span *prev;
|
||||
struct tbl_span *next;
|
||||
int line; /* parse line */
|
||||
enum tbl_spant pos;
|
||||
};
|
||||
|
||||
enum eqn_boxt {
|
||||
EQN_TEXT, /* text (number, variable, whatever) */
|
||||
EQN_SUBEXPR, /* nested `eqn' subexpression */
|
||||
EQN_LIST, /* list (braces, etc.) */
|
||||
EQN_PILE, /* vertical pile */
|
||||
EQN_MATRIX /* pile of piles */
|
||||
};
|
||||
|
||||
enum eqn_fontt {
|
||||
EQNFONT_NONE = 0,
|
||||
EQNFONT_ROMAN,
|
||||
EQNFONT_BOLD,
|
||||
EQNFONT_FAT,
|
||||
EQNFONT_ITALIC,
|
||||
EQNFONT__MAX
|
||||
};
|
||||
|
||||
enum eqn_post {
|
||||
EQNPOS_NONE = 0,
|
||||
EQNPOS_SUP,
|
||||
EQNPOS_SUBSUP,
|
||||
EQNPOS_SUB,
|
||||
EQNPOS_TO,
|
||||
EQNPOS_FROM,
|
||||
EQNPOS_FROMTO,
|
||||
EQNPOS_OVER,
|
||||
EQNPOS_SQRT,
|
||||
EQNPOS__MAX
|
||||
};
|
||||
|
||||
enum eqn_pilet {
|
||||
EQNPILE_NONE = 0,
|
||||
EQNPILE_PILE,
|
||||
EQNPILE_CPILE,
|
||||
EQNPILE_RPILE,
|
||||
EQNPILE_LPILE,
|
||||
EQNPILE_COL,
|
||||
EQNPILE_CCOL,
|
||||
EQNPILE_RCOL,
|
||||
EQNPILE_LCOL,
|
||||
EQNPILE__MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* A "box" is a parsed mathematical expression as defined by the eqn.7
|
||||
* grammar.
|
||||
*/
|
||||
struct eqn_box {
|
||||
int size; /* font size of expression */
|
||||
#define EQN_DEFSIZE INT_MIN
|
||||
enum eqn_boxt type; /* type of node */
|
||||
struct eqn_box *first; /* first child node */
|
||||
struct eqn_box *last; /* last child node */
|
||||
struct eqn_box *next; /* node sibling */
|
||||
struct eqn_box *prev; /* node sibling */
|
||||
struct eqn_box *parent; /* node sibling */
|
||||
char *text; /* text (or NULL) */
|
||||
char *left; /* fence left-hand */
|
||||
char *right; /* fence right-hand */
|
||||
char *top; /* expression over-symbol */
|
||||
char *bottom; /* expression under-symbol */
|
||||
size_t args; /* arguments in parent */
|
||||
size_t expectargs; /* max arguments in parent */
|
||||
enum eqn_post pos; /* position of next box */
|
||||
enum eqn_fontt font; /* font of box */
|
||||
enum eqn_pilet pile; /* equation piling */
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse options.
|
||||
*/
|
||||
#define MPARSE_MDOC 1 /* assume -mdoc */
|
||||
#define MPARSE_MAN 2 /* assume -man */
|
||||
#define MPARSE_SO 4 /* honour .so requests */
|
||||
#define MPARSE_QUICK 8 /* abort the parse early */
|
||||
#define MPARSE_UTF8 16 /* accept UTF-8 input */
|
||||
#define MPARSE_LATIN1 32 /* accept ISO-LATIN-1 input */
|
||||
|
||||
enum mandoc_os {
|
||||
MANDOC_OS_OTHER = 0,
|
||||
MANDOC_OS_NETBSD,
|
||||
MANDOC_OS_OPENBSD
|
||||
};
|
||||
|
||||
enum mandoc_esc {
|
||||
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
||||
ESCAPE_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_FONT, /* a generic font mode */
|
||||
ESCAPE_FONTBOLD, /* bold font mode */
|
||||
ESCAPE_FONTITALIC, /* italic font mode */
|
||||
ESCAPE_FONTBI, /* bold italic font mode */
|
||||
ESCAPE_FONTROMAN, /* roman font mode */
|
||||
ESCAPE_FONTCW, /* constant width font mode */
|
||||
ESCAPE_FONTPREV, /* previous font mode */
|
||||
ESCAPE_NUMBERED, /* a numbered glyph */
|
||||
ESCAPE_UNICODE, /* a unicode codepoint */
|
||||
ESCAPE_DEVICE, /* print the output device name */
|
||||
ESCAPE_BREAK, /* break the output line */
|
||||
ESCAPE_NOSPACE, /* suppress space if the last on a line */
|
||||
ESCAPE_HORIZ, /* horizontal movement */
|
||||
@ -439,14 +269,18 @@ enum mandoc_esc {
|
||||
ESCAPE_OVERSTRIKE /* overstrike all chars in the argument */
|
||||
};
|
||||
|
||||
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
|
||||
const char *, int, int, const char *);
|
||||
|
||||
|
||||
struct mparse;
|
||||
struct roff_man;
|
||||
|
||||
enum mandoc_esc mandoc_font(const char *, int sz);
|
||||
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
||||
void mandoc_msg_setoutfile(FILE *);
|
||||
const char *mandoc_msg_getinfilename(void);
|
||||
void mandoc_msg_setinfilename(const char *);
|
||||
enum mandocerr mandoc_msg_getmin(void);
|
||||
void mandoc_msg_setmin(enum mandocerr);
|
||||
enum mandoclevel mandoc_msg_getrc(void);
|
||||
void mandoc_msg_setrc(enum mandoclevel);
|
||||
void mandoc_msg(enum mandocerr, int, int, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 4, 5)));
|
||||
void mchars_alloc(void);
|
||||
void mchars_free(void);
|
||||
int mchars_num2char(const char *, size_t);
|
||||
@ -454,18 +288,3 @@ const char *mchars_uc2str(int);
|
||||
int mchars_num2uc(const char *, size_t);
|
||||
int mchars_spec2cp(const char *, size_t);
|
||||
const char *mchars_spec2str(const char *, size_t, size_t *);
|
||||
struct mparse *mparse_alloc(int, enum mandocerr, mandocmsg,
|
||||
enum mandoc_os, const char *);
|
||||
void mparse_free(struct mparse *);
|
||||
void mparse_keep(struct mparse *);
|
||||
int mparse_open(struct mparse *, const char *);
|
||||
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
|
||||
enum mandoclevel mparse_readmem(struct mparse *, void *, size_t,
|
||||
const char *);
|
||||
void mparse_reset(struct mparse *);
|
||||
void mparse_result(struct mparse *,
|
||||
struct roff_man **, char **);
|
||||
const char *mparse_getkeep(const struct mparse *);
|
||||
const char *mparse_strerror(enum mandocerr);
|
||||
const char *mparse_strlevel(enum mandoclevel);
|
||||
void mparse_updaterc(struct mparse *, enum mandoclevel *);
|
||||
|
@ -1,8 +1,8 @@
|
||||
.\" $Id: mandoc_char.7,v 1.72 2018/08/08 14:30:48 schwarze Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.75 2018/12/15 19:30:26 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2013, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011,2013,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 8 2018 $
|
||||
.Dd $Mdocdate: December 15 2018 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -266,11 +266,13 @@ Spacing:
|
||||
.It Em Input Ta Em Description
|
||||
.It Sq \e\ \& Ta unpaddable non-breaking space
|
||||
.It \e\(ti Ta paddable non-breaking space
|
||||
.It \e0 Ta unpaddable, breaking digit-width space
|
||||
.It \e0 Ta digit-width space allowing line break
|
||||
.It \e| Ta one-sixth \e(em narrow space, zero width in nroff mode
|
||||
.It \e^ Ta one-twelfth \e(em half-narrow space, zero width in nroff
|
||||
.It \e& Ta zero-width space
|
||||
.It \e& Ta zero-width non-breaking space
|
||||
.It \e) Ta zero-width space transparent to end-of-sentence detection
|
||||
.It \e% Ta zero-width space allowing hyphenation
|
||||
.It \e: Ta zero-width space allowing line break
|
||||
.El
|
||||
.Pp
|
||||
Lines:
|
||||
@ -543,11 +545,13 @@ Accented letters:
|
||||
.It \e(\(aqI Ta \('I Ta acute I
|
||||
.It \e(\(aqO Ta \('O Ta acute O
|
||||
.It \e(\(aqU Ta \('U Ta acute U
|
||||
.It \e(\(aqY Ta \('Y Ta acute Y
|
||||
.It \e(\(aqa Ta \('a Ta acute a
|
||||
.It \e(\(aqe Ta \('e Ta acute e
|
||||
.It \e(\(aqi Ta \('i Ta acute i
|
||||
.It \e(\(aqo Ta \('o Ta acute o
|
||||
.It \e(\(aqu Ta \('u Ta acute u
|
||||
.It \e(\(aqy Ta \('y Ta acute y
|
||||
.It \e(\(gaA Ta \(`A Ta grave A
|
||||
.It \e(\(gaE Ta \(`E Ta grave E
|
||||
.It \e(\(gaI Ta \(`I Ta grave I
|
||||
@ -761,14 +765,16 @@ For backward compatibility with existing manuals,
|
||||
.Xr mandoc 1
|
||||
also supports the
|
||||
.Pp
|
||||
.Dl \eN\(aq Ns Ar number Ns \(aq
|
||||
.Dl \eN\(aq Ns Ar number Ns \(aq and \e[ Ns Cm char Ns Ar number ]
|
||||
.Pp
|
||||
escape sequence, inserting the character
|
||||
escape sequences, inserting the character
|
||||
.Ar number
|
||||
from the current character set into the output.
|
||||
Of course, this is inherently non-portable and is already marked
|
||||
as deprecated in the Heirloom roff manual.
|
||||
For example, do not use \eN\(aq34\(aq, use \e(dq, or even the plain
|
||||
as deprecated in the Heirloom roff manual;
|
||||
on top of that, the second form is a GNU extension.
|
||||
For example, do not use \eN\(aq34\(aq or \e[char34], use \e(dq,
|
||||
or even the plain
|
||||
.Sq \(dq
|
||||
character where possible.
|
||||
.Sh COMPATIBILITY
|
||||
|
@ -1,4 +1,4 @@
|
||||
.Dd $Mdocdate: July 8 2017 $
|
||||
.Dd $Mdocdate: December 30 2018 $
|
||||
.Dt MANDOC_HEADERS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -25,15 +25,15 @@ separate from each other:
|
||||
.Pp
|
||||
.Bl -dash -offset indent -compact
|
||||
.It
|
||||
.Xr roff 7
|
||||
parser
|
||||
.It
|
||||
.Xr mdoc 7
|
||||
parser
|
||||
.It
|
||||
.Xr man 7
|
||||
parser
|
||||
.It
|
||||
.Xr roff 7
|
||||
parser
|
||||
.It
|
||||
.Xr tbl 7
|
||||
parser
|
||||
.It
|
||||
@ -45,6 +45,8 @@ terminal formatters
|
||||
HTML formatters
|
||||
.It
|
||||
search tools
|
||||
.It
|
||||
main programs
|
||||
.El
|
||||
.Pp
|
||||
Note that mere usage of an opaque struct type does
|
||||
@ -56,14 +58,18 @@ any other mandoc header.
|
||||
These headers should be included before any other mandoc headers.
|
||||
.Bl -tag -width Ds
|
||||
.It Qq Pa mandoc_aux.h
|
||||
Memory allocation utility functions; can be used everywhere.
|
||||
.Pp
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides the utility functions documented in
|
||||
Provides the functions documented in
|
||||
.Xr mandoc_malloc 3 .
|
||||
.It Qq Pa mandoc_ohash.h
|
||||
Hashing utility functions; can be used everywhere.
|
||||
.Pp
|
||||
Requires
|
||||
.In stddef.h
|
||||
for
|
||||
@ -78,73 +84,37 @@ Includes
|
||||
and provides
|
||||
.Fn mandoc_ohash_init .
|
||||
.It Qq Pa mandoc.h
|
||||
Error handling, escape sequence, and character utilities;
|
||||
can be used everywhere.
|
||||
.Pp
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Vt size_t
|
||||
and
|
||||
.In stdio.h
|
||||
for
|
||||
.Vt FILE .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum mandoc_esc ,
|
||||
.Vt enum mandocerr ,
|
||||
.Vt enum mandoclevel ,
|
||||
.Vt enum mandoc_os ,
|
||||
.Vt enum tbl_cellt ,
|
||||
.Vt enum tbl_datt ,
|
||||
.Vt enum tbl_spant ,
|
||||
.Vt enum eqn_boxt ,
|
||||
.Vt enum eqn_fontt ,
|
||||
.Vt enum eqn_pilet ,
|
||||
.Vt enum eqn_post ,
|
||||
.Vt struct tbl_opts ,
|
||||
.Vt struct tbl_cell ,
|
||||
.Vt struct tbl_row ,
|
||||
.Vt struct tbl_dat ,
|
||||
.Vt struct tbl_span ,
|
||||
.Vt struct eqn_box ,
|
||||
the function prototype typedef
|
||||
.Fn mandocmsg ,
|
||||
the function
|
||||
.Xr mandoc_escape 3 ,
|
||||
the functions described in
|
||||
.Xr mchars_alloc 3 ,
|
||||
and the functions
|
||||
.Fn mparse_*
|
||||
described in
|
||||
.Xr mandoc 3 .
|
||||
.Pp
|
||||
Uses the opaque type
|
||||
.Vt struct mparse
|
||||
from
|
||||
.Pa read.c
|
||||
for function prototypes.
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa mandoc_xr.h
|
||||
Provides
|
||||
.Vt struct mandoc_xr
|
||||
and the functions
|
||||
.Fn mandoc_xr_reset ,
|
||||
.Fn mandoc_xr_add ,
|
||||
.Fn mandoc_xr_get ,
|
||||
and
|
||||
.Fn mandoc_xr_free .
|
||||
and the
|
||||
.Fn mandoc_msg*
|
||||
functions.
|
||||
.It Qq Pa roff.h
|
||||
Requires
|
||||
.Qq Pa mandoc_ohash.h
|
||||
for
|
||||
.Vt struct ohash
|
||||
and
|
||||
.Qq Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandoc_os .
|
||||
Common data types for all syntax trees and related functions;
|
||||
can be used everywhere.
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum mandoc_os ,
|
||||
.Vt enum mdoc_endbody ,
|
||||
.Vt enum roff_macroset ,
|
||||
.Vt enum roff_next ,
|
||||
.Vt enum roff_sec ,
|
||||
.Vt enum roff_tok ,
|
||||
.Vt enum roff_type ,
|
||||
@ -153,21 +123,99 @@ Provides
|
||||
.Vt struct roff_node ,
|
||||
the constant array
|
||||
.Va roff_name
|
||||
and the functions
|
||||
.Fn deroff ,
|
||||
.Fn roffhash_alloc ,
|
||||
.Fn roffhash_find ,
|
||||
.Fn roffhash_free ,
|
||||
and
|
||||
.Fn roff_validate .
|
||||
and the function
|
||||
.Fn deroff .
|
||||
.Pp
|
||||
Uses pointers to the types
|
||||
.Vt struct ohash
|
||||
from
|
||||
.Pa mandoc_ohash.h ,
|
||||
.Vt struct mdoc_arg
|
||||
and
|
||||
.Vt union mdoc_data
|
||||
from
|
||||
.Pa mdoc.h
|
||||
.Pa mdoc.h ,
|
||||
.Vt struct tbl_span
|
||||
from
|
||||
.Pa tbl.h ,
|
||||
and
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa eqn.h
|
||||
as opaque struct members.
|
||||
.It Qq Pa tbl.h
|
||||
Data structures for the
|
||||
.Xr tbl 7
|
||||
parse tree; can be used everywhere.
|
||||
.Pp
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum tbl_cellt ,
|
||||
.Vt enum tbl_datt ,
|
||||
.Vt enum tbl_spant ,
|
||||
.Vt struct tbl_opts ,
|
||||
.Vt struct tbl_cell ,
|
||||
.Vt struct tbl_row ,
|
||||
.Vt struct tbl_dat ,
|
||||
and
|
||||
.Vt struct tbl_span .
|
||||
.It Qq Pa eqn.h
|
||||
Data structures for the
|
||||
.Xr eqn 7
|
||||
parse tree; can be used everywhere.
|
||||
.Pp
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum eqn_boxt ,
|
||||
.Vt enum eqn_fontt ,
|
||||
.Vt enum eqn_post ,
|
||||
and
|
||||
.Vt struct eqn_box .
|
||||
.It Qq Pa mandoc_parse.h
|
||||
Top level parser interface, for use in the main program
|
||||
and in the main parser, but not in formatters.
|
||||
.Pp
|
||||
Requires
|
||||
.Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandocerr
|
||||
and
|
||||
.Vt enum mandoclevel
|
||||
and
|
||||
.Pa roff.h
|
||||
for
|
||||
.Vt enum mandoc_os .
|
||||
.Pp
|
||||
Uses the opaque type
|
||||
.Vt struct mparse
|
||||
from
|
||||
.Pa read.c
|
||||
for function prototypes.
|
||||
Uses
|
||||
.Vt struct roff_meta
|
||||
from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa mandoc_xr.h
|
||||
Cross reference validation; intended for use in the main program
|
||||
and in parsers, but not in formatters.
|
||||
.Pp
|
||||
Provides
|
||||
.Vt struct mandoc_xr
|
||||
and the functions
|
||||
.Fn mandoc_xr_reset ,
|
||||
.Fn mandoc_xr_add ,
|
||||
.Fn mandoc_xr_get ,
|
||||
and
|
||||
.Fn mandoc_xr_free .
|
||||
.El
|
||||
.Pp
|
||||
The following two require
|
||||
@ -200,27 +248,24 @@ and the functions
|
||||
described in
|
||||
.Xr mandoc 3 .
|
||||
.Pp
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
Uses the types
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
and
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff_int.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa libman.h
|
||||
or
|
||||
.Pa libroff.h .
|
||||
internals of different parsers.
|
||||
.It Qq Pa man.h
|
||||
Provides the functions
|
||||
.Fn man_*
|
||||
described in
|
||||
.Xr mandoc 3 .
|
||||
.Pp
|
||||
Uses the opaque type
|
||||
.Vt struct mparse
|
||||
from
|
||||
.Pa read.c
|
||||
for function prototypes.
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
from
|
||||
@ -228,12 +273,10 @@ from
|
||||
as an opaque type for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa libmdoc.h
|
||||
or
|
||||
.Pa libroff.h .
|
||||
internals of different parsers.
|
||||
.El
|
||||
.Ss Parser internals
|
||||
The following headers require inclusion of a parser interface header
|
||||
Most of the following headers require inclusion of a parser interface header
|
||||
before they can be included.
|
||||
All parser interface headers should precede all parser internal headers.
|
||||
When any parser internal headers are included, the same file should
|
||||
@ -250,16 +293,11 @@ for
|
||||
.Vt enum mandocerr .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum rofferr ,
|
||||
.Vt struct buf ,
|
||||
utility functions needed by multiple parsers,
|
||||
and the top-level functions to call the parsers.
|
||||
.Pp
|
||||
Uses the opaque types
|
||||
.Vt struct mparse
|
||||
from
|
||||
.Pa read.c
|
||||
and
|
||||
Uses the opaque type
|
||||
.Vt struct roff
|
||||
from
|
||||
.Pa roff.c
|
||||
@ -270,14 +308,28 @@ from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa roff_int.h
|
||||
Parser internals shared by multiple parsers.
|
||||
Can be used in all parsers, but not in main programs or formatters.
|
||||
.Pp
|
||||
Requires
|
||||
.Qq Pa roff.h
|
||||
for
|
||||
.Vt enum roff_type .
|
||||
.Vt enum roff_type
|
||||
and
|
||||
.Vt enum roff_tok .
|
||||
.Pp
|
||||
Provides functions named
|
||||
Provides
|
||||
.Vt enum roff_next ,
|
||||
.Vt struct roff_man ,
|
||||
functions named
|
||||
.Fn roff_*
|
||||
to handle roff nodes and the two special functions
|
||||
to handle roff nodes,
|
||||
.Fn roffhash_alloc ,
|
||||
.Fn roffhash_find ,
|
||||
.Fn roffhash_free ,
|
||||
and
|
||||
.Fn roff_validate ,
|
||||
and the two special functions
|
||||
.Fn man_breakscope
|
||||
and
|
||||
.Fn mdoc_argv_free
|
||||
@ -285,11 +337,17 @@ because the latter two are needed by
|
||||
.Qq Pa roff.c .
|
||||
.Pp
|
||||
Uses the types
|
||||
.Vt struct roff_man
|
||||
and
|
||||
.Vt struct roff_node
|
||||
.Vt struct ohash
|
||||
from
|
||||
.Pa roff.h
|
||||
.Pa mandoc_ohash.h ,
|
||||
.Vt struct roff_node
|
||||
and
|
||||
.Vt struct roff_meta
|
||||
from
|
||||
.Pa roff.h ,
|
||||
.Vt struct roff
|
||||
from
|
||||
.Pa roff.c ,
|
||||
and
|
||||
.Vt struct mdoc_arg
|
||||
from
|
||||
@ -301,11 +359,7 @@ Requires
|
||||
for
|
||||
.Vt enum roff_tok
|
||||
and
|
||||
.Qq Pa mdoc.h
|
||||
for
|
||||
.Vt enum mdoc_*
|
||||
and
|
||||
.Vt struct mdoc_* .
|
||||
.Vt enum roff_sec .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum margserr ,
|
||||
@ -315,23 +369,21 @@ and many functions internal to the
|
||||
.Xr mdoc 7
|
||||
parser.
|
||||
.Pp
|
||||
Uses the opaque type
|
||||
.Vt struct mparse
|
||||
from
|
||||
.Pa read.c .
|
||||
Uses the types
|
||||
.Vt struct roff_man
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
.Pa roff.h ,
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff_int.h ,
|
||||
and
|
||||
.Vt struct mdoc_arg
|
||||
from
|
||||
.Pa mdoc.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa man.h ,
|
||||
.Pa libman.h ,
|
||||
or
|
||||
.Pa libroff.h .
|
||||
interfaces of different parsers.
|
||||
.It Qq Pa libman.h
|
||||
Requires
|
||||
.Qq Pa roff.h
|
||||
@ -345,52 +397,109 @@ and some functions internal to the
|
||||
parser.
|
||||
.Pp
|
||||
Uses the types
|
||||
.Vt struct roff_man
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
and
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff_int.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa mdoc.h ,
|
||||
.Pa libmdoc.h ,
|
||||
or
|
||||
.Pa libroff.h .
|
||||
.It Qq Pa libroff.h
|
||||
interfaces of different parsers.
|
||||
.It Qq Pa eqn_parse.h
|
||||
External interface of the
|
||||
.Xr eqn 7
|
||||
parser, for use in the
|
||||
.Xr roff 7
|
||||
and
|
||||
.Xr eqn 7
|
||||
parsers only.
|
||||
.Pp
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt struct eqn_node
|
||||
and the functions
|
||||
.Fn eqn_alloc ,
|
||||
.Fn eqn_box_new ,
|
||||
.Fn eqn_box_free ,
|
||||
.Fn eqn_free ,
|
||||
.Fn eqn_parse ,
|
||||
.Fn eqn_read ,
|
||||
and
|
||||
.Qq Pa mandoc.h
|
||||
.Fn eqn_reset .
|
||||
.Pp
|
||||
Uses the type
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa mandoc.h
|
||||
as an opaque type for function prototypes.
|
||||
Uses the types
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
and
|
||||
.Vt struct eqn_def
|
||||
from
|
||||
.Pa eqn.c
|
||||
as opaque struct members.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
internals of different parsers.
|
||||
.It Qq Pa tbl_parse.h
|
||||
External interface of the
|
||||
.Xr tbl 7
|
||||
parser, for use in the
|
||||
.Xr roff 7
|
||||
and
|
||||
.Xr tbl 7
|
||||
parsers only.
|
||||
.Pp
|
||||
Provides the functions documented in
|
||||
.Xr tbl 3 .
|
||||
.Pp
|
||||
Uses the types
|
||||
.Vt struct tbl_span
|
||||
from
|
||||
.Pa tbl.h
|
||||
and
|
||||
.Vt struct tbl_node
|
||||
from
|
||||
.Pa tbl_int.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
internals of different parsers.
|
||||
.It Qq Pa tbl_int.h
|
||||
Internal interfaces of the
|
||||
.Xr tbl 7
|
||||
parser, for use inside the
|
||||
.Xr tbl 7
|
||||
parser only.
|
||||
.Pp
|
||||
Requires
|
||||
.Qq Pa tbl.h
|
||||
for
|
||||
.Vt struct tbl_*
|
||||
and
|
||||
.Vt struct eqn_box .
|
||||
.Vt struct tbl_opts .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum tbl_part ,
|
||||
.Vt struct tbl_node ,
|
||||
.Vt struct eqn_def ,
|
||||
.Vt struct eqn_node ,
|
||||
and many functions internal to the
|
||||
.Xr tbl 7
|
||||
and the functions
|
||||
.Fn tbl_option ,
|
||||
.Fn tbl_layout ,
|
||||
.Fn tbl_data ,
|
||||
.Fn tbl_cdata ,
|
||||
and
|
||||
.Xr eqn 7
|
||||
parsers.
|
||||
.Pp
|
||||
Uses the opaque type
|
||||
.Vt struct mparse
|
||||
from
|
||||
.Pa read.c .
|
||||
.Fn tbl_reset .
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa man.h ,
|
||||
.Pa mdoc.h ,
|
||||
.Pa libman.h ,
|
||||
or
|
||||
.Pa libmdoc.h .
|
||||
interfaces of different parsers.
|
||||
.El
|
||||
.Ss Formatter interface
|
||||
These headers should be included after any parser interface headers.
|
||||
@ -466,7 +575,10 @@ or
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t
|
||||
.Vt size_t ,
|
||||
.Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandoc_esc ,
|
||||
and
|
||||
.Qq Pa out.h
|
||||
for
|
||||
@ -517,7 +629,7 @@ functionality mentioned in
|
||||
Provides the top level steering functions for all formatters.
|
||||
.Pp
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
.Vt struct roff_meta
|
||||
from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_html.3,v 1.17 2018/06/25 16:54:59 schwarze Exp $
|
||||
.\" $Id: mandoc_html.3,v 1.19 2019/01/11 12:56:43 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: June 25 2018 $
|
||||
.Dd $Mdocdate: January 11 2019 $
|
||||
.Dt MANDOC_HTML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -167,11 +167,6 @@ the respective attribute is not written.
|
||||
Print a
|
||||
.Cm class
|
||||
attribute.
|
||||
This attribute letter can optionally be followed by the modifier letter
|
||||
.Cm T .
|
||||
In that case, a
|
||||
.Cm title
|
||||
attribute with the same value is also printed.
|
||||
.It Cm h
|
||||
Print a
|
||||
.Cm href
|
||||
@ -216,6 +211,14 @@ It requires two
|
||||
.Va char *
|
||||
arguments.
|
||||
The first is the name of the style property, the second its value.
|
||||
The name must not be
|
||||
.Dv NULL .
|
||||
The
|
||||
.Cm s
|
||||
.Ar fmt
|
||||
letter can be repeated, each repetition requiring an additional pair of
|
||||
.Va char *
|
||||
arguments.
|
||||
.El
|
||||
.Pp
|
||||
.Fn print_otag
|
||||
|
329
contrib/mandoc/mandoc_msg.c
Normal file
329
contrib/mandoc/mandoc_msg.c
Normal file
@ -0,0 +1,329 @@
|
||||
/* $Id: mandoc_msg.c,v 1.6 2019/03/06 15:55:38 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014,2015,2016,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
|
||||
* 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.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
|
||||
static const enum mandocerr lowest_type[MANDOCLEVEL_MAX] = {
|
||||
MANDOCERR_OK,
|
||||
MANDOCERR_OK,
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_ERROR,
|
||||
MANDOCERR_UNSUPP,
|
||||
MANDOCERR_MAX,
|
||||
MANDOCERR_MAX
|
||||
};
|
||||
|
||||
static const char *const level_name[MANDOCLEVEL_MAX] = {
|
||||
"SUCCESS",
|
||||
"STYLE",
|
||||
"WARNING",
|
||||
"ERROR",
|
||||
"UNSUPP",
|
||||
"BADARG",
|
||||
"SYSERR"
|
||||
};
|
||||
|
||||
static const char *const type_message[MANDOCERR_MAX] = {
|
||||
"ok",
|
||||
|
||||
"base system convention",
|
||||
|
||||
"Mdocdate found",
|
||||
"Mdocdate missing",
|
||||
"unknown architecture",
|
||||
"operating system explicitly specified",
|
||||
"RCS id missing",
|
||||
"referenced manual not found",
|
||||
|
||||
"generic style suggestion",
|
||||
|
||||
"legacy man(7) date format",
|
||||
"normalizing date format to",
|
||||
"lower case character in document title",
|
||||
"duplicate RCS id",
|
||||
"possible typo in section name",
|
||||
"unterminated quoted argument",
|
||||
"useless macro",
|
||||
"consider using OS macro",
|
||||
"errnos out of order",
|
||||
"duplicate errno",
|
||||
"trailing delimiter",
|
||||
"no blank before trailing delimiter",
|
||||
"fill mode already enabled, skipping",
|
||||
"fill mode already disabled, skipping",
|
||||
"verbatim \"--\", maybe consider using \\(em",
|
||||
"function name without markup",
|
||||
"whitespace at end of input line",
|
||||
"bad comment style",
|
||||
|
||||
"generic warning",
|
||||
|
||||
/* related to the prologue */
|
||||
"missing manual title, using UNTITLED",
|
||||
"missing manual title, using \"\"",
|
||||
"missing manual section, using \"\"",
|
||||
"unknown manual section",
|
||||
"missing date, using today's date",
|
||||
"cannot parse date, using it verbatim",
|
||||
"date in the future, using it anyway",
|
||||
"missing Os macro, using \"\"",
|
||||
"late prologue macro",
|
||||
"prologue macros out of order",
|
||||
|
||||
/* related to document structure */
|
||||
".so is fragile, better use ln(1)",
|
||||
"no document body",
|
||||
"content before first section header",
|
||||
"first section is not \"NAME\"",
|
||||
"NAME section without Nm before Nd",
|
||||
"NAME section without description",
|
||||
"description not at the end of NAME",
|
||||
"bad NAME section content",
|
||||
"missing comma before name",
|
||||
"missing description line, using \"\"",
|
||||
"description line outside NAME section",
|
||||
"sections out of conventional order",
|
||||
"duplicate section title",
|
||||
"unexpected section",
|
||||
"cross reference to self",
|
||||
"unusual Xr order",
|
||||
"unusual Xr punctuation",
|
||||
"AUTHORS section without An macro",
|
||||
|
||||
/* related to macros and nesting */
|
||||
"obsolete macro",
|
||||
"macro neither callable nor escaped",
|
||||
"skipping paragraph macro",
|
||||
"moving paragraph macro out of list",
|
||||
"skipping no-space macro",
|
||||
"blocks badly nested",
|
||||
"nested displays are not portable",
|
||||
"moving content out of list",
|
||||
"first macro on line",
|
||||
"line scope broken",
|
||||
"skipping blank line in line scope",
|
||||
|
||||
/* related to missing macro arguments */
|
||||
"skipping empty request",
|
||||
"conditional request controls empty scope",
|
||||
"skipping empty macro",
|
||||
"empty block",
|
||||
"empty argument, using 0n",
|
||||
"missing display type, using -ragged",
|
||||
"list type is not the first argument",
|
||||
"missing -width in -tag list, using 6n",
|
||||
"missing utility name, using \"\"",
|
||||
"missing function name, using \"\"",
|
||||
"empty head in list item",
|
||||
"empty list item",
|
||||
"missing argument, using next line",
|
||||
"missing font type, using \\fR",
|
||||
"unknown font type, using \\fR",
|
||||
"nothing follows prefix",
|
||||
"empty reference block",
|
||||
"missing section argument",
|
||||
"missing -std argument, adding it",
|
||||
"missing option string, using \"\"",
|
||||
"missing resource identifier, using \"\"",
|
||||
"missing eqn box, using \"\"",
|
||||
|
||||
/* related to bad macro arguments */
|
||||
"duplicate argument",
|
||||
"skipping duplicate argument",
|
||||
"skipping duplicate display type",
|
||||
"skipping duplicate list type",
|
||||
"skipping -width argument",
|
||||
"wrong number of cells",
|
||||
"unknown AT&T UNIX version",
|
||||
"comma in function argument",
|
||||
"parenthesis in function name",
|
||||
"unknown library name",
|
||||
"invalid content in Rs block",
|
||||
"invalid Boolean argument",
|
||||
"argument contains two font escapes",
|
||||
"unknown font, skipping request",
|
||||
"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",
|
||||
"undefined escape, printing literally",
|
||||
"undefined string, using \"\"",
|
||||
|
||||
/* related to tables */
|
||||
"tbl line starts with span",
|
||||
"tbl column starts with span",
|
||||
"skipping vertical bar in tbl layout",
|
||||
|
||||
"generic error",
|
||||
|
||||
/* related to tables */
|
||||
"non-alphabetic character in tbl options",
|
||||
"skipping unknown tbl option",
|
||||
"missing tbl option argument",
|
||||
"wrong tbl option argument size",
|
||||
"empty tbl layout",
|
||||
"invalid character in tbl layout",
|
||||
"unmatched parenthesis in tbl layout",
|
||||
"tbl without any data cells",
|
||||
"ignoring data in spanned tbl cell",
|
||||
"ignoring extra tbl data cells",
|
||||
"data block open at end of tbl",
|
||||
|
||||
/* related to document structure and macros */
|
||||
NULL,
|
||||
"duplicate prologue macro",
|
||||
"skipping late title macro",
|
||||
"input stack limit exceeded, infinite loop?",
|
||||
"skipping bad character",
|
||||
"skipping unknown macro",
|
||||
"ignoring request outside macro",
|
||||
"skipping insecure request",
|
||||
"skipping item outside list",
|
||||
"skipping column outside column list",
|
||||
"skipping end of block that is not open",
|
||||
"fewer RS blocks open, skipping",
|
||||
"inserting missing end of block",
|
||||
"appending missing end of block",
|
||||
|
||||
/* related to request and macro arguments */
|
||||
"escaped character not allowed in a name",
|
||||
"using macro argument outside macro",
|
||||
"argument number is not numeric",
|
||||
"NOT IMPLEMENTED: Bd -file",
|
||||
"skipping display without arguments",
|
||||
"missing list type, using -item",
|
||||
"argument is not numeric, using 1",
|
||||
"argument is not a character",
|
||||
"missing manual name, using \"\"",
|
||||
"uname(3) system call failed, using UNKNOWN",
|
||||
"unknown standard specifier",
|
||||
"skipping request without numeric argument",
|
||||
"excessive shift",
|
||||
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
||||
".so request failed",
|
||||
"skipping all arguments",
|
||||
"skipping excess arguments",
|
||||
"divide by zero",
|
||||
|
||||
"unsupported feature",
|
||||
"input too large",
|
||||
"unsupported control character",
|
||||
"unsupported escape sequence",
|
||||
"unsupported roff request",
|
||||
"nested .while loops",
|
||||
"end of scope with open .while loop",
|
||||
"end of .while loop in inner scope",
|
||||
"cannot continue this .while loop",
|
||||
"eqn delim option in tbl",
|
||||
"unsupported tbl layout modifier",
|
||||
"ignoring macro in table",
|
||||
};
|
||||
|
||||
static FILE *fileptr = NULL;
|
||||
static const char *filename = NULL;
|
||||
static enum mandocerr min_type = MANDOCERR_MAX;
|
||||
static enum mandoclevel rc = MANDOCLEVEL_OK;
|
||||
|
||||
|
||||
void
|
||||
mandoc_msg_setoutfile(FILE *fp)
|
||||
{
|
||||
fileptr = fp;
|
||||
}
|
||||
|
||||
const char *
|
||||
mandoc_msg_getinfilename(void)
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_msg_setinfilename(const char *fn)
|
||||
{
|
||||
filename = fn;
|
||||
}
|
||||
|
||||
enum mandocerr
|
||||
mandoc_msg_getmin(void)
|
||||
{
|
||||
return min_type;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_msg_setmin(enum mandocerr t)
|
||||
{
|
||||
min_type = t;
|
||||
}
|
||||
|
||||
enum mandoclevel
|
||||
mandoc_msg_getrc(void)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_msg_setrc(enum mandoclevel level)
|
||||
{
|
||||
if (rc < level)
|
||||
rc = level;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_msg(enum mandocerr t, int line, int col, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
enum mandoclevel level;
|
||||
|
||||
if (t < min_type && t != MANDOCERR_FILE)
|
||||
return;
|
||||
|
||||
level = MANDOCLEVEL_UNSUPP;
|
||||
while (t < lowest_type[level])
|
||||
level--;
|
||||
mandoc_msg_setrc(level);
|
||||
|
||||
if (fileptr == NULL)
|
||||
return;
|
||||
|
||||
fprintf(fileptr, "%s:", getprogname());
|
||||
if (filename != NULL)
|
||||
fprintf(fileptr, " %s:", filename);
|
||||
|
||||
if (line > 0)
|
||||
fprintf(fileptr, "%d:%d:", line, col + 1);
|
||||
|
||||
fprintf(fileptr, " %s", level_name[level]);
|
||||
if (type_message[t] != NULL)
|
||||
fprintf(fileptr, ": %s", type_message[t]);
|
||||
|
||||
if (fmt != NULL) {
|
||||
fprintf(fileptr, ": ");
|
||||
va_start(ap, fmt);
|
||||
vfprintf(fileptr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
fputc('\n', fileptr);
|
||||
}
|
43
contrib/mandoc/mandoc_parse.h
Normal file
43
contrib/mandoc/mandoc_parse.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* $Id: mandoc_parse.h,v 1.4 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014,2015,2016,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
|
||||
* 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.
|
||||
*
|
||||
* Top level parser interface. For use in the main program
|
||||
* and in the main parser, but not in formatters.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parse options.
|
||||
*/
|
||||
#define MPARSE_MDOC (1 << 0) /* assume -mdoc */
|
||||
#define MPARSE_MAN (1 << 1) /* assume -man */
|
||||
#define MPARSE_SO (1 << 2) /* honour .so requests */
|
||||
#define MPARSE_QUICK (1 << 3) /* abort the parse early */
|
||||
#define MPARSE_UTF8 (1 << 4) /* accept UTF-8 input */
|
||||
#define MPARSE_LATIN1 (1 << 5) /* accept ISO-LATIN-1 input */
|
||||
#define MPARSE_VALIDATE (1 << 6) /* call validation functions */
|
||||
|
||||
|
||||
struct roff_meta;
|
||||
struct mparse;
|
||||
|
||||
struct mparse *mparse_alloc(int, enum mandoc_os, const char *);
|
||||
void mparse_copy(const struct mparse *);
|
||||
void mparse_free(struct mparse *);
|
||||
int mparse_open(struct mparse *, const char *);
|
||||
void mparse_readfd(struct mparse *, int, const char *);
|
||||
void mparse_reset(struct mparse *);
|
||||
struct roff_meta *mparse_result(struct mparse *);
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mandocd.c,v 1.6 2017/06/24 14:38:32 schwarze Exp $ */
|
||||
/* $Id: mandocd.c,v 1.11 2019/03/03 13:02:11 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 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
|
||||
@ -38,6 +38,7 @@
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "mandoc_parse.h"
|
||||
#include "main.h"
|
||||
#include "manconf.h"
|
||||
|
||||
@ -170,8 +171,8 @@ main(int argc, char *argv[])
|
||||
errx(1, "file descriptor %s %s", argv[1], errstr);
|
||||
|
||||
mchars_alloc();
|
||||
parser = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1,
|
||||
MANDOCERR_MAX, NULL, MANDOC_OS_OTHER, defos);
|
||||
parser = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1 |
|
||||
MPARSE_VALIDATE, MANDOC_OS_OTHER, defos);
|
||||
|
||||
memset(&options, 0, sizeof(options));
|
||||
switch (outtype) {
|
||||
@ -212,6 +213,8 @@ main(int argc, char *argv[])
|
||||
|
||||
process(parser, outtype, formatter);
|
||||
mparse_reset(parser);
|
||||
if (outtype == OUTT_HTML)
|
||||
html_reset(formatter);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
@ -243,35 +246,29 @@ main(int argc, char *argv[])
|
||||
static void
|
||||
process(struct mparse *parser, enum outt outtype, void *formatter)
|
||||
{
|
||||
struct roff_man *man;
|
||||
struct roff_meta *meta;
|
||||
|
||||
mparse_readfd(parser, STDIN_FILENO, "<unixfd>");
|
||||
mparse_result(parser, &man, NULL);
|
||||
|
||||
if (man == NULL)
|
||||
return;
|
||||
|
||||
if (man->macroset == MACROSET_MDOC) {
|
||||
mdoc_validate(man);
|
||||
meta = mparse_result(parser);
|
||||
if (meta->macroset == MACROSET_MDOC) {
|
||||
switch (outtype) {
|
||||
case OUTT_ASCII:
|
||||
case OUTT_UTF8:
|
||||
terminal_mdoc(formatter, man);
|
||||
terminal_mdoc(formatter, meta);
|
||||
break;
|
||||
case OUTT_HTML:
|
||||
html_mdoc(formatter, man);
|
||||
html_mdoc(formatter, meta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (man->macroset == MACROSET_MAN) {
|
||||
man_validate(man);
|
||||
if (meta->macroset == MACROSET_MAN) {
|
||||
switch (outtype) {
|
||||
case OUTT_ASCII:
|
||||
case OUTT_UTF8:
|
||||
terminal_man(formatter, man);
|
||||
terminal_man(formatter, meta);
|
||||
break;
|
||||
case OUTT_HTML:
|
||||
html_man(formatter, man);
|
||||
html_man(formatter, meta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mandocdb.c,v 1.258 2018/02/23 18:25:57 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.262 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -52,6 +52,7 @@
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "mandoc_parse.h"
|
||||
#include "manconf.h"
|
||||
#include "mansearch.h"
|
||||
#include "dba_array.h"
|
||||
@ -185,7 +186,7 @@ static struct ohash names; /* table of all names */
|
||||
static struct ohash strings; /* table of all strings */
|
||||
static uint64_t name_mask;
|
||||
|
||||
static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = {
|
||||
static const struct mdoc_handler mdoc_handlers[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, 0, NODE_NOPRT }, /* Dd */
|
||||
{ NULL, 0, NODE_NOPRT }, /* Dt */
|
||||
{ NULL, 0, NODE_NOPRT }, /* Os */
|
||||
@ -307,7 +308,6 @@ static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, 0, 0 }, /* %U */
|
||||
{ NULL, 0, 0 }, /* Ta */
|
||||
};
|
||||
static const struct mdoc_handler *const mdocs = __mdocs - MDOC_Dd;
|
||||
|
||||
|
||||
int
|
||||
@ -347,6 +347,7 @@ mandocdb(int argc, char *argv[])
|
||||
goto usage; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
mparse_options = MPARSE_VALIDATE;
|
||||
path_arg = NULL;
|
||||
op = OP_DEFAULT;
|
||||
|
||||
@ -422,8 +423,7 @@ mandocdb(int argc, char *argv[])
|
||||
|
||||
exitcode = (int)MANDOCLEVEL_OK;
|
||||
mchars_alloc();
|
||||
mp = mparse_alloc(mparse_options, MANDOCERR_MAX, NULL,
|
||||
MANDOC_OS_OTHER, NULL);
|
||||
mp = mparse_alloc(mparse_options, MANDOC_OS_OTHER, NULL);
|
||||
mandoc_ohash_init(&mpages, 6, offsetof(struct mpage, inodev));
|
||||
mandoc_ohash_init(&mlinks, 6, offsetof(struct mlink, file));
|
||||
|
||||
@ -1116,8 +1116,7 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
{
|
||||
struct mpage *mpage, *mpage_dest;
|
||||
struct mlink *mlink, *mlink_dest;
|
||||
struct roff_man *man;
|
||||
char *sodest;
|
||||
struct roff_meta *meta;
|
||||
char *cp;
|
||||
int fd;
|
||||
|
||||
@ -1130,8 +1129,7 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
mandoc_ohash_init(&names, 4, offsetof(struct str, key));
|
||||
mandoc_ohash_init(&strings, 6, offsetof(struct str, key));
|
||||
mparse_reset(mp);
|
||||
man = NULL;
|
||||
sodest = NULL;
|
||||
meta = NULL;
|
||||
|
||||
if ((fd = mparse_open(mp, mlink->file)) == -1) {
|
||||
say(mlink->file, "&open");
|
||||
@ -1146,14 +1144,14 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
mparse_readfd(mp, fd, mlink->file);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
mparse_result(mp, &man, &sodest);
|
||||
meta = mparse_result(mp);
|
||||
}
|
||||
|
||||
if (sodest != NULL) {
|
||||
if (meta != NULL && meta->sodest != NULL) {
|
||||
mlink_dest = ohash_find(&mlinks,
|
||||
ohash_qlookup(&mlinks, sodest));
|
||||
ohash_qlookup(&mlinks, meta->sodest));
|
||||
if (mlink_dest == NULL) {
|
||||
mandoc_asprintf(&cp, "%s.gz", sodest);
|
||||
mandoc_asprintf(&cp, "%s.gz", meta->sodest);
|
||||
mlink_dest = ohash_find(&mlinks,
|
||||
ohash_qlookup(&mlinks, cp));
|
||||
free(cp);
|
||||
@ -1190,39 +1188,36 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
mpage->mlinks = NULL;
|
||||
}
|
||||
goto nextpage;
|
||||
} else if (man != NULL && man->macroset == MACROSET_MDOC) {
|
||||
mdoc_validate(man);
|
||||
} else if (meta != NULL && meta->macroset == MACROSET_MDOC) {
|
||||
mpage->form = FORM_SRC;
|
||||
mpage->sec = man->meta.msec;
|
||||
mpage->sec = meta->msec;
|
||||
mpage->sec = mandoc_strdup(
|
||||
mpage->sec == NULL ? "" : mpage->sec);
|
||||
mpage->arch = man->meta.arch;
|
||||
mpage->arch = meta->arch;
|
||||
mpage->arch = mandoc_strdup(
|
||||
mpage->arch == NULL ? "" : mpage->arch);
|
||||
mpage->title = mandoc_strdup(man->meta.title);
|
||||
} else if (man != NULL && man->macroset == MACROSET_MAN) {
|
||||
man_validate(man);
|
||||
if (*man->meta.msec != '\0' ||
|
||||
*man->meta.title != '\0') {
|
||||
mpage->title = mandoc_strdup(meta->title);
|
||||
} else if (meta != NULL && meta->macroset == MACROSET_MAN) {
|
||||
if (*meta->msec != '\0' || *meta->title != '\0') {
|
||||
mpage->form = FORM_SRC;
|
||||
mpage->sec = mandoc_strdup(man->meta.msec);
|
||||
mpage->sec = mandoc_strdup(meta->msec);
|
||||
mpage->arch = mandoc_strdup(mlink->arch);
|
||||
mpage->title = mandoc_strdup(man->meta.title);
|
||||
mpage->title = mandoc_strdup(meta->title);
|
||||
} else
|
||||
man = NULL;
|
||||
meta = NULL;
|
||||
}
|
||||
|
||||
assert(mpage->desc == NULL);
|
||||
if (man == NULL) {
|
||||
if (meta == NULL) {
|
||||
mpage->form = FORM_CAT;
|
||||
mpage->sec = mandoc_strdup(mlink->dsec);
|
||||
mpage->arch = mandoc_strdup(mlink->arch);
|
||||
mpage->title = mandoc_strdup(mlink->name);
|
||||
parse_cat(mpage, fd);
|
||||
} else if (man->macroset == MACROSET_MDOC)
|
||||
parse_mdoc(mpage, &man->meta, man->first);
|
||||
} else if (meta->macroset == MACROSET_MDOC)
|
||||
parse_mdoc(mpage, meta, meta->first);
|
||||
else
|
||||
parse_man(mpage, &man->meta, man->first);
|
||||
parse_man(mpage, meta, meta->first);
|
||||
if (mpage->desc == NULL) {
|
||||
mpage->desc = mandoc_strdup(mlink->name);
|
||||
if (warnings)
|
||||
@ -1546,25 +1541,28 @@ static void
|
||||
parse_mdoc(struct mpage *mpage, const struct roff_meta *meta,
|
||||
const struct roff_node *n)
|
||||
{
|
||||
const struct mdoc_handler *handler;
|
||||
|
||||
for (n = n->child; n != NULL; n = n->next) {
|
||||
if (n->tok == TOKEN_NONE ||
|
||||
n->tok < ROFF_MAX ||
|
||||
n->flags & mdocs[n->tok].taboo)
|
||||
if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
|
||||
continue;
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
handler = mdoc_handlers + (n->tok - MDOC_Dd);
|
||||
if (n->flags & handler->taboo)
|
||||
continue;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_ELEM:
|
||||
case ROFFT_BLOCK:
|
||||
case ROFFT_HEAD:
|
||||
case ROFFT_BODY:
|
||||
case ROFFT_TAIL:
|
||||
if (mdocs[n->tok].fp != NULL &&
|
||||
(*mdocs[n->tok].fp)(mpage, meta, n) == 0)
|
||||
if (handler->fp != NULL &&
|
||||
(*handler->fp)(mpage, meta, n) == 0)
|
||||
break;
|
||||
if (mdocs[n->tok].mask)
|
||||
if (handler->mask)
|
||||
putmdockey(mpage, n->child,
|
||||
mdocs[n->tok].mask, mdocs[n->tok].taboo);
|
||||
handler->mask, handler->taboo);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* $Id: manpath.c,v 1.35 2017/07/01 09:47:30 schwarze Exp $ */
|
||||
/* $Id: manpath.c,v 1.37 2018/11/22 11:30:23 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -232,8 +232,8 @@ int
|
||||
manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
{
|
||||
const char *const toks[] = {
|
||||
"includes", "man", "paper", "style",
|
||||
"indent", "width", "fragment", "mdoc", "noval"
|
||||
"includes", "man", "paper", "style", "indent", "width",
|
||||
"tag", "fragment", "mdoc", "noval", "toc"
|
||||
};
|
||||
|
||||
const char *errstr;
|
||||
@ -257,7 +257,7 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
warnx("-O %s=?: Missing argument value", toks[tok]);
|
||||
return -1;
|
||||
}
|
||||
if ((tok == 6 || tok == 7) && *cp != '\0') {
|
||||
if (tok > 6 && *cp != '\0') {
|
||||
warnx("-O %s: Does not take a value: %s", toks[tok], cp);
|
||||
return -1;
|
||||
}
|
||||
@ -312,14 +312,24 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
warnx("-O width=%s is %s", cp, errstr);
|
||||
return -1;
|
||||
case 6:
|
||||
conf->fragment = 1;
|
||||
if (conf->tag != NULL) {
|
||||
oldval = mandoc_strdup(conf->tag);
|
||||
break;
|
||||
}
|
||||
conf->tag = mandoc_strdup(cp);
|
||||
return 0;
|
||||
case 7:
|
||||
conf->mdoc = 1;
|
||||
conf->fragment = 1;
|
||||
return 0;
|
||||
case 8:
|
||||
conf->mdoc = 1;
|
||||
return 0;
|
||||
case 9:
|
||||
conf->noval = 1;
|
||||
return 0;
|
||||
case 10:
|
||||
conf->toc = 1;
|
||||
return 0;
|
||||
default:
|
||||
if (fromfile)
|
||||
warnx("-O %s: Bad argument", cp);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mansearch.c,v 1.77 2017/08/22 17:50:11 schwarze Exp $ */
|
||||
/* $Id: mansearch.c,v 1.80 2018/12/13 11:55:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013-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
|
||||
@ -36,7 +36,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "manconf.h"
|
||||
@ -201,7 +200,6 @@ mansearch(const struct mansearch *search,
|
||||
mpage->names = buildnames(page);
|
||||
mpage->output = buildoutput(outkey, page);
|
||||
mpage->ipath = i;
|
||||
mpage->bits = rp->bits;
|
||||
mpage->sec = *page->sect - '0';
|
||||
if (mpage->sec < 0 || mpage->sec > 9)
|
||||
mpage->sec = 10;
|
||||
@ -296,10 +294,8 @@ manmerge_term(struct expr *e, struct ohash *htab)
|
||||
break;
|
||||
slot = ohash_lookup_memory(htab,
|
||||
(char *)&res, sizeof(res.page), res.page);
|
||||
if ((rp = ohash_find(htab, slot)) != NULL) {
|
||||
rp->bits |= res.bits;
|
||||
if ((rp = ohash_find(htab, slot)) != NULL)
|
||||
continue;
|
||||
}
|
||||
rp = mandoc_malloc(sizeof(*rp));
|
||||
*rp = res;
|
||||
ohash_insert(htab, slot, rp);
|
||||
@ -412,8 +408,7 @@ manpage_compare(const void *vp1, const void *vp2)
|
||||
|
||||
mp1 = vp1;
|
||||
mp2 = vp2;
|
||||
if ((diff = mp2->bits - mp1->bits) ||
|
||||
(diff = mp1->sec - mp2->sec))
|
||||
if ((diff = mp1->sec - mp2->sec))
|
||||
return diff;
|
||||
|
||||
/* Fall back to alphabetic ordering of names. */
|
||||
@ -774,8 +769,9 @@ exprterm(const struct mansearch *search, int argc, char *argv[], int *argi)
|
||||
cs = 0;
|
||||
} else if ((val = strpbrk(argv[*argi], "=~")) == NULL) {
|
||||
e->bits = TYPE_Nm | TYPE_Nd;
|
||||
e->match.type = DBM_SUB;
|
||||
e->match.str = argv[*argi];
|
||||
e->match.type = DBM_REGEX;
|
||||
val = argv[*argi];
|
||||
cs = 0;
|
||||
} else {
|
||||
if (val == argv[*argi])
|
||||
e->bits = TYPE_Nm | TYPE_Nd;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mansearch.h,v 1.28 2017/04/17 20:05:08 schwarze Exp $ */
|
||||
/* $Id: mansearch.h,v 1.29 2018/11/22 12:01:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -93,7 +93,6 @@ struct manpage {
|
||||
char *names; /* a list of names with sections */
|
||||
char *output; /* user-defined additional output */
|
||||
size_t ipath; /* number of the manpath */
|
||||
uint64_t bits; /* name type mask */
|
||||
int sec; /* section number, 10 means invalid */
|
||||
enum form form;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc.c,v 1.268 2017/08/11 16:56:21 schwarze Exp $ */
|
||||
/* $Id: mdoc.c,v 1.274 2018/12/31 07:46:07 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -79,13 +79,6 @@ mdoc_parseln(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
mdoc_ptext(mdoc, ln, buf, offs);
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_macro(MACRO_PROT_ARGS)
|
||||
{
|
||||
assert(tok >= MDOC_Dd && tok < MDOC_MAX);
|
||||
(*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf);
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, enum roff_tok tok)
|
||||
{
|
||||
@ -162,15 +155,6 @@ mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos,
|
||||
mdoc->next = ROFF_NEXT_CHILD;
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_node_relink(struct roff_man *mdoc, struct roff_node *p)
|
||||
{
|
||||
|
||||
roff_node_unlink(mdoc, p);
|
||||
p->prev = p->next = NULL;
|
||||
roff_node_append(mdoc, p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse free-form text, that is, a line that does not begin with the
|
||||
* control character.
|
||||
@ -196,7 +180,8 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
(n->parent != NULL && n->parent->tok == MDOC_Bl &&
|
||||
n->parent->norm->Bl.type == LIST_column)) {
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
|
||||
(*mdoc_macro(MDOC_It)->fp)(mdoc, MDOC_It,
|
||||
line, offs, &offs, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -225,7 +210,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
* Strip trailing tabs in literal context only;
|
||||
* outside, they affect the next line.
|
||||
*/
|
||||
if (MDOC_LITERAL & mdoc->flags)
|
||||
if (mdoc->flags & ROFF_NOFILL)
|
||||
continue;
|
||||
break;
|
||||
case '\\':
|
||||
@ -242,8 +227,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
*end = '\0';
|
||||
|
||||
if (ws)
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||
line, (int)(ws-buf), NULL);
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, line, (int)(ws - buf), NULL);
|
||||
|
||||
/*
|
||||
* Blank lines are allowed in no-fill mode
|
||||
@ -251,7 +235,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
* but add a single vertical space elsewhere.
|
||||
*/
|
||||
|
||||
if (buf[offs] == '\0' && ! (mdoc->flags & MDOC_LITERAL)) {
|
||||
if (buf[offs] == '\0' && (mdoc->flags & ROFF_NOFILL) == 0) {
|
||||
switch (mdoc->last->type) {
|
||||
case ROFFT_TEXT:
|
||||
sp = mdoc->last->string;
|
||||
@ -267,8 +251,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse,
|
||||
line, (int)(c - buf), NULL);
|
||||
mandoc_msg(MANDOCERR_FI_BLANK, line, (int)(c - buf), NULL);
|
||||
roff_elem_alloc(mdoc, line, offs, ROFF_sp);
|
||||
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
@ -277,7 +260,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
|
||||
roff_word_alloc(mdoc, line, offs, buf+offs);
|
||||
|
||||
if (mdoc->flags & MDOC_LITERAL)
|
||||
if (mdoc->flags & ROFF_NOFILL)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
@ -308,8 +291,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
if (*c == ' ')
|
||||
c++;
|
||||
if (isupper((unsigned char)(*c)))
|
||||
mandoc_msg(MANDOCERR_EOS, mdoc->parse,
|
||||
line, (int)(c - buf), NULL);
|
||||
mandoc_msg(MANDOCERR_EOS, line, (int)(c - buf), NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -337,8 +319,7 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
if (sz == 2 || sz == 3)
|
||||
tok = roffhash_find(mdoc->mdocmac, buf + sv, sz);
|
||||
if (tok == TOKEN_NONE) {
|
||||
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
|
||||
ln, sv, buf + sv - 1);
|
||||
mandoc_msg(MANDOCERR_MACRO, ln, sv, "%s", buf + sv - 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -368,8 +349,7 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
*/
|
||||
|
||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||
ln, offs - 1, NULL);
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, ln, offs - 1, NULL);
|
||||
|
||||
/*
|
||||
* If an initial macro or a list invocation, divert directly
|
||||
@ -378,7 +358,7 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
|
||||
n = mdoc->last;
|
||||
if (n == NULL || tok == MDOC_It || tok == MDOC_El) {
|
||||
mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
|
||||
(*mdoc_macro(tok)->fp)(mdoc, tok, ln, sv, &offs, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -394,13 +374,13 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
(n->parent != NULL && n->parent->tok == MDOC_Bl &&
|
||||
n->parent->norm->Bl.type == LIST_column)) {
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
|
||||
(*mdoc_macro(MDOC_It)->fp)(mdoc, MDOC_It, ln, sv, &sv, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Normal processing of a macro. */
|
||||
|
||||
mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
|
||||
(*mdoc_macro(tok)->fp)(mdoc, tok, ln, sv, &offs, buf);
|
||||
|
||||
/* In quick mode (for mandocdb), abort after the NAME section. */
|
||||
|
||||
@ -448,12 +428,3 @@ mdoc_isdelim(const char *p)
|
||||
|
||||
return DELIM_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_validate(struct roff_man *mdoc)
|
||||
{
|
||||
|
||||
mdoc->last = mdoc->first;
|
||||
mdoc_node_validate(mdoc);
|
||||
mdoc_state_reset(mdoc);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc.h,v 1.145 2017/04/24 23:06:18 schwarze Exp $ */
|
||||
/* $Id: mdoc.h,v 1.146 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,6 +16,9 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct roff_node;
|
||||
struct roff_man;
|
||||
|
||||
enum mdocargt {
|
||||
MDOC_Split, /* -split */
|
||||
MDOC_Nosplit, /* -nospli */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user