external/bsd/mdocml: Update
Change-Id: I17b54e52e8322676d83ed4386f586f8ef3029f72
This commit is contained in:
parent
ff68abe6b3
commit
92395e9c3f
115 changed files with 19705 additions and 8226 deletions
|
@ -1180,8 +1180,8 @@
|
|||
./usr/include/minix/hgfs.h minix-sys
|
||||
./usr/include/minix/i2cdriver.h minix-sys
|
||||
./usr/include/minix/i2c.h minix-sys
|
||||
./usr/include/minix/input.h minix-sys
|
||||
./usr/include/minix/inputdriver.h minix-sys
|
||||
./usr/include/minix/input.h minix-sys
|
||||
./usr/include/minix/ioctl.h minix-sys
|
||||
./usr/include/minix/ipcconst.h minix-sys
|
||||
./usr/include/minix/ipc.h minix-sys
|
||||
|
@ -2215,8 +2215,8 @@
|
|||
./usr/man/man2/FD_ISSET.2 minix-sys
|
||||
./usr/man/man2/FD_SET.2 minix-sys
|
||||
./usr/man/man2/fork.2 minix-sys
|
||||
./usr/man/man2/fstatvfs.2 minix-sys
|
||||
./usr/man/man2/fstatvfs1.2 minix-sys
|
||||
./usr/man/man2/fstatvfs.2 minix-sys
|
||||
./usr/man/man2/getgid.2 minix-sys
|
||||
./usr/man/man2/getitimer.2 minix-sys
|
||||
./usr/man/man2/getnucred.2 minix-sys
|
||||
|
@ -2268,8 +2268,8 @@
|
|||
./usr/man/man2/sigsuspend.2 minix-sys
|
||||
./usr/man/man2/socket.2 minix-sys
|
||||
./usr/man/man2/socketpair.2 minix-sys
|
||||
./usr/man/man2/statvfs.2 minix-sys
|
||||
./usr/man/man2/statvfs1.2 minix-sys
|
||||
./usr/man/man2/statvfs.2 minix-sys
|
||||
./usr/man/man2/svrctl.2 minix-sys
|
||||
./usr/man/man2/symlink.2 minix-sys
|
||||
./usr/man/man2/sync.2 minix-sys
|
||||
|
@ -3423,9 +3423,9 @@
|
|||
./usr/man/man3/libarchive_internals.3 minix-sys
|
||||
./usr/man/man3/libmagic.3 minix-sys
|
||||
./usr/man/man3/link_addr.3 minix-sys
|
||||
./usr/man/man3/linkaddr.3 minix-sys
|
||||
./usr/man/man3/link_field.3 minix-sys
|
||||
./usr/man/man3/link_fieldtype.3 minix-sys
|
||||
./usr/man/man3/linkaddr.3 minix-sys
|
||||
./usr/man/man3/link_ntoa.3 minix-sys
|
||||
./usr/man/man3/linkntoa.3 minix-sys
|
||||
./usr/man/man3/llabs.3 minix-sys
|
||||
|
@ -3482,7 +3482,7 @@
|
|||
./usr/man/man3/magic_setflags.3 minix-sys
|
||||
./usr/man/man3/makecontext.3 minix-sys
|
||||
./usr/man/man3/malloc.3 minix-sys
|
||||
./usr/man/man3/man.3 minix-sys
|
||||
./usr/man/man3/mandoc.3 minix-sys
|
||||
./usr/man/man3/math.3 minix-sys
|
||||
./usr/man/man3/mblen.3 minix-sys
|
||||
./usr/man/man3/mbrlen.3 minix-sys
|
||||
|
@ -3514,7 +3514,6 @@
|
|||
./usr/man/man3/MD5Final.3 minix-sys
|
||||
./usr/man/man3/MD5Init.3 minix-sys
|
||||
./usr/man/man3/MD5Update.3 minix-sys
|
||||
./usr/man/man3/mdoc.3 minix-sys
|
||||
./usr/man/man3/membar_consumer.3 minix-sys
|
||||
./usr/man/man3/membar_enter.3 minix-sys
|
||||
./usr/man/man3/membar_exit.3 minix-sys
|
||||
|
@ -4617,6 +4616,7 @@
|
|||
./usr/man/man7/kyua-test-filters.7 minix-sys kyua
|
||||
./usr/man/man7/man.7 minix-sys
|
||||
./usr/man/man7/mandoc_char.7 minix-sys
|
||||
./usr/man/man7/mandoc_eqn.7 minix-sys
|
||||
./usr/man/man7/mandoc_man.7 minix-sys
|
||||
./usr/man/man7/mandoc_mdoc.7 minix-sys
|
||||
./usr/man/man7/mandoc_roff.7 minix-sys
|
||||
|
@ -4768,8 +4768,8 @@
|
|||
./usr/sbin/vipw minix-sys
|
||||
./usr/sbin/vm minix-sys
|
||||
./usr/sbin/vnconfig minix-sys
|
||||
./usr/sbin/vndconfig minix-sys
|
||||
./usr/sbin/vnd minix-sys
|
||||
./usr/sbin/vndconfig minix-sys
|
||||
./usr/sbin/zic minix-sys
|
||||
./usr/share minix-sys
|
||||
./usr/share/atf minix-sys atf
|
||||
|
@ -5575,6 +5575,12 @@
|
|||
./usr/tests/lib/libpthread/dlopen minix-sys atf
|
||||
./usr/tests/libexec/Atffile minix-sys atf
|
||||
./usr/tests/minix-posix minix-sys
|
||||
./usr/tests/minix-posix/blocktest minix-sys
|
||||
./usr/tests/minix-posix/blocktest/blocktest minix-sys
|
||||
./usr/tests/minix-posix/blocktest/README minix-sys
|
||||
./usr/tests/minix-posix/blocktest/support.sh minix-sys
|
||||
./usr/tests/minix-posix/blocktest/system.conf minix-sys
|
||||
./usr/tests/minix-posix/blocktest/test.sh minix-sys
|
||||
./usr/tests/minix-posix/run minix-sys
|
||||
./usr/tests/minix-posix/t10a minix-sys
|
||||
./usr/tests/minix-posix/t11a minix-sys
|
||||
|
@ -5674,12 +5680,6 @@
|
|||
./usr/tests/minix-posix/testvm.conf minix-sys
|
||||
./usr/tests/minix-posix/testvnd minix-sys
|
||||
./usr/tests/minix-posix/tvnd minix-sys
|
||||
./usr/tests/minix-posix/blocktest minix-sys
|
||||
./usr/tests/minix-posix/blocktest/README minix-sys
|
||||
./usr/tests/minix-posix/blocktest/blocktest minix-sys
|
||||
./usr/tests/minix-posix/blocktest/support.sh minix-sys
|
||||
./usr/tests/minix-posix/blocktest/system.conf minix-sys
|
||||
./usr/tests/minix-posix/blocktest/test.sh minix-sys
|
||||
./usr/tests/usr.bin/jot/Atffile minix-sys atf
|
||||
./usr/tests/usr.bin/jot/d_basic.out minix-sys atf
|
||||
./usr/tests/usr.bin/jot/t_jot minix-sys atf
|
||||
|
|
7
external/bsd/mdocml/Makefile.inc
vendored
7
external/bsd/mdocml/Makefile.inc
vendored
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.inc,v 1.12 2010/07/25 19:16:18 joerg Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.15 2012/02/16 22:56:12 joerg Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
|
@ -8,14 +8,15 @@ CPPFLAGS+= -DVERSION=\"${VERSION}\" -DUGLY
|
|||
CPPFLAGS+= -UOSNAME -DOSNAME=\"Minix\"
|
||||
|
||||
.if (${HOSTPROG:U} == "")
|
||||
CPPFLAGS+= -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRPTIME -DHAVE_MMAP
|
||||
# Minix mmap not yet up to the task
|
||||
CPPFLAGS+= -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRPTIME #-DHAVE_MMAP
|
||||
.endif
|
||||
|
||||
DISTDIR:= ${.PARSEDIR}/dist
|
||||
|
||||
.PATH: ${DISTDIR}
|
||||
|
||||
.for _LIB in man mdoc roff
|
||||
.for _LIB in mandoc
|
||||
MDOCMLOBJDIR.${_LIB} != cd ${.PARSEDIR}/lib/lib${_LIB} && ${PRINTOBJDIR}
|
||||
MDOCMLLIB.${_LIB}= ${MDOCMLOBJDIR.${_LIB}}/lib${_LIB}.a
|
||||
.endfor
|
||||
|
|
22
external/bsd/mdocml/bin/mandoc/Makefile
vendored
22
external/bsd/mdocml/bin/mandoc/Makefile
vendored
|
@ -1,24 +1,22 @@
|
|||
# $NetBSD: Makefile,v 1.4 2011/01/12 23:02:21 joerg Exp $
|
||||
# $NetBSD: Makefile,v 1.6 2011/10/11 19:20:13 joerg Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= mandoc
|
||||
|
||||
SRCS= main.c mdoc_term.c chars.c term.c term_ascii.c term_ps.c \
|
||||
tbl_term.c tbl_html.c tree.c compat.c \
|
||||
man_term.c html.c mdoc_html.c man_html.c out.c
|
||||
SRCS= chars.c main.c out.c tree.c \
|
||||
eqn_html.c eqn_term.c \
|
||||
html.c man_html.c mdoc_html.c tbl_html.c \
|
||||
man_term.c mdoc_term.c term.c term_ascii.c \
|
||||
term_ps.c tbl_term.c
|
||||
|
||||
.ifndef HOSTPROG
|
||||
DPADD+= ${MDOCMLLIB.man} ${MDOCMLLIB.mdoc} ${MDOCMLLIB.roff}
|
||||
LDADD+= -L${MDOCMLOBJDIR.man} -lman \
|
||||
-L${MDOCMLOBJDIR.mdoc} -lmdoc \
|
||||
-L${MDOCMLOBJDIR.roff} -lroff
|
||||
DPADD+= ${MDOCMLLIB.mandoc}
|
||||
LDADD+= -L${MDOCMLOBJDIR.mandoc} -lmandoc
|
||||
.else
|
||||
SRCS.libman!= cd ${.PARSEDIR}/../../lib/libman && ${MAKE} -V '$${SRCS}'
|
||||
SRCS.libmdoc!= cd ${.PARSEDIR}/../../lib/libmdoc && ${MAKE} -V '$${SRCS}'
|
||||
SRCS.libroff!= cd ${.PARSEDIR}/../../lib/libroff && ${MAKE} -V '$${SRCS}'
|
||||
SRCS.libmandoc!=cd ${.PARSEDIR}/../../lib/libmandoc && ${MAKE} -V '$${SRCS}'
|
||||
|
||||
SRCS+= ${SRCS.libman} ${SRCS.libmdoc:Nmandoc.c} ${SRCS.libroff}
|
||||
SRCS+= ${SRCS.libmandoc}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
811
external/bsd/mdocml/dist/Makefile
vendored
811
external/bsd/mdocml/dist/Makefile
vendored
|
@ -1,346 +1,643 @@
|
|||
.SUFFIXES: .html .xml .sgml .1 .3 .7 .md5 .tar.gz
|
||||
.SUFFIXES: .1.txt .3.txt .7.txt
|
||||
.SUFFIXES: .1.xhtml .3.xhtml .7.xhtml
|
||||
.SUFFIXES: .1.sgml .3.sgml .7.sgml
|
||||
.SUFFIXES: .h .h.html
|
||||
.SUFFIXES: .1.ps .3.ps .7.ps
|
||||
.SUFFIXES: .1.pdf .3.pdf .7.pdf
|
||||
.PHONY: clean install installwww
|
||||
.SUFFIXES: .sgml .html .md5 .h .h.html
|
||||
.SUFFIXES: .1 .3 .7 .8
|
||||
.SUFFIXES: .1.txt .3.txt .7.txt .8.txt
|
||||
.SUFFIXES: .1.pdf .3.pdf .7.pdf .8.pdf
|
||||
.SUFFIXES: .1.ps .3.ps .7.ps .8.ps
|
||||
.SUFFIXES: .1.html .3.html .7.html .8.html
|
||||
.SUFFIXES: .1.xhtml .3.xhtml .7.xhtml .8.xhtml
|
||||
|
||||
# Specify this if you want to hard-code the operating system to appear
|
||||
# in the lower-left hand corner of -mdoc manuals.
|
||||
#
|
||||
# CFLAGS += -DOSNAME="\"OpenBSD 4.5\""
|
||||
|
||||
VERSION = 1.12.0
|
||||
VDATE = 8 October 2011
|
||||
|
||||
# IFF your system supports multi-byte functions (setlocale(), wcwidth(),
|
||||
# putwchar()) AND has __STDC_ISO_10646__ (that is, wchar_t is simply a
|
||||
# UCS-4 value) should you define USE_WCHAR. If you define it and your
|
||||
# system DOESN'T support this, -Tlocale will produce garbage.
|
||||
# If you don't define it, -Tlocale is a synonym for -Tacsii.
|
||||
#
|
||||
CFLAGS += -DUSE_WCHAR
|
||||
|
||||
# If your system has manpath(1), uncomment this. This is most any
|
||||
# system that's not OpenBSD or NetBSD. If uncommented, apropos(1),
|
||||
# mandocdb(8), and man.cgi will popen(3) manpath(1) to get the MANPATH
|
||||
# variable.
|
||||
#CFLAGS += -DUSE_MANPATH
|
||||
|
||||
# If your system supports static binaries only, uncomment this. This
|
||||
# appears only to be BSD UNIX systems (Mac OS X has no support and Linux
|
||||
# requires -pthreads for static libdb).
|
||||
STATIC = -static
|
||||
|
||||
CFLAGS += -g -DHAVE_CONFIG_H -DVERSION="\"$(VERSION)\""
|
||||
CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings
|
||||
PREFIX = /usr/local
|
||||
WWWPREFIX = /var/www
|
||||
HTDOCDIR = $(WWWPREFIX)/htdocs
|
||||
CGIBINDIR = $(WWWPREFIX)/cgi-bin
|
||||
BINDIR = $(PREFIX)/bin
|
||||
INCLUDEDIR = $(PREFIX)/include
|
||||
LIBDIR = $(PREFIX)/lib
|
||||
INCLUDEDIR = $(PREFIX)/include/mandoc
|
||||
LIBDIR = $(PREFIX)/lib/mandoc
|
||||
MANDIR = $(PREFIX)/man
|
||||
EXAMPLEDIR = $(PREFIX)/share/examples/mandoc
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL) -m 0755
|
||||
INSTALL_DATA = $(INSTALL) -m 0444
|
||||
INSTALL_LIB = $(INSTALL) -m 0644
|
||||
INSTALL_SOURCE = $(INSTALL) -m 0644
|
||||
INSTALL_MAN = $(INSTALL_DATA)
|
||||
|
||||
VERSION = 1.10.9
|
||||
VDATE = 07 January 2010
|
||||
# Non-BSD systems (Linux, etc.) need -ldb to compile mandocdb and
|
||||
# apropos.
|
||||
# However, if you don't have -ldb at all (or it's not native), then
|
||||
# comment out apropos and mandocdb.
|
||||
#
|
||||
#DBLIB = -ldb
|
||||
DBBIN = apropos mandocdb man.cgi catman whatis
|
||||
DBLN = llib-lapropos.ln llib-lmandocdb.ln llib-lman.cgi.ln llib-lcatman.ln
|
||||
|
||||
VFLAGS = -DVERSION="\"$(VERSION)\""
|
||||
WFLAGS = -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings
|
||||
CFLAGS += -g $(WFLAGS) $(VFLAGS) -DHAVE_CONFIG_H
|
||||
all: mandoc preconv demandoc $(DBBIN)
|
||||
|
||||
# Specify this if you want to hard-code the operating system to appear
|
||||
# in the lower-left hand corner of -mdoc manuals.
|
||||
# CFLAGS += -DOSNAME="\"OpenBSD 4.5\""
|
||||
CFLAGS += -UOSNAME -DOSNAME="\"Minix\""
|
||||
SRCS = Makefile \
|
||||
TODO \
|
||||
apropos.1 \
|
||||
apropos.c \
|
||||
apropos_db.c \
|
||||
apropos_db.h \
|
||||
arch.c \
|
||||
arch.in \
|
||||
att.c \
|
||||
att.in \
|
||||
catman.8 \
|
||||
catman.c \
|
||||
cgi.c \
|
||||
chars.c \
|
||||
chars.in \
|
||||
compat_fgetln.c \
|
||||
compat_getsubopt.c \
|
||||
compat_strlcat.c \
|
||||
compat_strlcpy.c \
|
||||
config.h.post \
|
||||
config.h.pre \
|
||||
demandoc.1 \
|
||||
demandoc.c \
|
||||
eqn.7 \
|
||||
eqn.c \
|
||||
eqn_html.c \
|
||||
eqn_term.c \
|
||||
example.style.css \
|
||||
external.png \
|
||||
html.c \
|
||||
html.h \
|
||||
index.css \
|
||||
index.sgml \
|
||||
lib.c \
|
||||
lib.in \
|
||||
libman.h \
|
||||
libmandoc.h \
|
||||
libmdoc.h \
|
||||
libroff.h \
|
||||
main.c \
|
||||
main.h \
|
||||
man.7 \
|
||||
man.c \
|
||||
man.cgi.7 \
|
||||
man-cgi.css \
|
||||
man.h \
|
||||
man_hash.c \
|
||||
man_html.c \
|
||||
man_macro.c \
|
||||
man_term.c \
|
||||
man_validate.c \
|
||||
mandoc.1 \
|
||||
mandoc.3 \
|
||||
mandoc.c \
|
||||
mandoc.h \
|
||||
mandoc_char.7 \
|
||||
mandocdb.8 \
|
||||
mandocdb.c \
|
||||
mandocdb.h \
|
||||
manpath.c \
|
||||
manpath.h \
|
||||
mdoc.7 \
|
||||
mdoc.c \
|
||||
mdoc.h \
|
||||
mdoc_argv.c \
|
||||
mdoc_hash.c \
|
||||
mdoc_html.c \
|
||||
mdoc_macro.c \
|
||||
mdoc_man.c \
|
||||
mdoc_term.c \
|
||||
mdoc_validate.c \
|
||||
msec.c \
|
||||
msec.in \
|
||||
out.c \
|
||||
out.h \
|
||||
preconv.1 \
|
||||
preconv.c \
|
||||
predefs.in \
|
||||
read.c \
|
||||
regress \
|
||||
roff.7 \
|
||||
roff.c \
|
||||
st.c \
|
||||
st.in \
|
||||
style.css \
|
||||
tbl.7 \
|
||||
tbl.c \
|
||||
tbl_data.c \
|
||||
tbl_html.c \
|
||||
tbl_layout.c \
|
||||
tbl_opts.c \
|
||||
tbl_term.c \
|
||||
term.c \
|
||||
term.h \
|
||||
term_ascii.c \
|
||||
term_ps.c \
|
||||
test-fgetln.c \
|
||||
test-getsubopt.c \
|
||||
test-mmap.c \
|
||||
test-strlcat.c \
|
||||
test-strlcpy.c \
|
||||
test-strptime.c \
|
||||
tree.c \
|
||||
vol.c \
|
||||
vol.in \
|
||||
whatis.1
|
||||
|
||||
LINTFLAGS += $(VFLAGS)
|
||||
LIBMAN_OBJS = man.o \
|
||||
man_hash.o \
|
||||
man_macro.o \
|
||||
man_validate.o
|
||||
LIBMAN_LNS = man.ln \
|
||||
man_hash.ln \
|
||||
man_macro.ln \
|
||||
man_validate.ln
|
||||
|
||||
ROFFLNS = roff.ln tbl.ln tbl_opts.ln tbl_layout.ln tbl_data.ln
|
||||
LIBMDOC_OBJS = arch.o \
|
||||
att.o \
|
||||
lib.o \
|
||||
mdoc.o \
|
||||
mdoc_argv.o \
|
||||
mdoc_hash.o \
|
||||
mdoc_macro.o \
|
||||
mdoc_validate.o \
|
||||
st.o \
|
||||
vol.o
|
||||
LIBMDOC_LNS = arch.ln \
|
||||
att.ln \
|
||||
lib.ln \
|
||||
mdoc.ln \
|
||||
mdoc_argv.ln \
|
||||
mdoc_hash.ln \
|
||||
mdoc_macro.ln \
|
||||
mdoc_validate.ln \
|
||||
st.ln \
|
||||
vol.ln
|
||||
|
||||
ROFFSRCS = roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c
|
||||
LIBROFF_OBJS = eqn.o \
|
||||
roff.o \
|
||||
tbl.o \
|
||||
tbl_data.o \
|
||||
tbl_layout.o \
|
||||
tbl_opts.o
|
||||
LIBROFF_LNS = eqn.ln \
|
||||
roff.ln \
|
||||
tbl.ln \
|
||||
tbl_data.ln \
|
||||
tbl_layout.ln \
|
||||
tbl_opts.ln
|
||||
|
||||
ROFFOBJS = roff.o tbl.o tbl_opts.o tbl_layout.o tbl_data.o
|
||||
LIBMANDOC_OBJS = $(LIBMAN_OBJS) \
|
||||
$(LIBMDOC_OBJS) \
|
||||
$(LIBROFF_OBJS) \
|
||||
chars.o \
|
||||
mandoc.o \
|
||||
msec.o \
|
||||
read.o
|
||||
LIBMANDOC_LNS = $(LIBMAN_LNS) \
|
||||
$(LIBMDOC_LNS) \
|
||||
$(LIBROFF_LNS) \
|
||||
chars.ln \
|
||||
mandoc.ln \
|
||||
msec.ln \
|
||||
read.ln
|
||||
|
||||
MANDOCLNS = mandoc.ln
|
||||
COMPAT_OBJS = compat_fgetln.o \
|
||||
compat_getsubopt.o \
|
||||
compat_strlcat.o \
|
||||
compat_strlcpy.o
|
||||
COMPAT_LNS = compat_fgetln.ln \
|
||||
compat_getsubopt.ln \
|
||||
compat_strlcat.ln \
|
||||
compat_strlcpy.ln
|
||||
|
||||
MANDOCSRCS = mandoc.c
|
||||
arch.o arch.ln: arch.in
|
||||
att.o att.ln: att.in
|
||||
chars.o chars.ln: chars.in
|
||||
lib.o lib.ln: lib.in
|
||||
msec.o msec.ln: msec.in
|
||||
roff.o roff.ln: predefs.in
|
||||
st.o st.ln: st.in
|
||||
vol.o vol.ln: vol.in
|
||||
|
||||
MANDOCOBJS = mandoc.o
|
||||
$(LIBMAN_OBJS) $(LIBMAN_LNS): libman.h
|
||||
$(LIBMDOC_OBJS) $(LIBMDOC_LNS): libmdoc.h
|
||||
$(LIBROFF_OBJS) $(LIBROFF_LNS): libroff.h
|
||||
$(LIBMANDOC_OBJS) $(LIBMANDOC_LNS): mandoc.h mdoc.h man.h libmandoc.h config.h
|
||||
|
||||
MDOCLNS = mdoc_macro.ln mdoc.ln mdoc_hash.ln mdoc_strings.ln \
|
||||
mdoc_argv.ln mdoc_validate.ln \
|
||||
lib.ln att.ln arch.ln vol.ln msec.ln st.ln
|
||||
$(COMPAT_OBJS) $(COMPAT_LNS): config.h
|
||||
|
||||
MDOCOBJS = mdoc_macro.o mdoc.o mdoc_hash.o mdoc_strings.o \
|
||||
mdoc_argv.o mdoc_validate.o lib.o att.o \
|
||||
arch.o vol.o msec.o st.o
|
||||
MANDOC_HTML_OBJS = eqn_html.o \
|
||||
html.o \
|
||||
man_html.o \
|
||||
mdoc_html.o \
|
||||
tbl_html.o
|
||||
MANDOC_HTML_LNS = eqn_html.ln \
|
||||
html.ln \
|
||||
man_html.ln \
|
||||
mdoc_html.ln \
|
||||
tbl_html.ln
|
||||
|
||||
MDOCSRCS = mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \
|
||||
mdoc_argv.c mdoc_validate.c lib.c att.c \
|
||||
arch.c vol.c msec.c st.c
|
||||
MANDOC_MAN_OBJS = mdoc_man.o
|
||||
MANDOC_MAN_LNS = mdoc_man.ln
|
||||
|
||||
MANLNS = man_macro.ln man.ln man_hash.ln man_validate.ln \
|
||||
man_argv.ln
|
||||
MANDOC_TERM_OBJS = eqn_term.o \
|
||||
man_term.o \
|
||||
mdoc_term.o \
|
||||
term.o \
|
||||
term_ascii.o \
|
||||
term_ps.o \
|
||||
tbl_term.o
|
||||
MANDOC_TERM_LNS = eqn_term.ln \
|
||||
man_term.ln \
|
||||
mdoc_term.ln \
|
||||
term.ln \
|
||||
term_ascii.ln \
|
||||
term_ps.ln \
|
||||
tbl_term.ln
|
||||
|
||||
MANOBJS = man_macro.o man.o man_hash.o man_validate.o \
|
||||
man_argv.o
|
||||
MANSRCS = man_macro.c man.c man_hash.c man_validate.c \
|
||||
man_argv.c
|
||||
MANDOC_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
$(MANDOC_MAN_OBJS) \
|
||||
$(MANDOC_TERM_OBJS) \
|
||||
main.o \
|
||||
out.o \
|
||||
tree.o
|
||||
MANDOC_LNS = $(MANDOC_HTML_LNS) \
|
||||
$(MANDOC_MAN_LNS) \
|
||||
$(MANDOC_TERM_LNS) \
|
||||
main.ln \
|
||||
out.ln \
|
||||
tree.ln
|
||||
|
||||
MAINLNS = main.ln mdoc_term.ln chars.ln term.ln tree.ln \
|
||||
compat.ln man_term.ln html.ln mdoc_html.ln \
|
||||
man_html.ln out.ln term_ps.ln term_ascii.ln \
|
||||
tbl_term.ln tbl_html.ln
|
||||
$(MANDOC_HTML_OBJS) $(MANDOC_HTML_LNS): html.h
|
||||
$(MANDOC_TERM_OBJS) $(MANDOC_TERM_LNS): term.h
|
||||
$(MANDOC_OBJS) $(MANDOC_LNS): main.h mandoc.h mdoc.h man.h config.h out.h
|
||||
|
||||
MAINOBJS = main.o mdoc_term.o chars.o term.o tree.o compat.o \
|
||||
man_term.o html.o mdoc_html.o man_html.o out.o \
|
||||
term_ps.o term_ascii.o tbl_term.o tbl_html.o
|
||||
MANDOCDB_OBJS = mandocdb.o manpath.o
|
||||
MANDOCDB_LNS = mandocdb.ln manpath.ln
|
||||
|
||||
MAINSRCS = main.c mdoc_term.c chars.c term.c tree.c compat.c \
|
||||
man_term.c html.c mdoc_html.c man_html.c out.c \
|
||||
term_ps.c term_ascii.c tbl_term.c tbl_html.c
|
||||
$(MANDOCDB_OBJS) $(MANDOCDB_LNS): mandocdb.h mandoc.h mdoc.h man.h config.h manpath.h
|
||||
|
||||
LLNS = llib-llibmdoc.ln llib-llibman.ln llib-lmandoc.ln \
|
||||
llib-llibmandoc.ln llib-llibroff.ln
|
||||
PRECONV_OBJS = preconv.o
|
||||
PRECONV_LNS = preconv.ln
|
||||
|
||||
LNS = $(MAINLNS) $(MDOCLNS) $(MANLNS) \
|
||||
$(MANDOCLNS) $(ROFFLNS)
|
||||
$(PRECONV_OBJS) $(PRECONV_LNS): config.h
|
||||
|
||||
LIBS = libmdoc.a libman.a libmandoc.a libroff.a
|
||||
APROPOS_OBJS = apropos.o apropos_db.o manpath.o
|
||||
APROPOS_LNS = apropos.ln apropos_db.ln manpath.ln
|
||||
|
||||
OBJS = $(MDOCOBJS) $(MAINOBJS) $(MANOBJS) \
|
||||
$(MANDOCOBJS) $(ROFFOBJS)
|
||||
$(APROPOS_OBJS) $(APROPOS_LNS): config.h mandoc.h apropos_db.h manpath.h mandocdb.h
|
||||
|
||||
SRCS = $(MDOCSRCS) $(MAINSRCS) $(MANSRCS) \
|
||||
$(MANDOCSRCS) $(ROFFSRCS)
|
||||
CGI_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
$(MANDOC_MAN_OBJS) \
|
||||
$(MANDOC_TERM_OBJS) \
|
||||
cgi.o \
|
||||
apropos_db.o \
|
||||
manpath.o \
|
||||
out.o \
|
||||
tree.o
|
||||
|
||||
DATAS = arch.in att.in lib.in msec.in st.in \
|
||||
vol.in chars.in
|
||||
CGI_LNS = $(MANDOC_HTML_LNS) \
|
||||
$(MANDOC_MAN_LNS) \
|
||||
$(MANDOC_TERM_LNS) \
|
||||
cgi.ln \
|
||||
apropos_db.ln \
|
||||
manpath.ln \
|
||||
out.ln \
|
||||
tree.ln
|
||||
|
||||
HEADS = mdoc.h libmdoc.h man.h libman.h term.h \
|
||||
libmandoc.h html.h chars.h out.h main.h roff.h \
|
||||
mandoc.h libroff.h
|
||||
$(CGI_OBJS) $(CGI_LNS): main.h mdoc.h man.h out.h config.h mandoc.h apropos_db.h manpath.h mandocdb.h
|
||||
|
||||
GSGMLS = mandoc.1.sgml mdoc.3.sgml mdoc.7.sgml \
|
||||
mandoc_char.7.sgml man.7.sgml man.3.sgml roff.7.sgml \
|
||||
roff.3.sgml tbl.7.sgml
|
||||
CATMAN_OBJS = catman.o manpath.o
|
||||
CATMAN_LNS = catman.ln manpath.ln
|
||||
|
||||
SGMLS = index.sgml
|
||||
$(CATMAN_OBJS) $(CATMAN_LNS): config.h mandoc.h manpath.h mandocdb.h
|
||||
|
||||
XHTMLS = mandoc.1.xhtml mdoc.3.xhtml \
|
||||
man.3.xhtml mdoc.7.xhtml man.7.xhtml mandoc_char.7.xhtml \
|
||||
roff.7.xhtml roff.3.xhtml tbl.7.xhtml
|
||||
DEMANDOC_OBJS = demandoc.o
|
||||
DEMANDOC_LNS = demandoc.ln
|
||||
|
||||
HTMLS = ChangeLog.html index.html man.h.html mdoc.h.html \
|
||||
mandoc.h.html roff.h.html mandoc.1.html mdoc.3.html \
|
||||
man.3.html mdoc.7.html man.7.html mandoc_char.7.html \
|
||||
roff.7.html roff.3.html tbl.7.html
|
||||
$(DEMANDOC_OBJS) $(DEMANDOC_LNS): config.h
|
||||
|
||||
PSS = mandoc.1.ps mdoc.3.ps man.3.ps mdoc.7.ps man.7.ps \
|
||||
mandoc_char.7.ps roff.7.ps roff.3.ps tbl.7.ps
|
||||
INDEX_MANS = apropos.1.html \
|
||||
apropos.1.xhtml \
|
||||
apropos.1.ps \
|
||||
apropos.1.pdf \
|
||||
apropos.1.txt \
|
||||
catman.8.html \
|
||||
catman.8.xhtml \
|
||||
catman.8.ps \
|
||||
catman.8.pdf \
|
||||
catman.8.txt \
|
||||
demandoc.1.html \
|
||||
demandoc.1.xhtml \
|
||||
demandoc.1.ps \
|
||||
demandoc.1.pdf \
|
||||
demandoc.1.txt \
|
||||
mandoc.1.html \
|
||||
mandoc.1.xhtml \
|
||||
mandoc.1.ps \
|
||||
mandoc.1.pdf \
|
||||
mandoc.1.txt \
|
||||
whatis.1.html \
|
||||
whatis.1.xhtml \
|
||||
whatis.1.ps \
|
||||
whatis.1.pdf \
|
||||
whatis.1.txt \
|
||||
mandoc.3.html \
|
||||
mandoc.3.xhtml \
|
||||
mandoc.3.ps \
|
||||
mandoc.3.pdf \
|
||||
mandoc.3.txt \
|
||||
eqn.7.html \
|
||||
eqn.7.xhtml \
|
||||
eqn.7.ps \
|
||||
eqn.7.pdf \
|
||||
eqn.7.txt \
|
||||
man.7.html \
|
||||
man.7.xhtml \
|
||||
man.7.ps \
|
||||
man.7.pdf \
|
||||
man.7.txt \
|
||||
man.cgi.7.html \
|
||||
man.cgi.7.xhtml \
|
||||
man.cgi.7.ps \
|
||||
man.cgi.7.pdf \
|
||||
man.cgi.7.txt \
|
||||
mandoc_char.7.html \
|
||||
mandoc_char.7.xhtml \
|
||||
mandoc_char.7.ps \
|
||||
mandoc_char.7.pdf \
|
||||
mandoc_char.7.txt \
|
||||
mdoc.7.html \
|
||||
mdoc.7.xhtml \
|
||||
mdoc.7.ps \
|
||||
mdoc.7.pdf \
|
||||
mdoc.7.txt \
|
||||
preconv.1.html \
|
||||
preconv.1.xhtml \
|
||||
preconv.1.ps \
|
||||
preconv.1.pdf \
|
||||
preconv.1.txt \
|
||||
roff.7.html \
|
||||
roff.7.xhtml \
|
||||
roff.7.ps \
|
||||
roff.7.pdf \
|
||||
roff.7.txt \
|
||||
tbl.7.html \
|
||||
tbl.7.xhtml \
|
||||
tbl.7.ps \
|
||||
tbl.7.pdf \
|
||||
tbl.7.txt \
|
||||
mandocdb.8.html \
|
||||
mandocdb.8.xhtml \
|
||||
mandocdb.8.ps \
|
||||
mandocdb.8.pdf \
|
||||
mandocdb.8.txt
|
||||
|
||||
PDFS = mandoc.1.pdf mdoc.3.pdf man.3.pdf mdoc.7.pdf man.7.pdf \
|
||||
mandoc_char.7.pdf roff.7.pdf roff.3.pdf tbl.7.pdf
|
||||
$(INDEX_MANS): mandoc
|
||||
|
||||
XSLS = ChangeLog.xsl
|
||||
INDEX_OBJS = $(INDEX_MANS) \
|
||||
man.h.html \
|
||||
mandoc.h.html \
|
||||
mdoc.h.html \
|
||||
mdocml.tar.gz \
|
||||
mdocml.md5
|
||||
|
||||
TEXTS = mandoc.1.txt mdoc.3.txt man.3.txt mdoc.7.txt man.7.txt \
|
||||
mandoc_char.7.txt ChangeLog.txt \
|
||||
roff.7.txt roff.3.txt tbl.7.txt
|
||||
www: index.html
|
||||
|
||||
EXAMPLES = example.style.css
|
||||
|
||||
XMLS = ChangeLog.xml
|
||||
|
||||
STATICS = index.css style.css external.png
|
||||
|
||||
MD5S = mdocml-$(VERSION).md5
|
||||
|
||||
TARGZS = mdocml-$(VERSION).tar.gz
|
||||
|
||||
MANS = mandoc.1 mdoc.3 mdoc.7 mandoc_char.7 man.7 \
|
||||
man.3 roff.7 roff.3 tbl.7
|
||||
|
||||
BINS = mandoc
|
||||
|
||||
TESTS = test-strlcat.c test-strlcpy.c
|
||||
|
||||
CONFIGS = config.h.pre config.h.post
|
||||
|
||||
DOCLEAN = $(BINS) $(LNS) $(LLNS) $(LIBS) $(OBJS) $(HTMLS) \
|
||||
$(TARGZS) tags $(MD5S) $(XMLS) $(TEXTS) $(GSGMLS) \
|
||||
config.h config.log $(PSS) $(PDFS) $(XHTMLS)
|
||||
|
||||
DOINSTALL = $(SRCS) $(HEADS) Makefile $(MANS) $(SGMLS) $(STATICS) \
|
||||
$(DATAS) $(XSLS) $(EXAMPLES) $(TESTS) $(CONFIGS)
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
lint: $(LLNS)
|
||||
lint: llib-lmandoc.ln llib-lpreconv.ln llib-ldemandoc.ln $(DBLN)
|
||||
|
||||
clean:
|
||||
rm -f $(DOCLEAN)
|
||||
rm -f libmandoc.a $(LIBMANDOC_OBJS)
|
||||
rm -f llib-llibmandoc.ln $(LIBMANDOC_LNS)
|
||||
rm -f mandocdb $(MANDOCDB_OBJS)
|
||||
rm -f llib-lmandocdb.ln $(MANDOCDB_LNS)
|
||||
rm -f preconv $(PRECONV_OBJS)
|
||||
rm -f llib-lpreconv.ln $(PRECONV_LNS)
|
||||
rm -f apropos whatis $(APROPOS_OBJS)
|
||||
rm -f llib-lapropos.ln $(APROPOS_LNS)
|
||||
rm -f man.cgi $(CGI_OBJS)
|
||||
rm -f llib-lman.cgi.ln $(CGI_LNS)
|
||||
rm -f catman $(CATMAN_OBJS)
|
||||
rm -f llib-lcatman.ln $(CATMAN_LNS)
|
||||
rm -f demandoc $(DEMANDOC_OBJS)
|
||||
rm -f llib-ldemandoc.ln $(DEMANDOC_LNS)
|
||||
rm -f mandoc $(MANDOC_OBJS)
|
||||
rm -f llib-lmandoc.ln $(MANDOC_LNS)
|
||||
rm -f config.h config.log $(COMPAT_OBJS) $(COMPAT_LNS)
|
||||
rm -f mdocml.tar.gz mdocml-win32.zip mdocml-win64.zip mdocml-macosx.zip
|
||||
rm -f index.html $(INDEX_OBJS)
|
||||
rm -rf test-fgetln.DSYM
|
||||
rm -rf test-strlcpy.DSYM
|
||||
rm -rf test-strlcat.DSYM
|
||||
rm -rf test-strptime.DSYM
|
||||
rm -rf test-mmap.DSYM
|
||||
rm -rf test-getsubopt.DSYM
|
||||
|
||||
dist: mdocml-$(VERSION).tar.gz
|
||||
|
||||
www: all $(GSGMLS) $(HTMLS) $(XHTMLS) $(TEXTS) $(MD5S) $(TARGZS) $(PSS) $(PDFS)
|
||||
|
||||
ps: $(PSS)
|
||||
|
||||
pdf: $(PDFS)
|
||||
|
||||
installwww: www
|
||||
$(INSTALL_DATA) $(HTMLS) $(XHTMLS) $(PSS) $(PDFS) $(TEXTS) $(STATICS) $(DESTDIR)$(PREFIX)/
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).tar.gz $(DESTDIR)$(PREFIX)/snapshots/
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).md5 $(DESTDIR)$(PREFIX)/snapshots/
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).tar.gz $(DESTDIR)$(PREFIX)/snapshots/mdocml.tar.gz
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).md5 $(DESTDIR)$(PREFIX)/snapshots/mdocml.md5
|
||||
|
||||
install:
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(EXAMPLEDIR)
|
||||
mkdir -p $(DESTDIR)$(LIBDIR)
|
||||
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man3
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man7
|
||||
$(INSTALL_PROGRAM) mandoc $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_MAN) mandoc.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL_MAN) man.7 mdoc.7 roff.7 tbl.7 mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL_PROGRAM) mandoc preconv demandoc $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL_LIB) man.h mdoc.h mandoc.h $(DESTDIR)$(INCLUDEDIR)
|
||||
$(INSTALL_MAN) mandoc.1 preconv.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL_MAN) mandoc.3 $(DESTDIR)$(MANDIR)/man3
|
||||
$(INSTALL_MAN) man.7 mdoc.7 roff.7 eqn.7 tbl.7 mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
|
||||
$(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR)
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(BINDIR)/mandoc
|
||||
rm -f $(DESTDIR)$(MANDIR)/man1/mandoc.1
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/mdoc.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/roff.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/tbl.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/man.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/mandoc_char.7
|
||||
rm -f $(DESTDIR)$(EXAMPLEDIR)/example.style.css
|
||||
installcgi: all
|
||||
mkdir -p $(DESTDIR)$(CGIBINDIR)
|
||||
mkdir -p $(DESTDIR)$(HTDOCDIR)
|
||||
$(INSTALL_PROGRAM) man.cgi $(DESTDIR)$(CGIBINDIR)
|
||||
$(INSTALL_DATA) example.style.css $(DESTDIR)$(HTDOCDIR)/man.css
|
||||
$(INSTALL_DATA) man-cgi.css $(DESTDIR)$(HTDOCDIR)
|
||||
|
||||
$(OBJS): config.h
|
||||
installwww: www
|
||||
mkdir -p $(PREFIX)/snapshots
|
||||
mkdir -p $(PREFIX)/binaries
|
||||
$(INSTALL_DATA) index.html external.png index.css $(PREFIX)
|
||||
$(INSTALL_DATA) $(INDEX_MANS) style.css $(PREFIX)
|
||||
$(INSTALL_DATA) mandoc.h.html man.h.html mdoc.h.html $(PREFIX)
|
||||
$(INSTALL_DATA) mdocml.tar.gz $(PREFIX)/snapshots
|
||||
$(INSTALL_DATA) mdocml.md5 $(PREFIX)/snapshots
|
||||
$(INSTALL_DATA) mdocml.tar.gz $(PREFIX)/snapshots/mdocml-$(VERSION).tar.gz
|
||||
$(INSTALL_DATA) mdocml.md5 $(PREFIX)/snapshots/mdocml-$(VERSION).md5
|
||||
|
||||
$(LNS): config.h
|
||||
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||
$(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||
|
||||
man_macro.ln man_macro.o: man_macro.c libman.h
|
||||
llib-llibmandoc.ln: $(COMPAT_LNS) $(LIBMANDOC_LNS)
|
||||
$(LINT) $(LINTFLAGS) -Clibmandoc $(COMPAT_LNS) $(LIBMANDOC_LNS)
|
||||
|
||||
lib.ln lib.o: lib.c lib.in libmdoc.h
|
||||
mandoc: $(MANDOC_OBJS) libmandoc.a
|
||||
$(CC) $(LDFLAGS) -o $@ $(MANDOC_OBJS) libmandoc.a
|
||||
|
||||
att.ln att.o: att.c att.in libmdoc.h
|
||||
llib-lmandoc.ln: $(MANDOC_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Cmandoc $(MANDOC_LNS) llib-llibmandoc.ln
|
||||
|
||||
arch.ln arch.o: arch.c arch.in libmdoc.h
|
||||
mandocdb: $(MANDOCDB_OBJS) libmandoc.a
|
||||
$(CC) $(LDFLAGS) -o $@ $(MANDOCDB_OBJS) libmandoc.a $(DBLIB)
|
||||
|
||||
vol.ln vol.o: vol.c vol.in libmdoc.h
|
||||
llib-lmandocdb.ln: $(MANDOCDB_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Cmandocdb $(MANDOCDB_LNS) llib-llibmandoc.ln
|
||||
|
||||
chars.ln chars.o: chars.c chars.in chars.h
|
||||
preconv: $(PRECONV_OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(PRECONV_OBJS)
|
||||
|
||||
msec.ln msec.o: msec.c msec.in libmdoc.h
|
||||
llib-lpreconv.ln: $(PRECONV_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Cpreconv $(PRECONV_LNS) llib-llibmandoc.ln
|
||||
|
||||
st.ln st.o: st.c st.in libmdoc.h
|
||||
whatis: apropos
|
||||
cp -f apropos whatis
|
||||
|
||||
mdoc_macro.ln mdoc_macro.o: mdoc_macro.c libmdoc.h
|
||||
apropos: $(APROPOS_OBJS) libmandoc.a
|
||||
$(CC) $(LDFLAGS) -o $@ $(APROPOS_OBJS) libmandoc.a $(DBLIB)
|
||||
|
||||
mdoc_term.ln mdoc_term.o: mdoc_term.c term.h mdoc.h
|
||||
llib-lapropos.ln: $(APROPOS_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Capropos $(APROPOS_LNS) llib-llibmandoc.ln
|
||||
|
||||
mdoc_strings.ln mdoc_strings.o: mdoc_strings.c libmdoc.h
|
||||
catman: $(CATMAN_OBJS) libmandoc.a
|
||||
$(CC) $(LDFLAGS) -o $@ $(CATMAN_OBJS) libmandoc.a $(DBLIB)
|
||||
|
||||
man_hash.ln man_hash.o: man_hash.c libman.h
|
||||
llib-lcatman.ln: $(CATMAN_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Ccatman $(CATMAN_LNS) llib-llibmandoc.ln
|
||||
|
||||
mdoc_hash.ln mdoc_hash.o: mdoc_hash.c libmdoc.h
|
||||
man.cgi: $(CGI_OBJS) libmandoc.a
|
||||
$(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB)
|
||||
|
||||
mdoc.ln mdoc.o: mdoc.c libmdoc.h
|
||||
llib-lman.cgi.ln: $(CGI_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Cman.cgi $(CGI_LNS) llib-llibmandoc.ln
|
||||
|
||||
man.ln man.o: man.c libman.h
|
||||
demandoc: $(DEMANDOC_OBJS) libmandoc.a
|
||||
$(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a
|
||||
|
||||
main.ln main.o: main.c mdoc.h man.h roff.h
|
||||
llib-ldemandoc.ln: $(DEMANDOC_LNS) llib-llibmandoc.ln
|
||||
$(LINT) $(LINTFLAGS) -Cdemandoc $(DEMANDOC_LNS) llib-llibmandoc.ln
|
||||
|
||||
compat.ln compat.o: compat.c
|
||||
mdocml.md5: mdocml.tar.gz
|
||||
md5 mdocml.tar.gz >$@
|
||||
|
||||
term.ln term.o: term.c term.h man.h mdoc.h chars.h
|
||||
|
||||
term_ps.ln term_ps.o: term_ps.c term.h main.h
|
||||
|
||||
term_ascii.ln term_ascii.o: term_ascii.c term.h main.h
|
||||
|
||||
html.ln html.o: html.c html.h chars.h
|
||||
|
||||
mdoc_html.ln mdoc_html.o: mdoc_html.c html.h mdoc.h
|
||||
|
||||
man_html.ln man_html.o: man_html.c html.h man.h out.h
|
||||
|
||||
out.ln out.o: out.c out.h
|
||||
|
||||
mandoc.ln mandoc.o: mandoc.c libmandoc.h
|
||||
|
||||
tree.ln tree.o: tree.c man.h mdoc.h
|
||||
|
||||
mdoc_argv.ln mdoc_argv.o: mdoc_argv.c libmdoc.h
|
||||
|
||||
man_argv.ln man_argv.o: man_argv.c libman.h
|
||||
|
||||
man_validate.ln man_validate.o: man_validate.c libman.h
|
||||
|
||||
mdoc_validate.ln mdoc_validate.o: mdoc_validate.c libmdoc.h
|
||||
|
||||
libmdoc.h: mdoc.h
|
||||
|
||||
ChangeLog.xml:
|
||||
cvs2cl --xml --xml-encoding iso-8859-15 -t --noxmlns -f $@
|
||||
|
||||
ChangeLog.txt:
|
||||
cvs2cl -t -f $@
|
||||
|
||||
ChangeLog.html: ChangeLog.xml ChangeLog.xsl
|
||||
xsltproc -o $@ ChangeLog.xsl ChangeLog.xml
|
||||
|
||||
mdocml-$(VERSION).tar.gz: $(DOINSTALL)
|
||||
mkdir -p .dist/mdocml/mdocml-$(VERSION)/
|
||||
cp -f $(DOINSTALL) .dist/mdocml/mdocml-$(VERSION)/
|
||||
( cd .dist/mdocml/ && tar zcf ../../$@ mdocml-$(VERSION)/ )
|
||||
mdocml.tar.gz: $(SRCS)
|
||||
mkdir -p .dist/mdocml-$(VERSION)/
|
||||
$(INSTALL_SOURCE) $(SRCS) .dist/mdocml-$(VERSION)
|
||||
( cd .dist/ && tar zcf ../$@ ./ )
|
||||
rm -rf .dist/
|
||||
|
||||
llib-llibmdoc.ln: $(MDOCLNS)
|
||||
$(LINT) -Clibmdoc $(MDOCLNS)
|
||||
mdocml-win32.zip: $(SRCS)
|
||||
mkdir -p .win32/mdocml-$(VERSION)/
|
||||
$(INSTALL_SOURCE) $(SRCS) .win32
|
||||
cp .win32/Makefile .win32/Makefile.old
|
||||
egrep -v -e DUSE_WCHAR -e ^DBBIN .win32/Makefile.old >.win32/Makefile
|
||||
( cd .win32; \
|
||||
CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar CFLAGS='-DOSNAME=\"Windows\"' make; \
|
||||
make install PREFIX=mdocml-$(VERSION) ; \
|
||||
zip -r ../$@ mdocml-$(VERSION) )
|
||||
rm -rf .win32
|
||||
|
||||
llib-llibman.ln: $(MANLNS)
|
||||
$(LINT) -Clibman $(MANLNS)
|
||||
mdocml-win64.zip: $(SRCS)
|
||||
mkdir -p .win64/mdocml-$(VERSION)/
|
||||
$(INSTALL_SOURCE) $(SRCS) .win64
|
||||
cp .win64/Makefile .win64/Makefile.old
|
||||
egrep -v -e DUSE_WCHAR -e ^DBBIN .win64/Makefile.old >.win64/Makefile
|
||||
( cd .win64; \
|
||||
CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar CFLAGS='-DOSNAME=\"Windows\"' make; \
|
||||
make install PREFIX=mdocml-$(VERSION) ; \
|
||||
zip -r ../$@ mdocml-$(VERSION) )
|
||||
rm -rf .win64
|
||||
|
||||
llib-llibmandoc.ln: $(MANDOCLNS)
|
||||
$(LINT) -Clibmandoc $(MANDOCLNS)
|
||||
mdocml-macosx.zip: $(SRCS)
|
||||
mkdir -p .macosx/mdocml-$(VERSION)/
|
||||
$(INSTALL_SOURCE) $(SRCS) .macosx
|
||||
( cd .macosx; \
|
||||
CFLAGS="-arch i386 -arch x86_64 -arch ppc" LDFLAGS="-arch i386 -arch x86_64 -arch ppc" make; \
|
||||
make install PREFIX=mdocml-$(VERSION) ; \
|
||||
zip -r ../$@ mdocml-$(VERSION) )
|
||||
rm -rf .macosx
|
||||
|
||||
llib-llibroff.ln: $(ROFFLNS)
|
||||
$(LINT) -Clibroff $(ROFFLNS)
|
||||
|
||||
llib-lmandoc.ln: $(MAINLNS) llib-llibmdoc.ln llib-llibman.ln llib-llibmandoc.ln llib-llibroff.ln
|
||||
$(LINT) -Cmandoc $(MAINLNS) llib-llibmdoc.ln llib-llibman.ln llib-llibmandoc.ln llib-llibroff.ln
|
||||
|
||||
libmdoc.a: $(MDOCOBJS)
|
||||
$(AR) rs $@ $(MDOCOBJS)
|
||||
|
||||
libman.a: $(MANOBJS)
|
||||
$(AR) rs $@ $(MANOBJS)
|
||||
|
||||
libmandoc.a: $(MANDOCOBJS)
|
||||
$(AR) rs $@ $(MANDOCOBJS)
|
||||
|
||||
libroff.a: $(ROFFOBJS)
|
||||
$(AR) rs $@ $(ROFFOBJS)
|
||||
|
||||
mandoc: $(MAINOBJS) libroff.a libmdoc.a libman.a libmandoc.a
|
||||
$(CC) $(CFLAGS) -o $@ $(MAINOBJS) libroff.a libmdoc.a libman.a libmandoc.a
|
||||
|
||||
.sgml.html:
|
||||
validate --warn $<
|
||||
sed -e "s!@VERSION@!$(VERSION)!" -e "s!@VDATE@!$(VDATE)!" $< > $@
|
||||
|
||||
.1.1.txt .3.3.txt .7.7.txt:
|
||||
./mandoc -Tascii -Wall,stop $< | col -b > $@
|
||||
|
||||
.1.1.sgml .3.3.sgml .7.7.sgml:
|
||||
./mandoc -Thtml -Wall,stop -Ostyle=style.css,man=%N.%S.html,includes=%I.html $< > $@
|
||||
|
||||
.1.1.ps .3.3.ps .7.7.ps:
|
||||
./mandoc -Tps -Wall,stop $< > $@
|
||||
|
||||
.1.1.xhtml .3.3.xhtml .7.7.xhtml:
|
||||
./mandoc -Txhtml -Wall,stop -Ostyle=style.css,man=%N.%S.xhtml,includes=%I.html $< > $@
|
||||
|
||||
.1.1.pdf .3.3.pdf .7.7.pdf:
|
||||
./mandoc -Tpdf -Wall,stop $< > $@
|
||||
|
||||
.tar.gz.md5:
|
||||
md5 $< > $@
|
||||
|
||||
.h.h.html:
|
||||
highlight -I $< >$@
|
||||
index.html: $(INDEX_OBJS)
|
||||
|
||||
config.h: config.h.pre config.h.post
|
||||
rm -f config.log
|
||||
( cat config.h.pre; \
|
||||
echo; \
|
||||
if $(CC) $(CFLAGS) -Werror -c test-strlcat.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_STRLCAT'; \
|
||||
rm test-strlcat.o; \
|
||||
if $(CC) $(CFLAGS) -Werror -o test-fgetln test-fgetln.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_FGETLN'; \
|
||||
rm test-fgetln; \
|
||||
fi; \
|
||||
if $(CC) $(CFLAGS) -Werror -c test-strlcpy.c >> config.log 2>&1; then \
|
||||
if $(CC) $(CFLAGS) -Werror -o test-strptime test-strptime.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_STRPTIME'; \
|
||||
rm test-strptime; \
|
||||
fi; \
|
||||
if $(CC) $(CFLAGS) -Werror -o test-getsubopt test-getsubopt.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_GETSUBOPT'; \
|
||||
rm test-getsubopt; \
|
||||
fi; \
|
||||
if $(CC) $(CFLAGS) -Werror -o test-strlcat test-strlcat.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_STRLCAT'; \
|
||||
rm test-strlcat; \
|
||||
fi; \
|
||||
if $(CC) $(CFLAGS) -Werror -o test-mmap test-mmap.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_MMAP'; \
|
||||
rm test-mmap; \
|
||||
fi; \
|
||||
if $(CC) $(CFLAGS) -Werror -o test-strlcpy test-strlcpy.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_STRLCPY'; \
|
||||
rm test-strlcpy.o; \
|
||||
rm test-strlcpy; \
|
||||
fi; \
|
||||
echo; \
|
||||
cat config.h.post \
|
||||
) > $@
|
||||
|
||||
.h.h.html:
|
||||
highlight -I $< >$@
|
||||
|
||||
.1.1.txt .3.3.txt .7.7.txt .8.8.txt:
|
||||
./mandoc -Tascii -Wall,stop $< | col -b >$@
|
||||
|
||||
.1.1.html .3.3.html .7.7.html .8.8.html:
|
||||
./mandoc -Thtml -Wall,stop -Ostyle=style.css,man=%N.%S.html,includes=%I.html $< >$@
|
||||
|
||||
.1.1.ps .3.3.ps .7.7.ps .8.8.ps:
|
||||
./mandoc -Tps -Wall,stop $< >$@
|
||||
|
||||
.1.1.xhtml .3.3.xhtml .7.7.xhtml .8.8.xhtml:
|
||||
./mandoc -Txhtml -Wall,stop -Ostyle=style.css,man=%N.%S.xhtml,includes=%I.html $< >$@
|
||||
|
||||
.1.1.pdf .3.3.pdf .7.7.pdf .8.8.pdf:
|
||||
./mandoc -Tpdf -Wall,stop $< >$@
|
||||
|
||||
.sgml.html:
|
||||
validate --warn $<
|
||||
sed -e "s!@VERSION@!$(VERSION)!" -e "s!@VDATE@!$(VDATE)!" $< >$@
|
||||
|
|
312
external/bsd/mdocml/dist/apropos.1
vendored
Normal file
312
external/bsd/mdocml/dist/apropos.1
vendored
Normal file
|
@ -0,0 +1,312 @@
|
|||
.\" $Vendor-Id: apropos.1,v 1.16 2011/12/25 19:35:44 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd December 25, 2011
|
||||
.Dt APROPOS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm apropos
|
||||
.Nd search manual page databases
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl C Ar file
|
||||
.Op Fl M Ar manpath
|
||||
.Op Fl m Ar manpath
|
||||
.Op Fl S Ar arch
|
||||
.Op Fl s Ar section
|
||||
.Ar expression ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility queries manual page databases generated by
|
||||
.Xr mandocdb 8 ,
|
||||
evaluating on
|
||||
.Ar expression
|
||||
for each file in each database.
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
searches for
|
||||
.Xr mandocdb 8
|
||||
databases in the default paths stipulated by
|
||||
.Xr man 1 ,
|
||||
parses terms as case-sensitive regular expressions
|
||||
.Pq the Li \&~ operator
|
||||
over manual names and descriptions
|
||||
.Pq the Li \&Nm No and Li \&Nd No macro keys .
|
||||
Multiple terms imply pairwise
|
||||
.Fl o .
|
||||
.Pp
|
||||
Its arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl C Ar file
|
||||
Specify an alternative configuration
|
||||
.Ar file
|
||||
in
|
||||
.Xr man.conf 5
|
||||
format.
|
||||
.It Fl M Ar manpath
|
||||
Use the colon-separated path instead of the default list of paths
|
||||
searched for
|
||||
.Xr mandocdb 8
|
||||
databases.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
.It Fl m Ar manpath
|
||||
Prepend the colon-separated paths to the list of paths searched
|
||||
for
|
||||
.Xr mandocdb 8
|
||||
databases.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
.It Fl S Ar arch
|
||||
Search only for a particular architecture.
|
||||
.It Fl s Ar cat
|
||||
Search only for a manual section.
|
||||
See
|
||||
.Xr man 1
|
||||
for a listing of manual sections.
|
||||
.El
|
||||
.Pp
|
||||
An
|
||||
.Ar expression
|
||||
consists of search terms joined by logical operators
|
||||
.Fl a
|
||||
.Pq and
|
||||
and
|
||||
.Fl o
|
||||
.Pq or .
|
||||
The
|
||||
.Fl a
|
||||
operator has precedence over
|
||||
.Fl o
|
||||
and both are evaluated left-to-right.
|
||||
.Bl -tag -width Ds
|
||||
.It \&( Ar expr No \&)
|
||||
True if the subexpression
|
||||
.Ar expr
|
||||
is true.
|
||||
.It Ar expr1 Fl a Ar expr2
|
||||
True if both
|
||||
.Ar expr1
|
||||
and
|
||||
.Ar expr2
|
||||
are true (logical
|
||||
.Qq and ) .
|
||||
.It Ar expr1 Oo Fl o Oc Ar expr2
|
||||
True if
|
||||
.Ar expr1
|
||||
and/or
|
||||
.Ar expr2
|
||||
evaluate to true (logical
|
||||
.Qq or ) .
|
||||
.It Ar term
|
||||
True if
|
||||
.Ar term
|
||||
is satisfied.
|
||||
This has syntax
|
||||
.Li [key[,key]*(=~)]?val ,
|
||||
where operand
|
||||
.Cm key
|
||||
is an
|
||||
.Xr mdoc 7
|
||||
macro to query and
|
||||
.Cm val
|
||||
is its value.
|
||||
See
|
||||
.Sx Macro Keys
|
||||
for a list of available keys.
|
||||
Operator
|
||||
.Li \&=
|
||||
evaluates a substring, while
|
||||
.Li \&~
|
||||
evaluates a regular expression.
|
||||
.It Fl i Ar term
|
||||
If
|
||||
.Ar term
|
||||
is a regular expression, it
|
||||
is evaluated case-insensitively.
|
||||
Has no effect on substring terms.
|
||||
.El
|
||||
.Pp
|
||||
Results are sorted by manual title, with output formatted as
|
||||
.Pp
|
||||
.D1 title(sec) \- description
|
||||
.Pp
|
||||
Where
|
||||
.Qq title
|
||||
is the manual's title (note multiple manual names may exist for one
|
||||
title),
|
||||
.Qq sec
|
||||
is the manual section, and
|
||||
.Qq description
|
||||
is the manual's short description.
|
||||
If an architecture is specified for the manual, it is displayed as
|
||||
.Pp
|
||||
.D1 title(cat/arch) \- description
|
||||
.Pp
|
||||
Resulting manuals may be accessed as
|
||||
.Pp
|
||||
.Dl $ man \-s sec title
|
||||
.Pp
|
||||
If an architecture is specified in the output, use
|
||||
.Pp
|
||||
.Dl $ man \-s sec \-S arch title
|
||||
.Ss Macro Keys
|
||||
Queries evaluate over a subset of
|
||||
.Xr mdoc 7
|
||||
macros indexed by
|
||||
.Xr mandocdb 8 .
|
||||
In addition to the macro keys listed below, the special key
|
||||
.Cm any
|
||||
may be used to match any available macro key.
|
||||
.Pp
|
||||
Names and description:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&Nm Ta manual name
|
||||
.It Li \&Nd Ta one-line manual description
|
||||
.El
|
||||
.Pp
|
||||
Sections and cross references:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&Sh Ta section header (excluding standard sections)
|
||||
.It Li \&Ss Ta subsection header
|
||||
.It Li \&Xr Ta cross reference to another manual page
|
||||
.It Li \&Rs Ta bibliographic reference
|
||||
.El
|
||||
.Pp
|
||||
Semantic markup for command line utilities:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&Fl Ta command line options (flags)
|
||||
.It Li \&Cm Ta command modifier
|
||||
.It Li \&Ar Ta command argument
|
||||
.It Li \&Ic Ta internal or interactive command
|
||||
.It Li \&Ev Ta environmental variable
|
||||
.It Li \&Pa Ta file system path
|
||||
.El
|
||||
.Pp
|
||||
Semantic markup for function libraries:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&Lb Ta function library name
|
||||
.It Li \&In Ta include file
|
||||
.It Li \&Ft Ta function return type
|
||||
.It Li \&Fn Ta function name
|
||||
.It Li \&Fa Ta function argument type and name
|
||||
.It Li \&Vt Ta variable type
|
||||
.It Li \&Va Ta variable name
|
||||
.It Li \&Dv Ta defined variable or preprocessor constant
|
||||
.It Li \&Er Ta error constant
|
||||
.It Li \&Ev Ta environmental variable
|
||||
.El
|
||||
.Pp
|
||||
Various semantic markup:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&An Ta author name
|
||||
.It Li \&Lk Ta hyperlink
|
||||
.It Li \&Mt Ta Do mailto Dc hyperlink
|
||||
.It Li \&Cd Ta kernel configuration declaration
|
||||
.It Li \&Ms Ta mathematical symbol
|
||||
.It Li \&Tn Ta tradename
|
||||
.El
|
||||
.Pp
|
||||
Physical markup:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&Em Ta italic font or underline
|
||||
.It Li \&Sy Ta boldface font
|
||||
.It Li \&Li Ta typewriter font
|
||||
.El
|
||||
.Pp
|
||||
Text production:
|
||||
.Bl -column "xLix" description -offset indent -compact
|
||||
.It Li \&St Ta reference to a standards document
|
||||
.It Li \&At Ta At No version reference
|
||||
.It Li \&Bx Ta Bx No version reference
|
||||
.It Li \&Bsx Ta Bsx No version reference
|
||||
.It Li \&Nx Ta Nx No version reference
|
||||
.It Li \&Fx Ta Fx No version reference
|
||||
.It Li \&Ox Ta Ox No version reference
|
||||
.It Li \&Dx Ta Dx No version reference
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width Ds
|
||||
.It Ev MANPATH
|
||||
Colon-separated paths modifying the default list of paths searched for
|
||||
manual databases.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
Overridden by
|
||||
.Fl M .
|
||||
If
|
||||
.Ev MANPATH
|
||||
begins with a
|
||||
.Sq \&: ,
|
||||
it is appended to the default list;
|
||||
else if it ends with
|
||||
.Sq \&: ,
|
||||
it is prepended to the default list; else if it contains
|
||||
.Sq \&:: ,
|
||||
the default list is inserted between the colons.
|
||||
If none of these conditions are met, it overrides the default list.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/man.conf" -compact
|
||||
.It Pa whatis.db
|
||||
name of the
|
||||
.Xr mandocdb 8
|
||||
keyword database
|
||||
.It Pa whatis.index
|
||||
name of the
|
||||
.Xr mandocdb 8
|
||||
filename database
|
||||
.It Pa /etc/man.conf
|
||||
default
|
||||
.Xr man 1
|
||||
configuration file
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh EXAMPLES
|
||||
Search for
|
||||
.Qq mdoc
|
||||
as a substring and regular expression
|
||||
within each manual name and description:
|
||||
.Pp
|
||||
.Dl $ apropos mdoc
|
||||
.Dl $ apropos ~^mdoc$
|
||||
.Pp
|
||||
Include matches for
|
||||
.Qq roff
|
||||
and
|
||||
.Qq man
|
||||
for the regular expression case:
|
||||
.Pp
|
||||
.Dl $ apropos ~^mdoc$ roff man
|
||||
.Dl $ apropos ~^mdoc$ \-o roff \-o man
|
||||
.Pp
|
||||
Search for
|
||||
.Qq optind
|
||||
and
|
||||
.Qq optarg
|
||||
as variable names in the library category:
|
||||
.Pp
|
||||
.Dl $ apropos \-s 3 Va~^optind \-a Va~^optarg$
|
||||
.Sh SEE ALSO
|
||||
.Xr man 1 ,
|
||||
.Xr re_format 7 ,
|
||||
.Xr mandocdb 8
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
157
external/bsd/mdocml/dist/apropos.c
vendored
Normal file
157
external/bsd/mdocml/dist/apropos.c
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* $Vendor-Id: apropos.c,v 1.25 2011/12/31 18:47:52 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apropos_db.h"
|
||||
#include "mandoc.h"
|
||||
#include "manpath.h"
|
||||
|
||||
static int cmp(const void *, const void *);
|
||||
static void list(struct res *, size_t, void *);
|
||||
static void usage(void);
|
||||
|
||||
static char *progname;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, rc, whatis;
|
||||
struct manpaths paths;
|
||||
size_t terms;
|
||||
struct opts opts;
|
||||
struct expr *e;
|
||||
char *defpaths, *auxpaths;
|
||||
char *conf_file;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
++progname;
|
||||
|
||||
whatis = 0 == strncmp(progname, "whatis", 6);
|
||||
|
||||
memset(&paths, 0, sizeof(struct manpaths));
|
||||
memset(&opts, 0, sizeof(struct opts));
|
||||
|
||||
auxpaths = defpaths = NULL;
|
||||
conf_file = NULL;
|
||||
e = NULL;
|
||||
|
||||
while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
|
||||
switch (ch) {
|
||||
case ('C'):
|
||||
conf_file = optarg;
|
||||
break;
|
||||
case ('M'):
|
||||
defpaths = optarg;
|
||||
break;
|
||||
case ('m'):
|
||||
auxpaths = optarg;
|
||||
break;
|
||||
case ('S'):
|
||||
opts.arch = optarg;
|
||||
break;
|
||||
case ('s'):
|
||||
opts.cat = optarg;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (0 == argc)
|
||||
return(EXIT_SUCCESS);
|
||||
|
||||
rc = 0;
|
||||
|
||||
manpath_parse(&paths, conf_file, defpaths, auxpaths);
|
||||
|
||||
e = whatis ? termcomp(argc, argv, &terms) :
|
||||
exprcomp(argc, argv, &terms);
|
||||
|
||||
if (NULL == e) {
|
||||
fprintf(stderr, "%s: Bad expression\n", progname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = apropos_search
|
||||
(paths.sz, paths.paths,
|
||||
&opts, e, terms, NULL, list);
|
||||
|
||||
if (0 == rc)
|
||||
fprintf(stderr, "%s: Error reading "
|
||||
"manual database\n", progname);
|
||||
|
||||
out:
|
||||
manpath_free(&paths);
|
||||
exprfree(e);
|
||||
|
||||
return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
list(struct res *res, size_t sz, void *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
qsort(res, sz, sizeof(struct res), cmp);
|
||||
|
||||
for (i = 0; i < (int)sz; i++)
|
||||
printf("%s(%s%s%s) - %.70s\n", res[i].title,
|
||||
res[i].cat,
|
||||
*res[i].arch ? "/" : "",
|
||||
*res[i].arch ? res[i].arch : "",
|
||||
res[i].desc);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp(const void *p1, const void *p2)
|
||||
{
|
||||
|
||||
return(strcasecmp(((const struct res *)p1)->title,
|
||||
((const struct res *)p2)->title));
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s "
|
||||
"[-C file] "
|
||||
"[-M manpath] "
|
||||
"[-m manpath] "
|
||||
"[-S arch] "
|
||||
"[-s section] "
|
||||
"expression ...\n",
|
||||
progname);
|
||||
}
|
899
external/bsd/mdocml/dist/apropos_db.c
vendored
Normal file
899
external/bsd/mdocml/dist/apropos_db.c
vendored
Normal file
|
@ -0,0 +1,899 @@
|
|||
/* $Vendor-Id: apropos_db.c,v 1.28 2011/12/25 14:58:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <regex.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <endian.h>
|
||||
# include <db_185.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# include <db.h>
|
||||
#else
|
||||
# include <db.h>
|
||||
#endif
|
||||
|
||||
#include "mandocdb.h"
|
||||
#include "apropos_db.h"
|
||||
#include "mandoc.h"
|
||||
|
||||
struct rec {
|
||||
struct res res; /* resulting record info */
|
||||
/*
|
||||
* Maintain a binary tree for checking the uniqueness of `rec'
|
||||
* when adding elements to the results array.
|
||||
* Since the results array is dynamic, use offset in the array
|
||||
* instead of a pointer to the structure.
|
||||
*/
|
||||
int lhs;
|
||||
int rhs;
|
||||
int matched; /* expression is true */
|
||||
int *matches; /* partial truth evaluations */
|
||||
};
|
||||
|
||||
struct expr {
|
||||
int regex; /* is regex? */
|
||||
int index; /* index in match array */
|
||||
uint64_t mask; /* type-mask */
|
||||
int and; /* is rhs of logical AND? */
|
||||
char *v; /* search value */
|
||||
regex_t re; /* compiled re, if regex */
|
||||
struct expr *next; /* next in sequence */
|
||||
struct expr *subexpr;
|
||||
};
|
||||
|
||||
struct type {
|
||||
uint64_t mask;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct rectree {
|
||||
struct rec *node; /* record array for dir tree */
|
||||
int len; /* length of record array */
|
||||
};
|
||||
|
||||
static const struct type types[] = {
|
||||
{ TYPE_An, "An" },
|
||||
{ TYPE_Ar, "Ar" },
|
||||
{ TYPE_At, "At" },
|
||||
{ TYPE_Bsx, "Bsx" },
|
||||
{ TYPE_Bx, "Bx" },
|
||||
{ TYPE_Cd, "Cd" },
|
||||
{ TYPE_Cm, "Cm" },
|
||||
{ TYPE_Dv, "Dv" },
|
||||
{ TYPE_Dx, "Dx" },
|
||||
{ TYPE_Em, "Em" },
|
||||
{ TYPE_Er, "Er" },
|
||||
{ TYPE_Ev, "Ev" },
|
||||
{ TYPE_Fa, "Fa" },
|
||||
{ TYPE_Fl, "Fl" },
|
||||
{ TYPE_Fn, "Fn" },
|
||||
{ TYPE_Fn, "Fo" },
|
||||
{ TYPE_Ft, "Ft" },
|
||||
{ TYPE_Fx, "Fx" },
|
||||
{ TYPE_Ic, "Ic" },
|
||||
{ TYPE_In, "In" },
|
||||
{ TYPE_Lb, "Lb" },
|
||||
{ TYPE_Li, "Li" },
|
||||
{ TYPE_Lk, "Lk" },
|
||||
{ TYPE_Ms, "Ms" },
|
||||
{ TYPE_Mt, "Mt" },
|
||||
{ TYPE_Nd, "Nd" },
|
||||
{ TYPE_Nm, "Nm" },
|
||||
{ TYPE_Nx, "Nx" },
|
||||
{ TYPE_Ox, "Ox" },
|
||||
{ TYPE_Pa, "Pa" },
|
||||
{ TYPE_Rs, "Rs" },
|
||||
{ TYPE_Sh, "Sh" },
|
||||
{ TYPE_Ss, "Ss" },
|
||||
{ TYPE_St, "St" },
|
||||
{ TYPE_Sy, "Sy" },
|
||||
{ TYPE_Tn, "Tn" },
|
||||
{ TYPE_Va, "Va" },
|
||||
{ TYPE_Va, "Vt" },
|
||||
{ TYPE_Xr, "Xr" },
|
||||
{ UINT64_MAX, "any" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static DB *btree_open(void);
|
||||
static int btree_read(const DBT *, const DBT *,
|
||||
const struct mchars *,
|
||||
uint64_t *, recno_t *, char **);
|
||||
static int expreval(const struct expr *, int *);
|
||||
static void exprexec(const struct expr *,
|
||||
const char *, uint64_t, struct rec *);
|
||||
static int exprmark(const struct expr *,
|
||||
const char *, uint64_t, int *);
|
||||
static struct expr *exprexpr(int, char *[], int *, int *, size_t *);
|
||||
static struct expr *exprterm(char *, int);
|
||||
static DB *index_open(void);
|
||||
static int index_read(const DBT *, const DBT *, int,
|
||||
const struct mchars *, struct rec *);
|
||||
static void norm_string(const char *,
|
||||
const struct mchars *, char **);
|
||||
static size_t norm_utf8(unsigned int, char[7]);
|
||||
static void recfree(struct rec *);
|
||||
static int single_search(struct rectree *, const struct opts *,
|
||||
const struct expr *, size_t terms,
|
||||
struct mchars *, int);
|
||||
|
||||
/*
|
||||
* Open the keyword mandoc-db database.
|
||||
*/
|
||||
static DB *
|
||||
btree_open(void)
|
||||
{
|
||||
BTREEINFO info;
|
||||
DB *db;
|
||||
|
||||
memset(&info, 0, sizeof(BTREEINFO));
|
||||
info.flags = R_DUP;
|
||||
|
||||
db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info);
|
||||
if (NULL != db)
|
||||
return(db);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a keyword from the database and normalise it.
|
||||
* Return 0 if the database is insane, else 1.
|
||||
*/
|
||||
static int
|
||||
btree_read(const DBT *k, const DBT *v, const struct mchars *mc,
|
||||
uint64_t *mask, recno_t *rec, char **buf)
|
||||
{
|
||||
uint64_t vbuf[2];
|
||||
|
||||
/* Are our sizes sane? */
|
||||
if (k->size < 2 || sizeof(vbuf) != v->size)
|
||||
return(0);
|
||||
|
||||
/* Is our string nil-terminated? */
|
||||
if ('\0' != ((const char *)k->data)[(int)k->size - 1])
|
||||
return(0);
|
||||
|
||||
norm_string((const char *)k->data, mc, buf);
|
||||
memcpy(vbuf, v->data, v->size);
|
||||
*mask = betoh64(vbuf[0]);
|
||||
*rec = betoh64(vbuf[1]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take a Unicode codepoint and produce its UTF-8 encoding.
|
||||
* This isn't the best way to do this, but it works.
|
||||
* The magic numbers are from the UTF-8 packaging.
|
||||
* They're not as scary as they seem: read the UTF-8 spec for details.
|
||||
*/
|
||||
static size_t
|
||||
norm_utf8(unsigned int cp, char out[7])
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
|
||||
if (cp <= 0x0000007F) {
|
||||
rc = 1;
|
||||
out[0] = (char)cp;
|
||||
} else if (cp <= 0x000007FF) {
|
||||
rc = 2;
|
||||
out[0] = (cp >> 6 & 31) | 192;
|
||||
out[1] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x0000FFFF) {
|
||||
rc = 3;
|
||||
out[0] = (cp >> 12 & 15) | 224;
|
||||
out[1] = (cp >> 6 & 63) | 128;
|
||||
out[2] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x001FFFFF) {
|
||||
rc = 4;
|
||||
out[0] = (cp >> 18 & 7) | 240;
|
||||
out[1] = (cp >> 12 & 63) | 128;
|
||||
out[2] = (cp >> 6 & 63) | 128;
|
||||
out[3] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x03FFFFFF) {
|
||||
rc = 5;
|
||||
out[0] = (cp >> 24 & 3) | 248;
|
||||
out[1] = (cp >> 18 & 63) | 128;
|
||||
out[2] = (cp >> 12 & 63) | 128;
|
||||
out[3] = (cp >> 6 & 63) | 128;
|
||||
out[4] = (cp & 63) | 128;
|
||||
} else if (cp <= 0x7FFFFFFF) {
|
||||
rc = 6;
|
||||
out[0] = (cp >> 30 & 1) | 252;
|
||||
out[1] = (cp >> 24 & 63) | 128;
|
||||
out[2] = (cp >> 18 & 63) | 128;
|
||||
out[3] = (cp >> 12 & 63) | 128;
|
||||
out[4] = (cp >> 6 & 63) | 128;
|
||||
out[5] = (cp & 63) | 128;
|
||||
} else
|
||||
return(0);
|
||||
|
||||
out[rc] = '\0';
|
||||
return((size_t)rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalise strings from the index and database.
|
||||
* These strings are escaped as defined by mandoc_char(7) along with
|
||||
* other goop in mandoc.h (e.g., soft hyphens).
|
||||
* This function normalises these into a nice UTF-8 string.
|
||||
* Returns 0 if the database is fucked.
|
||||
*/
|
||||
static void
|
||||
norm_string(const char *val, const struct mchars *mc, char **buf)
|
||||
{
|
||||
size_t sz, bsz;
|
||||
char utfbuf[7];
|
||||
const char *seq, *cpp;
|
||||
int len, u, pos;
|
||||
enum mandoc_esc esc;
|
||||
static const char res[] = { '\\', '\t',
|
||||
ASCII_NBRSP, ASCII_HYPH, '\0' };
|
||||
|
||||
/* Pre-allocate by the length of the input */
|
||||
|
||||
bsz = strlen(val) + 1;
|
||||
*buf = mandoc_realloc(*buf, bsz);
|
||||
pos = 0;
|
||||
|
||||
while ('\0' != *val) {
|
||||
/*
|
||||
* Halt on the first escape sequence.
|
||||
* This also halts on the end of string, in which case
|
||||
* we just copy, fallthrough, and exit the loop.
|
||||
*/
|
||||
if ((sz = strcspn(val, res)) > 0) {
|
||||
memcpy(&(*buf)[pos], val, sz);
|
||||
pos += (int)sz;
|
||||
val += (int)sz;
|
||||
}
|
||||
|
||||
if (ASCII_HYPH == *val) {
|
||||
(*buf)[pos++] = '-';
|
||||
val++;
|
||||
continue;
|
||||
} else if ('\t' == *val || ASCII_NBRSP == *val) {
|
||||
(*buf)[pos++] = ' ';
|
||||
val++;
|
||||
continue;
|
||||
} else if ('\\' != *val)
|
||||
break;
|
||||
|
||||
/* Read past the slash. */
|
||||
|
||||
val++;
|
||||
u = 0;
|
||||
|
||||
/*
|
||||
* Parse the escape sequence and see if it's a
|
||||
* predefined character or special character.
|
||||
*/
|
||||
|
||||
esc = mandoc_escape(&val, &seq, &len);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
break;
|
||||
|
||||
/*
|
||||
* XXX - this just does UTF-8, but we need to know
|
||||
* beforehand whether we should do text substitution.
|
||||
*/
|
||||
|
||||
switch (esc) {
|
||||
case (ESCAPE_SPECIAL):
|
||||
if (0 != (u = mchars_spec2cp(mc, seq, len)))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have a Unicode codepoint, try to convert that
|
||||
* to a UTF-8 byte string.
|
||||
*/
|
||||
|
||||
cpp = utfbuf;
|
||||
if (0 == (sz = norm_utf8(u, utfbuf)))
|
||||
continue;
|
||||
|
||||
/* Copy the rendered glyph into the stream. */
|
||||
|
||||
sz = strlen(cpp);
|
||||
bsz += sz;
|
||||
|
||||
*buf = mandoc_realloc(*buf, bsz);
|
||||
|
||||
memcpy(&(*buf)[pos], cpp, sz);
|
||||
pos += (int)sz;
|
||||
}
|
||||
|
||||
(*buf)[pos] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the filename-index mandoc-db database.
|
||||
* Returns NULL if opening failed.
|
||||
*/
|
||||
static DB *
|
||||
index_open(void)
|
||||
{
|
||||
DB *db;
|
||||
|
||||
db = dbopen(MANDOC_IDX, O_RDONLY, 0, DB_RECNO, NULL);
|
||||
if (NULL != db)
|
||||
return(db);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safely unpack from an index file record into the structure.
|
||||
* Returns 1 if an entry was unpacked, 0 if the database is insane.
|
||||
*/
|
||||
static int
|
||||
index_read(const DBT *key, const DBT *val, int index,
|
||||
const struct mchars *mc, struct rec *rec)
|
||||
{
|
||||
size_t left;
|
||||
char *np, *cp;
|
||||
char type;
|
||||
|
||||
#define INDEX_BREAD(_dst) \
|
||||
do { \
|
||||
if (NULL == (np = memchr(cp, '\0', left))) \
|
||||
return(0); \
|
||||
norm_string(cp, mc, &(_dst)); \
|
||||
left -= (np - cp) + 1; \
|
||||
cp = np + 1; \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
if (0 == (left = val->size))
|
||||
return(0);
|
||||
|
||||
cp = val->data;
|
||||
assert(sizeof(recno_t) == key->size);
|
||||
memcpy(&rec->res.rec, key->data, key->size);
|
||||
rec->res.volume = index;
|
||||
|
||||
if ('d' == (type = *cp++))
|
||||
rec->res.type = RESTYPE_MDOC;
|
||||
else if ('a' == type)
|
||||
rec->res.type = RESTYPE_MAN;
|
||||
else if ('c' == type)
|
||||
rec->res.type = RESTYPE_CAT;
|
||||
else
|
||||
return(0);
|
||||
|
||||
left--;
|
||||
INDEX_BREAD(rec->res.file);
|
||||
INDEX_BREAD(rec->res.cat);
|
||||
INDEX_BREAD(rec->res.title);
|
||||
INDEX_BREAD(rec->res.arch);
|
||||
INDEX_BREAD(rec->res.desc);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search mandocdb databases in paths for expression "expr".
|
||||
* Filter out by "opts".
|
||||
* Call "res" with the results, which may be zero.
|
||||
* Return 0 if there was a database error, else return 1.
|
||||
*/
|
||||
int
|
||||
apropos_search(int pathsz, char **paths, const struct opts *opts,
|
||||
const struct expr *expr, size_t terms, void *arg,
|
||||
void (*res)(struct res *, size_t, void *))
|
||||
{
|
||||
struct rectree tree;
|
||||
struct mchars *mc;
|
||||
struct res *ress;
|
||||
int i, mlen, rc;
|
||||
|
||||
memset(&tree, 0, sizeof(struct rectree));
|
||||
|
||||
rc = 0;
|
||||
mc = mchars_alloc();
|
||||
|
||||
/*
|
||||
* Main loop. Change into the directory containing manpage
|
||||
* databases. Run our expession over each database in the set.
|
||||
*/
|
||||
|
||||
for (i = 0; i < pathsz; i++) {
|
||||
if (chdir(paths[i]))
|
||||
continue;
|
||||
if ( ! single_search(&tree, opts, expr, terms, mc, i))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count matching files, transfer to a "clean" array, then feed
|
||||
* them to the output handler.
|
||||
*/
|
||||
|
||||
for (mlen = i = 0; i < tree.len; i++)
|
||||
if (tree.node[i].matched)
|
||||
mlen++;
|
||||
|
||||
ress = mandoc_malloc(mlen * sizeof(struct res));
|
||||
|
||||
for (mlen = i = 0; i < tree.len; i++)
|
||||
if (tree.node[i].matched)
|
||||
memcpy(&ress[mlen++], &tree.node[i].res,
|
||||
sizeof(struct res));
|
||||
|
||||
(*res)(ress, mlen, arg);
|
||||
free(ress);
|
||||
|
||||
rc = 1;
|
||||
out:
|
||||
for (i = 0; i < tree.len; i++)
|
||||
recfree(&tree.node[i]);
|
||||
|
||||
free(tree.node);
|
||||
mchars_free(mc);
|
||||
return(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
single_search(struct rectree *tree, const struct opts *opts,
|
||||
const struct expr *expr, size_t terms,
|
||||
struct mchars *mc, int vol)
|
||||
{
|
||||
int root, leaf, ch;
|
||||
DBT key, val;
|
||||
DB *btree, *idx;
|
||||
char *buf;
|
||||
struct rec *rs;
|
||||
struct rec r;
|
||||
uint64_t mask;
|
||||
recno_t rec;
|
||||
|
||||
root = -1;
|
||||
leaf = -1;
|
||||
btree = NULL;
|
||||
idx = NULL;
|
||||
buf = NULL;
|
||||
rs = tree->node;
|
||||
|
||||
memset(&r, 0, sizeof(struct rec));
|
||||
|
||||
if (NULL == (btree = btree_open()))
|
||||
return(1);
|
||||
|
||||
if (NULL == (idx = index_open())) {
|
||||
(*btree->close)(btree);
|
||||
return(1);
|
||||
}
|
||||
|
||||
while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) {
|
||||
if ( ! btree_read(&key, &val, mc, &mask, &rec, &buf))
|
||||
break;
|
||||
|
||||
/*
|
||||
* See if this keyword record matches any of the
|
||||
* expressions we have stored.
|
||||
*/
|
||||
if ( ! exprmark(expr, buf, mask, NULL))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* O(log n) scan for prior records. Since a record
|
||||
* number is unbounded, this has decent performance over
|
||||
* a complex hash function.
|
||||
*/
|
||||
|
||||
for (leaf = root; leaf >= 0; )
|
||||
if (rec > rs[leaf].res.rec &&
|
||||
rs[leaf].rhs >= 0)
|
||||
leaf = rs[leaf].rhs;
|
||||
else if (rec < rs[leaf].res.rec &&
|
||||
rs[leaf].lhs >= 0)
|
||||
leaf = rs[leaf].lhs;
|
||||
else
|
||||
break;
|
||||
|
||||
/*
|
||||
* If we find a record, see if it has already evaluated
|
||||
* to true. If it has, great, just keep going. If not,
|
||||
* try to evaluate it now and continue anyway.
|
||||
*/
|
||||
|
||||
if (leaf >= 0 && rs[leaf].res.rec == rec) {
|
||||
if (0 == rs[leaf].matched)
|
||||
exprexec(expr, buf, mask, &rs[leaf]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a new file to examine.
|
||||
* Extract the manpage's metadata from the index
|
||||
* database, then begin partial evaluation.
|
||||
*/
|
||||
|
||||
key.data = &rec;
|
||||
key.size = sizeof(recno_t);
|
||||
|
||||
if (0 != (*idx->get)(idx, &key, &val, 0))
|
||||
break;
|
||||
|
||||
r.lhs = r.rhs = -1;
|
||||
if ( ! index_read(&key, &val, vol, mc, &r))
|
||||
break;
|
||||
|
||||
/* XXX: this should be elsewhere, I guess? */
|
||||
|
||||
if (opts->cat && strcasecmp(opts->cat, r.res.cat))
|
||||
continue;
|
||||
|
||||
if (opts->arch && *r.res.arch)
|
||||
if (strcasecmp(opts->arch, r.res.arch))
|
||||
continue;
|
||||
|
||||
tree->node = rs = mandoc_realloc
|
||||
(rs, (tree->len + 1) * sizeof(struct rec));
|
||||
|
||||
memcpy(&rs[tree->len], &r, sizeof(struct rec));
|
||||
memset(&r, 0, sizeof(struct rec));
|
||||
rs[tree->len].matches =
|
||||
mandoc_calloc(terms, sizeof(int));
|
||||
|
||||
exprexec(expr, buf, mask, &rs[tree->len]);
|
||||
|
||||
/* Append to our tree. */
|
||||
|
||||
if (leaf >= 0) {
|
||||
if (rec > rs[leaf].res.rec)
|
||||
rs[leaf].rhs = tree->len;
|
||||
else
|
||||
rs[leaf].lhs = tree->len;
|
||||
} else
|
||||
root = tree->len;
|
||||
|
||||
tree->len++;
|
||||
}
|
||||
|
||||
(*btree->close)(btree);
|
||||
(*idx->close)(idx);
|
||||
|
||||
free(buf);
|
||||
recfree(&r);
|
||||
return(1 == ch);
|
||||
}
|
||||
|
||||
static void
|
||||
recfree(struct rec *rec)
|
||||
{
|
||||
|
||||
free(rec->res.file);
|
||||
free(rec->res.cat);
|
||||
free(rec->res.title);
|
||||
free(rec->res.arch);
|
||||
free(rec->res.desc);
|
||||
|
||||
free(rec->matches);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile a list of straight-up terms.
|
||||
* The arguments are re-written into ~[[:<:]]term[[:>:]], or "term"
|
||||
* surrounded by word boundaries, then pumped through exprterm().
|
||||
* Terms are case-insensitive.
|
||||
* This emulates whatis(1) behaviour.
|
||||
*/
|
||||
struct expr *
|
||||
termcomp(int argc, char *argv[], size_t *tt)
|
||||
{
|
||||
char *buf;
|
||||
int pos;
|
||||
struct expr *e, *next;
|
||||
size_t sz;
|
||||
|
||||
buf = NULL;
|
||||
e = NULL;
|
||||
*tt = 0;
|
||||
|
||||
for (pos = argc - 1; pos >= 0; pos--) {
|
||||
sz = strlen(argv[pos]) + 18;
|
||||
buf = mandoc_realloc(buf, sz);
|
||||
strlcpy(buf, "Nm~[[:<:]]", sz);
|
||||
strlcat(buf, argv[pos], sz);
|
||||
strlcat(buf, "[[:>:]]", sz);
|
||||
if (NULL == (next = exprterm(buf, 0))) {
|
||||
free(buf);
|
||||
exprfree(e);
|
||||
return(NULL);
|
||||
}
|
||||
next->next = e;
|
||||
e = next;
|
||||
(*tt)++;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return(e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile a sequence of logical expressions.
|
||||
* See apropos.1 for a grammar of this sequence.
|
||||
*/
|
||||
struct expr *
|
||||
exprcomp(int argc, char *argv[], size_t *tt)
|
||||
{
|
||||
int pos, lvl;
|
||||
struct expr *e;
|
||||
|
||||
pos = lvl = 0;
|
||||
*tt = 0;
|
||||
|
||||
e = exprexpr(argc, argv, &pos, &lvl, tt);
|
||||
|
||||
if (0 == lvl && pos >= argc)
|
||||
return(e);
|
||||
|
||||
exprfree(e);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile an array of tokens into an expression.
|
||||
* An informal expression grammar is defined in apropos(1).
|
||||
* Return NULL if we fail doing so. All memory will be cleaned up.
|
||||
* Return the root of the expression sequence if alright.
|
||||
*/
|
||||
static struct expr *
|
||||
exprexpr(int argc, char *argv[], int *pos, int *lvl, size_t *tt)
|
||||
{
|
||||
struct expr *e, *first, *next;
|
||||
int log;
|
||||
|
||||
first = next = NULL;
|
||||
|
||||
for ( ; *pos < argc; (*pos)++) {
|
||||
e = next;
|
||||
|
||||
/*
|
||||
* Close out a subexpression.
|
||||
*/
|
||||
|
||||
if (NULL != e && 0 == strcmp(")", argv[*pos])) {
|
||||
if (--(*lvl) < 0)
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Small note: if we're just starting, don't let "-a"
|
||||
* and "-o" be considered logical operators: they're
|
||||
* just tokens unless pairwise joining, in which case we
|
||||
* record their existence (or assume "OR").
|
||||
*/
|
||||
log = 0;
|
||||
|
||||
if (NULL != e && 0 == strcmp("-a", argv[*pos]))
|
||||
log = 1;
|
||||
else if (NULL != e && 0 == strcmp("-o", argv[*pos]))
|
||||
log = 2;
|
||||
|
||||
if (log > 0 && ++(*pos) >= argc)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Now we parse the term part. This can begin with
|
||||
* "-i", in which case the expression is case
|
||||
* insensitive.
|
||||
*/
|
||||
|
||||
if (0 == strcmp("(", argv[*pos])) {
|
||||
++(*pos);
|
||||
++(*lvl);
|
||||
next = mandoc_calloc(1, sizeof(struct expr));
|
||||
next->subexpr = exprexpr(argc, argv, pos, lvl, tt);
|
||||
if (NULL == next->subexpr) {
|
||||
free(next);
|
||||
next = NULL;
|
||||
}
|
||||
} else if (0 == strcmp("-i", argv[*pos])) {
|
||||
if (++(*pos) >= argc)
|
||||
goto err;
|
||||
next = exprterm(argv[*pos], 0);
|
||||
} else
|
||||
next = exprterm(argv[*pos], 1);
|
||||
|
||||
if (NULL == next)
|
||||
goto err;
|
||||
|
||||
next->and = log == 1;
|
||||
next->index = (int)(*tt)++;
|
||||
|
||||
/* Append to our chain of expressions. */
|
||||
|
||||
if (NULL == first) {
|
||||
assert(NULL == e);
|
||||
first = next;
|
||||
} else {
|
||||
assert(NULL != e);
|
||||
e->next = next;
|
||||
}
|
||||
}
|
||||
|
||||
return(first);
|
||||
err:
|
||||
exprfree(first);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a terminal expression with the grammar as defined in
|
||||
* apropos(1).
|
||||
* Return NULL if we fail the parse.
|
||||
*/
|
||||
static struct expr *
|
||||
exprterm(char *buf, int cs)
|
||||
{
|
||||
struct expr e;
|
||||
struct expr *p;
|
||||
char *key;
|
||||
int i;
|
||||
|
||||
memset(&e, 0, sizeof(struct expr));
|
||||
|
||||
/* Choose regex or substring match. */
|
||||
|
||||
if (NULL == (e.v = strpbrk(buf, "=~"))) {
|
||||
e.regex = 0;
|
||||
e.v = buf;
|
||||
} else {
|
||||
e.regex = '~' == *e.v;
|
||||
*e.v++ = '\0';
|
||||
}
|
||||
|
||||
/* Determine the record types to search for. */
|
||||
|
||||
e.mask = 0;
|
||||
if (buf < e.v) {
|
||||
while (NULL != (key = strsep(&buf, ","))) {
|
||||
i = 0;
|
||||
while (types[i].mask &&
|
||||
strcmp(types[i].name, key))
|
||||
i++;
|
||||
e.mask |= types[i].mask;
|
||||
}
|
||||
}
|
||||
if (0 == e.mask)
|
||||
e.mask = TYPE_Nm | TYPE_Nd;
|
||||
|
||||
if (e.regex) {
|
||||
i = REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE);
|
||||
if (regcomp(&e.re, e.v, i))
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
e.v = mandoc_strdup(e.v);
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct expr));
|
||||
memcpy(p, &e, sizeof(struct expr));
|
||||
return(p);
|
||||
}
|
||||
|
||||
void
|
||||
exprfree(struct expr *p)
|
||||
{
|
||||
struct expr *pp;
|
||||
|
||||
while (NULL != p) {
|
||||
if (p->subexpr)
|
||||
exprfree(p->subexpr);
|
||||
if (p->regex)
|
||||
regfree(&p->re);
|
||||
free(p->v);
|
||||
pp = p->next;
|
||||
free(p);
|
||||
p = pp;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
exprmark(const struct expr *p, const char *cp,
|
||||
uint64_t mask, int *ms)
|
||||
{
|
||||
|
||||
for ( ; p; p = p->next) {
|
||||
if (p->subexpr) {
|
||||
if (exprmark(p->subexpr, cp, mask, ms))
|
||||
return(1);
|
||||
continue;
|
||||
} else if ( ! (mask & p->mask))
|
||||
continue;
|
||||
|
||||
if (p->regex) {
|
||||
if (regexec(&p->re, cp, 0, NULL, 0))
|
||||
continue;
|
||||
} else if (NULL == strcasestr(cp, p->v))
|
||||
continue;
|
||||
|
||||
if (NULL == ms)
|
||||
return(1);
|
||||
else
|
||||
ms[p->index] = 1;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
expreval(const struct expr *p, int *ms)
|
||||
{
|
||||
int match;
|
||||
|
||||
/*
|
||||
* AND has precedence over OR. Analysis is left-right, though
|
||||
* it doesn't matter because there are no side-effects.
|
||||
* Thus, step through pairwise ANDs and accumulate their Boolean
|
||||
* evaluation. If we encounter a single true AND collection or
|
||||
* standalone term, the whole expression is true (by definition
|
||||
* of OR).
|
||||
*/
|
||||
|
||||
for (match = 0; p && ! match; p = p->next) {
|
||||
/* Evaluate a subexpression, if applicable. */
|
||||
if (p->subexpr && ! ms[p->index])
|
||||
ms[p->index] = expreval(p->subexpr, ms);
|
||||
|
||||
match = ms[p->index];
|
||||
for ( ; p->next && p->next->and; p = p->next) {
|
||||
/* Evaluate a subexpression, if applicable. */
|
||||
if (p->next->subexpr && ! ms[p->next->index])
|
||||
ms[p->next->index] =
|
||||
expreval(p->next->subexpr, ms);
|
||||
match = match && ms[p->next->index];
|
||||
}
|
||||
}
|
||||
|
||||
return(match);
|
||||
}
|
||||
|
||||
/*
|
||||
* First, update the array of terms for which this expression evaluates
|
||||
* to true.
|
||||
* Second, logically evaluate all terms over the updated array of truth
|
||||
* values.
|
||||
* If this evaluates to true, mark the expression as satisfied.
|
||||
*/
|
||||
static void
|
||||
exprexec(const struct expr *e, const char *cp,
|
||||
uint64_t mask, struct rec *r)
|
||||
{
|
||||
|
||||
assert(0 == r->matched);
|
||||
exprmark(e, cp, mask, r->matches);
|
||||
r->matched = expreval(e, r->matches);
|
||||
}
|
59
external/bsd/mdocml/dist/apropos_db.h
vendored
Normal file
59
external/bsd/mdocml/dist/apropos_db.h
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* $Vendor-Id: apropos_db.h,v 1.11 2011/12/16 12:06:35 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifndef APROPOS_H
|
||||
#define APROPOS_H
|
||||
|
||||
enum restype {
|
||||
RESTYPE_MAN, /* man(7) file */
|
||||
RESTYPE_MDOC, /* mdoc(7) file */
|
||||
RESTYPE_CAT /* pre-formatted file */
|
||||
};
|
||||
|
||||
struct res {
|
||||
enum restype type; /* input file type */
|
||||
char *file; /* file in file-system */
|
||||
char *cat; /* category (3p, 3, etc.) */
|
||||
char *title; /* title (FOO, etc.) */
|
||||
char *arch; /* arch (or empty string) */
|
||||
char *desc; /* description (from Nd) */
|
||||
unsigned int rec; /* record in index */
|
||||
/*
|
||||
* The index volume. This indexes into the array of directories
|
||||
* searched for manual page databases.
|
||||
*/
|
||||
unsigned int volume;
|
||||
};
|
||||
|
||||
struct opts {
|
||||
const char *arch; /* restrict to architecture */
|
||||
const char *cat; /* restrict to manual section */
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct expr;
|
||||
|
||||
int apropos_search(int, char **, const struct opts *,
|
||||
const struct expr *, size_t, void *,
|
||||
void (*)(struct res *, size_t, void *));
|
||||
struct expr *exprcomp(int, char *[], size_t *);
|
||||
void exprfree(struct expr *);
|
||||
struct expr *termcomp(int, char *[], size_t *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!APROPOS_H*/
|
3
external/bsd/mdocml/dist/arch.c
vendored
3
external/bsd/mdocml/dist/arch.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: arch.c,v 1.8 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/* $Vendor-Id: arch.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
|
|
57
external/bsd/mdocml/dist/arch.in
vendored
57
external/bsd/mdocml/dist/arch.in
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: arch.in,v 1.10 2010/09/27 06:56:44 kristaps Exp $ */
|
||||
/* $Vendor-Id: arch.in,v 1.12 2012/01/28 14:02:17 joerg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -26,31 +26,86 @@
|
|||
* REMEMBER TO ADD NEW ARCHITECTURES TO MDOC.7!
|
||||
*/
|
||||
|
||||
LINE("acorn26", "Acorn26")
|
||||
LINE("acorn32", "Acorn32")
|
||||
LINE("algor", "Algor")
|
||||
LINE("alpha", "Alpha")
|
||||
LINE("amd64", "AMD64")
|
||||
LINE("amiga", "Amiga")
|
||||
LINE("amigappc", "AmigaPPC")
|
||||
LINE("arc", "ARC")
|
||||
LINE("arm", "ARM")
|
||||
LINE("arm26", "ARM26")
|
||||
LINE("arm32", "ARM32")
|
||||
LINE("armish", "ARMISH")
|
||||
LINE("aviion", "AViiON")
|
||||
LINE("atari", "ATARI")
|
||||
LINE("beagle", "Beagle")
|
||||
LINE("bebox", "BeBox")
|
||||
LINE("cats", "cats")
|
||||
LINE("cesfic", "CESFIC")
|
||||
LINE("cobalt", "Cobalt")
|
||||
LINE("dreamcast", "Dreamcast")
|
||||
LINE("emips", "EMIPS")
|
||||
LINE("evbarm", "evbARM")
|
||||
LINE("evbmips", "evbMIPS")
|
||||
LINE("evbppc", "evbPPC")
|
||||
LINE("evbsh3", "evbSH3")
|
||||
LINE("ews4800mips", "EWS4800MIPS")
|
||||
LINE("hp300", "HP300")
|
||||
LINE("hp700", "HP700")
|
||||
LINE("hpcarm", "HPCARM")
|
||||
LINE("hpcmips", "HPCMIPS")
|
||||
LINE("hpcsh", "HPCSH")
|
||||
LINE("hppa", "HPPA")
|
||||
LINE("hppa64", "HPPA64")
|
||||
LINE("ia64", "ia64")
|
||||
LINE("i386", "i386")
|
||||
LINE("ibmnws", "IBMNWS")
|
||||
LINE("iyonix", "Iyonix")
|
||||
LINE("landisk", "LANDISK")
|
||||
LINE("loongson", "Loongson")
|
||||
LINE("luna68k", "Luna68k")
|
||||
LINE("luna88k", "Luna88k")
|
||||
LINE("m68k", "m68k")
|
||||
LINE("mac68k", "Mac68k")
|
||||
LINE("macppc", "MacPPC")
|
||||
LINE("mips", "MIPS")
|
||||
LINE("mips64", "MIPS64")
|
||||
LINE("mipsco", "MIPSCo")
|
||||
LINE("mmeye", "mmEye")
|
||||
LINE("mvme68k", "MVME68k")
|
||||
LINE("mvme88k", "MVME88k")
|
||||
LINE("mvmeppc", "MVMEPPC")
|
||||
LINE("netwinder", "NetWinder")
|
||||
LINE("news68k", "NeWS68k")
|
||||
LINE("newsmips", "NeWSMIPS")
|
||||
LINE("next68k", "NeXT68k")
|
||||
LINE("ofppc", "OFPPC")
|
||||
LINE("palm", "Palm")
|
||||
LINE("pc532", "PC532")
|
||||
LINE("playstation2", "PlayStation2")
|
||||
LINE("pmax", "PMAX")
|
||||
LINE("pmppc", "pmPPC")
|
||||
LINE("powerpc", "PowerPC")
|
||||
LINE("prep", "PReP")
|
||||
LINE("rs6000", "RS6000")
|
||||
LINE("sandpoint", "Sandpoint")
|
||||
LINE("sbmips", "SBMIPS")
|
||||
LINE("sgi", "SGI")
|
||||
LINE("sgimips", "SGIMIPS")
|
||||
LINE("sh3", "SH3")
|
||||
LINE("shark", "Shark")
|
||||
LINE("socppc", "SOCPPC")
|
||||
LINE("solbourne", "Solbourne")
|
||||
LINE("sparc", "SPARC")
|
||||
LINE("sparc64", "SPARC64")
|
||||
LINE("sun2", "Sun2")
|
||||
LINE("sun3", "Sun3")
|
||||
LINE("tahoe", "Tahoe")
|
||||
LINE("vax", "VAX")
|
||||
LINE("x68k", "X68k")
|
||||
LINE("x86", "x86")
|
||||
LINE("x86_64", "x86_64")
|
||||
LINE("xen", "Xen")
|
||||
LINE("zaurus", "Zaurus")
|
||||
|
|
3
external/bsd/mdocml/dist/att.c
vendored
3
external/bsd/mdocml/dist/att.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: att.c,v 1.8 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/* $Vendor-Id: att.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
|
|
31
external/bsd/mdocml/dist/att.in
vendored
31
external/bsd/mdocml/dist/att.in
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: att.in,v 1.6 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/* $Vendor-Id: att.in,v 1.8 2011/07/31 17:30:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -20,18 +20,21 @@
|
|||
* isn't going to change. The right-hand side is the formatted string.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
* The non-breaking blanks prevent ending an output line right before
|
||||
* a number. Groff prevent line breaks at the same places.
|
||||
*/
|
||||
|
||||
LINE("v1", "Version 1 AT&T UNIX")
|
||||
LINE("v2", "Version 2 AT&T UNIX")
|
||||
LINE("v3", "Version 3 AT&T UNIX")
|
||||
LINE("v4", "Version 4 AT&T UNIX")
|
||||
LINE("v5", "Version 5 AT&T UNIX")
|
||||
LINE("v6", "Version 6 AT&T UNIX")
|
||||
LINE("v7", "Version 7 AT&T UNIX")
|
||||
LINE("32v", "Version 32V AT&T UNIX")
|
||||
LINE("V", "AT&T System V UNIX")
|
||||
LINE("V.1", "AT&T System V.1 UNIX")
|
||||
LINE("V.2", "AT&T System V.2 UNIX")
|
||||
LINE("V.3", "AT&T System V.3 UNIX")
|
||||
LINE("V.4", "AT&T System V.4 UNIX")
|
||||
LINE("v1", "Version\\~1 AT&T UNIX")
|
||||
LINE("v2", "Version\\~2 AT&T UNIX")
|
||||
LINE("v3", "Version\\~3 AT&T UNIX")
|
||||
LINE("v4", "Version\\~4 AT&T UNIX")
|
||||
LINE("v5", "Version\\~5 AT&T UNIX")
|
||||
LINE("v6", "Version\\~6 AT&T UNIX")
|
||||
LINE("v7", "Version\\~7 AT&T UNIX")
|
||||
LINE("32v", "Version\\~32V AT&T UNIX")
|
||||
LINE("III", "AT&T System\\~III UNIX")
|
||||
LINE("V", "AT&T System\\~V UNIX")
|
||||
LINE("V.1", "AT&T System\\~V Release\\~1 UNIX")
|
||||
LINE("V.2", "AT&T System\\~V Release\\~2 UNIX")
|
||||
LINE("V.3", "AT&T System\\~V Release\\~3 UNIX")
|
||||
LINE("V.4", "AT&T System\\~V Release\\~4 UNIX")
|
||||
|
|
111
external/bsd/mdocml/dist/catman.8
vendored
Normal file
111
external/bsd/mdocml/dist/catman.8
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
.\" $Vendor-Id: catman.8,v 1.5 2011/12/25 19:35:44 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd December 25, 2011
|
||||
.Dt CATMAN 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm catman
|
||||
.Nd update a man.cgi manpage cache
|
||||
.Sh SYNOPSIS
|
||||
.Nm catman
|
||||
.Op Fl fv
|
||||
.Op Fl C Ar file
|
||||
.Op Fl M Ar manpath
|
||||
.Op Fl m Ar manpath
|
||||
.Op Fl o Ar path
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility updates cached manpages for a jailed
|
||||
.Xr man.cgi 7 .
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
searches for
|
||||
.Xr mandocdb 8
|
||||
databases in the default paths stipulated by
|
||||
.Xr man 1
|
||||
and updates the cache in
|
||||
.Pa /var/www/cache/man.cgi .
|
||||
.Pp
|
||||
Its arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl f
|
||||
Force an update to all files.
|
||||
.It Fl v
|
||||
Print each file being updated.
|
||||
.It Fl C Ar file
|
||||
Specify an alternative configuration
|
||||
.Ar file
|
||||
in
|
||||
.Xr man.conf 5
|
||||
format.
|
||||
.It Fl M Ar manpath
|
||||
Use the colon-separated path instead of the default list of paths
|
||||
searched for
|
||||
.Xr mandocdb 8
|
||||
databases.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
.It Fl m Ar manpath
|
||||
Prepend the colon-separated paths to the list of paths searched
|
||||
for
|
||||
.Xr mandocdb 8
|
||||
databases.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
.It Fl o Ar path
|
||||
Update into the directory tree under
|
||||
.Ar path .
|
||||
.El
|
||||
.Pp
|
||||
Cache updates occur when a
|
||||
.Xr mandocdb 8
|
||||
database is older than the cached copy unless
|
||||
.Fl f
|
||||
is specified, in which case files are always considered out of date.
|
||||
Cached manual pages are only updated if older than the master copy.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width Ds
|
||||
.It Ev MANPATH
|
||||
Colon-separated paths modifying the default list of paths searched for
|
||||
manual databases.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
Overridden by
|
||||
.Fl M .
|
||||
If
|
||||
.Ev MANPATH
|
||||
begins with a
|
||||
.Sq \&: ,
|
||||
it is appended to the default list;
|
||||
else if it ends with
|
||||
.Sq \&: ,
|
||||
it is prepended to the default list; else if it contains
|
||||
.Sq \&:: ,
|
||||
the default list is inserted between the colons.
|
||||
If none of these conditions are met, it overrides the default list.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man.cgi 7 ,
|
||||
.Xr mandocdb 8
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
511
external/bsd/mdocml/dist/catman.c
vendored
Normal file
511
external/bsd/mdocml/dist/catman.c
vendored
Normal file
|
@ -0,0 +1,511 @@
|
|||
/* $Vendor-Id: catman.c,v 1.10 2012/01/03 15:17:20 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# include <db_185.h>
|
||||
#else
|
||||
# include <db.h>
|
||||
#endif
|
||||
|
||||
#include "manpath.h"
|
||||
#include "mandocdb.h"
|
||||
|
||||
#define xstrlcpy(_dst, _src, _sz) \
|
||||
do if (strlcpy((_dst), (_src), (_sz)) >= (_sz)) { \
|
||||
fprintf(stderr, "%s: Path too long", (_dst)); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} while (/* CONSTCOND */0)
|
||||
|
||||
#define xstrlcat(_dst, _src, _sz) \
|
||||
do if (strlcat((_dst), (_src), (_sz)) >= (_sz)) { \
|
||||
fprintf(stderr, "%s: Path too long", (_dst)); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} while (/* CONSTCOND */0)
|
||||
|
||||
static int indexhtml(char *, size_t, char *, size_t);
|
||||
static int manup(const struct manpaths *, char *);
|
||||
static int mkpath(char *, mode_t, mode_t);
|
||||
static int treecpy(char *, char *);
|
||||
static int update(char *, char *);
|
||||
static void usage(void);
|
||||
|
||||
static const char *progname;
|
||||
static int verbose;
|
||||
static int force;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
char *aux, *base, *conf_file;
|
||||
struct manpaths dirs;
|
||||
char buf[MAXPATHLEN];
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
++progname;
|
||||
|
||||
aux = base = conf_file = NULL;
|
||||
xstrlcpy(buf, "/var/www/cache/man.cgi", MAXPATHLEN);
|
||||
|
||||
while (-1 != (ch = getopt(argc, argv, "C:fm:M:o:v")))
|
||||
switch (ch) {
|
||||
case ('C'):
|
||||
conf_file = optarg;
|
||||
break;
|
||||
case ('f'):
|
||||
force = 1;
|
||||
break;
|
||||
case ('m'):
|
||||
aux = optarg;
|
||||
break;
|
||||
case ('M'):
|
||||
base = optarg;
|
||||
break;
|
||||
case ('o'):
|
||||
xstrlcpy(buf, optarg, MAXPATHLEN);
|
||||
break;
|
||||
case ('v'):
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 0) {
|
||||
usage();
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(&dirs, 0, sizeof(struct manpaths));
|
||||
manpath_parse(&dirs, conf_file, base, aux);
|
||||
ch = manup(&dirs, buf);
|
||||
manpath_free(&dirs);
|
||||
return(ch ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s "
|
||||
"[-fv] "
|
||||
"[-C file] "
|
||||
"[-o path] "
|
||||
"[-m manpath] "
|
||||
"[-M manpath]\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
/*
|
||||
* If "src" file doesn't exist (errors out), return -1. Otherwise,
|
||||
* return 1 if "src" is newer (which also happens "dst" doesn't exist)
|
||||
* and 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
isnewer(const char *dst, const char *src)
|
||||
{
|
||||
struct stat s1, s2;
|
||||
|
||||
if (-1 == stat(src, &s1))
|
||||
return(-1);
|
||||
if (force)
|
||||
return(1);
|
||||
|
||||
return(-1 == stat(dst, &s2) ? 1 : s1.st_mtime > s2.st_mtime);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the contents of one file into another.
|
||||
* Returns 0 on failure, 1 on success.
|
||||
*/
|
||||
static int
|
||||
filecpy(const char *dst, const char *src)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
int sfd, dfd, rc;
|
||||
ssize_t rsz, wsz;
|
||||
|
||||
sfd = dfd = -1;
|
||||
rc = 0;
|
||||
|
||||
if (-1 == (dfd = open(dst, O_CREAT|O_TRUNC|O_WRONLY, 0644))) {
|
||||
perror(dst);
|
||||
goto out;
|
||||
} else if (-1 == (sfd = open(src, O_RDONLY, 0))) {
|
||||
perror(src);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((rsz = read(sfd, buf, BUFSIZ)) > 0)
|
||||
if (-1 == (wsz = write(dfd, buf, (size_t)rsz))) {
|
||||
perror(dst);
|
||||
goto out;
|
||||
} else if (wsz < rsz) {
|
||||
fprintf(stderr, "%s: Short write\n", dst);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rsz < 0)
|
||||
perror(src);
|
||||
else
|
||||
rc = 1;
|
||||
out:
|
||||
if (-1 != sfd)
|
||||
close(sfd);
|
||||
if (-1 != dfd)
|
||||
close(dfd);
|
||||
|
||||
return(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass over the recno database and re-create HTML pages if they're
|
||||
* found to be out of date.
|
||||
* Returns -1 on fatal error, 1 on success.
|
||||
*/
|
||||
static int
|
||||
indexhtml(char *src, size_t ssz, char *dst, size_t dsz)
|
||||
{
|
||||
DB *idx;
|
||||
DBT key, val;
|
||||
int c, rc;
|
||||
unsigned int fl;
|
||||
const char *f;
|
||||
char *d;
|
||||
char fname[MAXPATHLEN];
|
||||
pid_t pid;
|
||||
|
||||
pid = -1;
|
||||
|
||||
xstrlcpy(fname, dst, MAXPATHLEN);
|
||||
xstrlcat(fname, "/", MAXPATHLEN);
|
||||
xstrlcat(fname, MANDOC_IDX, MAXPATHLEN);
|
||||
|
||||
idx = dbopen(fname, O_RDONLY, 0, DB_RECNO, NULL);
|
||||
if (NULL == idx) {
|
||||
perror(fname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
fl = R_FIRST;
|
||||
while (0 == (c = (*idx->seq)(idx, &key, &val, fl))) {
|
||||
fl = R_NEXT;
|
||||
/*
|
||||
* If the record is zero-length, then it's unassigned.
|
||||
* Skip past these.
|
||||
*/
|
||||
if (0 == val.size)
|
||||
continue;
|
||||
|
||||
f = (const char *)val.data + 1;
|
||||
if (NULL == memchr(f, '\0', val.size - 1))
|
||||
break;
|
||||
|
||||
src[(int)ssz] = dst[(int)dsz] = '\0';
|
||||
|
||||
xstrlcat(dst, "/", MAXPATHLEN);
|
||||
xstrlcat(dst, f, MAXPATHLEN);
|
||||
|
||||
xstrlcat(src, "/", MAXPATHLEN);
|
||||
xstrlcat(src, f, MAXPATHLEN);
|
||||
|
||||
if (-1 == (rc = isnewer(dst, src))) {
|
||||
fprintf(stderr, "%s: File missing\n", f);
|
||||
break;
|
||||
} else if (0 == rc)
|
||||
continue;
|
||||
|
||||
d = strrchr(dst, '/');
|
||||
assert(NULL != d);
|
||||
*d = '\0';
|
||||
|
||||
if (-1 == mkpath(dst, 0755, 0755)) {
|
||||
perror(dst);
|
||||
break;
|
||||
}
|
||||
|
||||
*d = '/';
|
||||
|
||||
if ( ! filecpy(dst, src))
|
||||
break;
|
||||
if (verbose)
|
||||
printf("%s\n", dst);
|
||||
}
|
||||
|
||||
(*idx->close)(idx);
|
||||
|
||||
if (c < 0)
|
||||
perror(fname);
|
||||
else if (0 == c)
|
||||
fprintf(stderr, "%s: Corrupt index\n", fname);
|
||||
|
||||
return(1 == c ? 1 : -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy both recno and btree databases into the destination.
|
||||
* Call in to begin recreating HTML files.
|
||||
* Return -1 on fatal error and 1 if the update went well.
|
||||
*/
|
||||
static int
|
||||
update(char *dst, char *src)
|
||||
{
|
||||
size_t dsz, ssz;
|
||||
|
||||
dsz = strlen(dst);
|
||||
ssz = strlen(src);
|
||||
|
||||
xstrlcat(src, "/", MAXPATHLEN);
|
||||
xstrlcat(dst, "/", MAXPATHLEN);
|
||||
|
||||
xstrlcat(src, MANDOC_DB, MAXPATHLEN);
|
||||
xstrlcat(dst, MANDOC_DB, MAXPATHLEN);
|
||||
|
||||
if ( ! filecpy(dst, src))
|
||||
return(-1);
|
||||
if (verbose)
|
||||
printf("%s\n", dst);
|
||||
|
||||
dst[(int)dsz] = src[(int)ssz] = '\0';
|
||||
|
||||
xstrlcat(src, "/", MAXPATHLEN);
|
||||
xstrlcat(dst, "/", MAXPATHLEN);
|
||||
|
||||
xstrlcat(src, MANDOC_IDX, MAXPATHLEN);
|
||||
xstrlcat(dst, MANDOC_IDX, MAXPATHLEN);
|
||||
|
||||
if ( ! filecpy(dst, src))
|
||||
return(-1);
|
||||
if (verbose)
|
||||
printf("%s\n", dst);
|
||||
|
||||
dst[(int)dsz] = src[(int)ssz] = '\0';
|
||||
|
||||
return(indexhtml(src, ssz, dst, dsz));
|
||||
}
|
||||
|
||||
/*
|
||||
* See if btree or recno databases in the destination are out of date
|
||||
* with respect to a single manpath component.
|
||||
* Return -1 on fatal error, 0 if the source is no longer valid (and
|
||||
* shouldn't be listed), and 1 if the update went well.
|
||||
*/
|
||||
static int
|
||||
treecpy(char *dst, char *src)
|
||||
{
|
||||
size_t dsz, ssz;
|
||||
int rc;
|
||||
|
||||
dsz = strlen(dst);
|
||||
ssz = strlen(src);
|
||||
|
||||
xstrlcat(src, "/", MAXPATHLEN);
|
||||
xstrlcat(dst, "/", MAXPATHLEN);
|
||||
|
||||
xstrlcat(src, MANDOC_IDX, MAXPATHLEN);
|
||||
xstrlcat(dst, MANDOC_IDX, MAXPATHLEN);
|
||||
|
||||
if (-1 == (rc = isnewer(dst, src)))
|
||||
return(0);
|
||||
|
||||
dst[(int)dsz] = src[(int)ssz] = '\0';
|
||||
|
||||
if (1 == rc)
|
||||
return(update(dst, src));
|
||||
|
||||
xstrlcat(src, "/", MAXPATHLEN);
|
||||
xstrlcat(dst, "/", MAXPATHLEN);
|
||||
|
||||
xstrlcat(src, MANDOC_DB, MAXPATHLEN);
|
||||
xstrlcat(dst, MANDOC_DB, MAXPATHLEN);
|
||||
|
||||
if (-1 == (rc = isnewer(dst, src)))
|
||||
return(0);
|
||||
else if (rc == 0)
|
||||
return(1);
|
||||
|
||||
dst[(int)dsz] = src[(int)ssz] = '\0';
|
||||
|
||||
return(update(dst, src));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the destination's file-tree with respect to changes in the
|
||||
* source manpath components.
|
||||
* "Change" is defined by an updated index or btree database.
|
||||
* Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
static int
|
||||
manup(const struct manpaths *dirs, char *base)
|
||||
{
|
||||
char dst[MAXPATHLEN],
|
||||
src[MAXPATHLEN];
|
||||
const char *path;
|
||||
int i, c;
|
||||
size_t sz;
|
||||
FILE *f;
|
||||
|
||||
/* Create the path and file for the catman.conf file. */
|
||||
|
||||
sz = strlen(base);
|
||||
xstrlcpy(dst, base, MAXPATHLEN);
|
||||
xstrlcat(dst, "/etc", MAXPATHLEN);
|
||||
if (-1 == mkpath(dst, 0755, 0755)) {
|
||||
perror(dst);
|
||||
return(0);
|
||||
}
|
||||
|
||||
xstrlcat(dst, "/catman.conf", MAXPATHLEN);
|
||||
if (NULL == (f = fopen(dst, "w"))) {
|
||||
perror(dst);
|
||||
return(0);
|
||||
} else if (verbose)
|
||||
printf("%s\n", dst);
|
||||
|
||||
for (i = 0; i < dirs->sz; i++) {
|
||||
path = dirs->paths[i];
|
||||
dst[(int)sz] = '\0';
|
||||
xstrlcat(dst, path, MAXPATHLEN);
|
||||
if (-1 == mkpath(dst, 0755, 0755)) {
|
||||
perror(dst);
|
||||
break;
|
||||
}
|
||||
|
||||
xstrlcpy(src, path, MAXPATHLEN);
|
||||
if (-1 == (c = treecpy(dst, src)))
|
||||
break;
|
||||
else if (0 == c)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We want to use a relative path here because manpath.h
|
||||
* will realpath() when invoked with man.cgi, and we'll
|
||||
* make sure to chdir() into the cache directory before.
|
||||
*
|
||||
* This allows the cache directory to be in an arbitrary
|
||||
* place, working in both chroot() and non-chroot()
|
||||
* "safe" modes.
|
||||
*/
|
||||
assert('/' == path[0]);
|
||||
fprintf(f, "_whatdb %s/whatis.db\n", path + 1);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return(i == dirs->sz);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
static int
|
||||
mkpath(char *path, mode_t mode, mode_t dir_mode)
|
||||
{
|
||||
struct stat sb;
|
||||
char *slash;
|
||||
int done, exists;
|
||||
|
||||
slash = path;
|
||||
|
||||
for (;;) {
|
||||
/* LINTED */
|
||||
slash += strspn(slash, "/");
|
||||
/* LINTED */
|
||||
slash += strcspn(slash, "/");
|
||||
|
||||
done = (*slash == '\0');
|
||||
*slash = '\0';
|
||||
|
||||
/* skip existing path components */
|
||||
exists = !stat(path, &sb);
|
||||
if (!done && exists && S_ISDIR(sb.st_mode)) {
|
||||
*slash = '/';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mkdir(path, done ? mode : dir_mode) == 0) {
|
||||
if (mode > 0777 && chmod(path, mode) < 0)
|
||||
return (-1);
|
||||
} else {
|
||||
if (!exists) {
|
||||
/* Not there */
|
||||
return (-1);
|
||||
}
|
||||
if (!S_ISDIR(sb.st_mode)) {
|
||||
/* Is there, but isn't a directory */
|
||||
errno = ENOTDIR;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (done)
|
||||
break;
|
||||
|
||||
*slash = '/';
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
1210
external/bsd/mdocml/dist/cgi.c
vendored
Normal file
1210
external/bsd/mdocml/dist/cgi.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
174
external/bsd/mdocml/dist/chars.c
vendored
174
external/bsd/mdocml/dist/chars.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: chars.c,v 1.31 2011/01/02 10:10:57 kristaps Exp $ */
|
||||
/* $Vendor-Id: chars.c,v 1.52 2011/11/08 00:15:23 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -19,12 +20,12 @@
|
|||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "chars.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
#define PRINT_HI 126
|
||||
#define PRINT_LO 32
|
||||
|
@ -34,52 +35,37 @@ struct ln {
|
|||
const char *code;
|
||||
const char *ascii;
|
||||
int unicode;
|
||||
int type;
|
||||
#define CHARS_CHAR (1 << 0)
|
||||
#define CHARS_STRING (1 << 1)
|
||||
#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
|
||||
};
|
||||
|
||||
#define LINES_MAX 351
|
||||
#define LINES_MAX 328
|
||||
|
||||
#define CHAR(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code), CHARS_CHAR },
|
||||
#define STRING(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code), CHARS_STRING },
|
||||
#define BOTH(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code), CHARS_BOTH },
|
||||
{ NULL, (in), (ch), (code) },
|
||||
|
||||
#define CHAR_TBL_START static struct ln lines[LINES_MAX] = {
|
||||
#define CHAR_TBL_END };
|
||||
|
||||
#include "chars.in"
|
||||
|
||||
struct ctab {
|
||||
enum chars type;
|
||||
struct mchars {
|
||||
struct ln **htab;
|
||||
};
|
||||
|
||||
static inline int match(const struct ln *,
|
||||
const char *, size_t, int);
|
||||
static const struct ln *find(struct ctab *, const char *, size_t, int);
|
||||
|
||||
static const struct ln *find(const struct mchars *,
|
||||
const char *, size_t);
|
||||
|
||||
void
|
||||
chars_free(void *arg)
|
||||
mchars_free(struct mchars *arg)
|
||||
{
|
||||
struct ctab *tab;
|
||||
|
||||
tab = (struct ctab *)arg;
|
||||
|
||||
free(tab->htab);
|
||||
free(tab);
|
||||
free(arg->htab);
|
||||
free(arg);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
chars_init(enum chars type)
|
||||
struct mchars *
|
||||
mchars_alloc(void)
|
||||
{
|
||||
struct ctab *tab;
|
||||
struct mchars *tab;
|
||||
struct ln **htab;
|
||||
struct ln *pp;
|
||||
int i, hash;
|
||||
|
@ -87,21 +73,11 @@ chars_init(enum chars type)
|
|||
/*
|
||||
* Constructs a very basic chaining hashtable. The hash routine
|
||||
* is simply the integral value of the first character.
|
||||
* Subsequent entries are chained in the order they're processed
|
||||
* (they're in-line re-ordered during lookup).
|
||||
* Subsequent entries are chained in the order they're processed.
|
||||
*/
|
||||
|
||||
tab = malloc(sizeof(struct ctab));
|
||||
if (NULL == tab) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
|
||||
if (NULL == htab) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
tab = mandoc_malloc(sizeof(struct mchars));
|
||||
htab = mandoc_calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
|
||||
|
||||
for (i = 0; i < LINES_MAX; i++) {
|
||||
hash = (int)lines[i].code[0] - PRINT_LO;
|
||||
|
@ -117,127 +93,75 @@ chars_init(enum chars type)
|
|||
}
|
||||
|
||||
tab->htab = htab;
|
||||
tab->type = type;
|
||||
return(tab);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Special character to Unicode codepoint.
|
||||
*/
|
||||
int
|
||||
chars_spec2cp(void *arg, const char *p, size_t sz)
|
||||
mchars_spec2cp(const struct mchars *arg, const char *p, size_t sz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_CHAR);
|
||||
ln = find(arg, p, sz);
|
||||
if (NULL == ln)
|
||||
return(-1);
|
||||
return(ln->unicode);
|
||||
}
|
||||
|
||||
char
|
||||
mchars_num2char(const char *p, size_t sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((i = mandoc_strntoi(p, sz, 10)) < 0)
|
||||
return('\0');
|
||||
return(i > 0 && i < 256 && isprint(i) ?
|
||||
/* LINTED */ i : '\0');
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserved word to Unicode codepoint.
|
||||
*/
|
||||
int
|
||||
chars_res2cp(void *arg, const char *p, size_t sz)
|
||||
mchars_num2uc(const char *p, size_t sz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
int i;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_STRING);
|
||||
if (NULL == ln)
|
||||
return(-1);
|
||||
return(ln->unicode);
|
||||
if ((i = mandoc_strntoi(p, sz, 16)) < 0)
|
||||
return('\0');
|
||||
/* FIXME: make sure we're not in a bogus range. */
|
||||
return(i > 0x80 && i <= 0x10FFFF ? i : '\0');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Special character to string array.
|
||||
*/
|
||||
const char *
|
||||
chars_spec2str(void *arg, const char *p, size_t sz, size_t *rsz)
|
||||
mchars_spec2str(const struct mchars *arg,
|
||||
const char *p, size_t sz, size_t *rsz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_CHAR);
|
||||
if (NULL == ln)
|
||||
ln = find(arg, p, sz);
|
||||
if (NULL == ln) {
|
||||
*rsz = 1;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
*rsz = strlen(ln->ascii);
|
||||
return(ln->ascii);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reserved word to string array.
|
||||
*/
|
||||
const char *
|
||||
chars_res2str(void *arg, const char *p, size_t sz, size_t *rsz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_STRING);
|
||||
if (NULL == ln)
|
||||
return(NULL);
|
||||
|
||||
*rsz = strlen(ln->ascii);
|
||||
return(ln->ascii);
|
||||
}
|
||||
|
||||
|
||||
static const struct ln *
|
||||
find(struct ctab *tab, const char *p, size_t sz, int type)
|
||||
find(const struct mchars *tab, const char *p, size_t sz)
|
||||
{
|
||||
struct ln *pp, *prev;
|
||||
struct ln **htab;
|
||||
const struct ln *pp;
|
||||
int hash;
|
||||
|
||||
assert(p);
|
||||
if (0 == sz)
|
||||
return(NULL);
|
||||
|
||||
if (p[0] < PRINT_LO || p[0] > PRINT_HI)
|
||||
if (0 == sz || p[0] < PRINT_LO || p[0] > PRINT_HI)
|
||||
return(NULL);
|
||||
|
||||
/*
|
||||
* Lookup the symbol in the symbol hash. See ascii2htab for the
|
||||
* hashtable specs. This dynamically re-orders the hash chain
|
||||
* to optimise for repeat hits.
|
||||
*/
|
||||
|
||||
hash = (int)p[0] - PRINT_LO;
|
||||
htab = tab->htab;
|
||||
|
||||
if (NULL == (pp = htab[hash]))
|
||||
return(NULL);
|
||||
|
||||
for (prev = NULL; pp; pp = pp->next) {
|
||||
if ( ! match(pp, p, sz, type)) {
|
||||
prev = pp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
prev->next = pp->next;
|
||||
pp->next = htab[hash];
|
||||
htab[hash] = pp;
|
||||
}
|
||||
|
||||
for (pp = tab->htab[hash]; pp; pp = pp->next)
|
||||
if (0 == strncmp(pp->code, p, sz) &&
|
||||
'\0' == pp->code[(int)sz])
|
||||
return(pp);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
match(const struct ln *ln, const char *p, size_t sz, int type)
|
||||
{
|
||||
|
||||
if ( ! (ln->type & type))
|
||||
return(0);
|
||||
if (strncmp(ln->code, p, sz))
|
||||
return(0);
|
||||
return('\0' == ln->code[(int)sz]);
|
||||
}
|
||||
|
|
36
external/bsd/mdocml/dist/chars.h
vendored
36
external/bsd/mdocml/dist/chars.h
vendored
|
@ -1,36 +0,0 @@
|
|||
/* $Vendor-Id: chars.h,v 1.6 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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.
|
||||
*/
|
||||
#ifndef CHARS_H
|
||||
#define CHARS_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
enum chars {
|
||||
CHARS_ASCII,
|
||||
CHARS_HTML
|
||||
};
|
||||
|
||||
void *chars_init(enum chars);
|
||||
const char *chars_spec2str(void *, const char *, size_t, size_t *);
|
||||
int chars_spec2cp(void *, const char *, size_t);
|
||||
const char *chars_res2str(void *, const char *, size_t, size_t *);
|
||||
int chars_res2cp(void *, const char *, size_t);
|
||||
void chars_free(void *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!CHARS_H*/
|
70
external/bsd/mdocml/dist/chars.in
vendored
70
external/bsd/mdocml/dist/chars.in
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: chars.in,v 1.35 2010/09/15 13:10:30 kristaps Exp $ */
|
||||
/* $Vendor-Id: chars.in,v 1.42 2011/10/02 10:02:26 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -16,15 +16,12 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* The ASCII translation tables. STRING corresponds to predefined
|
||||
* strings (cf. mdoc_samples.7 and tmac/mdoc/doc-nroff). CHAR
|
||||
* corresponds to special characters (cf. groff_char.7). BOTH contains
|
||||
* sequences that are equivalent in both STRING and CHAR.
|
||||
* The ASCII translation tables.
|
||||
*
|
||||
* Either way, the left-hand side corresponds to the input sequence (\x,
|
||||
* \(xx, \*(xx and so on) whose length is listed second element. The
|
||||
* right-hand side is what's produced by the front-end, with the fourth
|
||||
* element being its length.
|
||||
* The left-hand side corresponds to the input sequence (\x, \(xx, \*(xx
|
||||
* and so on) whose length is listed second element. The right-hand
|
||||
* side is what's produced by the front-end, with the fourth element
|
||||
* being its length.
|
||||
*
|
||||
* XXX - C-escape strings!
|
||||
* XXX - update LINES_MAX if adding more!
|
||||
|
@ -51,10 +48,10 @@ CHAR("a\"", "\"", 779)
|
|||
CHAR("a-", "-", 175)
|
||||
CHAR("a.", ".", 729)
|
||||
CHAR("a^", "^", 770)
|
||||
BOTH("\'", "\'", 769)
|
||||
BOTH("aa", "\'", 769)
|
||||
BOTH("ga", "`", 768)
|
||||
BOTH("`", "`", 768)
|
||||
CHAR("\'", "\'", 769)
|
||||
CHAR("aa", "\'", 769)
|
||||
CHAR("ga", "`", 768)
|
||||
CHAR("`", "`", 768)
|
||||
CHAR("ab", "`", 774)
|
||||
CHAR("ac", ",", 807)
|
||||
CHAR("ad", "\"", 776)
|
||||
|
@ -68,8 +65,8 @@ CHAR("ti", "~", 126)
|
|||
/* Quotes. */
|
||||
CHAR("Bq", ",,", 8222)
|
||||
CHAR("bq", ",", 8218)
|
||||
BOTH("lq", "``", 8220)
|
||||
BOTH("rq", "\'\'", 8221)
|
||||
CHAR("lq", "``", 8220)
|
||||
CHAR("rq", "\'\'", 8221)
|
||||
CHAR("oq", "`", 8216)
|
||||
CHAR("cq", "\'", 8217)
|
||||
CHAR("aq", "\'", 39)
|
||||
|
@ -187,7 +184,7 @@ CHAR(":U", "U", 220)
|
|||
CHAR(":a", "a", 228)
|
||||
CHAR(":e", "e", 235)
|
||||
CHAR(":i", "i", 239)
|
||||
CHAR(":o", "o", 245)
|
||||
CHAR(":o", "o", 246)
|
||||
CHAR(":u", "u", 252)
|
||||
CHAR(":y", "y", 255)
|
||||
CHAR("\'A", "A", 193)
|
||||
|
@ -232,8 +229,8 @@ CHAR("<-", "<-", 8592)
|
|||
CHAR("->", "->", 8594)
|
||||
CHAR("<>", "<>", 8596)
|
||||
CHAR("da", "v", 8595)
|
||||
BOTH("ua", "^", 8593)
|
||||
BOTH("va", "^v", 8597)
|
||||
CHAR("ua", "^", 8593)
|
||||
CHAR("va", "^v", 8597)
|
||||
CHAR("lA", "<=", 8656)
|
||||
CHAR("rA", "=>", 8658)
|
||||
CHAR("hA", "<=>", 8660)
|
||||
|
@ -270,8 +267,8 @@ CHAR("di", "-:-", 247)
|
|||
CHAR("tdi", "-:-", 247)
|
||||
CHAR("f/", "/", 8260)
|
||||
CHAR("**", "*", 8727)
|
||||
BOTH("<=", "<=", 8804)
|
||||
BOTH(">=", ">=", 8805)
|
||||
CHAR("<=", "<=", 8804)
|
||||
CHAR(">=", ">=", 8805)
|
||||
CHAR("<<", "<<", 8810)
|
||||
CHAR(">>", ">>", 8811)
|
||||
CHAR("eq", "=", 61)
|
||||
|
@ -315,6 +312,9 @@ CHAR("Im", "I", 8465)
|
|||
CHAR("Re", "R", 8476)
|
||||
CHAR("pd", "a", 8706)
|
||||
CHAR("-h", "/h", 8463)
|
||||
CHAR("12", "1/2", 189)
|
||||
CHAR("14", "1/4", 188)
|
||||
CHAR("34", "3/4", 190)
|
||||
|
||||
/* Ligatures. */
|
||||
CHAR("ff", "ff", 64256)
|
||||
|
@ -348,34 +348,6 @@ CHAR("Po", "L", 163)
|
|||
CHAR("Cs", "x", 164)
|
||||
CHAR("Fn", "f", 402)
|
||||
|
||||
/* Old style. */
|
||||
STRING("Am", "&", 38)
|
||||
STRING("Ba", "|", 124)
|
||||
STRING("Ge", ">=", 8805)
|
||||
STRING("Gt", ">", 62)
|
||||
STRING("If", "infinity", 0)
|
||||
STRING("Le", "<=", 8804)
|
||||
STRING("Lq", "``", 8220)
|
||||
STRING("Lt", "<", 60)
|
||||
STRING("Na", "NaN", 0)
|
||||
STRING("Ne", "!=", 8800)
|
||||
STRING("Pi", "pi", 960)
|
||||
STRING("Pm", "+-", 177)
|
||||
STRING("Rq", "\'\'", 8221)
|
||||
STRING("left-bracket", "[", 91)
|
||||
STRING("left-parenthesis", "(", 40)
|
||||
STRING("left-singlequote", "`", 8216)
|
||||
STRING("lp", "(", 40)
|
||||
STRING("q", "\"", 34)
|
||||
STRING("quote-left", "`", 8216)
|
||||
STRING("quote-right", "\'", 8217)
|
||||
STRING("R", "(R)", 174)
|
||||
STRING("right-bracket", "]", 93)
|
||||
STRING("right-parenthesis", ")", 41)
|
||||
STRING("right-singlequote", "\'", 8217)
|
||||
STRING("rp", ")", 41)
|
||||
STRING("Tm", "(Tm)", 8482)
|
||||
|
||||
/* Lines. */
|
||||
CHAR("ba", "|", 124)
|
||||
CHAR("br", "|", 9474)
|
||||
|
|
93
external/bsd/mdocml/dist/compat_fgetln.c
vendored
Normal file
93
external/bsd/mdocml/dist/compat_fgetln.c
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FGETLN
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $NetBSD: compat_fgetln.c,v 1.2 2012/01/30 17:03:01 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
fgetln(fp, len)
|
||||
FILE *fp;
|
||||
size_t *len;
|
||||
{
|
||||
static char *buf = NULL;
|
||||
static size_t bufsiz = 0;
|
||||
char *ptr;
|
||||
|
||||
|
||||
if (buf == NULL) {
|
||||
bufsiz = BUFSIZ;
|
||||
if ((buf = malloc(bufsiz)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fgets(buf, bufsiz, fp) == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = 0;
|
||||
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
|
||||
size_t nbufsiz = bufsiz + BUFSIZ;
|
||||
char *nbuf = realloc(buf, nbufsiz);
|
||||
|
||||
if (nbuf == NULL) {
|
||||
int oerrno = errno;
|
||||
free(buf);
|
||||
errno = oerrno;
|
||||
buf = NULL;
|
||||
return NULL;
|
||||
} else
|
||||
buf = nbuf;
|
||||
|
||||
*len = bufsiz;
|
||||
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
|
||||
return buf;
|
||||
|
||||
bufsiz = nbufsiz;
|
||||
}
|
||||
|
||||
*len = (ptr - buf) + 1;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif
|
104
external/bsd/mdocml/dist/compat_getsubopt.c
vendored
Normal file
104
external/bsd/mdocml/dist/compat_getsubopt.c
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETSUBOPT
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $OpenBSD: getsubopt.c,v 1.4 2005/08/08 08:05:36 espie Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* The SVID interface to getsubopt provides no way of figuring out which
|
||||
* part of the suboptions list wasn't matched. This makes error messages
|
||||
* tricky... The extern variable suboptarg is a pointer to the token
|
||||
* which didn't match.
|
||||
*/
|
||||
char *suboptarg;
|
||||
|
||||
int
|
||||
getsubopt(char **optionp, char * const *tokens, char **valuep)
|
||||
{
|
||||
int cnt;
|
||||
char *p;
|
||||
|
||||
suboptarg = *valuep = NULL;
|
||||
|
||||
if (!optionp || !*optionp)
|
||||
return(-1);
|
||||
|
||||
/* skip leading white-space, commas */
|
||||
for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
|
||||
|
||||
if (!*p) {
|
||||
*optionp = p;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* save the start of the token, and skip the rest of the token. */
|
||||
for (suboptarg = p;
|
||||
*++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
|
||||
|
||||
if (*p) {
|
||||
/*
|
||||
* If there's an equals sign, set the value pointer, and
|
||||
* skip over the value part of the token. Terminate the
|
||||
* token.
|
||||
*/
|
||||
if (*p == '=') {
|
||||
*p = '\0';
|
||||
for (*valuep = ++p;
|
||||
*p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
} else
|
||||
*p++ = '\0';
|
||||
/* Skip any whitespace or commas after this token. */
|
||||
for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
|
||||
}
|
||||
|
||||
/* set optionp for next round. */
|
||||
*optionp = p;
|
||||
|
||||
for (cnt = 0; *tokens; ++tokens, ++cnt)
|
||||
if (!strcmp(suboptarg, *tokens))
|
||||
return(cnt);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,3 +1,13 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRLCAT
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -15,16 +25,10 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
int dummy; /* To prevent an empty object file */
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
|
@ -59,37 +63,5 @@ strlcat(char *dst, const char *src, size_t siz)
|
|||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0) {
|
||||
while (--n != 0) {
|
||||
if ((*d++ = *s++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
63
external/bsd/mdocml/dist/compat_strlcpy.c
vendored
Normal file
63
external/bsd/mdocml/dist/compat_strlcpy.c
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRLCPY
|
||||
|
||||
int dummy;
|
||||
|
||||
#else
|
||||
|
||||
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0) {
|
||||
while (--n != 0) {
|
||||
if ((*d++ = *s++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif
|
17
external/bsd/mdocml/dist/config.h.post
vendored
17
external/bsd/mdocml/dist/config.h.post
vendored
|
@ -15,11 +15,28 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# define htobe32(x) OSSwapHostToBigInt32(x)
|
||||
# define betoh32(x) OSSwapBigToHostInt32(x)
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define betoh64(x) OSSwapBigToHostInt64(x)
|
||||
#elif defined(__linux__)
|
||||
# define betoh32(x) be32toh(x)
|
||||
# define betoh64(x) be64toh(x)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
extern size_t strlcat(char *, const char *, size_t);
|
||||
#endif
|
||||
#ifndef HAVE_STRLCPY
|
||||
extern size_t strlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
#ifndef HAVE_GETSUBOPT
|
||||
extern int getsubopt(char **, char * const *, char **);
|
||||
extern char *suboptarg;
|
||||
#endif
|
||||
#ifndef HAVE_FGETLN
|
||||
extern char *fgetln(FILE *, size_t *);
|
||||
#endif
|
||||
|
||||
#endif /* MANDOC_CONFIG_H */
|
||||
|
|
2
external/bsd/mdocml/dist/config.h.pre
vendored
2
external/bsd/mdocml/dist/config.h.pre
vendored
|
@ -4,3 +4,5 @@
|
|||
#if defined(__linux__) || defined(__MINT__)
|
||||
# define _GNU_SOURCE /* strptime(), getsubopt() */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
109
external/bsd/mdocml/dist/demandoc.1
vendored
Normal file
109
external/bsd/mdocml/dist/demandoc.1
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
.\" $Vendor-Id: demandoc.1,v 1.6 2011/12/25 19:35:44 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd December 25, 2011
|
||||
.Dt DEMANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm demandoc
|
||||
.Nd emit only text of UNIX manuals
|
||||
.Sh SYNOPSIS
|
||||
.Nm demandoc
|
||||
.Op Fl w
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility emits only the text portions of well-formed
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
.Ux
|
||||
manual files.
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
parses standard input and outputs only text nodes, preserving line
|
||||
and column position.
|
||||
Escape sequences are omitted from the output.
|
||||
.Pp
|
||||
Its arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl w
|
||||
Output a word list.
|
||||
This outputs each word of text on its own line.
|
||||
A
|
||||
.Qq word ,
|
||||
in this case, refers to whitespace-delimited terms beginning with at
|
||||
least two letters and not consisting of any escape sequences.
|
||||
Words have their leading and trailing punctuation
|
||||
.Pq double-quotes, sentence punctuation, etc.
|
||||
stripped.
|
||||
.It Ar
|
||||
The input files.
|
||||
.El
|
||||
.Pp
|
||||
If a document is not well-formed, it is skipped.
|
||||
.Pp
|
||||
The
|
||||
.Fl i ,
|
||||
.Fl k ,
|
||||
.Fl m ,
|
||||
and
|
||||
.Fl p
|
||||
flags are silently discarded for calling compatibility with the
|
||||
historical deroff.
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits with one of the following values:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It 0
|
||||
No errors occurred.
|
||||
.It 6
|
||||
An operating system error occurred, for example memory exhaustion or an
|
||||
error accessing input files.
|
||||
Such errors cause
|
||||
.Nm
|
||||
to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
The output databases are corrupt and should be removed .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The traditional usage of
|
||||
.Nm
|
||||
is for spell-checking manuals on
|
||||
.Bx .
|
||||
This is accomplished as follows (assuming British spelling):
|
||||
.Pp
|
||||
.Dl $ demandoc -w file.1 | spell -b
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7
|
||||
.Xr mdoc 7
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
replaces the historical deroff utility for handling modern
|
||||
.Xr man 7
|
||||
and
|
||||
.Xr mdoc 7
|
||||
documents.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
257
external/bsd/mdocml/dist/demandoc.c
vendored
Normal file
257
external/bsd/mdocml/dist/demandoc.c
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
/* $Vendor-Id: demandoc.c,v 1.6 2011/09/01 22:25:53 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "man.h"
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
|
||||
static void pline(int, int *, int *, int);
|
||||
static void pman(const struct man_node *, int *, int *, int);
|
||||
static void pmandoc(struct mparse *, int, const char *, int);
|
||||
static void pmdoc(const struct mdoc_node *, int *, int *, int);
|
||||
static void pstring(const char *, int, int *, int);
|
||||
static void usage(void);
|
||||
|
||||
static const char *progname;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct mparse *mp;
|
||||
int ch, i, list;
|
||||
extern int optind;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
++progname;
|
||||
|
||||
mp = NULL;
|
||||
list = 0;
|
||||
|
||||
while (-1 != (ch = getopt(argc, argv, "ikm:pw")))
|
||||
switch (ch) {
|
||||
case ('i'):
|
||||
/* FALLTHROUGH */
|
||||
case ('k'):
|
||||
/* FALLTHROUGH */
|
||||
case ('m'):
|
||||
/* FALLTHROUGH */
|
||||
case ('p'):
|
||||
break;
|
||||
case ('w'):
|
||||
list = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return((int)MANDOCLEVEL_BADARG);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL);
|
||||
assert(mp);
|
||||
|
||||
if (0 == argc)
|
||||
pmandoc(mp, STDIN_FILENO, "<stdin>", list);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
mparse_reset(mp);
|
||||
pmandoc(mp, -1, argv[i], list);
|
||||
}
|
||||
|
||||
mparse_free(mp);
|
||||
return((int)MANDOCLEVEL_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s [-w] [files...]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
pmandoc(struct mparse *mp, int fd, const char *fn, int list)
|
||||
{
|
||||
struct mdoc *mdoc;
|
||||
struct man *man;
|
||||
int line, col;
|
||||
|
||||
if (mparse_readfd(mp, fd, fn) >= MANDOCLEVEL_FATAL) {
|
||||
fprintf(stderr, "%s: Parse failure\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
mparse_result(mp, &mdoc, &man);
|
||||
line = 1;
|
||||
col = 0;
|
||||
|
||||
if (mdoc)
|
||||
pmdoc(mdoc_node(mdoc), &line, &col, list);
|
||||
else if (man)
|
||||
pman(man_node(man), &line, &col, list);
|
||||
else
|
||||
return;
|
||||
|
||||
if ( ! list)
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip the escapes out of a string, emitting the results.
|
||||
*/
|
||||
static void
|
||||
pstring(const char *p, int col, int *colp, int list)
|
||||
{
|
||||
enum mandoc_esc esc;
|
||||
const char *start, *end;
|
||||
int emit;
|
||||
|
||||
/*
|
||||
* Print as many column spaces til we achieve parity with the
|
||||
* input document.
|
||||
*/
|
||||
|
||||
again:
|
||||
if (list && '\0' != *p) {
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
|
||||
while ('\'' == *p || '(' == *p || '"' == *p)
|
||||
p++;
|
||||
|
||||
emit = isalpha((unsigned char)p[0]) &&
|
||||
isalpha((unsigned char)p[1]);
|
||||
|
||||
for (start = p; '\0' != *p; p++)
|
||||
if ('\\' == *p) {
|
||||
p++;
|
||||
esc = mandoc_escape(&p, NULL, NULL);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
return;
|
||||
emit = 0;
|
||||
} else if (isspace((unsigned char)*p))
|
||||
break;
|
||||
|
||||
end = p - 1;
|
||||
|
||||
while (end > start)
|
||||
if ('.' == *end || ',' == *end ||
|
||||
'\'' == *end || '"' == *end ||
|
||||
')' == *end || '!' == *end ||
|
||||
'?' == *end || ':' == *end ||
|
||||
';' == *end)
|
||||
end--;
|
||||
else
|
||||
break;
|
||||
|
||||
if (emit && end - start >= 1) {
|
||||
for ( ; start <= end; start++)
|
||||
if (ASCII_HYPH == *start)
|
||||
putchar('-');
|
||||
else
|
||||
putchar((unsigned char)*start);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if (isspace((unsigned char)*p))
|
||||
goto again;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (*colp < col) {
|
||||
putchar(' ');
|
||||
(*colp)++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the input word, skipping any special characters.
|
||||
*/
|
||||
while ('\0' != *p)
|
||||
if ('\\' == *p) {
|
||||
p++;
|
||||
esc = mandoc_escape(&p, NULL, NULL);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
break;
|
||||
} else {
|
||||
putchar((unsigned char )*p++);
|
||||
(*colp)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pline(int line, int *linep, int *col, int list)
|
||||
{
|
||||
|
||||
if (list)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Print out as many lines as needed to reach parity with the
|
||||
* original input.
|
||||
*/
|
||||
|
||||
while (*linep < line) {
|
||||
putchar('\n');
|
||||
(*linep)++;
|
||||
}
|
||||
|
||||
*col = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pmdoc(const struct mdoc_node *p, int *line, int *col, int list)
|
||||
{
|
||||
|
||||
for ( ; p; p = p->next) {
|
||||
if (MDOC_LINE & p->flags)
|
||||
pline(p->line, line, col, list);
|
||||
if (MDOC_TEXT == p->type)
|
||||
pstring(p->string, p->pos, col, list);
|
||||
if (p->child)
|
||||
pmdoc(p->child, line, col, list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pman(const struct man_node *p, int *line, int *col, int list)
|
||||
{
|
||||
|
||||
for ( ; p; p = p->next) {
|
||||
if (MAN_LINE & p->flags)
|
||||
pline(p->line, line, col, list);
|
||||
if (MAN_TEXT == p->type)
|
||||
pstring(p->string, p->pos, col, list);
|
||||
if (p->child)
|
||||
pman(p->child, line, col, list);
|
||||
}
|
||||
}
|
280
external/bsd/mdocml/dist/eqn.7
vendored
Normal file
280
external/bsd/mdocml/dist/eqn.7
vendored
Normal file
|
@ -0,0 +1,280 @@
|
|||
.\" $Vendor-Id: eqn.7,v 1.28 2011/09/25 18:37:09 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd September 25, 2011
|
||||
.Dt EQN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm eqn
|
||||
.Nd eqn language reference for mandoc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm eqn
|
||||
language is an equation-formatting language.
|
||||
It is used within
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
.Ux
|
||||
manual pages.
|
||||
It describes the
|
||||
.Em structure
|
||||
of an equation, not its mathematical meaning.
|
||||
This manual describes the
|
||||
.Nm
|
||||
language accepted by the
|
||||
.Xr mandoc 1
|
||||
utility, which corresponds to the Second Edition eqn specification (see
|
||||
.Sx SEE ALSO
|
||||
for references).
|
||||
.Pp
|
||||
Equations within
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
documents are enclosed by the standalone
|
||||
.Sq \&.EQ
|
||||
and
|
||||
.Sq \&.EN
|
||||
tags.
|
||||
Equations are multi-line blocks consisting of formulas and control
|
||||
statements.
|
||||
.Sh EQUATION STRUCTURE
|
||||
Each equation is bracketed by
|
||||
.Sq \&.EQ
|
||||
and
|
||||
.Sq \&.EN
|
||||
strings.
|
||||
.Em Note :
|
||||
these are not the same as
|
||||
.Xr roff 7
|
||||
macros, and may only be invoked as
|
||||
.Sq \&.EQ .
|
||||
.Pp
|
||||
The equation grammar is as follows, where quoted strings are
|
||||
case-sensitive literals in the input:
|
||||
.Bd -literal -offset indent
|
||||
eqn : box | eqn box
|
||||
box : text
|
||||
| \*q{\*q eqn \*q}\*q
|
||||
| \*qdefine\*q text text
|
||||
| \*qndefine\*q text text
|
||||
| \*qtdefine\*q text text
|
||||
| \*qgfont\*q text
|
||||
| \*qgsize\*q text
|
||||
| \*qset\*q text text
|
||||
| \*qundef\*q text
|
||||
| box pos box
|
||||
| box mark
|
||||
| \*qmatrix\*q \*q{\*q [col \*q{\*q list \*q}\*q ]*
|
||||
| pile \*q{\*q list \*q}\*q
|
||||
| font box
|
||||
| \*qsize\*q text box
|
||||
| \*qleft\*q text eqn [\*qright\*q text]
|
||||
col : \*qlcol\*q | \*qrcol\*q | \*qccol\*q | \*qcol\*q
|
||||
text : [^space\e\*q]+ | \e\*q.*\e\*q
|
||||
pile : \*qlpile\*q | \*qcpile\*q | \*qrpile\*q | \*qpile\*q
|
||||
pos : \*qover\*q | \*qsup\*q | \*qsub\*q | \*qto\*q | \*qfrom\*q
|
||||
mark : \*qdot\*q | \*qdotdot\*q | \*qhat\*q | \*qtilde\*q | \*qvec\*q
|
||||
| \*qdyad\*q | \*qbar\*q | \*qunder\*q
|
||||
font : \*qroman\*q | \*qitalic\*q | \*qbold\*q | \*qfat\*q
|
||||
list : eqn
|
||||
| list \*qabove\*q eqn
|
||||
space : [\e^~ \et]
|
||||
.Ed
|
||||
.Pp
|
||||
White-space consists of the space, tab, circumflex, and tilde
|
||||
characters.
|
||||
If within a quoted string, these space characters are retained.
|
||||
Quoted strings are also not scanned for replacement definitions.
|
||||
.Pp
|
||||
The following text terms are translated into a rendered glyph, if
|
||||
available: alpha, beta, chi, delta, epsilon, eta, gamma, iota, kappa,
|
||||
lambda, mu, nu, omega, omicron, phi, pi, psi, rho, sigma, tau, theta,
|
||||
upsilon, xi, zeta, DELTA, GAMMA, LAMBDA, OMEGA, PHI, PI, PSI, SIGMA,
|
||||
THETA, UPSILON, XI, inter (intersection), union (union), prod (product),
|
||||
int (integral), sum (summation), grad (gradient), del (vector
|
||||
differential), times (multiply), cdot (centre-dot), nothing (zero-width
|
||||
space), approx (approximately equals), prime (prime), half (one-half),
|
||||
partial (partial differential), inf (infinity), >> (much greater), <<
|
||||
(much less), \-> (left arrow), <\- (right arrow), += (plus-minus), !=
|
||||
(not equal), == (equivalence), <= (less-than-equal), and >=
|
||||
(more-than-equal).
|
||||
.Pp
|
||||
The following control statements are available:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm define
|
||||
Replace all occurrences of a key with a value.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 define Ar key cvalc
|
||||
.Pp
|
||||
The first character of the value string,
|
||||
.Ar c ,
|
||||
is used as the delimiter for the value
|
||||
.Ar val .
|
||||
This allows for arbitrary enclosure of terms (not just quotes), such as
|
||||
.Pp
|
||||
.D1 define Ar foo 'bar baz'
|
||||
.D1 define Ar foo cbar bazc
|
||||
.Pp
|
||||
It is an error to have an empty
|
||||
.Ar key
|
||||
or
|
||||
.Ar val .
|
||||
Note that a quoted
|
||||
.Ar key
|
||||
causes errors in some
|
||||
.Nm
|
||||
implementations and should not be considered portable.
|
||||
It is not expanded for replacements.
|
||||
Definitions may refer to other definitions; these are evaluated
|
||||
recursively when text replacement occurs and not when the definition is
|
||||
created.
|
||||
.Pp
|
||||
Definitions can create arbitrary strings, for example, the following is
|
||||
a legal construction.
|
||||
.Bd -literal -offset indent
|
||||
define foo 'define'
|
||||
foo bar 'baz'
|
||||
.Ed
|
||||
.Pp
|
||||
Self-referencing definitions will raise an error.
|
||||
The
|
||||
.Cm ndefine
|
||||
statement is a synonym for
|
||||
.Cm define ,
|
||||
while
|
||||
.Cm tdefine
|
||||
is discarded.
|
||||
.It Cm gfont
|
||||
Set the default font of subsequent output.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 gfont Ar font
|
||||
.Pp
|
||||
In mandoc, this value is discarded.
|
||||
.It Cm gsize
|
||||
Set the default size of subsequent output.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 gsize Ar size
|
||||
.Pp
|
||||
The
|
||||
.Ar size
|
||||
value should be an integer.
|
||||
.It Cm set
|
||||
Set an equation mode.
|
||||
In mandoc, both arguments are thrown away.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 set Ar key val
|
||||
.Pp
|
||||
The
|
||||
.Ar key
|
||||
and
|
||||
.Ar val
|
||||
are not expanded for replacements.
|
||||
This statement is a GNU extension.
|
||||
.It Cm undef
|
||||
Unset a previously-defined key.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 define Ar key
|
||||
.Pp
|
||||
Once invoked, the definition for
|
||||
.Ar key
|
||||
is discarded.
|
||||
The
|
||||
.Ar key
|
||||
is not expanded for replacements.
|
||||
This statement is a GNU extension.
|
||||
.El
|
||||
.Sh COMPATIBILITY
|
||||
This section documents the compatibility of mandoc
|
||||
.Nm
|
||||
and the troff
|
||||
.Nm
|
||||
implementation (including GNU troff).
|
||||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
The text string
|
||||
.Sq \e\*q
|
||||
is interpreted as a literal quote in troff.
|
||||
In mandoc, this is interpreted as a comment.
|
||||
.It
|
||||
In troff, The circumflex and tilde white-space symbols map to
|
||||
fixed-width spaces.
|
||||
In mandoc, these characters are synonyms for the space character.
|
||||
.It
|
||||
The troff implementation of
|
||||
.Nm
|
||||
allows for equation alignment with the
|
||||
.Cm mark
|
||||
and
|
||||
.Cm lineup
|
||||
tokens.
|
||||
mandoc discards these tokens.
|
||||
The
|
||||
.Cm back Ar n ,
|
||||
.Cm fwd Ar n ,
|
||||
.Cm up Ar n ,
|
||||
and
|
||||
.Cm down Ar n
|
||||
commands are also ignored.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7
|
||||
.Rs
|
||||
.%A Brian W. Kernighan
|
||||
.%A Lorinda L. Cherry
|
||||
.%T System for Typesetting Mathematics
|
||||
.%J Communications of the ACM
|
||||
.%V 18
|
||||
.%P 151\(en157
|
||||
.%D March, 1975
|
||||
.Re
|
||||
.Rs
|
||||
.%A Brian W. Kernighan
|
||||
.%A Lorinda L. Cherry
|
||||
.%T Typesetting Mathematics, User's Guide
|
||||
.%D 1976
|
||||
.Re
|
||||
.Rs
|
||||
.%A Brian W. Kernighan
|
||||
.%A Lorinda L. Cherry
|
||||
.%T Typesetting Mathematics, User's Guide (Second Edition)
|
||||
.%D 1978
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The eqn utility, a preprocessor for troff, was originally written by
|
||||
Brian W. Kernighan and Lorinda L. Cherry in 1975.
|
||||
The GNU reimplementation of eqn, part of the GNU troff package, was
|
||||
released in 1989 by James Clark.
|
||||
The eqn component of
|
||||
.Xr mandoc 1
|
||||
was added in 2011.
|
||||
.Sh AUTHORS
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
949
external/bsd/mdocml/dist/eqn.c
vendored
Normal file
949
external/bsd/mdocml/dist/eqn.c
vendored
Normal file
|
@ -0,0 +1,949 @@
|
|||
/* $Vendor-Id: eqn.c,v 1.38 2011/07/25 15:37:00 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
#define EQN_NEST_MAX 128 /* maximum nesting of defines */
|
||||
#define EQN_MSG(t, x) mandoc_msg((t), (x)->parse, (x)->eqn.ln, (x)->eqn.pos, NULL)
|
||||
|
||||
enum eqn_rest {
|
||||
EQN_DESCOPE,
|
||||
EQN_ERR,
|
||||
EQN_OK,
|
||||
EQN_EOF
|
||||
};
|
||||
|
||||
enum eqn_symt {
|
||||
EQNSYM_alpha,
|
||||
EQNSYM_beta,
|
||||
EQNSYM_chi,
|
||||
EQNSYM_delta,
|
||||
EQNSYM_epsilon,
|
||||
EQNSYM_eta,
|
||||
EQNSYM_gamma,
|
||||
EQNSYM_iota,
|
||||
EQNSYM_kappa,
|
||||
EQNSYM_lambda,
|
||||
EQNSYM_mu,
|
||||
EQNSYM_nu,
|
||||
EQNSYM_omega,
|
||||
EQNSYM_omicron,
|
||||
EQNSYM_phi,
|
||||
EQNSYM_pi,
|
||||
EQNSYM_ps,
|
||||
EQNSYM_rho,
|
||||
EQNSYM_sigma,
|
||||
EQNSYM_tau,
|
||||
EQNSYM_theta,
|
||||
EQNSYM_upsilon,
|
||||
EQNSYM_xi,
|
||||
EQNSYM_zeta,
|
||||
EQNSYM_DELTA,
|
||||
EQNSYM_GAMMA,
|
||||
EQNSYM_LAMBDA,
|
||||
EQNSYM_OMEGA,
|
||||
EQNSYM_PHI,
|
||||
EQNSYM_PI,
|
||||
EQNSYM_PSI,
|
||||
EQNSYM_SIGMA,
|
||||
EQNSYM_THETA,
|
||||
EQNSYM_UPSILON,
|
||||
EQNSYM_XI,
|
||||
EQNSYM_inter,
|
||||
EQNSYM_union,
|
||||
EQNSYM_prod,
|
||||
EQNSYM_int,
|
||||
EQNSYM_sum,
|
||||
EQNSYM_grad,
|
||||
EQNSYM_del,
|
||||
EQNSYM_times,
|
||||
EQNSYM_cdot,
|
||||
EQNSYM_nothing,
|
||||
EQNSYM_approx,
|
||||
EQNSYM_prime,
|
||||
EQNSYM_half,
|
||||
EQNSYM_partial,
|
||||
EQNSYM_inf,
|
||||
EQNSYM_muchgreat,
|
||||
EQNSYM_muchless,
|
||||
EQNSYM_larrow,
|
||||
EQNSYM_rarrow,
|
||||
EQNSYM_pm,
|
||||
EQNSYM_nequal,
|
||||
EQNSYM_equiv,
|
||||
EQNSYM_lessequal,
|
||||
EQNSYM_moreequal,
|
||||
EQNSYM__MAX
|
||||
};
|
||||
|
||||
enum eqnpartt {
|
||||
EQN_DEFINE = 0,
|
||||
EQN_NDEFINE,
|
||||
EQN_TDEFINE,
|
||||
EQN_SET,
|
||||
EQN_UNDEF,
|
||||
EQN_GFONT,
|
||||
EQN_GSIZE,
|
||||
EQN_BACK,
|
||||
EQN_FWD,
|
||||
EQN_UP,
|
||||
EQN_DOWN,
|
||||
EQN__MAX
|
||||
};
|
||||
|
||||
struct eqnstr {
|
||||
const char *name;
|
||||
size_t sz;
|
||||
};
|
||||
|
||||
#define STRNEQ(p1, sz1, p2, sz2) \
|
||||
((sz1) == (sz2) && 0 == strncmp((p1), (p2), (sz1)))
|
||||
#define EQNSTREQ(x, p, sz) \
|
||||
STRNEQ((x)->name, (x)->sz, (p), (sz))
|
||||
|
||||
struct eqnpart {
|
||||
struct eqnstr str;
|
||||
int (*fp)(struct eqn_node *);
|
||||
};
|
||||
|
||||
struct eqnsym {
|
||||
struct eqnstr str;
|
||||
const char *sym;
|
||||
};
|
||||
|
||||
|
||||
static enum eqn_rest eqn_box(struct eqn_node *, struct eqn_box *);
|
||||
static struct eqn_box *eqn_box_alloc(struct eqn_node *,
|
||||
struct eqn_box *);
|
||||
static void eqn_box_free(struct eqn_box *);
|
||||
static struct eqn_def *eqn_def_find(struct eqn_node *,
|
||||
const char *, size_t);
|
||||
static int eqn_do_gfont(struct eqn_node *);
|
||||
static int eqn_do_gsize(struct eqn_node *);
|
||||
static int eqn_do_define(struct eqn_node *);
|
||||
static int eqn_do_ign1(struct eqn_node *);
|
||||
static int eqn_do_ign2(struct eqn_node *);
|
||||
static int eqn_do_tdefine(struct eqn_node *);
|
||||
static int eqn_do_undef(struct eqn_node *);
|
||||
static enum eqn_rest eqn_eqn(struct eqn_node *, struct eqn_box *);
|
||||
static enum eqn_rest eqn_list(struct eqn_node *, struct eqn_box *);
|
||||
static enum eqn_rest eqn_matrix(struct eqn_node *, struct eqn_box *);
|
||||
static const char *eqn_nexttok(struct eqn_node *, size_t *);
|
||||
static const char *eqn_nextrawtok(struct eqn_node *, size_t *);
|
||||
static const char *eqn_next(struct eqn_node *,
|
||||
char, size_t *, int);
|
||||
static void eqn_rewind(struct eqn_node *);
|
||||
|
||||
static const struct eqnpart eqnparts[EQN__MAX] = {
|
||||
{ { "define", 6 }, eqn_do_define }, /* EQN_DEFINE */
|
||||
{ { "ndefine", 7 }, eqn_do_define }, /* EQN_NDEFINE */
|
||||
{ { "tdefine", 7 }, eqn_do_tdefine }, /* EQN_TDEFINE */
|
||||
{ { "set", 3 }, eqn_do_ign2 }, /* EQN_SET */
|
||||
{ { "undef", 5 }, eqn_do_undef }, /* EQN_UNDEF */
|
||||
{ { "gfont", 5 }, eqn_do_gfont }, /* EQN_GFONT */
|
||||
{ { "gsize", 5 }, eqn_do_gsize }, /* EQN_GSIZE */
|
||||
{ { "back", 4 }, eqn_do_ign1 }, /* EQN_BACK */
|
||||
{ { "fwd", 3 }, eqn_do_ign1 }, /* EQN_FWD */
|
||||
{ { "up", 2 }, eqn_do_ign1 }, /* EQN_UP */
|
||||
{ { "down", 4 }, eqn_do_ign1 }, /* EQN_DOWN */
|
||||
};
|
||||
|
||||
static const struct eqnstr eqnmarks[EQNMARK__MAX] = {
|
||||
{ "", 0 }, /* EQNMARK_NONE */
|
||||
{ "dot", 3 }, /* EQNMARK_DOT */
|
||||
{ "dotdot", 6 }, /* EQNMARK_DOTDOT */
|
||||
{ "hat", 3 }, /* EQNMARK_HAT */
|
||||
{ "tilde", 5 }, /* EQNMARK_TILDE */
|
||||
{ "vec", 3 }, /* EQNMARK_VEC */
|
||||
{ "dyad", 4 }, /* EQNMARK_DYAD */
|
||||
{ "bar", 3 }, /* EQNMARK_BAR */
|
||||
{ "under", 5 }, /* EQNMARK_UNDER */
|
||||
};
|
||||
|
||||
static const struct eqnstr eqnfonts[EQNFONT__MAX] = {
|
||||
{ "", 0 }, /* EQNFONT_NONE */
|
||||
{ "roman", 5 }, /* EQNFONT_ROMAN */
|
||||
{ "bold", 4 }, /* EQNFONT_BOLD */
|
||||
{ "fat", 3 }, /* EQNFONT_FAT */
|
||||
{ "italic", 6 }, /* EQNFONT_ITALIC */
|
||||
};
|
||||
|
||||
static const struct eqnstr eqnposs[EQNPOS__MAX] = {
|
||||
{ "", 0 }, /* EQNPOS_NONE */
|
||||
{ "over", 4 }, /* EQNPOS_OVER */
|
||||
{ "sup", 3 }, /* EQNPOS_SUP */
|
||||
{ "sub", 3 }, /* EQNPOS_SUB */
|
||||
{ "to", 2 }, /* EQNPOS_TO */
|
||||
{ "from", 4 }, /* EQNPOS_FROM */
|
||||
};
|
||||
|
||||
static const struct eqnstr eqnpiles[EQNPILE__MAX] = {
|
||||
{ "", 0 }, /* EQNPILE_NONE */
|
||||
{ "pile", 4 }, /* EQNPILE_PILE */
|
||||
{ "cpile", 5 }, /* EQNPILE_CPILE */
|
||||
{ "rpile", 5 }, /* EQNPILE_RPILE */
|
||||
{ "lpile", 5 }, /* EQNPILE_LPILE */
|
||||
{ "col", 3 }, /* EQNPILE_COL */
|
||||
{ "ccol", 4 }, /* EQNPILE_CCOL */
|
||||
{ "rcol", 4 }, /* EQNPILE_RCOL */
|
||||
{ "lcol", 4 }, /* EQNPILE_LCOL */
|
||||
};
|
||||
|
||||
static const struct eqnsym eqnsyms[EQNSYM__MAX] = {
|
||||
{ { "alpha", 5 }, "*a" }, /* EQNSYM_alpha */
|
||||
{ { "beta", 4 }, "*b" }, /* EQNSYM_beta */
|
||||
{ { "chi", 3 }, "*x" }, /* EQNSYM_chi */
|
||||
{ { "delta", 5 }, "*d" }, /* EQNSYM_delta */
|
||||
{ { "epsilon", 7 }, "*e" }, /* EQNSYM_epsilon */
|
||||
{ { "eta", 3 }, "*y" }, /* EQNSYM_eta */
|
||||
{ { "gamma", 5 }, "*g" }, /* EQNSYM_gamma */
|
||||
{ { "iota", 4 }, "*i" }, /* EQNSYM_iota */
|
||||
{ { "kappa", 5 }, "*k" }, /* EQNSYM_kappa */
|
||||
{ { "lambda", 6 }, "*l" }, /* EQNSYM_lambda */
|
||||
{ { "mu", 2 }, "*m" }, /* EQNSYM_mu */
|
||||
{ { "nu", 2 }, "*n" }, /* EQNSYM_nu */
|
||||
{ { "omega", 5 }, "*w" }, /* EQNSYM_omega */
|
||||
{ { "omicron", 7 }, "*o" }, /* EQNSYM_omicron */
|
||||
{ { "phi", 3 }, "*f" }, /* EQNSYM_phi */
|
||||
{ { "pi", 2 }, "*p" }, /* EQNSYM_pi */
|
||||
{ { "psi", 2 }, "*q" }, /* EQNSYM_psi */
|
||||
{ { "rho", 3 }, "*r" }, /* EQNSYM_rho */
|
||||
{ { "sigma", 5 }, "*s" }, /* EQNSYM_sigma */
|
||||
{ { "tau", 3 }, "*t" }, /* EQNSYM_tau */
|
||||
{ { "theta", 5 }, "*h" }, /* EQNSYM_theta */
|
||||
{ { "upsilon", 7 }, "*u" }, /* EQNSYM_upsilon */
|
||||
{ { "xi", 2 }, "*c" }, /* EQNSYM_xi */
|
||||
{ { "zeta", 4 }, "*z" }, /* EQNSYM_zeta */
|
||||
{ { "DELTA", 5 }, "*D" }, /* EQNSYM_DELTA */
|
||||
{ { "GAMMA", 5 }, "*G" }, /* EQNSYM_GAMMA */
|
||||
{ { "LAMBDA", 6 }, "*L" }, /* EQNSYM_LAMBDA */
|
||||
{ { "OMEGA", 5 }, "*W" }, /* EQNSYM_OMEGA */
|
||||
{ { "PHI", 3 }, "*F" }, /* EQNSYM_PHI */
|
||||
{ { "PI", 2 }, "*P" }, /* EQNSYM_PI */
|
||||
{ { "PSI", 3 }, "*Q" }, /* EQNSYM_PSI */
|
||||
{ { "SIGMA", 5 }, "*S" }, /* EQNSYM_SIGMA */
|
||||
{ { "THETA", 5 }, "*H" }, /* EQNSYM_THETA */
|
||||
{ { "UPSILON", 7 }, "*U" }, /* EQNSYM_UPSILON */
|
||||
{ { "XI", 2 }, "*C" }, /* EQNSYM_XI */
|
||||
{ { "inter", 5 }, "ca" }, /* EQNSYM_inter */
|
||||
{ { "union", 5 }, "cu" }, /* EQNSYM_union */
|
||||
{ { "prod", 4 }, "product" }, /* EQNSYM_prod */
|
||||
{ { "int", 3 }, "integral" }, /* EQNSYM_int */
|
||||
{ { "sum", 3 }, "sum" }, /* EQNSYM_sum */
|
||||
{ { "grad", 4 }, "gr" }, /* EQNSYM_grad */
|
||||
{ { "del", 3 }, "gr" }, /* EQNSYM_del */
|
||||
{ { "times", 5 }, "mu" }, /* EQNSYM_times */
|
||||
{ { "cdot", 4 }, "pc" }, /* EQNSYM_cdot */
|
||||
{ { "nothing", 7 }, "&" }, /* EQNSYM_nothing */
|
||||
{ { "approx", 6 }, "~~" }, /* EQNSYM_approx */
|
||||
{ { "prime", 5 }, "aq" }, /* EQNSYM_prime */
|
||||
{ { "half", 4 }, "12" }, /* EQNSYM_half */
|
||||
{ { "partial", 7 }, "pd" }, /* EQNSYM_partial */
|
||||
{ { "inf", 3 }, "if" }, /* EQNSYM_inf */
|
||||
{ { ">>", 2 }, ">>" }, /* EQNSYM_muchgreat */
|
||||
{ { "<<", 2 }, "<<" }, /* EQNSYM_muchless */
|
||||
{ { "<-", 2 }, "<-" }, /* EQNSYM_larrow */
|
||||
{ { "->", 2 }, "->" }, /* EQNSYM_rarrow */
|
||||
{ { "+-", 2 }, "+-" }, /* EQNSYM_pm */
|
||||
{ { "!=", 2 }, "!=" }, /* EQNSYM_nequal */
|
||||
{ { "==", 2 }, "==" }, /* EQNSYM_equiv */
|
||||
{ { "<=", 2 }, "<=" }, /* EQNSYM_lessequal */
|
||||
{ { ">=", 2 }, ">=" }, /* EQNSYM_moreequal */
|
||||
};
|
||||
|
||||
/* ARGSUSED */
|
||||
enum rofferr
|
||||
eqn_read(struct eqn_node **epp, int ln,
|
||||
const char *p, int pos, int *offs)
|
||||
{
|
||||
size_t sz;
|
||||
struct eqn_node *ep;
|
||||
enum rofferr er;
|
||||
|
||||
ep = *epp;
|
||||
|
||||
/*
|
||||
* If we're the terminating mark, unset our equation status and
|
||||
* validate the full equation.
|
||||
*/
|
||||
|
||||
if (0 == strncmp(p, ".EN", 3)) {
|
||||
er = eqn_end(epp);
|
||||
p += 3;
|
||||
while (' ' == *p || '\t' == *p)
|
||||
p++;
|
||||
if ('\0' == *p)
|
||||
return(er);
|
||||
mandoc_msg(MANDOCERR_ARGSLOST, ep->parse, ln, pos, NULL);
|
||||
return(er);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build up the full string, replacing all newlines with regular
|
||||
* whitespace.
|
||||
*/
|
||||
|
||||
sz = strlen(p + pos) + 1;
|
||||
ep->data = mandoc_realloc(ep->data, ep->sz + sz + 1);
|
||||
|
||||
/* First invocation: nil terminate the string. */
|
||||
|
||||
if (0 == ep->sz)
|
||||
*ep->data = '\0';
|
||||
|
||||
ep->sz += sz;
|
||||
strlcat(ep->data, p + pos, ep->sz + 1);
|
||||
strlcat(ep->data, " ", ep->sz + 1);
|
||||
return(ROFF_IGN);
|
||||
}
|
||||
|
||||
struct eqn_node *
|
||||
eqn_alloc(const char *name, int pos, int line, struct mparse *parse)
|
||||
{
|
||||
struct eqn_node *p;
|
||||
size_t sz;
|
||||
const char *end;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct eqn_node));
|
||||
|
||||
if (name && '\0' != *name) {
|
||||
sz = strlen(name);
|
||||
assert(sz);
|
||||
do {
|
||||
sz--;
|
||||
end = name + (int)sz;
|
||||
} while (' ' == *end || '\t' == *end);
|
||||
p->eqn.name = mandoc_strndup(name, sz + 1);
|
||||
}
|
||||
|
||||
p->parse = parse;
|
||||
p->eqn.ln = line;
|
||||
p->eqn.pos = pos;
|
||||
p->gsize = EQN_DEFSIZE;
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
enum rofferr
|
||||
eqn_end(struct eqn_node **epp)
|
||||
{
|
||||
struct eqn_node *ep;
|
||||
struct eqn_box *root;
|
||||
enum eqn_rest c;
|
||||
|
||||
ep = *epp;
|
||||
*epp = NULL;
|
||||
|
||||
ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box));
|
||||
|
||||
root = ep->eqn.root;
|
||||
root->type = EQN_ROOT;
|
||||
|
||||
if (0 == ep->sz)
|
||||
return(ROFF_IGN);
|
||||
|
||||
if (EQN_DESCOPE == (c = eqn_eqn(ep, root))) {
|
||||
EQN_MSG(MANDOCERR_EQNNSCOPE, ep);
|
||||
c = EQN_ERR;
|
||||
}
|
||||
|
||||
return(EQN_EOF == c ? ROFF_EQN : ROFF_IGN);
|
||||
}
|
||||
|
||||
static enum eqn_rest
|
||||
eqn_eqn(struct eqn_node *ep, struct eqn_box *last)
|
||||
{
|
||||
struct eqn_box *bp;
|
||||
enum eqn_rest c;
|
||||
|
||||
bp = eqn_box_alloc(ep, last);
|
||||
bp->type = EQN_SUBEXPR;
|
||||
|
||||
while (EQN_OK == (c = eqn_box(ep, bp)))
|
||||
/* Spin! */ ;
|
||||
|
||||
return(c);
|
||||
}
|
||||
|
||||
static enum eqn_rest
|
||||
eqn_matrix(struct eqn_node *ep, struct eqn_box *last)
|
||||
{
|
||||
struct eqn_box *bp;
|
||||
const char *start;
|
||||
size_t sz;
|
||||
enum eqn_rest c;
|
||||
|
||||
bp = eqn_box_alloc(ep, last);
|
||||
bp->type = EQN_MATRIX;
|
||||
|
||||
if (NULL == (start = eqn_nexttok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
if ( ! STRNEQ(start, sz, "{", 1)) {
|
||||
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
while (EQN_OK == (c = eqn_box(ep, bp)))
|
||||
switch (bp->last->pile) {
|
||||
case (EQNPILE_LCOL):
|
||||
/* FALLTHROUGH */
|
||||
case (EQNPILE_CCOL):
|
||||
/* FALLTHROUGH */
|
||||
case (EQNPILE_RCOL):
|
||||
continue;
|
||||
default:
|
||||
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
||||
return(EQN_ERR);
|
||||
};
|
||||
|
||||
if (EQN_DESCOPE != c) {
|
||||
if (EQN_EOF == c)
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
eqn_rewind(ep);
|
||||
start = eqn_nexttok(ep, &sz);
|
||||
assert(start);
|
||||
if (STRNEQ(start, sz, "}", 1))
|
||||
return(EQN_OK);
|
||||
|
||||
EQN_MSG(MANDOCERR_EQNBADSCOPE, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
static enum eqn_rest
|
||||
eqn_list(struct eqn_node *ep, struct eqn_box *last)
|
||||
{
|
||||
struct eqn_box *bp;
|
||||
const char *start;
|
||||
size_t sz;
|
||||
enum eqn_rest c;
|
||||
|
||||
bp = eqn_box_alloc(ep, last);
|
||||
bp->type = EQN_LIST;
|
||||
|
||||
if (NULL == (start = eqn_nexttok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
if ( ! STRNEQ(start, sz, "{", 1)) {
|
||||
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
while (EQN_DESCOPE == (c = eqn_eqn(ep, bp))) {
|
||||
eqn_rewind(ep);
|
||||
start = eqn_nexttok(ep, &sz);
|
||||
assert(start);
|
||||
if ( ! STRNEQ(start, sz, "above", 5))
|
||||
break;
|
||||
}
|
||||
|
||||
if (EQN_DESCOPE != c) {
|
||||
if (EQN_ERR != c)
|
||||
EQN_MSG(MANDOCERR_EQNSCOPE, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
eqn_rewind(ep);
|
||||
start = eqn_nexttok(ep, &sz);
|
||||
assert(start);
|
||||
if (STRNEQ(start, sz, "}", 1))
|
||||
return(EQN_OK);
|
||||
|
||||
EQN_MSG(MANDOCERR_EQNBADSCOPE, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
static enum eqn_rest
|
||||
eqn_box(struct eqn_node *ep, struct eqn_box *last)
|
||||
{
|
||||
size_t sz;
|
||||
const char *start;
|
||||
char *left;
|
||||
char sym[64];
|
||||
enum eqn_rest c;
|
||||
int i, size;
|
||||
struct eqn_box *bp;
|
||||
|
||||
if (NULL == (start = eqn_nexttok(ep, &sz)))
|
||||
return(EQN_EOF);
|
||||
|
||||
if (STRNEQ(start, sz, "}", 1))
|
||||
return(EQN_DESCOPE);
|
||||
else if (STRNEQ(start, sz, "right", 5))
|
||||
return(EQN_DESCOPE);
|
||||
else if (STRNEQ(start, sz, "above", 5))
|
||||
return(EQN_DESCOPE);
|
||||
else if (STRNEQ(start, sz, "mark", 4))
|
||||
return(EQN_OK);
|
||||
else if (STRNEQ(start, sz, "lineup", 6))
|
||||
return(EQN_OK);
|
||||
|
||||
for (i = 0; i < (int)EQN__MAX; i++) {
|
||||
if ( ! EQNSTREQ(&eqnparts[i].str, start, sz))
|
||||
continue;
|
||||
return((*eqnparts[i].fp)(ep) ?
|
||||
EQN_OK : EQN_ERR);
|
||||
}
|
||||
|
||||
if (STRNEQ(start, sz, "{", 1)) {
|
||||
if (EQN_DESCOPE != (c = eqn_eqn(ep, last))) {
|
||||
if (EQN_ERR != c)
|
||||
EQN_MSG(MANDOCERR_EQNSCOPE, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
eqn_rewind(ep);
|
||||
start = eqn_nexttok(ep, &sz);
|
||||
assert(start);
|
||||
if (STRNEQ(start, sz, "}", 1))
|
||||
return(EQN_OK);
|
||||
EQN_MSG(MANDOCERR_EQNBADSCOPE, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)EQNPILE__MAX; i++) {
|
||||
if ( ! EQNSTREQ(&eqnpiles[i], start, sz))
|
||||
continue;
|
||||
if (EQN_OK == (c = eqn_list(ep, last)))
|
||||
last->last->pile = (enum eqn_pilet)i;
|
||||
return(c);
|
||||
}
|
||||
|
||||
if (STRNEQ(start, sz, "matrix", 6))
|
||||
return(eqn_matrix(ep, last));
|
||||
|
||||
if (STRNEQ(start, sz, "left", 4)) {
|
||||
if (NULL == (start = eqn_nexttok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
left = mandoc_strndup(start, sz);
|
||||
c = eqn_eqn(ep, last);
|
||||
if (last->last)
|
||||
last->last->left = left;
|
||||
else
|
||||
free(left);
|
||||
if (EQN_DESCOPE != c)
|
||||
return(c);
|
||||
assert(last->last);
|
||||
eqn_rewind(ep);
|
||||
start = eqn_nexttok(ep, &sz);
|
||||
assert(start);
|
||||
if ( ! STRNEQ(start, sz, "right", 5))
|
||||
return(EQN_DESCOPE);
|
||||
if (NULL == (start = eqn_nexttok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
last->last->right = mandoc_strndup(start, sz);
|
||||
return(EQN_OK);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)EQNPOS__MAX; i++) {
|
||||
if ( ! EQNSTREQ(&eqnposs[i], start, sz))
|
||||
continue;
|
||||
if (NULL == last->last) {
|
||||
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
last->last->pos = (enum eqn_post)i;
|
||||
if (EQN_EOF == (c = eqn_box(ep, last))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)EQNMARK__MAX; i++) {
|
||||
if ( ! EQNSTREQ(&eqnmarks[i], start, sz))
|
||||
continue;
|
||||
if (NULL == last->last) {
|
||||
EQN_MSG(MANDOCERR_EQNSYNT, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
last->last->mark = (enum eqn_markt)i;
|
||||
if (EQN_EOF == (c = eqn_box(ep, last))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)EQNFONT__MAX; i++) {
|
||||
if ( ! EQNSTREQ(&eqnfonts[i], start, sz))
|
||||
continue;
|
||||
if (EQN_EOF == (c = eqn_box(ep, last))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
} else if (EQN_OK == c)
|
||||
last->last->font = (enum eqn_fontt)i;
|
||||
return(c);
|
||||
}
|
||||
|
||||
if (STRNEQ(start, sz, "size", 4)) {
|
||||
if (NULL == (start = eqn_nexttok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
}
|
||||
size = mandoc_strntoi(start, sz, 10);
|
||||
if (EQN_EOF == (c = eqn_box(ep, last))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(EQN_ERR);
|
||||
} else if (EQN_OK != c)
|
||||
return(c);
|
||||
last->last->size = size;
|
||||
}
|
||||
|
||||
bp = eqn_box_alloc(ep, last);
|
||||
bp->type = EQN_TEXT;
|
||||
for (i = 0; i < (int)EQNSYM__MAX; i++)
|
||||
if (EQNSTREQ(&eqnsyms[i].str, start, sz)) {
|
||||
sym[63] = '\0';
|
||||
snprintf(sym, 62, "\\[%s]", eqnsyms[i].sym);
|
||||
bp->text = mandoc_strdup(sym);
|
||||
return(EQN_OK);
|
||||
}
|
||||
|
||||
bp->text = mandoc_strndup(start, sz);
|
||||
return(EQN_OK);
|
||||
}
|
||||
|
||||
void
|
||||
eqn_free(struct eqn_node *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
eqn_box_free(p->eqn.root);
|
||||
|
||||
for (i = 0; i < (int)p->defsz; i++) {
|
||||
free(p->defs[i].key);
|
||||
free(p->defs[i].val);
|
||||
}
|
||||
|
||||
free(p->eqn.name);
|
||||
free(p->data);
|
||||
free(p->defs);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static struct eqn_box *
|
||||
eqn_box_alloc(struct eqn_node *ep, struct eqn_box *parent)
|
||||
{
|
||||
struct eqn_box *bp;
|
||||
|
||||
bp = mandoc_calloc(1, sizeof(struct eqn_box));
|
||||
bp->parent = parent;
|
||||
bp->size = ep->gsize;
|
||||
|
||||
if (NULL == parent->first)
|
||||
parent->first = bp;
|
||||
else
|
||||
parent->last->next = bp;
|
||||
|
||||
parent->last = bp;
|
||||
return(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
eqn_box_free(struct eqn_box *bp)
|
||||
{
|
||||
|
||||
if (bp->first)
|
||||
eqn_box_free(bp->first);
|
||||
if (bp->next)
|
||||
eqn_box_free(bp->next);
|
||||
|
||||
free(bp->text);
|
||||
free(bp->left);
|
||||
free(bp->right);
|
||||
free(bp);
|
||||
}
|
||||
|
||||
static const char *
|
||||
eqn_nextrawtok(struct eqn_node *ep, size_t *sz)
|
||||
{
|
||||
|
||||
return(eqn_next(ep, '"', sz, 0));
|
||||
}
|
||||
|
||||
static const char *
|
||||
eqn_nexttok(struct eqn_node *ep, size_t *sz)
|
||||
{
|
||||
|
||||
return(eqn_next(ep, '"', sz, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
eqn_rewind(struct eqn_node *ep)
|
||||
{
|
||||
|
||||
ep->cur = ep->rew;
|
||||
}
|
||||
|
||||
static const char *
|
||||
eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
{
|
||||
char *start, *next;
|
||||
int q, diff, lim;
|
||||
size_t ssz, dummy;
|
||||
struct eqn_def *def;
|
||||
|
||||
if (NULL == sz)
|
||||
sz = &dummy;
|
||||
|
||||
lim = 0;
|
||||
ep->rew = ep->cur;
|
||||
again:
|
||||
/* Prevent self-definitions. */
|
||||
|
||||
if (lim >= EQN_NEST_MAX) {
|
||||
EQN_MSG(MANDOCERR_ROFFLOOP, ep);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
ep->cur = ep->rew;
|
||||
start = &ep->data[(int)ep->cur];
|
||||
q = 0;
|
||||
|
||||
if ('\0' == *start)
|
||||
return(NULL);
|
||||
|
||||
if (quote == *start) {
|
||||
ep->cur++;
|
||||
q = 1;
|
||||
}
|
||||
|
||||
start = &ep->data[(int)ep->cur];
|
||||
|
||||
if ( ! q) {
|
||||
if ('{' == *start || '}' == *start)
|
||||
ssz = 1;
|
||||
else
|
||||
ssz = strcspn(start + 1, " ^~\"{}\t") + 1;
|
||||
next = start + (int)ssz;
|
||||
if ('\0' == *next)
|
||||
next = NULL;
|
||||
} else
|
||||
next = strchr(start, quote);
|
||||
|
||||
if (NULL != next) {
|
||||
*sz = (size_t)(next - start);
|
||||
ep->cur += *sz;
|
||||
if (q)
|
||||
ep->cur++;
|
||||
while (' ' == ep->data[(int)ep->cur] ||
|
||||
'\t' == ep->data[(int)ep->cur] ||
|
||||
'^' == ep->data[(int)ep->cur] ||
|
||||
'~' == ep->data[(int)ep->cur])
|
||||
ep->cur++;
|
||||
} else {
|
||||
if (q)
|
||||
EQN_MSG(MANDOCERR_BADQUOTE, ep);
|
||||
next = strchr(start, '\0');
|
||||
*sz = (size_t)(next - start);
|
||||
ep->cur += *sz;
|
||||
}
|
||||
|
||||
/* Quotes aren't expanded for values. */
|
||||
|
||||
if (q || ! repl)
|
||||
return(start);
|
||||
|
||||
if (NULL != (def = eqn_def_find(ep, start, *sz))) {
|
||||
diff = def->valsz - *sz;
|
||||
|
||||
if (def->valsz > *sz) {
|
||||
ep->sz += diff;
|
||||
ep->data = mandoc_realloc(ep->data, ep->sz + 1);
|
||||
ep->data[ep->sz] = '\0';
|
||||
start = &ep->data[(int)ep->rew];
|
||||
}
|
||||
|
||||
diff = def->valsz - *sz;
|
||||
memmove(start + *sz + diff, start + *sz,
|
||||
(strlen(start) - *sz) + 1);
|
||||
memcpy(start, def->val, def->valsz);
|
||||
goto again;
|
||||
}
|
||||
|
||||
return(start);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_ign1(struct eqn_node *ep)
|
||||
{
|
||||
|
||||
if (NULL == eqn_nextrawtok(ep, NULL))
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
else
|
||||
return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_ign2(struct eqn_node *ep)
|
||||
{
|
||||
|
||||
if (NULL == eqn_nextrawtok(ep, NULL))
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
else if (NULL == eqn_nextrawtok(ep, NULL))
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
else
|
||||
return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_tdefine(struct eqn_node *ep)
|
||||
{
|
||||
|
||||
if (NULL == eqn_nextrawtok(ep, NULL))
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
else if (NULL == eqn_next(ep, ep->data[(int)ep->cur], NULL, 0))
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
else
|
||||
return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_define(struct eqn_node *ep)
|
||||
{
|
||||
const char *start;
|
||||
size_t sz;
|
||||
struct eqn_def *def;
|
||||
int i;
|
||||
|
||||
if (NULL == (start = eqn_nextrawtok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a key that already exists.
|
||||
* Create a new key if none is found.
|
||||
*/
|
||||
|
||||
if (NULL == (def = eqn_def_find(ep, start, sz))) {
|
||||
/* Find holes in string array. */
|
||||
for (i = 0; i < (int)ep->defsz; i++)
|
||||
if (0 == ep->defs[i].keysz)
|
||||
break;
|
||||
|
||||
if (i == (int)ep->defsz) {
|
||||
ep->defsz++;
|
||||
ep->defs = mandoc_realloc
|
||||
(ep->defs, ep->defsz *
|
||||
sizeof(struct eqn_def));
|
||||
ep->defs[i].key = ep->defs[i].val = NULL;
|
||||
}
|
||||
|
||||
ep->defs[i].keysz = sz;
|
||||
ep->defs[i].key = mandoc_realloc
|
||||
(ep->defs[i].key, sz + 1);
|
||||
|
||||
memcpy(ep->defs[i].key, start, sz);
|
||||
ep->defs[i].key[(int)sz] = '\0';
|
||||
def = &ep->defs[i];
|
||||
}
|
||||
|
||||
start = eqn_next(ep, ep->data[(int)ep->cur], &sz, 0);
|
||||
|
||||
if (NULL == start) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(0);
|
||||
}
|
||||
|
||||
def->valsz = sz;
|
||||
def->val = mandoc_realloc(def->val, sz + 1);
|
||||
memcpy(def->val, start, sz);
|
||||
def->val[(int)sz] = '\0';
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_gfont(struct eqn_node *ep)
|
||||
{
|
||||
|
||||
if (NULL == eqn_nextrawtok(ep, NULL)) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_gsize(struct eqn_node *ep)
|
||||
{
|
||||
const char *start;
|
||||
size_t sz;
|
||||
|
||||
if (NULL == (start = eqn_nextrawtok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(0);
|
||||
}
|
||||
ep->gsize = mandoc_strntoi(start, sz, 10);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
eqn_do_undef(struct eqn_node *ep)
|
||||
{
|
||||
const char *start;
|
||||
struct eqn_def *def;
|
||||
size_t sz;
|
||||
|
||||
if (NULL == (start = eqn_nextrawtok(ep, &sz))) {
|
||||
EQN_MSG(MANDOCERR_EQNEOF, ep);
|
||||
return(0);
|
||||
} else if (NULL != (def = eqn_def_find(ep, start, sz)))
|
||||
def->keysz = 0;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static struct eqn_def *
|
||||
eqn_def_find(struct eqn_node *ep, const char *key, size_t sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)ep->defsz; i++)
|
||||
if (ep->defs[i].keysz && STRNEQ(ep->defs[i].key,
|
||||
ep->defs[i].keysz, key, sz))
|
||||
return(&ep->defs[i]);
|
||||
|
||||
return(NULL);
|
||||
}
|
81
external/bsd/mdocml/dist/eqn_html.c
vendored
Normal file
81
external/bsd/mdocml/dist/eqn_html.c
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* $Vendor-Id: eqn_html.c,v 1.2 2011/07/24 10:09:03 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
||||
static const enum htmltag fontmap[EQNFONT__MAX] = {
|
||||
TAG_SPAN, /* EQNFONT_NONE */
|
||||
TAG_SPAN, /* EQNFONT_ROMAN */
|
||||
TAG_B, /* EQNFONT_BOLD */
|
||||
TAG_B, /* EQNFONT_FAT */
|
||||
TAG_I /* EQNFONT_ITALIC */
|
||||
};
|
||||
|
||||
|
||||
static void eqn_box(struct html *, const struct eqn_box *);
|
||||
|
||||
void
|
||||
print_eqn(struct html *p, const struct eqn *ep)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct tag *t;
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "eqn");
|
||||
t = print_otag(p, TAG_SPAN, 1, &tag);
|
||||
|
||||
p->flags |= HTML_NONOSPACE;
|
||||
eqn_box(p, ep->root);
|
||||
p->flags &= ~HTML_NONOSPACE;
|
||||
|
||||
print_tagq(p, t);
|
||||
}
|
||||
|
||||
static void
|
||||
eqn_box(struct html *p, const struct eqn_box *bp)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
t = EQNFONT_NONE == bp->font ? NULL :
|
||||
print_otag(p, fontmap[(int)bp->font], 0, NULL);
|
||||
|
||||
if (bp->left)
|
||||
print_text(p, bp->left);
|
||||
|
||||
if (bp->text)
|
||||
print_text(p, bp->text);
|
||||
|
||||
if (bp->first)
|
||||
eqn_box(p, bp->first);
|
||||
|
||||
if (NULL != t)
|
||||
print_tagq(p, t);
|
||||
if (bp->right)
|
||||
print_text(p, bp->right);
|
||||
|
||||
if (bp->next)
|
||||
eqn_box(p, bp->next);
|
||||
}
|
76
external/bsd/mdocml/dist/eqn_term.c
vendored
Normal file
76
external/bsd/mdocml/dist/eqn_term.c
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* $Vendor-Id: eqn_term.c,v 1.4 2011/07/24 10:09:03 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
static const enum termfont fontmap[EQNFONT__MAX] = {
|
||||
TERMFONT_NONE, /* EQNFONT_NONE */
|
||||
TERMFONT_NONE, /* EQNFONT_ROMAN */
|
||||
TERMFONT_BOLD, /* EQNFONT_BOLD */
|
||||
TERMFONT_BOLD, /* EQNFONT_FAT */
|
||||
TERMFONT_UNDER /* EQNFONT_ITALIC */
|
||||
};
|
||||
|
||||
static void eqn_box(struct termp *, const struct eqn_box *);
|
||||
|
||||
void
|
||||
term_eqn(struct termp *p, const struct eqn *ep)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_NONOSPACE;
|
||||
eqn_box(p, ep->root);
|
||||
term_word(p, " ");
|
||||
p->flags &= ~TERMP_NONOSPACE;
|
||||
}
|
||||
|
||||
static void
|
||||
eqn_box(struct termp *p, const struct eqn_box *bp)
|
||||
{
|
||||
|
||||
if (EQNFONT_NONE != bp->font)
|
||||
term_fontpush(p, fontmap[(int)bp->font]);
|
||||
if (bp->left)
|
||||
term_word(p, bp->left);
|
||||
if (EQN_SUBEXPR == bp->type)
|
||||
term_word(p, "(");
|
||||
|
||||
if (bp->text)
|
||||
term_word(p, bp->text);
|
||||
|
||||
if (bp->first)
|
||||
eqn_box(p, bp->first);
|
||||
|
||||
if (EQN_SUBEXPR == bp->type)
|
||||
term_word(p, ")");
|
||||
if (bp->right)
|
||||
term_word(p, bp->right);
|
||||
if (EQNFONT_NONE != bp->font)
|
||||
term_fontpop(p);
|
||||
|
||||
if (bp->next)
|
||||
eqn_box(p, bp->next);
|
||||
}
|
244
external/bsd/mdocml/dist/example.style.css
vendored
244
external/bsd/mdocml/dist/example.style.css
vendored
|
@ -1,146 +1,110 @@
|
|||
/* $Vendor-Id: example.style.css,v 1.41 2011/01/05 13:00:11 kristaps Exp $ */
|
||||
|
||||
/* $Vendor-Id: example.style.css,v 1.49 2011/12/15 12:18:57 kristaps Exp $ */
|
||||
/*
|
||||
* This is an example style-sheet provided for mandoc(1) and the -Thtml
|
||||
* or -Txhtml output mode.
|
||||
*
|
||||
* It mimics the appearance of the traditional cvsweb output.
|
||||
*
|
||||
* It mimics the appearance of the legacy man.cgi output.
|
||||
* See mdoc(7) and man(7) for macro explanations.
|
||||
*/
|
||||
|
||||
html { min-width: 580px; width: 580px; }
|
||||
body { font-family: monospace; }
|
||||
|
||||
/* Preamble structure. */
|
||||
|
||||
table.foot { width: 100%; } /* Document footer. */
|
||||
td.foot-date { width: 50%; } /* Document footer: date. */
|
||||
td.foot-os { width: 50%; text-align: right; } /* Document footer: OS/source. */
|
||||
table.head { width: 100%; } /* Document header. */
|
||||
td.head-ltitle { width: 10%; } /* Document header: left-title. */
|
||||
td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */
|
||||
td.head-rtitle { width: 10%; text-align: right; } /* Document header: right-title. */
|
||||
|
||||
/* Sections. */
|
||||
|
||||
h1 { margin-bottom: 0px; font-size: medium; margin-left: -4ex; } /* Section header (Sh, SH). */
|
||||
h2 { margin-bottom: 0px; font-size: medium; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
|
||||
div.section { margin-bottom: 2ex; margin-left: 4ex; } /* Sections (Sh, SH). */
|
||||
div.subsection { } /* Sub-sections (Ss, SS). */
|
||||
table.synopsis { } /* SYNOPSIS section table. */
|
||||
|
||||
/* Vertical spacing. */
|
||||
|
||||
p { } /* Paragraph: Pp, Lp. */
|
||||
blockquote { margin-top: 0px; margin-bottom: 0px; }
|
||||
table { margin-top: 0px; margin-bottom: 0px; }
|
||||
td { vertical-align: top; }
|
||||
|
||||
/* General font modes. */
|
||||
|
||||
i { } /* Italic: BI, IB, I, (implicit). */
|
||||
.emph { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
|
||||
b { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
|
||||
.symb { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
|
||||
small { } /* Small: SB, SM. */
|
||||
|
||||
/* Block modes. */
|
||||
|
||||
.display { } /* Top of all Bd, D1, Dl. */
|
||||
.list { } /* Top of all Bl. */
|
||||
|
||||
/* Context-specific modes. */
|
||||
|
||||
i.addr { font-weight: normal; } /* Address (Ad). */
|
||||
i.arg { font-weight: normal; } /* Command argument (Ar). */
|
||||
span.author { } /* Author name (An). */
|
||||
b.cmd { font-style: normal; } /* Command (Cm). */
|
||||
b.config { font-style: normal; } /* Config statement (Cd). */
|
||||
span.define { } /* Defines (Dv). */
|
||||
span.desc { } /* Nd. After em-dash. */
|
||||
b.diag { font-style: normal; } /* Diagnostic (Bl -diag). */
|
||||
span.env { } /* Environment variables (Ev). */
|
||||
span.errno { } /* Error string (Er). */
|
||||
i.farg { font-weight: normal; } /* Function argument (Fa, Fn). */
|
||||
i.file { font-weight: normal; } /* File (Pa). */
|
||||
b.flag { font-style: normal; } /* Flag (Fl, Cm). */
|
||||
b.fname { font-style: normal; } /* Function name (Fa, Fn, Rv). */
|
||||
i.ftype { font-weight: normal; } /* Function types (Ft, Fn). */
|
||||
b.includes { font-style: normal; } /* Header includes (In). */
|
||||
span.lib { } /* Library (Lb). */
|
||||
i.link-sec { font-weight: normal; } /* Section links (Sx). */
|
||||
code.lit { font-style: normal; font-weight: normal; } /* Literal: Dl, Li, Bf -literal, Bl -literal, Bl -unfilled. */
|
||||
b.macro { font-style: normal; } /* Macro-ish thing (Fd). */
|
||||
b.name { font-style: normal; } /* Name of utility (Nm). */
|
||||
span.opt { } /* Options (Op, Oo/Oc). */
|
||||
span.ref { } /* Citations (Rs). */
|
||||
span.ref-auth { } /* Reference author (%A). */
|
||||
i.ref-book { font-weight: normal; } /* Reference book (%B). */
|
||||
span.ref-city { } /* Reference city (%C). */
|
||||
span.ref-date { } /* Reference date (%D). */
|
||||
i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */
|
||||
i.ref-jrnl { font-weight: normal; } /* Reference journal (%J). */
|
||||
span.ref-num { } /* Reference number (%N). */
|
||||
span.ref-opt { } /* Reference optionals (%O). */
|
||||
span.ref-page { } /* Reference page (%P). */
|
||||
span.ref-corp { } /* Reference corporate/foreign author (%Q). */
|
||||
span.ref-rep { } /* Reference report (%R). */
|
||||
span.ref-title { text-decoration: underline; } /* Reference title (%T). */
|
||||
span.ref-vol { } /* Reference volume (%V). */
|
||||
span.type { font-style: italic; font-weight: normal; } /* Variable types (Vt). */
|
||||
span.unix { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
|
||||
b.utility { font-style: normal; } /* Name of utility (Ex). */
|
||||
b.var { font-style: normal; } /* Variables (Rv). */
|
||||
|
||||
a.link-ext { } /* Off-site link (Lk). */
|
||||
a.link-includes { } /* Include-file link (In). */
|
||||
a.link-mail { } /* Mailto links (Mt). */
|
||||
a.link-man { } /* Manual links (Xr). */
|
||||
a.link-ref { } /* Reference section links (%Q). */
|
||||
a.link-sec { } /* Section links (Sx). */
|
||||
|
||||
/* Formatting for lists. See mdoc(7). */
|
||||
|
||||
dl.list-diag { }
|
||||
dt.list-diag { }
|
||||
dd.list-diag { }
|
||||
|
||||
dl.list-hang { }
|
||||
dt.list-hang { }
|
||||
dd.list-hang { }
|
||||
|
||||
dl.list-inset { }
|
||||
dt.list-inset { }
|
||||
dd.list-inset { }
|
||||
|
||||
dl.list-ohang { }
|
||||
dt.list-ohang { }
|
||||
dd.list-ohang { margin-left: 0em; }
|
||||
|
||||
dl.list-tag { }
|
||||
dt.list-tag { }
|
||||
dd.list-tag { }
|
||||
|
||||
table.list-col { }
|
||||
tr.list-col { }
|
||||
td.list-col { }
|
||||
|
||||
ul.list-bul { list-style-type: disc; padding-left: 1em; }
|
||||
li.list-bul { }
|
||||
|
||||
ul.list-dash { list-style-type: none; padding-left: 0em; }
|
||||
li.list-dash:before { content: "\2014 "; }
|
||||
|
||||
ul.list-hyph { list-style-type: none; padding-left: 0em; }
|
||||
li.list-hyph:before { content: "\2013 "; }
|
||||
|
||||
ul.list-item { list-style-type: none; padding-left: 0em; }
|
||||
li.list-item { }
|
||||
|
||||
ol.list-enum { padding-left: 2em; }
|
||||
li.list-enum { }
|
||||
|
||||
/* Table modes. See tbl(7). */
|
||||
|
||||
table.tbl { }
|
||||
div.mandoc { min-width: 102ex;
|
||||
width: 102ex;
|
||||
font-family: monospace; } /* This is the outer node of all mandoc -T[x]html documents. */
|
||||
div.mandoc h1 { margin-bottom: 0ex; font-size: inherit; margin-left: -4ex; } /* Section header (Sh, SH). */
|
||||
div.mandoc h2 { margin-bottom: 0ex; font-size: inherit; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
|
||||
div.mandoc table { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */
|
||||
div.mandoc td { vertical-align: top; } /* All table cells. */
|
||||
div.mandoc p { } /* Paragraph: Pp, Lp. */
|
||||
div.mandoc blockquote { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1, Dl. */
|
||||
div.mandoc div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
|
||||
div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */
|
||||
div.mandoc table.synopsis { } /* SYNOPSIS section table. */
|
||||
div.mandoc table.foot { } /* Document footer. */
|
||||
div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */
|
||||
div.mandoc td.foot-os { width: 50%; text-align: right; } /* Document footer: OS/source. */
|
||||
div.mandoc table.head { } /* Document header. */
|
||||
div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */
|
||||
div.mandoc td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */
|
||||
div.mandoc td.head-rtitle { width: 10%; text-align: right; } /* Document header: right-title. */
|
||||
div.mandoc .display { } /* All Bd, D1, Dl. */
|
||||
div.mandoc .list { } /* All Bl. */
|
||||
div.mandoc i { } /* Italic: BI, IB, I, (implicit). */
|
||||
div.mandoc b { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
|
||||
div.mandoc small { } /* Small: SB, SM. */
|
||||
div.mandoc .emph { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
|
||||
div.mandoc .symb { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
|
||||
div.mandoc .lit { font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */
|
||||
div.mandoc i.addr { font-weight: normal; } /* Address (Ad). */
|
||||
div.mandoc i.arg { font-weight: normal; } /* Command argument (Ar). */
|
||||
div.mandoc span.author { } /* Author name (An). */
|
||||
div.mandoc b.cmd { font-style: normal; } /* Command (Cm). */
|
||||
div.mandoc b.config { font-style: normal; } /* Config statement (Cd). */
|
||||
div.mandoc span.define { } /* Defines (Dv). */
|
||||
div.mandoc span.desc { } /* Nd. After em-dash. */
|
||||
div.mandoc b.diag { font-style: normal; } /* Diagnostic (Bl -diag). */
|
||||
div.mandoc span.env { } /* Environment variables (Ev). */
|
||||
div.mandoc span.errno { } /* Error string (Er). */
|
||||
div.mandoc i.farg { font-weight: normal; } /* Function argument (Fa, Fn). */
|
||||
div.mandoc i.file { font-weight: normal; } /* File (Pa). */
|
||||
div.mandoc b.flag { font-style: normal; } /* Flag (Fl, Cm). */
|
||||
div.mandoc b.fname { font-style: normal; } /* Function name (Fa, Fn, Rv). */
|
||||
div.mandoc i.ftype { font-weight: normal; } /* Function types (Ft, Fn). */
|
||||
div.mandoc b.includes { font-style: normal; } /* Header includes (In). */
|
||||
div.mandoc span.lib { } /* Library (Lb). */
|
||||
div.mandoc i.link-sec { font-weight: normal; } /* Section links (Sx). */
|
||||
div.mandoc b.macro { font-style: normal; } /* Macro-ish thing (Fd). */
|
||||
div.mandoc b.name { font-style: normal; } /* Name of utility (Nm). */
|
||||
div.mandoc span.opt { } /* Options (Op, Oo/Oc). */
|
||||
div.mandoc span.ref { } /* Citations (Rs). */
|
||||
div.mandoc span.ref-auth { } /* Reference author (%A). */
|
||||
div.mandoc i.ref-book { font-weight: normal; } /* Reference book (%B). */
|
||||
div.mandoc span.ref-city { } /* Reference city (%C). */
|
||||
div.mandoc span.ref-date { } /* Reference date (%D). */
|
||||
div.mandoc i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */
|
||||
div.mandoc i.ref-jrnl { font-weight: normal; } /* Reference journal (%J). */
|
||||
div.mandoc span.ref-num { } /* Reference number (%N). */
|
||||
div.mandoc span.ref-opt { } /* Reference optionals (%O). */
|
||||
div.mandoc span.ref-page { } /* Reference page (%P). */
|
||||
div.mandoc span.ref-corp { } /* Reference corporate/foreign author (%Q). */
|
||||
div.mandoc span.ref-rep { } /* Reference report (%R). */
|
||||
div.mandoc span.ref-title { text-decoration: underline; } /* Reference title (%T). */
|
||||
div.mandoc span.ref-vol { } /* Reference volume (%V). */
|
||||
div.mandoc span.type { font-style: italic; font-weight: normal; } /* Variable types (Vt). */
|
||||
div.mandoc span.unix { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
|
||||
div.mandoc b.utility { font-style: normal; } /* Name of utility (Ex). */
|
||||
div.mandoc b.var { font-style: normal; } /* Variables (Rv). */
|
||||
div.mandoc a.link-ext { } /* Off-site link (Lk). */
|
||||
div.mandoc a.link-includes { } /* Include-file link (In). */
|
||||
div.mandoc a.link-mail { } /* Mailto links (Mt). */
|
||||
div.mandoc a.link-man { } /* Manual links (Xr). */
|
||||
div.mandoc a.link-ref { } /* Reference section links (%Q). */
|
||||
div.mandoc a.link-sec { } /* Section links (Sx). */
|
||||
div.mandoc dl.list-diag { } /* Formatting for lists. See mdoc(7). */
|
||||
div.mandoc dt.list-diag { }
|
||||
div.mandoc dd.list-diag { }
|
||||
div.mandoc dl.list-hang { }
|
||||
div.mandoc dt.list-hang { }
|
||||
div.mandoc dd.list-hang { }
|
||||
div.mandoc dl.list-inset { }
|
||||
div.mandoc dt.list-inset { }
|
||||
div.mandoc dd.list-inset { }
|
||||
div.mandoc dl.list-ohang { }
|
||||
div.mandoc dt.list-ohang { }
|
||||
div.mandoc dd.list-ohang { margin-left: 0ex; }
|
||||
div.mandoc dl.list-tag { }
|
||||
div.mandoc dt.list-tag { }
|
||||
div.mandoc dd.list-tag { }
|
||||
div.mandoc table.list-col { }
|
||||
div.mandoc tr.list-col { }
|
||||
div.mandoc td.list-col { }
|
||||
div.mandoc ul.list-bul { list-style-type: disc; padding-left: 1em; }
|
||||
div.mandoc li.list-bul { }
|
||||
div.mandoc ul.list-dash { list-style-type: none; padding-left: 0em; }
|
||||
div.mandoc li.list-dash:before { content: "\2014 "; }
|
||||
div.mandoc ul.list-hyph { list-style-type: none; padding-left: 0em; }
|
||||
div.mandoc li.list-hyph:before { content: "\2013 "; }
|
||||
div.mandoc ul.list-item { list-style-type: none; padding-left: 0em; }
|
||||
div.mandoc li.list-item { }
|
||||
div.mandoc ol.list-enum { padding-left: 2em; }
|
||||
div.mandoc li.list-enum { }
|
||||
div.mandoc span.eqn { } /* Equation modes. See eqn(7). */
|
||||
div.mandoc table.tbl { } /* Table modes. See tbl(7). */
|
||||
|
|
2
external/bsd/mdocml/dist/external.png.uu
vendored
2
external/bsd/mdocml/dist/external.png.uu
vendored
|
@ -1,4 +1,4 @@
|
|||
begin 644 external.png
|
||||
begin 664 external.png
|
||||
MB5!.1PT*&@H````-24A$4@````H````*"`,```"Z[#^/````%5!,5$5FF<PS
|
||||
MF<R9S/\`9LP`9O________]$Z@B5````!W123E/_______\`&DL#1@```#A)
|
||||
M1$%4&%<ERT$2`$`$`T$BZ_]/WL$<5!\DFKP%RGBT;.>RR#IR])3+$:.A0J[.
|
||||
|
|
425
external/bsd/mdocml/dist/html.c
vendored
425
external/bsd/mdocml/dist/html.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: html.c,v 1.124 2010/12/27 21:41:05 schwarze Exp $ */
|
||||
/* $Vendor-Id: html.c,v 1.150 2011/10/05 21:35:17 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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 +31,8 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "out.h"
|
||||
#include "chars.h"
|
||||
#include "html.h"
|
||||
#include "main.h"
|
||||
|
||||
|
@ -90,42 +91,47 @@ static const char *const htmlattrs[ATTR_MAX] = {
|
|||
"id", /* ATTR_ID */
|
||||
"summary", /* ATTR_SUMMARY */
|
||||
"align", /* ATTR_ALIGN */
|
||||
"colspan", /* ATTR_COLSPAN */
|
||||
};
|
||||
|
||||
static void print_spec(struct html *, enum roffdeco,
|
||||
const char *, size_t);
|
||||
static void print_res(struct html *, const char *, size_t);
|
||||
static void print_ctag(struct html *, enum htmltag);
|
||||
static void print_doctype(struct html *);
|
||||
static void print_xmltype(struct html *);
|
||||
static int print_encode(struct html *, const char *, int);
|
||||
static void print_metaf(struct html *, enum roffdeco);
|
||||
static void print_attr(struct html *,
|
||||
const char *, const char *);
|
||||
static void *ml_alloc(char *, enum htmltype);
|
||||
static const char *const roffscales[SCALE_MAX] = {
|
||||
"cm", /* SCALE_CM */
|
||||
"in", /* SCALE_IN */
|
||||
"pc", /* SCALE_PC */
|
||||
"pt", /* SCALE_PT */
|
||||
"em", /* SCALE_EM */
|
||||
"em", /* SCALE_MM */
|
||||
"ex", /* SCALE_EN */
|
||||
"ex", /* SCALE_BU */
|
||||
"em", /* SCALE_VS */
|
||||
"ex", /* SCALE_FS */
|
||||
};
|
||||
|
||||
static void bufncat(struct html *, const char *, size_t);
|
||||
static void print_ctag(struct html *, enum htmltag);
|
||||
static int print_encode(struct html *, const char *, int);
|
||||
static void print_metaf(struct html *, enum mandoc_esc);
|
||||
static void print_attr(struct html *, const char *, const char *);
|
||||
static void *ml_alloc(char *, enum htmltype);
|
||||
|
||||
static void *
|
||||
ml_alloc(char *outopts, enum htmltype type)
|
||||
{
|
||||
struct html *h;
|
||||
const char *toks[4];
|
||||
const char *toks[5];
|
||||
char *v;
|
||||
|
||||
toks[0] = "style";
|
||||
toks[1] = "man";
|
||||
toks[2] = "includes";
|
||||
toks[3] = NULL;
|
||||
toks[3] = "fragment";
|
||||
toks[4] = NULL;
|
||||
|
||||
h = calloc(1, sizeof(struct html));
|
||||
if (NULL == h) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
h = mandoc_calloc(1, sizeof(struct html));
|
||||
|
||||
h->type = type;
|
||||
h->tags.head = NULL;
|
||||
h->symtab = chars_init(CHARS_HTML);
|
||||
h->symtab = mchars_alloc();
|
||||
|
||||
while (outopts && *outopts)
|
||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||
|
@ -138,6 +144,9 @@ ml_alloc(char *outopts, enum htmltype type)
|
|||
case (2):
|
||||
h->base_includes = v;
|
||||
break;
|
||||
case (3):
|
||||
h->oflags |= HTML_FRAGMENT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -175,7 +184,7 @@ html_free(void *p)
|
|||
}
|
||||
|
||||
if (h->symtab)
|
||||
chars_free(h->symtab);
|
||||
mchars_free(h->symtab);
|
||||
|
||||
free(h);
|
||||
}
|
||||
|
@ -211,62 +220,24 @@ print_gen_head(struct html *h)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_spec(struct html *h, enum roffdeco d, const char *p, size_t len)
|
||||
{
|
||||
int cp;
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
if ((cp = chars_spec2cp(h->symtab, p, len)) > 0) {
|
||||
printf("&#%d;", cp);
|
||||
return;
|
||||
} else if (-1 == cp && DECO_SSPECIAL == d) {
|
||||
fwrite(p, 1, len, stdout);
|
||||
return;
|
||||
} else if (-1 == cp)
|
||||
return;
|
||||
|
||||
if (NULL != (rhs = chars_spec2str(h->symtab, p, len, &sz)))
|
||||
fwrite(rhs, 1, sz, stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_res(struct html *h, const char *p, size_t len)
|
||||
{
|
||||
int cp;
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
if ((cp = chars_res2cp(h->symtab, p, len)) > 0) {
|
||||
printf("&#%d;", cp);
|
||||
return;
|
||||
} else if (-1 == cp)
|
||||
return;
|
||||
|
||||
if (NULL != (rhs = chars_res2str(h->symtab, p, len, &sz)))
|
||||
fwrite(rhs, 1, sz, stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_metaf(struct html *h, enum roffdeco deco)
|
||||
print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
{
|
||||
enum htmlfont font;
|
||||
|
||||
switch (deco) {
|
||||
case (DECO_PREVIOUS):
|
||||
case (ESCAPE_FONTPREV):
|
||||
font = h->metal;
|
||||
break;
|
||||
case (DECO_ITALIC):
|
||||
case (ESCAPE_FONTITALIC):
|
||||
font = HTMLFONT_ITALIC;
|
||||
break;
|
||||
case (DECO_BOLD):
|
||||
case (ESCAPE_FONTBOLD):
|
||||
font = HTMLFONT_BOLD;
|
||||
break;
|
||||
case (DECO_ROMAN):
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
font = HTMLFONT_NONE;
|
||||
break;
|
||||
default:
|
||||
|
@ -288,77 +259,123 @@ print_metaf(struct html *h, enum roffdeco deco)
|
|||
print_otag(h, TAG_I, 0, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
html_strlen(const char *cp)
|
||||
{
|
||||
int ssz, sz;
|
||||
const char *seq, *p;
|
||||
|
||||
/*
|
||||
* Account for escaped sequences within string length
|
||||
* calculations. This follows the logic in term_strlen() as we
|
||||
* must calculate the width of produced strings.
|
||||
* Assume that characters are always width of "1". This is
|
||||
* hacky, but it gets the job done for approximation of widths.
|
||||
*/
|
||||
|
||||
sz = 0;
|
||||
while (NULL != (p = strchr(cp, '\\'))) {
|
||||
sz += (int)(p - cp);
|
||||
++cp;
|
||||
switch (mandoc_escape(&cp, &seq, &ssz)) {
|
||||
case (ESCAPE_ERROR):
|
||||
return(sz);
|
||||
case (ESCAPE_UNICODE):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_NUMBERED):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_SPECIAL):
|
||||
sz++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(sz >= 0);
|
||||
return(sz + strlen(cp));
|
||||
}
|
||||
|
||||
static int
|
||||
print_encode(struct html *h, const char *p, int norecurse)
|
||||
{
|
||||
size_t sz;
|
||||
int len, nospace;
|
||||
int c, len, nospace;
|
||||
const char *seq;
|
||||
enum roffdeco deco;
|
||||
enum mandoc_esc esc;
|
||||
static const char rejs[6] = { '\\', '<', '>', '&', ASCII_HYPH, '\0' };
|
||||
|
||||
nospace = 0;
|
||||
|
||||
for (; *p; p++) {
|
||||
while ('\0' != *p) {
|
||||
sz = strcspn(p, rejs);
|
||||
|
||||
fwrite(p, 1, sz, stdout);
|
||||
p += /* LINTED */
|
||||
sz;
|
||||
p += (int)sz;
|
||||
|
||||
if ('<' == *p) {
|
||||
if ('\0' == *p)
|
||||
break;
|
||||
|
||||
switch (*p++) {
|
||||
case ('<'):
|
||||
printf("<");
|
||||
continue;
|
||||
} else if ('>' == *p) {
|
||||
case ('>'):
|
||||
printf(">");
|
||||
continue;
|
||||
} else if ('&' == *p) {
|
||||
case ('&'):
|
||||
printf("&");
|
||||
continue;
|
||||
} else if (ASCII_HYPH == *p) {
|
||||
/*
|
||||
* Note: "soft hyphens" aren't graphically
|
||||
* displayed when not breaking the text; we want
|
||||
* them to be displayed.
|
||||
*/
|
||||
/*printf("­");*/
|
||||
case (ASCII_HYPH):
|
||||
putchar('-');
|
||||
continue;
|
||||
} else if ('\0' == *p)
|
||||
break;
|
||||
|
||||
seq = ++p;
|
||||
len = a2roffdeco(&deco, &seq, &sz);
|
||||
|
||||
switch (deco) {
|
||||
case (DECO_RESERVED):
|
||||
print_res(h, seq, sz);
|
||||
break;
|
||||
case (DECO_SSPECIAL):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_SPECIAL):
|
||||
print_spec(h, deco, seq, sz);
|
||||
break;
|
||||
case (DECO_PREVIOUS):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_BOLD):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_ITALIC):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_ROMAN):
|
||||
if (norecurse)
|
||||
break;
|
||||
print_metaf(h, deco);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p += len - 1;
|
||||
esc = mandoc_escape(&p, &seq, &len);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
break;
|
||||
|
||||
if (DECO_NOSPACE == deco && '\0' == *(p + 1))
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
/* Skip passed "u" header. */
|
||||
c = mchars_num2uc(seq + 1, len - 1);
|
||||
if ('\0' != c)
|
||||
printf("&#x%x;", c);
|
||||
break;
|
||||
case (ESCAPE_NUMBERED):
|
||||
c = mchars_num2char(seq, len);
|
||||
if ('\0' != c)
|
||||
putchar(c);
|
||||
break;
|
||||
case (ESCAPE_SPECIAL):
|
||||
c = mchars_spec2cp(h->symtab, seq, len);
|
||||
if (c > 0)
|
||||
printf("&#%d;", c);
|
||||
else if (-1 == c && 1 == len)
|
||||
putchar((int)*seq);
|
||||
break;
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTPREV):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTBOLD):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTITALIC):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
if (norecurse)
|
||||
break;
|
||||
print_metaf(h, esc);
|
||||
break;
|
||||
case (ESCAPE_NOSPACE):
|
||||
if ('\0' == *p)
|
||||
nospace = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(nospace);
|
||||
|
@ -384,11 +401,7 @@ print_otag(struct html *h, enum htmltag tag,
|
|||
/* Push this tags onto the stack of open scopes. */
|
||||
|
||||
if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
|
||||
t = malloc(sizeof(struct tag));
|
||||
if (NULL == t) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
t = mandoc_malloc(sizeof(struct tag));
|
||||
t->tag = tag;
|
||||
t->next = h->tags.head;
|
||||
h->tags.head = t;
|
||||
|
@ -425,7 +438,7 @@ print_otag(struct html *h, enum htmltag tag,
|
|||
print_attr(h, "lang", "en");
|
||||
}
|
||||
|
||||
/* Accomodate for XML "well-formed" singleton escaping. */
|
||||
/* Accommodate for XML "well-formed" singleton escaping. */
|
||||
|
||||
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
||||
switch (h->type) {
|
||||
|
@ -458,27 +471,8 @@ print_ctag(struct html *h, enum htmltag tag)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_gen_decls(struct html *h)
|
||||
{
|
||||
|
||||
print_xmltype(h);
|
||||
print_doctype(h);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_xmltype(struct html *h)
|
||||
{
|
||||
|
||||
if (HTML_XHTML_1_0_STRICT == h->type)
|
||||
puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_doctype(struct html *h)
|
||||
{
|
||||
const char *doctype;
|
||||
const char *dtd;
|
||||
|
@ -491,6 +485,7 @@ print_doctype(struct html *h)
|
|||
dtd = "http://www.w3.org/TR/html4/strict.dtd";
|
||||
break;
|
||||
default:
|
||||
puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
name = "html";
|
||||
doctype = "-//W3C//DTD XHTML 1.0 Strict//EN";
|
||||
dtd = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
|
||||
|
@ -501,35 +496,10 @@ print_doctype(struct html *h)
|
|||
name, doctype, dtd);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_text(struct html *h, const char *word)
|
||||
{
|
||||
|
||||
if (word[0] && '\0' == word[1])
|
||||
switch (word[0]) {
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
if ( ! (HTML_IGNDELIM & h->flags))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! (HTML_NOSPACE & h->flags)) {
|
||||
/* Manage keeps! */
|
||||
if ( ! (HTML_KEEP & h->flags)) {
|
||||
|
@ -547,9 +517,11 @@ print_text(struct html *h, const char *word)
|
|||
print_otag(h, TAG_I, 0, NULL);
|
||||
|
||||
assert(word);
|
||||
if ( ! print_encode(h, word, 0))
|
||||
if ( ! print_encode(h, word, 0)) {
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
} else
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
if (h->metaf) {
|
||||
print_tagq(h, h->metaf);
|
||||
|
@ -557,21 +529,6 @@ print_text(struct html *h, const char *word)
|
|||
}
|
||||
|
||||
h->flags &= ~HTML_IGNDELIM;
|
||||
|
||||
/*
|
||||
* Note that we don't process the pipe: the parser sees it as
|
||||
* punctuation, but we don't in terms of typography.
|
||||
*/
|
||||
if (word[0] && '\0' == word[1])
|
||||
switch (word[0]) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
h->flags |= HTML_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -581,8 +538,14 @@ print_tagq(struct html *h, const struct tag *until)
|
|||
struct tag *tag;
|
||||
|
||||
while ((tag = h->tags.head) != NULL) {
|
||||
/*
|
||||
* 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;
|
||||
print_ctag(h, tag->tag);
|
||||
h->tags.head = tag->next;
|
||||
free(tag);
|
||||
|
@ -600,15 +563,20 @@ print_stagq(struct html *h, const struct tag *suntil)
|
|||
while ((tag = h->tags.head) != NULL) {
|
||||
if (suntil && tag == suntil)
|
||||
return;
|
||||
/*
|
||||
* 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;
|
||||
print_ctag(h, tag->tag);
|
||||
h->tags.head = tag->next;
|
||||
free(tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufinit(struct html *h)
|
||||
{
|
||||
|
@ -617,28 +585,26 @@ bufinit(struct html *h)
|
|||
h->buflen = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufcat_style(struct html *h, const char *key, const char *val)
|
||||
{
|
||||
|
||||
bufcat(h, key);
|
||||
bufncat(h, ":", 1);
|
||||
bufcat(h, ":");
|
||||
bufcat(h, val);
|
||||
bufncat(h, ";", 1);
|
||||
bufcat(h, ";");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufcat(struct html *h, const char *p)
|
||||
{
|
||||
|
||||
bufncat(h, p, strlen(p));
|
||||
h->buflen = strlcat(h->buf, p, BUFSIZ);
|
||||
assert(h->buflen < BUFSIZ);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buffmt(struct html *h, const char *fmt, ...)
|
||||
bufcat_fmt(struct html *h, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
@ -649,19 +615,15 @@ buffmt(struct html *h, const char *fmt, ...)
|
|||
h->buflen = strlen(h->buf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
bufncat(struct html *h, const char *p, size_t sz)
|
||||
{
|
||||
|
||||
if (h->buflen + sz > BUFSIZ - 1)
|
||||
sz = BUFSIZ - 1 - h->buflen;
|
||||
|
||||
(void)strncat(h->buf, p, sz);
|
||||
assert(h->buflen + sz + 1 < BUFSIZ);
|
||||
strncat(h->buf, p, sz);
|
||||
h->buflen += sz;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buffmt_includes(struct html *h, const char *name)
|
||||
{
|
||||
|
@ -669,6 +631,7 @@ buffmt_includes(struct html *h, const char *name)
|
|||
|
||||
pp = h->base_includes;
|
||||
|
||||
bufinit(h);
|
||||
while (NULL != (p = strchr(pp, '%'))) {
|
||||
bufncat(h, pp, (size_t)(p - pp));
|
||||
switch (*(p + 1)) {
|
||||
|
@ -685,7 +648,6 @@ buffmt_includes(struct html *h, const char *name)
|
|||
bufcat(h, pp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buffmt_man(struct html *h,
|
||||
const char *name, const char *sec)
|
||||
|
@ -694,7 +656,7 @@ buffmt_man(struct html *h,
|
|||
|
||||
pp = h->base_man;
|
||||
|
||||
/* LINTED */
|
||||
bufinit(h);
|
||||
while (NULL != (p = strchr(pp, '%'))) {
|
||||
bufncat(h, pp, (size_t)(p - pp));
|
||||
switch (*(p + 1)) {
|
||||
|
@ -702,7 +664,7 @@ buffmt_man(struct html *h,
|
|||
bufcat(h, sec ? sec : "1");
|
||||
break;
|
||||
case('N'):
|
||||
buffmt(h, name);
|
||||
bufcat_fmt(h, name);
|
||||
break;
|
||||
default:
|
||||
bufncat(h, p, 2);
|
||||
|
@ -714,85 +676,24 @@ buffmt_man(struct html *h,
|
|||
bufcat(h, pp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufcat_su(struct html *h, const char *p, const struct roffsu *su)
|
||||
{
|
||||
double v;
|
||||
const char *u;
|
||||
|
||||
v = su->scale;
|
||||
if (SCALE_MM == su->unit && 0.0 == (v /= 100.0))
|
||||
v = 1.0;
|
||||
|
||||
switch (su->unit) {
|
||||
case (SCALE_CM):
|
||||
u = "cm";
|
||||
break;
|
||||
case (SCALE_IN):
|
||||
u = "in";
|
||||
break;
|
||||
case (SCALE_PC):
|
||||
u = "pc";
|
||||
break;
|
||||
case (SCALE_PT):
|
||||
u = "pt";
|
||||
break;
|
||||
case (SCALE_EM):
|
||||
u = "em";
|
||||
break;
|
||||
case (SCALE_MM):
|
||||
if (0 == (v /= 100))
|
||||
v = 1;
|
||||
u = "em";
|
||||
break;
|
||||
case (SCALE_EN):
|
||||
u = "ex";
|
||||
break;
|
||||
case (SCALE_BU):
|
||||
u = "ex";
|
||||
break;
|
||||
case (SCALE_VS):
|
||||
u = "em";
|
||||
break;
|
||||
default:
|
||||
u = "ex";
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: the CSS spec isn't clear as to which types accept
|
||||
* integer or real numbers, so we just make them all decimals.
|
||||
*/
|
||||
buffmt(h, "%s: %.2f%s;", p, v, u);
|
||||
bufcat_fmt(h, "%s: %.2f%s;", p, v, roffscales[su->unit]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
html_idcat(char *dst, const char *src, int sz)
|
||||
bufcat_id(struct html *h, const char *src)
|
||||
{
|
||||
int ssz;
|
||||
|
||||
assert(sz > 2);
|
||||
|
||||
/* Cf. <http://www.w3.org/TR/html4/types.html#h-6.2>. */
|
||||
|
||||
/* We can't start with a number (bah). */
|
||||
|
||||
if ('#' == *dst) {
|
||||
dst++;
|
||||
sz--;
|
||||
}
|
||||
if ('\0' == *dst) {
|
||||
*dst++ = 'x';
|
||||
*dst = '\0';
|
||||
sz--;
|
||||
}
|
||||
|
||||
for ( ; *dst != '\0' && sz; dst++, sz--)
|
||||
/* Jump to end. */ ;
|
||||
|
||||
for ( ; *src != '\0' && sz > 1; src++) {
|
||||
ssz = snprintf(dst, (size_t)sz, "%.2x", *src);
|
||||
sz -= ssz;
|
||||
dst += ssz;
|
||||
}
|
||||
while ('\0' != *src)
|
||||
bufcat_fmt(h, "%.2x", *src++);
|
||||
}
|
||||
|
|
33
external/bsd/mdocml/dist/html.h
vendored
33
external/bsd/mdocml/dist/html.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: html.h,v 1.38 2011/01/06 11:55:39 kristaps Exp $ */
|
||||
/* $Vendor-Id: html.h,v 1.47 2011/10/05 21:35:17 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -67,6 +67,7 @@ enum htmlattr {
|
|||
ATTR_ID,
|
||||
ATTR_SUMMARY,
|
||||
ATTR_ALIGN,
|
||||
ATTR_COLSPAN,
|
||||
ATTR_MAX
|
||||
};
|
||||
|
||||
|
@ -110,14 +111,16 @@ enum htmltype {
|
|||
|
||||
struct html {
|
||||
int flags;
|
||||
#define HTML_NOSPACE (1 << 0)
|
||||
#define HTML_NOSPACE (1 << 0) /* suppress next space */
|
||||
#define HTML_IGNDELIM (1 << 1)
|
||||
#define HTML_KEEP (1 << 2)
|
||||
#define HTML_PREKEEP (1 << 3)
|
||||
#define HTML_NONOSPACE (1 << 4)
|
||||
#define HTML_NONOSPACE (1 << 4) /* never add spaces */
|
||||
#define HTML_LITERAL (1 << 5) /* literal (e.g., <PRE>) context */
|
||||
struct tagq tags; /* stack of open tags */
|
||||
struct rofftbl tbl; /* current table */
|
||||
void *symtab; /* character-escapes */
|
||||
struct tag *tblt; /* current open table scope */
|
||||
struct mchars *symtab; /* character-escapes */
|
||||
char *base_man; /* base for manpage href */
|
||||
char *base_includes; /* base for include href */
|
||||
char *style; /* style-sheet URI */
|
||||
|
@ -126,7 +129,9 @@ struct html {
|
|||
struct tag *metaf; /* current open font scope */
|
||||
enum htmlfont metal; /* last used font */
|
||||
enum htmlfont metac; /* current font mode */
|
||||
enum htmltype type;
|
||||
enum htmltype type; /* output media type */
|
||||
int oflags; /* output options */
|
||||
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
|
||||
};
|
||||
|
||||
void print_gen_decls(struct html *);
|
||||
|
@ -136,21 +141,23 @@ struct tag *print_otag(struct html *, enum htmltag,
|
|||
void print_tagq(struct html *, const struct tag *);
|
||||
void print_stagq(struct html *, const struct tag *);
|
||||
void print_text(struct html *, const char *);
|
||||
void print_tblclose(struct html *);
|
||||
void print_tbl(struct html *, const struct tbl_span *);
|
||||
void print_eqn(struct html *, const struct eqn *);
|
||||
|
||||
void bufcat_fmt(struct html *, const char *, ...);
|
||||
void bufcat(struct html *, const char *);
|
||||
void bufcat_id(struct html *, const char *);
|
||||
void bufcat_style(struct html *,
|
||||
const char *, const char *);
|
||||
void bufcat_su(struct html *, const char *,
|
||||
const struct roffsu *);
|
||||
void bufinit(struct html *);
|
||||
void buffmt_man(struct html *,
|
||||
const char *, const char *);
|
||||
void buffmt_includes(struct html *, const char *);
|
||||
void buffmt(struct html *, const char *, ...);
|
||||
void bufcat(struct html *, const char *);
|
||||
void bufcat_style(struct html *,
|
||||
const char *, const char *);
|
||||
void bufncat(struct html *, const char *, size_t);
|
||||
void bufinit(struct html *);
|
||||
|
||||
void html_idcat(char *, const char *, int);
|
||||
int html_strlen(const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
3
external/bsd/mdocml/dist/lib.c
vendored
3
external/bsd/mdocml/dist/lib.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: lib.c,v 1.8 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/* $Vendor-Id: lib.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
|
|
12
external/bsd/mdocml/dist/lib.in
vendored
12
external/bsd/mdocml/dist/lib.in
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: lib.in,v 1.9 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/* $Vendor-Id: lib.in,v 1.13 2012/01/28 23:46:28 joerg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -40,9 +40,11 @@ LINE("libcurses", "Curses Library (libcurses, \\-lcurses)")
|
|||
LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)")
|
||||
LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)")
|
||||
LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)")
|
||||
LINE("libdwarf", "DWARF Access Library (libdwarf, \\-ldwarf)")
|
||||
LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)")
|
||||
LINE("libelf", "ELF Parsing Library (libelf, \\-lelf)")
|
||||
LINE("libelf", "ELF Access Library (libelf, \\-lelf)")
|
||||
LINE("libevent", "Event Notification Library (libevent, \\-levent)")
|
||||
LINE("libexecinfo", "Backtrace Information Library (libexecinfo, \\-lexecinfo)")
|
||||
LINE("libfetch", "File Transfer Library for URLs (libfetch, \\-lfetch)")
|
||||
LINE("libform", "Curses Form Library (libform, \\-lform)")
|
||||
LINE("libgeom", "Userland API Library for kernel GEOM subsystem (libgeom, \\-lgeom)")
|
||||
|
@ -71,16 +73,20 @@ LINE("libpcap", "Capture Library (libpcap, \\-lpcap)")
|
|||
LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
|
||||
LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
|
||||
LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
|
||||
LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
|
||||
LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
|
||||
LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
|
||||
LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
|
||||
LINE("libquota", "Disk Quota Access and Control Library (libquota, \\-lquota)")
|
||||
LINE("librefuse", "File System in Userspace Convenience Library (librefuse, \\-lrefuse)")
|
||||
LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
|
||||
LINE("librpcsec_gss", "RPC GSS-API Authentication Library (librpcsec_gss, \\-lrpcsec_gss)")
|
||||
LINE("librpcsvc", "RPC Service Library (librpcsvc, \\-lrpcsvc)")
|
||||
LINE("librt", "POSIX Real\\-time Library (librt, -lrt)")
|
||||
LINE("librt", "POSIX Real\\-time Library (librt, \\-lrt)")
|
||||
LINE("libsaslc", "Simple Authentication and Security Layer client library (libsaslc, \\-lsaslc)")
|
||||
LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)")
|
||||
LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
|
||||
LINE("libSystem", "System Library (libSystem, \\-lSystem)")
|
||||
LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
|
||||
LINE("libterminfo", "Terminal Information Library (libterminfo, \\-lterminfo)")
|
||||
LINE("libthr", "1:1 Threading Library (libthr, \\-lthr)")
|
||||
|
|
25
external/bsd/mdocml/dist/libman.h
vendored
25
external/bsd/mdocml/dist/libman.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: libman.h,v 1.44 2010/11/30 15:36:28 kristaps Exp $ */
|
||||
/* $Vendor-Id: libman.h,v 1.55 2011/11/07 01:24:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,16 +17,13 @@
|
|||
#ifndef LIBMAN_H
|
||||
#define LIBMAN_H
|
||||
|
||||
#include "man.h"
|
||||
|
||||
enum man_next {
|
||||
MAN_NEXT_SIBLING = 0,
|
||||
MAN_NEXT_CHILD
|
||||
};
|
||||
|
||||
struct man {
|
||||
void *data; /* private application data */
|
||||
mandocmsg msg; /* output message handler */
|
||||
struct mparse *parse; /* parse pointer */
|
||||
int flags; /* parse flags */
|
||||
#define MAN_HALT (1 << 0) /* badness happened: die */
|
||||
#define MAN_ELINE (1 << 1) /* Next-line element scope. */
|
||||
|
@ -34,11 +31,12 @@ struct man {
|
|||
#define MAN_ILINE (1 << 3) /* Ignored in next-line scope. */
|
||||
#define MAN_LITERAL (1 << 4) /* Literal input. */
|
||||
#define MAN_BPLINE (1 << 5)
|
||||
#define MAN_NEWLINE (1 << 6) /* first macro/text in a line */
|
||||
enum man_next next; /* where to put the next node */
|
||||
struct man_node *last; /* the last parsed node */
|
||||
struct man_node *first; /* the first parsed node */
|
||||
struct man_meta meta; /* document meta-data */
|
||||
struct regset *regs; /* registers */
|
||||
struct roff *roff;
|
||||
};
|
||||
|
||||
#define MACRO_PROT_ARGS struct man *m, \
|
||||
|
@ -56,6 +54,7 @@ struct man_macro {
|
|||
#define MAN_FSCOPED (1 << 2) /* See blk_imp(). */
|
||||
#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */
|
||||
#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */
|
||||
#define MAN_BSCOPE (1 << 5) /* Break BLINE scope. */
|
||||
};
|
||||
|
||||
extern const struct man_macro *const man_macros;
|
||||
|
@ -63,25 +62,19 @@ extern const struct man_macro *const man_macros;
|
|||
__BEGIN_DECLS
|
||||
|
||||
#define man_pmsg(m, l, p, t) \
|
||||
(*(m)->msg)((t), (m)->data, (l), (p), NULL)
|
||||
mandoc_msg((t), (m)->parse, (l), (p), NULL)
|
||||
#define man_nmsg(m, n, t) \
|
||||
(*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL)
|
||||
mandoc_msg((t), (m)->parse, (n)->line, (n)->pos, NULL)
|
||||
int man_word_alloc(struct man *, int, int, const char *);
|
||||
int man_block_alloc(struct man *, int, int, enum mant);
|
||||
int man_head_alloc(struct man *, int, int, enum mant);
|
||||
int man_tail_alloc(struct man *, int, int, enum mant);
|
||||
int man_body_alloc(struct man *, int, int, enum mant);
|
||||
int man_elem_alloc(struct man *, int, int, enum mant);
|
||||
void man_node_delete(struct man *, struct man_node *);
|
||||
void man_hash_init(void);
|
||||
enum mant man_hash_find(const char *);
|
||||
int man_macroend(struct man *);
|
||||
int man_args(struct man *, int, int *, char *, char **);
|
||||
#define ARGS_ERROR (-1)
|
||||
#define ARGS_EOLN (0)
|
||||
#define ARGS_WORD (1)
|
||||
#define ARGS_QWORD (1)
|
||||
int man_vmsg(struct man *, enum mandocerr,
|
||||
int, int, const char *, ...);
|
||||
int man_valid_post(struct man *);
|
||||
int man_valid_pre(struct man *, struct man_node *);
|
||||
int man_unscope(struct man *,
|
||||
|
|
82
external/bsd/mdocml/dist/libmandoc.h
vendored
82
external/bsd/mdocml/dist/libmandoc.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: libmandoc.h,v 1.10 2011/01/03 22:42:37 schwarze Exp $ */
|
||||
/* $Vendor-Id: libmandoc.h,v 1.29 2011/12/02 01:37:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,21 +17,75 @@
|
|||
#ifndef LIBMANDOC_H
|
||||
#define LIBMANDOC_H
|
||||
|
||||
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 */
|
||||
ROFF_TBL, /* a table row was successfully parsed */
|
||||
ROFF_EQN, /* an equation was successfully parsed */
|
||||
ROFF_ERR /* badness: puke and stop */
|
||||
};
|
||||
|
||||
enum regs {
|
||||
REG_nS = 0, /* nS register */
|
||||
REG__MAX
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int mandoc_special(char *);
|
||||
void *mandoc_calloc(size_t, size_t);
|
||||
char *mandoc_strdup(const char *);
|
||||
void *mandoc_malloc(size_t);
|
||||
void *mandoc_realloc(void *, size_t);
|
||||
char *mandoc_getarg(char **, mandocmsg, void *, int, int *);
|
||||
time_t mandoc_a2time(int, const char *);
|
||||
#define MTIME_CANONICAL (1 << 0)
|
||||
#define MTIME_REDUCED (1 << 1)
|
||||
#define MTIME_MDOCDATE (1 << 2)
|
||||
#define MTIME_ISO_8601 (1 << 3)
|
||||
struct roff;
|
||||
struct mdoc;
|
||||
struct man;
|
||||
|
||||
void mandoc_msg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *);
|
||||
void mandoc_vmsg(enum mandocerr, struct mparse *,
|
||||
int, int, const char *, ...);
|
||||
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
||||
char *mandoc_normdate(struct mparse *, char *, int, int);
|
||||
int mandoc_eos(const char *, size_t, int);
|
||||
int mandoc_hyph(const char *, const char *);
|
||||
int mandoc_getcontrol(const char *, int *);
|
||||
int mandoc_strntoi(const char *, size_t, int);
|
||||
const char *mandoc_a2msec(const char*);
|
||||
|
||||
void mdoc_free(struct mdoc *);
|
||||
struct mdoc *mdoc_alloc(struct roff *, struct mparse *);
|
||||
void mdoc_reset(struct mdoc *);
|
||||
int mdoc_parseln(struct mdoc *, int, char *, int);
|
||||
int mdoc_endparse(struct mdoc *);
|
||||
int mdoc_addspan(struct mdoc *, const struct tbl_span *);
|
||||
int mdoc_addeqn(struct mdoc *, const struct eqn *);
|
||||
|
||||
void man_free(struct man *);
|
||||
struct man *man_alloc(struct roff *, struct mparse *);
|
||||
void man_reset(struct man *);
|
||||
int man_parseln(struct man *, int, char *, int);
|
||||
int man_endparse(struct man *);
|
||||
int man_addspan(struct man *, const struct tbl_span *);
|
||||
int man_addeqn(struct man *, const struct eqn *);
|
||||
|
||||
void roff_free(struct roff *);
|
||||
struct roff *roff_alloc(struct mparse *);
|
||||
void roff_reset(struct roff *);
|
||||
enum rofferr roff_parseln(struct roff *, int,
|
||||
char **, size_t *, int, int *);
|
||||
void roff_endparse(struct roff *);
|
||||
int roff_regisset(const struct roff *, enum regs);
|
||||
unsigned int roff_regget(const struct roff *, enum regs);
|
||||
void roff_regunset(struct roff *, enum regs);
|
||||
char *roff_strdup(const struct roff *, const char *);
|
||||
#if 0
|
||||
char roff_eqndelim(const struct roff *);
|
||||
void roff_openeqn(struct roff *, const char *,
|
||||
int, int, const char *);
|
||||
int roff_closeeqn(struct roff *);
|
||||
#endif
|
||||
|
||||
const struct tbl_span *roff_span(const struct roff *);
|
||||
const struct eqn *roff_eqn(const struct roff *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
66
external/bsd/mdocml/dist/libmdoc.h
vendored
66
external/bsd/mdocml/dist/libmdoc.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: libmdoc.h,v 1.63 2010/11/30 13:04:14 kristaps Exp $ */
|
||||
/* $Vendor-Id: libmdoc.h,v 1.78 2011/12/02 01:37:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,17 +17,14 @@
|
|||
#ifndef LIBMDOC_H
|
||||
#define LIBMDOC_H
|
||||
|
||||
#include "mdoc.h"
|
||||
|
||||
enum mdoc_next {
|
||||
MDOC_NEXT_SIBLING = 0,
|
||||
MDOC_NEXT_CHILD
|
||||
};
|
||||
|
||||
struct mdoc {
|
||||
void *data; /* private application data */
|
||||
mandocmsg msg; /* message callback */
|
||||
int flags;
|
||||
struct mparse *parse; /* parse pointer */
|
||||
int flags; /* parse flags */
|
||||
#define MDOC_HALT (1 << 0) /* error in parse: halt */
|
||||
#define MDOC_LITERAL (1 << 1) /* in a literal scope */
|
||||
#define MDOC_PBODY (1 << 2) /* in the document body */
|
||||
|
@ -42,7 +39,7 @@ struct mdoc {
|
|||
struct mdoc_meta meta; /* document meta-data */
|
||||
enum mdoc_sec lastnamed;
|
||||
enum mdoc_sec lastsec;
|
||||
struct regset *regs; /* registers */
|
||||
struct roff *roff;
|
||||
};
|
||||
|
||||
#define MACRO_PROT_ARGS struct mdoc *m, \
|
||||
|
@ -65,27 +62,37 @@ struct mdoc_macro {
|
|||
|
||||
enum margserr {
|
||||
ARGS_ERROR,
|
||||
ARGS_EOLN,
|
||||
ARGS_WORD,
|
||||
ARGS_PUNCT,
|
||||
ARGS_QWORD,
|
||||
ARGS_PHRASE,
|
||||
ARGS_PPHRASE,
|
||||
ARGS_PEND
|
||||
ARGS_EOLN, /* end-of-line */
|
||||
ARGS_WORD, /* normal word */
|
||||
ARGS_PUNCT, /* series of punctuation */
|
||||
ARGS_QWORD, /* quoted word */
|
||||
ARGS_PHRASE, /* Ta'd phrase (-column) */
|
||||
ARGS_PPHRASE, /* tabbed phrase (-column) */
|
||||
ARGS_PEND /* last phrase (-column) */
|
||||
};
|
||||
|
||||
enum margverr {
|
||||
ARGV_ERROR,
|
||||
ARGV_EOLN,
|
||||
ARGV_ARG,
|
||||
ARGV_WORD
|
||||
ARGV_EOLN, /* end of line */
|
||||
ARGV_ARG, /* valid argument */
|
||||
ARGV_WORD /* normal word (or bad argument---same thing) */
|
||||
};
|
||||
|
||||
/*
|
||||
* A punctuation delimiter is opening, closing, or "middle mark"
|
||||
* punctuation. These govern spacing.
|
||||
* Opening punctuation (e.g., the opening parenthesis) suppresses the
|
||||
* following space; closing punctuation (e.g., the closing parenthesis)
|
||||
* suppresses the leading space; middle punctuation (e.g., the vertical
|
||||
* bar) can do either. The middle punctuation delimiter bends the rules
|
||||
* depending on usage.
|
||||
*/
|
||||
enum mdelim {
|
||||
DELIM_NONE = 0,
|
||||
DELIM_OPEN,
|
||||
DELIM_MIDDLE,
|
||||
DELIM_CLOSE
|
||||
DELIM_CLOSE,
|
||||
DELIM_MAX
|
||||
};
|
||||
|
||||
extern const struct mdoc_macro *const mdoc_macros;
|
||||
|
@ -93,11 +100,9 @@ extern const struct mdoc_macro *const mdoc_macros;
|
|||
__BEGIN_DECLS
|
||||
|
||||
#define mdoc_pmsg(m, l, p, t) \
|
||||
(*(m)->msg)((t), (m)->data, (l), (p), NULL)
|
||||
mandoc_msg((t), (m)->parse, (l), (p), NULL)
|
||||
#define mdoc_nmsg(m, n, t) \
|
||||
(*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL)
|
||||
int mdoc_vmsg(struct mdoc *, enum mandocerr,
|
||||
int, int, const char *, ...);
|
||||
mandoc_msg((t), (m)->parse, (n)->line, (n)->pos, NULL)
|
||||
int mdoc_macro(MACRO_PROT_ARGS);
|
||||
int mdoc_word_alloc(struct mdoc *,
|
||||
int, int, const char *);
|
||||
|
@ -114,33 +119,22 @@ int mdoc_endbody_alloc(struct mdoc *m, int line, int pos,
|
|||
void mdoc_node_delete(struct mdoc *, struct mdoc_node *);
|
||||
void mdoc_hash_init(void);
|
||||
enum mdoct mdoc_hash_find(const char *);
|
||||
enum mdelim mdoc_iscdelim(char);
|
||||
enum mdelim mdoc_isdelim(const char *);
|
||||
size_t mdoc_isescape(const char *);
|
||||
enum mdoc_sec mdoc_str2sec(const char *);
|
||||
time_t mdoc_atotime(const char *);
|
||||
size_t mdoc_macro2len(enum mdoct);
|
||||
const char *mdoc_a2att(const char *);
|
||||
const char *mdoc_a2lib(const char *);
|
||||
const char *mdoc_a2st(const char *);
|
||||
const char *mdoc_a2arch(const char *);
|
||||
const char *mdoc_a2vol(const char *);
|
||||
const char *mdoc_a2msec(const char *);
|
||||
int mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
|
||||
int mdoc_valid_post(struct mdoc *);
|
||||
enum margverr mdoc_argv(struct mdoc *, int, enum mdoct,
|
||||
struct mdoc_arg **, int *, char *);
|
||||
void mdoc_argv_free(struct mdoc_arg *);
|
||||
void mdoc_argn_free(struct mdoc_arg *, int);
|
||||
enum margserr mdoc_args(struct mdoc *, int,
|
||||
int *, char *, enum mdoct, char **);
|
||||
enum margserr mdoc_zargs(struct mdoc *, int,
|
||||
int *, char *, int, char **);
|
||||
#define ARGS_DELIM (1 << 1)
|
||||
#define ARGS_TABSEP (1 << 2)
|
||||
#define ARGS_NOWARN (1 << 3)
|
||||
|
||||
int *, char *, char **);
|
||||
int mdoc_macroend(struct mdoc *);
|
||||
enum mdelim mdoc_isdelim(const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
40
external/bsd/mdocml/dist/libroff.h
vendored
40
external/bsd/mdocml/dist/libroff.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: libroff.h,v 1.16 2011/01/04 15:02:00 kristaps Exp $ */
|
||||
/* $Vendor-Id: libroff.h,v 1.27 2011/07/25 15:37:00 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -27,8 +27,7 @@ enum tbl_part {
|
|||
};
|
||||
|
||||
struct tbl_node {
|
||||
mandocmsg msg; /* status messages */
|
||||
void *data; /* privdata for messages */
|
||||
struct mparse *parse; /* parse point */
|
||||
int pos; /* invocation column */
|
||||
int line; /* invocation line */
|
||||
enum tbl_part part;
|
||||
|
@ -36,16 +35,34 @@ struct tbl_node {
|
|||
struct tbl_row *first_row;
|
||||
struct tbl_row *last_row;
|
||||
struct tbl_span *first_span;
|
||||
struct tbl_span *current_span;
|
||||
struct tbl_span *last_span;
|
||||
struct tbl_head *first_head;
|
||||
struct tbl_head *last_head;
|
||||
struct tbl_node *next;
|
||||
};
|
||||
|
||||
#define TBL_MSG(tblp, type, line, col) \
|
||||
(*(tblp)->msg)((type), (tblp)->data, (line), (col), NULL)
|
||||
struct eqn_node {
|
||||
struct eqn_def *defs;
|
||||
size_t defsz;
|
||||
char *data;
|
||||
size_t rew;
|
||||
size_t cur;
|
||||
size_t sz;
|
||||
int gsize;
|
||||
struct eqn eqn;
|
||||
struct mparse *parse;
|
||||
struct eqn_node *next;
|
||||
};
|
||||
|
||||
struct tbl_node *tbl_alloc(int, int, void *, mandocmsg);
|
||||
struct eqn_def {
|
||||
char *key;
|
||||
size_t keysz;
|
||||
char *val;
|
||||
size_t valsz;
|
||||
};
|
||||
|
||||
struct tbl_node *tbl_alloc(int, int, struct mparse *);
|
||||
void tbl_restart(int, int, struct tbl_node *);
|
||||
void tbl_free(struct tbl_node *);
|
||||
void tbl_reset(struct tbl_node *);
|
||||
|
@ -54,8 +71,13 @@ int tbl_option(struct tbl_node *, int, const char *);
|
|||
int tbl_layout(struct tbl_node *, int, const char *);
|
||||
int tbl_data(struct tbl_node *, int, const char *);
|
||||
int tbl_cdata(struct tbl_node *, int, const char *);
|
||||
const struct tbl_span *tbl_span(const struct tbl_node *);
|
||||
void tbl_end(struct tbl_node *);
|
||||
const struct tbl_span *tbl_span(struct tbl_node *);
|
||||
void tbl_end(struct tbl_node **);
|
||||
struct eqn_node *eqn_alloc(const char *, int, int, struct mparse *);
|
||||
enum rofferr eqn_end(struct eqn_node **);
|
||||
void eqn_free(struct eqn_node *);
|
||||
enum rofferr eqn_read(struct eqn_node **, int,
|
||||
const char *, int, int *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
851
external/bsd/mdocml/dist/main.c
vendored
851
external/bsd/mdocml/dist/main.c
vendored
File diff suppressed because it is too large
Load diff
9
external/bsd/mdocml/dist/main.h
vendored
9
external/bsd/mdocml/dist/main.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: main.h,v 1.10 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/* $Vendor-Id: main.h,v 1.15 2011/10/06 22:29:12 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -41,6 +41,11 @@ void html_free(void *);
|
|||
void tree_mdoc(void *, const struct mdoc *);
|
||||
void tree_man(void *, const struct man *);
|
||||
|
||||
void man_mdoc(void *, const struct mdoc *);
|
||||
void man_man(void *, const struct man *);
|
||||
|
||||
void *locale_alloc(char *);
|
||||
void *utf8_alloc(char *);
|
||||
void *ascii_alloc(char *);
|
||||
void ascii_free(void *);
|
||||
|
||||
|
|
13
external/bsd/mdocml/dist/man-cgi.css
vendored
Normal file
13
external/bsd/mdocml/dist/man-cgi.css
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
body { font-family: Helvetica, Arial, sans-serif; }
|
||||
body > div { padding-left: 2em;
|
||||
padding-top: 1em; }
|
||||
body > div#mancgi { padding-left: 0em;
|
||||
padding-top: 0em; }
|
||||
body > div.results { font-size: smaller; }
|
||||
#mancgi fieldset { text-align: center;
|
||||
border: thin solid silver;
|
||||
border-radius: 1em;
|
||||
font-size: small; }
|
||||
#mancgi input[name=expr] { width: 25%; }
|
||||
.results td.title { vertical-align: top;
|
||||
padding-right: 1em; }
|
272
external/bsd/mdocml/dist/man.3
vendored
272
external/bsd/mdocml/dist/man.3
vendored
|
@ -1,272 +0,0 @@
|
|||
.\" $Vendor-Id: man.3,v 1.29 2011/01/03 11:31:26 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 3, 2011
|
||||
.Dt MAN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm man ,
|
||||
.Nm man_alloc ,
|
||||
.Nm man_endparse ,
|
||||
.Nm man_free ,
|
||||
.Nm man_meta ,
|
||||
.Nm man_node ,
|
||||
.Nm man_parseln ,
|
||||
.Nm man_reset
|
||||
.Nd man macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In mandoc.h
|
||||
.In man.h
|
||||
.Vt extern const char * const * man_macronames;
|
||||
.Ft int
|
||||
.Fo man_addspan
|
||||
.Fa "struct man *man"
|
||||
.Fa "const struct tbl_span *span"
|
||||
.Fc
|
||||
.Ft "struct man *"
|
||||
.Fo man_alloc
|
||||
.Fa "struct regset *regs"
|
||||
.Fa "void *data"
|
||||
.Fa "mandocmsg msgs"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn man_endparse "struct man *man"
|
||||
.Ft void
|
||||
.Fn man_free "struct man *man"
|
||||
.Ft "const struct man_meta *"
|
||||
.Fn man_meta "const struct man *man"
|
||||
.Ft "const struct man_node *"
|
||||
.Fn man_node "const struct man *man"
|
||||
.Ft int
|
||||
.Fo man_parseln
|
||||
.Fa "struct man *man"
|
||||
.Fa "int line"
|
||||
.Fa "char *buf"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn man_reset "struct man *man"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
library parses lines of
|
||||
.Xr man 7
|
||||
input into an abstract syntax tree (AST).
|
||||
.Pp
|
||||
In general, applications initiate a parsing sequence with
|
||||
.Fn man_alloc ,
|
||||
parse each line in a document with
|
||||
.Fn man_parseln ,
|
||||
close the parsing session with
|
||||
.Fn man_endparse ,
|
||||
operate over the syntax tree returned by
|
||||
.Fn man_node
|
||||
and
|
||||
.Fn man_meta ,
|
||||
then free all allocated memory with
|
||||
.Fn man_free .
|
||||
The
|
||||
.Fn man_reset
|
||||
function may be used in order to reset the parser for another input
|
||||
sequence.
|
||||
.Pp
|
||||
Beyond the full set of macros defined in
|
||||
.Xr man 7 ,
|
||||
the
|
||||
.Nm
|
||||
library also accepts the following macro:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It PD
|
||||
Has no effect.
|
||||
Handled as a current-scope line macro.
|
||||
.El
|
||||
.Ss Types
|
||||
.Bl -ohang
|
||||
.It Vt struct man
|
||||
An opaque type.
|
||||
Its values are only used privately within the library.
|
||||
.It Vt struct man_node
|
||||
A parsed node.
|
||||
See
|
||||
.Sx Abstract Syntax Tree
|
||||
for details.
|
||||
.El
|
||||
.Ss Functions
|
||||
If
|
||||
.Fn man_addspan ,
|
||||
.Fn man_parseln ,
|
||||
or
|
||||
.Fn man_endparse
|
||||
return 0, calls to any function but
|
||||
.Fn man_reset
|
||||
or
|
||||
.Fn man_free
|
||||
will raise an assertion.
|
||||
.Bl -ohang
|
||||
.It Fn man_addspan
|
||||
Add a table span to the parsing stream.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn man_alloc
|
||||
Allocates a parsing structure.
|
||||
The
|
||||
.Fa data
|
||||
pointer is passed to
|
||||
.Fa msgs .
|
||||
Always returns a valid pointer.
|
||||
The pointer must be freed with
|
||||
.Fn man_free .
|
||||
.It Fn man_reset
|
||||
Reset the parser for another parse routine.
|
||||
After its use,
|
||||
.Fn man_parseln
|
||||
behaves as if invoked for the first time.
|
||||
.It Fn man_free
|
||||
Free all resources of a parser.
|
||||
The pointer is no longer valid after invocation.
|
||||
.It Fn man_parseln
|
||||
Parse a nil-terminated line of input.
|
||||
This line should not contain the trailing newline.
|
||||
Returns 0 on failure, 1 on success.
|
||||
The input buffer
|
||||
.Fa buf
|
||||
is modified by this function.
|
||||
.It Fn man_endparse
|
||||
Signals that the parse is complete.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn man_node
|
||||
Returns the first node of the parse.
|
||||
.It Fn man_meta
|
||||
Returns the document's parsed meta-data.
|
||||
.El
|
||||
.Ss Variables
|
||||
The following variables are also defined:
|
||||
.Bl -ohang
|
||||
.It Va man_macronames
|
||||
An array of string-ified token names.
|
||||
.El
|
||||
.Ss Abstract Syntax Tree
|
||||
The
|
||||
.Nm
|
||||
functions produce an abstract syntax tree (AST) describing input in a
|
||||
regular form.
|
||||
It may be reviewed at any time with
|
||||
.Fn man_nodes ;
|
||||
however, if called before
|
||||
.Fn man_endparse ,
|
||||
or after
|
||||
.Fn man_endparse
|
||||
or
|
||||
.Fn man_parseln
|
||||
fail, it may be incomplete.
|
||||
.Pp
|
||||
This AST is governed by the ontological rules dictated in
|
||||
.Xr man 7
|
||||
and derives its terminology accordingly.
|
||||
.Pp
|
||||
The AST is composed of
|
||||
.Vt struct man_node
|
||||
nodes with element, root and text types as declared by the
|
||||
.Va type
|
||||
field.
|
||||
Each node also provides its parse point (the
|
||||
.Va line ,
|
||||
.Va sec ,
|
||||
and
|
||||
.Va pos
|
||||
fields), its position in the tree (the
|
||||
.Va parent ,
|
||||
.Va child ,
|
||||
.Va next
|
||||
and
|
||||
.Va prev
|
||||
fields) and some type-specific data.
|
||||
.Pp
|
||||
The tree itself is arranged according to the following normal form,
|
||||
where capitalised non-terminals represent nodes.
|
||||
.Pp
|
||||
.Bl -tag -width "ELEMENTXX" -compact
|
||||
.It ROOT
|
||||
\(<- mnode+
|
||||
.It mnode
|
||||
\(<- ELEMENT | TEXT | BLOCK
|
||||
.It BLOCK
|
||||
\(<- HEAD BODY
|
||||
.It HEAD
|
||||
\(<- mnode*
|
||||
.It BODY
|
||||
\(<- mnode*
|
||||
.It ELEMENT
|
||||
\(<- ELEMENT | TEXT*
|
||||
.It TEXT
|
||||
\(<- [[:alpha:]]*
|
||||
.El
|
||||
.Pp
|
||||
The only elements capable of nesting other elements are those with
|
||||
next-lint scope as documented in
|
||||
.Xr man 7 .
|
||||
.Sh EXAMPLES
|
||||
The following example reads lines from stdin and parses them, operating
|
||||
on the finished parse tree with
|
||||
.Fn parsed .
|
||||
This example does not error-check nor free memory upon failure.
|
||||
.Bd -literal -offset indent
|
||||
struct regset regs;
|
||||
struct man *man;
|
||||
struct man_node *node;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int line;
|
||||
|
||||
bzero(®s, sizeof(struct regset));
|
||||
line = 1;
|
||||
man = man_alloc(®s, NULL, NULL);
|
||||
buf = NULL;
|
||||
alloc_len = 0;
|
||||
|
||||
while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
|
||||
if (len && buflen[len - 1] = '\en')
|
||||
buf[len - 1] = '\e0';
|
||||
if ( ! man_parseln(man, line, buf))
|
||||
errx(1, "man_parseln");
|
||||
line++;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
if ( ! man_endparse(man))
|
||||
errx(1, "man_endparse");
|
||||
if (NULL == (node = man_node(man)))
|
||||
errx(1, "man_node");
|
||||
|
||||
parsed(man, node);
|
||||
man_free(man);
|
||||
.Ed
|
||||
.Pp
|
||||
To compile this, execute
|
||||
.Pp
|
||||
.Dl % cc main.c libman.a libmandoc.a
|
||||
.Pp
|
||||
where
|
||||
.Pa main.c
|
||||
is the example file.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
690
external/bsd/mdocml/dist/man.7
vendored
690
external/bsd/mdocml/dist/man.7
vendored
|
@ -1,6 +1,7 @@
|
|||
.\" $Vendor-Id: man.7,v 1.94 2011/01/04 23:32:21 kristaps Exp $
|
||||
.\" $Vendor-Id: man.7,v 1.113 2012/01/03 15:16:24 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011 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,194 +15,68 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 4, 2011
|
||||
.Dd January 3, 2012
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm man
|
||||
.Nd man language reference
|
||||
.Nd legacy formatting language for manual pages
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
Traditionally, the
|
||||
.Nm man
|
||||
language was historically used to format
|
||||
language has been used to write
|
||||
.Ux
|
||||
manuals.
|
||||
This reference document describes its syntax, structure, and usage.
|
||||
manuals for the
|
||||
.Xr man 1
|
||||
utility.
|
||||
It supports limited control of presentational details like fonts,
|
||||
indentation and spacing.
|
||||
This reference document describes the structure of manual pages
|
||||
and the syntax and usage of the man language.
|
||||
.Pp
|
||||
.Bf -emphasis
|
||||
Do not use
|
||||
.Nm
|
||||
to write your manuals.
|
||||
to write your manuals:
|
||||
.Ef
|
||||
It lacks support for semantic markup.
|
||||
Use the
|
||||
.Xr mdoc 7
|
||||
language, instead.
|
||||
.Pp
|
||||
A
|
||||
In a
|
||||
.Nm
|
||||
document follows simple rules: lines beginning with the control
|
||||
character
|
||||
document, lines beginning with the control character
|
||||
.Sq \&.
|
||||
are parsed for macros.
|
||||
Other lines are interpreted within the scope of
|
||||
prior macros:
|
||||
are called
|
||||
.Dq macro lines .
|
||||
The first word is the macro name.
|
||||
It usually consists of two capital letters.
|
||||
For a list of available macros, see
|
||||
.Sx MACRO OVERVIEW .
|
||||
The words following the macro name are arguments to the macro.
|
||||
.Pp
|
||||
Lines not beginning with the control character are called
|
||||
.Dq text lines .
|
||||
They provide free-form text to be printed; the formatting of the text
|
||||
depends on the respective processing context:
|
||||
.Bd -literal -offset indent
|
||||
\&.SH Macro lines change control state.
|
||||
Other lines are interpreted within the current state.
|
||||
Text lines are interpreted within the current state.
|
||||
.Ed
|
||||
.Sh INPUT ENCODING
|
||||
.Nm
|
||||
documents may contain only graphable 7-bit ASCII characters, the
|
||||
space character, and the tab character.
|
||||
All manuals must have
|
||||
.Ux
|
||||
line termination.
|
||||
.Pp
|
||||
Blank lines are acceptable; where found, the output will assert a
|
||||
vertical space.
|
||||
.Ss Comments
|
||||
Text following a
|
||||
.Sq \e\*q ,
|
||||
whether in a macro or free-form text line, is ignored to the end of
|
||||
line.
|
||||
A macro line with only a control character and comment escape,
|
||||
.Sq \&.\e\*q ,
|
||||
is also ignored.
|
||||
Macro lines with only a control character and optionally whitespace are
|
||||
stripped from input.
|
||||
.Ss Special Characters
|
||||
Special characters may occur in both macro and free-form lines.
|
||||
Sequences begin with the escape character
|
||||
.Sq \e
|
||||
followed by either an open-parenthesis
|
||||
.Sq \&(
|
||||
for two-character sequences; an open-bracket
|
||||
.Sq \&[
|
||||
for n-character sequences (terminated at a close-bracket
|
||||
.Sq \&] ) ;
|
||||
or a single one-character sequence.
|
||||
See
|
||||
.Xr mandoc_char 7
|
||||
for a complete list.
|
||||
Examples include
|
||||
.Sq \e(em
|
||||
.Pq em-dash
|
||||
Many aspects of the basic syntax of the
|
||||
.Nm
|
||||
language are based on the
|
||||
.Xr roff 7
|
||||
language; see the
|
||||
.Em LANGUAGE SYNTAX
|
||||
and
|
||||
.Sq \ee
|
||||
.Pq back-slash .
|
||||
.Ss Text Decoration
|
||||
Terms may be text-decorated using the
|
||||
.Sq \ef
|
||||
escape followed by an indicator: B (bold), I (italic), R (Roman), or P
|
||||
(revert to previous mode):
|
||||
.Pp
|
||||
.D1 \efBbold\efR \efIitalic\efP
|
||||
.Pp
|
||||
A numerical representation 3, 2, or 1 (bold, italic, and Roman,
|
||||
respectively) may be used instead.
|
||||
A text decoration is only valid, if specified in free-form text, until
|
||||
the next macro invocation; if specified within a macro, it's only valid
|
||||
until the macro closes scope.
|
||||
Note that macros like
|
||||
.Sx \&BR
|
||||
open and close a font scope with each argument.
|
||||
.Pp
|
||||
The
|
||||
.Sq \ef
|
||||
attribute is forgotten when entering or exiting a macro block.
|
||||
.Ss Whitespace
|
||||
Whitespace consists of the space character.
|
||||
In free-form lines, whitespace is preserved within a line; unescaped
|
||||
trailing spaces are stripped from input (unless in a literal context).
|
||||
Blank free-form lines, which may include spaces, are permitted and
|
||||
rendered as an empty line.
|
||||
.Pp
|
||||
In macro lines, whitespace delimits arguments and is discarded.
|
||||
If arguments are quoted, whitespace within the quotes is retained.
|
||||
.Ss Dates
|
||||
The
|
||||
.Sx \&TH
|
||||
macro is the only
|
||||
.Nm
|
||||
macro that requires a date.
|
||||
The form for this date is the ISO-8601
|
||||
standard
|
||||
.Cm YYYY-MM-DD .
|
||||
.Ss Scaling Widths
|
||||
Many macros support scaled widths for their arguments, such as
|
||||
stipulating a two-inch paragraph indentation with the following:
|
||||
.Bd -literal -offset indent
|
||||
\&.HP 2i
|
||||
.Ed
|
||||
.Pp
|
||||
The syntax for scaled widths is
|
||||
.Sq Li [+-]?[0-9]*.[0-9]*[:unit:]? ,
|
||||
where a decimal must be preceded or proceeded by at least one digit.
|
||||
Negative numbers, while accepted, are truncated to zero.
|
||||
The following scaling units are accepted:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It c
|
||||
centimetre
|
||||
.It i
|
||||
inch
|
||||
.It P
|
||||
pica (~1/6 inch)
|
||||
.It p
|
||||
point (~1/72 inch)
|
||||
.It f
|
||||
synonym for
|
||||
.Sq u
|
||||
.It v
|
||||
default vertical span
|
||||
.It m
|
||||
width of rendered
|
||||
.Sq m
|
||||
.Pq em
|
||||
character
|
||||
.It n
|
||||
width of rendered
|
||||
.Sq n
|
||||
.Pq en
|
||||
character
|
||||
.It u
|
||||
default horizontal span
|
||||
.It M
|
||||
mini-em (~1/100 em)
|
||||
.El
|
||||
.Pp
|
||||
Using anything other than
|
||||
.Sq m ,
|
||||
.Sq n ,
|
||||
.Sq u ,
|
||||
or
|
||||
.Sq v
|
||||
is necessarily non-portable across output media.
|
||||
.Pp
|
||||
If a scaling unit is not provided, the numerical value is interpreted
|
||||
under the default rules of
|
||||
.Sq v
|
||||
for vertical spaces and
|
||||
.Sq u
|
||||
for horizontal ones.
|
||||
.Em Note :
|
||||
this differs from
|
||||
.Xr mdoc 7 ,
|
||||
which, if a unit is not provided, will instead interpret the string as
|
||||
literal text.
|
||||
.Ss Sentence Spacing
|
||||
When composing a manual, make sure that sentences end at the end of
|
||||
a line.
|
||||
By doing so, front-ends will be able to apply the proper amount of
|
||||
spacing after the end of sentence (unescaped) period, exclamation mark,
|
||||
or question mark followed by zero or more non-sentence closing
|
||||
delimiters
|
||||
.Po
|
||||
.Sq \&) ,
|
||||
.Sq \&] ,
|
||||
.Sq \&' ,
|
||||
.Sq \&"
|
||||
.Pc .
|
||||
.Em MACRO SYNTAX
|
||||
sections in the
|
||||
.Xr roff 7
|
||||
manual for details, in particular regarding
|
||||
comments, escape sequences, whitespace, and quoting.
|
||||
.Sh MANUAL STRUCTURE
|
||||
Each
|
||||
.Nm
|
||||
|
@ -213,42 +88,46 @@ appears as the first macro.
|
|||
.Pp
|
||||
Beyond
|
||||
.Sx \&TH ,
|
||||
at least one macro or text node must appear in the document.
|
||||
Documents are generally structured as follows:
|
||||
at least one macro or text line must appear in the document.
|
||||
.Pp
|
||||
The following is a well-formed skeleton
|
||||
.Nm
|
||||
file for a utility
|
||||
.Qq progname :
|
||||
.Bd -literal -offset indent
|
||||
\&.TH FOO 1 2009-10-10
|
||||
\&.TH PROGNAME 1 2009-10-10
|
||||
\&.SH NAME
|
||||
\efBfoo\efR \e(en a description goes here
|
||||
\&.\e\*q .SH LIBRARY
|
||||
\&.\e\*q For sections 2 & 3 only.
|
||||
\&.\e\*q Not used in OpenBSD.
|
||||
\efBprogname\efR \e(en a description goes here
|
||||
\&.\e\(dq .SH LIBRARY
|
||||
\&.\e\(dq For sections 2 & 3 only.
|
||||
\&.\e\(dq Not used in OpenBSD.
|
||||
\&.SH SYNOPSIS
|
||||
\efBfoo\efR [\efB\e-options\efR] arguments...
|
||||
\efBprogname\efR [\efB\e-options\efR] arguments...
|
||||
\&.SH DESCRIPTION
|
||||
The \efBfoo\efR utility processes files...
|
||||
\&.\e\*q .SH IMPLEMENTATION NOTES
|
||||
\&.\e\*q Not used in OpenBSD.
|
||||
\&.\e\*q .SH RETURN VALUES
|
||||
\&.\e\*q For sections 2, 3, & 9 only.
|
||||
\&.\e\*q .SH ENVIRONMENT
|
||||
\&.\e\*q For sections 1, 6, 7, & 8 only.
|
||||
\&.\e\*q .SH FILES
|
||||
\&.\e\*q .SH EXIT STATUS
|
||||
\&.\e\*q For sections 1, 6, & 8 only.
|
||||
\&.\e\*q .SH EXAMPLES
|
||||
\&.\e\*q .SH DIAGNOSTICS
|
||||
\&.\e\*q For sections 1, 4, 6, 7, & 8 only.
|
||||
\&.\e\*q .SH ERRORS
|
||||
\&.\e\*q For sections 2, 3, & 9 only.
|
||||
\&.\e\*q .SH SEE ALSO
|
||||
\&.\e\*q .BR foo ( 1 )
|
||||
\&.\e\*q .SH STANDARDS
|
||||
\&.\e\*q .SH HISTORY
|
||||
\&.\e\*q .SH AUTHORS
|
||||
\&.\e\*q .SH CAVEATS
|
||||
\&.\e\*q .SH BUGS
|
||||
\&.\e\*q .SH SECURITY CONSIDERATIONS
|
||||
\&.\e\*q Not used in OpenBSD.
|
||||
\&.\e\(dq .SH IMPLEMENTATION NOTES
|
||||
\&.\e\(dq Not used in OpenBSD.
|
||||
\&.\e\(dq .SH RETURN VALUES
|
||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
||||
\&.\e\(dq .SH ENVIRONMENT
|
||||
\&.\e\(dq For sections 1, 6, 7, & 8 only.
|
||||
\&.\e\(dq .SH FILES
|
||||
\&.\e\(dq .SH EXIT STATUS
|
||||
\&.\e\(dq For sections 1, 6, & 8 only.
|
||||
\&.\e\(dq .SH EXAMPLES
|
||||
\&.\e\(dq .SH DIAGNOSTICS
|
||||
\&.\e\(dq For sections 1, 4, 6, 7, & 8 only.
|
||||
\&.\e\(dq .SH ERRORS
|
||||
\&.\e\(dq For sections 2, 3, & 9 only.
|
||||
\&.\e\(dq .SH SEE ALSO
|
||||
\&.\e\(dq .BR foo ( 1 )
|
||||
\&.\e\(dq .SH STANDARDS
|
||||
\&.\e\(dq .SH HISTORY
|
||||
\&.\e\(dq .SH AUTHORS
|
||||
\&.\e\(dq .SH CAVEATS
|
||||
\&.\e\(dq .SH BUGS
|
||||
\&.\e\(dq .SH SECURITY CONSIDERATIONS
|
||||
\&.\e\(dq Not used in OpenBSD.
|
||||
.Ed
|
||||
.Pp
|
||||
The sections in a
|
||||
|
@ -354,146 +233,50 @@ in this section.
|
|||
.It Em SECURITY CONSIDERATIONS
|
||||
Documents any security precautions that operators should consider.
|
||||
.El
|
||||
.Sh MACRO SYNTAX
|
||||
Macros are one to three characters in length and begin with a
|
||||
control character,
|
||||
.Sq \&. ,
|
||||
at the beginning of the line.
|
||||
The
|
||||
.Sq \(aq
|
||||
macro control character is also accepted.
|
||||
An arbitrary amount of whitespace (spaces or tabs) may sit between the
|
||||
control character and the macro name.
|
||||
Thus, the following are equivalent:
|
||||
.Bd -literal -offset indent
|
||||
\&.PP
|
||||
\&.\ \ \ PP
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
macros are classified by scope: line scope or block scope.
|
||||
Line macros are only scoped to the current line (and, in some
|
||||
situations, the subsequent line).
|
||||
Block macros are scoped to the current line and subsequent lines until
|
||||
closed by another block macro.
|
||||
.Ss Line Macros
|
||||
Line macros are generally scoped to the current line, with the body
|
||||
consisting of zero or more arguments.
|
||||
If a macro is scoped to the next line and the line arguments are empty,
|
||||
the next line, which must be text, is used instead.
|
||||
Thus:
|
||||
.Bd -literal -offset indent
|
||||
\&.I
|
||||
foo
|
||||
.Ed
|
||||
.Pp
|
||||
is equivalent to
|
||||
.Sq \&.I foo .
|
||||
If next-line macros are invoked consecutively, only the last is used.
|
||||
If a next-line macro is followed by a non-next-line macro, an error is
|
||||
raised, except for
|
||||
.Sx \&br ,
|
||||
.Sx \&sp ,
|
||||
and
|
||||
.Sx \&na .
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.YO \(lBbody...\(rB
|
||||
\(lBbody...\(rB
|
||||
.Ed
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX"
|
||||
.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes
|
||||
.It Sx \&AT Ta <=1 Ta current Ta \&
|
||||
.It Sx \&B Ta n Ta next-line Ta \&
|
||||
.It Sx \&BI Ta n Ta current Ta \&
|
||||
.It Sx \&BR Ta n Ta current Ta \&
|
||||
.It Sx \&DT Ta 0 Ta current Ta \&
|
||||
.It Sx \&I Ta n Ta next-line Ta \&
|
||||
.It Sx \&IB Ta n Ta current Ta \&
|
||||
.It Sx \&IR Ta n Ta current Ta \&
|
||||
.It Sx \&R Ta n Ta next-line Ta \&
|
||||
.It Sx \&RB Ta n Ta current Ta \&
|
||||
.It Sx \&RI Ta n Ta current Ta \&
|
||||
.It Sx \&SB Ta n Ta next-line Ta \&
|
||||
.It Sx \&SM Ta n Ta next-line Ta \&
|
||||
.It Sx \&TH Ta >1, <6 Ta current Ta \&
|
||||
.It Sx \&UC Ta <=1 Ta current Ta \&
|
||||
.It Sx \&br Ta 0 Ta current Ta compat
|
||||
.It Sx \&fi Ta 0 Ta current Ta compat
|
||||
.It Sx \&ft Ta 1 Ta current Ta compat
|
||||
.It Sx \&in Ta 1 Ta current Ta compat
|
||||
.It Sx \&na Ta 0 Ta current Ta compat
|
||||
.It Sx \&nf Ta 0 Ta current Ta compat
|
||||
.It Sx \&sp Ta 1 Ta current Ta compat
|
||||
.Sh MACRO OVERVIEW
|
||||
This overview is sorted such that macros of similar purpose are listed
|
||||
together, to help find the best macro for any given purpose.
|
||||
Deprecated macros are not included in the overview, but can be found
|
||||
in the alphabetical reference below.
|
||||
.Ss Page header and footer meta-data
|
||||
.Bl -column "PP, LP, P" description
|
||||
.It Sx TH Ta set the title: Ar title section date Op Ar source Op Ar volume
|
||||
.It Sx AT Ta display AT&T UNIX version in the page footer (<= 1 argument)
|
||||
.It Sx UC Ta display BSD version in the page footer (<= 1 argument)
|
||||
.El
|
||||
.Pp
|
||||
Macros marked as
|
||||
.Qq compat
|
||||
are included for compatibility with the significant corpus of existing
|
||||
manuals that mix dialects of roff.
|
||||
These macros should not be used for portable
|
||||
.Nm
|
||||
manuals.
|
||||
.Ss Block Macros
|
||||
Block macros comprise a head and body.
|
||||
As with in-line macros, the head is scoped to the current line and, in
|
||||
one circumstance, the next line (the next-line stipulations as in
|
||||
.Sx Line Macros
|
||||
apply here as well).
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.YO \(lBhead...\(rB
|
||||
\(lBhead...\(rB
|
||||
\(lBbody...\(rB
|
||||
.Ed
|
||||
.Pp
|
||||
The closure of body scope may be to the section, where a macro is closed
|
||||
by
|
||||
.Sx \&SH ;
|
||||
sub-section, closed by a section or
|
||||
.Sx \&SS ;
|
||||
part, closed by a section, sub-section, or
|
||||
.Sx \&RE ;
|
||||
or paragraph, closed by a section, sub-section, part,
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
or
|
||||
.Sx \&TP .
|
||||
No closure refers to an explicit block closing macro.
|
||||
.Pp
|
||||
As a rule, block macros may not be nested; thus, calling a block macro
|
||||
while another block macro scope is open, and the open scope is not
|
||||
implicitly closed, is syntactically incorrect.
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX"
|
||||
.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
|
||||
.It Sx \&HP Ta <2 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&IP Ta <3 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&LP Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&P Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&PP Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&RE Ta 0 Ta current Ta none Ta compat
|
||||
.It Sx \&RS Ta 1 Ta current Ta part Ta compat
|
||||
.It Sx \&SH Ta >0 Ta next-line Ta section Ta \&
|
||||
.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \&
|
||||
.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \&
|
||||
.Ss Sections and paragraphs
|
||||
.Bl -column "PP, LP, P" description
|
||||
.It Sx SH Ta section header (one line)
|
||||
.It Sx SS Ta subsection header (one line)
|
||||
.It Sx PP , LP , P Ta start an undecorated paragraph (no arguments)
|
||||
.It Sx RS , RE Ta reset the left margin: Op Ar width
|
||||
.It Sx IP Ta indented paragraph: Op Ar head Op Ar width
|
||||
.It Sx TP Ta tagged paragraph: Op Ar width
|
||||
.It Sx HP Ta hanged paragraph: Op Ar width
|
||||
.It Sx \&br Ta force output line break in text mode (no arguments)
|
||||
.It Sx \&sp Ta force vertical space: Op Ar height
|
||||
.It Sx fi , nf Ta fill mode and no-fill mode (no arguments)
|
||||
.It Sx in Ta additional indent: Op Ar width
|
||||
.El
|
||||
.Pp
|
||||
Macros marked
|
||||
.Qq compat
|
||||
are as mentioned in
|
||||
.Sx Line Macros .
|
||||
.Pp
|
||||
If a block macro is next-line scoped, it may only be followed by in-line
|
||||
macros for decorating text.
|
||||
.Sh REFERENCE
|
||||
.Ss Physical markup
|
||||
.Bl -column "PP, LP, P" description
|
||||
.It Sx B Ta boldface font
|
||||
.It Sx I Ta italic font
|
||||
.It Sx R Ta roman (default) font
|
||||
.It Sx SB Ta small boldface font
|
||||
.It Sx SM Ta small roman font
|
||||
.It Sx BI Ta alternate between boldface and italic fonts
|
||||
.It Sx BR Ta alternate between boldface and roman fonts
|
||||
.It Sx IB Ta alternate between italic and boldface fonts
|
||||
.It Sx IR Ta alternate between italic and roman fonts
|
||||
.It Sx RB Ta alternate between roman and boldface fonts
|
||||
.It Sx RI Ta alternate between roman and italic fonts
|
||||
.El
|
||||
.Ss Semantic markup
|
||||
.Bl -column "PP, LP, P" description
|
||||
.It Sx OP Ta optional arguments
|
||||
.El
|
||||
.Sh MACRO REFERENCE
|
||||
This section is a canonical reference to all macros, arranged
|
||||
alphabetically.
|
||||
For the scoping of individual macros, see
|
||||
|
@ -658,6 +441,19 @@ See also
|
|||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&OP
|
||||
Optional command-line argument.
|
||||
This has the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&OP
|
||||
.Cm key Op Cm value
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Cm key
|
||||
is usually a command-line flag and
|
||||
.Cm value
|
||||
its argument.
|
||||
.Ss \&P
|
||||
Synonym for
|
||||
.Sx \&LP .
|
||||
|
@ -705,6 +501,9 @@ and
|
|||
.Ss \&RE
|
||||
Explicitly close out the scope of a prior
|
||||
.Sx \&RS .
|
||||
The default left margin is restored to the state of the original
|
||||
.Sx \&RS
|
||||
invocation.
|
||||
.Ss \&RI
|
||||
Text is rendered alternately in roman (the default font) and italics.
|
||||
Whitespace between arguments is omitted in output.
|
||||
|
@ -721,13 +520,10 @@ See also
|
|||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&RS
|
||||
Begin a part setting the left margin.
|
||||
The left margin controls the offset, following an initial indentation,
|
||||
to un-indented text such as that of
|
||||
.Sx \&PP .
|
||||
Temporarily reset the default left margin.
|
||||
This has the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&Rs
|
||||
.Pf \. Sx \&RS
|
||||
.Op Cm width
|
||||
.Ed
|
||||
.Pp
|
||||
|
@ -736,6 +532,9 @@ The
|
|||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
If not specified, the saved or default width is used.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&RE .
|
||||
.Ss \&SB
|
||||
Text is rendered in small size (one point smaller than the default font)
|
||||
bold face.
|
||||
|
@ -756,26 +555,27 @@ The paragraph left-margin width is reset to the default.
|
|||
Sets the title of the manual page with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&TH
|
||||
.Cm title section
|
||||
.Op Cm date Op Cm source Op Cm volume
|
||||
.Ar title section date
|
||||
.Op Ar source Op Ar volume
|
||||
.Ed
|
||||
.Pp
|
||||
At least the upper-case document
|
||||
.Cm title
|
||||
and the manual
|
||||
.Cm section
|
||||
arguments must be provided.
|
||||
The
|
||||
.Cm date
|
||||
argument should be formatted as described in
|
||||
.Sx Dates ,
|
||||
but will be printed verbatim if it is not.
|
||||
If the date is not specified, the current date is used.
|
||||
The
|
||||
.Cm source
|
||||
Conventionally, the document
|
||||
.Ar title
|
||||
is given in all caps.
|
||||
The recommended
|
||||
.Ar date
|
||||
format is
|
||||
.Sy YYYY-MM-DD
|
||||
as specified in the ISO-8601 standard;
|
||||
if the argument does not conform, it is printed verbatim.
|
||||
If the
|
||||
.Ar date
|
||||
is empty or not specified, the current date is used.
|
||||
The optional
|
||||
.Ar source
|
||||
string specifies the organisation providing the utility.
|
||||
The
|
||||
.Cm volume
|
||||
.Ar volume
|
||||
string replaces the default rendered volume, which is dictated by the
|
||||
manual section.
|
||||
.Pp
|
||||
|
@ -842,6 +642,10 @@ Begin literal mode: all subsequent free-form lines have their end of
|
|||
line boundaries preserved.
|
||||
May be ended by
|
||||
.Sx \&fi .
|
||||
Literal mode is implicitly ended by
|
||||
.Sx \&SH
|
||||
or
|
||||
.Sx \&SS .
|
||||
.Ss \&sp
|
||||
Insert vertical spaces into output with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
|
@ -860,6 +664,144 @@ Defaults to 1, if unspecified.
|
|||
.Pp
|
||||
See also
|
||||
.Sx \&br .
|
||||
.Sh MACRO SYNTAX
|
||||
The
|
||||
.Nm
|
||||
macros are classified by scope: line scope or block scope.
|
||||
Line macros are only scoped to the current line (and, in some
|
||||
situations, the subsequent line).
|
||||
Block macros are scoped to the current line and subsequent lines until
|
||||
closed by another block macro.
|
||||
.Ss Line Macros
|
||||
Line macros are generally scoped to the current line, with the body
|
||||
consisting of zero or more arguments.
|
||||
If a macro is scoped to the next line and the line arguments are empty,
|
||||
the next line, which must be text, is used instead.
|
||||
Thus:
|
||||
.Bd -literal -offset indent
|
||||
\&.I
|
||||
foo
|
||||
.Ed
|
||||
.Pp
|
||||
is equivalent to
|
||||
.Sq \&.I foo .
|
||||
If next-line macros are invoked consecutively, only the last is used.
|
||||
If a next-line macro is followed by a non-next-line macro, an error is
|
||||
raised, except for
|
||||
.Sx \&br ,
|
||||
.Sx \&sp ,
|
||||
and
|
||||
.Sx \&na .
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.YO \(lBbody...\(rB
|
||||
\(lBbody...\(rB
|
||||
.Ed
|
||||
.Bl -column "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX" -offset indent
|
||||
.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes
|
||||
.It Sx \&AT Ta <=1 Ta current Ta \&
|
||||
.It Sx \&B Ta n Ta next-line Ta \&
|
||||
.It Sx \&BI Ta n Ta current Ta \&
|
||||
.It Sx \&BR Ta n Ta current Ta \&
|
||||
.It Sx \&DT Ta 0 Ta current Ta \&
|
||||
.It Sx \&I Ta n Ta next-line Ta \&
|
||||
.It Sx \&IB Ta n Ta current Ta \&
|
||||
.It Sx \&IR Ta n Ta current Ta \&
|
||||
.It Sx \&OP Ta 0, 1 Ta current Ta compat
|
||||
.It Sx \&R Ta n Ta next-line Ta \&
|
||||
.It Sx \&RB Ta n Ta current Ta \&
|
||||
.It Sx \&RI Ta n Ta current Ta \&
|
||||
.It Sx \&SB Ta n Ta next-line Ta \&
|
||||
.It Sx \&SM Ta n Ta next-line Ta \&
|
||||
.It Sx \&TH Ta >1, <6 Ta current Ta \&
|
||||
.It Sx \&UC Ta <=1 Ta current Ta \&
|
||||
.It Sx \&br Ta 0 Ta current Ta compat
|
||||
.It Sx \&fi Ta 0 Ta current Ta compat
|
||||
.It Sx \&ft Ta 1 Ta current Ta compat
|
||||
.It Sx \&in Ta 1 Ta current Ta compat
|
||||
.It Sx \&na Ta 0 Ta current Ta compat
|
||||
.It Sx \&nf Ta 0 Ta current Ta compat
|
||||
.It Sx \&sp Ta 1 Ta current Ta compat
|
||||
.El
|
||||
.Pp
|
||||
Macros marked as
|
||||
.Qq compat
|
||||
are included for compatibility with the significant corpus of existing
|
||||
manuals that mix dialects of roff.
|
||||
These macros should not be used for portable
|
||||
.Nm
|
||||
manuals.
|
||||
.Ss Block Macros
|
||||
Block macros comprise a head and body.
|
||||
As with in-line macros, the head is scoped to the current line and, in
|
||||
one circumstance, the next line (the next-line stipulations as in
|
||||
.Sx Line Macros
|
||||
apply here as well).
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.YO \(lBhead...\(rB
|
||||
\(lBhead...\(rB
|
||||
\(lBbody...\(rB
|
||||
.Ed
|
||||
.Pp
|
||||
The closure of body scope may be to the section, where a macro is closed
|
||||
by
|
||||
.Sx \&SH ;
|
||||
sub-section, closed by a section or
|
||||
.Sx \&SS ;
|
||||
part, closed by a section, sub-section, or
|
||||
.Sx \&RE ;
|
||||
or paragraph, closed by a section, sub-section, part,
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
or
|
||||
.Sx \&TP .
|
||||
No closure refers to an explicit block closing macro.
|
||||
.Pp
|
||||
As a rule, block macros may not be nested; thus, calling a block macro
|
||||
while another block macro scope is open, and the open scope is not
|
||||
implicitly closed, is syntactically incorrect.
|
||||
.Bl -column "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX" -offset indent
|
||||
.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
|
||||
.It Sx \&HP Ta <2 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&IP Ta <3 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&LP Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&P Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&PP Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&RE Ta 0 Ta current Ta none Ta compat
|
||||
.It Sx \&RS Ta 1 Ta current Ta part Ta compat
|
||||
.It Sx \&SH Ta >0 Ta next-line Ta section Ta \&
|
||||
.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \&
|
||||
.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \&
|
||||
.El
|
||||
.Pp
|
||||
Macros marked
|
||||
.Qq compat
|
||||
are as mentioned in
|
||||
.Sx Line Macros .
|
||||
.Pp
|
||||
If a block macro is next-line scoped, it may only be followed by in-line
|
||||
macros for decorating text.
|
||||
.Ss Font handling
|
||||
In
|
||||
.Nm
|
||||
documents, both
|
||||
.Sx Physical markup
|
||||
macros and
|
||||
.Xr roff 7
|
||||
.Ql \ef
|
||||
font escape sequences can be used to choose fonts.
|
||||
In text lines, the effect of manual font selection by escape sequences
|
||||
only lasts until the next macro invocation; in macro lines, it only lasts
|
||||
until the end of the macro scope.
|
||||
Note that macros like
|
||||
.Sx \&BR
|
||||
open and close a font scope for each argument.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents areas of questionable portability between
|
||||
implementations of the
|
||||
|
@ -868,6 +810,14 @@ language.
|
|||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
Do not depend on
|
||||
.Sx \&SH
|
||||
or
|
||||
.Sx \&SS
|
||||
to close out a literal context opened with
|
||||
.Sx \&nf .
|
||||
This behaviour may not be portable.
|
||||
.It
|
||||
In quoted literals, GNU troff allowed pair-wise double-quotes to produce
|
||||
a standalone double-quote in formatted output.
|
||||
It is not known whether this behaviour is exhibited by other formatters.
|
||||
|
@ -908,10 +858,30 @@ The
|
|||
.Sx \&sp
|
||||
macro does not accept negative values in mandoc.
|
||||
In GNU troff, this would result in strange behaviour.
|
||||
.It
|
||||
In page header lines, GNU troff versions up to and including 1.21
|
||||
only print
|
||||
.Ar volume
|
||||
names explicitly specified in the
|
||||
.Sx \&TH
|
||||
macro; mandoc and newer groff print the default volume name
|
||||
corresponding to the
|
||||
.Ar section
|
||||
number when no
|
||||
.Ar volume
|
||||
is given, like in
|
||||
.Xr mdoc 7 .
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Sx OP
|
||||
macro is part of the extended
|
||||
.Nm
|
||||
macro set, and may not be portable to non-GNU troff implementations.
|
||||
.Sh SEE ALSO
|
||||
.Xr man 1 ,
|
||||
.Xr mandoc 1 ,
|
||||
.Xr eqn 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7 ,
|
||||
|
@ -923,6 +893,9 @@ language first appeared as a macro package for the roff typesetting
|
|||
system in
|
||||
.At v7 .
|
||||
It was later rewritten by James Clark as a macro package for groff.
|
||||
Eric S. Raymond wrote the extended
|
||||
.Nm
|
||||
macros for groff in 2007.
|
||||
The stand-alone implementation that is part of the
|
||||
.Xr mandoc 1
|
||||
utility written by Kristaps Dzonsons appeared in
|
||||
|
@ -931,7 +904,8 @@ utility written by Kristaps Dzonsons appeared in
|
|||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
Do not use this language.
|
||||
Use
|
||||
|
|
240
external/bsd/mdocml/dist/man.c
vendored
240
external/bsd/mdocml/dist/man.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: man.c,v 1.96 2011/01/03 11:31:26 kristaps Exp $ */
|
||||
/* $Vendor-Id: man.c,v 1.115 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -26,6 +26,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "man.h"
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
#include "libmandoc.h"
|
||||
|
@ -39,17 +40,15 @@ const char *const __man_macronames[MAN_MAX] = {
|
|||
"RI", "na", "sp", "nf",
|
||||
"fi", "RE", "RS", "DT",
|
||||
"UC", "PD", "AT", "in",
|
||||
"ft"
|
||||
"ft", "OP"
|
||||
};
|
||||
|
||||
const char * const *man_macronames = __man_macronames;
|
||||
|
||||
static struct man_node *man_node_alloc(int, int,
|
||||
static struct man_node *man_node_alloc(struct man *, int, int,
|
||||
enum man_type, enum mant);
|
||||
static int man_node_append(struct man *,
|
||||
struct man_node *);
|
||||
static int man_span_alloc(struct man *,
|
||||
const struct tbl_span *);
|
||||
static void man_node_free(struct man_node *);
|
||||
static void man_node_unlink(struct man *,
|
||||
struct man_node *);
|
||||
|
@ -97,16 +96,15 @@ man_free(struct man *man)
|
|||
|
||||
|
||||
struct man *
|
||||
man_alloc(struct regset *regs, void *data, mandocmsg msg)
|
||||
man_alloc(struct roff *roff, struct mparse *parse)
|
||||
{
|
||||
struct man *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct man));
|
||||
|
||||
man_hash_init();
|
||||
p->data = data;
|
||||
p->msg = msg;
|
||||
p->regs = regs;
|
||||
p->parse = parse;
|
||||
p->roff = roff;
|
||||
|
||||
man_alloc1(p);
|
||||
return(p);
|
||||
|
@ -129,8 +127,11 @@ int
|
|||
man_parseln(struct man *m, int ln, char *buf, int offs)
|
||||
{
|
||||
|
||||
m->flags |= MAN_NEWLINE;
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
return(('.' == buf[offs] || '\'' == buf[offs]) ?
|
||||
|
||||
return (mandoc_getcontrol(buf, &offs) ?
|
||||
man_pmacro(m, ln, buf, offs) :
|
||||
man_ptext(m, ln, buf, offs));
|
||||
}
|
||||
|
@ -146,8 +147,8 @@ man_free1(struct man *man)
|
|||
free(man->meta.title);
|
||||
if (man->meta.source)
|
||||
free(man->meta.source);
|
||||
if (man->meta.rawdate)
|
||||
free(man->meta.rawdate);
|
||||
if (man->meta.date)
|
||||
free(man->meta.date);
|
||||
if (man->meta.vol)
|
||||
free(man->meta.vol);
|
||||
if (man->meta.msec)
|
||||
|
@ -203,6 +204,10 @@ man_node_append(struct man *man, struct man_node *p)
|
|||
assert(MAN_BLOCK == p->parent->type);
|
||||
p->parent->head = p;
|
||||
break;
|
||||
case (MAN_TAIL):
|
||||
assert(MAN_BLOCK == p->parent->type);
|
||||
p->parent->tail = p;
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
assert(MAN_BLOCK == p->parent->type);
|
||||
p->parent->body = p;
|
||||
|
@ -229,7 +234,8 @@ man_node_append(struct man *man, struct man_node *p)
|
|||
|
||||
|
||||
static struct man_node *
|
||||
man_node_alloc(int line, int pos, enum man_type type, enum mant tok)
|
||||
man_node_alloc(struct man *m, int line, int pos,
|
||||
enum man_type type, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
|
@ -238,6 +244,10 @@ man_node_alloc(int line, int pos, enum man_type type, enum mant tok)
|
|||
p->pos = pos;
|
||||
p->type = type;
|
||||
p->tok = tok;
|
||||
|
||||
if (MAN_NEWLINE & m->flags)
|
||||
p->flags |= MAN_LINE;
|
||||
m->flags &= ~MAN_NEWLINE;
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
@ -247,7 +257,20 @@ man_elem_alloc(struct man *m, int line, int pos, enum mant tok)
|
|||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_ELEM, tok);
|
||||
p = man_node_alloc(m, line, pos, MAN_ELEM, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_tail_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(m, line, pos, MAN_TAIL, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
|
@ -260,7 +283,7 @@ man_head_alloc(struct man *m, int line, int pos, enum mant tok)
|
|||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_HEAD, tok);
|
||||
p = man_node_alloc(m, line, pos, MAN_HEAD, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
|
@ -273,7 +296,7 @@ man_body_alloc(struct man *m, int line, int pos, enum mant tok)
|
|||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_BODY, tok);
|
||||
p = man_node_alloc(m, line, pos, MAN_BODY, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
|
@ -286,43 +309,20 @@ man_block_alloc(struct man *m, int line, int pos, enum mant tok)
|
|||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_BLOCK, tok);
|
||||
p = man_node_alloc(m, line, pos, MAN_BLOCK, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
man_span_alloc(struct man *m, const struct tbl_span *span)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
/* FIXME: grab from span */
|
||||
n = man_node_alloc(0, 0, MAN_TBL, MAN_MAX);
|
||||
n->span = span;
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
man_word_alloc(struct man *m, int line, int pos, const char *word)
|
||||
{
|
||||
struct man_node *n;
|
||||
size_t sv, len;
|
||||
|
||||
len = strlen(word);
|
||||
|
||||
n = man_node_alloc(line, pos, MAN_TEXT, MAN_MAX);
|
||||
n->string = mandoc_malloc(len + 1);
|
||||
sv = strlcpy(n->string, word, len + 1);
|
||||
|
||||
/* Prohibit truncation. */
|
||||
assert(sv < len + 1);
|
||||
n = man_node_alloc(m, line, pos, MAN_TEXT, MAN_MAX);
|
||||
n->string = roff_strdup(m->roff, word);
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
return(0);
|
||||
|
@ -357,15 +357,38 @@ man_node_delete(struct man *m, struct man_node *p)
|
|||
man_node_free(p);
|
||||
}
|
||||
|
||||
int
|
||||
man_addeqn(struct man *m, const struct eqn *ep)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
|
||||
n = man_node_alloc(m, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
|
||||
n->eqn = ep;
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(man_descope(m, ep->ln, ep->pos));
|
||||
}
|
||||
|
||||
int
|
||||
man_addspan(struct man *m, const struct tbl_span *sp)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
if ( ! man_span_alloc(m, sp))
|
||||
|
||||
n = man_node_alloc(m, sp->line, 0, MAN_TBL, MAN_MAX);
|
||||
n->span = sp;
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
return(0);
|
||||
return(man_descope(m, 0, 0));
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(man_descope(m, sp->line, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -392,21 +415,11 @@ man_descope(struct man *m, int line, int offs)
|
|||
return(man_body_alloc(m, line, offs, m->last->tok));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
man_ptext(struct man *m, int line, char *buf, int offs)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Ignore bogus comments. */
|
||||
|
||||
if ('\\' == buf[offs] &&
|
||||
'.' == buf[offs + 1] &&
|
||||
'"' == buf[offs + 2]) {
|
||||
man_pmsg(m, line, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Literal free-form text whitespace is preserved. */
|
||||
|
||||
if (MAN_LITERAL & m->flags) {
|
||||
|
@ -464,67 +477,54 @@ man_ptext(struct man *m, int line, char *buf, int offs)
|
|||
return(man_descope(m, line, offs));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
{
|
||||
int i, j, ppos;
|
||||
int i, ppos;
|
||||
enum mant tok;
|
||||
char mac[5];
|
||||
struct man_node *n;
|
||||
|
||||
/* Comments and empties are quickly ignored. */
|
||||
|
||||
offs++;
|
||||
|
||||
if ('\0' == buf[offs])
|
||||
if ('"' == buf[offs]) {
|
||||
man_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
} else if ('\0' == buf[offs])
|
||||
return(1);
|
||||
|
||||
i = offs;
|
||||
|
||||
/*
|
||||
* Skip whitespace between the control character and initial
|
||||
* text. "Whitespace" is both spaces and tabs.
|
||||
*/
|
||||
|
||||
if (' ' == buf[i] || '\t' == buf[i]) {
|
||||
i++;
|
||||
while (buf[i] && (' ' == buf[i] || '\t' == buf[i]))
|
||||
i++;
|
||||
if ('\0' == buf[i])
|
||||
goto out;
|
||||
}
|
||||
|
||||
ppos = i;
|
||||
ppos = offs;
|
||||
|
||||
/*
|
||||
* Copy the first word into a nil-terminated buffer.
|
||||
* Stop copying when a tab, space, or eoln is encountered.
|
||||
*/
|
||||
|
||||
j = 0;
|
||||
while (j < 4 && '\0' != buf[i] && ' ' != buf[i] && '\t' != buf[i])
|
||||
mac[j++] = buf[i++];
|
||||
mac[j] = '\0';
|
||||
i = 0;
|
||||
while (i < 4 && '\0' != buf[offs] &&
|
||||
' ' != buf[offs] && '\t' != buf[offs])
|
||||
mac[i++] = buf[offs++];
|
||||
|
||||
mac[i] = '\0';
|
||||
|
||||
tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
|
||||
|
||||
tok = (j > 0 && j < 4) ? man_hash_find(mac) : MAN_MAX;
|
||||
if (MAN_MAX == tok) {
|
||||
man_vmsg(m, MANDOCERR_MACRO, ln, ppos, "%s", buf + ppos - 1);
|
||||
mandoc_vmsg(MANDOCERR_MACRO, m->parse, ln,
|
||||
ppos, "%s", buf + ppos - 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* The macro is sane. Jump to the next word. */
|
||||
|
||||
while (buf[i] && ' ' == buf[i])
|
||||
i++;
|
||||
while (buf[offs] && ' ' == buf[offs])
|
||||
offs++;
|
||||
|
||||
/*
|
||||
* Trailing whitespace. Note that tabs are allowed to be passed
|
||||
* into the parser as "text", so we only warn about spaces here.
|
||||
*/
|
||||
|
||||
if ('\0' == buf[i] && ' ' == buf[i - 1])
|
||||
man_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE);
|
||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||
man_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
/*
|
||||
* Remove prior ELINE macro, as it's being clobbered by a new
|
||||
|
@ -542,13 +542,45 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
|||
if (MAN_NSCOPED & man_macros[n->tok].flags)
|
||||
n = n->parent;
|
||||
|
||||
man_vmsg(m, MANDOCERR_LINESCOPE, n->line, n->pos,
|
||||
"%s", man_macronames[n->tok]);
|
||||
mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line,
|
||||
n->pos, "%s breaks %s", man_macronames[tok],
|
||||
man_macronames[n->tok]);
|
||||
|
||||
man_node_delete(m, n);
|
||||
m->flags &= ~MAN_ELINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove prior BLINE macro that is being clobbered.
|
||||
*/
|
||||
if ((m->flags & MAN_BLINE) &&
|
||||
(MAN_BSCOPE & man_macros[tok].flags)) {
|
||||
n = m->last;
|
||||
|
||||
/* Might be a text node like 8 in
|
||||
* .TP 8
|
||||
* .SH foo
|
||||
*/
|
||||
if (MAN_TEXT == n->type)
|
||||
n = n->parent;
|
||||
|
||||
/* Remove element that didn't end BLINE, if any. */
|
||||
if ( ! (MAN_BSCOPE & man_macros[n->tok].flags))
|
||||
n = n->parent;
|
||||
|
||||
assert(MAN_HEAD == n->type);
|
||||
n = n->parent;
|
||||
assert(MAN_BLOCK == n->type);
|
||||
assert(MAN_SCOPED & man_macros[n->tok].flags);
|
||||
|
||||
mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line,
|
||||
n->pos, "%s breaks %s", man_macronames[tok],
|
||||
man_macronames[n->tok]);
|
||||
|
||||
man_node_delete(m, n);
|
||||
m->flags &= ~MAN_BLINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the fact that we're in the next-line for a block. In
|
||||
* this way, embedded roff instructions can "remember" state
|
||||
|
@ -561,10 +593,9 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
|||
/* Call to handler... */
|
||||
|
||||
assert(man_macros[tok].fp);
|
||||
if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &i, buf))
|
||||
if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &offs, buf))
|
||||
goto err;
|
||||
|
||||
out:
|
||||
/*
|
||||
* We weren't in a block-line scope when entering the
|
||||
* above-parsed macro, so return.
|
||||
|
@ -601,7 +632,7 @@ out:
|
|||
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
return(man_body_alloc(m, ln, offs, m->last->tok));
|
||||
return(man_body_alloc(m, ln, ppos, m->last->tok));
|
||||
|
||||
err: /* Error out. */
|
||||
|
||||
|
@ -609,21 +640,6 @@ err: /* Error out. */
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_vmsg(struct man *man, enum mandocerr t,
|
||||
int ln, int pos, const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
return((*man->msg)(t, man->data, ln, pos, buf));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unlink a node from its context. If "m" is provided, the last parse
|
||||
* point will also be adjusted accordingly.
|
||||
|
@ -664,3 +680,11 @@ man_node_unlink(struct man *m, struct man_node *n)
|
|||
if (m && m->first == n)
|
||||
m->first = NULL;
|
||||
}
|
||||
|
||||
const struct mparse *
|
||||
man_mparse(const struct man *m)
|
||||
{
|
||||
|
||||
assert(m && m->parse);
|
||||
return(m->parse);
|
||||
}
|
||||
|
|
123
external/bsd/mdocml/dist/man.cgi.7
vendored
Normal file
123
external/bsd/mdocml/dist/man.cgi.7
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
.Dd December 15, 2011
|
||||
.Dt MAN.CGI 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm man.cgi
|
||||
.Nd cgi for manpage query and display
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
script queries and displays manual pages.
|
||||
It interfaces with
|
||||
.Xr mandocdb 8
|
||||
databases cached with
|
||||
.Xr catman 8 .
|
||||
.Pp
|
||||
To use
|
||||
.Nm ,
|
||||
create a manual cache in
|
||||
.Xr catman 8 .
|
||||
Assign this directory to the environment variable
|
||||
.Ev CACHE_DIR ,
|
||||
defaulting to
|
||||
.Pa /cache/man.cgi .
|
||||
Copy the
|
||||
.Pa man.cgi
|
||||
script into your CGI directory (see
|
||||
.Sx FILES
|
||||
for other relevant files).
|
||||
.Pp
|
||||
Multiple
|
||||
.Xr catman 8
|
||||
trees may be managed by
|
||||
.Nm :
|
||||
directories under
|
||||
.Ev CACHE_DIR
|
||||
containing
|
||||
.Pa etc/catman.conf
|
||||
are identified as
|
||||
.Qq manroots .
|
||||
The path of a manroot under
|
||||
.Ev CACHE_DIR
|
||||
is converted to a name by replacing path separators with spaces.
|
||||
.Pp
|
||||
Thus, if
|
||||
.Ev CACHE_DIR
|
||||
is the default
|
||||
.Pa /cache/man.cgi ,
|
||||
the web-server is jailed to
|
||||
.Pa /var/www ,
|
||||
and cache subdirectories
|
||||
.Pa ./foo/1
|
||||
and
|
||||
.Pa ./bar/2
|
||||
contain
|
||||
.Pa etc/catman.conf ,
|
||||
.Nm
|
||||
will assign these to manroots
|
||||
.Qq foo 1
|
||||
and
|
||||
.Qq bar 2 ,
|
||||
respectively.
|
||||
These names will appear as choices when searching for manuals.
|
||||
.Pp
|
||||
If
|
||||
.Nm
|
||||
finds only one manroot, or none, then the selection box is omitted.
|
||||
If no manroot is specified during search, the first manroot is used by
|
||||
default.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width Ds
|
||||
.It Ev CACHE_DIR
|
||||
The absolute path of the
|
||||
.Xr catman 8
|
||||
cache directory.
|
||||
This must not have a trailing slash.
|
||||
.It Ev CSS_DIR
|
||||
Prepended to CSS file links in outputted HTML files.
|
||||
This must not have a trailing slash.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa etc/catman.conf
|
||||
Built by
|
||||
.Xr catman 8
|
||||
and must exist at least once under the configuration directory root.
|
||||
.It Pa man.css
|
||||
Should be visible in the server document root or within
|
||||
.Ev CSS_DIR .
|
||||
Included in each page after
|
||||
.Pa man-cgi.css ,
|
||||
ostensibly for
|
||||
.Xr mandoc 1
|
||||
HTML output styling.
|
||||
.It Pa man.cgi.css
|
||||
Should be visible in the server document root or within
|
||||
.Ev CSS_DIR .
|
||||
Included in each page, ostensibly for general
|
||||
.Nm
|
||||
styling.
|
||||
.El
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Nm
|
||||
script is call-compatible with queries from the traditional
|
||||
.Pa man.cgi
|
||||
script by Wolfram Schneider.
|
||||
However, the results may not be quite the same.
|
||||
.Sh SEE ALSO
|
||||
.Xr catman 8 ,
|
||||
.Xr mandocdb 8
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
If you're running in a jailed web-server, make sure the
|
||||
.Pa /tmp
|
||||
directory exists and is writable.
|
||||
The databases may need this for scratch space.
|
41
external/bsd/mdocml/dist/man.h
vendored
41
external/bsd/mdocml/dist/man.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: man.h,v 1.50 2011/01/01 12:59:17 kristaps Exp $ */
|
||||
/* $Vendor-Id: man.h,v 1.60 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,9 +17,6 @@
|
|||
#ifndef MAN_H
|
||||
#define MAN_H
|
||||
|
||||
/*
|
||||
* What follows is a list of ALL possible macros.
|
||||
*/
|
||||
enum mant {
|
||||
MAN_br = 0,
|
||||
MAN_TH,
|
||||
|
@ -54,12 +51,10 @@ enum mant {
|
|||
MAN_AT,
|
||||
MAN_in,
|
||||
MAN_ft,
|
||||
MAN_OP,
|
||||
MAN_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of a syntax node.
|
||||
*/
|
||||
enum man_type {
|
||||
MAN_TEXT,
|
||||
MAN_ELEM,
|
||||
|
@ -67,24 +62,19 @@ enum man_type {
|
|||
MAN_BLOCK,
|
||||
MAN_HEAD,
|
||||
MAN_BODY,
|
||||
MAN_TBL
|
||||
MAN_TAIL,
|
||||
MAN_TBL,
|
||||
MAN_EQN
|
||||
};
|
||||
|
||||
/*
|
||||
* Information from prologue.
|
||||
*/
|
||||
struct man_meta {
|
||||
char *msec; /* `TH' section (1, 3p, etc.) */
|
||||
time_t date; /* `TH' normalised date */
|
||||
char *rawdate; /* raw `TH' date */
|
||||
char *date; /* `TH' normalised date */
|
||||
char *vol; /* `TH' volume */
|
||||
char *title; /* `TH' title (e.g., FOO) */
|
||||
char *source; /* `TH' source (e.g., GNU) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Single node in tree-linked AST.
|
||||
*/
|
||||
struct man_node {
|
||||
struct man_node *parent; /* parent AST node */
|
||||
struct man_node *child; /* first child AST node */
|
||||
|
@ -97,33 +87,26 @@ struct man_node {
|
|||
int flags;
|
||||
#define MAN_VALID (1 << 0) /* has been validated */
|
||||
#define MAN_EOS (1 << 2) /* at sentence boundary */
|
||||
#define MAN_LINE (1 << 3) /* first macro/text on line */
|
||||
enum man_type type; /* AST node type */
|
||||
char *string; /* TEXT node argument */
|
||||
struct man_node *head; /* BLOCK node HEAD ptr */
|
||||
struct man_node *tail; /* BLOCK node TAIL ptr */
|
||||
struct man_node *body; /* BLOCK node BODY ptr */
|
||||
const struct tbl_span *span; /* TBL */
|
||||
const struct eqn *eqn; /* EQN */
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of macros. Index is enum mant. Indexing into this returns
|
||||
* the normalised name, e.g., man_macronames[MAN_SH] -> "SH".
|
||||
*/
|
||||
/* Names of macros. Index is enum mant. */
|
||||
extern const char *const *man_macronames;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct man;
|
||||
|
||||
void man_free(struct man *);
|
||||
struct man *man_alloc(struct regset *, void *, mandocmsg);
|
||||
void man_reset(struct man *);
|
||||
int man_parseln(struct man *, int, char *, int);
|
||||
int man_endparse(struct man *);
|
||||
int man_addspan(struct man *,
|
||||
const struct tbl_span *);
|
||||
|
||||
const struct man_node *man_node(const struct man *);
|
||||
const struct man_meta *man_meta(const struct man *);
|
||||
const struct mparse *man_mparse(const struct man *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
13
external/bsd/mdocml/dist/man_hash.c
vendored
13
external/bsd/mdocml/dist/man_hash.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: man_hash.c,v 1.23 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/* $Vendor-Id: man_hash.c,v 1.25 2011/07/24 18:15:14 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -26,13 +26,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "man.h"
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
|
||||
#define HASH_DEPTH 6
|
||||
|
||||
#define HASH_ROW(x) do { \
|
||||
if (isupper((u_char)(x))) \
|
||||
if (isupper((unsigned char)(x))) \
|
||||
(x) -= 65; \
|
||||
else \
|
||||
(x) -= 97; \
|
||||
|
@ -46,7 +47,7 @@
|
|||
* macro (the integer value of the enum stored as a char to save a bit
|
||||
* of space).
|
||||
*/
|
||||
static u_char table[26 * HASH_DEPTH];
|
||||
static unsigned char table[26 * HASH_DEPTH];
|
||||
|
||||
/*
|
||||
* XXX - this hash has global scope, so if intended for use as a library
|
||||
|
@ -65,13 +66,13 @@ man_hash_init(void)
|
|||
for (i = 0; i < (int)MAN_MAX; i++) {
|
||||
x = man_macronames[i][0];
|
||||
|
||||
assert(isalpha((u_char)x));
|
||||
assert(isalpha((unsigned char)x));
|
||||
|
||||
HASH_ROW(x);
|
||||
|
||||
for (j = 0; j < HASH_DEPTH; j++)
|
||||
if (UCHAR_MAX == table[x + j]) {
|
||||
table[x + j] = (u_char)i;
|
||||
table[x + j] = (unsigned char)i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -88,7 +89,7 @@ man_hash_find(const char *tmp)
|
|||
|
||||
if ('\0' == (x = tmp[0]))
|
||||
return(MAN_MAX);
|
||||
if ( ! (isalpha((u_char)x)))
|
||||
if ( ! (isalpha((unsigned char)x)))
|
||||
return(MAN_MAX);
|
||||
|
||||
HASH_ROW(x);
|
||||
|
|
334
external/bsd/mdocml/dist/man_html.c
vendored
334
external/bsd/mdocml/dist/man_html.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: man_html.c,v 1.62 2011/01/07 13:20:58 kristaps Exp $ */
|
||||
/* $Vendor-Id: man_html.c,v 1.86 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -36,7 +36,6 @@
|
|||
/* FIXME: have PD set the default vspace width. */
|
||||
|
||||
#define INDENT 5
|
||||
#define HALFINDENT 3
|
||||
|
||||
#define MAN_ARGS const struct man_meta *m, \
|
||||
const struct man_node *n, \
|
||||
|
@ -53,30 +52,31 @@ struct htmlman {
|
|||
int (*post)(MAN_ARGS);
|
||||
};
|
||||
|
||||
static void print_bvspace(struct html *,
|
||||
const struct man_node *);
|
||||
static void print_man(MAN_ARGS);
|
||||
static void print_man_head(MAN_ARGS);
|
||||
static void print_man_nodelist(MAN_ARGS);
|
||||
static void print_man_node(MAN_ARGS);
|
||||
|
||||
static int a2width(const struct man_node *,
|
||||
struct roffsu *);
|
||||
|
||||
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);
|
||||
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_alt_pre(MAN_ARGS);
|
||||
static int man_br_pre(MAN_ARGS);
|
||||
static int man_ign_pre(MAN_ARGS);
|
||||
static int man_in_pre(MAN_ARGS);
|
||||
static int man_literal_pre(MAN_ARGS);
|
||||
static void man_root_post(MAN_ARGS);
|
||||
static int man_root_pre(MAN_ARGS);
|
||||
static int man_B_pre(MAN_ARGS);
|
||||
static int man_HP_pre(MAN_ARGS);
|
||||
static int man_I_pre(MAN_ARGS);
|
||||
static int man_IP_pre(MAN_ARGS);
|
||||
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 void man_root_pre(MAN_ARGS);
|
||||
|
||||
static const struct htmlman mans[MAN_MAX] = {
|
||||
{ man_br_pre, NULL }, /* br */
|
||||
|
@ -100,7 +100,7 @@ static const struct htmlman mans[MAN_MAX] = {
|
|||
{ man_I_pre, NULL }, /* I */
|
||||
{ man_alt_pre, NULL }, /* IR */
|
||||
{ man_alt_pre, NULL }, /* RI */
|
||||
{ NULL, NULL }, /* na */
|
||||
{ man_ign_pre, NULL }, /* na */
|
||||
{ man_br_pre, NULL }, /* sp */
|
||||
{ man_literal_pre, NULL }, /* nf */
|
||||
{ man_literal_pre, NULL }, /* fi */
|
||||
|
@ -112,40 +112,61 @@ static const struct htmlman mans[MAN_MAX] = {
|
|||
{ man_ign_pre, NULL }, /* AT */
|
||||
{ man_in_pre, NULL }, /* in */
|
||||
{ man_ign_pre, NULL }, /* ft */
|
||||
{ man_OP_pre, NULL }, /* OP */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 man_node *n)
|
||||
{
|
||||
|
||||
if (n->body && n->body->child)
|
||||
if (MAN_TBL == n->body->child->type)
|
||||
return;
|
||||
|
||||
if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
|
||||
if (NULL == n->prev)
|
||||
return;
|
||||
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
html_man(void *arg, const struct man *m)
|
||||
{
|
||||
struct html *h;
|
||||
struct tag *t;
|
||||
struct mhtml mh;
|
||||
|
||||
h = (struct html *)arg;
|
||||
|
||||
print_gen_decls(h);
|
||||
|
||||
memset(&mh, 0, sizeof(struct mhtml));
|
||||
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
print_man(man_meta(m), man_node(m), &mh, h);
|
||||
print_tagq(h, t);
|
||||
|
||||
printf("\n");
|
||||
print_man(man_meta(m), man_node(m), &mh, (struct html *)arg);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_man(MAN_ARGS)
|
||||
{
|
||||
struct tag *t;
|
||||
struct tag *t, *tt;
|
||||
struct htmlpair tag;
|
||||
|
||||
t = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
PAIR_CLASS_INIT(&tag, "mandoc");
|
||||
|
||||
if ( ! (HTML_FRAGMENT & h->oflags)) {
|
||||
print_gen_decls(h);
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
tt = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
print_man_head(m, n, mh, h);
|
||||
print_tagq(h, t);
|
||||
print_tagq(h, tt);
|
||||
print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
||||
t = print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_man_nodelist(m, n, mh, h);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
@ -157,9 +178,9 @@ print_man_head(MAN_ARGS)
|
|||
{
|
||||
|
||||
print_gen_head(h);
|
||||
bufinit(h);
|
||||
buffmt(h, "%s(%s)", m->title, m->msec);
|
||||
|
||||
assert(m->title);
|
||||
assert(m->msec);
|
||||
bufcat_fmt(h, "%s(%s)", m->title, m->msec);
|
||||
print_otag(h, TAG_TITLE, 0, NULL);
|
||||
print_text(h, h->buf);
|
||||
}
|
||||
|
@ -184,36 +205,58 @@ print_man_node(MAN_ARGS)
|
|||
child = 1;
|
||||
t = h->tags.head;
|
||||
|
||||
bufinit(h);
|
||||
|
||||
/*
|
||||
* FIXME: embedded elements within next-line scopes (e.g., `br'
|
||||
* within an empty `B') will cause formatting to be forgotten
|
||||
* due to scope closing out.
|
||||
*/
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
child = man_root_pre(m, n, mh, h);
|
||||
man_root_pre(m, n, mh, h);
|
||||
break;
|
||||
case (MAN_TEXT):
|
||||
print_text(h, n->string);
|
||||
if (MANH_LITERAL & mh->fl)
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
/*
|
||||
* If we have a blank line, output a vertical space.
|
||||
* If we have a space as the first character, break
|
||||
* before printing the line's data.
|
||||
*/
|
||||
if ('\0' == *n->string) {
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
return;
|
||||
case (MAN_TBL):
|
||||
print_tbl(h, n->span);
|
||||
}
|
||||
|
||||
if (' ' == *n->string && MAN_LINE & n->flags)
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
else if (MANH_LITERAL & mh->fl && n->prev)
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
|
||||
print_text(h, n->string);
|
||||
return;
|
||||
case (MAN_EQN):
|
||||
print_eqn(h, n->eqn);
|
||||
break;
|
||||
case (MAN_TBL):
|
||||
/*
|
||||
* This will take care of initialising all of the table
|
||||
* state data for the first table, then tearing it down
|
||||
* for the last one.
|
||||
*/
|
||||
print_tbl(h, n->span);
|
||||
return;
|
||||
default:
|
||||
/*
|
||||
* Close out scope of font prior to opening a macro
|
||||
* scope. Assert that the metafont is on the top of the
|
||||
* stack (it's never nested).
|
||||
* scope.
|
||||
*/
|
||||
if (HTMLFONT_NONE != h->metac) {
|
||||
h->metal = h->metac;
|
||||
h->metac = HTMLFONT_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close out the current table, if it's open, and unset
|
||||
* the "meta" table state. This will be reopened on the
|
||||
* next table element.
|
||||
*/
|
||||
if (h->tblt) {
|
||||
print_tblclose(h);
|
||||
t = h->tags.head;
|
||||
}
|
||||
if (mans[n->tok].pre)
|
||||
child = (*mans[n->tok].pre)(m, n, mh, h);
|
||||
break;
|
||||
|
@ -225,13 +268,11 @@ print_man_node(MAN_ARGS)
|
|||
/* This will automatically close out any font scope. */
|
||||
print_stagq(h, t);
|
||||
|
||||
bufinit(h);
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
man_root_post(m, n, mh, h);
|
||||
break;
|
||||
case (MAN_TBL):
|
||||
case (MAN_EQN):
|
||||
break;
|
||||
default:
|
||||
if (mans[n->tok].post)
|
||||
|
@ -255,7 +296,7 @@ a2width(const struct man_node *n, struct roffsu *su)
|
|||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
static void
|
||||
man_root_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag[3];
|
||||
|
@ -266,19 +307,18 @@ man_root_pre(MAN_ARGS)
|
|||
if (m->vol)
|
||||
(void)strlcat(b, m->vol, BUFSIZ);
|
||||
|
||||
assert(m->title);
|
||||
assert(m->msec);
|
||||
snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
||||
PAIR_CLASS_INIT(&tag[1], "head");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_TABLE, 2, tag);
|
||||
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
|
||||
|
@ -286,30 +326,20 @@ man_root_pre(MAN_ARGS)
|
|||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-ltitle");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, title);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, b);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-rtitle");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, title);
|
||||
print_tagq(h, t);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,38 +349,27 @@ man_root_post(MAN_ARGS)
|
|||
{
|
||||
struct htmlpair tag[3];
|
||||
struct tag *t, *tt;
|
||||
char b[DATESIZ];
|
||||
|
||||
if (m->rawdate)
|
||||
strlcpy(b, m->rawdate, DATESIZ);
|
||||
else
|
||||
time2a(m->date, b, DATESIZ);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
|
||||
PAIR_CLASS_INIT(&tag[1], "foot");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_TABLE, 2, tag);
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, b);
|
||||
assert(m->date);
|
||||
print_text(h, m->date);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
if (m->source)
|
||||
print_text(h, m->source);
|
||||
|
@ -358,7 +377,6 @@ man_root_post(MAN_ARGS)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_br_pre(MAN_ARGS)
|
||||
|
@ -369,11 +387,13 @@ man_br_pre(MAN_ARGS)
|
|||
SCALE_VS_INIT(&su, 1);
|
||||
|
||||
if (MAN_sp == n->tok) {
|
||||
if (n->child)
|
||||
a2roffsu(n->child->string, &su, SCALE_VS);
|
||||
if (NULL != (n = n->child))
|
||||
if ( ! a2roffsu(n->string, &su, SCALE_VS))
|
||||
SCALE_VS_INIT(&su, atoi(n->string));
|
||||
} else
|
||||
su.scale = 0;
|
||||
|
||||
bufinit(h);
|
||||
bufcat_su(h, "height", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
@ -384,7 +404,6 @@ man_br_pre(MAN_ARGS)
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_SH_pre(MAN_ARGS)
|
||||
|
@ -392,6 +411,7 @@ man_SH_pre(MAN_ARGS)
|
|||
struct htmlpair tag;
|
||||
|
||||
if (MAN_BLOCK == n->type) {
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
PAIR_CLASS_INIT(&tag, "section");
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
return(1);
|
||||
|
@ -402,16 +422,20 @@ man_SH_pre(MAN_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_alt_pre(MAN_ARGS)
|
||||
{
|
||||
const struct man_node *nn;
|
||||
int i;
|
||||
int i, savelit;
|
||||
enum htmltag fp;
|
||||
struct tag *t;
|
||||
|
||||
if ((savelit = mh->fl & MANH_LITERAL))
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
|
||||
for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
|
||||
t = NULL;
|
||||
switch (n->tok) {
|
||||
|
@ -450,10 +474,12 @@ man_alt_pre(MAN_ARGS)
|
|||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
if (savelit)
|
||||
mh->fl |= MANH_LITERAL;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_SM_pre(MAN_ARGS)
|
||||
|
@ -465,7 +491,6 @@ man_SM_pre(MAN_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_SS_pre(MAN_ARGS)
|
||||
|
@ -473,6 +498,7 @@ man_SS_pre(MAN_ARGS)
|
|||
struct htmlpair tag;
|
||||
|
||||
if (MAN_BLOCK == n->type) {
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
PAIR_CLASS_INIT(&tag, "subsection");
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
return(1);
|
||||
|
@ -483,7 +509,6 @@ man_SS_pre(MAN_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_PP_pre(MAN_ARGS)
|
||||
|
@ -491,67 +516,29 @@ man_PP_pre(MAN_ARGS)
|
|||
|
||||
if (MAN_HEAD == n->type)
|
||||
return(0);
|
||||
else if (MAN_BODY == n->type && n->prev)
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
else if (MAN_BLOCK == n->type)
|
||||
print_bvspace(h, n);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_IP_pre(MAN_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
struct htmlpair tag;
|
||||
const struct man_node *nn;
|
||||
|
||||
/*
|
||||
* This scattering of 1-BU margins and pads is to make sure that
|
||||
* when text overruns its box, the subsequent text isn't flush
|
||||
* up against it. However, the rest of the right-hand box must
|
||||
* also be adjusted in consideration of this 1-BU space.
|
||||
*/
|
||||
|
||||
if (MAN_BODY == n->type) {
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
print_otag(h, TAG_DD, 0, NULL);
|
||||
return(1);
|
||||
} else if (MAN_HEAD != n->type) {
|
||||
print_otag(h, TAG_DL, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
nn = MAN_BLOCK == n->type ?
|
||||
n->head->child : n->parent->head->child;
|
||||
/* FIXME: width specification. */
|
||||
|
||||
SCALE_HS_INIT(&su, INDENT);
|
||||
|
||||
/* Width is the second token. */
|
||||
|
||||
if (MAN_IP == n->tok && NULL != nn)
|
||||
if (NULL != (nn = nn->next))
|
||||
a2width(nn, &su);
|
||||
|
||||
/* Width is the first token. */
|
||||
|
||||
if (MAN_TP == n->tok && NULL != nn) {
|
||||
/* Skip past non-text children. */
|
||||
while (nn && MAN_TEXT != nn->type)
|
||||
nn = nn->next;
|
||||
if (nn)
|
||||
a2width(nn, &su);
|
||||
}
|
||||
|
||||
if (MAN_BLOCK == n->type) {
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
print_otag(h, TAG_TABLE, 0, NULL);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
print_otag(h, TAG_COL, 0, NULL);
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
print_otag(h, TAG_TR, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
print_otag(h, TAG_DT, 0, NULL);
|
||||
|
||||
/* For IP, only print the first header element. */
|
||||
|
||||
|
@ -568,7 +555,6 @@ man_IP_pre(MAN_ARGS)
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_HP_pre(MAN_ARGS)
|
||||
|
@ -577,35 +563,57 @@ man_HP_pre(MAN_ARGS)
|
|||
struct roffsu su;
|
||||
const struct man_node *np;
|
||||
|
||||
np = MAN_BLOCK == n->type ?
|
||||
n->head->child :
|
||||
n->parent->head->child;
|
||||
if (MAN_HEAD == n->type)
|
||||
return(0);
|
||||
else if (MAN_BLOCK != n->type)
|
||||
return(1);
|
||||
|
||||
np = n->head->child;
|
||||
|
||||
if (NULL == np || ! a2width(np, &su))
|
||||
SCALE_HS_INIT(&su, INDENT);
|
||||
|
||||
if (MAN_HEAD == n->type) {
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
return(0);
|
||||
} else if (MAN_BLOCK == n->type) {
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
print_otag(h, TAG_TABLE, 0, NULL);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
print_otag(h, TAG_COL, 0, NULL);
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
print_otag(h, TAG_TR, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
bufinit(h);
|
||||
|
||||
print_bvspace(h, n);
|
||||
bufcat_su(h, "margin-left", &su);
|
||||
su.scale = -su.scale;
|
||||
bufcat_su(h, "text-indent", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
print_otag(h, TAG_P, 1, &tag);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_OP_pre(MAN_ARGS)
|
||||
{
|
||||
struct tag *tt;
|
||||
struct htmlpair tag;
|
||||
|
||||
print_text(h, "[");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
PAIR_CLASS_INIT(&tag, "opt");
|
||||
tt = print_otag(h, TAG_SPAN, 1, &tag);
|
||||
|
||||
if (NULL != (n = n->child)) {
|
||||
print_otag(h, TAG_B, 0, NULL);
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
print_stagq(h, tt);
|
||||
|
||||
if (NULL != n && NULL != n->next) {
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
print_text(h, n->next->string);
|
||||
}
|
||||
|
||||
print_stagq(h, tt);
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "]");
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
|
@ -616,7 +624,6 @@ man_B_pre(MAN_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_I_pre(MAN_ARGS)
|
||||
|
@ -626,22 +633,20 @@ man_I_pre(MAN_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_literal_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
if (MAN_nf == n->tok) {
|
||||
if (MAN_nf != n->tok) {
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
mh->fl |= MANH_LITERAL;
|
||||
} else
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
} else
|
||||
mh->fl |= MANH_LITERAL;
|
||||
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_in_pre(MAN_ARGS)
|
||||
|
@ -651,7 +656,6 @@ man_in_pre(MAN_ARGS)
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_ign_pre(MAN_ARGS)
|
||||
|
@ -660,7 +664,6 @@ man_ign_pre(MAN_ARGS)
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_RS_pre(MAN_ARGS)
|
||||
|
@ -677,6 +680,7 @@ man_RS_pre(MAN_ARGS)
|
|||
if (n->head->child)
|
||||
a2width(n->head->child, &su);
|
||||
|
||||
bufinit(h);
|
||||
bufcat_su(h, "margin-left", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
|
127
external/bsd/mdocml/dist/man_macro.c
vendored
127
external/bsd/mdocml/dist/man_macro.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: man_macro.c,v 1.54 2010/12/08 10:58:22 kristaps Exp $ */
|
||||
/* $Vendor-Id: man_macro.c,v 1.71 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -23,7 +23,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "man.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libman.h"
|
||||
|
||||
enum rew {
|
||||
|
@ -36,6 +38,8 @@ static int blk_close(MACRO_PROT_ARGS);
|
|||
static int blk_exp(MACRO_PROT_ARGS);
|
||||
static int blk_imp(MACRO_PROT_ARGS);
|
||||
static int in_line_eoln(MACRO_PROT_ARGS);
|
||||
static int man_args(struct man *, int,
|
||||
int *, char *, char **);
|
||||
|
||||
static int rew_scope(enum man_type,
|
||||
struct man *, enum mant);
|
||||
|
@ -43,20 +47,20 @@ static enum rew rew_dohalt(enum mant, enum man_type,
|
|||
const struct man_node *);
|
||||
static enum rew rew_block(enum mant, enum man_type,
|
||||
const struct man_node *);
|
||||
static int rew_warn(struct man *,
|
||||
static void rew_warn(struct man *,
|
||||
struct man_node *, enum mandocerr);
|
||||
|
||||
const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* br */
|
||||
{ in_line_eoln, 0 }, /* TH */
|
||||
{ blk_imp, MAN_SCOPED }, /* SH */
|
||||
{ blk_imp, MAN_SCOPED }, /* SS */
|
||||
{ blk_imp, MAN_SCOPED | MAN_FSCOPED }, /* TP */
|
||||
{ blk_imp, 0 }, /* LP */
|
||||
{ blk_imp, 0 }, /* PP */
|
||||
{ blk_imp, 0 }, /* P */
|
||||
{ blk_imp, 0 }, /* IP */
|
||||
{ blk_imp, 0 }, /* HP */
|
||||
{ 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 | MAN_FSCOPED }, /* 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 }, /* SM */
|
||||
{ in_line_eoln, MAN_SCOPED }, /* SB */
|
||||
{ in_line_eoln, 0 }, /* BI */
|
||||
|
@ -70,8 +74,8 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
|||
{ in_line_eoln, 0 }, /* RI */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* na */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* sp */
|
||||
{ in_line_eoln, 0 }, /* nf */
|
||||
{ in_line_eoln, 0 }, /* fi */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* nf */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* fi */
|
||||
{ blk_close, 0 }, /* RE */
|
||||
{ blk_exp, MAN_EXPLICIT }, /* RS */
|
||||
{ in_line_eoln, 0 }, /* DT */
|
||||
|
@ -80,6 +84,7 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
|||
{ in_line_eoln, 0 }, /* AT */
|
||||
{ in_line_eoln, 0 }, /* in */
|
||||
{ in_line_eoln, 0 }, /* ft */
|
||||
{ in_line_eoln, 0 }, /* OP */
|
||||
};
|
||||
|
||||
const struct man_macro * const man_macros = __man_macros;
|
||||
|
@ -88,17 +93,19 @@ const struct man_macro * const man_macros = __man_macros;
|
|||
/*
|
||||
* Warn when "n" is an explicit non-roff macro.
|
||||
*/
|
||||
static int
|
||||
static void
|
||||
rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
|
||||
{
|
||||
|
||||
if (er == MANDOCERR_MAX || MAN_BLOCK != n->type)
|
||||
return(1);
|
||||
return;
|
||||
if (MAN_VALID & n->flags)
|
||||
return(1);
|
||||
return;
|
||||
if ( ! (MAN_EXPLICIT & man_macros[n->tok].flags))
|
||||
return(1);
|
||||
return(man_nmsg(m, n, er));
|
||||
return;
|
||||
|
||||
assert(er < MANDOCERR_FATAL);
|
||||
man_nmsg(m, n, er);
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,30 +114,35 @@ rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
|
|||
* will be used if an explicit block scope is being closed out.
|
||||
*/
|
||||
int
|
||||
man_unscope(struct man *m, const struct man_node *n,
|
||||
man_unscope(struct man *m, const struct man_node *to,
|
||||
enum mandocerr er)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
assert(n);
|
||||
assert(to);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
|
||||
/* LINTED */
|
||||
while (m->last != n) {
|
||||
if ( ! rew_warn(m, m->last, er))
|
||||
return(0);
|
||||
while (m->last != to) {
|
||||
/*
|
||||
* Save the parent here, because we may delete the
|
||||
* m->last node in the post-validation phase and reset
|
||||
* it to m->last->parent, causing a step in the closing
|
||||
* out to be lost.
|
||||
*/
|
||||
n = m->last->parent;
|
||||
rew_warn(m, m->last, er);
|
||||
if ( ! man_valid_post(m))
|
||||
return(0);
|
||||
m->last = m->last->parent;
|
||||
m->last = n;
|
||||
assert(m->last);
|
||||
}
|
||||
|
||||
if ( ! rew_warn(m, m->last, er))
|
||||
return(0);
|
||||
rew_warn(m, m->last, er);
|
||||
if ( ! man_valid_post(m))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_ROOT == m->last->type ?
|
||||
MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -271,8 +283,7 @@ blk_close(MACRO_PROT_ARGS)
|
|||
break;
|
||||
|
||||
if (NULL == nn)
|
||||
if ( ! man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE))
|
||||
return(0);
|
||||
man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE);
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, ntok))
|
||||
return(0);
|
||||
|
@ -287,7 +298,7 @@ blk_close(MACRO_PROT_ARGS)
|
|||
int
|
||||
blk_exp(MACRO_PROT_ARGS)
|
||||
{
|
||||
int w, la;
|
||||
int la;
|
||||
char *p;
|
||||
|
||||
/*
|
||||
|
@ -296,11 +307,6 @@ blk_exp(MACRO_PROT_ARGS)
|
|||
* anywhere.
|
||||
*/
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, tok))
|
||||
return(0);
|
||||
if ( ! rew_scope(MAN_BLOCK, m, tok))
|
||||
return(0);
|
||||
|
||||
if ( ! man_block_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
if ( ! man_head_alloc(m, line, ppos, tok))
|
||||
|
@ -308,13 +314,8 @@ blk_exp(MACRO_PROT_ARGS)
|
|||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
w = man_args(m, line, pos, buf, &p);
|
||||
|
||||
if (-1 == w)
|
||||
return(0);
|
||||
if (0 == w)
|
||||
if ( ! man_args(m, line, pos, buf, &p))
|
||||
break;
|
||||
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
@ -339,7 +340,7 @@ blk_exp(MACRO_PROT_ARGS)
|
|||
int
|
||||
blk_imp(MACRO_PROT_ARGS)
|
||||
{
|
||||
int w, la;
|
||||
int la;
|
||||
char *p;
|
||||
struct man_node *n;
|
||||
|
||||
|
@ -363,13 +364,8 @@ blk_imp(MACRO_PROT_ARGS)
|
|||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
w = man_args(m, line, pos, buf, &p);
|
||||
|
||||
if (-1 == w)
|
||||
return(0);
|
||||
if (0 == w)
|
||||
if ( ! man_args(m, line, pos, buf, &p))
|
||||
break;
|
||||
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
@ -397,7 +393,7 @@ blk_imp(MACRO_PROT_ARGS)
|
|||
int
|
||||
in_line_eoln(MACRO_PROT_ARGS)
|
||||
{
|
||||
int w, la;
|
||||
int la;
|
||||
char *p;
|
||||
struct man_node *n;
|
||||
|
||||
|
@ -408,11 +404,7 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
w = man_args(m, line, pos, buf, &p);
|
||||
|
||||
if (-1 == w)
|
||||
return(0);
|
||||
if (0 == w)
|
||||
if ( ! man_args(m, line, pos, buf, &p))
|
||||
break;
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
|
@ -437,6 +429,9 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||
m->flags |= MAN_ILINE;
|
||||
}
|
||||
|
||||
assert(MAN_ROOT != m->last->type);
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
|
||||
/*
|
||||
* Rewind our element scope. Note that when TH is pruned, we'll
|
||||
* be back at the root, so make sure that we don't clobber as
|
||||
|
@ -461,9 +456,6 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||
if (m->last->type != MAN_ROOT && ! man_valid_post(m))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_ROOT == m->last->type ?
|
||||
MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -475,3 +467,18 @@ man_macroend(struct man *m)
|
|||
return(man_unscope(m, m->first, MANDOCERR_SCOPEEXIT));
|
||||
}
|
||||
|
||||
static int
|
||||
man_args(struct man *m, int line, int *pos, char *buf, char **v)
|
||||
{
|
||||
char *start;
|
||||
|
||||
assert(*pos);
|
||||
*v = start = buf + *pos;
|
||||
assert(' ' != *start);
|
||||
|
||||
if ('\0' == *start)
|
||||
return(0);
|
||||
|
||||
*v = mandoc_getarg(m->parse, v, line, pos);
|
||||
return(1);
|
||||
}
|
||||
|
|
368
external/bsd/mdocml/dist/man_term.c
vendored
368
external/bsd/mdocml/dist/man_term.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: man_term.c,v 1.94 2011/01/04 01:23:18 schwarze Exp $ */
|
||||
/* $Vendor-Id: man_term.c,v 1.127 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -31,32 +31,19 @@
|
|||
#include "out.h"
|
||||
#include "man.h"
|
||||
#include "term.h"
|
||||
#include "chars.h"
|
||||
#include "main.h"
|
||||
|
||||
#define INDENT 7
|
||||
#define HALFINDENT 3
|
||||
#define MAXMARGINS 64 /* maximum number of indented scopes */
|
||||
|
||||
/* FIXME: have PD set the default vspace width. */
|
||||
|
||||
struct mtermp {
|
||||
int fl;
|
||||
#define MANT_LITERAL (1 << 0)
|
||||
/*
|
||||
* Default amount to indent the left margin after leading text
|
||||
* has been printed (e.g., `HP' left-indent, `TP' and `IP' body
|
||||
* indent). This needs to be saved because `HP' and so on, if
|
||||
* not having a specified value, must default.
|
||||
*
|
||||
* Note that this is the indentation AFTER the left offset, so
|
||||
* the total offset is usually offset + lmargin.
|
||||
*/
|
||||
size_t lmargin;
|
||||
/*
|
||||
* The default offset, i.e., the amount between any text and the
|
||||
* page boundary.
|
||||
*/
|
||||
size_t offset;
|
||||
size_t lmargin[MAXMARGINS]; /* margins (incl. visible page) */
|
||||
int lmargincur; /* index of current margin */
|
||||
int lmarginsz; /* actual number of nested margins */
|
||||
size_t offset; /* default offset to visible page */
|
||||
};
|
||||
|
||||
#define DECL_ARGS struct termp *p, \
|
||||
|
@ -81,21 +68,22 @@ static void print_man_foot(struct termp *, const void *);
|
|||
static void print_bvspace(struct termp *,
|
||||
const struct man_node *);
|
||||
|
||||
static int pre_alternate(DECL_ARGS);
|
||||
static int pre_B(DECL_ARGS);
|
||||
static int pre_HP(DECL_ARGS);
|
||||
static int pre_I(DECL_ARGS);
|
||||
static int pre_IP(DECL_ARGS);
|
||||
static int pre_OP(DECL_ARGS);
|
||||
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_TP(DECL_ARGS);
|
||||
static int pre_alternate(DECL_ARGS);
|
||||
static int pre_ft(DECL_ARGS);
|
||||
static int pre_ign(DECL_ARGS);
|
||||
static int pre_in(DECL_ARGS);
|
||||
static int pre_literal(DECL_ARGS);
|
||||
static int pre_sp(DECL_ARGS);
|
||||
static int pre_ft(DECL_ARGS);
|
||||
|
||||
static void post_IP(DECL_ARGS);
|
||||
static void post_HP(DECL_ARGS);
|
||||
|
@ -126,7 +114,7 @@ static const struct termact termacts[MAN_MAX] = {
|
|||
{ pre_I, NULL, 0 }, /* I */
|
||||
{ pre_alternate, NULL, 0 }, /* IR */
|
||||
{ pre_alternate, NULL, 0 }, /* RI */
|
||||
{ NULL, NULL, MAN_NOTEXT }, /* na */
|
||||
{ pre_ign, NULL, MAN_NOTEXT }, /* na */
|
||||
{ pre_sp, NULL, MAN_NOTEXT }, /* sp */
|
||||
{ pre_literal, NULL, 0 }, /* nf */
|
||||
{ pre_literal, NULL, 0 }, /* fi */
|
||||
|
@ -138,6 +126,7 @@ static const struct termact termacts[MAN_MAX] = {
|
|||
{ pre_ign, NULL, 0 }, /* AT */
|
||||
{ pre_in, NULL, MAN_NOTEXT }, /* in */
|
||||
{ pre_ft, NULL, MAN_NOTEXT }, /* ft */
|
||||
{ pre_OP, NULL, 0 }, /* OP */
|
||||
};
|
||||
|
||||
|
||||
|
@ -152,19 +141,15 @@ terminal_man(void *arg, const struct man *man)
|
|||
|
||||
p = (struct termp *)arg;
|
||||
|
||||
if (0 == p->defindent)
|
||||
p->defindent = 7;
|
||||
|
||||
p->overstep = 0;
|
||||
p->maxrmargin = p->defrmargin;
|
||||
p->tabwidth = term_len(p, 5);
|
||||
|
||||
if (NULL == p->symtab)
|
||||
switch (p->enc) {
|
||||
case (TERMENC_ASCII):
|
||||
p->symtab = chars_init(CHARS_ASCII);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
p->symtab = mchars_alloc();
|
||||
|
||||
n = man_node(man);
|
||||
m = man_meta(man);
|
||||
|
@ -172,9 +157,10 @@ terminal_man(void *arg, const struct man *man)
|
|||
term_begin(p, print_man_head, print_man_foot, m);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
mt.fl = 0;
|
||||
mt.lmargin = term_len(p, INDENT);
|
||||
mt.offset = term_len(p, INDENT);
|
||||
memset(&mt, 0, sizeof(struct mtermp));
|
||||
|
||||
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
||||
mt.offset = term_len(p, p->defindent);
|
||||
|
||||
if (n->child)
|
||||
print_man_nodelist(p, &mt, n->child, m);
|
||||
|
@ -189,7 +175,7 @@ a2height(const struct termp *p, const char *cp)
|
|||
struct roffsu su;
|
||||
|
||||
if ( ! a2roffsu(cp, &su, SCALE_VS))
|
||||
SCALE_VS_INIT(&su, term_strlen(p, cp));
|
||||
SCALE_VS_INIT(&su, atoi(cp));
|
||||
|
||||
return(term_vspan(p, &su));
|
||||
}
|
||||
|
@ -206,24 +192,31 @@ a2width(const struct termp *p, const char *cp)
|
|||
return((int)term_hspan(p, &su));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 termp *p, const struct man_node *n)
|
||||
{
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (NULL == n->prev)
|
||||
if (n->body && n->body->child)
|
||||
if (MAN_TBL == n->body->child->type)
|
||||
return;
|
||||
|
||||
if (MAN_SS == n->prev->tok)
|
||||
return;
|
||||
if (MAN_SH == n->prev->tok)
|
||||
if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
|
||||
if (NULL == n->prev)
|
||||
return;
|
||||
|
||||
term_vspace(p);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_ign(DECL_ARGS)
|
||||
|
@ -255,7 +248,19 @@ pre_literal(DECL_ARGS)
|
|||
else
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
||||
return(1);
|
||||
/*
|
||||
* Unlike .IP and .TP, .HP does not have a HEAD.
|
||||
* So in case a second call to term_flushln() is needed,
|
||||
* indentation has to be set up explicitly.
|
||||
*/
|
||||
if (MAN_HP == n->parent->tok && p->rmargin < p->maxrmargin) {
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_TWOSPACE);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -319,6 +324,29 @@ pre_B(DECL_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_OP(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_word(p, "[");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
if (NULL != (n = n->child)) {
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
term_word(p, n->string);
|
||||
}
|
||||
if (NULL != n && NULL != n->next) {
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
term_word(p, n->next->string);
|
||||
}
|
||||
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "]");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_ft(DECL_ARGS)
|
||||
|
@ -397,6 +425,11 @@ pre_in(DECL_ARGS)
|
|||
else
|
||||
p->offset = v;
|
||||
|
||||
/* Don't let this creep beyond the right margin. */
|
||||
|
||||
if (p->offset > p->rmargin)
|
||||
p->offset = p->rmargin;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -407,6 +440,13 @@ pre_sp(DECL_ARGS)
|
|||
{
|
||||
size_t i, len;
|
||||
|
||||
if ((NULL == n->prev && n->parent)) {
|
||||
if (MAN_SS == n->parent->tok)
|
||||
return(0);
|
||||
if (MAN_SH == n->parent->tok)
|
||||
return(0);
|
||||
}
|
||||
|
||||
switch (n->tok) {
|
||||
case (MAN_br):
|
||||
len = 0;
|
||||
|
@ -429,7 +469,7 @@ pre_sp(DECL_ARGS)
|
|||
static int
|
||||
pre_HP(DECL_ARGS)
|
||||
{
|
||||
size_t len;
|
||||
size_t len, one;
|
||||
int ival;
|
||||
const struct man_node *nn;
|
||||
|
||||
|
@ -445,7 +485,7 @@ pre_HP(DECL_ARGS)
|
|||
return(0);
|
||||
}
|
||||
|
||||
len = mt->lmargin;
|
||||
len = mt->lmargin[mt->lmargincur];
|
||||
ival = -1;
|
||||
|
||||
/* Calculate offset. */
|
||||
|
@ -454,14 +494,15 @@ pre_HP(DECL_ARGS)
|
|||
if ((ival = a2width(p, nn->string)) >= 0)
|
||||
len = (size_t)ival;
|
||||
|
||||
if (0 == len)
|
||||
len = term_len(p, 1);
|
||||
one = term_len(p, 1);
|
||||
if (len < one)
|
||||
len = one;
|
||||
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = mt->offset + len;
|
||||
|
||||
if (ival >= 0)
|
||||
mt->lmargin = (size_t)ival;
|
||||
mt->lmargin[mt->lmargincur] = (size_t)ival;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -496,7 +537,7 @@ pre_PP(DECL_ARGS)
|
|||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
mt->lmargin = term_len(p, INDENT);
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
print_bvspace(p, n);
|
||||
break;
|
||||
default:
|
||||
|
@ -518,7 +559,6 @@ pre_IP(DECL_ARGS)
|
|||
|
||||
switch (n->type) {
|
||||
case (MAN_BODY):
|
||||
p->flags |= TERMP_NOLPAD;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case (MAN_HEAD):
|
||||
|
@ -531,7 +571,7 @@ pre_IP(DECL_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
len = mt->lmargin;
|
||||
len = mt->lmargin[mt->lmargincur];
|
||||
ival = -1;
|
||||
|
||||
/* Calculate the offset from the optional second argument. */
|
||||
|
@ -552,7 +592,7 @@ pre_IP(DECL_ARGS)
|
|||
break;
|
||||
|
||||
/* Set the saved left-margin. */
|
||||
mt->lmargin = (size_t)ival;
|
||||
mt->lmargin[mt->lmargincur] = (size_t)ival;
|
||||
|
||||
savelit = MANT_LITERAL & mt->fl;
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
@ -589,7 +629,6 @@ post_IP(DECL_ARGS)
|
|||
break;
|
||||
case (MAN_BODY):
|
||||
term_newln(p);
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -610,7 +649,6 @@ pre_TP(DECL_ARGS)
|
|||
p->flags |= TERMP_NOBREAK;
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
p->flags |= TERMP_NOLPAD;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case (MAN_BLOCK):
|
||||
|
@ -620,18 +658,15 @@ pre_TP(DECL_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
len = (size_t)mt->lmargin;
|
||||
len = (size_t)mt->lmargin[mt->lmargincur];
|
||||
ival = -1;
|
||||
|
||||
/* Calculate offset. */
|
||||
|
||||
if (NULL != (nn = n->parent->head->child)) {
|
||||
while (nn && MAN_TEXT != nn->type)
|
||||
nn = nn->next;
|
||||
if (nn && nn->next)
|
||||
if (NULL != (nn = n->parent->head->child))
|
||||
if (nn->string && nn->parent->line == nn->line)
|
||||
if ((ival = a2width(p, nn->string)) >= 0)
|
||||
len = (size_t)ival;
|
||||
}
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_HEAD):
|
||||
|
@ -652,9 +687,8 @@ pre_TP(DECL_ARGS)
|
|||
|
||||
if (savelit)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
|
||||
if (ival >= 0)
|
||||
mt->lmargin = (size_t)ival;
|
||||
mt->lmargin[mt->lmargincur] = (size_t)ival;
|
||||
|
||||
return(0);
|
||||
case (MAN_BODY):
|
||||
|
@ -683,7 +717,6 @@ post_TP(DECL_ARGS)
|
|||
break;
|
||||
case (MAN_BODY):
|
||||
term_newln(p);
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -698,8 +731,9 @@ pre_SS(DECL_ARGS)
|
|||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
mt->lmargin = term_len(p, INDENT);
|
||||
mt->offset = term_len(p, INDENT);
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->offset = term_len(p, p->defindent);
|
||||
/* If following a prior empty `SS', no vspace. */
|
||||
if (n->prev && MAN_SS == n->prev->tok)
|
||||
if (NULL == n->prev->body->child)
|
||||
|
@ -710,7 +744,7 @@ pre_SS(DECL_ARGS)
|
|||
break;
|
||||
case (MAN_HEAD):
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
p->offset = term_len(p, HALFINDENT);
|
||||
p->offset = term_len(p, p->defindent/2);
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
p->offset = mt->offset;
|
||||
|
@ -748,8 +782,9 @@ pre_SH(DECL_ARGS)
|
|||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
mt->lmargin = term_len(p, INDENT);
|
||||
mt->offset = term_len(p, INDENT);
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
mt->offset = term_len(p, p->defindent);
|
||||
/* If following a prior empty `SH', no vspace. */
|
||||
if (n->prev && MAN_SH == n->prev->tok)
|
||||
if (NULL == n->prev->body->child)
|
||||
|
@ -791,13 +826,12 @@ post_SH(DECL_ARGS)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_RS(DECL_ARGS)
|
||||
{
|
||||
const struct man_node *nn;
|
||||
int ival;
|
||||
size_t sz;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
|
@ -809,40 +843,52 @@ pre_RS(DECL_ARGS)
|
|||
break;
|
||||
}
|
||||
|
||||
if (NULL == (nn = n->parent->head->child)) {
|
||||
mt->offset = mt->lmargin + term_len(p, INDENT);
|
||||
p->offset = mt->offset;
|
||||
return(1);
|
||||
}
|
||||
sz = term_len(p, p->defindent);
|
||||
|
||||
if ((ival = a2width(p, nn->string)) < 0)
|
||||
return(1);
|
||||
if (NULL != (n = n->parent->head->child))
|
||||
if ((ival = a2width(p, n->string)) >= 0)
|
||||
sz = (size_t)ival;
|
||||
|
||||
mt->offset = term_len(p, INDENT) + (size_t)ival;
|
||||
p->offset = mt->offset;
|
||||
mt->offset += sz;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->offset = mt->offset < p->rmargin ? mt->offset : p->rmargin;
|
||||
|
||||
if (++mt->lmarginsz < MAXMARGINS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
|
||||
mt->lmargin[mt->lmargincur] = mt->lmargin[mt->lmargincur - 1];
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
post_RS(DECL_ARGS)
|
||||
{
|
||||
int ival;
|
||||
size_t sz;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
mt->offset = mt->lmargin = term_len(p, INDENT);
|
||||
break;
|
||||
return;
|
||||
case (MAN_HEAD):
|
||||
break;
|
||||
return;
|
||||
default:
|
||||
term_newln(p);
|
||||
p->offset = term_len(p, INDENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sz = term_len(p, p->defindent);
|
||||
|
||||
if (NULL != (n = n->parent->head->child))
|
||||
if ((ival = a2width(p, n->string)) >= 0)
|
||||
sz = (size_t)ival;
|
||||
|
||||
mt->offset = mt->offset < sz ? 0 : mt->offset - sz;
|
||||
p->offset = mt->offset;
|
||||
|
||||
if (--mt->lmarginsz < MAXMARGINS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
}
|
||||
|
||||
static void
|
||||
print_man_node(DECL_ARGS)
|
||||
|
@ -850,58 +896,73 @@ print_man_node(DECL_ARGS)
|
|||
size_t rm, rmax;
|
||||
int c;
|
||||
|
||||
c = 1;
|
||||
|
||||
switch (n->type) {
|
||||
case(MAN_TEXT):
|
||||
if (0 == *n->string) {
|
||||
/*
|
||||
* If we have a blank line, output a vertical space.
|
||||
* If we have a space as the first character, break
|
||||
* before printing the line's data.
|
||||
*/
|
||||
if ('\0' == *n->string) {
|
||||
term_vspace(p);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
} else if (' ' == *n->string && MAN_LINE & n->flags)
|
||||
term_newln(p);
|
||||
|
||||
term_word(p, n->string);
|
||||
|
||||
/* FIXME: this means that macro lines are munged! */
|
||||
|
||||
if (MANT_LITERAL & mt->fl) {
|
||||
/*
|
||||
* If we're in a literal context, make sure that words
|
||||
* togehter on the same line stay together. This is a
|
||||
* POST-printing call, so we check the NEXT word. Since
|
||||
* -man doesn't have nested macros, we don't need to be
|
||||
* more specific than this.
|
||||
*/
|
||||
if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
|
||||
(NULL == n->next ||
|
||||
n->next->line > n->line)) {
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
}
|
||||
break;
|
||||
|
||||
if (MAN_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
return;
|
||||
case (MAN_EQN):
|
||||
term_eqn(p, n->eqn);
|
||||
return;
|
||||
case (MAN_TBL):
|
||||
/*
|
||||
* Tables are preceded by a newline. Then process a
|
||||
* table line, which will cause line termination,
|
||||
*/
|
||||
if (TBL_SPAN_FIRST & n->span->flags)
|
||||
term_newln(p);
|
||||
term_tbl(p, n->span);
|
||||
break;
|
||||
return;
|
||||
default:
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
if (termacts[n->tok].pre)
|
||||
c = (*termacts[n->tok].pre)(p, mt, n, m);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
c = 1;
|
||||
if (termacts[n->tok].pre)
|
||||
c = (*termacts[n->tok].pre)(p, mt, n, m);
|
||||
|
||||
if (c && n->child)
|
||||
print_man_nodelist(p, mt, n->child, m);
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_TEXT):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TBL):
|
||||
break;
|
||||
default:
|
||||
if (termacts[n->tok].post)
|
||||
(*termacts[n->tok].post)(p, mt, n, m);
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (MAN_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
@ -922,42 +983,65 @@ print_man_nodelist(DECL_ARGS)
|
|||
static void
|
||||
print_man_foot(struct termp *p, const void *arg)
|
||||
{
|
||||
char buf[DATESIZ];
|
||||
char title[BUFSIZ];
|
||||
size_t datelen;
|
||||
const struct man_meta *meta;
|
||||
|
||||
meta = (const struct man_meta *)arg;
|
||||
assert(meta->title);
|
||||
assert(meta->msec);
|
||||
assert(meta->date);
|
||||
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
if (meta->rawdate)
|
||||
strlcpy(buf, meta->rawdate, DATESIZ);
|
||||
else
|
||||
time2a(meta->date, buf, DATESIZ);
|
||||
term_vspace(p);
|
||||
|
||||
/*
|
||||
* Temporary, undocumented option to imitate mdoc(7) output.
|
||||
* In the bottom right corner, use the source instead of
|
||||
* the title.
|
||||
*/
|
||||
|
||||
if ( ! p->mdocstyle) {
|
||||
term_vspace(p);
|
||||
term_vspace(p);
|
||||
term_vspace(p);
|
||||
snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
|
||||
} else if (meta->source) {
|
||||
strlcpy(title, meta->source, BUFSIZ);
|
||||
} else {
|
||||
title[0] = '\0';
|
||||
}
|
||||
datelen = term_strlen(p, meta->date);
|
||||
|
||||
/* Bottom left corner: manual source. */
|
||||
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, buf);
|
||||
p->offset = 0;
|
||||
|
||||
/* term_strlen() can return zero. */
|
||||
if (p->rmargin == p->maxrmargin)
|
||||
p->rmargin--;
|
||||
p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2;
|
||||
|
||||
if (meta->source)
|
||||
term_word(p, meta->source);
|
||||
if (meta->source)
|
||||
term_word(p, "");
|
||||
term_flushln(p);
|
||||
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
/* At the bottom in the middle: manual date. */
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, title);
|
||||
if (p->offset + datelen >= p->rmargin)
|
||||
p->rmargin = p->offset + datelen;
|
||||
|
||||
term_word(p, meta->date);
|
||||
term_flushln(p);
|
||||
|
||||
/* Bottom right corner: manual title and section. */
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
|
||||
term_word(p, buf);
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
|
@ -970,36 +1054,33 @@ print_man_head(struct termp *p, const void *arg)
|
|||
const struct man_meta *m;
|
||||
|
||||
m = (const struct man_meta *)arg;
|
||||
|
||||
/*
|
||||
* Note that old groff would spit out some spaces before the
|
||||
* header. We discontinue this strange behaviour, but at one
|
||||
* point we did so here.
|
||||
*/
|
||||
|
||||
p->rmargin = p->maxrmargin;
|
||||
|
||||
p->offset = 0;
|
||||
buf[0] = title[0] = '\0';
|
||||
assert(m->title);
|
||||
assert(m->msec);
|
||||
|
||||
if (m->vol)
|
||||
strlcpy(buf, m->vol, BUFSIZ);
|
||||
else
|
||||
buf[0] = '\0';
|
||||
buflen = term_strlen(p, buf);
|
||||
|
||||
/* Top left corner: manual title and section. */
|
||||
|
||||
snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
|
||||
titlen = term_strlen(p, title);
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
p->offset = 0;
|
||||
p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
|
||||
(p->maxrmargin -
|
||||
term_strlen(p, buf) + term_len(p, 1)) / 2 :
|
||||
p->maxrmargin - buflen;
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
/* At the top in the middle: manual volume. */
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
|
||||
p->maxrmargin - titlen : p->maxrmargin;
|
||||
|
@ -1007,25 +1088,30 @@ print_man_head(struct termp *p, const void *arg)
|
|||
term_word(p, buf);
|
||||
term_flushln(p);
|
||||
|
||||
/* Top right corner: title and section, again. */
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
if (p->rmargin + titlen <= p->maxrmargin) {
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->offset = 0;
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
|
||||
/*
|
||||
* Groff likes to have some leading spaces before content. Well
|
||||
* that's fine by me.
|
||||
* Groff prints three blank lines before the content.
|
||||
* Do the same, except in the temporary, undocumented
|
||||
* mode imitating mdoc(7) output.
|
||||
*/
|
||||
|
||||
term_vspace(p);
|
||||
if ( ! p->mdocstyle) {
|
||||
term_vspace(p);
|
||||
term_vspace(p);
|
||||
}
|
||||
}
|
||||
|
|
277
external/bsd/mdocml/dist/man_validate.c
vendored
277
external/bsd/mdocml/dist/man_validate.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: man_validate.c,v 1.57 2011/01/01 12:59:17 kristaps Exp $ */
|
||||
/* $Vendor-Id: man_validate.c,v 1.80 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 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
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "man.h"
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
#include "libmandoc.h"
|
||||
|
@ -42,50 +44,52 @@ struct man_valid {
|
|||
v_check *posts;
|
||||
};
|
||||
|
||||
static int check_bline(CHKARGS);
|
||||
static int check_eq0(CHKARGS);
|
||||
static int check_ft(CHKARGS);
|
||||
static int check_eq2(CHKARGS);
|
||||
static int check_le1(CHKARGS);
|
||||
static int check_ge2(CHKARGS);
|
||||
static int check_le5(CHKARGS);
|
||||
static int check_par(CHKARGS);
|
||||
static int check_part(CHKARGS);
|
||||
static int check_root(CHKARGS);
|
||||
static int check_sec(CHKARGS);
|
||||
static int check_text(CHKARGS);
|
||||
static int check_title(CHKARGS);
|
||||
static void check_text(CHKARGS);
|
||||
|
||||
static int post_AT(CHKARGS);
|
||||
static int post_vs(CHKARGS);
|
||||
static int post_fi(CHKARGS);
|
||||
static int post_ft(CHKARGS);
|
||||
static int post_nf(CHKARGS);
|
||||
static int post_sec(CHKARGS);
|
||||
static int post_TH(CHKARGS);
|
||||
static int post_UC(CHKARGS);
|
||||
static int pre_sec(CHKARGS);
|
||||
|
||||
static v_check posts_at[] = { post_AT, NULL };
|
||||
static v_check posts_br[] = { post_vs, check_eq0, NULL };
|
||||
static v_check posts_eq0[] = { check_eq0, NULL };
|
||||
static v_check posts_eq2[] = { check_eq2, NULL };
|
||||
static v_check posts_fi[] = { check_eq0, post_fi, NULL };
|
||||
static v_check posts_le1[] = { check_le1, NULL };
|
||||
static v_check posts_ft[] = { check_ft, NULL };
|
||||
static v_check posts_ft[] = { post_ft, NULL };
|
||||
static v_check posts_nf[] = { check_eq0, post_nf, NULL };
|
||||
static v_check posts_par[] = { check_par, NULL };
|
||||
static v_check posts_part[] = { check_part, NULL };
|
||||
static v_check posts_sec[] = { check_sec, NULL };
|
||||
static v_check posts_th[] = { check_ge2, check_le5, check_title, post_TH, NULL };
|
||||
static v_check posts_sec[] = { post_sec, NULL };
|
||||
static v_check posts_sp[] = { post_vs, check_le1, NULL };
|
||||
static v_check posts_th[] = { check_ge2, check_le5, post_TH, NULL };
|
||||
static v_check posts_uc[] = { post_UC, NULL };
|
||||
static v_check pres_bline[] = { check_bline, NULL };
|
||||
|
||||
static v_check pres_sec[] = { pre_sec, NULL };
|
||||
|
||||
static const struct man_valid man_valids[MAN_MAX] = {
|
||||
{ NULL, posts_eq0 }, /* br */
|
||||
{ pres_bline, posts_th }, /* TH */
|
||||
{ pres_bline, posts_sec }, /* SH */
|
||||
{ pres_bline, posts_sec }, /* SS */
|
||||
{ pres_bline, posts_par }, /* TP */
|
||||
{ pres_bline, posts_par }, /* LP */
|
||||
{ pres_bline, posts_par }, /* PP */
|
||||
{ pres_bline, posts_par }, /* P */
|
||||
{ pres_bline, posts_par }, /* IP */
|
||||
{ pres_bline, posts_par }, /* HP */
|
||||
{ NULL, posts_br }, /* br */
|
||||
{ NULL, posts_th }, /* TH */
|
||||
{ pres_sec, posts_sec }, /* SH */
|
||||
{ pres_sec, posts_sec }, /* SS */
|
||||
{ NULL, NULL }, /* TP */
|
||||
{ NULL, posts_par }, /* LP */
|
||||
{ NULL, posts_par }, /* PP */
|
||||
{ NULL, posts_par }, /* P */
|
||||
{ NULL, NULL }, /* IP */
|
||||
{ NULL, NULL }, /* HP */
|
||||
{ NULL, NULL }, /* SM */
|
||||
{ NULL, NULL }, /* SB */
|
||||
{ NULL, NULL }, /* BI */
|
||||
|
@ -97,10 +101,10 @@ static const struct man_valid man_valids[MAN_MAX] = {
|
|||
{ NULL, NULL }, /* I */
|
||||
{ NULL, NULL }, /* IR */
|
||||
{ NULL, NULL }, /* RI */
|
||||
{ NULL, posts_eq0 }, /* na */ /* FIXME: should warn only. */
|
||||
{ NULL, posts_le1 }, /* sp */ /* FIXME: should warn only. */
|
||||
{ pres_bline, posts_nf }, /* nf */
|
||||
{ pres_bline, posts_fi }, /* fi */
|
||||
{ NULL, posts_eq0 }, /* na */
|
||||
{ NULL, posts_sp }, /* sp */
|
||||
{ NULL, posts_nf }, /* nf */
|
||||
{ NULL, posts_fi }, /* fi */
|
||||
{ NULL, NULL }, /* RE */
|
||||
{ NULL, posts_part }, /* RS */
|
||||
{ NULL, NULL }, /* DT */
|
||||
|
@ -109,6 +113,7 @@ static const struct man_valid man_valids[MAN_MAX] = {
|
|||
{ NULL, posts_at }, /* AT */
|
||||
{ NULL, NULL }, /* in */
|
||||
{ NULL, posts_ft }, /* ft */
|
||||
{ NULL, posts_eq2 }, /* OP */
|
||||
};
|
||||
|
||||
|
||||
|
@ -122,6 +127,8 @@ man_valid_pre(struct man *m, struct man_node *n)
|
|||
/* FALLTHROUGH */
|
||||
case (MAN_ROOT):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_EQN):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TBL):
|
||||
return(1);
|
||||
default:
|
||||
|
@ -148,9 +155,12 @@ man_valid_post(struct man *m)
|
|||
|
||||
switch (m->last->type) {
|
||||
case (MAN_TEXT):
|
||||
return(check_text(m, m->last));
|
||||
check_text(m, m->last);
|
||||
return(1);
|
||||
case (MAN_ROOT):
|
||||
return(check_root(m, m->last));
|
||||
case (MAN_EQN):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TBL):
|
||||
return(1);
|
||||
default:
|
||||
|
@ -191,94 +201,47 @@ check_root(CHKARGS)
|
|||
*/
|
||||
|
||||
m->meta.title = mandoc_strdup("unknown");
|
||||
m->meta.date = time(NULL);
|
||||
m->meta.msec = mandoc_strdup("1");
|
||||
m->meta.date = mandoc_normdate
|
||||
(m->parse, NULL, n->line, n->pos);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_title(CHKARGS)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
assert(n->child);
|
||||
/* FIXME: is this sufficient? */
|
||||
if ('\0' == *n->child->string) {
|
||||
man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (p = n->child->string; '\0' != *p; p++)
|
||||
/* Only warn about this once... */
|
||||
if (isalpha((u_char)*p) && ! isupper((u_char)*p)) {
|
||||
man_nmsg(m, n, MANDOCERR_UPPERCASE);
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static void
|
||||
check_text(CHKARGS)
|
||||
{
|
||||
char *p;
|
||||
int pos, c;
|
||||
size_t sz;
|
||||
char *cp, *p;
|
||||
|
||||
for (p = n->string, pos = n->pos + 1; *p; p++, pos++) {
|
||||
sz = strcspn(p, "\t\\");
|
||||
p += (int)sz;
|
||||
|
||||
if ('\0' == *p)
|
||||
break;
|
||||
|
||||
pos += (int)sz;
|
||||
|
||||
if ('\t' == *p) {
|
||||
if (MAN_LITERAL & m->flags)
|
||||
continue;
|
||||
if (man_pmsg(m, n->line, pos, MANDOCERR_BADTAB))
|
||||
continue;
|
||||
return(0);
|
||||
}
|
||||
return;
|
||||
|
||||
/* Check the special character. */
|
||||
|
||||
c = mandoc_special(p);
|
||||
if (c) {
|
||||
p += c - 1;
|
||||
pos += c - 1;
|
||||
} else
|
||||
man_pmsg(m, n->line, pos, MANDOCERR_BADESCAPE);
|
||||
}
|
||||
|
||||
return(1);
|
||||
cp = n->string;
|
||||
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
||||
man_pmsg(m, n->line, (int)(p - cp), MANDOCERR_BADTAB);
|
||||
}
|
||||
|
||||
|
||||
#define INEQ_DEFINE(x, ineq, name) \
|
||||
static int \
|
||||
check_##name(CHKARGS) \
|
||||
{ \
|
||||
if (n->nchild ineq (x)) \
|
||||
return(1); \
|
||||
man_vmsg(m, MANDOCERR_SYNTARGCOUNT, n->line, n->pos, \
|
||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, m->parse, n->line, n->pos, \
|
||||
"line arguments %s %d (have %d)", \
|
||||
#ineq, (x), n->nchild); \
|
||||
return(0); \
|
||||
return(1); \
|
||||
}
|
||||
|
||||
INEQ_DEFINE(0, ==, eq0)
|
||||
INEQ_DEFINE(2, ==, eq2)
|
||||
INEQ_DEFINE(1, <=, le1)
|
||||
INEQ_DEFINE(2, >=, ge2)
|
||||
INEQ_DEFINE(5, <=, le5)
|
||||
|
||||
static int
|
||||
check_ft(CHKARGS)
|
||||
post_ft(CHKARGS)
|
||||
{
|
||||
char *cp;
|
||||
int ok;
|
||||
|
@ -318,38 +281,48 @@ check_ft(CHKARGS)
|
|||
}
|
||||
|
||||
if (0 == ok) {
|
||||
man_vmsg(m, MANDOCERR_BADFONT,
|
||||
mandoc_vmsg
|
||||
(MANDOCERR_BADFONT, m->parse,
|
||||
n->line, n->pos, "%s", cp);
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
if (1 < n->nchild)
|
||||
man_vmsg(m, MANDOCERR_ARGCOUNT, n->line, n->pos,
|
||||
"want one child (have %d)", n->nchild);
|
||||
mandoc_vmsg
|
||||
(MANDOCERR_ARGCOUNT, m->parse, n->line,
|
||||
n->pos, "want one child (have %d)",
|
||||
n->nchild);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
check_sec(CHKARGS)
|
||||
pre_sec(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_HEAD == n->type && 0 == n->nchild) {
|
||||
man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
|
||||
return(0);
|
||||
} else if (MAN_BODY == n->type && 0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_NOBODY);
|
||||
|
||||
if (MAN_BLOCK == n->type)
|
||||
m->flags &= ~MAN_LITERAL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_sec(CHKARGS)
|
||||
{
|
||||
|
||||
if ( ! (MAN_HEAD == n->type && 0 == n->nchild))
|
||||
return(1);
|
||||
|
||||
man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_part(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BODY == n->type && 0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_NOBODY);
|
||||
mandoc_msg(MANDOCERR_ARGCWARN, m->parse, n->line,
|
||||
n->pos, "want children (have none)");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -359,27 +332,16 @@ static int
|
|||
check_par(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BODY == n->type)
|
||||
switch (n->tok) {
|
||||
case (MAN_IP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_HP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TP):
|
||||
/* Body-less lists are ok. */
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
if (0 == n->body->nchild)
|
||||
man_node_delete(m, n);
|
||||
break;
|
||||
default:
|
||||
case (MAN_BODY):
|
||||
if (0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_NOBODY);
|
||||
man_nmsg(m, n, MANDOCERR_IGNPAR);
|
||||
break;
|
||||
}
|
||||
if (MAN_HEAD == n->type)
|
||||
switch (n->tok) {
|
||||
case (MAN_PP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_P):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_LP):
|
||||
case (MAN_HEAD):
|
||||
if (n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_ARGSLOST);
|
||||
break;
|
||||
|
@ -391,22 +353,11 @@ check_par(CHKARGS)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
check_bline(CHKARGS)
|
||||
{
|
||||
|
||||
assert( ! (MAN_ELINE & m->flags));
|
||||
if (MAN_BLINE & m->flags) {
|
||||
man_nmsg(m, n, MANDOCERR_SYNTLINESCOPE);
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_TH(CHKARGS)
|
||||
{
|
||||
const char *p;
|
||||
int line, pos;
|
||||
|
||||
if (m->meta.title)
|
||||
free(m->meta.title);
|
||||
|
@ -416,44 +367,49 @@ post_TH(CHKARGS)
|
|||
free(m->meta.source);
|
||||
if (m->meta.msec)
|
||||
free(m->meta.msec);
|
||||
if (m->meta.rawdate)
|
||||
free(m->meta.rawdate);
|
||||
if (m->meta.date)
|
||||
free(m->meta.date);
|
||||
|
||||
m->meta.title = m->meta.vol = m->meta.rawdate =
|
||||
line = n->line;
|
||||
pos = n->pos;
|
||||
m->meta.title = m->meta.vol = m->meta.date =
|
||||
m->meta.msec = m->meta.source = NULL;
|
||||
m->meta.date = 0;
|
||||
|
||||
/* ->TITLE<- MSEC DATE SOURCE VOL */
|
||||
|
||||
n = n->child;
|
||||
assert(n);
|
||||
if (n && n->string) {
|
||||
for (p = n->string; '\0' != *p; p++) {
|
||||
/* Only warn about this once... */
|
||||
if (isalpha((unsigned char)*p) &&
|
||||
! isupper((unsigned char)*p)) {
|
||||
man_nmsg(m, n, MANDOCERR_UPPERCASE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m->meta.title = mandoc_strdup(n->string);
|
||||
} else
|
||||
m->meta.title = mandoc_strdup("");
|
||||
|
||||
/* TITLE ->MSEC<- DATE SOURCE VOL */
|
||||
|
||||
if (n)
|
||||
n = n->next;
|
||||
assert(n);
|
||||
if (n && n->string)
|
||||
m->meta.msec = mandoc_strdup(n->string);
|
||||
else
|
||||
m->meta.msec = mandoc_strdup("");
|
||||
|
||||
/* TITLE MSEC ->DATE<- SOURCE VOL */
|
||||
|
||||
/*
|
||||
* Try to parse the date. If this works, stash the epoch (this
|
||||
* is optimal because we can reformat it in the canonical form).
|
||||
* If it doesn't parse, isn't specified at all, or is an empty
|
||||
* string, then use the current date.
|
||||
*/
|
||||
|
||||
if (n)
|
||||
n = n->next;
|
||||
if (n && n->string && *n->string) {
|
||||
m->meta.date = mandoc_a2time
|
||||
(MTIME_ISO_8601, n->string);
|
||||
if (0 == m->meta.date) {
|
||||
man_nmsg(m, n, MANDOCERR_BADDATE);
|
||||
m->meta.rawdate = mandoc_strdup(n->string);
|
||||
}
|
||||
if (n && n->string && '\0' != n->string[0]) {
|
||||
pos = n->pos;
|
||||
m->meta.date = mandoc_normdate
|
||||
(m->parse, n->string, line, pos);
|
||||
} else
|
||||
m->meta.date = time(NULL);
|
||||
m->meta.date = mandoc_strdup("");
|
||||
|
||||
/* TITLE MSEC DATE ->SOURCE<- VOL */
|
||||
|
||||
|
@ -461,9 +417,13 @@ post_TH(CHKARGS)
|
|||
m->meta.source = mandoc_strdup(n->string);
|
||||
|
||||
/* TITLE MSEC DATE SOURCE ->VOL<- */
|
||||
/* If missing, use the default VOL name for MSEC. */
|
||||
|
||||
if (n && (n = n->next))
|
||||
m->meta.vol = mandoc_strdup(n->string);
|
||||
else if ('\0' != m->meta.msec[0] &&
|
||||
(NULL != (p = mandoc_a2msec(m->meta.msec))))
|
||||
m->meta.vol = mandoc_strdup(p);
|
||||
|
||||
/*
|
||||
* Remove the `TH' node after we've processed it for our
|
||||
|
@ -489,7 +449,7 @@ post_fi(CHKARGS)
|
|||
{
|
||||
|
||||
if ( ! (MAN_LITERAL & m->flags))
|
||||
man_nmsg(m, n, MANDOCERR_NOSCOPE);
|
||||
man_nmsg(m, n, MANDOCERR_WNOSCOPE);
|
||||
|
||||
m->flags &= ~MAN_LITERAL;
|
||||
return(1);
|
||||
|
@ -509,7 +469,6 @@ post_UC(CHKARGS)
|
|||
const char *p, *s;
|
||||
|
||||
n = n->child;
|
||||
n = m->last->child;
|
||||
|
||||
if (NULL == n || MAN_TEXT != n->type)
|
||||
p = bsd_versions[0];
|
||||
|
@ -575,3 +534,17 @@ post_AT(CHKARGS)
|
|||
m->meta.source = mandoc_strdup(p);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_vs(CHKARGS)
|
||||
{
|
||||
|
||||
/*
|
||||
* Don't warn about this because it occurs in pod2man and would
|
||||
* cause considerable (unfixable) warnage.
|
||||
*/
|
||||
if (NULL == n->prev && MAN_ROOT == n->parent->type)
|
||||
man_node_delete(m, n);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
|
BIN
external/bsd/mdocml/dist/mandoc
vendored
BIN
external/bsd/mdocml/dist/mandoc
vendored
Binary file not shown.
158
external/bsd/mdocml/dist/mandoc.1
vendored
158
external/bsd/mdocml/dist/mandoc.1
vendored
|
@ -1,6 +1,6 @@
|
|||
.\" $Vendor-Id: mandoc.1,v 1.84 2011/01/04 23:32:21 kristaps Exp $
|
||||
.\" $Vendor-Id: mandoc.1,v 1.100 2011/12/25 19:35:44 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -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 January 4, 2011
|
||||
.Dd December 25, 2011
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -27,13 +27,26 @@
|
|||
.Op Fl O Ns Ar option
|
||||
.Op Fl T Ns Ar output
|
||||
.Op Fl W Ns Ar level
|
||||
.Op Ar file...
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility formats
|
||||
.Ux
|
||||
manual pages for display.
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
reads
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
text from stdin, implying
|
||||
.Fl m Ns Cm andoc ,
|
||||
and produces
|
||||
.Fl T Ns Cm ascii
|
||||
output.
|
||||
.Pp
|
||||
The arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl m Ns Ar format
|
||||
|
@ -96,18 +109,6 @@ If multiple files are specified,
|
|||
.Nm
|
||||
will halt with the first failed parse.
|
||||
.El
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
reads
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
text from stdin, implying
|
||||
.Fl m Ns Cm andoc ,
|
||||
and produces
|
||||
.Fl T Ns Cm ascii
|
||||
output.
|
||||
.Ss Input Formats
|
||||
The
|
||||
.Nm
|
||||
|
@ -157,7 +158,7 @@ The
|
|||
utility accepts the following
|
||||
.Fl T
|
||||
arguments, which correspond to output modes:
|
||||
.Bl -tag -width Ds
|
||||
.Bl -tag -width "-Tlocale"
|
||||
.It Fl T Ns Cm ascii
|
||||
Produce 7-bit ASCII output.
|
||||
This is the default.
|
||||
|
@ -171,6 +172,16 @@ See
|
|||
Parse only: produce no output.
|
||||
Implies
|
||||
.Fl W Ns Cm warning .
|
||||
.It Fl T Ns Cm locale
|
||||
Encode output using the current locale.
|
||||
See
|
||||
.Sx Locale Output .
|
||||
.It Fl T Ns Cm man
|
||||
Produce
|
||||
.Xr man 7
|
||||
format output.
|
||||
See
|
||||
.Sx Man Output .
|
||||
.It Fl T Ns Cm pdf
|
||||
Produce PDF output.
|
||||
See
|
||||
|
@ -181,6 +192,10 @@ See
|
|||
.Sx PostScript Output .
|
||||
.It Fl T Ns Cm tree
|
||||
Produce an indented parse tree.
|
||||
.It Fl T Ns Cm utf8
|
||||
Encode output in the UTF\-8 multi-byte format.
|
||||
See
|
||||
.Sx UTF\-8 Output .
|
||||
.It Fl T Ns Cm xhtml
|
||||
Produce strict CSS1/XHTML-1.0 output.
|
||||
See
|
||||
|
@ -209,6 +224,9 @@ Emboldened characters are rendered as
|
|||
The special characters documented in
|
||||
.Xr mandoc_char 7
|
||||
are rendered best-effort in an ASCII equivalent.
|
||||
If no equivalent is found,
|
||||
.Sq \&?
|
||||
is used instead.
|
||||
.Pp
|
||||
Output width is limited to 78 visible columns unless literal input lines
|
||||
exceed this limit.
|
||||
|
@ -217,6 +235,15 @@ The following
|
|||
.Fl O
|
||||
arguments are accepted:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm indent Ns = Ns Ar indent
|
||||
The left margin for normal text is set to
|
||||
.Ar indent
|
||||
blank characters instead of the default of five for
|
||||
.Xr mdoc 7
|
||||
and seven for
|
||||
.Xr man 7 .
|
||||
Increasing this is not recommended; it may result in degraded formatting,
|
||||
for example overfull lines or ugly line breaks.
|
||||
.It Cm width Ns = Ns Ar width
|
||||
The output width is set to
|
||||
.Ar width ,
|
||||
|
@ -236,12 +263,27 @@ If a style-sheet is not specified with
|
|||
defaults to simple output readable in any graphical or text-based web
|
||||
browser.
|
||||
.Pp
|
||||
Special characters are rendered in decimal-encoded UTF-8.
|
||||
Special characters are rendered in decimal-encoded UTF\-8.
|
||||
.Pp
|
||||
The following
|
||||
.Fl O
|
||||
arguments are accepted:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm fragment
|
||||
Omit the
|
||||
.Aq !DOCTYPE
|
||||
declaration and the
|
||||
.Aq html ,
|
||||
.Aq head ,
|
||||
and
|
||||
.Aq body
|
||||
elements and only emit the subtree below the
|
||||
.Aq body
|
||||
element.
|
||||
The
|
||||
.Cm style
|
||||
argument will be ignored.
|
||||
This is useful when embedding manual content within existing documents.
|
||||
.It Cm includes Ns = Ns Ar fmt
|
||||
The string
|
||||
.Ar fmt ,
|
||||
|
@ -278,6 +320,48 @@ is used for an external style-sheet.
|
|||
This must be a valid absolute or
|
||||
relative URI.
|
||||
.El
|
||||
.Ss Locale Output
|
||||
Locale-depending output encoding is triggered with
|
||||
.Fl T Ns Cm locale .
|
||||
This option is not available on all systems: systems without locale
|
||||
support, or those whose internal representation is not natively UCS-4,
|
||||
will fall back to
|
||||
.Fl T Ns Cm ascii .
|
||||
See
|
||||
.Sx ASCII Output
|
||||
for font style specification and available command-line arguments.
|
||||
.Ss Man Output
|
||||
Translate input format into
|
||||
.Xr man 7
|
||||
output format.
|
||||
This is useful for distributing manual sources to legancy systems
|
||||
lacking
|
||||
.Xr mdoc 7
|
||||
formatters.
|
||||
.Pp
|
||||
If
|
||||
.Xr mdoc 7
|
||||
is passed as input, it is translated into
|
||||
.Xr man 7 .
|
||||
If the input format is
|
||||
.Xr man 7 ,
|
||||
the input is copied to the output, expanding any
|
||||
.Xr roff 7
|
||||
.Sq so
|
||||
requests.
|
||||
The parser is also run, and as usual, the
|
||||
.Fl W
|
||||
level controls which
|
||||
.Sx DIAGNOSTICS
|
||||
are displayed before copying the input to the output.
|
||||
.Ss PDF Output
|
||||
PDF-1.1 output may be generated by
|
||||
.Fl T Ns Cm pdf .
|
||||
See
|
||||
.Sx PostScript Output
|
||||
for
|
||||
.Fl O
|
||||
arguments and defaults.
|
||||
.Ss PostScript Output
|
||||
PostScript
|
||||
.Qq Adobe-3.0
|
||||
|
@ -312,14 +396,13 @@ If an unknown value is encountered,
|
|||
.Ar letter
|
||||
is used.
|
||||
.El
|
||||
.Ss PDF Output
|
||||
PDF-1.1 output may be generated by
|
||||
.Fl T Ns Cm pdf .
|
||||
.Ss UTF\-8 Output
|
||||
Use
|
||||
.Fl T Ns Cm utf8
|
||||
to force a UTF\-8 locale.
|
||||
See
|
||||
.Sx PostScript Output
|
||||
for
|
||||
.Fl O
|
||||
arguments and defaults.
|
||||
.Sx Locale Output
|
||||
for details and options.
|
||||
.Ss XHTML Output
|
||||
Output produced by
|
||||
.Fl T Ns Cm xhtml
|
||||
|
@ -389,6 +472,16 @@ To check over a large set of manuals:
|
|||
To produce a series of PostScript manuals for A4 paper:
|
||||
.Pp
|
||||
.Dl $ mandoc \-Tps \-Opaper=a4 mdoc.7 man.7 \*(Gt manuals.ps
|
||||
.Pp
|
||||
Convert a modern
|
||||
.Xr mdoc 7
|
||||
manual to the older
|
||||
.Xr man 7
|
||||
format, for use on systems lacking an
|
||||
.Xr mdoc 7
|
||||
parser:
|
||||
.Pp
|
||||
.Dl $ mandoc \-Tman foo.mdoc \*(Gt foo.man
|
||||
.Sh DIAGNOSTICS
|
||||
Standard error messages reporting parsing errors are prefixed by
|
||||
.Pp
|
||||
|
@ -460,6 +553,13 @@ Each input and output format is separately noted.
|
|||
.Ss ASCII Compatibility
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Unrenderable unicode codepoints specified with
|
||||
.Sq \e[uNNNN]
|
||||
escapes are printed as
|
||||
.Sq \&?
|
||||
in mandoc.
|
||||
In GNU troff, these raise an error.
|
||||
.It
|
||||
The
|
||||
.Sq \&Bd \-literal
|
||||
and
|
||||
|
@ -470,7 +570,7 @@ in
|
|||
.Fl T Ns Cm ascii
|
||||
are synonyms, as are \-filled and \-ragged.
|
||||
.It
|
||||
In GNU troff, the
|
||||
In historic GNU troff, the
|
||||
.Sq \&Pa
|
||||
.Xr mdoc 7
|
||||
macro does not underline when scoped under an
|
||||
|
@ -495,8 +595,6 @@ macro in
|
|||
has no effect.
|
||||
.It
|
||||
Words aren't hyphenated.
|
||||
.It
|
||||
Sentences are unilaterally monospaced.
|
||||
.El
|
||||
.Ss HTML/XHTML Compatibility
|
||||
.Bl -bullet -compact
|
||||
|
@ -529,6 +627,7 @@ and
|
|||
lists render similarly.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr eqn 7 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
|
@ -538,7 +637,8 @@ lists render similarly.
|
|||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
In
|
||||
.Fl T Ns Cm html
|
||||
|
|
600
external/bsd/mdocml/dist/mandoc.3
vendored
Normal file
600
external/bsd/mdocml/dist/mandoc.3
vendored
Normal file
|
@ -0,0 +1,600 @@
|
|||
.\" $Vendor-Id: mandoc.3,v 1.17 2012/01/13 15:27:14 joerg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010 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.
|
||||
.\"
|
||||
.Dd January 13, 2012
|
||||
.Dt MANDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc ,
|
||||
.Nm mandoc_escape ,
|
||||
.Nm man_meta ,
|
||||
.Nm man_mparse ,
|
||||
.Nm man_node ,
|
||||
.Nm mchars_alloc ,
|
||||
.Nm mchars_free ,
|
||||
.Nm mchars_num2char ,
|
||||
.Nm mchars_num2uc ,
|
||||
.Nm mchars_spec2cp ,
|
||||
.Nm mchars_spec2str ,
|
||||
.Nm mdoc_meta ,
|
||||
.Nm mdoc_node ,
|
||||
.Nm mparse_alloc ,
|
||||
.Nm mparse_free ,
|
||||
.Nm mparse_getkeep ,
|
||||
.Nm mparse_keep ,
|
||||
.Nm mparse_readfd ,
|
||||
.Nm mparse_reset ,
|
||||
.Nm mparse_result ,
|
||||
.Nm mparse_strerror ,
|
||||
.Nm mparse_strlevel
|
||||
.Nd mandoc macro compiler library
|
||||
.Sh LIBRARY
|
||||
.Lb mandoc
|
||||
.Sh SYNOPSIS
|
||||
.In man.h
|
||||
.In mdoc.h
|
||||
.In mandoc.h
|
||||
.Ft "enum mandoc_esc"
|
||||
.Fo mandoc_escape
|
||||
.Fa "const char **end"
|
||||
.Fa "const char **start"
|
||||
.Fa "int *sz"
|
||||
.Fc
|
||||
.Ft "const struct man_meta *"
|
||||
.Fo man_meta
|
||||
.Fa "const struct man *man"
|
||||
.Fc
|
||||
.Ft "const struct mparse *"
|
||||
.Fo man_mparse
|
||||
.Fa "const struct man *man"
|
||||
.Fc
|
||||
.Ft "const struct man_node *"
|
||||
.Fo man_node
|
||||
.Fa "const struct man *man"
|
||||
.Fc
|
||||
.Ft "struct mchars *"
|
||||
.Fn mchars_alloc
|
||||
.Ft void
|
||||
.Fn mchars_free "struct mchars *p"
|
||||
.Ft char
|
||||
.Fn mchars_num2char "const char *cp" "size_t sz"
|
||||
.Ft int
|
||||
.Fn mchars_num2uc "const char *cp" "size_t sz"
|
||||
.Ft "const char *"
|
||||
.Fo mchars_spec2str
|
||||
.Fa "const struct mchars *p"
|
||||
.Fa "const char *cp"
|
||||
.Fa "size_t sz"
|
||||
.Fa "size_t *rsz"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo mchars_spec2cp
|
||||
.Fa "const struct mchars *p"
|
||||
.Fa "const char *cp"
|
||||
.Fa "size_t sz"
|
||||
.Ft "const char *"
|
||||
.Fc
|
||||
.Ft "const struct mdoc_meta *"
|
||||
.Fo mdoc_meta
|
||||
.Fa "const struct mdoc *mdoc"
|
||||
.Fc
|
||||
.Ft "const struct mdoc_node *"
|
||||
.Fo mdoc_node
|
||||
.Fa "const struct mdoc *mdoc"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_alloc
|
||||
.Fa "enum mparset type"
|
||||
.Fa "enum mandoclevel wlevel"
|
||||
.Fa "mandocmsg msg"
|
||||
.Fa "void *msgarg"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_free
|
||||
.Fa "struct mparse *parse"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_getkeep
|
||||
.Fa "const struct mparse *parse"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_keep
|
||||
.Fa "struct mparse *parse"
|
||||
.Fc
|
||||
.Ft "enum mandoclevel"
|
||||
.Fo mparse_readfd
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "int fd"
|
||||
.Fa "const char *fname"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_reset
|
||||
.Fa "struct mparse *parse"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo mparse_result
|
||||
.Fa "struct mparse *parse"
|
||||
.Fa "struct mdoc **mdoc"
|
||||
.Fa "struct man **man"
|
||||
.Fc
|
||||
.Ft "const char *"
|
||||
.Fo mparse_strerror
|
||||
.Fa "enum mandocerr"
|
||||
.Fc
|
||||
.Ft "const char *"
|
||||
.Fo mparse_strlevel
|
||||
.Fa "enum mandoclevel"
|
||||
.Fc
|
||||
.Vt extern const char * const * man_macronames;
|
||||
.Vt extern const char * const * mdoc_argnames;
|
||||
.Vt extern const char * const * mdoc_macronames;
|
||||
.Fd "#define ASCII_NBRSP"
|
||||
.Fd "#define ASCII_HYPH"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mandoc
|
||||
library parses a
|
||||
.Ux
|
||||
manual into an abstract syntax tree (AST).
|
||||
.Ux
|
||||
manuals are composed of
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7 ,
|
||||
and may be mixed with
|
||||
.Xr roff 7 ,
|
||||
.Xr tbl 7 ,
|
||||
and
|
||||
.Xr eqn 7
|
||||
invocations.
|
||||
.Pp
|
||||
The following describes a general parse sequence:
|
||||
.Bl -enum
|
||||
.It
|
||||
initiate a parsing sequence with
|
||||
.Fn mparse_alloc ;
|
||||
.It
|
||||
parse files or file descriptors with
|
||||
.Fn mparse_readfd ;
|
||||
.It
|
||||
retrieve a parsed syntax tree, if the parse was successful, with
|
||||
.Fn mparse_result ;
|
||||
.It
|
||||
iterate over parse nodes with
|
||||
.Fn mdoc_node
|
||||
or
|
||||
.Fn man_node ;
|
||||
.It
|
||||
free all allocated memory with
|
||||
.Fn mparse_free ,
|
||||
or invoke
|
||||
.Fn mparse_reset
|
||||
and parse new files.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
library also contains routines for translating character strings into glyphs
|
||||
.Pq see Fn mchars_alloc
|
||||
and parsing escape sequences from strings
|
||||
.Pq see Fn mandoc_escape .
|
||||
.Sh REFERENCE
|
||||
This section documents the functions, types, and variables available
|
||||
via
|
||||
.In mandoc.h .
|
||||
.Ss Types
|
||||
.Bl -ohang
|
||||
.It Vt "enum mandoc_esc"
|
||||
An escape sequence classification.
|
||||
.It Vt "enum mandocerr"
|
||||
A fatal error, error, or warning message during parsing.
|
||||
.It Vt "enum mandoclevel"
|
||||
A classification of an
|
||||
.Vt "enum mandoclevel"
|
||||
as regards system operation.
|
||||
.It Vt "struct mchars"
|
||||
An opaque pointer to an object allowing for translation between
|
||||
character strings and glyphs.
|
||||
See
|
||||
.Fn mchars_alloc .
|
||||
.It Vt "enum mparset"
|
||||
The type of parser when reading input.
|
||||
This should usually be
|
||||
.Dv MPARSE_AUTO
|
||||
for auto-detection.
|
||||
.It Vt "struct mparse"
|
||||
An opaque pointer to a running parse sequence.
|
||||
Created with
|
||||
.Fn mparse_alloc
|
||||
and freed with
|
||||
.Fn mparse_free .
|
||||
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 fatal error, error, and warning
|
||||
messages emitted by the parser.
|
||||
.El
|
||||
.Ss Functions
|
||||
.Bl -ohang
|
||||
.It Fn mandoc_escape
|
||||
Scan an escape sequence, i.e., a character string beginning with
|
||||
.Sq \e .
|
||||
Pass a pointer to the character after the
|
||||
.Sq \e
|
||||
as
|
||||
.Va end ;
|
||||
it will be set to the supremum of the parsed escape sequence unless
|
||||
returning
|
||||
.Dv ESCAPE_ERROR ,
|
||||
in which case the string is bogus and should be
|
||||
thrown away.
|
||||
If not
|
||||
.Dv ESCAPE_ERROR
|
||||
or
|
||||
.Dv ESCAPE_IGNORE ,
|
||||
.Va start
|
||||
is set to the first relevant character of the substring (font, glyph,
|
||||
whatever) of length
|
||||
.Va sz .
|
||||
Both
|
||||
.Va start
|
||||
and
|
||||
.Va sz
|
||||
may be
|
||||
.Dv NULL .
|
||||
.It Fn man_meta
|
||||
Obtain the meta-data of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
.It Fn man_mparse
|
||||
Get the parser used for the current output.
|
||||
.It Fn man_node
|
||||
Obtain the root node of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
.It Fn mchars_alloc
|
||||
Allocate an
|
||||
.Vt "struct mchars *"
|
||||
object for translating special characters into glyphs.
|
||||
See
|
||||
.Xr mandoc_char 7
|
||||
for an overview of special characters.
|
||||
The object must be freed with
|
||||
.Fn mchars_free .
|
||||
.It Fn mchars_free
|
||||
Free an object created with
|
||||
.Fn mchars_alloc .
|
||||
.It Fn mchars_num2char
|
||||
Convert a character index (e.g., the \eN\(aq\(aq escape) into a
|
||||
printable ASCII character.
|
||||
Returns \e0 (the nil character) if the input sequence is malformed.
|
||||
.It Fn mchars_num2uc
|
||||
Convert a hexadecimal character index (e.g., the \e[uNNNN] escape) into
|
||||
a Unicode codepoint.
|
||||
Returns \e0 (the nil character) if the input sequence is malformed.
|
||||
.It Fn mchars_spec2cp
|
||||
Convert a special character into a valid Unicode codepoint.
|
||||
Returns \-1 on failure or a non-zero Unicode codepoint on success.
|
||||
.It Fn mchars_spec2str
|
||||
Convert a special character into an ASCII string.
|
||||
Returns
|
||||
.Dv NULL
|
||||
on failure.
|
||||
.It Fn mdoc_meta
|
||||
Obtain the meta-data of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
.It Fn mdoc_node
|
||||
Obtain the root node of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
.It Fn mparse_alloc
|
||||
Allocate a parser.
|
||||
The same parser may be used for multiple files so long as
|
||||
.Fn mparse_reset
|
||||
is called between parses.
|
||||
.Fn mparse_free
|
||||
must be called to free the memory allocated by this function.
|
||||
.It Fn mparse_free
|
||||
Free all memory allocated by
|
||||
.Fn mparse_alloc .
|
||||
.It Fn mparse_getkeep
|
||||
Acquire the keep buffer.
|
||||
Must follow a call of
|
||||
.Fn mparse_keep .
|
||||
.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_readfd
|
||||
Parse a file or file descriptor.
|
||||
If
|
||||
.Va fd
|
||||
is -1,
|
||||
.Va fname
|
||||
is opened for reading.
|
||||
Otherwise,
|
||||
.Va fname
|
||||
is assumed to be the name associated with
|
||||
.Va fd .
|
||||
This may be called multiple times with different parameters; however,
|
||||
.Fn mparse_reset
|
||||
should be invoked between parses.
|
||||
.It Fn mparse_reset
|
||||
Reset a parser so that
|
||||
.Fn mparse_readfd
|
||||
may be used again.
|
||||
.It Fn mparse_result
|
||||
Obtain the result of a parse.
|
||||
Only successful parses
|
||||
.Po
|
||||
i.e., those where
|
||||
.Fn mparse_readfd
|
||||
returned less than MANDOCLEVEL_FATAL
|
||||
.Pc
|
||||
should invoke this function, in which case one of the two pointers will
|
||||
be filled in.
|
||||
.It Fn mparse_strerror
|
||||
Return a statically-allocated string representation of an error code.
|
||||
.It Fn mparse_strlevel
|
||||
Return a statically-allocated string representation of a level code.
|
||||
.El
|
||||
.Ss Variables
|
||||
.Bl -ohang
|
||||
.It Va man_macronames
|
||||
The string representation of a man macro as indexed by
|
||||
.Vt "enum mant" .
|
||||
.It Va mdoc_argnames
|
||||
The string representation of a mdoc macro argument as indexed by
|
||||
.Vt "enum mdocargt" .
|
||||
.It Va mdoc_macronames
|
||||
The string representation of a mdoc macro as indexed by
|
||||
.Vt "enum mdoct" .
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
This section consists of structural documentation for
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
syntax trees and strings.
|
||||
.Ss Man and Mdoc Strings
|
||||
Strings may be extracted from mdoc and man meta-data, or from text
|
||||
nodes (MDOC_TEXT and MAN_TEXT, respectively).
|
||||
These strings have special non-printing formatting cues embedded in the
|
||||
text itself, as well as
|
||||
.Xr roff 7
|
||||
escapes preserved from input.
|
||||
Implementing systems will need to handle both situations to produce
|
||||
human-readable text.
|
||||
In general, strings may be assumed to consist of 7-bit ASCII characters.
|
||||
.Pp
|
||||
The following non-printing characters may be embedded in text strings:
|
||||
.Bl -tag -width Ds
|
||||
.It Dv ASCII_NBRSP
|
||||
A non-breaking space character.
|
||||
.It Dv ASCII_HYPH
|
||||
A soft hyphen.
|
||||
.El
|
||||
.Pp
|
||||
Escape characters are also passed verbatim into text strings.
|
||||
An escape character is a sequence of characters beginning with the
|
||||
backslash
|
||||
.Pq Sq \e .
|
||||
To construct human-readable text, these should be intercepted with
|
||||
.Fn mandoc_escape
|
||||
and converted with one of
|
||||
.Fn mchars_num2char ,
|
||||
.Fn mchars_spec2str ,
|
||||
and so on.
|
||||
.Ss Man Abstract Syntax Tree
|
||||
This AST is governed by the ontological rules dictated in
|
||||
.Xr man 7
|
||||
and derives its terminology accordingly.
|
||||
.Pp
|
||||
The AST is composed of
|
||||
.Vt struct man_node
|
||||
nodes with element, root and text types as declared by the
|
||||
.Va type
|
||||
field.
|
||||
Each node also provides its parse point (the
|
||||
.Va line ,
|
||||
.Va sec ,
|
||||
and
|
||||
.Va pos
|
||||
fields), its position in the tree (the
|
||||
.Va parent ,
|
||||
.Va child ,
|
||||
.Va next
|
||||
and
|
||||
.Va prev
|
||||
fields) and some type-specific data.
|
||||
.Pp
|
||||
The tree itself is arranged according to the following normal form,
|
||||
where capitalised non-terminals represent nodes.
|
||||
.Pp
|
||||
.Bl -tag -width "ELEMENTXX" -compact
|
||||
.It ROOT
|
||||
\(<- mnode+
|
||||
.It mnode
|
||||
\(<- ELEMENT | TEXT | BLOCK
|
||||
.It BLOCK
|
||||
\(<- HEAD BODY
|
||||
.It HEAD
|
||||
\(<- mnode*
|
||||
.It BODY
|
||||
\(<- mnode*
|
||||
.It ELEMENT
|
||||
\(<- ELEMENT | TEXT*
|
||||
.It TEXT
|
||||
\(<- [[:ascii:]]*
|
||||
.El
|
||||
.Pp
|
||||
The only elements capable of nesting other elements are those with
|
||||
next-lint scope as documented in
|
||||
.Xr man 7 .
|
||||
.Ss Mdoc Abstract Syntax Tree
|
||||
This AST is governed by the ontological
|
||||
rules dictated in
|
||||
.Xr mdoc 7
|
||||
and derives its terminology accordingly.
|
||||
.Qq In-line
|
||||
elements described in
|
||||
.Xr mdoc 7
|
||||
are described simply as
|
||||
.Qq elements .
|
||||
.Pp
|
||||
The AST is composed of
|
||||
.Vt struct mdoc_node
|
||||
nodes with block, head, body, element, root and text types as declared
|
||||
by the
|
||||
.Va type
|
||||
field.
|
||||
Each node also provides its parse point (the
|
||||
.Va line ,
|
||||
.Va sec ,
|
||||
and
|
||||
.Va pos
|
||||
fields), its position in the tree (the
|
||||
.Va parent ,
|
||||
.Va child ,
|
||||
.Va nchild ,
|
||||
.Va next
|
||||
and
|
||||
.Va prev
|
||||
fields) and some type-specific data, in particular, for nodes generated
|
||||
from macros, the generating macro in the
|
||||
.Va tok
|
||||
field.
|
||||
.Pp
|
||||
The tree itself is arranged according to the following normal form,
|
||||
where capitalised non-terminals represent nodes.
|
||||
.Pp
|
||||
.Bl -tag -width "ELEMENTXX" -compact
|
||||
.It ROOT
|
||||
\(<- mnode+
|
||||
.It mnode
|
||||
\(<- BLOCK | ELEMENT | TEXT
|
||||
.It BLOCK
|
||||
\(<- HEAD [TEXT] (BODY [TEXT])+ [TAIL [TEXT]]
|
||||
.It ELEMENT
|
||||
\(<- TEXT*
|
||||
.It HEAD
|
||||
\(<- mnode*
|
||||
.It BODY
|
||||
\(<- mnode* [ENDBODY mnode*]
|
||||
.It TAIL
|
||||
\(<- mnode*
|
||||
.It TEXT
|
||||
\(<- [[:ascii:]]*
|
||||
.El
|
||||
.Pp
|
||||
Of note are the TEXT nodes following the HEAD, BODY and TAIL nodes of
|
||||
the BLOCK production: these refer to punctuation marks.
|
||||
Furthermore, although a TEXT node will generally have a non-zero-length
|
||||
string, in the specific case of
|
||||
.Sq \&.Bd \-literal ,
|
||||
an empty line will produce a zero-length string.
|
||||
Multiple body parts are only found in invocations of
|
||||
.Sq \&Bl \-column ,
|
||||
where a new body introduces a new phrase.
|
||||
.Pp
|
||||
The
|
||||
.Xr mdoc 7
|
||||
syntax tree accommodates for broken block structures as well.
|
||||
The ENDBODY node is available to end the formatting associated
|
||||
with a given block before the physical end of that block.
|
||||
It has a non-null
|
||||
.Va end
|
||||
field, is of the BODY
|
||||
.Va type ,
|
||||
has the same
|
||||
.Va tok
|
||||
as the BLOCK it is ending, and has a
|
||||
.Va pending
|
||||
field pointing to that BLOCK's BODY node.
|
||||
It is an indirect child of that BODY node
|
||||
and has no children of its own.
|
||||
.Pp
|
||||
An ENDBODY node is generated when a block ends while one of its child
|
||||
blocks is still open, like in the following example:
|
||||
.Bd -literal -offset indent
|
||||
\&.Ao ao
|
||||
\&.Bo bo ac
|
||||
\&.Ac bc
|
||||
\&.Bc end
|
||||
.Ed
|
||||
.Pp
|
||||
This example results in the following block structure:
|
||||
.Bd -literal -offset indent
|
||||
BLOCK Ao
|
||||
HEAD Ao
|
||||
BODY Ao
|
||||
TEXT ao
|
||||
BLOCK Bo, pending -> Ao
|
||||
HEAD Bo
|
||||
BODY Bo
|
||||
TEXT bo
|
||||
TEXT ac
|
||||
ENDBODY Ao, pending -> Ao
|
||||
TEXT bc
|
||||
TEXT end
|
||||
.Ed
|
||||
.Pp
|
||||
Here, the formatting of the
|
||||
.Sq \&Ao
|
||||
block extends from TEXT ao to TEXT ac,
|
||||
while the formatting of the
|
||||
.Sq \&Bo
|
||||
block extends from TEXT bo to TEXT bc.
|
||||
It renders as follows in
|
||||
.Fl T Ns Cm ascii
|
||||
mode:
|
||||
.Pp
|
||||
.Dl <ao [bo ac> bc] end
|
||||
.Pp
|
||||
Support for badly-nested blocks is only provided for backward
|
||||
compatibility with some older
|
||||
.Xr mdoc 7
|
||||
implementations.
|
||||
Using badly-nested blocks is
|
||||
.Em strongly discouraged ;
|
||||
for example, the
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml
|
||||
front-ends to
|
||||
.Xr mandoc 1
|
||||
are unable to render them in any meaningful way.
|
||||
Furthermore, behaviour when encountering badly-nested blocks is not
|
||||
consistent across troff implementations, especially when using multiple
|
||||
levels of badly-nested blocks.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr eqn 7 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7 ,
|
||||
.Xr tbl 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
668
external/bsd/mdocml/dist/mandoc.c
vendored
668
external/bsd/mdocml/dist/mandoc.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mandoc.c,v 1.36 2011/01/03 22:42:37 schwarze Exp $ */
|
||||
/* $Vendor-Id: mandoc.c,v 1.62 2011/12/03 16:08:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -31,200 +33,384 @@
|
|||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
#define DATESIZE 32
|
||||
|
||||
static int a2time(time_t *, const char *, const char *);
|
||||
static char *time2a(time_t);
|
||||
static int numescape(const char *);
|
||||
|
||||
|
||||
int
|
||||
mandoc_special(char *p)
|
||||
/*
|
||||
* Pass over recursive numerical expressions. This context of this
|
||||
* function is important: it's only called within character-terminating
|
||||
* escapes (e.g., \s[xxxyyy]), so all we need to do is handle initial
|
||||
* recursion: we don't care about what's in these blocks.
|
||||
* This returns the number of characters skipped or -1 if an error
|
||||
* occurs (the caller should bail).
|
||||
*/
|
||||
static int
|
||||
numescape(const char *start)
|
||||
{
|
||||
int len, i;
|
||||
char term;
|
||||
char *sv;
|
||||
|
||||
len = 0;
|
||||
term = '\0';
|
||||
sv = p;
|
||||
|
||||
assert('\\' == *p);
|
||||
p++;
|
||||
|
||||
switch (*p++) {
|
||||
#if 0
|
||||
case ('Z'):
|
||||
/* FALLTHROUGH */
|
||||
case ('X'):
|
||||
/* FALLTHROUGH */
|
||||
case ('x'):
|
||||
/* FALLTHROUGH */
|
||||
case ('S'):
|
||||
/* FALLTHROUGH */
|
||||
case ('R'):
|
||||
/* FALLTHROUGH */
|
||||
case ('N'):
|
||||
/* FALLTHROUGH */
|
||||
case ('l'):
|
||||
/* FALLTHROUGH */
|
||||
case ('L'):
|
||||
/* FALLTHROUGH */
|
||||
case ('H'):
|
||||
/* FALLTHROUGH */
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('D'):
|
||||
/* FALLTHROUGH */
|
||||
case ('C'):
|
||||
/* FALLTHROUGH */
|
||||
case ('b'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
/* FALLTHROUGH */
|
||||
case ('a'):
|
||||
/* FALLTHROUGH */
|
||||
case ('A'):
|
||||
if (*p++ != '\'')
|
||||
return(0);
|
||||
term = '\'';
|
||||
break;
|
||||
#endif
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* FALLTHROUGH */
|
||||
case ('s'):
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
int i;
|
||||
size_t sz;
|
||||
const char *cp;
|
||||
|
||||
i = 0;
|
||||
if ('+' == *p || '-' == *p) {
|
||||
p++;
|
||||
i = 1;
|
||||
|
||||
/* The expression consists of a subexpression. */
|
||||
|
||||
if ('\\' == start[i]) {
|
||||
cp = &start[++i];
|
||||
/*
|
||||
* Read past the end of the subexpression.
|
||||
* Bail immediately on errors.
|
||||
*/
|
||||
if (ESCAPE_ERROR == mandoc_escape(&cp, NULL, NULL))
|
||||
return(-1);
|
||||
return(i + cp - &start[i]);
|
||||
}
|
||||
|
||||
switch (*p++) {
|
||||
if ('(' != start[i++])
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* A parenthesised subexpression. Read until the closing
|
||||
* parenthesis, making sure to handle any nested subexpressions
|
||||
* that might ruin our parse.
|
||||
*/
|
||||
|
||||
while (')' != start[i]) {
|
||||
sz = strcspn(&start[i], ")\\");
|
||||
i += (int)sz;
|
||||
|
||||
if ('\0' == start[i])
|
||||
return(-1);
|
||||
else if ('\\' != start[i])
|
||||
continue;
|
||||
|
||||
cp = &start[++i];
|
||||
if (ESCAPE_ERROR == mandoc_escape(&cp, NULL, NULL))
|
||||
return(-1);
|
||||
i += cp - &start[i];
|
||||
}
|
||||
|
||||
/* Read past the terminating ')'. */
|
||||
return(++i);
|
||||
}
|
||||
|
||||
enum mandoc_esc
|
||||
mandoc_escape(const char **end, const char **start, int *sz)
|
||||
{
|
||||
char c, term, numeric;
|
||||
int i, lim, ssz, rlim;
|
||||
const char *cp, *rstart;
|
||||
enum mandoc_esc gly;
|
||||
|
||||
cp = *end;
|
||||
rstart = cp;
|
||||
if (start)
|
||||
*start = rstart;
|
||||
i = lim = 0;
|
||||
gly = ESCAPE_ERROR;
|
||||
term = numeric = '\0';
|
||||
|
||||
switch ((c = cp[i++])) {
|
||||
/*
|
||||
* First the glyphs. There are several different forms of
|
||||
* these, but each eventually returns a substring of the glyph
|
||||
* name.
|
||||
*/
|
||||
case ('('):
|
||||
len = 2;
|
||||
gly = ESCAPE_SPECIAL;
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
gly = ESCAPE_SPECIAL;
|
||||
/*
|
||||
* Unicode escapes are defined in groff as \[uXXXX] to
|
||||
* \[u10FFFF], where the contained value must be a valid
|
||||
* Unicode codepoint. Here, however, only check whether
|
||||
* it's not a zero-width escape.
|
||||
*/
|
||||
if ('u' == cp[i] && ']' != cp[i + 1])
|
||||
gly = ESCAPE_UNICODE;
|
||||
term = ']';
|
||||
break;
|
||||
case ('\''):
|
||||
case ('C'):
|
||||
if ('\'' != cp[i])
|
||||
return(ESCAPE_ERROR);
|
||||
gly = ESCAPE_SPECIAL;
|
||||
term = '\'';
|
||||
break;
|
||||
case ('0'):
|
||||
i = 1;
|
||||
|
||||
/*
|
||||
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
|
||||
* 'X' is the trigger. These have opaque sub-strings.
|
||||
*/
|
||||
case ('F'):
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
len = 1;
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
if ('+' == *p || '-' == *p) {
|
||||
if (i)
|
||||
return(0);
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Handle embedded numerical subexp or escape. */
|
||||
|
||||
if ('(' == *p) {
|
||||
while (*p && ')' != *p)
|
||||
if ('\\' == *p++) {
|
||||
i = mandoc_special(--p);
|
||||
if (0 == i)
|
||||
return(0);
|
||||
p += i;
|
||||
}
|
||||
|
||||
if (')' == *p++)
|
||||
break;
|
||||
|
||||
return(0);
|
||||
} else if ('\\' == *p) {
|
||||
if (0 == (i = mandoc_special(p)))
|
||||
return(0);
|
||||
p += i;
|
||||
}
|
||||
|
||||
break;
|
||||
#if 0
|
||||
case ('Y'):
|
||||
case ('g'):
|
||||
/* FALLTHROUGH */
|
||||
case ('V'):
|
||||
/* FALLTHROUGH */
|
||||
case ('$'):
|
||||
/* FALLTHROUGH */
|
||||
case ('n'):
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case ('k'):
|
||||
/* FALLTHROUGH */
|
||||
case ('M'):
|
||||
/* FALLTHROUGH */
|
||||
case ('m'):
|
||||
/* FALLTHROUGH */
|
||||
case ('n'):
|
||||
/* FALLTHROUGH */
|
||||
case ('V'):
|
||||
/* FALLTHROUGH */
|
||||
case ('Y'):
|
||||
gly = ESCAPE_IGNORE;
|
||||
/* FALLTHROUGH */
|
||||
case ('f'):
|
||||
/* FALLTHROUGH */
|
||||
case ('F'):
|
||||
/* FALLTHROUGH */
|
||||
case ('*'):
|
||||
switch (*p++) {
|
||||
if (ESCAPE_ERROR == gly)
|
||||
gly = ESCAPE_FONT;
|
||||
|
||||
rstart= &cp[i];
|
||||
if (start)
|
||||
*start = rstart;
|
||||
|
||||
switch (cp[i++]) {
|
||||
case ('('):
|
||||
len = 2;
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
len = 1;
|
||||
p--;
|
||||
lim = 1;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ('('):
|
||||
len = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('z'):
|
||||
len = 1;
|
||||
if ('\\' == *p) {
|
||||
if (0 == (i = mandoc_special(p)))
|
||||
return(0);
|
||||
p += i;
|
||||
return(*p ? (int)(p - sv) : 0);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* These escapes are of the form \X'Y', where 'X' is the trigger
|
||||
* and 'Y' is any string. These have opaque sub-strings.
|
||||
*/
|
||||
case ('A'):
|
||||
/* FALLTHROUGH */
|
||||
case ('b'):
|
||||
/* FALLTHROUGH */
|
||||
case ('D'):
|
||||
/* FALLTHROUGH */
|
||||
case ('o'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
if ('\'' == *p++) {
|
||||
case ('R'):
|
||||
/* FALLTHROUGH */
|
||||
case ('X'):
|
||||
/* FALLTHROUGH */
|
||||
case ('Z'):
|
||||
if ('\'' != cp[i++])
|
||||
return(ESCAPE_ERROR);
|
||||
gly = ESCAPE_IGNORE;
|
||||
term = '\'';
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* These escapes are of the form \X'N', where 'X' is the trigger
|
||||
* and 'N' resolves to a numerical expression.
|
||||
*/
|
||||
case ('B'):
|
||||
/* FALLTHROUGH */
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('H'):
|
||||
/* FALLTHROUGH */
|
||||
case ('L'):
|
||||
/* FALLTHROUGH */
|
||||
case ('l'):
|
||||
gly = ESCAPE_NUMBERED;
|
||||
/* FALLTHROUGH */
|
||||
case ('S'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
/* FALLTHROUGH */
|
||||
case ('x'):
|
||||
if (ESCAPE_ERROR == gly)
|
||||
gly = ESCAPE_IGNORE;
|
||||
if ('\'' != cp[i++])
|
||||
return(ESCAPE_ERROR);
|
||||
term = numeric = '\'';
|
||||
break;
|
||||
|
||||
/*
|
||||
* Special handling for the numbered character escape.
|
||||
* XXX Do any other escapes need similar handling?
|
||||
*/
|
||||
case ('N'):
|
||||
if ('\0' == cp[i])
|
||||
return(ESCAPE_ERROR);
|
||||
*end = &cp[++i];
|
||||
if (isdigit((unsigned char)cp[i-1]))
|
||||
return(ESCAPE_IGNORE);
|
||||
while (isdigit((unsigned char)**end))
|
||||
(*end)++;
|
||||
if (start)
|
||||
*start = &cp[i];
|
||||
if (sz)
|
||||
*sz = *end - &cp[i];
|
||||
if ('\0' != **end)
|
||||
(*end)++;
|
||||
return(ESCAPE_NUMBERED);
|
||||
|
||||
/*
|
||||
* Sizes get a special category of their own.
|
||||
*/
|
||||
case ('s'):
|
||||
gly = ESCAPE_IGNORE;
|
||||
|
||||
rstart = &cp[i];
|
||||
if (start)
|
||||
*start = rstart;
|
||||
|
||||
/* See +/- counts as a sign. */
|
||||
c = cp[i];
|
||||
if ('+' == c || '-' == c || ASCII_HYPH == c)
|
||||
++i;
|
||||
|
||||
switch (cp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = numeric = ']';
|
||||
break;
|
||||
case ('\''):
|
||||
term = numeric = '\'';
|
||||
break;
|
||||
default:
|
||||
len = 1;
|
||||
p--;
|
||||
lim = 1;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (term) {
|
||||
for ( ; *p && term != *p; p++)
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
return(*p ? (int)(p - sv) : 0);
|
||||
/* See +/- counts as a sign. */
|
||||
c = cp[i];
|
||||
if ('+' == c || '-' == c || ASCII_HYPH == c)
|
||||
++i;
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
* Anything else is assumed to be a glyph.
|
||||
*/
|
||||
default:
|
||||
gly = ESCAPE_SPECIAL;
|
||||
lim = 1;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; *p && i < len; i++, p++)
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
return(i == len ? (int)(p - sv) : 0);
|
||||
}
|
||||
assert(ESCAPE_ERROR != gly);
|
||||
|
||||
rstart = &cp[i];
|
||||
if (start)
|
||||
*start = rstart;
|
||||
|
||||
/*
|
||||
* If a terminating block has been specified, we need to
|
||||
* handle the case of recursion, which could have their
|
||||
* own terminating blocks that mess up our parse. This, by the
|
||||
* way, means that the "start" and "size" values will be
|
||||
* effectively meaningless.
|
||||
*/
|
||||
|
||||
ssz = 0;
|
||||
if (numeric && -1 == (ssz = numescape(&cp[i])))
|
||||
return(ESCAPE_ERROR);
|
||||
|
||||
i += ssz;
|
||||
rlim = -1;
|
||||
|
||||
/*
|
||||
* We have a character terminator. Try to read up to that
|
||||
* character. If we can't (i.e., we hit the nil), then return
|
||||
* an error; if we can, calculate our length, read past the
|
||||
* terminating character, and exit.
|
||||
*/
|
||||
|
||||
if ('\0' != term) {
|
||||
*end = strchr(&cp[i], term);
|
||||
if ('\0' == *end)
|
||||
return(ESCAPE_ERROR);
|
||||
|
||||
rlim = *end - &cp[i];
|
||||
if (sz)
|
||||
*sz = rlim;
|
||||
(*end)++;
|
||||
goto out;
|
||||
}
|
||||
|
||||
assert(lim > 0);
|
||||
|
||||
/*
|
||||
* We have a numeric limit. If the string is shorter than that,
|
||||
* stop and return an error. Else adjust our endpoint, length,
|
||||
* and return the current glyph.
|
||||
*/
|
||||
|
||||
if ((size_t)lim > strlen(&cp[i]))
|
||||
return(ESCAPE_ERROR);
|
||||
|
||||
rlim = lim;
|
||||
if (sz)
|
||||
*sz = rlim;
|
||||
|
||||
*end = &cp[i] + lim;
|
||||
|
||||
out:
|
||||
assert(rlim >= 0 && rstart);
|
||||
|
||||
/* Run post-processors. */
|
||||
|
||||
switch (gly) {
|
||||
case (ESCAPE_FONT):
|
||||
/*
|
||||
* Pretend that the constant-width font modes are the
|
||||
* same as the regular font modes.
|
||||
*/
|
||||
if (2 == rlim && 'C' == *rstart)
|
||||
rstart++;
|
||||
else if (1 != rlim)
|
||||
break;
|
||||
|
||||
switch (*rstart) {
|
||||
case ('3'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
gly = ESCAPE_FONTBOLD;
|
||||
break;
|
||||
case ('2'):
|
||||
/* FALLTHROUGH */
|
||||
case ('I'):
|
||||
gly = ESCAPE_FONTITALIC;
|
||||
break;
|
||||
case ('P'):
|
||||
gly = ESCAPE_FONTPREV;
|
||||
break;
|
||||
case ('1'):
|
||||
/* FALLTHROUGH */
|
||||
case ('R'):
|
||||
gly = ESCAPE_FONTROMAN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case (ESCAPE_SPECIAL):
|
||||
if (1 != rlim)
|
||||
break;
|
||||
if ('c' == *rstart)
|
||||
gly = ESCAPE_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(gly);
|
||||
}
|
||||
|
||||
void *
|
||||
mandoc_calloc(size_t num, size_t size)
|
||||
|
@ -269,6 +455,16 @@ mandoc_realloc(void *ptr, size_t size)
|
|||
return(ptr);
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_strndup(const char *ptr, size_t sz)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = mandoc_malloc(sz + 1);
|
||||
memcpy(p, ptr, sz);
|
||||
p[(int)sz] = '\0';
|
||||
return(p);
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_strdup(const char *ptr)
|
||||
|
@ -294,18 +490,18 @@ mandoc_strdup(const char *ptr)
|
|||
* or to the null byte terminating the argument line.
|
||||
*/
|
||||
char *
|
||||
mandoc_getarg(char **cpp, mandocmsg msg, void *data, int ln, int *pos)
|
||||
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++;
|
||||
} else
|
||||
quoted = 0;
|
||||
}
|
||||
|
||||
pairs = 0;
|
||||
white = 0;
|
||||
|
@ -341,8 +537,8 @@ mandoc_getarg(char **cpp, mandocmsg msg, void *data, int ln, int *pos)
|
|||
}
|
||||
|
||||
/* Quoted argument without a closing quote. */
|
||||
if (1 == quoted && msg)
|
||||
(*msg)(MANDOCERR_BADQUOTE, data, ln, *pos, NULL);
|
||||
if (1 == quoted)
|
||||
mandoc_msg(MANDOCERR_BADQUOTE, parse, ln, *pos, NULL);
|
||||
|
||||
/* Null-terminate this argument and move to the next one. */
|
||||
if (pairs)
|
||||
|
@ -352,16 +548,15 @@ mandoc_getarg(char **cpp, mandocmsg msg, void *data, int ln, int *pos)
|
|||
while (' ' == *cp)
|
||||
cp++;
|
||||
}
|
||||
*pos += (cp - start) + (quoted ? 1 : 0);
|
||||
*pos += (int)(cp - start) + (quoted ? 1 : 0);
|
||||
*cpp = cp;
|
||||
|
||||
if ('\0' == *cp && msg && (white || ' ' == cp[-1]))
|
||||
(*msg)(MANDOCERR_EOLNSPACE, data, ln, *pos, NULL);
|
||||
if ('\0' == *cp && (white || ' ' == cp[-1]))
|
||||
mandoc_msg(MANDOCERR_EOLNSPACE, parse, ln, *pos, NULL);
|
||||
|
||||
return(start);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
a2time(time_t *t, const char *fmt, const char *p)
|
||||
{
|
||||
|
@ -370,7 +565,10 @@ a2time(time_t *t, const char *fmt, const char *p)
|
|||
|
||||
memset(&tm, 0, sizeof(struct tm));
|
||||
|
||||
pp = NULL;
|
||||
#ifdef HAVE_STRPTIME
|
||||
pp = strptime(p, fmt, &tm);
|
||||
#endif
|
||||
if (NULL != pp && '\0' == *pp) {
|
||||
*t = mktime(&tm);
|
||||
return(1);
|
||||
|
@ -379,41 +577,62 @@ a2time(time_t *t, const char *fmt, const char *p)
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert from a manual date string (see mdoc(7) and man(7)) into a
|
||||
* date according to the stipulated date type.
|
||||
*/
|
||||
time_t
|
||||
mandoc_a2time(int flags, const char *p)
|
||||
static char *
|
||||
time2a(time_t t)
|
||||
{
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
char *buf, *p;
|
||||
size_t ssz;
|
||||
int isz;
|
||||
|
||||
if (MTIME_MDOCDATE & flags) {
|
||||
if (0 == strcmp(p, "$" "Mdocdate$"))
|
||||
return(time(NULL));
|
||||
if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
|
||||
return(t);
|
||||
}
|
||||
tm = localtime(&t);
|
||||
|
||||
if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags)
|
||||
if (a2time(&t, "%b %d, %Y", p))
|
||||
return(t);
|
||||
/*
|
||||
* Reserve space:
|
||||
* up to 9 characters for the month (September) + blank
|
||||
* up to 2 characters for the day + comma + blank
|
||||
* 4 characters for the year and a terminating '\0'
|
||||
*/
|
||||
p = buf = mandoc_malloc(10 + 4 + 4 + 1);
|
||||
|
||||
if (MTIME_ISO_8601 & flags)
|
||||
if (a2time(&t, "%Y-%m-%d", p))
|
||||
return(t);
|
||||
if (0 == (ssz = strftime(p, 10 + 1, "%B ", tm)))
|
||||
goto fail;
|
||||
p += (int)ssz;
|
||||
|
||||
if (MTIME_REDUCED & flags) {
|
||||
if (a2time(&t, "%d, %Y", p))
|
||||
return(t);
|
||||
if (a2time(&t, "%Y", p))
|
||||
return(t);
|
||||
}
|
||||
if (-1 == (isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)))
|
||||
goto fail;
|
||||
p += isz;
|
||||
|
||||
return(0);
|
||||
if (0 == strftime(p, 4 + 1, "%Y", tm))
|
||||
goto fail;
|
||||
return(buf);
|
||||
|
||||
fail:
|
||||
free(buf);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
char *
|
||||
mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
|
||||
{
|
||||
char *out;
|
||||
time_t t;
|
||||
|
||||
if (NULL == in || '\0' == *in ||
|
||||
0 == strcmp(in, "$" "Mdocdate$")) {
|
||||
mandoc_msg(MANDOCERR_NODATE, parse, ln, pos, NULL);
|
||||
time(&t);
|
||||
}
|
||||
else if (a2time(&t, "%Y-%m-%d", in))
|
||||
t = 0;
|
||||
else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) &&
|
||||
!a2time(&t, "%b %d, %Y", in)) {
|
||||
mandoc_msg(MANDOCERR_BADDATE, parse, ln, pos, NULL);
|
||||
t = 0;
|
||||
}
|
||||
out = t ? time2a(t) : NULL;
|
||||
return(out ? out : mandoc_strdup(in));
|
||||
}
|
||||
|
||||
int
|
||||
mandoc_eos(const char *p, size_t sz, int enclosed)
|
||||
|
@ -427,7 +646,7 @@ mandoc_eos(const char *p, size_t sz, int enclosed)
|
|||
/*
|
||||
* End-of-sentence recognition must include situations where
|
||||
* some symbols, such as `)', allow prior EOS punctuation to
|
||||
* propogate outward.
|
||||
* propagate outward.
|
||||
*/
|
||||
|
||||
found = 0;
|
||||
|
@ -458,30 +677,59 @@ mandoc_eos(const char *p, size_t sz, int enclosed)
|
|||
return(found && !enclosed);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mandoc_hyph(const char *start, const char *c)
|
||||
{
|
||||
|
||||
/*
|
||||
* Choose whether to break at a hyphenated character. We only
|
||||
* do this if it's free-standing within a word.
|
||||
/*
|
||||
* Find out whether a line is a macro line or not. If it is, adjust the
|
||||
* current position and return one; if it isn't, return zero and don't
|
||||
* change the current position.
|
||||
*/
|
||||
int
|
||||
mandoc_getcontrol(const char *cp, int *ppos)
|
||||
{
|
||||
int pos;
|
||||
|
||||
/* Skip first/last character of buffer. */
|
||||
if (c == start || '\0' == *(c + 1))
|
||||
return(0);
|
||||
/* Skip first/last character of word. */
|
||||
if ('\t' == *(c + 1) || '\t' == *(c - 1))
|
||||
return(0);
|
||||
if (' ' == *(c + 1) || ' ' == *(c - 1))
|
||||
return(0);
|
||||
/* Skip double invocations. */
|
||||
if ('-' == *(c + 1) || '-' == *(c - 1))
|
||||
return(0);
|
||||
/* Skip escapes. */
|
||||
if ('\\' == *(c - 1))
|
||||
pos = *ppos;
|
||||
|
||||
if ('\\' == cp[pos] && '.' == cp[pos + 1])
|
||||
pos += 2;
|
||||
else if ('.' == cp[pos] || '\'' == cp[pos])
|
||||
pos++;
|
||||
else
|
||||
return(0);
|
||||
|
||||
while (' ' == cp[pos] || '\t' == cp[pos])
|
||||
pos++;
|
||||
|
||||
*ppos = pos;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string to a long that may not be <0.
|
||||
* If the string is invalid, or is less than 0, return -1.
|
||||
*/
|
||||
int
|
||||
mandoc_strntoi(const char *p, size_t sz, int base)
|
||||
{
|
||||
char buf[32];
|
||||
char *ep;
|
||||
long v;
|
||||
|
||||
if (sz > 31)
|
||||
return(-1);
|
||||
|
||||
memcpy(buf, p, sz);
|
||||
buf[(int)sz] = '\0';
|
||||
|
||||
errno = 0;
|
||||
v = strtol(buf, &ep, base);
|
||||
|
||||
if (buf[0] == '\0' || *ep != '\0')
|
||||
return(-1);
|
||||
|
||||
if (v > INT_MAX)
|
||||
v = INT_MAX;
|
||||
if (v < INT_MIN)
|
||||
v = INT_MIN;
|
||||
|
||||
return((int)v);
|
||||
}
|
||||
|
|
207
external/bsd/mdocml/dist/mandoc.h
vendored
207
external/bsd/mdocml/dist/mandoc.h
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: mandoc.h,v 1.49 2011/01/06 13:45:47 kristaps Exp $ */
|
||||
/* $Vendor-Id: mandoc.h,v 1.99 2012/02/16 20:51:31 joerg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -50,7 +50,8 @@ enum mandocerr {
|
|||
MANDOCERR_NOTITLE, /* no title in document */
|
||||
MANDOCERR_UPPERCASE, /* document title should be all caps */
|
||||
MANDOCERR_BADMSEC, /* unknown manual section */
|
||||
MANDOCERR_BADDATE, /* cannot parse date argument */
|
||||
MANDOCERR_NODATE, /* date missing, using today's date */
|
||||
MANDOCERR_BADDATE, /* cannot parse date, using it verbatim */
|
||||
MANDOCERR_PROLOGOOO, /* prologue macros out of order */
|
||||
MANDOCERR_PROLOGREP, /* duplicate prologue macro */
|
||||
MANDOCERR_BADPROLOG, /* macro not allowed in prologue */
|
||||
|
@ -68,10 +69,12 @@ enum mandocerr {
|
|||
/* related to macros and nesting */
|
||||
MANDOCERR_MACROOBS, /* skipping obsolete macro */
|
||||
MANDOCERR_IGNPAR, /* skipping paragraph macro */
|
||||
MANDOCERR_IGNNS, /* skipping no-space macro */
|
||||
MANDOCERR_SCOPENEST, /* blocks badly nested */
|
||||
MANDOCERR_CHILD, /* child violates parent syntax */
|
||||
MANDOCERR_NESTEDDISP, /* nested displays are not portable */
|
||||
MANDOCERR_SCOPEREP, /* already in literal mode */
|
||||
MANDOCERR_LINESCOPE, /* line scope broken */
|
||||
|
||||
/* related to missing macro arguments */
|
||||
MANDOCERR_MACROEMPTY, /* skipping empty macro */
|
||||
|
@ -80,6 +83,7 @@ enum mandocerr {
|
|||
MANDOCERR_LISTFIRST, /* list type must come first */
|
||||
MANDOCERR_NOWIDTHARG, /* tag lists require a width argument */
|
||||
MANDOCERR_FONTTYPE, /* missing font type */
|
||||
MANDOCERR_WNOSCOPE, /* skipping end of block that is not open */
|
||||
|
||||
/* related to bad macro arguments */
|
||||
MANDOCERR_IGNARGV, /* skipping argument */
|
||||
|
@ -100,11 +104,18 @@ enum mandocerr {
|
|||
MANDOCERR_BADESCAPE, /* unknown escape sequence */
|
||||
MANDOCERR_BADQUOTE, /* unterminated quoted string */
|
||||
|
||||
/* related to tables */
|
||||
MANDOCERR_TBLEXTRADAT, /* extra data cells */
|
||||
/* related to equations */
|
||||
MANDOCERR_EQNQUOTE, /* unexpected literal in equation */
|
||||
|
||||
MANDOCERR_ERROR, /* ===== start of errors ===== */
|
||||
|
||||
/* related to equations */
|
||||
MANDOCERR_EQNNSCOPE, /* unexpected equation scope closure*/
|
||||
MANDOCERR_EQNSCOPE, /* equation scope open on exit */
|
||||
MANDOCERR_EQNBADSCOPE, /* overlapping equation scopes */
|
||||
MANDOCERR_EQNEOF, /* unexpected end of equation */
|
||||
MANDOCERR_EQNSYNT, /* equation syntax error */
|
||||
|
||||
/* related to tables */
|
||||
MANDOCERR_TBL, /* bad table syntax */
|
||||
MANDOCERR_TBLOPT, /* bad table option */
|
||||
|
@ -113,13 +124,14 @@ enum mandocerr {
|
|||
MANDOCERR_TBLNODATA, /* no table data cells specified */
|
||||
MANDOCERR_TBLIGNDATA, /* ignore data in cell */
|
||||
MANDOCERR_TBLBLOCK, /* data block still open */
|
||||
MANDOCERR_TBLEXTRADAT, /* ignoring extra data cells */
|
||||
|
||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||
MANDOCERR_BADCHAR, /* skipping bad character */
|
||||
MANDOCERR_NAMESC, /* escaped character not allowed in a name */
|
||||
MANDOCERR_NOTEXT, /* skipping text before the first section header */
|
||||
MANDOCERR_MACRO, /* skipping unknown macro */
|
||||
MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */
|
||||
MANDOCERR_LINESCOPE, /* line scope broken */
|
||||
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
||||
MANDOCERR_NOSCOPE, /* skipping end of block that is not open */
|
||||
MANDOCERR_SCOPEBROKEN, /* missing end of block */
|
||||
|
@ -135,9 +147,9 @@ enum mandocerr {
|
|||
|
||||
MANDOCERR_FATAL, /* ===== start of fatal errors ===== */
|
||||
|
||||
MANDOCERR_NOTMANUAL, /* manual isn't really a manual */
|
||||
MANDOCERR_COLUMNS, /* column syntax is inconsistent */
|
||||
MANDOCERR_BADDISP, /* NOT IMPLEMENTED: .Bd -file */
|
||||
MANDOCERR_SYNTLINESCOPE, /* line scope broken, syntax violated */
|
||||
MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */
|
||||
MANDOCERR_SYNTCHILD, /* child violates parent syntax */
|
||||
MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */
|
||||
|
@ -202,7 +214,7 @@ enum tbl_cellt {
|
|||
struct tbl_cell {
|
||||
struct tbl_cell *next;
|
||||
enum tbl_cellt pos;
|
||||
int spacing;
|
||||
size_t spacing;
|
||||
int flags;
|
||||
#define TBL_CELL_TALIGN (1 << 0) /* t, T */
|
||||
#define TBL_CELL_BALIGN (1 << 1) /* d, D */
|
||||
|
@ -224,12 +236,12 @@ struct tbl_row {
|
|||
};
|
||||
|
||||
enum tbl_datt {
|
||||
TBL_DATA_NONE,
|
||||
TBL_DATA_DATA,
|
||||
TBL_DATA_HORIZ,
|
||||
TBL_DATA_DHORIZ,
|
||||
TBL_DATA_NHORIZ,
|
||||
TBL_DATA_NDHORIZ
|
||||
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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -237,9 +249,10 @@ enum tbl_datt {
|
|||
* string value that's in the cell. The rest is layout.
|
||||
*/
|
||||
struct tbl_dat {
|
||||
struct tbl_cell *layout; /* layout cell: CAN BE NULL */
|
||||
struct tbl_cell *layout; /* layout cell */
|
||||
int spans; /* how many spans follow */
|
||||
struct tbl_dat *next;
|
||||
char *string;
|
||||
char *string; /* data (NULL if not TBL_DATA_DATA) */
|
||||
enum tbl_datt pos;
|
||||
};
|
||||
|
||||
|
@ -255,9 +268,10 @@ enum tbl_spant {
|
|||
struct tbl_span {
|
||||
struct tbl *tbl;
|
||||
struct tbl_head *head;
|
||||
struct tbl_row *layout; /* layout row: CAN BE NULL */
|
||||
struct tbl_row *layout; /* layout row */
|
||||
struct tbl_dat *first;
|
||||
struct tbl_dat *last;
|
||||
int line; /* parse line */
|
||||
int flags;
|
||||
#define TBL_SPAN_FIRST (1 << 0)
|
||||
#define TBL_SPAN_LAST (1 << 1)
|
||||
|
@ -265,50 +279,153 @@ struct tbl_span {
|
|||
struct tbl_span *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* Available registers (set in libroff, accessed elsewhere).
|
||||
enum eqn_boxt {
|
||||
EQN_ROOT, /* root of parse tree */
|
||||
EQN_TEXT, /* text (number, variable, whatever) */
|
||||
EQN_SUBEXPR, /* nested `eqn' subexpression */
|
||||
EQN_LIST, /* subexpressions list */
|
||||
EQN_MATRIX /* matrix subexpression */
|
||||
};
|
||||
|
||||
enum eqn_markt {
|
||||
EQNMARK_NONE = 0,
|
||||
EQNMARK_DOT,
|
||||
EQNMARK_DOTDOT,
|
||||
EQNMARK_HAT,
|
||||
EQNMARK_TILDE,
|
||||
EQNMARK_VEC,
|
||||
EQNMARK_DYAD,
|
||||
EQNMARK_BAR,
|
||||
EQNMARK_UNDER,
|
||||
EQNMARK__MAX
|
||||
};
|
||||
|
||||
enum eqn_fontt {
|
||||
EQNFONT_NONE = 0,
|
||||
EQNFONT_ROMAN,
|
||||
EQNFONT_BOLD,
|
||||
EQNFONT_FAT,
|
||||
EQNFONT_ITALIC,
|
||||
EQNFONT__MAX
|
||||
};
|
||||
|
||||
enum eqn_post {
|
||||
EQNPOS_NONE = 0,
|
||||
EQNPOS_OVER,
|
||||
EQNPOS_SUP,
|
||||
EQNPOS_SUB,
|
||||
EQNPOS_TO,
|
||||
EQNPOS_FROM,
|
||||
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.
|
||||
*/
|
||||
enum regs {
|
||||
REG_nS = 0,
|
||||
REG__MAX
|
||||
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 *parent; /* node sibling */
|
||||
char *text; /* text (or NULL) */
|
||||
char *left;
|
||||
char *right;
|
||||
enum eqn_post pos; /* position of next box */
|
||||
enum eqn_markt mark; /* a mark about the box */
|
||||
enum eqn_fontt font; /* font of box */
|
||||
enum eqn_pilet pile; /* equation piling */
|
||||
};
|
||||
|
||||
/*
|
||||
* A register (struct reg) can consist of many types: this consists of
|
||||
* normalised types from the original string form.
|
||||
* An equation consists of a tree of expressions starting at a given
|
||||
* line and position.
|
||||
*/
|
||||
union regval {
|
||||
unsigned u; /* unsigned integer */
|
||||
struct eqn {
|
||||
char *name; /* identifier (or NULL) */
|
||||
struct eqn_box *root; /* root mathematical expression */
|
||||
int ln; /* invocation line */
|
||||
int pos; /* invocation position */
|
||||
};
|
||||
|
||||
/*
|
||||
* A single register entity. If "set" is zero, the value of the
|
||||
* register should be the default one, which is per-register. It's
|
||||
* assumed that callers know which type in "v" corresponds to which
|
||||
* register value.
|
||||
* The type of parse sequence. This value is usually passed via the
|
||||
* mandoc(1) command line of -man and -mdoc. It's almost exclusively
|
||||
* -mandoc but the others have been retained for compatibility.
|
||||
*/
|
||||
struct reg {
|
||||
int set; /* whether set or not */
|
||||
union regval v; /* parsed data */
|
||||
enum mparset {
|
||||
MPARSE_AUTO, /* magically determine the document type */
|
||||
MPARSE_MDOC, /* assume -mdoc */
|
||||
MPARSE_MAN /* assume -man */
|
||||
};
|
||||
|
||||
/*
|
||||
* The primary interface to setting register values is in libroff,
|
||||
* although libmdoc and libman from time to time will manipulate
|
||||
* registers (such as `.Sh SYNOPSIS' enabling REG_nS).
|
||||
*/
|
||||
struct regset {
|
||||
struct reg regs[REG__MAX];
|
||||
enum mandoc_esc {
|
||||
ESCAPE_ERROR = 0, /* bail! unparsable escape */
|
||||
ESCAPE_IGNORE, /* escape to be ignored */
|
||||
ESCAPE_SPECIAL, /* a regular special character */
|
||||
ESCAPE_FONT, /* a generic font mode */
|
||||
ESCAPE_FONTBOLD, /* bold font mode */
|
||||
ESCAPE_FONTITALIC, /* italic font mode */
|
||||
ESCAPE_FONTROMAN, /* roman font mode */
|
||||
ESCAPE_FONTPREV, /* previous font mode */
|
||||
ESCAPE_NUMBERED, /* a numbered glyph */
|
||||
ESCAPE_UNICODE, /* a unicode codepoint */
|
||||
ESCAPE_NOSPACE /* suppress space if the last on a line */
|
||||
};
|
||||
|
||||
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
|
||||
const char *, int, int, const char *);
|
||||
|
||||
struct mparse;
|
||||
struct mchars;
|
||||
struct mdoc;
|
||||
struct man;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Callback function for warnings, errors, and fatal errors as they
|
||||
* occur in the compilers libroff, libmdoc, and libman.
|
||||
*/
|
||||
typedef int (*mandocmsg)(enum mandocerr, void *,
|
||||
int, int, const char *);
|
||||
void *mandoc_calloc(size_t, size_t);
|
||||
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
|
||||
void *mandoc_malloc(size_t);
|
||||
void *mandoc_realloc(void *, size_t);
|
||||
char *mandoc_strdup(const char *);
|
||||
char *mandoc_strndup(const char *, size_t);
|
||||
struct mchars *mchars_alloc(void);
|
||||
void mchars_free(struct mchars *);
|
||||
char mchars_num2char(const char *, size_t);
|
||||
int mchars_num2uc(const char *, size_t);
|
||||
int mchars_spec2cp(const struct mchars *,
|
||||
const char *, size_t);
|
||||
const char *mchars_spec2str(const struct mchars *,
|
||||
const char *, size_t, size_t *);
|
||||
struct mparse *mparse_alloc(enum mparset,
|
||||
enum mandoclevel, mandocmsg, void *);
|
||||
void mparse_free(struct mparse *);
|
||||
void mparse_keep(struct mparse *);
|
||||
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
|
||||
enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t,
|
||||
const char *);
|
||||
void mparse_reset(struct mparse *);
|
||||
void mparse_result(struct mparse *,
|
||||
struct mdoc **, struct man **);
|
||||
const char *mparse_getkeep(const struct mparse *);
|
||||
const char *mparse_strerror(enum mandocerr);
|
||||
const char *mparse_strlevel(enum mandoclevel);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
357
external/bsd/mdocml/dist/mandoc_char.7
vendored
357
external/bsd/mdocml/dist/mandoc_char.7
vendored
|
@ -1,6 +1,8 @@
|
|||
.\" $Vendor-Id: mandoc_char.7,v 1.40 2010/10/29 00:05:53 schwarze Exp $
|
||||
.\" $Vendor-Id: mandoc_char.7,v 1.51 2011/11/23 10:09:30 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011 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,26 +16,168 @@
|
|||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd October 29, 2010
|
||||
.Dd November 23, 2011
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc_char
|
||||
.Nd mandoc special characters
|
||||
.Sh DESCRIPTION
|
||||
This page documents the special characters and predefined strings accepted by
|
||||
This page documents the
|
||||
.Xr roff 7
|
||||
escape sequences accepted by
|
||||
.Xr mandoc 1
|
||||
to format
|
||||
to represent special characters in
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
documents.
|
||||
.Pp
|
||||
Both
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
encode special characters with
|
||||
The rendering depends on the
|
||||
.Xr mandoc 1
|
||||
output mode; in ASCII output, most characters are completely
|
||||
unintelligible.
|
||||
For that reason, using any of the special characters documented here,
|
||||
except those discussed in the
|
||||
.Sx DESCRIPTION ,
|
||||
is strongly discouraged; they are supported merely for backwards
|
||||
compatibility with existing documents.
|
||||
.Pp
|
||||
In particular, in English manual pages, do not use special-character
|
||||
escape sequences to represent national language characters in author
|
||||
names; instead, provide ASCII transcriptions of the names.
|
||||
.Ss Dashes and Hyphens
|
||||
In typography there are different types of dashes of various width:
|
||||
the hyphen (-),
|
||||
the minus sign (\-),
|
||||
the en-dash (\(en),
|
||||
and the em-dash (\(em).
|
||||
.Pp
|
||||
Hyphens are used for adjectives;
|
||||
to separate the two parts of a compound word;
|
||||
or to separate a word across two successive lines of text.
|
||||
The hyphen does not need to be escaped:
|
||||
.Bd -unfilled -offset indent
|
||||
blue-eyed
|
||||
lorry-driver
|
||||
.Ed
|
||||
.Pp
|
||||
The mathematical minus sign is used for negative numbers or subtraction.
|
||||
It should be written as
|
||||
.Sq \e- :
|
||||
.Bd -unfilled -offset indent
|
||||
a = 3 \e- 1;
|
||||
b = \e-2;
|
||||
.Ed
|
||||
.Pp
|
||||
The en-dash is used to separate the two elements of a range,
|
||||
or can be used the same way as an em-dash.
|
||||
It should be written as
|
||||
.Sq \e(en :
|
||||
.Bd -unfilled -offset indent
|
||||
pp. 95\e(en97.
|
||||
Go away \e(en or else!
|
||||
.Ed
|
||||
.Pp
|
||||
The em-dash can be used to show an interruption
|
||||
or can be used the same way as colons, semi-colons, or parentheses.
|
||||
It should be written as
|
||||
.Sq \e(em :
|
||||
.Bd -unfilled -offset indent
|
||||
Three things \e(em apples, oranges, and bananas.
|
||||
This is not that \e(em rather, this is that.
|
||||
.Ed
|
||||
.Pp
|
||||
Note:
|
||||
hyphens, minus signs, and en-dashes look identical under normal ASCII output.
|
||||
Other formats, such as PostScript, render them correctly,
|
||||
with differing widths.
|
||||
.Ss Spaces
|
||||
To separate words in normal text, for indenting and alignment
|
||||
in literal context, and when none of the following special cases apply,
|
||||
just use the normal space character
|
||||
.Pq Sq \ .
|
||||
.Pp
|
||||
When filling text, lines may be broken between words, i.e. at space
|
||||
characters.
|
||||
To prevent a line break between two particular words,
|
||||
use the non-breaking space escape sequence
|
||||
.Pq Sq \e~
|
||||
instead of the normal space character.
|
||||
For example, the input string
|
||||
.Dq number\e~1
|
||||
will be kept together as
|
||||
.Dq number\~1
|
||||
on the same output line.
|
||||
.Pp
|
||||
On request and macro lines, the normal space character serves as an
|
||||
argument delimiter.
|
||||
To include whitespace into arguments, quoting is usually the best choice.
|
||||
In some cases, using either the non-breaking
|
||||
.Pq Sq \e~
|
||||
or the breaking
|
||||
.Pq Sq \e\ \&
|
||||
space escape sequence may be preferable.
|
||||
To escape macro names and to protect whitespace at the end
|
||||
of input lines, the zero-width space
|
||||
.Pq Sq \e&
|
||||
is often useful.
|
||||
For example, in
|
||||
.Xr mdoc 7 ,
|
||||
a normal space character can be displayed in single quotes in either
|
||||
of the following ways:
|
||||
.Pp
|
||||
.Dl .Sq \(dq \(dq
|
||||
.Dl .Sq \e \e&
|
||||
.Ss Quotes
|
||||
On request and macro lines, the double-quote character
|
||||
.Pq Sq \(dq
|
||||
is handled specially to allow quoting.
|
||||
One way to prevent this special handling is by using the
|
||||
.Sq \e(dq
|
||||
escape sequence.
|
||||
.Pp
|
||||
Note that on text lines, literal double-quote characters can be used
|
||||
verbatim.
|
||||
All other quote-like characters can be used verbatim as well,
|
||||
even on request and macro lines.
|
||||
.Ss Periods
|
||||
The period
|
||||
.Pq Sq \&.
|
||||
is handled specially at the beginning of an input line,
|
||||
where it introduces a
|
||||
.Xr roff 7
|
||||
request or a macro, and when appearing alone as a macro argument in
|
||||
.Xr mdoc 7 .
|
||||
In such situations, prepend a zero-width space
|
||||
.Pq Sq \e&.
|
||||
to make it behave like normal text.
|
||||
.Pp
|
||||
Do not use the
|
||||
.Sq \e.
|
||||
escape sequence.
|
||||
It does not prevent special handling of the period.
|
||||
.Ss Backslashes
|
||||
To include a literal backslash
|
||||
.Pq Sq \e
|
||||
into the output, use the
|
||||
.Pq Sq \ee
|
||||
escape sequence.
|
||||
.Pp
|
||||
Note that doubling it
|
||||
.Pq Sq \e\e
|
||||
is not the right way to output a backslash.
|
||||
Because
|
||||
.Xr mandoc 1
|
||||
does not implement full
|
||||
.Xr roff 7
|
||||
functionality, it may work with
|
||||
.Xr mandoc 1 ,
|
||||
but it may have weird effects on complete
|
||||
.Xr roff 7
|
||||
implementations.
|
||||
.Sh SPECIAL CHARACTERS
|
||||
Special characters are encoded as
|
||||
.Sq \eX
|
||||
.Pq for a one-character escape ,
|
||||
.Sq \e(XX
|
||||
|
@ -41,40 +185,14 @@ encode special characters with
|
|||
and
|
||||
.Sq \e[N]
|
||||
.Pq N-character .
|
||||
One may generalise
|
||||
.Sq \e(XX
|
||||
as
|
||||
.Sq \e[XX]
|
||||
and
|
||||
.Sq \eX
|
||||
as
|
||||
.Sq \e[X] .
|
||||
Predefined strings are functionally similar to special characters, using
|
||||
.Sq \e*X
|
||||
.Pq for a one-character escape ,
|
||||
.Sq \e*(XX
|
||||
.Pq two-character ,
|
||||
and
|
||||
.Sq \e*[N]
|
||||
.Pq N-character .
|
||||
One may generalise
|
||||
.Sq \e*(XX
|
||||
as
|
||||
.Sq \e*[XX]
|
||||
and
|
||||
.Sq \e*X
|
||||
as
|
||||
.Sq \e*[X] .
|
||||
.Pp
|
||||
Note that each output mode will have a different rendering of the
|
||||
characters.
|
||||
It's guaranteed that each input symbol will correspond to a
|
||||
(more or less) meaningful output rendering, regardless the mode.
|
||||
.Sh SPECIAL CHARACTERS
|
||||
These are the preferred input symbols for producing special characters.
|
||||
For details, see the
|
||||
.Em Special Characters
|
||||
subsection of the
|
||||
.Xr roff 7
|
||||
manual.
|
||||
.Pp
|
||||
Spacing:
|
||||
.Bl -column -compact -offset indent "Input" "Description"
|
||||
.Bl -column "Input" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Description
|
||||
.It \e~ Ta non-breaking, non-collapsing space
|
||||
.It \e Ta breaking, non-collapsing n-width space
|
||||
|
@ -87,7 +205,7 @@ Spacing:
|
|||
.El
|
||||
.Pp
|
||||
Lines:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(ba Ta \(ba Ta bar
|
||||
.It \e(br Ta \(br Ta box rule
|
||||
|
@ -99,7 +217,7 @@ Lines:
|
|||
.El
|
||||
.Pp
|
||||
Text markers:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(ci Ta \(ci Ta circle
|
||||
.It \e(bu Ta \(bu Ta bullet
|
||||
|
@ -118,7 +236,7 @@ Text markers:
|
|||
.El
|
||||
.Pp
|
||||
Legal symbols:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(co Ta \(co Ta copyright
|
||||
.It \e(rg Ta \(rg Ta registered
|
||||
|
@ -126,7 +244,7 @@ Legal symbols:
|
|||
.El
|
||||
.Pp
|
||||
Punctuation:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(em Ta \(em Ta em-dash
|
||||
.It \e(en Ta \(en Ta en-dash
|
||||
|
@ -138,7 +256,7 @@ Punctuation:
|
|||
.El
|
||||
.Pp
|
||||
Quotes:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(Bq Ta \(Bq Ta right low double-quote
|
||||
.It \e(bq Ta \(bq Ta right low single-quote
|
||||
|
@ -155,7 +273,7 @@ Quotes:
|
|||
.El
|
||||
.Pp
|
||||
Brackets:
|
||||
.Bl -column -compact -offset indent "xxbracketrightbpx" Rendered Description
|
||||
.Bl -column "xxbracketrightbpx" Rendered Description -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(lB Ta \(lB Ta left bracket
|
||||
.It \e(rB Ta \(rB Ta right bracket
|
||||
|
@ -194,7 +312,7 @@ Brackets:
|
|||
.El
|
||||
.Pp
|
||||
Arrows:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(<- Ta \(<- Ta left arrow
|
||||
.It \e(-> Ta \(-> Ta right arrow
|
||||
|
@ -211,7 +329,7 @@ Arrows:
|
|||
.El
|
||||
.Pp
|
||||
Logical:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(AN Ta \(AN Ta logical and
|
||||
.It \e(OR Ta \(OR Ta logical or
|
||||
|
@ -226,7 +344,7 @@ Logical:
|
|||
.El
|
||||
.Pp
|
||||
Mathematical:
|
||||
.Bl -column -compact -offset indent "xxcoproductxx" "Rendered" "Description"
|
||||
.Bl -column "xxcoproductxx" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(pl Ta \(pl Ta plus
|
||||
.It \e(mi Ta \(mi Ta minus
|
||||
|
@ -288,10 +406,13 @@ Mathematical:
|
|||
.It \e(Re Ta \(Re Ta real
|
||||
.It \e(pd Ta \(pd Ta partial differential
|
||||
.It \e(-h Ta \(-h Ta Planck constant over 2\(*p
|
||||
.It \e[12] Ta \[12] Ta one-half
|
||||
.It \e[14] Ta \[14] Ta one-fourth
|
||||
.It \e[34] Ta \[34] Ta three-fourths
|
||||
.El
|
||||
.Pp
|
||||
Ligatures:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(ff Ta \(ff Ta ff ligature
|
||||
.It \e(fi Ta \(fi Ta fi ligature
|
||||
|
@ -308,7 +429,7 @@ Ligatures:
|
|||
.El
|
||||
.Pp
|
||||
Accents:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(a" Ta \(a" Ta Hungarian umlaut
|
||||
.It \e(a- Ta \(a- Ta macron
|
||||
|
@ -330,7 +451,7 @@ Accents:
|
|||
.El
|
||||
.Pp
|
||||
Accented letters:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e('A Ta \('A Ta acute A
|
||||
.It \e('E Ta \('E Ta acute E
|
||||
|
@ -390,7 +511,7 @@ Accented letters:
|
|||
.El
|
||||
.Pp
|
||||
Special letters:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(-D Ta \(-D Ta Eth
|
||||
.It \e(Sd Ta \(Sd Ta eth
|
||||
|
@ -401,7 +522,7 @@ Special letters:
|
|||
.El
|
||||
.Pp
|
||||
Currency:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(Do Ta \(Do Ta dollar
|
||||
.It \e(ct Ta \(ct Ta cent
|
||||
|
@ -414,7 +535,7 @@ Currency:
|
|||
.El
|
||||
.Pp
|
||||
Units:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(de Ta \(de Ta degree
|
||||
.It \e(%0 Ta \(%0 Ta per-thousand
|
||||
|
@ -424,7 +545,7 @@ Units:
|
|||
.El
|
||||
.Pp
|
||||
Greek letters:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(*A Ta \(*A Ta Alpha
|
||||
.It \e(*B Ta \(*B Ta Beta
|
||||
|
@ -481,10 +602,28 @@ Greek letters:
|
|||
.It \e(ts Ta \(ts Ta sigma terminal
|
||||
.El
|
||||
.Sh PREDEFINED STRINGS
|
||||
These are not recommended for use, as they differ across
|
||||
implementations:
|
||||
Predefined strings are inherited from the macro packages of historical
|
||||
troff implementations.
|
||||
They are
|
||||
.Em not recommended
|
||||
for use, as they differ across implementations.
|
||||
Manuals using these predefined strings are almost certainly not
|
||||
portable.
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
Their syntax is similar to special characters, using
|
||||
.Sq \e*X
|
||||
.Pq for a one-character escape ,
|
||||
.Sq \e*(XX
|
||||
.Pq two-character ,
|
||||
and
|
||||
.Sq \e*[N]
|
||||
.Pq N-character .
|
||||
For details, see the
|
||||
.Em Predefined Strings
|
||||
subsection of the
|
||||
.Xr roff 7
|
||||
manual.
|
||||
.Bl -column "Input" "Rendered" "Description" -offset indent
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e*(Ba Ta \*(Ba Ta vertical bar
|
||||
.It \e*(Ne Ta \*(Ne Ta not equal
|
||||
|
@ -512,39 +651,85 @@ implementations:
|
|||
.It \e*(>= Ta \*(>= Ta greater-than-equal
|
||||
.It \e*(aa Ta \*(aa Ta acute
|
||||
.It \e*(ga Ta \*(ga Ta grave
|
||||
.It \e*(Px Ta \*(Px Ta POSIX standard name
|
||||
.It \e*(Ai Ta \*(Ai Ta ANSI standard name
|
||||
.El
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility of
|
||||
.Nm
|
||||
with older or existing versions of groff.
|
||||
.Sh UNICODE CHARACTERS
|
||||
The escape sequence
|
||||
.Pp
|
||||
The following render differently in
|
||||
.Fl T Ns Ar ascii
|
||||
output mode:
|
||||
.Bd -ragged -offset indent
|
||||
\e(ss, \e(nm, \e(nb, \e(nc, \e(ib, \e(ip, \e(pp, \e[sum], \e[product],
|
||||
\e[coproduct], \e(gr, \e(-h, \e(a.
|
||||
.Ed
|
||||
.Dl \e[uXXXX]
|
||||
.Pp
|
||||
The following render differently in
|
||||
.Fl T Ns Ar html
|
||||
output mode:
|
||||
.Bd -ragged -offset indent
|
||||
\e(~=, \e(nb, \e(nc
|
||||
.Ed
|
||||
.Pp
|
||||
Finally, the following have been omitted by being poorly documented or
|
||||
having no known representation:
|
||||
.Bd -ragged -offset indent
|
||||
\e[radicalex], \e[sqrtex], \e(ru
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
is interpreted as a Unicode codepoint.
|
||||
The codepoint must be in the range above U+0080 and less than U+10FFFF.
|
||||
For compatibility, points must be zero-padded to four characters; if
|
||||
greater than four characters, no zero padding is allowed.
|
||||
Unicode surrogates are not allowed.
|
||||
.\" .Pp
|
||||
.\" Unicode glyphs attenuate to the
|
||||
.\" .Sq \&?
|
||||
.\" character if invalid or not rendered by current output media.
|
||||
.Sh NUMBERED CHARACTERS
|
||||
For backward compatibility with existing manuals,
|
||||
.Xr mandoc 1
|
||||
also supports the
|
||||
.Pp
|
||||
.Dl \eN\(aq Ns Ar number Ns \(aq
|
||||
.Pp
|
||||
escape sequence, 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'34', use \e(dq, or even the plain
|
||||
.Sq \(dq
|
||||
character where possible.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility between mandoc and other other
|
||||
troff implementations, at this time limited to GNU troff
|
||||
.Pq Qq groff .
|
||||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
The \eN\(aq\(aq escape sequence is limited to printable characters; in
|
||||
groff, it accepts arbitrary character numbers.
|
||||
.It
|
||||
In
|
||||
.Fl T Ns Cm ascii ,
|
||||
the
|
||||
\e(ss, \e(nm, \e(nb, \e(nc, \e(ib, \e(ip, \e(pp, \e[sum], \e[product],
|
||||
\e[coproduct], \e(gr, \e(\-h, and \e(a. special characters render
|
||||
differently between mandoc and groff.
|
||||
.It
|
||||
In
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml ,
|
||||
the \e(~=, \e(nb, and \e(nc special characters render differently
|
||||
between mandoc and groff.
|
||||
.It
|
||||
The
|
||||
.Fl T Ns Cm ps
|
||||
and
|
||||
.Fl T Ns Cm pdf
|
||||
modes format like
|
||||
.Fl T Ns Cm ascii
|
||||
instead of rendering glyphs as in groff.
|
||||
.It
|
||||
The \e[radicalex], \e[sqrtex], and \e(ru special characters have been omitted
|
||||
from mandoc either because they are poorly documented or they have no
|
||||
known representation.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
manual page was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
The
|
||||
.Sq \e*(Ba
|
||||
|
|
293
external/bsd/mdocml/dist/mandocdb.8
vendored
Normal file
293
external/bsd/mdocml/dist/mandocdb.8
vendored
Normal file
|
@ -0,0 +1,293 @@
|
|||
.\" $Vendor-Id: mandocdb.8,v 1.17 2011/12/25 21:00:23 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd December 25, 2011
|
||||
.Dt MANDOCDB 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandocdb
|
||||
.Nd index UNIX manuals
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl avW
|
||||
.Op Fl C Ar file
|
||||
.Nm
|
||||
.Op Fl avW
|
||||
.Ar dir ...
|
||||
.Nm
|
||||
.Op Fl vW
|
||||
.Fl d Ar dir
|
||||
.Op Ar
|
||||
.Nm
|
||||
.Op Fl vW
|
||||
.Fl u Ar dir
|
||||
.Op Ar
|
||||
.Nm
|
||||
.Fl t Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility extracts keywords from
|
||||
.Ux
|
||||
manuals and indexes them in a
|
||||
.Sx Keyword Database
|
||||
and
|
||||
.Sx Index Database
|
||||
for fast retrieval by
|
||||
.Xr apropos 1 ,
|
||||
.Xr whatis 1 ,
|
||||
and
|
||||
.Xr man 1 Ns 's
|
||||
.Fl k
|
||||
option.
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
creates databases in each
|
||||
.Ar dir
|
||||
using the files
|
||||
.Sm off
|
||||
.Sy man Ar section Li /
|
||||
.Op Ar arch Li /
|
||||
.Ar title . section
|
||||
.Sm on
|
||||
and
|
||||
.Sm off
|
||||
.Sy cat Ar section Li /
|
||||
.Op Ar arch Li /
|
||||
.Ar title . Sy 0
|
||||
.Sm on
|
||||
in that directory;
|
||||
existing databases are truncated.
|
||||
If
|
||||
.Ar dir
|
||||
is not provided,
|
||||
.Nm
|
||||
uses the default paths stipulated by
|
||||
.Xr man 1 .
|
||||
.Pp
|
||||
The arguments are as follows:
|
||||
.Bl -tag -width "-C file"
|
||||
.It Fl a
|
||||
Use all directories and files found below
|
||||
.Ar dir ... .
|
||||
.It Fl C Ar file
|
||||
Specify an alternative configuration
|
||||
.Ar file
|
||||
in
|
||||
.Xr man.conf 5
|
||||
format.
|
||||
.It Fl d Ar dir
|
||||
Merge (remove and re-add)
|
||||
.Ar
|
||||
to the database in
|
||||
.Ar dir
|
||||
without truncating it.
|
||||
.It Fl t Ar
|
||||
Check the given
|
||||
.Ar files
|
||||
for potential problems.
|
||||
No databases are modified.
|
||||
Implies
|
||||
.Fl a
|
||||
and
|
||||
.Fl W .
|
||||
All diagnostic messages are printed to the standard output;
|
||||
the standard error output is not used.
|
||||
.It Fl u Ar dir
|
||||
Remove
|
||||
.Ar
|
||||
from the database in
|
||||
.Ar dir
|
||||
without truncating it.
|
||||
.It Fl v
|
||||
Display all files added or removed to the index.
|
||||
.It Fl W
|
||||
Print warnings about potential problems with manual pages
|
||||
to the standard error output.
|
||||
.El
|
||||
.Pp
|
||||
If fatal parse errors are encountered while parsing, the offending file
|
||||
is printed to stderr, omitted from the index, and the parse continues
|
||||
with the next input file.
|
||||
.Ss Index Database
|
||||
The index database,
|
||||
.Pa whatis.index ,
|
||||
is a
|
||||
.Xr recno 3
|
||||
database with record values consisting of
|
||||
.Pp
|
||||
.Bl -enum -compact
|
||||
.It
|
||||
the character
|
||||
.Cm d ,
|
||||
.Cm a ,
|
||||
or
|
||||
.Cm c
|
||||
to indicate the file type
|
||||
.Po
|
||||
.Xr mdoc 7 ,
|
||||
.Xr man 7 ,
|
||||
and post-formatted, respectively
|
||||
.Pc ,
|
||||
.It
|
||||
the filename relative to the databases' path,
|
||||
.It
|
||||
the manual section,
|
||||
.It
|
||||
the manual title,
|
||||
.It
|
||||
the architecture
|
||||
.Pq often empty ,
|
||||
.It
|
||||
and the description.
|
||||
.El
|
||||
.Pp
|
||||
Each of the above is NUL-terminated.
|
||||
.Pp
|
||||
If the record value is zero-length, it is unassigned.
|
||||
.Ss Keyword Database
|
||||
The keyword database,
|
||||
.Pa whatis.db ,
|
||||
is a
|
||||
.Xr btree 3
|
||||
database of NUL-terminated keywords (record length is non-zero string
|
||||
length plus one) mapping to a 16-byte binary field consisting of the
|
||||
64-bit keyword type and the 64-bit
|
||||
.Sx Index Database
|
||||
record number, both in network-byte order.
|
||||
.Pp
|
||||
The type bit-mask consists of the following
|
||||
values mapping into
|
||||
.Xr mdoc 7
|
||||
macro identifiers:
|
||||
.Pp
|
||||
.Bl -column "x0x0000000000000001ULLx" "xLix" -offset indent -compact
|
||||
.It Li 0x0000000000000001ULL Ta \&An
|
||||
.It Li 0x0000000000000002ULL Ta \&Ar
|
||||
.It Li 0x0000000000000004ULL Ta \&At
|
||||
.It Li 0x0000000000000008ULL Ta \&Bsx
|
||||
.It Li 0x0000000000000010ULL Ta \&Bx
|
||||
.It Li 0x0000000000000020ULL Ta \&Cd
|
||||
.It Li 0x0000000000000040ULL Ta \&Cm
|
||||
.It Li 0x0000000000000080ULL Ta \&Dv
|
||||
.It Li 0x0000000000000100ULL Ta \&Dx
|
||||
.It Li 0x0000000000000200ULL Ta \&Em
|
||||
.It Li 0x0000000000000400ULL Ta \&Er
|
||||
.It Li 0x0000000000000800ULL Ta \&Ev
|
||||
.It Li 0x0000000000001000ULL Ta \&Fa
|
||||
.It Li 0x0000000000002000ULL Ta \&Fl
|
||||
.It Li 0x0000000000004000ULL Ta \&Fn
|
||||
.It Li 0x0000000000008000ULL Ta \&Ft
|
||||
.It Li 0x0000000000010000ULL Ta \&Fx
|
||||
.It Li 0x0000000000020000ULL Ta \&Ic
|
||||
.It Li 0x0000000000040000ULL Ta \&In
|
||||
.It Li 0x0000000000080000ULL Ta \&Lb
|
||||
.It Li 0x0000000000100000ULL Ta \&Li
|
||||
.It Li 0x0000000000200000ULL Ta \&Lk
|
||||
.It Li 0x0000000000400000ULL Ta \&Ms
|
||||
.It Li 0x0000000000800000ULL Ta \&Mt
|
||||
.It Li 0x0000000001000000ULL Ta \&Nd
|
||||
.It Li 0x0000000002000000ULL Ta \&Nm
|
||||
.It Li 0x0000000004000000ULL Ta \&Nx
|
||||
.It Li 0x0000000008000000ULL Ta \&Ox
|
||||
.It Li 0x0000000010000000ULL Ta \&Pa
|
||||
.It Li 0x0000000020000000ULL Ta \&Rs
|
||||
.It Li 0x0000000040000000ULL Ta \&Sh
|
||||
.It Li 0x0000000080000000ULL Ta \&Ss
|
||||
.It Li 0x0000000100000000ULL Ta \&St
|
||||
.It Li 0x0000000200000000ULL Ta \&Sy
|
||||
.It Li 0x0000000400000000ULL Ta \&Tn
|
||||
.It Li 0x0000000800000000ULL Ta \&Va
|
||||
.It Li 0x0000001000000000ULL Ta \&Vt
|
||||
.It Li 0x0000002000000000ULL Ta \&Xr
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
The time to construct a new database pair grows linearly with the
|
||||
number of keywords in the input files.
|
||||
However, removing or updating entries with
|
||||
.Fl u
|
||||
or
|
||||
.Fl d ,
|
||||
respectively, grows as a multiple of the index length and input size.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa whatis.db
|
||||
A
|
||||
.Xr btree 3
|
||||
keyword database mapping keywords to a type and file reference in
|
||||
.Pa whatis.index .
|
||||
.It Pa whatis.index
|
||||
A
|
||||
.Xr recno 3
|
||||
database of indexed file-names.
|
||||
.It Pa /etc/man.conf
|
||||
The default
|
||||
.Xr man 1
|
||||
configuration file.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits with one of the following values:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It 0
|
||||
No errors occurred.
|
||||
.It 5
|
||||
Invalid command line arguments were specified.
|
||||
No input files have been read.
|
||||
.It 6
|
||||
An operating system error occurred, for example memory exhaustion or an
|
||||
error accessing input files.
|
||||
Such errors cause
|
||||
.Nm
|
||||
to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
The output databases are corrupt and should be removed.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
If the following errors occur, the
|
||||
.Nm
|
||||
databases should be rebuilt.
|
||||
.Bl -diag
|
||||
.It "%s: Corrupt database"
|
||||
The keyword database file indicated by
|
||||
.Pa %s
|
||||
is unreadable.
|
||||
.It "%s: Corrupt index"
|
||||
The index database file indicated by
|
||||
.Pa %s
|
||||
is unreadable.
|
||||
.It "%s: Path too long"
|
||||
The file
|
||||
.Pa %s
|
||||
is too long.
|
||||
This usually indicates database corruption or invalid command-line
|
||||
arguments.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr apropos 1 ,
|
||||
.Xr man 1 ,
|
||||
.Xr whatis 1 ,
|
||||
.Xr btree 3 ,
|
||||
.Xr recno 3 ,
|
||||
.Xr man.conf 5
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
1834
external/bsd/mdocml/dist/mandocdb.c
vendored
Normal file
1834
external/bsd/mdocml/dist/mandocdb.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
62
external/bsd/mdocml/dist/mandocdb.h
vendored
Normal file
62
external/bsd/mdocml/dist/mandocdb.h
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* $Vendor-Id: mandocdb.h,v 1.5 2011/12/25 16:53:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifndef MANDOCDB_H
|
||||
#define MANDOCDB_H
|
||||
|
||||
#define MANDOC_DB "whatis.db"
|
||||
#define MANDOC_IDX "whatis.index"
|
||||
|
||||
#define TYPE_An 0x0000000000000001ULL
|
||||
#define TYPE_Ar 0x0000000000000002ULL
|
||||
#define TYPE_At 0x0000000000000004ULL
|
||||
#define TYPE_Bsx 0x0000000000000008ULL
|
||||
#define TYPE_Bx 0x0000000000000010ULL
|
||||
#define TYPE_Cd 0x0000000000000020ULL
|
||||
#define TYPE_Cm 0x0000000000000040ULL
|
||||
#define TYPE_Dv 0x0000000000000080ULL
|
||||
#define TYPE_Dx 0x0000000000000100ULL
|
||||
#define TYPE_Em 0x0000000000000200ULL
|
||||
#define TYPE_Er 0x0000000000000400ULL
|
||||
#define TYPE_Ev 0x0000000000000800ULL
|
||||
#define TYPE_Fa 0x0000000000001000ULL
|
||||
#define TYPE_Fl 0x0000000000002000ULL
|
||||
#define TYPE_Fn 0x0000000000004000ULL
|
||||
#define TYPE_Ft 0x0000000000008000ULL
|
||||
#define TYPE_Fx 0x0000000000010000ULL
|
||||
#define TYPE_Ic 0x0000000000020000ULL
|
||||
#define TYPE_In 0x0000000000040000ULL
|
||||
#define TYPE_Lb 0x0000000000080000ULL
|
||||
#define TYPE_Li 0x0000000000100000ULL
|
||||
#define TYPE_Lk 0x0000000000200000ULL
|
||||
#define TYPE_Ms 0x0000000000400000ULL
|
||||
#define TYPE_Mt 0x0000000000800000ULL
|
||||
#define TYPE_Nd 0x0000000001000000ULL
|
||||
#define TYPE_Nm 0x0000000002000000ULL
|
||||
#define TYPE_Nx 0x0000000004000000ULL
|
||||
#define TYPE_Ox 0x0000000008000000ULL
|
||||
#define TYPE_Pa 0x0000000010000000ULL
|
||||
#define TYPE_Rs 0x0000000020000000ULL
|
||||
#define TYPE_Sh 0x0000000040000000ULL
|
||||
#define TYPE_Ss 0x0000000080000000ULL
|
||||
#define TYPE_St 0x0000000100000000ULL
|
||||
#define TYPE_Sy 0x0000000200000000ULL
|
||||
#define TYPE_Tn 0x0000000400000000ULL
|
||||
#define TYPE_Va 0x0000000800000000ULL
|
||||
#define TYPE_Vt 0x0000001000000000ULL
|
||||
#define TYPE_Xr 0x0000002000000000ULL
|
||||
|
||||
#endif /*!MANDOCDB_H */
|
225
external/bsd/mdocml/dist/manpath.c
vendored
Normal file
225
external/bsd/mdocml/dist/manpath.c
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
/* $Vendor-Id: manpath.c,v 1.8 2011/12/24 22:37:16 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "manpath.h"
|
||||
|
||||
#define MAN_CONF_FILE "/etc/man.conf"
|
||||
#define MAN_CONF_KEY "_whatdb"
|
||||
|
||||
static void manpath_add(struct manpaths *, const char *);
|
||||
static void manpath_parseline(struct manpaths *, char *);
|
||||
|
||||
void
|
||||
manpath_parse(struct manpaths *dirs, const char *file,
|
||||
char *defp, char *auxp)
|
||||
{
|
||||
#ifdef USE_MANPATH
|
||||
char cmd[(MAXPATHLEN * 3) + 20];
|
||||
FILE *stream;
|
||||
char *buf;
|
||||
size_t sz, bsz;
|
||||
|
||||
strlcpy(cmd, "manpath", sizeof(cmd));
|
||||
if (file) {
|
||||
strlcat(cmd, " -C ", sizeof(cmd));
|
||||
strlcat(cmd, file, sizeof(cmd));
|
||||
}
|
||||
if (auxp) {
|
||||
strlcat(cmd, " -m ", sizeof(cmd));
|
||||
strlcat(cmd, auxp, sizeof(cmd));
|
||||
}
|
||||
if (defp) {
|
||||
strlcat(cmd, " -M ", sizeof(cmd));
|
||||
strlcat(cmd, defp, sizeof(cmd));
|
||||
}
|
||||
|
||||
/* Open manpath(1). Ignore errors. */
|
||||
|
||||
stream = popen(cmd, "r");
|
||||
if (NULL == stream)
|
||||
return;
|
||||
|
||||
buf = NULL;
|
||||
bsz = 0;
|
||||
|
||||
/* Read in as much output as we can. */
|
||||
|
||||
do {
|
||||
buf = mandoc_realloc(buf, bsz + 1024);
|
||||
sz = fread(buf + (int)bsz, 1, 1024, stream);
|
||||
bsz += sz;
|
||||
} while (sz > 0);
|
||||
|
||||
if ( ! ferror(stream) && feof(stream) &&
|
||||
bsz && '\n' == buf[bsz - 1]) {
|
||||
buf[bsz - 1] = '\0';
|
||||
manpath_parseline(dirs, buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
pclose(stream);
|
||||
#else
|
||||
char *insert;
|
||||
|
||||
/* Always prepend -m. */
|
||||
manpath_parseline(dirs, auxp);
|
||||
|
||||
/* If -M is given, it overrides everything else. */
|
||||
if (NULL != defp) {
|
||||
manpath_parseline(dirs, defp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* MANPATH and man.conf(5) cooperate. */
|
||||
defp = getenv("MANPATH");
|
||||
if (NULL == file)
|
||||
file = MAN_CONF_FILE;
|
||||
|
||||
/* No MANPATH; use man.conf(5) only. */
|
||||
if (NULL == defp || '\0' == defp[0]) {
|
||||
manpath_manconf(dirs, file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepend man.conf(5) to MANPATH. */
|
||||
if (':' == defp[0]) {
|
||||
manpath_manconf(dirs, file);
|
||||
manpath_parseline(dirs, defp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append man.conf(5) to MANPATH. */
|
||||
if (':' == defp[(int)strlen(defp) - 1]) {
|
||||
manpath_parseline(dirs, defp);
|
||||
manpath_manconf(dirs, file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Insert man.conf(5) into MANPATH. */
|
||||
insert = strstr(defp, "::");
|
||||
if (NULL != insert) {
|
||||
*insert++ = '\0';
|
||||
manpath_parseline(dirs, defp);
|
||||
manpath_manconf(dirs, file);
|
||||
manpath_parseline(dirs, insert + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* MANPATH overrides man.conf(5) completely. */
|
||||
manpath_parseline(dirs, defp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a FULL pathname from a colon-separated list of arrays.
|
||||
*/
|
||||
static void
|
||||
manpath_parseline(struct manpaths *dirs, char *path)
|
||||
{
|
||||
char *dir;
|
||||
|
||||
if (NULL == path)
|
||||
return;
|
||||
|
||||
for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
|
||||
manpath_add(dirs, dir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a directory to the array, ignoring bad directories.
|
||||
* Grow the array one-by-one for simplicity's sake.
|
||||
*/
|
||||
static void
|
||||
manpath_add(struct manpaths *dirs, const char *dir)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
if (NULL == (cp = realpath(dir, buf)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < dirs->sz; i++)
|
||||
if (0 == strcmp(dirs->paths[i], dir))
|
||||
return;
|
||||
|
||||
dirs->paths = mandoc_realloc
|
||||
(dirs->paths,
|
||||
((size_t)dirs->sz + 1) * sizeof(char *));
|
||||
|
||||
dirs->paths[dirs->sz++] = mandoc_strdup(cp);
|
||||
}
|
||||
|
||||
void
|
||||
manpath_free(struct manpaths *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < p->sz; i++)
|
||||
free(p->paths[i]);
|
||||
|
||||
free(p->paths);
|
||||
}
|
||||
|
||||
void
|
||||
manpath_manconf(struct manpaths *dirs, const char *file)
|
||||
{
|
||||
FILE *stream;
|
||||
char *p, *q;
|
||||
size_t len, keysz;
|
||||
|
||||
keysz = strlen(MAN_CONF_KEY);
|
||||
assert(keysz > 0);
|
||||
|
||||
if (NULL == (stream = fopen(file, "r")))
|
||||
return;
|
||||
|
||||
while (NULL != (p = fgetln(stream, &len))) {
|
||||
if (0 == len || '\n' != p[--len])
|
||||
break;
|
||||
p[len] = '\0';
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (strncmp(MAN_CONF_KEY, p, keysz))
|
||||
continue;
|
||||
p += keysz;
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
if ('\0' == *p)
|
||||
continue;
|
||||
if (NULL == (q = strrchr(p, '/')))
|
||||
continue;
|
||||
*q = '\0';
|
||||
manpath_add(dirs, p);
|
||||
}
|
||||
|
||||
fclose(stream);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: man_argv.c,v 1.5 2011/01/03 22:42:37 schwarze Exp $ */
|
||||
/* $Vendor-Id: manpath.h,v 1.5 2011/12/13 20:56:46 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,31 +15,24 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#ifndef MANPATH_H
|
||||
#define MANPATH_H
|
||||
|
||||
#include <sys/types.h>
|
||||
/*
|
||||
* Unsorted list of unique, absolute paths to be searched for manual
|
||||
* databases.
|
||||
*/
|
||||
struct manpaths {
|
||||
int sz;
|
||||
char **paths;
|
||||
};
|
||||
|
||||
#include <assert.h>
|
||||
__BEGIN_DECLS
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
#include "libmandoc.h"
|
||||
void manpath_manconf(struct manpaths *, const char *);
|
||||
void manpath_parse(struct manpaths *, const char *, char *, char *);
|
||||
void manpath_free(struct manpaths *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
int
|
||||
man_args(struct man *m, int line, int *pos, char *buf, char **v)
|
||||
{
|
||||
char *start;
|
||||
|
||||
assert(*pos);
|
||||
*v = start = buf + *pos;
|
||||
assert(' ' != *start);
|
||||
|
||||
if ('\0' == *start)
|
||||
return(ARGS_EOLN);
|
||||
|
||||
*v = mandoc_getarg(v, m->msg, m->data, line, pos);
|
||||
return('"' == *start ? ARGS_QWORD : ARGS_WORD);
|
||||
}
|
||||
#endif /*!MANPATH_H*/
|
348
external/bsd/mdocml/dist/mdoc.3
vendored
348
external/bsd/mdocml/dist/mdoc.3
vendored
|
@ -1,348 +0,0 @@
|
|||
.\" $Vendor-Id: mdoc.3,v 1.55 2011/01/07 15:07:21 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010 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.
|
||||
.\"
|
||||
.Dd January 7, 2011
|
||||
.Dt MDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mdoc ,
|
||||
.Nm mdoc_alloc ,
|
||||
.Nm mdoc_endparse ,
|
||||
.Nm mdoc_free ,
|
||||
.Nm mdoc_meta ,
|
||||
.Nm mdoc_node ,
|
||||
.Nm mdoc_parseln ,
|
||||
.Nm mdoc_reset
|
||||
.Nd mdoc macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In mandoc.h
|
||||
.In mdoc.h
|
||||
.Vt extern const char * const * mdoc_macronames;
|
||||
.Vt extern const char * const * mdoc_argnames;
|
||||
.Ft int
|
||||
.Fo mdoc_addspan
|
||||
.Fa "struct mdoc *mdoc"
|
||||
.Fa "const struct tbl_span *span"
|
||||
.Fc
|
||||
.Ft "struct mdoc *"
|
||||
.Fo mdoc_alloc
|
||||
.Fa "struct regset *regs"
|
||||
.Fa "void *data"
|
||||
.Fa "mandocmsg msgs"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn mdoc_endparse "struct mdoc *mdoc"
|
||||
.Ft void
|
||||
.Fn mdoc_free "struct mdoc *mdoc"
|
||||
.Ft "const struct mdoc_meta *"
|
||||
.Fn mdoc_meta "const struct mdoc *mdoc"
|
||||
.Ft "const struct mdoc_node *"
|
||||
.Fn mdoc_node "const struct mdoc *mdoc"
|
||||
.Ft int
|
||||
.Fo mdoc_parseln
|
||||
.Fa "struct mdoc *mdoc"
|
||||
.Fa "int line"
|
||||
.Fa "char *buf"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn mdoc_reset "struct mdoc *mdoc"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mdoc
|
||||
library parses lines of
|
||||
.Xr mdoc 7
|
||||
input
|
||||
into an abstract syntax tree (AST).
|
||||
.Pp
|
||||
In general, applications initiate a parsing sequence with
|
||||
.Fn mdoc_alloc ,
|
||||
parse each line in a document with
|
||||
.Fn mdoc_parseln ,
|
||||
close the parsing session with
|
||||
.Fn mdoc_endparse ,
|
||||
operate over the syntax tree returned by
|
||||
.Fn mdoc_node
|
||||
and
|
||||
.Fn mdoc_meta ,
|
||||
then free all allocated memory with
|
||||
.Fn mdoc_free .
|
||||
The
|
||||
.Fn mdoc_reset
|
||||
function may be used in order to reset the parser for another input
|
||||
sequence.
|
||||
.Ss Types
|
||||
.Bl -ohang
|
||||
.It Vt struct mdoc
|
||||
An opaque type.
|
||||
Its values are only used privately within the library.
|
||||
.It Vt struct mdoc_node
|
||||
A parsed node.
|
||||
See
|
||||
.Sx Abstract Syntax Tree
|
||||
for details.
|
||||
.El
|
||||
.Ss Functions
|
||||
If
|
||||
.Fn mdoc_addspan ,
|
||||
.Fn mdoc_parseln ,
|
||||
or
|
||||
.Fn mdoc_endparse
|
||||
return 0, calls to any function but
|
||||
.Fn mdoc_reset
|
||||
or
|
||||
.Fn mdoc_free
|
||||
will raise an assertion.
|
||||
.Bl -ohang
|
||||
.It Fn mdoc_addspan
|
||||
Add a table span to the parsing stream.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn mdoc_alloc
|
||||
Allocates a parsing structure.
|
||||
The
|
||||
.Fa data
|
||||
pointer is passed to
|
||||
.Fa msgs .
|
||||
Always returns a valid pointer.
|
||||
The pointer must be freed with
|
||||
.Fn mdoc_free .
|
||||
.It Fn mdoc_reset
|
||||
Reset the parser for another parse routine.
|
||||
After its use,
|
||||
.Fn mdoc_parseln
|
||||
behaves as if invoked for the first time.
|
||||
If it returns 0, memory could not be allocated.
|
||||
.It Fn mdoc_free
|
||||
Free all resources of a parser.
|
||||
The pointer is no longer valid after invocation.
|
||||
.It Fn mdoc_parseln
|
||||
Parse a nil-terminated line of input.
|
||||
This line should not contain the trailing newline.
|
||||
Returns 0 on failure, 1 on success.
|
||||
The input buffer
|
||||
.Fa buf
|
||||
is modified by this function.
|
||||
.It Fn mdoc_endparse
|
||||
Signals that the parse is complete.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn mdoc_node
|
||||
Returns the first node of the parse.
|
||||
.It Fn mdoc_meta
|
||||
Returns the document's parsed meta-data.
|
||||
.El
|
||||
.Ss Variables
|
||||
.Bl -ohang
|
||||
.It Va mdoc_macronames
|
||||
An array of string-ified token names.
|
||||
.It Va mdoc_argnames
|
||||
An array of string-ified token argument names.
|
||||
.El
|
||||
.Ss Abstract Syntax Tree
|
||||
The
|
||||
.Nm
|
||||
functions produce an abstract syntax tree (AST) describing input in a
|
||||
regular form.
|
||||
It may be reviewed at any time with
|
||||
.Fn mdoc_nodes ;
|
||||
however, if called before
|
||||
.Fn mdoc_endparse ,
|
||||
or after
|
||||
.Fn mdoc_endparse
|
||||
or
|
||||
.Fn mdoc_parseln
|
||||
fail, it may be incomplete.
|
||||
.Pp
|
||||
This AST is governed by the ontological
|
||||
rules dictated in
|
||||
.Xr mdoc 7
|
||||
and derives its terminology accordingly.
|
||||
.Qq In-line
|
||||
elements described in
|
||||
.Xr mdoc 7
|
||||
are described simply as
|
||||
.Qq elements .
|
||||
.Pp
|
||||
The AST is composed of
|
||||
.Vt struct mdoc_node
|
||||
nodes with block, head, body, element, root and text types as declared
|
||||
by the
|
||||
.Va type
|
||||
field.
|
||||
Each node also provides its parse point (the
|
||||
.Va line ,
|
||||
.Va sec ,
|
||||
and
|
||||
.Va pos
|
||||
fields), its position in the tree (the
|
||||
.Va parent ,
|
||||
.Va child ,
|
||||
.Va nchild ,
|
||||
.Va next
|
||||
and
|
||||
.Va prev
|
||||
fields) and some type-specific data, in particular, for nodes generated
|
||||
from macros, the generating macro in the
|
||||
.Va tok
|
||||
field.
|
||||
.Pp
|
||||
The tree itself is arranged according to the following normal form,
|
||||
where capitalised non-terminals represent nodes.
|
||||
.Pp
|
||||
.Bl -tag -width "ELEMENTXX" -compact
|
||||
.It ROOT
|
||||
\(<- mnode+
|
||||
.It mnode
|
||||
\(<- BLOCK | ELEMENT | TEXT
|
||||
.It BLOCK
|
||||
\(<- HEAD [TEXT] (BODY [TEXT])+ [TAIL [TEXT]]
|
||||
.It ELEMENT
|
||||
\(<- TEXT*
|
||||
.It HEAD
|
||||
\(<- mnode*
|
||||
.It BODY
|
||||
\(<- mnode* [ENDBODY mnode*]
|
||||
.It TAIL
|
||||
\(<- mnode*
|
||||
.It TEXT
|
||||
\(<- [[:printable:],0x1e]*
|
||||
.El
|
||||
.Pp
|
||||
Of note are the TEXT nodes following the HEAD, BODY and TAIL nodes of
|
||||
the BLOCK production: these refer to punctuation marks.
|
||||
Furthermore, although a TEXT node will generally have a non-zero-length
|
||||
string, in the specific case of
|
||||
.Sq \&.Bd \-literal ,
|
||||
an empty line will produce a zero-length string.
|
||||
Multiple body parts are only found in invocations of
|
||||
.Sq \&Bl \-column ,
|
||||
where a new body introduces a new phrase.
|
||||
.Ss Badly-nested Blocks
|
||||
The ENDBODY node is available to end the formatting associated
|
||||
with a given block before the physical end of that block.
|
||||
It has a non-null
|
||||
.Va end
|
||||
field, is of the BODY
|
||||
.Va type ,
|
||||
has the same
|
||||
.Va tok
|
||||
as the BLOCK it is ending, and has a
|
||||
.Va pending
|
||||
field pointing to that BLOCK's BODY node.
|
||||
It is an indirect child of that BODY node
|
||||
and has no children of its own.
|
||||
.Pp
|
||||
An ENDBODY node is generated when a block ends while one of its child
|
||||
blocks is still open, like in the following example:
|
||||
.Bd -literal -offset indent
|
||||
\&.Ao ao
|
||||
\&.Bo bo ac
|
||||
\&.Ac bc
|
||||
\&.Bc end
|
||||
.Ed
|
||||
.Pp
|
||||
This example results in the following block structure:
|
||||
.Bd -literal -offset indent
|
||||
BLOCK Ao
|
||||
HEAD Ao
|
||||
BODY Ao
|
||||
TEXT ao
|
||||
BLOCK Bo, pending -> Ao
|
||||
HEAD Bo
|
||||
BODY Bo
|
||||
TEXT bo
|
||||
TEXT ac
|
||||
ENDBODY Ao, pending -> Ao
|
||||
TEXT bc
|
||||
TEXT end
|
||||
.Ed
|
||||
.Pp
|
||||
Here, the formatting of the
|
||||
.Sq \&Ao
|
||||
block extends from TEXT ao to TEXT ac,
|
||||
while the formatting of the
|
||||
.Sq \&Bo
|
||||
block extends from TEXT bo to TEXT bc.
|
||||
It renders as follows in
|
||||
.Fl T Ns Cm ascii
|
||||
mode:
|
||||
.Pp
|
||||
.Dl <ao [bo ac> bc] end
|
||||
.Pp
|
||||
Support for badly-nested blocks is only provided for backward
|
||||
compatibility with some older
|
||||
.Xr mdoc 7
|
||||
implementations.
|
||||
Using badly-nested blocks is
|
||||
.Em strongly discouraged :
|
||||
the
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml
|
||||
front-ends are unable to render them in any meaningful way.
|
||||
Furthermore, behaviour when encountering badly-nested blocks is not
|
||||
consistent across troff implementations, especially when using multiple
|
||||
levels of badly-nested blocks.
|
||||
.Sh EXAMPLES
|
||||
The following example reads lines from stdin and parses them, operating
|
||||
on the finished parse tree with
|
||||
.Fn parsed .
|
||||
This example does not error-check nor free memory upon failure.
|
||||
.Bd -literal -offset indent
|
||||
struct regset regs;
|
||||
struct mdoc *mdoc;
|
||||
const struct mdoc_node *node;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int line;
|
||||
|
||||
bzero(®s, sizeof(struct regset));
|
||||
line = 1;
|
||||
mdoc = mdoc_alloc(®s, NULL, NULL);
|
||||
buf = NULL;
|
||||
alloc_len = 0;
|
||||
|
||||
while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
|
||||
if (len && buflen[len - 1] = '\en')
|
||||
buf[len - 1] = '\e0';
|
||||
if ( ! mdoc_parseln(mdoc, line, buf))
|
||||
errx(1, "mdoc_parseln");
|
||||
line++;
|
||||
}
|
||||
|
||||
if ( ! mdoc_endparse(mdoc))
|
||||
errx(1, "mdoc_endparse");
|
||||
if (NULL == (node = mdoc_node(mdoc)))
|
||||
errx(1, "mdoc_node");
|
||||
|
||||
parsed(mdoc, node);
|
||||
mdoc_free(mdoc);
|
||||
.Ed
|
||||
.Pp
|
||||
To compile this, execute
|
||||
.Pp
|
||||
.Dl % cc main.c libmdoc.a libmandoc.a
|
||||
.Pp
|
||||
where
|
||||
.Pa main.c
|
||||
is the example file.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr mdoc 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
1797
external/bsd/mdocml/dist/mdoc.7
vendored
1797
external/bsd/mdocml/dist/mdoc.7
vendored
File diff suppressed because it is too large
Load diff
281
external/bsd/mdocml/dist/mdoc.c
vendored
281
external/bsd/mdocml/dist/mdoc.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mdoc.c,v 1.177 2011/01/03 11:27:33 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc.c,v 1.196 2011/09/30 00:13:28 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
@ -96,11 +97,11 @@ static struct mdoc_node *node_alloc(struct mdoc *, int, int,
|
|||
enum mdoct, enum mdoc_type);
|
||||
static int node_append(struct mdoc *,
|
||||
struct mdoc_node *);
|
||||
#if 0
|
||||
static int mdoc_preptext(struct mdoc *, int, char *, int);
|
||||
#endif
|
||||
static int mdoc_ptext(struct mdoc *, int, char *, int);
|
||||
static int mdoc_pmacro(struct mdoc *, int, char *, int);
|
||||
static int mdoc_span_alloc(struct mdoc *,
|
||||
const struct tbl_span *);
|
||||
|
||||
|
||||
const struct mdoc_node *
|
||||
mdoc_node(const struct mdoc *m)
|
||||
|
@ -141,6 +142,8 @@ mdoc_free1(struct mdoc *mdoc)
|
|||
free(mdoc->meta.vol);
|
||||
if (mdoc->meta.msec)
|
||||
free(mdoc->meta.msec);
|
||||
if (mdoc->meta.date)
|
||||
free(mdoc->meta.date);
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,6 +160,7 @@ mdoc_alloc1(struct mdoc *mdoc)
|
|||
mdoc->last = mandoc_calloc(1, sizeof(struct mdoc_node));
|
||||
mdoc->first = mdoc->last;
|
||||
mdoc->last->type = MDOC_ROOT;
|
||||
mdoc->last->tok = MDOC_MAX;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
}
|
||||
|
||||
|
@ -193,15 +197,14 @@ mdoc_free(struct mdoc *mdoc)
|
|||
* Allocate volatile and non-volatile parse resources.
|
||||
*/
|
||||
struct mdoc *
|
||||
mdoc_alloc(struct regset *regs, void *data, mandocmsg msg)
|
||||
mdoc_alloc(struct roff *roff, struct mparse *parse)
|
||||
{
|
||||
struct mdoc *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct mdoc));
|
||||
|
||||
p->msg = msg;
|
||||
p->data = data;
|
||||
p->regs = regs;
|
||||
p->parse = parse;
|
||||
p->roff = roff;
|
||||
|
||||
mdoc_hash_init();
|
||||
mdoc_alloc1(p);
|
||||
|
@ -225,20 +228,51 @@ mdoc_endparse(struct mdoc *m)
|
|||
}
|
||||
|
||||
int
|
||||
mdoc_addspan(struct mdoc *m, const struct tbl_span *sp)
|
||||
mdoc_addeqn(struct mdoc *m, const struct eqn *ep)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
/* FIXME: grab from span. */
|
||||
mdoc_pmsg(m, 0, 0, MANDOCERR_NOTEXT);
|
||||
mdoc_pmsg(m, ep->ln, ep->pos, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(mdoc_span_alloc(m, sp));
|
||||
n = node_alloc(m, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
|
||||
n->eqn = ep;
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_addspan(struct mdoc *m, const struct tbl_span *sp)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
mdoc_pmsg(m, sp->line, 0, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
n = node_alloc(m, sp->line, 0, MDOC_MAX, MDOC_TBL);
|
||||
n->span = sp;
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,34 +294,18 @@ mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
|
|||
* whether this mode is on or off.
|
||||
* Note that this mode is also switched by the Sh macro.
|
||||
*/
|
||||
if (m->regs->regs[(int)REG_nS].set) {
|
||||
if (m->regs->regs[(int)REG_nS].v.u)
|
||||
if (roff_regisset(m->roff, REG_nS)) {
|
||||
if (roff_regget(m->roff, REG_nS))
|
||||
m->flags |= MDOC_SYNOPSIS;
|
||||
else
|
||||
m->flags &= ~MDOC_SYNOPSIS;
|
||||
}
|
||||
|
||||
return(('.' == buf[offs] || '\'' == buf[offs]) ?
|
||||
return(mandoc_getcontrol(buf, &offs) ?
|
||||
mdoc_pmacro(m, ln, buf, offs) :
|
||||
mdoc_ptext(m, ln, buf, offs));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_vmsg(struct mdoc *mdoc, enum mandocerr t,
|
||||
int ln, int pos, const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return((*mdoc->msg)(t, mdoc->data, ln, pos, buf));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_macro(MACRO_PROT_ARGS)
|
||||
{
|
||||
|
@ -314,8 +332,9 @@ mdoc_macro(MACRO_PROT_ARGS)
|
|||
m->meta.vol = mandoc_strdup("LOCAL");
|
||||
if (NULL == m->meta.os)
|
||||
m->meta.os = mandoc_strdup("LOCAL");
|
||||
if (0 == m->meta.date)
|
||||
m->meta.date = time(NULL);
|
||||
if (NULL == m->meta.date)
|
||||
m->meta.date = mandoc_normdate
|
||||
(m->parse, NULL, line, ppos);
|
||||
m->flags |= MDOC_PBODY;
|
||||
}
|
||||
|
||||
|
@ -546,37 +565,13 @@ mdoc_elem_alloc(struct mdoc *m, int line, int pos,
|
|||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_span_alloc(struct mdoc *m, const struct tbl_span *sp)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* FIXME: grab from tbl_span. */
|
||||
n = node_alloc(m, 0, 0, MDOC_MAX, MDOC_TBL);
|
||||
n->span = sp;
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
size_t sv, len;
|
||||
|
||||
len = strlen(p);
|
||||
|
||||
n = node_alloc(m, line, pos, MDOC_MAX, MDOC_TEXT);
|
||||
n->string = mandoc_malloc(len + 1);
|
||||
sv = strlcpy(n->string, p, len + 1);
|
||||
|
||||
/* Prohibit truncation. */
|
||||
assert(sv < len + 1);
|
||||
n->string = roff_strdup(m->roff, p);
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
return(0);
|
||||
|
@ -652,6 +647,59 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
|
|||
mdoc_node_free(p);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Pre-treat a text line.
|
||||
* Text lines can consist of equations, which must be handled apart from
|
||||
* the regular text.
|
||||
* Thus, use this function to step through a line checking if it has any
|
||||
* equations embedded in it.
|
||||
* This must handle multiple equations AND equations that do not end at
|
||||
* the end-of-line, i.e., will re-enter in the next roff parse.
|
||||
*/
|
||||
static int
|
||||
mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
{
|
||||
char *start, *end;
|
||||
char delim;
|
||||
|
||||
while ('\0' != buf[offs]) {
|
||||
/* Mark starting position if eqn is set. */
|
||||
start = NULL;
|
||||
if ('\0' != (delim = roff_eqndelim(m->roff)))
|
||||
if (NULL != (start = strchr(buf + offs, delim)))
|
||||
*start++ = '\0';
|
||||
|
||||
/* Parse text as normal. */
|
||||
if ( ! mdoc_ptext(m, line, buf, offs))
|
||||
return(0);
|
||||
|
||||
/* Continue only if an equation exists. */
|
||||
if (NULL == start)
|
||||
break;
|
||||
|
||||
/* Read past the end of the equation. */
|
||||
offs += start - (buf + offs);
|
||||
assert(start == &buf[offs]);
|
||||
if (NULL != (end = strchr(buf + offs, delim))) {
|
||||
*end++ = '\0';
|
||||
while (' ' == *end)
|
||||
end++;
|
||||
}
|
||||
|
||||
/* Parse the equation itself. */
|
||||
roff_openeqn(m->roff, NULL, line, offs, buf);
|
||||
|
||||
/* Process a finished equation? */
|
||||
if (roff_closeeqn(m->roff))
|
||||
if ( ! mdoc_addeqn(m, roff_eqn(m->roff)))
|
||||
return(0);
|
||||
offs += (end - (buf + offs));
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parse free-form text, that is, a line that does not begin with the
|
||||
|
@ -663,15 +711,6 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
|||
char *c, *ws, *end;
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* Ignore bogus comments. */
|
||||
|
||||
if ('\\' == buf[offs] &&
|
||||
'.' == buf[offs + 1] &&
|
||||
'"' == buf[offs + 2]) {
|
||||
mdoc_pmsg(m, line, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
|
@ -714,11 +753,6 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
|||
ws = NULL;
|
||||
for (c = end = buf + offs; *c; c++) {
|
||||
switch (*c) {
|
||||
case '-':
|
||||
if (mandoc_hyph(buf + offs, c))
|
||||
*c = ASCII_HYPH;
|
||||
ws = NULL;
|
||||
break;
|
||||
case ' ':
|
||||
if (NULL == ws)
|
||||
ws = c;
|
||||
|
@ -798,64 +832,57 @@ static int
|
|||
mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
{
|
||||
enum mdoct tok;
|
||||
int i, j, sv;
|
||||
int i, sv;
|
||||
char mac[5];
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* Empty lines are ignored. */
|
||||
/* Empty post-control lines are ignored. */
|
||||
|
||||
offs++;
|
||||
|
||||
if ('\0' == buf[offs])
|
||||
if ('"' == buf[offs]) {
|
||||
mdoc_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
} else if ('\0' == buf[offs])
|
||||
return(1);
|
||||
|
||||
i = offs;
|
||||
|
||||
/* Accept tabs/whitespace after the initial control char. */
|
||||
|
||||
if (' ' == buf[i] || '\t' == buf[i]) {
|
||||
i++;
|
||||
while (buf[i] && (' ' == buf[i] || '\t' == buf[i]))
|
||||
i++;
|
||||
if ('\0' == buf[i])
|
||||
return(1);
|
||||
}
|
||||
|
||||
sv = i;
|
||||
sv = offs;
|
||||
|
||||
/*
|
||||
* Copy the first word into a nil-terminated buffer.
|
||||
* Stop copying when a tab, space, or eoln is encountered.
|
||||
*/
|
||||
|
||||
j = 0;
|
||||
while (j < 4 && '\0' != buf[i] && ' ' != buf[i] && '\t' != buf[i])
|
||||
mac[j++] = buf[i++];
|
||||
mac[j] = '\0';
|
||||
i = 0;
|
||||
while (i < 4 && '\0' != buf[offs] &&
|
||||
' ' != buf[offs] && '\t' != buf[offs])
|
||||
mac[i++] = buf[offs++];
|
||||
|
||||
mac[i] = '\0';
|
||||
|
||||
tok = (i > 1 || i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
|
||||
|
||||
tok = (j > 1 || j < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
|
||||
if (MDOC_MAX == tok) {
|
||||
mdoc_vmsg(m, MANDOCERR_MACRO, ln, sv, "%s", buf + sv - 1);
|
||||
mandoc_vmsg(MANDOCERR_MACRO, m->parse,
|
||||
ln, sv, "%s", buf + sv - 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Disregard the first trailing tab, if applicable. */
|
||||
|
||||
if ('\t' == buf[i])
|
||||
i++;
|
||||
if ('\t' == buf[offs])
|
||||
offs++;
|
||||
|
||||
/* Jump to the next non-whitespace word. */
|
||||
|
||||
while (buf[i] && ' ' == buf[i])
|
||||
i++;
|
||||
while (buf[offs] && ' ' == buf[offs])
|
||||
offs++;
|
||||
|
||||
/*
|
||||
* Trailing whitespace. Note that tabs are allowed to be passed
|
||||
* into the parser as "text", so we only warn about spaces here.
|
||||
*/
|
||||
|
||||
if ('\0' == buf[i] && ' ' == buf[i - 1])
|
||||
mdoc_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE);
|
||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||
mdoc_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
/*
|
||||
* If an initial macro or a list invocation, divert directly
|
||||
|
@ -863,7 +890,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
|||
*/
|
||||
|
||||
if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) {
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &i, buf))
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
|
@ -902,7 +929,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
|||
|
||||
/* Normal processing of a macro. */
|
||||
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &i, buf))
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf))
|
||||
goto err;
|
||||
|
||||
return(1);
|
||||
|
@ -913,4 +940,48 @@ err: /* Error out. */
|
|||
return(0);
|
||||
}
|
||||
|
||||
enum mdelim
|
||||
mdoc_isdelim(const char *p)
|
||||
{
|
||||
|
||||
if ('\0' == p[0])
|
||||
return(DELIM_NONE);
|
||||
|
||||
if ('\0' == p[1])
|
||||
switch (p[0]) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
return(DELIM_OPEN);
|
||||
case('|'):
|
||||
return(DELIM_MIDDLE);
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
return(DELIM_CLOSE);
|
||||
default:
|
||||
return(DELIM_NONE);
|
||||
}
|
||||
|
||||
if ('\\' != p[0])
|
||||
return(DELIM_NONE);
|
||||
|
||||
if (0 == strcmp(p + 1, "."))
|
||||
return(DELIM_CLOSE);
|
||||
if (0 == strcmp(p + 1, "*(Ba"))
|
||||
return(DELIM_MIDDLE);
|
||||
|
||||
return(DELIM_NONE);
|
||||
}
|
||||
|
|
210
external/bsd/mdocml/dist/mdoc.h
vendored
210
external/bsd/mdocml/dist/mdoc.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mdoc.h,v 1.114 2011/01/01 12:18:37 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc.h,v 1.122 2011/03/22 14:05:45 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,9 +17,6 @@
|
|||
#ifndef MDOC_H
|
||||
#define MDOC_H
|
||||
|
||||
/*
|
||||
* What follows is a list of ALL possible macros.
|
||||
*/
|
||||
enum mdoct {
|
||||
MDOC_Ap = 0,
|
||||
MDOC_Dd,
|
||||
|
@ -146,43 +143,37 @@ enum mdoct {
|
|||
MDOC_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* What follows is a list of ALL possible macro arguments.
|
||||
*/
|
||||
enum mdocargt {
|
||||
MDOC_Split,
|
||||
MDOC_Nosplit,
|
||||
MDOC_Ragged,
|
||||
MDOC_Unfilled,
|
||||
MDOC_Literal,
|
||||
MDOC_File,
|
||||
MDOC_Offset,
|
||||
MDOC_Bullet,
|
||||
MDOC_Dash,
|
||||
MDOC_Hyphen,
|
||||
MDOC_Item,
|
||||
MDOC_Enum,
|
||||
MDOC_Tag,
|
||||
MDOC_Diag,
|
||||
MDOC_Hang,
|
||||
MDOC_Ohang,
|
||||
MDOC_Inset,
|
||||
MDOC_Column,
|
||||
MDOC_Width,
|
||||
MDOC_Compact,
|
||||
MDOC_Std,
|
||||
MDOC_Filled,
|
||||
MDOC_Words,
|
||||
MDOC_Emphasis,
|
||||
MDOC_Symbolic,
|
||||
MDOC_Nested,
|
||||
MDOC_Centred,
|
||||
MDOC_Split, /* -split */
|
||||
MDOC_Nosplit, /* -nospli */
|
||||
MDOC_Ragged, /* -ragged */
|
||||
MDOC_Unfilled, /* -unfilled */
|
||||
MDOC_Literal, /* -literal */
|
||||
MDOC_File, /* -file */
|
||||
MDOC_Offset, /* -offset */
|
||||
MDOC_Bullet, /* -bullet */
|
||||
MDOC_Dash, /* -dash */
|
||||
MDOC_Hyphen, /* -hyphen */
|
||||
MDOC_Item, /* -item */
|
||||
MDOC_Enum, /* -enum */
|
||||
MDOC_Tag, /* -tag */
|
||||
MDOC_Diag, /* -diag */
|
||||
MDOC_Hang, /* -hang */
|
||||
MDOC_Ohang, /* -ohang */
|
||||
MDOC_Inset, /* -inset */
|
||||
MDOC_Column, /* -column */
|
||||
MDOC_Width, /* -width */
|
||||
MDOC_Compact, /* -compact */
|
||||
MDOC_Std, /* -std */
|
||||
MDOC_Filled, /* -filled */
|
||||
MDOC_Words, /* -words */
|
||||
MDOC_Emphasis, /* -emphasis */
|
||||
MDOC_Symbolic, /* -symbolic */
|
||||
MDOC_Nested, /* -nested */
|
||||
MDOC_Centred, /* -centered */
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of a syntax node.
|
||||
*/
|
||||
enum mdoc_type {
|
||||
MDOC_TEXT,
|
||||
MDOC_ELEM,
|
||||
|
@ -191,47 +182,47 @@ enum mdoc_type {
|
|||
MDOC_BODY,
|
||||
MDOC_BLOCK,
|
||||
MDOC_TBL,
|
||||
MDOC_EQN,
|
||||
MDOC_ROOT
|
||||
};
|
||||
|
||||
/*
|
||||
* Section (named/unnamed) of `Sh'. Note that these appear in the
|
||||
* conventional order imposed by mdoc.7.
|
||||
* conventional order imposed by mdoc.7. In the case of SEC_NONE, no
|
||||
* section has been invoked (this shouldn't happen). SEC_CUSTOM refers
|
||||
* to other sections.
|
||||
*/
|
||||
enum mdoc_sec {
|
||||
SEC_NONE = 0, /* No section, yet. */
|
||||
SEC_NAME,
|
||||
SEC_LIBRARY,
|
||||
SEC_SYNOPSIS,
|
||||
SEC_DESCRIPTION,
|
||||
SEC_IMPLEMENTATION,
|
||||
SEC_RETURN_VALUES,
|
||||
SEC_ENVIRONMENT,
|
||||
SEC_FILES,
|
||||
SEC_EXIT_STATUS,
|
||||
SEC_EXAMPLES,
|
||||
SEC_DIAGNOSTICS,
|
||||
SEC_COMPATIBILITY,
|
||||
SEC_ERRORS,
|
||||
SEC_SEE_ALSO,
|
||||
SEC_STANDARDS,
|
||||
SEC_HISTORY,
|
||||
SEC_AUTHORS,
|
||||
SEC_CAVEATS,
|
||||
SEC_BUGS,
|
||||
SEC_SECURITY,
|
||||
SEC_CUSTOM, /* User-defined. */
|
||||
SEC_NONE = 0,
|
||||
SEC_NAME, /* NAME */
|
||||
SEC_LIBRARY, /* LIBRARY */
|
||||
SEC_SYNOPSIS, /* SYNOPSIS */
|
||||
SEC_DESCRIPTION, /* DESCRIPTION */
|
||||
SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */
|
||||
SEC_RETURN_VALUES, /* RETURN VALUES */
|
||||
SEC_ENVIRONMENT, /* ENVIRONMENT */
|
||||
SEC_FILES, /* FILES */
|
||||
SEC_EXIT_STATUS, /* EXIT STATUS */
|
||||
SEC_EXAMPLES, /* EXAMPLES */
|
||||
SEC_DIAGNOSTICS, /* DIAGNOSTICS */
|
||||
SEC_COMPATIBILITY, /* COMPATIBILITY */
|
||||
SEC_ERRORS, /* ERRORS */
|
||||
SEC_SEE_ALSO, /* SEE ALSO */
|
||||
SEC_STANDARDS, /* STANDARDS */
|
||||
SEC_HISTORY, /* HISTORY */
|
||||
SEC_AUTHORS, /* AUTHORS */
|
||||
SEC_CAVEATS, /* CAVEATS */
|
||||
SEC_BUGS, /* BUGS */
|
||||
SEC_SECURITY, /* SECURITY */
|
||||
SEC_CUSTOM,
|
||||
SEC__MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Information from prologue.
|
||||
*/
|
||||
struct mdoc_meta {
|
||||
char *msec; /* `Dt' section (1, 3p, etc.) */
|
||||
char *vol; /* `Dt' volume (implied) */
|
||||
char *arch; /* `Dt' arch (i386, etc.) */
|
||||
time_t date; /* `Dd' normalised date */
|
||||
char *date; /* `Dd' normalised date */
|
||||
char *title; /* `Dt' title (FOO, etc.) */
|
||||
char *os; /* `Os' system (OpenBSD, etc.) */
|
||||
char *name; /* leading `Nm' name */
|
||||
|
@ -269,68 +260,50 @@ enum mdoc_endbody {
|
|||
ENDBODY_NOSPACE /* is broken: don't append a space */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `Bl' list type.
|
||||
*/
|
||||
enum mdoc_list {
|
||||
LIST__NONE = 0,
|
||||
LIST_bullet,
|
||||
LIST_column,
|
||||
LIST_dash,
|
||||
LIST_diag,
|
||||
LIST_enum,
|
||||
LIST_hang,
|
||||
LIST_hyphen,
|
||||
LIST_inset,
|
||||
LIST_item,
|
||||
LIST_ohang,
|
||||
LIST_tag,
|
||||
LIST_bullet, /* -bullet */
|
||||
LIST_column, /* -column */
|
||||
LIST_dash, /* -dash */
|
||||
LIST_diag, /* -diag */
|
||||
LIST_enum, /* -enum */
|
||||
LIST_hang, /* -hang */
|
||||
LIST_hyphen, /* -hyphen */
|
||||
LIST_inset, /* -inset */
|
||||
LIST_item, /* -item */
|
||||
LIST_ohang, /* -ohang */
|
||||
LIST_tag, /* -tag */
|
||||
LIST_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `Bd' display type.
|
||||
*/
|
||||
enum mdoc_disp {
|
||||
DISP__NONE = 0,
|
||||
DISP_centred,
|
||||
DISP_ragged,
|
||||
DISP_unfilled,
|
||||
DISP_filled,
|
||||
DISP_literal
|
||||
DISP_centred, /* -centered */
|
||||
DISP_ragged, /* -ragged */
|
||||
DISP_unfilled, /* -unfilled */
|
||||
DISP_filled, /* -filled */
|
||||
DISP_literal /* -literal */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `An' splitting argument.
|
||||
*/
|
||||
enum mdoc_auth {
|
||||
AUTH__NONE = 0,
|
||||
AUTH_split,
|
||||
AUTH_nosplit
|
||||
AUTH_split, /* -split */
|
||||
AUTH_nosplit /* -nosplit */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `Bf' font type.
|
||||
*/
|
||||
enum mdoc_font {
|
||||
FONT__NONE = 0,
|
||||
FONT_Em,
|
||||
FONT_Li,
|
||||
FONT_Sy
|
||||
FONT_Em, /* Em, -emphasis */
|
||||
FONT_Li, /* Li, -literal */
|
||||
FONT_Sy /* Sy, -symbolic */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `Bd'.
|
||||
*/
|
||||
struct mdoc_bd {
|
||||
const char *offs; /* -offset */
|
||||
enum mdoc_disp type; /* -ragged, etc. */
|
||||
int comp; /* -compact */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `Bl'.
|
||||
*/
|
||||
struct mdoc_bl {
|
||||
const char *width; /* -width */
|
||||
const char *offs; /* -offset */
|
||||
|
@ -340,22 +313,16 @@ struct mdoc_bl {
|
|||
const char **cols; /* -column val ptr */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `Bf'.
|
||||
*/
|
||||
struct mdoc_bf {
|
||||
enum mdoc_font font; /* font */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `An'.
|
||||
*/
|
||||
struct mdoc_an {
|
||||
enum mdoc_auth auth; /* -split, etc. */
|
||||
};
|
||||
|
||||
struct mdoc_rs {
|
||||
struct mdoc_node *child_J; /* pointer to %J */
|
||||
int quote_T; /* whether to quote %T */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -390,6 +357,8 @@ struct mdoc_node {
|
|||
#define MDOC_LINE (1 << 3) /* first macro/text on line */
|
||||
#define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting */
|
||||
#define MDOC_ENDED (1 << 5) /* rendering has been ended */
|
||||
#define MDOC_DELIMO (1 << 6)
|
||||
#define MDOC_DELIMC (1 << 7)
|
||||
enum mdoc_type type; /* AST node type */
|
||||
enum mdoc_sec sec; /* current named section */
|
||||
union mdoc_data *norm; /* normalised args */
|
||||
|
@ -401,35 +370,22 @@ struct mdoc_node {
|
|||
struct mdoc_node *tail; /* BLOCK */
|
||||
char *string; /* TEXT */
|
||||
const struct tbl_span *span; /* TBL */
|
||||
const struct eqn *eqn; /* EQN */
|
||||
enum mdoc_endbody end; /* BODY */
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of macros. Index is enum mdoct. Indexing into this returns
|
||||
* the normalised name, e.g., mdoc_macronames[MDOC_Sh] -> "Sh".
|
||||
*/
|
||||
/* Names of macros. Index is enum mdoct. */
|
||||
extern const char *const *mdoc_macronames;
|
||||
|
||||
/*
|
||||
* Names of macro args. Index is enum mdocargt. Indexing into this
|
||||
* returns the normalised name, e.g., mdoc_argnames[MDOC_File] ->
|
||||
* "file".
|
||||
*/
|
||||
/* Names of macro args. Index is enum mdocargt. */
|
||||
extern const char *const *mdoc_argnames;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct mdoc;
|
||||
|
||||
void mdoc_free(struct mdoc *);
|
||||
struct mdoc *mdoc_alloc(struct regset *, void *, mandocmsg);
|
||||
void mdoc_reset(struct mdoc *);
|
||||
int mdoc_parseln(struct mdoc *, int, char *, int);
|
||||
const struct mdoc_node *mdoc_node(const struct mdoc *);
|
||||
const struct mdoc_meta *mdoc_meta(const struct mdoc *);
|
||||
int mdoc_endparse(struct mdoc *);
|
||||
int mdoc_addspan(struct mdoc *,
|
||||
const struct tbl_span *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
712
external/bsd/mdocml/dist/mdoc_argv.c
vendored
712
external/bsd/mdocml/dist/mdoc_argv.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mdoc_argv.c,v 1.62 2010/12/24 14:00:40 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc_argv.c,v 1.81 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -21,45 +21,48 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
/*
|
||||
* Routines to parse arguments of macros. Arguments follow the syntax
|
||||
* of `-arg [val [valN...]]'. Arguments come in all types: quoted
|
||||
* arguments, multiple arguments per value, no-value arguments, etc.
|
||||
*
|
||||
* There's no limit to the number or arguments that may be allocated.
|
||||
*/
|
||||
#define MULTI_STEP 5 /* pre-allocate argument values */
|
||||
#define DELIMSZ 6 /* max possible size of a delimiter */
|
||||
|
||||
#define ARGV_NONE (1 << 0)
|
||||
#define ARGV_SINGLE (1 << 1)
|
||||
#define ARGV_MULTI (1 << 2)
|
||||
#define ARGV_OPT_SINGLE (1 << 3)
|
||||
enum argsflag {
|
||||
ARGSFL_NONE = 0,
|
||||
ARGSFL_DELIM, /* handle delimiters of [[::delim::][ ]+]+ */
|
||||
ARGSFL_TABSEP /* handle tab/`Ta' separated phrases */
|
||||
};
|
||||
|
||||
#define MULTI_STEP 5
|
||||
enum argvflag {
|
||||
ARGV_NONE, /* no args to flag (e.g., -split) */
|
||||
ARGV_SINGLE, /* one arg to flag (e.g., -file xxx) */
|
||||
ARGV_MULTI, /* multiple args (e.g., -column xxx yyy) */
|
||||
ARGV_OPT_SINGLE /* optional arg (e.g., -offset [xxx]) */
|
||||
};
|
||||
|
||||
static enum mdocargt argv_a2arg(enum mdoct, const char *);
|
||||
struct mdocarg {
|
||||
enum argsflag flags;
|
||||
const enum mdocargt *argvs;
|
||||
};
|
||||
|
||||
static void argn_free(struct mdoc_arg *, int);
|
||||
static enum margserr args(struct mdoc *, int, int *,
|
||||
char *, int, char **);
|
||||
static int argv(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_single(struct mdoc *, int,
|
||||
char *, enum argsflag, char **);
|
||||
static int args_checkpunct(const char *, int);
|
||||
static int argv_multi(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_opt_single(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_multi(struct mdoc *, int,
|
||||
static int argv_single(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
|
||||
/* Per-argument flags. */
|
||||
|
||||
static int mdoc_argvflags[MDOC_ARG_MAX] = {
|
||||
static const enum argvflag argvflags[MDOC_ARG_MAX] = {
|
||||
ARGV_NONE, /* MDOC_Split */
|
||||
ARGV_NONE, /* MDOC_Nosplit */
|
||||
ARGV_NONE, /* MDOC_Ragged */
|
||||
|
@ -88,129 +91,183 @@ static int mdoc_argvflags[MDOC_ARG_MAX] = {
|
|||
ARGV_NONE /* MDOC_Symbolic */
|
||||
};
|
||||
|
||||
static int mdoc_argflags[MDOC_MAX] = {
|
||||
0, /* Ap */
|
||||
0, /* Dd */
|
||||
0, /* Dt */
|
||||
0, /* Os */
|
||||
0, /* Sh */
|
||||
0, /* Ss */
|
||||
0, /* Pp */
|
||||
ARGS_DELIM, /* D1 */
|
||||
ARGS_DELIM, /* Dl */
|
||||
0, /* Bd */
|
||||
0, /* Ed */
|
||||
0, /* Bl */
|
||||
0, /* El */
|
||||
0, /* It */
|
||||
ARGS_DELIM, /* Ad */
|
||||
ARGS_DELIM, /* An */
|
||||
ARGS_DELIM, /* Ar */
|
||||
0, /* Cd */
|
||||
ARGS_DELIM, /* Cm */
|
||||
ARGS_DELIM, /* Dv */
|
||||
ARGS_DELIM, /* Er */
|
||||
ARGS_DELIM, /* Ev */
|
||||
0, /* Ex */
|
||||
ARGS_DELIM, /* Fa */
|
||||
0, /* Fd */
|
||||
ARGS_DELIM, /* Fl */
|
||||
ARGS_DELIM, /* Fn */
|
||||
ARGS_DELIM, /* Ft */
|
||||
ARGS_DELIM, /* Ic */
|
||||
0, /* In */
|
||||
ARGS_DELIM, /* Li */
|
||||
0, /* Nd */
|
||||
ARGS_DELIM, /* Nm */
|
||||
ARGS_DELIM, /* Op */
|
||||
0, /* Ot */
|
||||
ARGS_DELIM, /* Pa */
|
||||
0, /* Rv */
|
||||
ARGS_DELIM, /* St */
|
||||
ARGS_DELIM, /* Va */
|
||||
ARGS_DELIM, /* Vt */
|
||||
ARGS_DELIM, /* Xr */
|
||||
0, /* %A */
|
||||
0, /* %B */
|
||||
0, /* %D */
|
||||
0, /* %I */
|
||||
0, /* %J */
|
||||
0, /* %N */
|
||||
0, /* %O */
|
||||
0, /* %P */
|
||||
0, /* %R */
|
||||
0, /* %T */
|
||||
0, /* %V */
|
||||
ARGS_DELIM, /* Ac */
|
||||
0, /* Ao */
|
||||
ARGS_DELIM, /* Aq */
|
||||
ARGS_DELIM, /* At */
|
||||
ARGS_DELIM, /* Bc */
|
||||
0, /* Bf */
|
||||
0, /* Bo */
|
||||
ARGS_DELIM, /* Bq */
|
||||
ARGS_DELIM, /* Bsx */
|
||||
ARGS_DELIM, /* Bx */
|
||||
0, /* Db */
|
||||
ARGS_DELIM, /* Dc */
|
||||
0, /* Do */
|
||||
ARGS_DELIM, /* Dq */
|
||||
ARGS_DELIM, /* Ec */
|
||||
0, /* Ef */
|
||||
ARGS_DELIM, /* Em */
|
||||
0, /* Eo */
|
||||
ARGS_DELIM, /* Fx */
|
||||
ARGS_DELIM, /* Ms */
|
||||
ARGS_DELIM, /* No */
|
||||
ARGS_DELIM, /* Ns */
|
||||
ARGS_DELIM, /* Nx */
|
||||
ARGS_DELIM, /* Ox */
|
||||
ARGS_DELIM, /* Pc */
|
||||
ARGS_DELIM, /* Pf */
|
||||
0, /* Po */
|
||||
ARGS_DELIM, /* Pq */
|
||||
ARGS_DELIM, /* Qc */
|
||||
ARGS_DELIM, /* Ql */
|
||||
0, /* Qo */
|
||||
ARGS_DELIM, /* Qq */
|
||||
0, /* Re */
|
||||
0, /* Rs */
|
||||
ARGS_DELIM, /* Sc */
|
||||
0, /* So */
|
||||
ARGS_DELIM, /* Sq */
|
||||
0, /* Sm */
|
||||
ARGS_DELIM, /* Sx */
|
||||
ARGS_DELIM, /* Sy */
|
||||
ARGS_DELIM, /* Tn */
|
||||
ARGS_DELIM, /* Ux */
|
||||
ARGS_DELIM, /* Xc */
|
||||
0, /* Xo */
|
||||
0, /* Fo */
|
||||
0, /* Fc */
|
||||
0, /* Oo */
|
||||
ARGS_DELIM, /* Oc */
|
||||
0, /* Bk */
|
||||
0, /* Ek */
|
||||
0, /* Bt */
|
||||
0, /* Hf */
|
||||
0, /* Fr */
|
||||
0, /* Ud */
|
||||
0, /* Lb */
|
||||
0, /* Lp */
|
||||
ARGS_DELIM, /* Lk */
|
||||
ARGS_DELIM, /* Mt */
|
||||
ARGS_DELIM, /* Brq */
|
||||
0, /* Bro */
|
||||
ARGS_DELIM, /* Brc */
|
||||
0, /* %C */
|
||||
0, /* Es */
|
||||
0, /* En */
|
||||
0, /* Dx */
|
||||
0, /* %Q */
|
||||
0, /* br */
|
||||
0, /* sp */
|
||||
0, /* %U */
|
||||
0, /* Ta */
|
||||
static const enum mdocargt args_Ex[] = {
|
||||
MDOC_Std,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const enum mdocargt args_An[] = {
|
||||
MDOC_Split,
|
||||
MDOC_Nosplit,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const enum mdocargt args_Bd[] = {
|
||||
MDOC_Ragged,
|
||||
MDOC_Unfilled,
|
||||
MDOC_Filled,
|
||||
MDOC_Literal,
|
||||
MDOC_File,
|
||||
MDOC_Offset,
|
||||
MDOC_Compact,
|
||||
MDOC_Centred,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const enum mdocargt args_Bf[] = {
|
||||
MDOC_Emphasis,
|
||||
MDOC_Literal,
|
||||
MDOC_Symbolic,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const enum mdocargt args_Bk[] = {
|
||||
MDOC_Words,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const enum mdocargt args_Bl[] = {
|
||||
MDOC_Bullet,
|
||||
MDOC_Dash,
|
||||
MDOC_Hyphen,
|
||||
MDOC_Item,
|
||||
MDOC_Enum,
|
||||
MDOC_Tag,
|
||||
MDOC_Diag,
|
||||
MDOC_Hang,
|
||||
MDOC_Ohang,
|
||||
MDOC_Inset,
|
||||
MDOC_Column,
|
||||
MDOC_Width,
|
||||
MDOC_Offset,
|
||||
MDOC_Compact,
|
||||
MDOC_Nested,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_NONE, NULL }, /* Ap */
|
||||
{ ARGSFL_NONE, NULL }, /* Dd */
|
||||
{ ARGSFL_NONE, NULL }, /* Dt */
|
||||
{ ARGSFL_NONE, NULL }, /* Os */
|
||||
{ ARGSFL_NONE, NULL }, /* Sh */
|
||||
{ ARGSFL_NONE, NULL }, /* Ss */
|
||||
{ ARGSFL_NONE, NULL }, /* Pp */
|
||||
{ ARGSFL_DELIM, NULL }, /* D1 */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dl */
|
||||
{ ARGSFL_NONE, args_Bd }, /* Bd */
|
||||
{ ARGSFL_NONE, NULL }, /* Ed */
|
||||
{ ARGSFL_NONE, args_Bl }, /* Bl */
|
||||
{ ARGSFL_NONE, NULL }, /* El */
|
||||
{ ARGSFL_NONE, NULL }, /* It */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ad */
|
||||
{ ARGSFL_DELIM, args_An }, /* An */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ar */
|
||||
{ ARGSFL_NONE, NULL }, /* Cd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Cm */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dv */
|
||||
{ ARGSFL_DELIM, NULL }, /* Er */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ev */
|
||||
{ ARGSFL_NONE, args_Ex }, /* Ex */
|
||||
{ ARGSFL_DELIM, NULL }, /* Fa */
|
||||
{ ARGSFL_NONE, NULL }, /* Fd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Fl */
|
||||
{ ARGSFL_DELIM, NULL }, /* Fn */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ft */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ic */
|
||||
{ ARGSFL_NONE, NULL }, /* In */
|
||||
{ ARGSFL_DELIM, NULL }, /* Li */
|
||||
{ ARGSFL_NONE, NULL }, /* Nd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Nm */
|
||||
{ ARGSFL_DELIM, NULL }, /* Op */
|
||||
{ ARGSFL_NONE, NULL }, /* Ot */
|
||||
{ ARGSFL_DELIM, NULL }, /* Pa */
|
||||
{ ARGSFL_NONE, args_Ex }, /* Rv */
|
||||
{ ARGSFL_DELIM, NULL }, /* St */
|
||||
{ ARGSFL_DELIM, NULL }, /* Va */
|
||||
{ ARGSFL_DELIM, NULL }, /* Vt */
|
||||
{ ARGSFL_DELIM, NULL }, /* Xr */
|
||||
{ ARGSFL_NONE, NULL }, /* %A */
|
||||
{ ARGSFL_NONE, NULL }, /* %B */
|
||||
{ ARGSFL_NONE, NULL }, /* %D */
|
||||
{ ARGSFL_NONE, NULL }, /* %I */
|
||||
{ ARGSFL_NONE, NULL }, /* %J */
|
||||
{ ARGSFL_NONE, NULL }, /* %N */
|
||||
{ ARGSFL_NONE, NULL }, /* %O */
|
||||
{ ARGSFL_NONE, NULL }, /* %P */
|
||||
{ ARGSFL_NONE, NULL }, /* %R */
|
||||
{ ARGSFL_NONE, NULL }, /* %T */
|
||||
{ ARGSFL_NONE, NULL }, /* %V */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ac */
|
||||
{ ARGSFL_NONE, NULL }, /* Ao */
|
||||
{ ARGSFL_DELIM, NULL }, /* Aq */
|
||||
{ ARGSFL_DELIM, NULL }, /* At */
|
||||
{ ARGSFL_DELIM, NULL }, /* Bc */
|
||||
{ ARGSFL_NONE, args_Bf }, /* Bf */
|
||||
{ ARGSFL_NONE, NULL }, /* Bo */
|
||||
{ ARGSFL_DELIM, NULL }, /* Bq */
|
||||
{ ARGSFL_DELIM, NULL }, /* Bsx */
|
||||
{ ARGSFL_DELIM, NULL }, /* Bx */
|
||||
{ ARGSFL_NONE, NULL }, /* Db */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dc */
|
||||
{ ARGSFL_NONE, NULL }, /* Do */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dq */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ec */
|
||||
{ ARGSFL_NONE, NULL }, /* Ef */
|
||||
{ ARGSFL_DELIM, NULL }, /* Em */
|
||||
{ ARGSFL_NONE, NULL }, /* Eo */
|
||||
{ ARGSFL_DELIM, NULL }, /* Fx */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ms */
|
||||
{ ARGSFL_DELIM, NULL }, /* No */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ns */
|
||||
{ ARGSFL_DELIM, NULL }, /* Nx */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ox */
|
||||
{ ARGSFL_DELIM, NULL }, /* Pc */
|
||||
{ ARGSFL_DELIM, NULL }, /* Pf */
|
||||
{ ARGSFL_NONE, NULL }, /* Po */
|
||||
{ ARGSFL_DELIM, NULL }, /* Pq */
|
||||
{ ARGSFL_DELIM, NULL }, /* Qc */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ql */
|
||||
{ ARGSFL_NONE, NULL }, /* Qo */
|
||||
{ ARGSFL_DELIM, NULL }, /* Qq */
|
||||
{ ARGSFL_NONE, NULL }, /* Re */
|
||||
{ ARGSFL_NONE, NULL }, /* Rs */
|
||||
{ ARGSFL_DELIM, NULL }, /* Sc */
|
||||
{ ARGSFL_NONE, NULL }, /* So */
|
||||
{ ARGSFL_DELIM, NULL }, /* Sq */
|
||||
{ ARGSFL_NONE, NULL }, /* Sm */
|
||||
{ ARGSFL_DELIM, NULL }, /* Sx */
|
||||
{ ARGSFL_DELIM, NULL }, /* Sy */
|
||||
{ ARGSFL_DELIM, NULL }, /* Tn */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ux */
|
||||
{ ARGSFL_DELIM, NULL }, /* Xc */
|
||||
{ ARGSFL_NONE, NULL }, /* Xo */
|
||||
{ ARGSFL_NONE, NULL }, /* Fo */
|
||||
{ ARGSFL_NONE, NULL }, /* Fc */
|
||||
{ ARGSFL_NONE, NULL }, /* Oo */
|
||||
{ ARGSFL_DELIM, NULL }, /* Oc */
|
||||
{ ARGSFL_NONE, args_Bk }, /* Bk */
|
||||
{ ARGSFL_NONE, NULL }, /* Ek */
|
||||
{ ARGSFL_NONE, NULL }, /* Bt */
|
||||
{ ARGSFL_NONE, NULL }, /* Hf */
|
||||
{ ARGSFL_NONE, NULL }, /* Fr */
|
||||
{ ARGSFL_NONE, NULL }, /* Ud */
|
||||
{ ARGSFL_NONE, NULL }, /* Lb */
|
||||
{ ARGSFL_NONE, NULL }, /* Lp */
|
||||
{ ARGSFL_DELIM, NULL }, /* Lk */
|
||||
{ ARGSFL_DELIM, NULL }, /* Mt */
|
||||
{ ARGSFL_DELIM, NULL }, /* Brq */
|
||||
{ ARGSFL_NONE, NULL }, /* Bro */
|
||||
{ ARGSFL_DELIM, NULL }, /* Brc */
|
||||
{ ARGSFL_NONE, NULL }, /* %C */
|
||||
{ ARGSFL_NONE, NULL }, /* Es */
|
||||
{ ARGSFL_NONE, NULL }, /* En */
|
||||
{ ARGSFL_NONE, NULL }, /* Dx */
|
||||
{ ARGSFL_NONE, NULL }, /* %Q */
|
||||
{ ARGSFL_NONE, NULL }, /* br */
|
||||
{ ARGSFL_NONE, NULL }, /* sp */
|
||||
{ ARGSFL_NONE, NULL }, /* %U */
|
||||
{ ARGSFL_NONE, NULL }, /* Ta */
|
||||
};
|
||||
|
||||
|
||||
|
@ -226,52 +283,81 @@ mdoc_argv(struct mdoc *m, int line, enum mdoct tok,
|
|||
char *p, sv;
|
||||
struct mdoc_argv tmp;
|
||||
struct mdoc_arg *arg;
|
||||
const enum mdocargt *ap;
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
return(ARGV_EOLN);
|
||||
else if (NULL == (ap = mdocargs[tok].argvs))
|
||||
return(ARGV_WORD);
|
||||
else if ('-' != buf[*pos])
|
||||
return(ARGV_WORD);
|
||||
|
||||
assert(' ' != buf[*pos]);
|
||||
|
||||
/* Parse through to the first unescaped space. */
|
||||
/* Seek to the first unescaped space. */
|
||||
|
||||
p = &buf[++(*pos)];
|
||||
|
||||
assert(*pos > 0);
|
||||
|
||||
/* LINTED */
|
||||
while (buf[*pos]) {
|
||||
if (' ' == buf[*pos])
|
||||
if ('\\' != buf[*pos - 1])
|
||||
for ( ; buf[*pos] ; (*pos)++)
|
||||
if (' ' == buf[*pos] && '\\' != buf[*pos - 1])
|
||||
break;
|
||||
(*pos)++;
|
||||
}
|
||||
|
||||
/* XXX - save zeroed byte, if not an argument. */
|
||||
/*
|
||||
* We want to nil-terminate the word to look it up (it's easier
|
||||
* that way). But we may not have a flag, in which case we need
|
||||
* to restore the line as-is. So keep around the stray byte,
|
||||
* which we'll reset upon exiting (if necessary).
|
||||
*/
|
||||
|
||||
sv = '\0';
|
||||
if (buf[*pos]) {
|
||||
sv = buf[*pos];
|
||||
if ('\0' != (sv = buf[*pos]))
|
||||
buf[(*pos)++] = '\0';
|
||||
}
|
||||
|
||||
(void)memset(&tmp, 0, sizeof(struct mdoc_argv));
|
||||
/*
|
||||
* Now look up the word as a flag. Use temporary storage that
|
||||
* we'll copy into the node's flags, if necessary.
|
||||
*/
|
||||
|
||||
memset(&tmp, 0, sizeof(struct mdoc_argv));
|
||||
|
||||
tmp.line = line;
|
||||
tmp.pos = *pos;
|
||||
tmp.arg = MDOC_ARG_MAX;
|
||||
|
||||
/* See if our token accepts the argument. */
|
||||
while (MDOC_ARG_MAX != (tmp.arg = *ap++))
|
||||
if (0 == strcmp(p, mdoc_argnames[tmp.arg]))
|
||||
break;
|
||||
|
||||
if (MDOC_ARG_MAX == (tmp.arg = argv_a2arg(tok, p))) {
|
||||
/* XXX - restore saved zeroed byte. */
|
||||
if (MDOC_ARG_MAX == tmp.arg) {
|
||||
/*
|
||||
* The flag was not found.
|
||||
* Restore saved zeroed byte and return as a word.
|
||||
*/
|
||||
if (sv)
|
||||
buf[*pos - 1] = sv;
|
||||
return(ARGV_WORD);
|
||||
}
|
||||
|
||||
/* Read to the next word (the argument). */
|
||||
|
||||
while (buf[*pos] && ' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if ( ! argv(m, line, &tmp, pos, buf))
|
||||
switch (argvflags[tmp.arg]) {
|
||||
case (ARGV_SINGLE):
|
||||
if ( ! argv_single(m, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
break;
|
||||
case (ARGV_MULTI):
|
||||
if ( ! argv_multi(m, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
break;
|
||||
case (ARGV_OPT_SINGLE):
|
||||
if ( ! argv_opt_single(m, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
break;
|
||||
case (ARGV_NONE):
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL == (arg = *v))
|
||||
arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
|
||||
|
@ -280,13 +366,12 @@ mdoc_argv(struct mdoc *m, int line, enum mdoct tok,
|
|||
arg->argv = mandoc_realloc
|
||||
(arg->argv, arg->argc * sizeof(struct mdoc_argv));
|
||||
|
||||
(void)memcpy(&arg->argv[(int)arg->argc - 1],
|
||||
memcpy(&arg->argv[(int)arg->argc - 1],
|
||||
&tmp, sizeof(struct mdoc_argv));
|
||||
|
||||
return(ARGV_ARG);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdoc_argv_free(struct mdoc_arg *p)
|
||||
{
|
||||
|
@ -303,15 +388,14 @@ mdoc_argv_free(struct mdoc_arg *p)
|
|||
assert(p->argc);
|
||||
|
||||
for (i = (int)p->argc - 1; i >= 0; i--)
|
||||
mdoc_argn_free(p, i);
|
||||
argn_free(p, i);
|
||||
|
||||
free(p->argv);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdoc_argn_free(struct mdoc_arg *p, int iarg)
|
||||
static void
|
||||
argn_free(struct mdoc_arg *p, int iarg)
|
||||
{
|
||||
struct mdoc_argv *arg;
|
||||
int j;
|
||||
|
@ -328,24 +412,21 @@ mdoc_argn_free(struct mdoc_arg *p, int iarg)
|
|||
p->argv[iarg] = p->argv[iarg+1];
|
||||
}
|
||||
|
||||
|
||||
enum margserr
|
||||
mdoc_zargs(struct mdoc *m, int line, int *pos,
|
||||
char *buf, int flags, char **v)
|
||||
mdoc_zargs(struct mdoc *m, int line, int *pos, char *buf, char **v)
|
||||
{
|
||||
|
||||
return(args(m, line, pos, buf, flags, v));
|
||||
return(args(m, line, pos, buf, ARGSFL_NONE, v));
|
||||
}
|
||||
|
||||
|
||||
enum margserr
|
||||
mdoc_args(struct mdoc *m, int line, int *pos,
|
||||
char *buf, enum mdoct tok, char **v)
|
||||
{
|
||||
int fl;
|
||||
enum argsflag fl;
|
||||
struct mdoc_node *n;
|
||||
|
||||
fl = mdoc_argflags[tok];
|
||||
fl = mdocargs[tok].flags;
|
||||
|
||||
if (MDOC_It != tok)
|
||||
return(args(m, line, pos, buf, fl, v));
|
||||
|
@ -359,42 +440,20 @@ mdoc_args(struct mdoc *m, int line, int *pos,
|
|||
|
||||
for (n = m->last; n; n = n->parent)
|
||||
if (MDOC_Bl == n->tok)
|
||||
if (LIST_column == n->norm->Bl.type) {
|
||||
fl = ARGSFL_TABSEP;
|
||||
break;
|
||||
|
||||
if (n && LIST_column == n->norm->Bl.type) {
|
||||
fl |= ARGS_TABSEP;
|
||||
fl &= ~ARGS_DELIM;
|
||||
}
|
||||
|
||||
return(args(m, line, pos, buf, fl, v));
|
||||
}
|
||||
|
||||
|
||||
static enum margserr
|
||||
args(struct mdoc *m, int line, int *pos,
|
||||
char *buf, int fl, char **v)
|
||||
char *buf, enum argsflag fl, char **v)
|
||||
{
|
||||
int i;
|
||||
char *p, *pp;
|
||||
enum margserr rc;
|
||||
enum mdelim d;
|
||||
|
||||
/*
|
||||
* Parse out the terms (like `val' in `.Xx -arg val' or simply
|
||||
* `.Xx val'), which can have all sorts of properties:
|
||||
*
|
||||
* ARGS_DELIM: use special handling if encountering trailing
|
||||
* delimiters in the form of [[::delim::][ ]+]+.
|
||||
*
|
||||
* ARGS_NOWARN: don't post warnings. This is only used when
|
||||
* re-parsing delimiters, as the warnings have already been
|
||||
* posted.
|
||||
*
|
||||
* ARGS_TABSEP: use special handling for tab/`Ta' separated
|
||||
* phrases like in `Bl -column'.
|
||||
*/
|
||||
|
||||
assert(' ' != buf[*pos]);
|
||||
|
||||
if ('\0' == buf[*pos]) {
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
|
@ -405,46 +464,17 @@ args(struct mdoc *m, int line, int *pos,
|
|||
* is unterminated.
|
||||
*/
|
||||
if (MDOC_PHRASELIT & m->flags)
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
|
||||
return(ARGS_ERROR);
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE);
|
||||
|
||||
m->flags &= ~MDOC_PHRASELIT;
|
||||
return(ARGS_EOLN);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the first character is a closing delimiter and we're to
|
||||
* look for delimited strings, then pass down the buffer seeing
|
||||
* if it follows the pattern of [[::delim::][ ]+]+. Note that
|
||||
* we ONLY care about closing delimiters.
|
||||
*/
|
||||
|
||||
if ((fl & ARGS_DELIM) && DELIM_CLOSE == mdoc_iscdelim(buf[*pos])) {
|
||||
for (i = *pos; buf[i]; ) {
|
||||
d = mdoc_iscdelim(buf[i]);
|
||||
if (DELIM_NONE == d || DELIM_OPEN == d)
|
||||
break;
|
||||
i++;
|
||||
if ('\0' == buf[i] || ' ' != buf[i])
|
||||
break;
|
||||
i++;
|
||||
while (buf[i] && ' ' == buf[i])
|
||||
i++;
|
||||
}
|
||||
|
||||
if ('\0' == buf[i]) {
|
||||
*v = &buf[*pos];
|
||||
if (i && ' ' != buf[i - 1])
|
||||
return(ARGS_PUNCT);
|
||||
if (ARGS_NOWARN & fl)
|
||||
return(ARGS_PUNCT);
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
return(ARGS_PUNCT);
|
||||
}
|
||||
}
|
||||
|
||||
*v = &buf[*pos];
|
||||
if (ARGSFL_DELIM == fl)
|
||||
if (args_checkpunct(buf, *pos))
|
||||
return(ARGS_PUNCT);
|
||||
|
||||
/*
|
||||
* First handle TABSEP items, restricted to `Bl -column'. This
|
||||
|
@ -453,7 +483,7 @@ args(struct mdoc *m, int line, int *pos,
|
|||
* for arguments at a later phase.
|
||||
*/
|
||||
|
||||
if (ARGS_TABSEP & fl) {
|
||||
if (ARGSFL_TABSEP == fl) {
|
||||
/* Scan ahead to tab (can't be escaped). */
|
||||
p = strchr(*v, '\t');
|
||||
pp = NULL;
|
||||
|
@ -492,9 +522,8 @@ args(struct mdoc *m, int line, int *pos,
|
|||
}
|
||||
|
||||
/* Whitespace check for eoln case... */
|
||||
if ('\0' == *p && ' ' == *(p - 1) && ! (ARGS_NOWARN & fl))
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
if ('\0' == *p && ' ' == *(p - 1))
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE);
|
||||
|
||||
*pos += (int)(p - *v);
|
||||
|
||||
|
@ -536,10 +565,9 @@ args(struct mdoc *m, int line, int *pos,
|
|||
}
|
||||
|
||||
if ('\0' == buf[*pos]) {
|
||||
if (ARGS_NOWARN & fl || MDOC_PPHRASE & m->flags)
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
return(ARGS_QWORD);
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
|
||||
return(ARGS_ERROR);
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE);
|
||||
return(ARGS_QWORD);
|
||||
}
|
||||
|
||||
|
@ -552,138 +580,68 @@ args(struct mdoc *m, int line, int *pos,
|
|||
while (' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if (0 == buf[*pos] && ! (ARGS_NOWARN & fl))
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
if ('\0' == buf[*pos])
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE);
|
||||
|
||||
return(ARGS_QWORD);
|
||||
}
|
||||
|
||||
/*
|
||||
* A non-quoted term progresses until either the end of line or
|
||||
* a non-escaped whitespace.
|
||||
*/
|
||||
|
||||
for ( ; buf[*pos]; (*pos)++)
|
||||
if (*pos && ' ' == buf[*pos] && '\\' != buf[*pos - 1])
|
||||
break;
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
return(ARGS_WORD);
|
||||
|
||||
buf[(*pos)++] = '\0';
|
||||
|
||||
while (' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if ('\0' == buf[*pos] && ! (ARGS_NOWARN & fl))
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
p = &buf[*pos];
|
||||
*v = mandoc_getarg(m->parse, &p, line, pos);
|
||||
|
||||
return(ARGS_WORD);
|
||||
}
|
||||
|
||||
|
||||
static enum mdocargt
|
||||
argv_a2arg(enum mdoct tok, const char *p)
|
||||
{
|
||||
|
||||
/*
|
||||
* Parse an argument identifier from its text. XXX - this
|
||||
* should really be table-driven to clarify the code.
|
||||
*
|
||||
* If you add an argument to the list, make sure that you
|
||||
* register it here with its one or more macros!
|
||||
/*
|
||||
* Check if the string consists only of space-separated closing
|
||||
* delimiters. This is a bit of a dance: the first must be a close
|
||||
* delimiter, but it may be followed by middle delimiters. Arbitrary
|
||||
* whitespace may separate these tokens.
|
||||
*/
|
||||
static int
|
||||
args_checkpunct(const char *buf, int i)
|
||||
{
|
||||
int j;
|
||||
char dbuf[DELIMSZ];
|
||||
enum mdelim d;
|
||||
|
||||
switch (tok) {
|
||||
case (MDOC_An):
|
||||
if (0 == strcmp(p, "split"))
|
||||
return(MDOC_Split);
|
||||
else if (0 == strcmp(p, "nosplit"))
|
||||
return(MDOC_Nosplit);
|
||||
break;
|
||||
/* First token must be a close-delimiter. */
|
||||
|
||||
case (MDOC_Bd):
|
||||
if (0 == strcmp(p, "ragged"))
|
||||
return(MDOC_Ragged);
|
||||
else if (0 == strcmp(p, "unfilled"))
|
||||
return(MDOC_Unfilled);
|
||||
else if (0 == strcmp(p, "filled"))
|
||||
return(MDOC_Filled);
|
||||
else if (0 == strcmp(p, "literal"))
|
||||
return(MDOC_Literal);
|
||||
else if (0 == strcmp(p, "file"))
|
||||
return(MDOC_File);
|
||||
else if (0 == strcmp(p, "offset"))
|
||||
return(MDOC_Offset);
|
||||
else if (0 == strcmp(p, "compact"))
|
||||
return(MDOC_Compact);
|
||||
else if (0 == strcmp(p, "centered"))
|
||||
return(MDOC_Centred);
|
||||
break;
|
||||
for (j = 0; buf[i] && ' ' != buf[i] && j < DELIMSZ; j++, i++)
|
||||
dbuf[j] = buf[i];
|
||||
|
||||
case (MDOC_Bf):
|
||||
if (0 == strcmp(p, "emphasis"))
|
||||
return(MDOC_Emphasis);
|
||||
else if (0 == strcmp(p, "literal"))
|
||||
return(MDOC_Literal);
|
||||
else if (0 == strcmp(p, "symbolic"))
|
||||
return(MDOC_Symbolic);
|
||||
break;
|
||||
if (DELIMSZ == j)
|
||||
return(0);
|
||||
|
||||
case (MDOC_Bk):
|
||||
if (0 == strcmp(p, "words"))
|
||||
return(MDOC_Words);
|
||||
break;
|
||||
dbuf[j] = '\0';
|
||||
if (DELIM_CLOSE != mdoc_isdelim(dbuf))
|
||||
return(0);
|
||||
|
||||
case (MDOC_Bl):
|
||||
if (0 == strcmp(p, "bullet"))
|
||||
return(MDOC_Bullet);
|
||||
else if (0 == strcmp(p, "dash"))
|
||||
return(MDOC_Dash);
|
||||
else if (0 == strcmp(p, "hyphen"))
|
||||
return(MDOC_Hyphen);
|
||||
else if (0 == strcmp(p, "item"))
|
||||
return(MDOC_Item);
|
||||
else if (0 == strcmp(p, "enum"))
|
||||
return(MDOC_Enum);
|
||||
else if (0 == strcmp(p, "tag"))
|
||||
return(MDOC_Tag);
|
||||
else if (0 == strcmp(p, "diag"))
|
||||
return(MDOC_Diag);
|
||||
else if (0 == strcmp(p, "hang"))
|
||||
return(MDOC_Hang);
|
||||
else if (0 == strcmp(p, "ohang"))
|
||||
return(MDOC_Ohang);
|
||||
else if (0 == strcmp(p, "inset"))
|
||||
return(MDOC_Inset);
|
||||
else if (0 == strcmp(p, "column"))
|
||||
return(MDOC_Column);
|
||||
else if (0 == strcmp(p, "width"))
|
||||
return(MDOC_Width);
|
||||
else if (0 == strcmp(p, "offset"))
|
||||
return(MDOC_Offset);
|
||||
else if (0 == strcmp(p, "compact"))
|
||||
return(MDOC_Compact);
|
||||
else if (0 == strcmp(p, "nested"))
|
||||
return(MDOC_Nested);
|
||||
break;
|
||||
while (' ' == buf[i])
|
||||
i++;
|
||||
|
||||
case (MDOC_Rv):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Ex):
|
||||
if (0 == strcmp(p, "std"))
|
||||
return(MDOC_Std);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/* Remaining must NOT be open/none. */
|
||||
|
||||
while (buf[i]) {
|
||||
j = 0;
|
||||
while (buf[i] && ' ' != buf[i] && j < DELIMSZ)
|
||||
dbuf[j++] = buf[i++];
|
||||
|
||||
if (DELIMSZ == j)
|
||||
return(0);
|
||||
|
||||
dbuf[j] = '\0';
|
||||
d = mdoc_isdelim(dbuf);
|
||||
if (DELIM_NONE == d || DELIM_OPEN == d)
|
||||
return(0);
|
||||
|
||||
while (' ' == buf[i])
|
||||
i++;
|
||||
}
|
||||
|
||||
return(MDOC_ARG_MAX);
|
||||
return('\0' == buf[i]);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
argv_multi(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
|
@ -694,7 +652,7 @@ argv_multi(struct mdoc *m, int line,
|
|||
for (v->sz = 0; ; v->sz++) {
|
||||
if ('-' == buf[*pos])
|
||||
break;
|
||||
ac = args(m, line, pos, buf, 0, &p);
|
||||
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
else if (ARGS_EOLN == ac)
|
||||
|
@ -710,7 +668,6 @@ argv_multi(struct mdoc *m, int line,
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
argv_opt_single(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
|
@ -721,7 +678,7 @@ argv_opt_single(struct mdoc *m, int line,
|
|||
if ('-' == buf[*pos])
|
||||
return(1);
|
||||
|
||||
ac = args(m, line, pos, buf, 0, &p);
|
||||
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
if (ARGS_EOLN == ac)
|
||||
|
@ -734,10 +691,6 @@ argv_opt_single(struct mdoc *m, int line,
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse a single, mandatory value from the stream.
|
||||
*/
|
||||
static int
|
||||
argv_single(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
|
@ -748,7 +701,7 @@ argv_single(struct mdoc *m, int line,
|
|||
|
||||
ppos = *pos;
|
||||
|
||||
ac = args(m, line, pos, buf, 0, &p);
|
||||
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
|
||||
if (ARGS_EOLN == ac) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT);
|
||||
return(0);
|
||||
|
@ -761,32 +714,3 @@ argv_single(struct mdoc *m, int line,
|
|||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine rules for parsing arguments. Arguments can either accept
|
||||
* no parameters, an optional single parameter, one parameter, or
|
||||
* multiple parameters.
|
||||
*/
|
||||
static int
|
||||
argv(struct mdoc *mdoc, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
|
||||
v->sz = 0;
|
||||
v->value = NULL;
|
||||
|
||||
switch (mdoc_argvflags[v->arg]) {
|
||||
case (ARGV_SINGLE):
|
||||
return(argv_single(mdoc, line, v, pos, buf));
|
||||
case (ARGV_MULTI):
|
||||
return(argv_multi(mdoc, line, v, pos, buf));
|
||||
case (ARGV_OPT_SINGLE):
|
||||
return(argv_opt_single(mdoc, line, v, pos, buf));
|
||||
default:
|
||||
/* ARGV_NONE */
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
|
17
external/bsd/mdocml/dist/mdoc_hash.c
vendored
17
external/bsd/mdocml/dist/mdoc_hash.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: mdoc_hash.c,v 1.16 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc_hash.c,v 1.18 2011/07/24 18:15:14 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -27,10 +27,11 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
static u_char table[27 * 12];
|
||||
static unsigned char table[27 * 12];
|
||||
|
||||
/*
|
||||
* XXX - this hash has global scope, so if intended for use as a library
|
||||
|
@ -47,14 +48,14 @@ mdoc_hash_init(void)
|
|||
for (i = 0; i < (int)MDOC_MAX; i++) {
|
||||
p = mdoc_macronames[i];
|
||||
|
||||
if (isalpha((u_char)p[1]))
|
||||
major = 12 * (tolower((u_char)p[1]) - 97);
|
||||
if (isalpha((unsigned char)p[1]))
|
||||
major = 12 * (tolower((unsigned char)p[1]) - 97);
|
||||
else
|
||||
major = 12 * 26;
|
||||
|
||||
for (j = 0; j < 12; j++)
|
||||
if (UCHAR_MAX == table[major + j]) {
|
||||
table[major + j] = (u_char)i;
|
||||
table[major + j] = (unsigned char)i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -69,11 +70,11 @@ mdoc_hash_find(const char *p)
|
|||
|
||||
if (0 == p[0])
|
||||
return(MDOC_MAX);
|
||||
if ( ! isalpha((u_char)p[0]) && '%' != p[0])
|
||||
if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
|
||||
return(MDOC_MAX);
|
||||
|
||||
if (isalpha((u_char)p[1]))
|
||||
major = 12 * (tolower((u_char)p[1]) - 97);
|
||||
if (isalpha((unsigned char)p[1]))
|
||||
major = 12 * (tolower((unsigned char)p[1]) - 97);
|
||||
else if ('1' == p[1])
|
||||
major = 12 * 26;
|
||||
else
|
||||
|
|
447
external/bsd/mdocml/dist/mdoc_html.c
vendored
447
external/bsd/mdocml/dist/mdoc_html.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mdoc_html.c,v 1.142 2011/01/07 13:20:58 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc_html.c,v 1.182 2011/11/03 20:37:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -34,7 +34,6 @@
|
|||
#include "main.h"
|
||||
|
||||
#define INDENT 5
|
||||
#define HALFINDENT 3
|
||||
|
||||
#define MDOC_ARGS const struct mdoc_meta *m, \
|
||||
const struct mdoc_node *n, \
|
||||
|
@ -190,7 +189,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
|
|||
{NULL, NULL}, /* Ec */ /* FIXME: no space */
|
||||
{NULL, NULL}, /* Ef */
|
||||
{mdoc_em_pre, NULL}, /* Em */
|
||||
{NULL, NULL}, /* Eo */
|
||||
{mdoc_quote_pre, mdoc_quote_post}, /* Eo */
|
||||
{mdoc_xx_pre, NULL}, /* Fx */
|
||||
{mdoc_ms_pre, NULL}, /* Ms */
|
||||
{mdoc_igndelim_pre, NULL}, /* No */
|
||||
|
@ -263,17 +262,9 @@ static const char * const lists[LIST_MAX] = {
|
|||
void
|
||||
html_mdoc(void *arg, const struct mdoc *m)
|
||||
{
|
||||
struct html *h;
|
||||
struct tag *t;
|
||||
|
||||
h = (struct html *)arg;
|
||||
|
||||
print_gen_decls(h);
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
print_mdoc(mdoc_meta(m), mdoc_node(m), h);
|
||||
print_tagq(h, t);
|
||||
|
||||
printf("\n");
|
||||
print_mdoc(mdoc_meta(m), mdoc_node(m), (struct html *)arg);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
|
@ -288,7 +279,7 @@ a2width(const char *p, struct roffsu *su)
|
|||
|
||||
if ( ! a2roffsu(p, su, SCALE_MAX)) {
|
||||
su->unit = SCALE_BU;
|
||||
su->scale = (int)strlen(p);
|
||||
su->scale = html_strlen(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,23 +344,30 @@ a2offs(const char *p, struct roffsu *su)
|
|||
SCALE_HS_INIT(su, INDENT);
|
||||
else if (0 == strcmp(p, "indent-two"))
|
||||
SCALE_HS_INIT(su, INDENT * 2);
|
||||
else if ( ! a2roffsu(p, su, SCALE_MAX)) {
|
||||
su->unit = SCALE_BU;
|
||||
su->scale = (int)strlen(p);
|
||||
}
|
||||
else if ( ! a2roffsu(p, su, SCALE_MAX))
|
||||
SCALE_HS_INIT(su, html_strlen(p));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_mdoc(MDOC_ARGS)
|
||||
{
|
||||
struct tag *t;
|
||||
struct tag *t, *tt;
|
||||
struct htmlpair tag;
|
||||
|
||||
t = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
PAIR_CLASS_INIT(&tag, "mandoc");
|
||||
|
||||
if ( ! (HTML_FRAGMENT & h->oflags)) {
|
||||
print_gen_decls(h);
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
tt = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
print_mdoc_head(m, n, h);
|
||||
print_tagq(h, t);
|
||||
print_tagq(h, tt);
|
||||
print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
||||
t = print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_mdoc_nodelist(m, n, h);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
@ -382,13 +380,10 @@ print_mdoc_head(MDOC_ARGS)
|
|||
|
||||
print_gen_head(h);
|
||||
bufinit(h);
|
||||
buffmt(h, "%s(%s)", m->title, m->msec);
|
||||
bufcat_fmt(h, "%s(%s)", m->title, m->msec);
|
||||
|
||||
if (m->arch) {
|
||||
bufcat(h, " (");
|
||||
bufcat(h, m->arch);
|
||||
bufcat(h, ")");
|
||||
}
|
||||
if (m->arch)
|
||||
bufcat_fmt(h, " (%s)", m->arch);
|
||||
|
||||
print_otag(h, TAG_TITLE, 0, NULL);
|
||||
print_text(h, h->buf);
|
||||
|
@ -414,18 +409,50 @@ print_mdoc_node(MDOC_ARGS)
|
|||
child = 1;
|
||||
t = h->tags.head;
|
||||
|
||||
bufinit(h);
|
||||
switch (n->type) {
|
||||
case (MDOC_ROOT):
|
||||
child = mdoc_root_pre(m, n, h);
|
||||
break;
|
||||
case (MDOC_TEXT):
|
||||
/* No tables in this mode... */
|
||||
assert(NULL == h->tblt);
|
||||
|
||||
/*
|
||||
* Make sure that if we're in a literal mode already
|
||||
* (i.e., within a <PRE>) don't print the newline.
|
||||
*/
|
||||
if (' ' == *n->string && MDOC_LINE & n->flags)
|
||||
if ( ! (HTML_LITERAL & h->flags))
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
if (MDOC_DELIMC & n->flags)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->string);
|
||||
if (MDOC_DELIMO & n->flags)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
return;
|
||||
case (MDOC_TBL):
|
||||
print_tbl(h, n->span);
|
||||
case (MDOC_EQN):
|
||||
print_eqn(h, n->eqn);
|
||||
break;
|
||||
case (MDOC_TBL):
|
||||
/*
|
||||
* This will take care of initialising all of the table
|
||||
* state data for the first table, then tearing it down
|
||||
* for the last one.
|
||||
*/
|
||||
print_tbl(h, n->span);
|
||||
return;
|
||||
default:
|
||||
/*
|
||||
* Close out the current table, if it's open, and unset
|
||||
* the "meta" table state. This will be reopened on the
|
||||
* next table element.
|
||||
*/
|
||||
if (h->tblt) {
|
||||
print_tblclose(h);
|
||||
t = h->tags.head;
|
||||
}
|
||||
|
||||
assert(NULL == h->tblt);
|
||||
if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
|
||||
child = (*mdocs[n->tok].pre)(m, n, h);
|
||||
break;
|
||||
|
@ -448,12 +475,11 @@ print_mdoc_node(MDOC_ARGS)
|
|||
|
||||
print_stagq(h, t);
|
||||
|
||||
bufinit(h);
|
||||
switch (n->type) {
|
||||
case (MDOC_ROOT):
|
||||
mdoc_root_post(m, n, h);
|
||||
break;
|
||||
case (MDOC_TBL):
|
||||
case (MDOC_EQN):
|
||||
break;
|
||||
default:
|
||||
if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
|
||||
|
@ -468,38 +494,27 @@ mdoc_root_post(MDOC_ARGS)
|
|||
{
|
||||
struct htmlpair tag[3];
|
||||
struct tag *t, *tt;
|
||||
char b[DATESIZ];
|
||||
|
||||
time2a(m->date, b, DATESIZ);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
|
||||
PAIR_CLASS_INIT(&tag[1], "foot");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_TABLE, 2, tag);
|
||||
|
||||
t = print_otag(h, TAG_TBODY, 0, NULL);
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, b);
|
||||
print_text(h, m->date);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, m->os);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
@ -525,15 +540,12 @@ mdoc_root_pre(MDOC_ARGS)
|
|||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
||||
PAIR_CLASS_INIT(&tag[1], "head");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_TABLE, 2, tag);
|
||||
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
|
||||
|
@ -541,27 +553,18 @@ mdoc_root_pre(MDOC_ARGS)
|
|||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-ltitle");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, title);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, b);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-rtitle");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, title);
|
||||
print_tagq(h, t);
|
||||
return(1);
|
||||
|
@ -573,7 +576,6 @@ static int
|
|||
mdoc_sh_pre(MDOC_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
if (MDOC_BLOCK == n->type) {
|
||||
PAIR_CLASS_INIT(&tag, "section");
|
||||
|
@ -582,25 +584,29 @@ mdoc_sh_pre(MDOC_ARGS)
|
|||
} else if (MDOC_BODY == n->type)
|
||||
return(1);
|
||||
|
||||
buf[0] = '\0';
|
||||
for (n = n->child; n; n = n->next) {
|
||||
html_idcat(buf, n->string, BUFSIZ);
|
||||
if (n->next)
|
||||
html_idcat(buf, " ", BUFSIZ);
|
||||
bufinit(h);
|
||||
bufcat(h, "x");
|
||||
|
||||
for (n = n->child; n && MDOC_TEXT == n->type; ) {
|
||||
bufcat_id(h, n->string);
|
||||
if (NULL != (n = n->next))
|
||||
bufcat_id(h, " ");
|
||||
}
|
||||
|
||||
PAIR_ID_INIT(&tag, buf);
|
||||
if (NULL == n) {
|
||||
PAIR_ID_INIT(&tag, h->buf);
|
||||
print_otag(h, TAG_H1, 1, &tag);
|
||||
} else
|
||||
print_otag(h, TAG_H1, 0, NULL);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
mdoc_ss_pre(MDOC_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
if (MDOC_BLOCK == n->type) {
|
||||
PAIR_CLASS_INIT(&tag, "subsection");
|
||||
|
@ -609,15 +615,21 @@ mdoc_ss_pre(MDOC_ARGS)
|
|||
} else if (MDOC_BODY == n->type)
|
||||
return(1);
|
||||
|
||||
buf[0] = '\0';
|
||||
for (n = n->child; n; n = n->next) {
|
||||
html_idcat(buf, n->string, BUFSIZ);
|
||||
if (n->next)
|
||||
html_idcat(buf, " ", BUFSIZ);
|
||||
bufinit(h);
|
||||
bufcat(h, "x");
|
||||
|
||||
for (n = n->child; n && MDOC_TEXT == n->type; ) {
|
||||
bufcat_id(h, n->string);
|
||||
if (NULL != (n = n->next))
|
||||
bufcat_id(h, " ");
|
||||
}
|
||||
|
||||
PAIR_ID_INIT(&tag, buf);
|
||||
if (NULL == n) {
|
||||
PAIR_ID_INIT(&tag, h->buf);
|
||||
print_otag(h, TAG_H2, 1, &tag);
|
||||
} else
|
||||
print_otag(h, TAG_H2, 0, NULL);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -670,7 +682,7 @@ mdoc_nm_pre(MDOC_ARGS)
|
|||
{
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
size_t len;
|
||||
int len;
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_ELEM):
|
||||
|
@ -698,12 +710,13 @@ mdoc_nm_pre(MDOC_ARGS)
|
|||
|
||||
for (len = 0, n = n->child; n; n = n->next)
|
||||
if (MDOC_TEXT == n->type)
|
||||
len += strlen(n->string);
|
||||
len += html_strlen(n->string);
|
||||
|
||||
if (0 == len && m->name)
|
||||
len = strlen(m->name);
|
||||
len = html_strlen(m->name);
|
||||
|
||||
SCALE_HS_INIT(&su, (double)len);
|
||||
bufinit(h);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
|
@ -719,7 +732,6 @@ static int
|
|||
mdoc_xr_pre(MDOC_ARGS)
|
||||
{
|
||||
struct htmlpair tag[2];
|
||||
const struct mdoc_node *nn;
|
||||
|
||||
if (NULL == n->child)
|
||||
return(0);
|
||||
|
@ -735,16 +747,16 @@ mdoc_xr_pre(MDOC_ARGS)
|
|||
} else
|
||||
print_otag(h, TAG_A, 1, tag);
|
||||
|
||||
nn = n->child;
|
||||
print_text(h, nn->string);
|
||||
n = n->child;
|
||||
print_text(h, n->string);
|
||||
|
||||
if (NULL == (nn = nn->next))
|
||||
if (NULL == (n = n->next))
|
||||
return(0);
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "(");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, nn->string);
|
||||
print_text(h, n->string);
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ")");
|
||||
return(0);
|
||||
|
@ -756,6 +768,7 @@ static int
|
|||
mdoc_ns_pre(MDOC_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (MDOC_LINE & n->flags))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
return(1);
|
||||
}
|
||||
|
@ -779,6 +792,7 @@ mdoc_xx_pre(MDOC_ARGS)
|
|||
{
|
||||
const char *pp;
|
||||
struct htmlpair tag;
|
||||
int flags;
|
||||
|
||||
switch (n->tok) {
|
||||
case (MDOC_Bsx):
|
||||
|
@ -805,8 +819,15 @@ mdoc_xx_pre(MDOC_ARGS)
|
|||
|
||||
PAIR_CLASS_INIT(&tag, "unix");
|
||||
print_otag(h, TAG_SPAN, 1, &tag);
|
||||
|
||||
print_text(h, pp);
|
||||
return(1);
|
||||
if (n->child) {
|
||||
flags = h->flags;
|
||||
h->flags |= HTML_KEEP;
|
||||
print_text(h, n->child->string);
|
||||
h->flags = flags;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -814,19 +835,27 @@ mdoc_xx_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_bx_pre(MDOC_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
struct htmlpair tag;
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "unix");
|
||||
print_otag(h, TAG_SPAN, 1, &tag);
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next)
|
||||
print_mdoc_node(m, nn, h);
|
||||
|
||||
if (n->child)
|
||||
if (NULL != (n = n->child)) {
|
||||
print_text(h, n->string);
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
print_text(h, "BSD");
|
||||
} else {
|
||||
print_text(h, "BSD");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (NULL != (n = n->next)) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "-");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -850,6 +879,8 @@ mdoc_it_pre(MDOC_ARGS)
|
|||
assert(lists[type]);
|
||||
PAIR_CLASS_INIT(&tag[0], lists[type]);
|
||||
|
||||
bufinit(h);
|
||||
|
||||
if (MDOC_HEAD == n->type) {
|
||||
switch (type) {
|
||||
case(LIST_bullet):
|
||||
|
@ -950,6 +981,8 @@ mdoc_bl_pre(MDOC_ARGS)
|
|||
struct roffsu su;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
bufinit(h);
|
||||
|
||||
if (MDOC_BODY == n->type) {
|
||||
if (LIST_column == n->norm->Bl.type)
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
|
@ -969,7 +1002,6 @@ mdoc_bl_pre(MDOC_ARGS)
|
|||
|
||||
for (i = 0; i < (int)n->norm->Bl.ncols; i++) {
|
||||
a2width(n->norm->Bl.cols[i], &su);
|
||||
bufinit(h);
|
||||
if (i < (int)n->norm->Bl.ncols - 1)
|
||||
bufcat_su(h, "width", &su);
|
||||
else
|
||||
|
@ -1037,9 +1069,9 @@ mdoc_bl_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_ex_pre(MDOC_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
struct tag *t;
|
||||
struct htmlpair tag;
|
||||
int nchild;
|
||||
|
||||
if (n->prev)
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
|
@ -1047,22 +1079,25 @@ mdoc_ex_pre(MDOC_ARGS)
|
|||
PAIR_CLASS_INIT(&tag, "utility");
|
||||
|
||||
print_text(h, "The");
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
|
||||
nchild = n->nchild;
|
||||
for (n = n->child; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
t = print_otag(h, TAG_B, 1, &tag);
|
||||
print_text(h, nn->string);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
|
||||
if (nchild > 2 && n->next) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
if (nn->next && NULL == nn->next->next)
|
||||
print_text(h, ", and");
|
||||
else if (nn->next)
|
||||
print_text(h, ",");
|
||||
else
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
}
|
||||
|
||||
if (n->child && n->child->next)
|
||||
if (n->next && NULL == n->next->next)
|
||||
print_text(h, "and");
|
||||
}
|
||||
|
||||
if (nchild > 1)
|
||||
print_text(h, "utilities exit");
|
||||
else
|
||||
print_text(h, "utility exits");
|
||||
|
@ -1095,6 +1130,7 @@ mdoc_d1_pre(MDOC_ARGS)
|
|||
return(1);
|
||||
|
||||
SCALE_VS_INIT(&su, 0);
|
||||
bufinit(h);
|
||||
bufcat_su(h, "margin-top", &su);
|
||||
bufcat_su(h, "margin-bottom", &su);
|
||||
PAIR_STYLE_INIT(&tag[0], h);
|
||||
|
@ -1119,18 +1155,18 @@ static int
|
|||
mdoc_sx_pre(MDOC_ARGS)
|
||||
{
|
||||
struct htmlpair tag[2];
|
||||
const struct mdoc_node *nn;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
strlcpy(buf, "#", BUFSIZ);
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
html_idcat(buf, nn->string, BUFSIZ);
|
||||
if (nn->next)
|
||||
html_idcat(buf, " ", BUFSIZ);
|
||||
bufinit(h);
|
||||
bufcat(h, "#x");
|
||||
|
||||
for (n = n->child; n; ) {
|
||||
bufcat_id(h, n->string);
|
||||
if (NULL != (n = n->next))
|
||||
bufcat_id(h, " ");
|
||||
}
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "link-sec");
|
||||
PAIR_HREF_INIT(&tag[1], buf);
|
||||
PAIR_HREF_INIT(&tag[1], h->buf);
|
||||
|
||||
print_otag(h, TAG_I, 1, tag);
|
||||
print_otag(h, TAG_A, 2, tag);
|
||||
|
@ -1143,7 +1179,7 @@ static int
|
|||
mdoc_bd_pre(MDOC_ARGS)
|
||||
{
|
||||
struct htmlpair tag[2];
|
||||
int comp;
|
||||
int comp, sv;
|
||||
const struct mdoc_node *nn;
|
||||
struct roffsu su;
|
||||
|
||||
|
@ -1169,6 +1205,7 @@ mdoc_bd_pre(MDOC_ARGS)
|
|||
if (n->norm->Bd.offs)
|
||||
a2offs(n->norm->Bd.offs, &su);
|
||||
|
||||
bufinit(h);
|
||||
bufcat_su(h, "margin-left", &su);
|
||||
PAIR_STYLE_INIT(&tag[0], h);
|
||||
|
||||
|
@ -1182,6 +1219,11 @@ mdoc_bd_pre(MDOC_ARGS)
|
|||
PAIR_CLASS_INIT(&tag[1], "lit display");
|
||||
print_otag(h, TAG_PRE, 2, tag);
|
||||
|
||||
/* This can be recursive: save & set our literal state. */
|
||||
|
||||
sv = h->flags & HTML_LITERAL;
|
||||
h->flags |= HTML_LITERAL;
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
print_mdoc_node(m, nn, h);
|
||||
/*
|
||||
|
@ -1218,6 +1260,9 @@ mdoc_bd_pre(MDOC_ARGS)
|
|||
h->flags |= HTML_NOSPACE;
|
||||
}
|
||||
|
||||
if (0 == sv)
|
||||
h->flags &= ~HTML_LITERAL;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1327,12 +1372,16 @@ mdoc_fa_pre(MDOC_ARGS)
|
|||
t = print_otag(h, TAG_I, 1, &tag);
|
||||
print_text(h, nn->string);
|
||||
print_tagq(h, t);
|
||||
if (nn->next)
|
||||
if (nn->next) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if (n->child && n->next && n->next->tok == MDOC_Fa)
|
||||
if (n->child && n->next && n->next->tok == MDOC_Fa) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ",");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1342,13 +1391,60 @@ mdoc_fa_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_fd_pre(MDOC_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct htmlpair tag[2];
|
||||
char buf[BUFSIZ];
|
||||
size_t sz;
|
||||
int i;
|
||||
struct tag *t;
|
||||
|
||||
synopsis_pre(h, n);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "macro");
|
||||
print_otag(h, TAG_B, 1, &tag);
|
||||
if (NULL == (n = n->child))
|
||||
return(0);
|
||||
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
if (strcmp(n->string, "#include")) {
|
||||
PAIR_CLASS_INIT(&tag[0], "macro");
|
||||
print_otag(h, TAG_B, 1, tag);
|
||||
return(1);
|
||||
}
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "includes");
|
||||
print_otag(h, TAG_B, 1, tag);
|
||||
print_text(h, n->string);
|
||||
|
||||
if (NULL != (n = n->next)) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
strlcpy(buf, '<' == *n->string || '"' == *n->string ?
|
||||
n->string + 1 : n->string, BUFSIZ);
|
||||
|
||||
sz = strlen(buf);
|
||||
if (sz && ('>' == buf[sz - 1] || '"' == buf[sz - 1]))
|
||||
buf[sz - 1] = '\0';
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "link-includes");
|
||||
|
||||
i = 1;
|
||||
if (h->base_includes) {
|
||||
buffmt_includes(h, buf);
|
||||
PAIR_HREF_INIT(&tag[i], h->buf);
|
||||
i++;
|
||||
}
|
||||
|
||||
t = print_otag(h, TAG_A, i, tag);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
for ( ; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1391,11 +1487,11 @@ mdoc_fn_pre(MDOC_ARGS)
|
|||
{
|
||||
struct tag *t;
|
||||
struct htmlpair tag[2];
|
||||
const struct mdoc_node *nn;
|
||||
char nbuf[BUFSIZ];
|
||||
const char *sp, *ep;
|
||||
int sz, i;
|
||||
int sz, i, pretty;
|
||||
|
||||
pretty = MDOC_SYNPRETTY & n->flags;
|
||||
synopsis_pre(h, n);
|
||||
|
||||
/* Split apart into type and name. */
|
||||
|
@ -1447,26 +1543,33 @@ mdoc_fn_pre(MDOC_ARGS)
|
|||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, "(");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
bufinit(h);
|
||||
PAIR_CLASS_INIT(&tag[0], "farg");
|
||||
bufinit(h);
|
||||
bufcat_style(h, "white-space", "nowrap");
|
||||
PAIR_STYLE_INIT(&tag[1], h);
|
||||
|
||||
for (nn = n->child->next; nn; nn = nn->next) {
|
||||
for (n = n->child->next; n; n = n->next) {
|
||||
i = 1;
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
i = 2;
|
||||
t = print_otag(h, TAG_I, i, tag);
|
||||
print_text(h, nn->string);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
if (nn->next)
|
||||
if (n->next) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ",");
|
||||
}
|
||||
}
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ")");
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
|
||||
if (pretty) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ";");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1517,11 +1620,13 @@ mdoc_sp_pre(MDOC_ARGS)
|
|||
SCALE_VS_INIT(&su, 1);
|
||||
|
||||
if (MDOC_sp == n->tok) {
|
||||
if (n->child)
|
||||
a2roffsu(n->child->string, &su, SCALE_VS);
|
||||
if (NULL != (n = n->child))
|
||||
if ( ! a2roffsu(n->string, &su, SCALE_VS))
|
||||
SCALE_VS_INIT(&su, atoi(n->string));
|
||||
} else
|
||||
su.scale = 0;
|
||||
|
||||
bufinit(h);
|
||||
bufcat_su(h, "height", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
@ -1537,20 +1642,23 @@ mdoc_sp_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_lk_pre(MDOC_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
struct htmlpair tag[2];
|
||||
|
||||
nn = n->child;
|
||||
if (NULL == (n = n->child))
|
||||
return(0);
|
||||
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "link-ext");
|
||||
PAIR_HREF_INIT(&tag[1], nn->string);
|
||||
PAIR_HREF_INIT(&tag[1], n->string);
|
||||
|
||||
print_otag(h, TAG_A, 2, tag);
|
||||
|
||||
if (NULL == nn || NULL == nn->next)
|
||||
return(1);
|
||||
if (NULL == n->next)
|
||||
print_text(h, n->string);
|
||||
|
||||
for (nn = nn->next; nn; nn = nn->next)
|
||||
print_text(h, nn->string);
|
||||
for (n = n->next; n; n = n->next)
|
||||
print_text(h, n->string);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1562,17 +1670,19 @@ mdoc_mt_pre(MDOC_ARGS)
|
|||
{
|
||||
struct htmlpair tag[2];
|
||||
struct tag *t;
|
||||
const struct mdoc_node *nn;
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "link-mail");
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
for (n = n->child; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
bufinit(h);
|
||||
bufcat(h, "mailto:");
|
||||
bufcat(h, nn->string);
|
||||
bufcat(h, n->string);
|
||||
|
||||
PAIR_HREF_INIT(&tag[1], h->buf);
|
||||
t = print_otag(h, TAG_A, 2, tag);
|
||||
print_text(h, nn->string);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
@ -1617,7 +1727,9 @@ mdoc_fo_post(MDOC_ARGS)
|
|||
|
||||
if (MDOC_BODY != n->type)
|
||||
return;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ")");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ";");
|
||||
}
|
||||
|
||||
|
@ -1626,7 +1738,6 @@ mdoc_fo_post(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_in_pre(MDOC_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
struct tag *t;
|
||||
struct htmlpair tag[2];
|
||||
int i;
|
||||
|
@ -1636,29 +1747,46 @@ mdoc_in_pre(MDOC_ARGS)
|
|||
PAIR_CLASS_INIT(&tag[0], "includes");
|
||||
print_otag(h, TAG_B, 1, tag);
|
||||
|
||||
/*
|
||||
* The first argument of the `In' gets special treatment as
|
||||
* being a linked value. Subsequent values are printed
|
||||
* afterward. groff does similarly. This also handles the case
|
||||
* of no children.
|
||||
*/
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags)
|
||||
print_text(h, "#include");
|
||||
|
||||
print_text(h, "<");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
if (NULL != (n = n->child)) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "link-includes");
|
||||
|
||||
i = 1;
|
||||
bufinit(h);
|
||||
if (h->base_includes) {
|
||||
buffmt_includes(h, nn->string);
|
||||
buffmt_includes(h, n->string);
|
||||
PAIR_HREF_INIT(&tag[i], h->buf);
|
||||
i++;
|
||||
}
|
||||
|
||||
t = print_otag(h, TAG_A, i, tag);
|
||||
print_mdoc_node(m, nn, h);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ">");
|
||||
|
||||
for ( ; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
print_text(h, n->string);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1679,31 +1807,38 @@ mdoc_ic_pre(MDOC_ARGS)
|
|||
static int
|
||||
mdoc_rv_pre(MDOC_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
struct htmlpair tag;
|
||||
struct tag *t;
|
||||
int nchild;
|
||||
|
||||
if (n->prev)
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "fname");
|
||||
|
||||
print_text(h, "The");
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
PAIR_CLASS_INIT(&tag, "fname");
|
||||
nchild = n->nchild;
|
||||
for (n = n->child; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
t = print_otag(h, TAG_B, 1, &tag);
|
||||
print_text(h, nn->string);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
if (nn->next && NULL == nn->next->next)
|
||||
print_text(h, "(), and");
|
||||
else if (nn->next)
|
||||
print_text(h, "(),");
|
||||
else
|
||||
print_text(h, "()");
|
||||
|
||||
if (nchild > 2 && n->next) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, ",");
|
||||
}
|
||||
|
||||
if (n->child && n->child->next)
|
||||
if (n->next && NULL == n->next->next)
|
||||
print_text(h, "and");
|
||||
}
|
||||
|
||||
if (nchild > 1)
|
||||
print_text(h, "functions return");
|
||||
else
|
||||
print_text(h, "function returns");
|
||||
|
@ -1769,6 +1904,7 @@ mdoc_bf_pre(MDOC_ARGS)
|
|||
* We want this to be inline-formatted, but needs to be div to
|
||||
* accept block children.
|
||||
*/
|
||||
bufinit(h);
|
||||
bufcat_style(h, "display", "inline");
|
||||
SCALE_HS_INIT(&su, 1);
|
||||
/* Needs a left-margin for spacing. */
|
||||
|
@ -1836,7 +1972,7 @@ mdoc_li_pre(MDOC_ARGS)
|
|||
struct htmlpair tag;
|
||||
|
||||
PAIR_CLASS_INIT(&tag, "lit");
|
||||
print_otag(h, TAG_SPAN, 1, &tag);
|
||||
print_otag(h, TAG_CODE, 1, &tag);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -1978,6 +2114,7 @@ mdoc__x_post(MDOC_ARGS)
|
|||
if (NULL == n->parent || MDOC_Rs != n->parent->tok)
|
||||
return;
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->next ? "," : ".");
|
||||
}
|
||||
|
||||
|
@ -2048,6 +2185,8 @@ mdoc_quote_pre(MDOC_ARGS)
|
|||
PAIR_CLASS_INIT(&tag, "opt");
|
||||
print_otag(h, TAG_SPAN, 1, &tag);
|
||||
break;
|
||||
case (MDOC_Eo):
|
||||
break;
|
||||
case (MDOC_Do):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Dq):
|
||||
|
@ -2063,7 +2202,11 @@ mdoc_quote_pre(MDOC_ARGS)
|
|||
print_text(h, "(");
|
||||
break;
|
||||
case (MDOC_Ql):
|
||||
/* FALLTHROUGH */
|
||||
print_text(h, "\\(oq");
|
||||
h->flags |= HTML_NOSPACE;
|
||||
PAIR_CLASS_INIT(&tag, "lit");
|
||||
print_otag(h, TAG_CODE, 1, &tag);
|
||||
break;
|
||||
case (MDOC_So):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Sq):
|
||||
|
@ -2109,6 +2252,8 @@ mdoc_quote_post(MDOC_ARGS)
|
|||
case (MDOC_Bq):
|
||||
print_text(h, "\\(rB");
|
||||
break;
|
||||
case (MDOC_Eo):
|
||||
break;
|
||||
case (MDOC_Qo):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Qq):
|
||||
|
|
170
external/bsd/mdocml/dist/mdoc_macro.c
vendored
170
external/bsd/mdocml/dist/mdoc_macro.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mdoc_macro.c,v 1.99 2010/12/15 23:39:40 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc_macro.c,v 1.115 2012/01/05 00:43:51 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -26,6 +26,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
@ -50,6 +51,8 @@ static int in_line(MACRO_PROT_ARGS);
|
|||
static int obsolete(MACRO_PROT_ARGS);
|
||||
static int phrase_ta(MACRO_PROT_ARGS);
|
||||
|
||||
static int dword(struct mdoc *, int, int,
|
||||
const char *, enum mdelim);
|
||||
static int append_delims(struct mdoc *,
|
||||
int, int *, char *);
|
||||
static enum mdoct lookup(enum mdoct, const char *);
|
||||
|
@ -71,8 +74,8 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
|||
{ in_line_eoln, MDOC_PROLOGUE }, /* Dd */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Dt */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Os */
|
||||
{ blk_full, 0 }, /* Sh */
|
||||
{ blk_full, 0 }, /* Ss */
|
||||
{ blk_full, MDOC_PARSED }, /* Sh */
|
||||
{ blk_full, MDOC_PARSED }, /* Ss */
|
||||
{ in_line_eoln, 0 }, /* Pp */
|
||||
{ blk_part_imp, MDOC_PARSED }, /* D1 */
|
||||
{ blk_part_imp, MDOC_PARSED }, /* Dl */
|
||||
|
@ -225,7 +228,6 @@ mdoc_macroend(struct mdoc *m)
|
|||
static enum mdoct
|
||||
lookup(enum mdoct from, const char *p)
|
||||
{
|
||||
/* FIXME: make -diag lists be un-PARSED. */
|
||||
|
||||
if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
|
||||
return(MDOC_MAX);
|
||||
|
@ -252,17 +254,24 @@ lookup_raw(const char *p)
|
|||
static int
|
||||
rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
struct mdoc_node *n, *np;
|
||||
|
||||
assert(to);
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
|
||||
/* LINTED */
|
||||
while (mdoc->last != to) {
|
||||
/*
|
||||
* Save the parent here, because we may delete the
|
||||
* m->last node in the post-validation phase and reset
|
||||
* it to m->last->parent, causing a step in the closing
|
||||
* out to be lost.
|
||||
*/
|
||||
np = mdoc->last->parent;
|
||||
if ( ! mdoc_valid_post(mdoc))
|
||||
return(0);
|
||||
n = mdoc->last;
|
||||
mdoc->last = mdoc->last->parent;
|
||||
mdoc->last = np;
|
||||
assert(mdoc->last);
|
||||
mdoc->last->last = n;
|
||||
}
|
||||
|
@ -506,7 +515,7 @@ make_pending(struct mdoc_node *broken, enum mdoct tok,
|
|||
taker->pending = broken->pending;
|
||||
}
|
||||
broken->pending = breaker;
|
||||
mdoc_vmsg(m, MANDOCERR_SCOPENEST, line, ppos,
|
||||
mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos,
|
||||
"%s breaks %s", mdoc_macronames[tok],
|
||||
mdoc_macronames[broken->tok]);
|
||||
return(1);
|
||||
|
@ -534,8 +543,9 @@ rew_sub(enum mdoc_type t, struct mdoc *m,
|
|||
case (REWIND_THIS):
|
||||
break;
|
||||
case (REWIND_FORCE):
|
||||
mdoc_vmsg(m, MANDOCERR_SCOPEBROKEN, line, ppos,
|
||||
"%s breaks %s", mdoc_macronames[tok],
|
||||
mandoc_vmsg(MANDOCERR_SCOPEBROKEN, m->parse,
|
||||
line, ppos, "%s breaks %s",
|
||||
mdoc_macronames[tok],
|
||||
mdoc_macronames[n->tok]);
|
||||
/* FALLTHROUGH */
|
||||
case (REWIND_MORE):
|
||||
|
@ -572,6 +582,40 @@ rew_sub(enum mdoc_type t, struct mdoc *m,
|
|||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a word and check whether it's punctuation or not.
|
||||
* Punctuation consists of those tokens found in mdoc_isdelim().
|
||||
*/
|
||||
static int
|
||||
dword(struct mdoc *m, int line,
|
||||
int col, const char *p, enum mdelim d)
|
||||
{
|
||||
|
||||
if (DELIM_MAX == d)
|
||||
d = mdoc_isdelim(p);
|
||||
|
||||
if ( ! mdoc_word_alloc(m, line, col, p))
|
||||
return(0);
|
||||
|
||||
if (DELIM_OPEN == d)
|
||||
m->last->flags |= MDOC_DELIMO;
|
||||
|
||||
/*
|
||||
* Closing delimiters only suppress the preceding space
|
||||
* when they follow something, not when they start a new
|
||||
* block or element, and not when they follow `No'.
|
||||
*
|
||||
* XXX Explicitly special-casing MDOC_No here feels
|
||||
* like a layering violation. Find a better way
|
||||
* and solve this in the code related to `No'!
|
||||
*/
|
||||
|
||||
else if (DELIM_CLOSE == d && m->last->prev &&
|
||||
m->last->prev->tok != MDOC_No)
|
||||
m->last->flags |= MDOC_DELIMC;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
append_delims(struct mdoc *m, int line, int *pos, char *buf)
|
||||
|
@ -585,27 +629,25 @@ append_delims(struct mdoc *m, int line, int *pos, char *buf)
|
|||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
ac = mdoc_zargs(m, line, pos, buf, ARGS_NOWARN, &p);
|
||||
ac = mdoc_zargs(m, line, pos, buf, &p);
|
||||
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
else if (ARGS_EOLN == ac)
|
||||
break;
|
||||
|
||||
assert(DELIM_NONE != mdoc_isdelim(p));
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
dword(m, line, la, p, DELIM_MAX);
|
||||
|
||||
/*
|
||||
* If we encounter end-of-sentence symbols, then trigger
|
||||
* the double-space.
|
||||
*
|
||||
* XXX: it's easy to allow this to propogate outward to
|
||||
* XXX: it's easy to allow this to propagate outward to
|
||||
* the last symbol, such that `. )' will cause the
|
||||
* correct double-spacing. However, (1) groff isn't
|
||||
* smart enough to do this and (2) it would require
|
||||
* knowing which symbols break this behaviour, for
|
||||
* example, `. ;' shouldn't propogate the double-space.
|
||||
* example, `. ;' shouldn't propagate the double-space.
|
||||
*/
|
||||
if (mandoc_eos(p, strlen(p), 0))
|
||||
m->last->flags |= MDOC_EOS;
|
||||
|
@ -703,8 +745,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
|||
if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
|
||||
/* FIXME: do this in validate */
|
||||
if (buf[*pos])
|
||||
if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST))
|
||||
return(0);
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST);
|
||||
|
||||
if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
|
||||
return(0);
|
||||
|
@ -739,7 +780,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
|||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, lastarg, p))
|
||||
if ( ! dword(m, line, lastarg, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -847,9 +888,9 @@ in_line(MACRO_PROT_ARGS)
|
|||
return(0);
|
||||
} else if ( ! nc && 0 == cnt) {
|
||||
mdoc_argv_free(arg);
|
||||
if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY))
|
||||
return(0);
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY);
|
||||
}
|
||||
|
||||
if ( ! mdoc_macro(m, ntok, line, la, pos, buf))
|
||||
return(0);
|
||||
if ( ! nl)
|
||||
|
@ -898,7 +939,8 @@ in_line(MACRO_PROT_ARGS)
|
|||
|
||||
if (DELIM_NONE == d)
|
||||
cnt++;
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
|
||||
if ( ! dword(m, line, la, p, d))
|
||||
return(0);
|
||||
|
||||
/*
|
||||
|
@ -929,8 +971,7 @@ in_line(MACRO_PROT_ARGS)
|
|||
return(0);
|
||||
} else if ( ! nc && 0 == cnt) {
|
||||
mdoc_argv_free(arg);
|
||||
if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY))
|
||||
return(0);
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY);
|
||||
}
|
||||
|
||||
if ( ! nl)
|
||||
|
@ -942,7 +983,7 @@ in_line(MACRO_PROT_ARGS)
|
|||
static int
|
||||
blk_full(MACRO_PROT_ARGS)
|
||||
{
|
||||
int la, nl;
|
||||
int la, nl, nparsed;
|
||||
struct mdoc_arg *arg;
|
||||
struct mdoc_node *head; /* save of head macro */
|
||||
struct mdoc_node *body; /* save of body macro */
|
||||
|
@ -965,7 +1006,7 @@ blk_full(MACRO_PROT_ARGS)
|
|||
}
|
||||
|
||||
/*
|
||||
* This routine accomodates implicitly- and explicitly-scoped
|
||||
* This routine accommodates implicitly- and explicitly-scoped
|
||||
* macro openings. Implicit ones first close out prior scope
|
||||
* (seen above). Delay opening the head until necessary to
|
||||
* allow leading punctuation to print. Special consideration
|
||||
|
@ -996,6 +1037,14 @@ blk_full(MACRO_PROT_ARGS)
|
|||
|
||||
head = body = NULL;
|
||||
|
||||
/*
|
||||
* Exception: Heads of `It' macros in `-diag' lists are not
|
||||
* parsed, even though `It' macros in general are parsed.
|
||||
*/
|
||||
nparsed = MDOC_It == tok &&
|
||||
MDOC_Bl == m->last->parent->tok &&
|
||||
LIST_diag == m->last->parent->norm->Bl.type;
|
||||
|
||||
/*
|
||||
* The `Nd' macro has all arguments in its body: it's a hybrid
|
||||
* of block partial-explicit and full-implicit. Stupid.
|
||||
|
@ -1055,7 +1104,7 @@ blk_full(MACRO_PROT_ARGS)
|
|||
ARGS_PPHRASE != ac &&
|
||||
ARGS_QWORD != ac &&
|
||||
DELIM_OPEN == mdoc_isdelim(p)) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_OPEN))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1104,10 +1153,11 @@ blk_full(MACRO_PROT_ARGS)
|
|||
continue;
|
||||
}
|
||||
|
||||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
|
||||
ntok = nparsed || ARGS_QWORD == ac ?
|
||||
MDOC_MAX : lookup(tok, p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1218,7 +1268,7 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||
|
||||
if (NULL == body && ARGS_QWORD != ac &&
|
||||
DELIM_OPEN == mdoc_isdelim(p)) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_OPEN))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1232,7 +1282,7 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1262,7 +1312,7 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||
if (mandoc_eos(n->string, strlen(n->string), 1))
|
||||
n->flags |= MDOC_EOS;
|
||||
|
||||
/* Up-propogate the end-of-space flag. */
|
||||
/* Up-propagate the end-of-space flag. */
|
||||
|
||||
if (n && (MDOC_EOS & n->flags)) {
|
||||
body->flags |= MDOC_EOS;
|
||||
|
@ -1292,9 +1342,9 @@ blk_part_imp(MACRO_PROT_ARGS)
|
|||
* is ugly behaviour nodding its head to OpenBSD's overwhelming
|
||||
* crufty use of `Op' breakage.
|
||||
*/
|
||||
if (n != body && ! mdoc_vmsg(m, MANDOCERR_SCOPENEST,
|
||||
line, ppos, "%s broken", mdoc_macronames[tok]))
|
||||
return(0);
|
||||
if (n != body)
|
||||
mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos,
|
||||
"%s broken", mdoc_macronames[tok]);
|
||||
|
||||
if (n && ! rew_sub(MDOC_BODY, m, tok, line, ppos))
|
||||
return(0);
|
||||
|
@ -1350,7 +1400,7 @@ blk_part_exp(MACRO_PROT_ARGS)
|
|||
if (NULL == head && ARGS_QWORD != ac &&
|
||||
DELIM_OPEN == mdoc_isdelim(p)) {
|
||||
assert(NULL == body);
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_OPEN))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1371,7 +1421,7 @@ blk_part_exp(MACRO_PROT_ARGS)
|
|||
assert(head);
|
||||
/* No check whether it's a macro! */
|
||||
if (MDOC_Eo == tok)
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
|
||||
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
|
||||
|
@ -1389,7 +1439,7 @@ blk_part_exp(MACRO_PROT_ARGS)
|
|||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1401,18 +1451,15 @@ blk_part_exp(MACRO_PROT_ARGS)
|
|||
|
||||
/* Clean-up to leave in a consistent state. */
|
||||
|
||||
if (NULL == head) {
|
||||
if (NULL == head)
|
||||
if ( ! mdoc_head_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
head = m->last;
|
||||
}
|
||||
|
||||
if (NULL == body) {
|
||||
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
|
||||
return(0);
|
||||
if ( ! mdoc_body_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
body = m->last;
|
||||
}
|
||||
|
||||
/* Standard appending of delimiters. */
|
||||
|
@ -1454,6 +1501,8 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||
case (MDOC_Ux):
|
||||
maxargs = 0;
|
||||
break;
|
||||
case (MDOC_Bx):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Xr):
|
||||
maxargs = 2;
|
||||
break;
|
||||
|
@ -1492,9 +1541,9 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||
break;
|
||||
|
||||
if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
|
||||
ARGS_QWORD != ac &&
|
||||
0 == j && DELIM_OPEN == mdoc_isdelim(p)) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
ARGS_QWORD != ac && 0 == j &&
|
||||
DELIM_OPEN == mdoc_isdelim(p)) {
|
||||
if ( ! dword(m, line, la, p, DELIM_OPEN))
|
||||
return(0);
|
||||
continue;
|
||||
} else if (0 == j)
|
||||
|
@ -1528,23 +1577,7 @@ in_line_argn(MACRO_PROT_ARGS)
|
|||
flushed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: this is a hack to work around groff's ugliness
|
||||
* as regards `Xr' and extraneous arguments. It should
|
||||
* ideally be deprecated behaviour, but because this is
|
||||
* code is no here, it's unlikely to be removed.
|
||||
*/
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
if (MDOC_Xr == tok && j == maxargs) {
|
||||
if ( ! mdoc_elem_alloc(m, line, la, MDOC_Ns, NULL))
|
||||
return(0);
|
||||
if ( ! rew_elem(m, MDOC_Ns))
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
j++;
|
||||
}
|
||||
|
@ -1615,7 +1648,7 @@ in_line_eoln(MACRO_PROT_ARGS)
|
|||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1664,7 +1697,8 @@ static int
|
|||
obsolete(MACRO_PROT_ARGS)
|
||||
{
|
||||
|
||||
return(mdoc_pmsg(m, line, ppos, MANDOCERR_MACROOBS));
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_MACROOBS);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1684,7 +1718,7 @@ phrase(struct mdoc *m, int line, int ppos, char *buf)
|
|||
for (pos = ppos; ; ) {
|
||||
la = pos;
|
||||
|
||||
ac = mdoc_zargs(m, line, &pos, buf, 0, &p);
|
||||
ac = mdoc_zargs(m, line, &pos, buf, &p);
|
||||
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
|
@ -1694,7 +1728,7 @@ phrase(struct mdoc *m, int line, int ppos, char *buf)
|
|||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1729,7 +1763,7 @@ phrase_ta(MACRO_PROT_ARGS)
|
|||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
ac = mdoc_zargs(m, line, pos, buf, 0, &p);
|
||||
ac = mdoc_zargs(m, line, pos, buf, &p);
|
||||
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
|
@ -1739,7 +1773,7 @@ phrase_ta(MACRO_PROT_ARGS)
|
|||
ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p);
|
||||
|
||||
if (MDOC_MAX == ntok) {
|
||||
if ( ! mdoc_word_alloc(m, line, la, p))
|
||||
if ( ! dword(m, line, la, p, DELIM_MAX))
|
||||
return(0);
|
||||
continue;
|
||||
}
|
||||
|
|
637
external/bsd/mdocml/dist/mdoc_man.c
vendored
Normal file
637
external/bsd/mdocml/dist/mdoc_man.c
vendored
Normal file
|
@ -0,0 +1,637 @@
|
|||
/* $Vendor-Id: mdoc_man.c,v 1.9 2011/10/24 21:47:59 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "man.h"
|
||||
#include "mdoc.h"
|
||||
#include "main.h"
|
||||
|
||||
#define DECL_ARGS const struct mdoc_meta *m, \
|
||||
const struct mdoc_node *n, \
|
||||
struct mman *mm
|
||||
|
||||
struct mman {
|
||||
int need_space; /* next word needs prior ws */
|
||||
int need_nl; /* next word needs prior nl */
|
||||
};
|
||||
|
||||
struct manact {
|
||||
int (*cond)(DECL_ARGS); /* DON'T run actions */
|
||||
int (*pre)(DECL_ARGS); /* pre-node action */
|
||||
void (*post)(DECL_ARGS); /* post-node action */
|
||||
const char *prefix; /* pre-node string constant */
|
||||
const char *suffix; /* post-node string constant */
|
||||
};
|
||||
|
||||
static int cond_body(DECL_ARGS);
|
||||
static int cond_head(DECL_ARGS);
|
||||
static void post_bd(DECL_ARGS);
|
||||
static void post_dl(DECL_ARGS);
|
||||
static void post_enc(DECL_ARGS);
|
||||
static void post_nm(DECL_ARGS);
|
||||
static void post_percent(DECL_ARGS);
|
||||
static void post_pf(DECL_ARGS);
|
||||
static void post_sect(DECL_ARGS);
|
||||
static void post_sp(DECL_ARGS);
|
||||
static int pre_ap(DECL_ARGS);
|
||||
static int pre_bd(DECL_ARGS);
|
||||
static int pre_br(DECL_ARGS);
|
||||
static int pre_bx(DECL_ARGS);
|
||||
static int pre_dl(DECL_ARGS);
|
||||
static int pre_enc(DECL_ARGS);
|
||||
static int pre_it(DECL_ARGS);
|
||||
static int pre_nm(DECL_ARGS);
|
||||
static int pre_ns(DECL_ARGS);
|
||||
static int pre_pp(DECL_ARGS);
|
||||
static int pre_sp(DECL_ARGS);
|
||||
static int pre_sect(DECL_ARGS);
|
||||
static int pre_ux(DECL_ARGS);
|
||||
static int pre_xr(DECL_ARGS);
|
||||
static void print_word(struct mman *, const char *);
|
||||
static void print_node(DECL_ARGS);
|
||||
|
||||
static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dd */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dt */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Os */
|
||||
{ NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
|
||||
{ NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
|
||||
{ NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
|
||||
{ cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
|
||||
{ cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
|
||||
{ cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ed */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bl */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* El */
|
||||
{ NULL, pre_it, NULL, NULL, NULL }, /* _It */
|
||||
{ NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ad */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _An */
|
||||
{ NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ar */
|
||||
{ NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cd */
|
||||
{ NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cm */
|
||||
{ NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Dv */
|
||||
{ NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Er */
|
||||
{ NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Ev */
|
||||
{ NULL, pre_enc, post_enc, "The \\fB",
|
||||
"\\fP\nutility exits 0 on success, and >0 if an error occurs."
|
||||
}, /* Ex */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Fa */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Fd */
|
||||
{ NULL, pre_enc, post_enc, "\\fB-", "\\fP" }, /* Fl */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Fn */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Ft */
|
||||
{ NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ic */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _In */
|
||||
{ NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Li */
|
||||
{ cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
|
||||
{ NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ot */
|
||||
{ NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Pa */
|
||||
{ NULL, pre_enc, post_enc, "The \\fB",
|
||||
"\\fP\nfunction returns the value 0 if successful;\n"
|
||||
"otherwise the value -1 is returned and the global\n"
|
||||
"variable \\fIerrno\\fP is set to indicate the error."
|
||||
}, /* Rv */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* St */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Va */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Vt */
|
||||
{ NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* _%A */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%B */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* _%D */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%I */
|
||||
{ NULL, pre_enc, post_percent, "\\fI", "\\fP" }, /* %J */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%N */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%O */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%P */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%R */
|
||||
{ NULL, pre_enc, post_percent, "\"", "\"" }, /* %T */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%V */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ac */
|
||||
{ cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
|
||||
{ cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* At */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Bc */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Bf */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
|
||||
{ NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
|
||||
{ NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Db */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
|
||||
{ cond_body, pre_enc, post_enc, "``", "''" }, /* Do */
|
||||
{ cond_body, pre_enc, post_enc, "``", "''" }, /* Dq */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Ec */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Ef */
|
||||
{ NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Em */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Eo */
|
||||
{ NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
|
||||
{ NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ms */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* No */
|
||||
{ NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
|
||||
{ NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
|
||||
{ NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Pc */
|
||||
{ NULL, NULL, post_pf, NULL, NULL }, /* Pf */
|
||||
{ cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
|
||||
{ cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Qc */
|
||||
{ cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
|
||||
{ cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
|
||||
{ cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Re */
|
||||
{ cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Sc */
|
||||
{ cond_body, pre_enc, post_enc, "`", "'" }, /* So */
|
||||
{ cond_body, pre_enc, post_enc, "`", "'" }, /* Sq */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Sm */
|
||||
{ NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Sx */
|
||||
{ NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Sy */
|
||||
{ NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Tn */
|
||||
{ NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Xc */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Xo */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Fo */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Fc */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Oc */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Bk */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Ek */
|
||||
{ NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Hf */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Fr */
|
||||
{ NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Lb */
|
||||
{ NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Lk */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Mt */
|
||||
{ cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
|
||||
{ cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Brc */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%C */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Es */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _En */
|
||||
{ NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%Q */
|
||||
{ NULL, pre_br, NULL, NULL, NULL }, /* br */
|
||||
{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _%U */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* _Ta */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* ROOT */
|
||||
};
|
||||
|
||||
static void
|
||||
print_word(struct mman *mm, const char *s)
|
||||
{
|
||||
|
||||
if (mm->need_nl) {
|
||||
/*
|
||||
* If we need a newline, print it now and start afresh.
|
||||
*/
|
||||
putchar('\n');
|
||||
mm->need_space = 0;
|
||||
mm->need_nl = 0;
|
||||
} else if (mm->need_space && '\0' != s[0])
|
||||
/*
|
||||
* If we need a space, only print it before
|
||||
* (1) a nonzero length word;
|
||||
* (2) a word that is non-punctuation; and
|
||||
* (3) if punctuation, non-terminating puncutation.
|
||||
*/
|
||||
if (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1])
|
||||
putchar(' ');
|
||||
|
||||
/*
|
||||
* Reassign needing space if we're not following opening
|
||||
* punctuation.
|
||||
*/
|
||||
mm->need_space =
|
||||
('(' != s[0] && '[' != s[0]) || '\0' != s[1];
|
||||
|
||||
for ( ; *s; s++) {
|
||||
switch (*s) {
|
||||
case (ASCII_NBRSP):
|
||||
printf("\\~");
|
||||
break;
|
||||
case (ASCII_HYPH):
|
||||
putchar('-');
|
||||
break;
|
||||
default:
|
||||
putchar((unsigned char)*s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
man_man(void *arg, const struct man *man)
|
||||
{
|
||||
|
||||
/*
|
||||
* Dump the keep buffer.
|
||||
* We're guaranteed by now that this exists (is non-NULL).
|
||||
* Flush stdout afterward, just in case.
|
||||
*/
|
||||
fputs(mparse_getkeep(man_mparse(man)), stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
man_mdoc(void *arg, const struct mdoc *mdoc)
|
||||
{
|
||||
const struct mdoc_meta *m;
|
||||
const struct mdoc_node *n;
|
||||
struct mman mm;
|
||||
|
||||
m = mdoc_meta(mdoc);
|
||||
n = mdoc_node(mdoc);
|
||||
|
||||
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
|
||||
m->title, m->msec, m->date, m->os, m->vol);
|
||||
|
||||
memset(&mm, 0, sizeof(struct mman));
|
||||
|
||||
mm.need_nl = 1;
|
||||
print_node(m, n, &mm);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
print_node(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *prev, *sub;
|
||||
const struct manact *act;
|
||||
int cond, do_sub;
|
||||
|
||||
/*
|
||||
* Break the line if we were parsed subsequent the current node.
|
||||
* This makes the page structure be more consistent.
|
||||
*/
|
||||
prev = n->prev ? n->prev : n->parent;
|
||||
if (prev && prev->line < n->line)
|
||||
mm->need_nl = 1;
|
||||
|
||||
act = NULL;
|
||||
cond = 0;
|
||||
do_sub = 1;
|
||||
|
||||
if (MDOC_TEXT == n->type) {
|
||||
/*
|
||||
* Make sure that we don't happen to start with a
|
||||
* control character at the start of a line.
|
||||
*/
|
||||
if (mm->need_nl && ('.' == *n->string ||
|
||||
'\'' == *n->string)) {
|
||||
print_word(mm, "\\&");
|
||||
mm->need_space = 0;
|
||||
}
|
||||
print_word(mm, n->string);
|
||||
} else {
|
||||
/*
|
||||
* Conditionally run the pre-node action handler for a
|
||||
* node.
|
||||
*/
|
||||
act = manacts + n->tok;
|
||||
cond = NULL == act->cond || (*act->cond)(m, n, mm);
|
||||
if (cond && act->pre)
|
||||
do_sub = (*act->pre)(m, n, mm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Conditionally run all child nodes.
|
||||
* Note that this iterates over children instead of using
|
||||
* recursion. This prevents unnecessary depth in the stack.
|
||||
*/
|
||||
if (do_sub)
|
||||
for (sub = n->child; sub; sub = sub->next)
|
||||
print_node(m, sub, mm);
|
||||
|
||||
/*
|
||||
* Lastly, conditionally run the post-node handler.
|
||||
*/
|
||||
if (cond && act->post)
|
||||
(*act->post)(m, n, mm);
|
||||
}
|
||||
|
||||
static int
|
||||
cond_head(DECL_ARGS)
|
||||
{
|
||||
|
||||
return(MDOC_HEAD == n->type);
|
||||
}
|
||||
|
||||
static int
|
||||
cond_body(DECL_ARGS)
|
||||
{
|
||||
|
||||
return(MDOC_BODY == n->type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output a font encoding before a node, e.g., \fR.
|
||||
* This obviously has no trailing space.
|
||||
*/
|
||||
static int
|
||||
pre_enc(DECL_ARGS)
|
||||
{
|
||||
const char *prefix;
|
||||
|
||||
prefix = manacts[n->tok].prefix;
|
||||
if (NULL == prefix)
|
||||
return(1);
|
||||
print_word(mm, prefix);
|
||||
mm->need_space = 0;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output a font encoding subsequent a node, e.g., \fP.
|
||||
*/
|
||||
static void
|
||||
post_enc(DECL_ARGS)
|
||||
{
|
||||
const char *suffix;
|
||||
|
||||
suffix = manacts[n->tok].suffix;
|
||||
if (NULL == suffix)
|
||||
return;
|
||||
mm->need_space = 0;
|
||||
print_word(mm, suffix);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used in listings (percent = %A, e.g.).
|
||||
* FIXME: this is incomplete.
|
||||
* It doesn't print a nice ", and" for lists.
|
||||
*/
|
||||
static void
|
||||
post_percent(DECL_ARGS)
|
||||
{
|
||||
|
||||
post_enc(m, n, mm);
|
||||
if (n->next)
|
||||
print_word(mm, ",");
|
||||
else {
|
||||
print_word(mm, ".");
|
||||
mm->need_nl = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print before a section header.
|
||||
*/
|
||||
static int
|
||||
pre_sect(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_HEAD != n->type)
|
||||
return(1);
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, manacts[n->tok].prefix);
|
||||
print_word(mm, "\"");
|
||||
mm->need_space = 0;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print subsequent a section header.
|
||||
*/
|
||||
static void
|
||||
post_sect(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_HEAD != n->type)
|
||||
return;
|
||||
mm->need_space = 0;
|
||||
print_word(mm, "\"");
|
||||
mm->need_nl = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ap(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_space = 0;
|
||||
print_word(mm, "'");
|
||||
mm->need_space = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_bd(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (DISP_unfilled == n->norm->Bd.type ||
|
||||
DISP_literal == n->norm->Bd.type) {
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".nf");
|
||||
}
|
||||
mm->need_nl = 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
post_bd(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (DISP_unfilled == n->norm->Bd.type ||
|
||||
DISP_literal == n->norm->Bd.type) {
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".fi");
|
||||
}
|
||||
mm->need_nl = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_br(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".br");
|
||||
mm->need_nl = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_bx(DECL_ARGS)
|
||||
{
|
||||
|
||||
n = n->child;
|
||||
if (n) {
|
||||
print_word(mm, n->string);
|
||||
mm->need_space = 0;
|
||||
n = n->next;
|
||||
}
|
||||
print_word(mm, "BSD");
|
||||
if (NULL == n)
|
||||
return(0);
|
||||
mm->need_space = 0;
|
||||
print_word(mm, "-");
|
||||
mm->need_space = 0;
|
||||
print_word(mm, n->string);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_dl(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".RS 6n");
|
||||
mm->need_nl = 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
post_dl(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".RE");
|
||||
mm->need_nl = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_it(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *bln;
|
||||
|
||||
if (MDOC_HEAD == n->type) {
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".TP");
|
||||
bln = n->parent->parent->prev;
|
||||
switch (bln->norm->Bl.type) {
|
||||
case (LIST_bullet):
|
||||
print_word(mm, "4n");
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, "\\fBo\\fP");
|
||||
break;
|
||||
default:
|
||||
if (bln->norm->Bl.width)
|
||||
print_word(mm, bln->norm->Bl.width);
|
||||
break;
|
||||
}
|
||||
mm->need_nl = 1;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_nm(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
|
||||
return(1);
|
||||
print_word(mm, "\\fB");
|
||||
mm->need_space = 0;
|
||||
if (NULL == n->child)
|
||||
print_word(mm, m->name);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
post_nm(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
|
||||
return;
|
||||
mm->need_space = 0;
|
||||
print_word(mm, "\\fP");
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ns(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_space = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
post_pf(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_space = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_pp(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_nl = 1;
|
||||
if (MDOC_It == n->parent->tok)
|
||||
print_word(mm, ".sp");
|
||||
else
|
||||
print_word(mm, ".PP");
|
||||
mm->need_nl = 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_sp(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_nl = 1;
|
||||
print_word(mm, ".sp");
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
post_sp(DECL_ARGS)
|
||||
{
|
||||
|
||||
mm->need_nl = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_xr(DECL_ARGS)
|
||||
{
|
||||
|
||||
n = n->child;
|
||||
if (NULL == n)
|
||||
return(0);
|
||||
print_node(m, n, mm);
|
||||
n = n->next;
|
||||
if (NULL == n)
|
||||
return(0);
|
||||
mm->need_space = 0;
|
||||
print_word(mm, "(");
|
||||
print_node(m, n, mm);
|
||||
print_word(mm, ")");
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ux(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_word(mm, manacts[n->tok].prefix);
|
||||
if (NULL == n->child)
|
||||
return(0);
|
||||
mm->need_space = 0;
|
||||
print_word(mm, "\\~");
|
||||
mm->need_space = 0;
|
||||
return(1);
|
||||
}
|
219
external/bsd/mdocml/dist/mdoc_strings.c
vendored
219
external/bsd/mdocml/dist/mdoc_strings.c
vendored
|
@ -1,219 +0,0 @@
|
|||
/* $Vendor-Id: mdoc_strings.c,v 1.24 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
static const char * const secnames[SEC__MAX] = {
|
||||
NULL,
|
||||
"NAME",
|
||||
"LIBRARY",
|
||||
"SYNOPSIS",
|
||||
"DESCRIPTION",
|
||||
"IMPLEMENTATION NOTES",
|
||||
"RETURN VALUES",
|
||||
"ENVIRONMENT",
|
||||
"FILES",
|
||||
"EXIT STATUS",
|
||||
"EXAMPLES",
|
||||
"DIAGNOSTICS",
|
||||
"COMPATIBILITY",
|
||||
"ERRORS",
|
||||
"SEE ALSO",
|
||||
"STANDARDS",
|
||||
"HISTORY",
|
||||
"AUTHORS",
|
||||
"CAVEATS",
|
||||
"BUGS",
|
||||
"SECURITY CONSIDERATIONS",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: this is repeated in print_text() (html.c) and term_word()
|
||||
* (term.c).
|
||||
*/
|
||||
enum mdelim
|
||||
mdoc_iscdelim(char p)
|
||||
{
|
||||
|
||||
switch (p) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
return(DELIM_OPEN);
|
||||
case('|'):
|
||||
return(DELIM_MIDDLE);
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
return(DELIM_CLOSE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(DELIM_NONE);
|
||||
}
|
||||
|
||||
|
||||
enum mdelim
|
||||
mdoc_isdelim(const char *p)
|
||||
{
|
||||
|
||||
if ('\0' == p[0])
|
||||
return(DELIM_NONE);
|
||||
if ('\0' == p[1])
|
||||
return(mdoc_iscdelim(p[0]));
|
||||
|
||||
/*
|
||||
* XXX; account for groff bubu where the \*(Ba reserved string
|
||||
* is treated in exactly the same way as the vertical bar. This
|
||||
* is the only function that checks for this.
|
||||
*/
|
||||
return(strcmp(p, "\\*(Ba") ? DELIM_NONE : DELIM_MIDDLE);
|
||||
}
|
||||
|
||||
|
||||
enum mdoc_sec
|
||||
mdoc_str2sec(const char *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)SEC__MAX; i++)
|
||||
if (secnames[i] && 0 == strcmp(p, secnames[i]))
|
||||
return((enum mdoc_sec)i);
|
||||
|
||||
return(SEC_CUSTOM);
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: move this into an editable .in file. */
|
||||
size_t
|
||||
mdoc_macro2len(enum mdoct macro)
|
||||
{
|
||||
|
||||
switch (macro) {
|
||||
case(MDOC_Ad):
|
||||
return(12);
|
||||
case(MDOC_Ao):
|
||||
return(12);
|
||||
case(MDOC_An):
|
||||
return(12);
|
||||
case(MDOC_Aq):
|
||||
return(12);
|
||||
case(MDOC_Ar):
|
||||
return(12);
|
||||
case(MDOC_Bo):
|
||||
return(12);
|
||||
case(MDOC_Bq):
|
||||
return(12);
|
||||
case(MDOC_Cd):
|
||||
return(12);
|
||||
case(MDOC_Cm):
|
||||
return(10);
|
||||
case(MDOC_Do):
|
||||
return(10);
|
||||
case(MDOC_Dq):
|
||||
return(12);
|
||||
case(MDOC_Dv):
|
||||
return(12);
|
||||
case(MDOC_Eo):
|
||||
return(12);
|
||||
case(MDOC_Em):
|
||||
return(10);
|
||||
case(MDOC_Er):
|
||||
return(17);
|
||||
case(MDOC_Ev):
|
||||
return(15);
|
||||
case(MDOC_Fa):
|
||||
return(12);
|
||||
case(MDOC_Fl):
|
||||
return(10);
|
||||
case(MDOC_Fo):
|
||||
return(16);
|
||||
case(MDOC_Fn):
|
||||
return(16);
|
||||
case(MDOC_Ic):
|
||||
return(10);
|
||||
case(MDOC_Li):
|
||||
return(16);
|
||||
case(MDOC_Ms):
|
||||
return(6);
|
||||
case(MDOC_Nm):
|
||||
return(10);
|
||||
case(MDOC_No):
|
||||
return(12);
|
||||
case(MDOC_Oo):
|
||||
return(10);
|
||||
case(MDOC_Op):
|
||||
return(14);
|
||||
case(MDOC_Pa):
|
||||
return(32);
|
||||
case(MDOC_Pf):
|
||||
return(12);
|
||||
case(MDOC_Po):
|
||||
return(12);
|
||||
case(MDOC_Pq):
|
||||
return(12);
|
||||
case(MDOC_Ql):
|
||||
return(16);
|
||||
case(MDOC_Qo):
|
||||
return(12);
|
||||
case(MDOC_So):
|
||||
return(12);
|
||||
case(MDOC_Sq):
|
||||
return(12);
|
||||
case(MDOC_Sy):
|
||||
return(6);
|
||||
case(MDOC_Sx):
|
||||
return(16);
|
||||
case(MDOC_Tn):
|
||||
return(10);
|
||||
case(MDOC_Va):
|
||||
return(12);
|
||||
case(MDOC_Vt):
|
||||
return(12);
|
||||
case(MDOC_Xr):
|
||||
return(10);
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return(0);
|
||||
}
|
303
external/bsd/mdocml/dist/mdoc_term.c
vendored
303
external/bsd/mdocml/dist/mdoc_term.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: mdoc_term.c,v 1.208 2011/01/06 14:05:12 kristaps Exp $ */
|
||||
/* $Vendor-Id: mdoc_term.c,v 1.238 2011/11/13 13:15:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
@ -32,12 +32,8 @@
|
|||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "mdoc.h"
|
||||
#include "chars.h"
|
||||
#include "main.h"
|
||||
|
||||
#define INDENT 5
|
||||
#define HALFINDENT 3
|
||||
|
||||
struct termpair {
|
||||
struct termpair *ppair;
|
||||
int count;
|
||||
|
@ -73,7 +69,6 @@ static void termp_an_post(DECL_ARGS);
|
|||
static void termp_bd_post(DECL_ARGS);
|
||||
static void termp_bk_post(DECL_ARGS);
|
||||
static void termp_bl_post(DECL_ARGS);
|
||||
static void termp_bx_post(DECL_ARGS);
|
||||
static void termp_d1_post(DECL_ARGS);
|
||||
static void termp_fo_post(DECL_ARGS);
|
||||
static void termp_in_post(DECL_ARGS);
|
||||
|
@ -95,6 +90,7 @@ static int termp_bk_pre(DECL_ARGS);
|
|||
static int termp_bl_pre(DECL_ARGS);
|
||||
static int termp_bold_pre(DECL_ARGS);
|
||||
static int termp_bt_pre(DECL_ARGS);
|
||||
static int termp_bx_pre(DECL_ARGS);
|
||||
static int termp_cd_pre(DECL_ARGS);
|
||||
static int termp_d1_pre(DECL_ARGS);
|
||||
static int termp_ex_pre(DECL_ARGS);
|
||||
|
@ -187,7 +183,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||
{ termp_quote_pre, termp_quote_post }, /* Bo */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Bq */
|
||||
{ termp_xx_pre, NULL }, /* Bsx */
|
||||
{ NULL, termp_bx_post }, /* Bx */
|
||||
{ termp_bx_pre, NULL }, /* Bx */
|
||||
{ NULL, NULL }, /* Db */
|
||||
{ NULL, NULL }, /* Dc */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Do */
|
||||
|
@ -195,7 +191,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
|||
{ NULL, NULL }, /* Ec */ /* FIXME: no space */
|
||||
{ NULL, NULL }, /* Ef */
|
||||
{ termp_under_pre, NULL }, /* Em */
|
||||
{ NULL, NULL }, /* Eo */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Eo */
|
||||
{ termp_xx_pre, NULL }, /* Fx */
|
||||
{ termp_bold_pre, NULL }, /* Ms */
|
||||
{ termp_igndelim_pre, NULL }, /* No */
|
||||
|
@ -260,19 +256,15 @@ terminal_mdoc(void *arg, const struct mdoc *mdoc)
|
|||
|
||||
p = (struct termp *)arg;
|
||||
|
||||
if (0 == p->defindent)
|
||||
p->defindent = 5;
|
||||
|
||||
p->overstep = 0;
|
||||
p->maxrmargin = p->defrmargin;
|
||||
p->tabwidth = term_len(p, 5);
|
||||
|
||||
if (NULL == p->symtab)
|
||||
switch (p->enc) {
|
||||
case (TERMENC_ASCII):
|
||||
p->symtab = chars_init(CHARS_ASCII);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
p->symtab = mchars_alloc();
|
||||
|
||||
n = mdoc_node(mdoc);
|
||||
m = mdoc_meta(mdoc);
|
||||
|
@ -313,20 +305,6 @@ print_mdoc_node(DECL_ARGS)
|
|||
memset(&npair, 0, sizeof(struct termpair));
|
||||
npair.ppair = pair;
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_TEXT):
|
||||
term_word(p, n->string);
|
||||
break;
|
||||
case (MDOC_TBL):
|
||||
term_tbl(p, n->span);
|
||||
break;
|
||||
default:
|
||||
if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
|
||||
chld = (*termacts[n->tok].pre)
|
||||
(p, &npair, m, n);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keeps only work until the end of a line. If a keep was
|
||||
* invoked in a prior line, revert it to PREKEEP.
|
||||
|
@ -357,6 +335,34 @@ print_mdoc_node(DECL_ARGS)
|
|||
(n->parent && MDOC_SYNPRETTY & n->parent->flags)))
|
||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||
|
||||
/*
|
||||
* After the keep flags have been set up, we may now
|
||||
* produce output. Note that some pre-handlers do so.
|
||||
*/
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_TEXT):
|
||||
if (' ' == *n->string && MDOC_LINE & n->flags)
|
||||
term_newln(p);
|
||||
if (MDOC_DELIMC & n->flags)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, n->string);
|
||||
if (MDOC_DELIMO & n->flags)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case (MDOC_EQN):
|
||||
term_eqn(p, n->eqn);
|
||||
break;
|
||||
case (MDOC_TBL):
|
||||
term_tbl(p, n->span);
|
||||
break;
|
||||
default:
|
||||
if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
|
||||
chld = (*termacts[n->tok].pre)
|
||||
(p, &npair, m, n);
|
||||
break;
|
||||
}
|
||||
|
||||
if (chld && n->child)
|
||||
print_mdoc_nodelist(p, &npair, m, n->child);
|
||||
|
||||
|
@ -367,6 +373,8 @@ print_mdoc_node(DECL_ARGS)
|
|||
break;
|
||||
case (MDOC_TBL):
|
||||
break;
|
||||
case (MDOC_EQN):
|
||||
break;
|
||||
default:
|
||||
if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
|
||||
break;
|
||||
|
@ -401,7 +409,6 @@ print_mdoc_node(DECL_ARGS)
|
|||
static void
|
||||
print_mdoc_foot(struct termp *p, const void *arg)
|
||||
{
|
||||
char buf[DATESIZ], os[BUFSIZ];
|
||||
const struct mdoc_meta *m;
|
||||
|
||||
m = (const struct mdoc_meta *)arg;
|
||||
|
@ -416,32 +423,29 @@ print_mdoc_foot(struct termp *p, const void *arg)
|
|||
* SYSTEM DATE SYSTEM
|
||||
*/
|
||||
|
||||
time2a(m->date, buf, DATESIZ);
|
||||
strlcpy(os, m->os, BUFSIZ);
|
||||
|
||||
term_vspace(p);
|
||||
|
||||
p->offset = 0;
|
||||
p->rmargin = (p->maxrmargin -
|
||||
term_strlen(p, buf) + term_len(p, 1)) / 2;
|
||||
term_strlen(p, m->date) + term_len(p, 1)) / 2;
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
|
||||
term_word(p, os);
|
||||
term_word(p, m->os);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, os);
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, m->os);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, buf);
|
||||
term_word(p, m->date);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, os);
|
||||
term_word(p, m->os);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = 0;
|
||||
|
@ -454,13 +458,11 @@ static void
|
|||
print_mdoc_head(struct termp *p, const void *arg)
|
||||
{
|
||||
char buf[BUFSIZ], title[BUFSIZ];
|
||||
size_t buflen, titlen;
|
||||
const struct mdoc_meta *m;
|
||||
|
||||
m = (const struct mdoc_meta *)arg;
|
||||
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->offset = 0;
|
||||
|
||||
/*
|
||||
* The header is strange. It has three components, which are
|
||||
* really two with the first duplicated. It goes like this:
|
||||
|
@ -474,8 +476,12 @@ print_mdoc_head(struct termp *p, const void *arg)
|
|||
* switches on the manual section.
|
||||
*/
|
||||
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
|
||||
assert(m->vol);
|
||||
strlcpy(buf, m->vol, BUFSIZ);
|
||||
buflen = term_strlen(p, buf);
|
||||
|
||||
if (m->arch) {
|
||||
strlcat(buf, " (", BUFSIZ);
|
||||
|
@ -484,33 +490,38 @@ print_mdoc_head(struct termp *p, const void *arg)
|
|||
}
|
||||
|
||||
snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
|
||||
titlen = term_strlen(p, title);
|
||||
|
||||
p->offset = 0;
|
||||
p->rmargin = (p->maxrmargin -
|
||||
term_strlen(p, buf) + term_len(p, 1)) / 2;
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
p->offset = 0;
|
||||
p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
|
||||
(p->maxrmargin -
|
||||
term_strlen(p, buf) + term_len(p, 1)) / 2 :
|
||||
p->maxrmargin - buflen;
|
||||
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, title);
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
|
||||
p->maxrmargin - titlen : p->maxrmargin;
|
||||
|
||||
term_word(p, buf);
|
||||
term_flushln(p);
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
if (p->rmargin + titlen <= p->maxrmargin) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -519,9 +530,10 @@ a2height(const struct termp *p, const char *v)
|
|||
{
|
||||
struct roffsu su;
|
||||
|
||||
|
||||
assert(v);
|
||||
if ( ! a2roffsu(v, &su, SCALE_VS))
|
||||
SCALE_VS_INIT(&su, term_len(p, 1));
|
||||
SCALE_VS_INIT(&su, atoi(v));
|
||||
|
||||
return(term_vspan(p, &su));
|
||||
}
|
||||
|
@ -550,9 +562,9 @@ a2offs(const struct termp *p, const char *v)
|
|||
else if (0 == strcmp(v, "left"))
|
||||
return(0);
|
||||
else if (0 == strcmp(v, "indent"))
|
||||
return(term_len(p, INDENT + 1));
|
||||
return(term_len(p, p->defindent + 1));
|
||||
else if (0 == strcmp(v, "indent-two"))
|
||||
return(term_len(p, (INDENT + 1) * 2));
|
||||
return(term_len(p, (p->defindent + 1) * 2));
|
||||
else if ( ! a2roffsu(v, &su, SCALE_MAX))
|
||||
SCALE_HS_INIT(&su, term_strlen(p, v));
|
||||
|
||||
|
@ -572,6 +584,8 @@ print_bvspace(struct termp *p,
|
|||
{
|
||||
const struct mdoc_node *nn;
|
||||
|
||||
assert(n);
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (MDOC_Bd == bl->tok && bl->norm->Bd.comp)
|
||||
|
@ -782,16 +796,11 @@ termp_it_pre(DECL_ARGS)
|
|||
case (LIST_hyphen):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
else
|
||||
p->flags |= TERMP_NOLPAD;
|
||||
break;
|
||||
case (LIST_hang):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
else
|
||||
p->flags |= TERMP_NOLPAD;
|
||||
|
||||
if (MDOC_HEAD != n->type)
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -802,17 +811,14 @@ termp_it_pre(DECL_ARGS)
|
|||
*/
|
||||
if (n->next->child &&
|
||||
(MDOC_Bl == n->next->child->tok ||
|
||||
MDOC_Bd == n->next->child->tok)) {
|
||||
MDOC_Bd == n->next->child->tok))
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
} else
|
||||
else
|
||||
p->flags |= TERMP_HANG;
|
||||
break;
|
||||
case (LIST_tag):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK | TERMP_TWOSPACE;
|
||||
else
|
||||
p->flags |= TERMP_NOLPAD;
|
||||
|
||||
if (MDOC_HEAD != n->type)
|
||||
break;
|
||||
|
@ -828,10 +834,6 @@ termp_it_pre(DECL_ARGS)
|
|||
else
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
|
||||
assert(n->prev);
|
||||
if (MDOC_BODY == n->prev->type)
|
||||
p->flags |= TERMP_NOLPAD;
|
||||
|
||||
break;
|
||||
case (LIST_diag):
|
||||
if (MDOC_HEAD == n->type)
|
||||
|
@ -988,7 +990,6 @@ termp_it_post(DECL_ARGS)
|
|||
p->flags &= ~TERMP_DANGLE;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags &= ~TERMP_TWOSPACE;
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
p->flags &= ~TERMP_HANG;
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1005,7 @@ termp_nm_pre(DECL_ARGS)
|
|||
if (MDOC_BODY == n->type) {
|
||||
if (NULL == n->child)
|
||||
return(0);
|
||||
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset += term_len(p, 1) +
|
||||
(NULL == n->prev->child ? term_strlen(p, m->name) :
|
||||
MDOC_TEXT == n->prev->child->type ?
|
||||
|
@ -1049,10 +1050,8 @@ termp_nm_post(DECL_ARGS)
|
|||
if (MDOC_HEAD == n->type && n->next->child) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
|
||||
} else if (MDOC_BODY == n->type && n->child) {
|
||||
} else if (MDOC_BODY == n->type && n->child)
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1149,6 +1148,7 @@ static int
|
|||
termp_ns_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if ( ! (MDOC_LINE & n->flags))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
return(1);
|
||||
}
|
||||
|
@ -1171,25 +1171,30 @@ termp_rs_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_rv_pre(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
int nchild;
|
||||
|
||||
term_newln(p);
|
||||
term_word(p, "The");
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
nchild = n->nchild;
|
||||
for (n = n->child; n; n = n->next) {
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, nn->string);
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (nn->next && NULL == nn->next->next)
|
||||
term_word(p, "(), and");
|
||||
else if (nn->next)
|
||||
term_word(p, "(),");
|
||||
else
|
||||
term_word(p, "()");
|
||||
|
||||
if (nchild > 2 && n->next) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
|
||||
if (n->child && n->child->next)
|
||||
if (n->next && NULL == n->next->next)
|
||||
term_word(p, "and");
|
||||
}
|
||||
|
||||
if (nchild > 1)
|
||||
term_word(p, "functions return");
|
||||
else
|
||||
term_word(p, "function returns");
|
||||
|
@ -1212,31 +1217,34 @@ termp_rv_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_ex_pre(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
int nchild;
|
||||
|
||||
term_newln(p);
|
||||
term_word(p, "The");
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
nchild = n->nchild;
|
||||
for (n = n->child; n; n = n->next) {
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, nn->string);
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (nchild > 2 && n->next) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (nn->next && NULL == nn->next->next)
|
||||
term_word(p, ", and");
|
||||
else if (nn->next)
|
||||
term_word(p, ",");
|
||||
else
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
if (n->child && n->child->next)
|
||||
if (n->next && NULL == n->next->next)
|
||||
term_word(p, "and");
|
||||
}
|
||||
|
||||
if (nchild > 1)
|
||||
term_word(p, "utilities exit");
|
||||
else
|
||||
term_word(p, "utility exits");
|
||||
|
||||
term_word(p, "0 on success, and >0 if an error occurs.");
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1276,31 +1284,33 @@ termp_bl_post(DECL_ARGS)
|
|||
term_newln(p);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
termp_xr_pre(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
|
||||
if (NULL == n->child)
|
||||
if (NULL == (n = n->child))
|
||||
return(0);
|
||||
|
||||
assert(MDOC_TEXT == n->child->type);
|
||||
nn = n->child;
|
||||
assert(MDOC_TEXT == n->type);
|
||||
term_word(p, n->string);
|
||||
|
||||
term_word(p, nn->string);
|
||||
if (NULL == (nn = nn->next))
|
||||
if (NULL == (n = n->next))
|
||||
return(0);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "(");
|
||||
term_word(p, nn->string);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
assert(MDOC_TEXT == n->type);
|
||||
term_word(p, n->string);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ")");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This decides how to assert whitespace before any of the SYNOPSIS set
|
||||
* of macros (which, as in the case of Ft/Fo and Ft/Fn, may contain
|
||||
|
@ -1414,7 +1424,7 @@ termp_sh_pre(DECL_ARGS)
|
|||
term_fontpush(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case (MDOC_BODY):
|
||||
p->offset = term_len(p, INDENT);
|
||||
p->offset = term_len(p, p->defindent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1482,7 +1492,7 @@ termp_d1_pre(DECL_ARGS)
|
|||
if (MDOC_BLOCK != n->type)
|
||||
return(1);
|
||||
term_newln(p);
|
||||
p->offset += term_len(p, (INDENT + 1));
|
||||
p->offset += term_len(p, p->defindent + 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -1514,30 +1524,43 @@ termp_ft_pre(DECL_ARGS)
|
|||
static int
|
||||
termp_fn_pre(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn;
|
||||
int pretty;
|
||||
|
||||
pretty = MDOC_SYNPRETTY & n->flags;
|
||||
|
||||
synopsis_pre(p, n);
|
||||
|
||||
if (NULL == (n = n->child))
|
||||
return(0);
|
||||
|
||||
assert(MDOC_TEXT == n->type);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, n->child->string);
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
for (nn = n->child->next; nn; nn = nn->next) {
|
||||
for (n = n->next; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
term_word(p, nn->string);
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (nn->next)
|
||||
if (n->next) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
}
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ")");
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
if (pretty) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ";");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1559,12 +1582,16 @@ termp_fa_pre(DECL_ARGS)
|
|||
term_word(p, nn->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (nn->next)
|
||||
if (nn->next) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if (n->child && n->next && n->next->tok == MDOC_Fa)
|
||||
if (n->child && n->next && n->next->tok == MDOC_Fa) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1672,13 +1699,27 @@ termp_bd_post(DECL_ARGS)
|
|||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
termp_bx_post(DECL_ARGS)
|
||||
static int
|
||||
termp_bx_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->child)
|
||||
if (NULL != (n = n->child)) {
|
||||
term_word(p, n->string);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "BSD");
|
||||
} else {
|
||||
term_word(p, "BSD");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (NULL != (n = n->next)) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "-");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, n->string);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1687,6 +1728,7 @@ static int
|
|||
termp_xx_pre(DECL_ARGS)
|
||||
{
|
||||
const char *pp;
|
||||
int flags;
|
||||
|
||||
pp = NULL;
|
||||
switch (n->tok) {
|
||||
|
@ -1712,9 +1754,14 @@ termp_xx_pre(DECL_ARGS)
|
|||
break;
|
||||
}
|
||||
|
||||
assert(pp);
|
||||
term_word(p, pp);
|
||||
return(1);
|
||||
if (n->child) {
|
||||
flags = p->flags;
|
||||
p->flags |= TERMP_KEEP;
|
||||
term_word(p, n->child->string);
|
||||
p->flags = flags;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1750,7 +1797,7 @@ termp_ss_pre(DECL_ARGS)
|
|||
break;
|
||||
case (MDOC_HEAD):
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
p->offset = term_len(p, HALFINDENT);
|
||||
p->offset = term_len(p, (p->defindent+1)/2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1878,6 +1925,8 @@ termp_quote_pre(DECL_ARGS)
|
|||
case (MDOC_Dq):
|
||||
term_word(p, "``");
|
||||
break;
|
||||
case (MDOC_Eo):
|
||||
break;
|
||||
case (MDOC_Po):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Pq):
|
||||
|
@ -1942,6 +1991,8 @@ termp_quote_post(DECL_ARGS)
|
|||
case (MDOC_Dq):
|
||||
term_word(p, "''");
|
||||
break;
|
||||
case (MDOC_Eo):
|
||||
break;
|
||||
case (MDOC_Po):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Pq):
|
||||
|
@ -1979,6 +2030,7 @@ termp_fo_pre(DECL_ARGS)
|
|||
} else if (MDOC_BODY == n->type) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -2002,10 +2054,13 @@ termp_fo_post(DECL_ARGS)
|
|||
if (MDOC_BODY != n->type)
|
||||
return;
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ")");
|
||||
|
||||
if (MDOC_SYNPRETTY & n->flags)
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ";");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2079,6 +2134,7 @@ termp____post(DECL_ARGS)
|
|||
if (NULL == n->parent || MDOC_Rs != n->parent->tok)
|
||||
return;
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (NULL == n->next) {
|
||||
term_word(p, ".");
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
@ -2115,6 +2171,7 @@ termp_lk_pre(DECL_ARGS)
|
|||
|
||||
term_fontpop(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ":");
|
||||
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
|
@ -2167,7 +2224,7 @@ termp__t_post(DECL_ARGS)
|
|||
* us instead of underlining us (for disambiguation).
|
||||
*/
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
n->parent->norm->Rs.child_J)
|
||||
n->parent->norm->Rs.quote_T)
|
||||
termp_quote_post(p, pair, m, n);
|
||||
|
||||
termp____post(p, pair, m, n);
|
||||
|
@ -2183,7 +2240,7 @@ termp__t_pre(DECL_ARGS)
|
|||
* us instead of underlining us (for disambiguation).
|
||||
*/
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
n->parent->norm->Rs.child_J)
|
||||
n->parent->norm->Rs.quote_T)
|
||||
return(termp_quote_pre(p, pair, m, n));
|
||||
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
|
|
435
external/bsd/mdocml/dist/mdoc_validate.c
vendored
435
external/bsd/mdocml/dist/mdoc_validate.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: mdoc_validate.c,v 1.151 2011/01/03 23:53:51 schwarze Exp $ */
|
||||
/* $Vendor-Id: mdoc_validate.c,v 1.181 2011/12/03 16:58:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
|
@ -33,6 +33,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
@ -71,14 +72,13 @@ static void check_text(struct mdoc *, int, int, char *);
|
|||
static void check_argv(struct mdoc *,
|
||||
struct mdoc_node *, struct mdoc_argv *);
|
||||
static void check_args(struct mdoc *, struct mdoc_node *);
|
||||
|
||||
static int concat(struct mdoc *, char *,
|
||||
const struct mdoc_node *, size_t);
|
||||
static int concat(char *, const struct mdoc_node *, size_t);
|
||||
static enum mdoc_sec a2sec(const char *);
|
||||
static size_t macro2len(enum mdoct);
|
||||
|
||||
static int ebool(POST_ARGS);
|
||||
static int berr_ge1(POST_ARGS);
|
||||
static int bwarn_ge1(POST_ARGS);
|
||||
static int eerr_ge1(POST_ARGS);
|
||||
static int ewarn_eq0(POST_ARGS);
|
||||
static int ewarn_eq1(POST_ARGS);
|
||||
static int ewarn_ge1(POST_ARGS);
|
||||
|
@ -96,6 +96,7 @@ static int post_bl_block(POST_ARGS);
|
|||
static int post_bl_block_width(POST_ARGS);
|
||||
static int post_bl_block_tag(POST_ARGS);
|
||||
static int post_bl_head(POST_ARGS);
|
||||
static int post_bx(POST_ARGS);
|
||||
static int post_dd(POST_ARGS);
|
||||
static int post_dt(POST_ARGS);
|
||||
static int post_defaults(POST_ARGS);
|
||||
|
@ -104,6 +105,7 @@ static int post_eoln(POST_ARGS);
|
|||
static int post_it(POST_ARGS);
|
||||
static int post_lb(POST_ARGS);
|
||||
static int post_nm(POST_ARGS);
|
||||
static int post_ns(POST_ARGS);
|
||||
static int post_os(POST_ARGS);
|
||||
static int post_ignpar(POST_ARGS);
|
||||
static int post_prol(POST_ARGS);
|
||||
|
@ -135,10 +137,11 @@ static v_post posts_bd[] = { post_literal, hwarn_eq0, bwarn_ge1, NULL };
|
|||
static v_post posts_bf[] = { hwarn_le1, post_bf, NULL };
|
||||
static v_post posts_bk[] = { hwarn_eq0, bwarn_ge1, NULL };
|
||||
static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL };
|
||||
static v_post posts_bx[] = { post_bx, NULL };
|
||||
static v_post posts_bool[] = { ebool, NULL };
|
||||
static v_post posts_eoln[] = { post_eoln, NULL };
|
||||
static v_post posts_defaults[] = { post_defaults, NULL };
|
||||
static v_post posts_dd[] = { ewarn_ge1, post_dd, post_prol, NULL };
|
||||
static v_post posts_dd[] = { post_dd, post_prol, NULL };
|
||||
static v_post posts_dl[] = { post_literal, bwarn_ge1, NULL };
|
||||
static v_post posts_dt[] = { post_dt, post_prol, NULL };
|
||||
static v_post posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };
|
||||
|
@ -147,18 +150,18 @@ static v_post posts_lb[] = { post_lb, NULL };
|
|||
static v_post posts_nd[] = { berr_ge1, NULL };
|
||||
static v_post posts_nm[] = { post_nm, NULL };
|
||||
static v_post posts_notext[] = { ewarn_eq0, NULL };
|
||||
static v_post posts_ns[] = { post_ns, NULL };
|
||||
static v_post posts_os[] = { post_os, post_prol, NULL };
|
||||
static v_post posts_rs[] = { post_rs, NULL };
|
||||
static v_post posts_sh[] = { post_ignpar, hwarn_ge1, bwarn_ge1, post_sh, NULL };
|
||||
static v_post posts_sh[] = { post_ignpar, hwarn_ge1, post_sh, NULL };
|
||||
static v_post posts_sp[] = { ewarn_le1, NULL };
|
||||
static v_post posts_ss[] = { post_ignpar, hwarn_ge1, bwarn_ge1, NULL };
|
||||
static v_post posts_ss[] = { post_ignpar, hwarn_ge1, NULL };
|
||||
static v_post posts_st[] = { post_st, NULL };
|
||||
static v_post posts_std[] = { post_std, NULL };
|
||||
static v_post posts_text[] = { eerr_ge1, NULL };
|
||||
static v_post posts_text[] = { ewarn_ge1, NULL };
|
||||
static v_post posts_text1[] = { ewarn_eq1, NULL };
|
||||
static v_post posts_vt[] = { post_vt, NULL };
|
||||
static v_post posts_wline[] = { bwarn_ge1, NULL };
|
||||
static v_post posts_wtext[] = { ewarn_ge1, NULL };
|
||||
static v_pre pres_an[] = { pre_an, NULL };
|
||||
static v_pre pres_bd[] = { pre_display, pre_bd, pre_literal, pre_par, NULL };
|
||||
static v_pre pres_bl[] = { pre_bl, pre_par, NULL };
|
||||
|
@ -175,7 +178,7 @@ static v_pre pres_sh[] = { pre_sh, NULL };
|
|||
static v_pre pres_ss[] = { pre_ss, NULL };
|
||||
static v_pre pres_std[] = { pre_std, NULL };
|
||||
|
||||
const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* Ap */
|
||||
{ pres_dd, posts_dd }, /* Dd */
|
||||
{ pres_dt, posts_dt }, /* Dt */
|
||||
|
@ -190,21 +193,21 @@ const struct valids mdoc_valids[MDOC_MAX] = {
|
|||
{ pres_bl, posts_bl }, /* Bl */
|
||||
{ NULL, NULL }, /* El */
|
||||
{ pres_it, posts_it }, /* It */
|
||||
{ NULL, posts_text }, /* Ad */
|
||||
{ NULL, NULL }, /* Ad */
|
||||
{ pres_an, posts_an }, /* An */
|
||||
{ NULL, posts_defaults }, /* Ar */
|
||||
{ NULL, posts_text }, /* Cd */
|
||||
{ NULL, NULL }, /* Cd */
|
||||
{ NULL, NULL }, /* Cm */
|
||||
{ NULL, NULL }, /* Dv */
|
||||
{ pres_er, posts_text }, /* Er */
|
||||
{ pres_er, NULL }, /* Er */
|
||||
{ NULL, NULL }, /* Ev */
|
||||
{ pres_std, posts_std }, /* Ex */
|
||||
{ NULL, NULL }, /* Fa */
|
||||
{ pres_fd, posts_wtext }, /* Fd */
|
||||
{ pres_fd, posts_text }, /* Fd */
|
||||
{ NULL, NULL }, /* Fl */
|
||||
{ NULL, posts_text }, /* Fn */
|
||||
{ NULL, posts_wtext }, /* Ft */
|
||||
{ NULL, posts_text }, /* Ic */
|
||||
{ NULL, NULL }, /* Fn */
|
||||
{ NULL, NULL }, /* Ft */
|
||||
{ NULL, NULL }, /* Ic */
|
||||
{ NULL, posts_text1 }, /* In */
|
||||
{ NULL, posts_defaults }, /* Li */
|
||||
{ NULL, posts_nd }, /* Nd */
|
||||
|
@ -216,10 +219,10 @@ const struct valids mdoc_valids[MDOC_MAX] = {
|
|||
{ NULL, posts_st }, /* St */
|
||||
{ NULL, NULL }, /* Va */
|
||||
{ NULL, posts_vt }, /* Vt */
|
||||
{ NULL, posts_wtext }, /* Xr */
|
||||
{ NULL, posts_text }, /* Xr */
|
||||
{ NULL, posts_text }, /* %A */
|
||||
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */
|
||||
{ NULL, posts_text }, /* %D */ /* FIXME: check date with mandoc_a2time(). */
|
||||
{ NULL, posts_text }, /* %D */
|
||||
{ NULL, posts_text }, /* %I */
|
||||
{ NULL, posts_text }, /* %J */
|
||||
{ NULL, posts_text }, /* %N */
|
||||
|
@ -237,7 +240,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
|
|||
{ NULL, NULL }, /* Bo */
|
||||
{ NULL, NULL }, /* Bq */
|
||||
{ NULL, NULL }, /* Bsx */
|
||||
{ NULL, NULL }, /* Bx */
|
||||
{ NULL, posts_bx }, /* Bx */
|
||||
{ NULL, posts_bool }, /* Db */
|
||||
{ NULL, NULL }, /* Dc */
|
||||
{ NULL, NULL }, /* Do */
|
||||
|
@ -247,9 +250,9 @@ const struct valids mdoc_valids[MDOC_MAX] = {
|
|||
{ NULL, NULL }, /* Em */
|
||||
{ NULL, NULL }, /* Eo */
|
||||
{ NULL, NULL }, /* Fx */
|
||||
{ NULL, posts_text }, /* Ms */
|
||||
{ NULL, NULL }, /* Ms */
|
||||
{ NULL, posts_notext }, /* No */
|
||||
{ NULL, posts_notext }, /* Ns */
|
||||
{ NULL, posts_ns }, /* Ns */
|
||||
{ NULL, NULL }, /* Nx */
|
||||
{ NULL, NULL }, /* Ox */
|
||||
{ NULL, NULL }, /* Pc */
|
||||
|
@ -266,9 +269,9 @@ const struct valids mdoc_valids[MDOC_MAX] = {
|
|||
{ NULL, NULL }, /* So */
|
||||
{ NULL, NULL }, /* Sq */
|
||||
{ NULL, posts_bool }, /* Sm */
|
||||
{ NULL, posts_text }, /* Sx */
|
||||
{ NULL, posts_text }, /* Sy */
|
||||
{ NULL, posts_text }, /* Tn */
|
||||
{ NULL, NULL }, /* Sx */
|
||||
{ NULL, NULL }, /* Sy */
|
||||
{ NULL, NULL }, /* Tn */
|
||||
{ NULL, NULL }, /* Ux */
|
||||
{ NULL, NULL }, /* Xc */
|
||||
{ NULL, NULL }, /* Xo */
|
||||
|
@ -284,7 +287,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
|
|||
{ NULL, posts_eoln }, /* Ud */
|
||||
{ NULL, posts_lb }, /* Lb */
|
||||
{ NULL, posts_notext }, /* Lp */
|
||||
{ NULL, posts_text }, /* Lk */
|
||||
{ NULL, NULL }, /* Lk */
|
||||
{ NULL, posts_defaults }, /* Mt */
|
||||
{ NULL, NULL }, /* Brq */
|
||||
{ NULL, NULL }, /* Bro */
|
||||
|
@ -319,6 +322,30 @@ static const enum mdoct rsord[RSORD_MAX] = {
|
|||
MDOC__U
|
||||
};
|
||||
|
||||
static const char * const secnames[SEC__MAX] = {
|
||||
NULL,
|
||||
"NAME",
|
||||
"LIBRARY",
|
||||
"SYNOPSIS",
|
||||
"DESCRIPTION",
|
||||
"IMPLEMENTATION NOTES",
|
||||
"RETURN VALUES",
|
||||
"ENVIRONMENT",
|
||||
"FILES",
|
||||
"EXIT STATUS",
|
||||
"EXAMPLES",
|
||||
"DIAGNOSTICS",
|
||||
"COMPATIBILITY",
|
||||
"ERRORS",
|
||||
"SEE ALSO",
|
||||
"STANDARDS",
|
||||
"HISTORY",
|
||||
"AUTHORS",
|
||||
"CAVEATS",
|
||||
"BUGS",
|
||||
"SECURITY CONSIDERATIONS",
|
||||
NULL
|
||||
};
|
||||
|
||||
int
|
||||
mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
|
||||
|
@ -336,6 +363,8 @@ mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
|
|||
/* FALLTHROUGH */
|
||||
case (MDOC_TBL):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_EQN):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_ROOT):
|
||||
return(1);
|
||||
default:
|
||||
|
@ -365,6 +394,8 @@ mdoc_valid_post(struct mdoc *mdoc)
|
|||
switch (mdoc->last->type) {
|
||||
case (MDOC_TEXT):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_EQN):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_TBL):
|
||||
return(1);
|
||||
case (MDOC_ROOT):
|
||||
|
@ -414,10 +445,10 @@ check_count(struct mdoc *m, enum mdoc_type type,
|
|||
}
|
||||
|
||||
t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT;
|
||||
|
||||
return(mdoc_vmsg(m, t, m->last->line, m->last->pos,
|
||||
mandoc_vmsg(t, m->parse, m->last->line, m->last->pos,
|
||||
"want %s%d children (have %d)",
|
||||
p, val, m->last->nchild));
|
||||
p, val, m->last->nchild);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -433,12 +464,6 @@ bwarn_ge1(POST_ARGS)
|
|||
return(check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
eerr_ge1(POST_ARGS)
|
||||
{
|
||||
return(check_count(mdoc, MDOC_ELEM, CHECK_ERROR, CHECK_GT, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
ewarn_eq0(POST_ARGS)
|
||||
{
|
||||
|
@ -518,32 +543,13 @@ check_argv(struct mdoc *m, struct mdoc_node *n, struct mdoc_argv *v)
|
|||
static void
|
||||
check_text(struct mdoc *m, int ln, int pos, char *p)
|
||||
{
|
||||
int c;
|
||||
size_t sz;
|
||||
char *cp;
|
||||
|
||||
for ( ; *p; p++, pos++) {
|
||||
sz = strcspn(p, "\t\\");
|
||||
p += (int)sz;
|
||||
if (MDOC_LITERAL & m->flags)
|
||||
return;
|
||||
|
||||
if ('\0' == *p)
|
||||
break;
|
||||
|
||||
pos += (int)sz;
|
||||
|
||||
if ('\t' == *p) {
|
||||
if ( ! (MDOC_LITERAL & m->flags))
|
||||
mdoc_pmsg(m, ln, pos, MANDOCERR_BADTAB);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 == (c = mandoc_special(p))) {
|
||||
mdoc_pmsg(m, ln, pos, MANDOCERR_BADESCAPE);
|
||||
continue;
|
||||
}
|
||||
|
||||
p += c - 1;
|
||||
pos += c - 1;
|
||||
}
|
||||
for (cp = p; NULL != (p = strchr(p, '\t')); p++)
|
||||
mdoc_pmsg(m, ln, pos + (int)(p - cp), MANDOCERR_BADTAB);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -555,10 +561,9 @@ check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type t)
|
|||
(t == n->parent->type))
|
||||
return(1);
|
||||
|
||||
mdoc_vmsg(mdoc, MANDOCERR_SYNTCHILD,
|
||||
n->line, n->pos, "want parent %s",
|
||||
MDOC_ROOT == t ? "<root>" :
|
||||
mdoc_macronames[tok]);
|
||||
mandoc_vmsg(MANDOCERR_SYNTCHILD, mdoc->parse, n->line,
|
||||
n->pos, "want parent %s", MDOC_ROOT == t ?
|
||||
"<root>" : mdoc_macronames[tok]);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -697,7 +702,7 @@ pre_bl(PRE_ARGS)
|
|||
if (LIST_column == lt) {
|
||||
n->norm->Bl.ncols =
|
||||
n->args->argv[i].sz;
|
||||
n->norm->Bl.cols = (const char **)
|
||||
n->norm->Bl.cols = (void *)
|
||||
n->args->argv[i].value;
|
||||
}
|
||||
}
|
||||
|
@ -865,7 +870,7 @@ pre_sh(PRE_ARGS)
|
|||
if (MDOC_BLOCK != n->type)
|
||||
return(1);
|
||||
|
||||
mdoc->regs->regs[(int)REG_nS].set = 0;
|
||||
roff_regunset(mdoc->roff, REG_nS);
|
||||
return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT));
|
||||
}
|
||||
|
||||
|
@ -919,7 +924,7 @@ static int
|
|||
pre_dt(PRE_ARGS)
|
||||
{
|
||||
|
||||
if (0 == mdoc->meta.date || mdoc->meta.os)
|
||||
if (NULL == mdoc->meta.date || mdoc->meta.os)
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO);
|
||||
|
||||
if (mdoc->meta.title)
|
||||
|
@ -932,7 +937,7 @@ static int
|
|||
pre_os(PRE_ARGS)
|
||||
{
|
||||
|
||||
if (NULL == mdoc->meta.title || 0 == mdoc->meta.date)
|
||||
if (NULL == mdoc->meta.title || NULL == mdoc->meta.date)
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO);
|
||||
|
||||
if (mdoc->meta.os)
|
||||
|
@ -1079,12 +1084,11 @@ post_vt(POST_ARGS)
|
|||
/*
|
||||
* The Vt macro comes in both ELEM and BLOCK form, both of which
|
||||
* have different syntaxes (yet more context-sensitive
|
||||
* behaviour). ELEM types must have a child; BLOCK types,
|
||||
* behaviour). ELEM types must have a child, which is already
|
||||
* guaranteed by the in_line parsing routine; BLOCK types,
|
||||
* specifically the BODY, should only have TEXT children.
|
||||
*/
|
||||
|
||||
if (MDOC_ELEM == mdoc->last->type)
|
||||
return(eerr_ge1(mdoc));
|
||||
if (MDOC_BODY != mdoc->last->type)
|
||||
return(1);
|
||||
|
||||
|
@ -1100,6 +1104,7 @@ static int
|
|||
post_nm(POST_ARGS)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
int c;
|
||||
|
||||
/* If no child specified, make sure we have the meta name. */
|
||||
|
||||
|
@ -1111,11 +1116,14 @@ post_nm(POST_ARGS)
|
|||
|
||||
/* If no meta name, set it from the child. */
|
||||
|
||||
if ( ! concat(mdoc, buf, mdoc->last->child, BUFSIZ))
|
||||
buf[0] = '\0';
|
||||
if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) {
|
||||
mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);
|
||||
return(0);
|
||||
}
|
||||
|
||||
assert(c);
|
||||
mdoc->meta.name = mandoc_strdup(buf);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -1228,19 +1236,12 @@ post_an(POST_ARGS)
|
|||
struct mdoc_node *np;
|
||||
|
||||
np = mdoc->last;
|
||||
if (AUTH__NONE != np->norm->An.auth && np->child) {
|
||||
if (AUTH__NONE == np->norm->An.auth) {
|
||||
if (0 == np->child)
|
||||
check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0);
|
||||
} else if (np->child)
|
||||
check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: make this ewarn and make sure that the front-ends
|
||||
* don't print the arguments.
|
||||
*/
|
||||
if (AUTH__NONE != np->norm->An.auth || np->child)
|
||||
return(1);
|
||||
|
||||
mdoc_nmsg(mdoc, np, MANDOCERR_NOARGS);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -1248,7 +1249,7 @@ post_an(POST_ARGS)
|
|||
static int
|
||||
post_it(POST_ARGS)
|
||||
{
|
||||
int i, cols, rc;
|
||||
int i, cols;
|
||||
enum mdoc_list lt;
|
||||
struct mdoc_node *n, *c;
|
||||
enum mandocerr er;
|
||||
|
@ -1314,10 +1315,10 @@ post_it(POST_ARGS)
|
|||
else
|
||||
er = MANDOCERR_SYNTARGCOUNT;
|
||||
|
||||
rc = mdoc_vmsg(mdoc, er,
|
||||
mdoc->last->line, mdoc->last->pos,
|
||||
mandoc_vmsg(er, mdoc->parse, mdoc->last->line,
|
||||
mdoc->last->pos,
|
||||
"columns == %d (have %d)", cols, i);
|
||||
return(rc);
|
||||
return(MANDOCERR_ARGCOUNT == er);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1378,7 +1379,7 @@ post_bl_block_width(POST_ARGS)
|
|||
width = 6;
|
||||
else if (MDOC_MAX == (tok = mdoc_hash_find(n->norm->Bl.width)))
|
||||
return(1);
|
||||
else if (0 == (width = mdoc_macro2len(tok))) {
|
||||
else if (0 == (width = macro2len(tok))) {
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_BADWIDTH);
|
||||
return(1);
|
||||
}
|
||||
|
@ -1393,7 +1394,7 @@ post_bl_block_width(POST_ARGS)
|
|||
|
||||
assert(i < (int)n->args->argc);
|
||||
|
||||
snprintf(buf, NUMSIZ, "%zun", width);
|
||||
snprintf(buf, NUMSIZ, "%un", (unsigned int)width);
|
||||
free(n->args->argv[i].value[0]);
|
||||
n->args->argv[i].value[0] = mandoc_strdup(buf);
|
||||
|
||||
|
@ -1435,7 +1436,7 @@ post_bl_block_tag(POST_ARGS)
|
|||
break;
|
||||
}
|
||||
|
||||
if (0 != (ssz = mdoc_macro2len(nn->tok)))
|
||||
if (0 != (ssz = macro2len(nn->tok)))
|
||||
sz = ssz;
|
||||
|
||||
break;
|
||||
|
@ -1443,7 +1444,7 @@ post_bl_block_tag(POST_ARGS)
|
|||
|
||||
/* Defaults to ten ens. */
|
||||
|
||||
snprintf(buf, NUMSIZ, "%zun", sz);
|
||||
snprintf(buf, NUMSIZ, "%un", (unsigned int)sz);
|
||||
|
||||
/*
|
||||
* We have to dynamically add this to the macro's argument list.
|
||||
|
@ -1509,7 +1510,7 @@ post_bl_head(POST_ARGS)
|
|||
assert(0 == np->args->argv[j].sz);
|
||||
|
||||
/*
|
||||
* Accomodate for new-style groff column syntax. Shuffle the
|
||||
* Accommodate for new-style groff column syntax. Shuffle the
|
||||
* child nodes, all of which must be TEXT, as arguments for the
|
||||
* column field. Then, delete the head children.
|
||||
*/
|
||||
|
@ -1519,7 +1520,7 @@ post_bl_head(POST_ARGS)
|
|||
((size_t)mdoc->last->nchild * sizeof(char *));
|
||||
|
||||
mdoc->last->norm->Bl.ncols = np->args->argv[j].sz;
|
||||
mdoc->last->norm->Bl.cols = (const char **)np->args->argv[j].value;
|
||||
mdoc->last->norm->Bl.cols = (void *)np->args->argv[j].value;
|
||||
|
||||
for (i = 0, nn = mdoc->last->child; nn; i++) {
|
||||
np->args->argv[j].value[i] = nn->string;
|
||||
|
@ -1681,8 +1682,8 @@ post_rs(POST_ARGS)
|
|||
break;
|
||||
|
||||
if (i < RSORD_MAX) {
|
||||
if (MDOC__J == rsord[i])
|
||||
mdoc->last->norm->Rs.child_J = nn;
|
||||
if (MDOC__J == rsord[i] || MDOC__B == rsord[i])
|
||||
mdoc->last->norm->Rs.quote_T++;
|
||||
next = nn->next;
|
||||
continue;
|
||||
}
|
||||
|
@ -1692,6 +1693,14 @@ post_rs(POST_ARGS)
|
|||
mdoc_node_delete(mdoc, nn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing to sort if only invalid nodes were found
|
||||
* inside the `Rs' body.
|
||||
*/
|
||||
|
||||
if (NULL == mdoc->last->child)
|
||||
return(1);
|
||||
|
||||
/*
|
||||
* The full `Rs' block needs special handling to order the
|
||||
* sub-elements according to `rsord'. Pick through each element
|
||||
|
@ -1757,6 +1766,15 @@ post_rs(POST_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_ns(POST_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_LINE & mdoc->last->flags)
|
||||
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNNS);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_sh(POST_ARGS)
|
||||
{
|
||||
|
@ -1808,7 +1826,9 @@ static int
|
|||
post_sh_head(POST_ARGS)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
struct mdoc_node *n;
|
||||
enum mdoc_sec sec;
|
||||
int c;
|
||||
|
||||
/*
|
||||
* Process a new section. Sections are either "named" or
|
||||
|
@ -1817,10 +1837,13 @@ post_sh_head(POST_ARGS)
|
|||
* manual sections.
|
||||
*/
|
||||
|
||||
if ( ! concat(mdoc, buf, mdoc->last->child, BUFSIZ))
|
||||
sec = SEC_CUSTOM;
|
||||
buf[0] = '\0';
|
||||
if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) {
|
||||
mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);
|
||||
return(0);
|
||||
|
||||
sec = mdoc_str2sec(buf);
|
||||
} else if (1 == c)
|
||||
sec = a2sec(buf);
|
||||
|
||||
/* The NAME should be first. */
|
||||
|
||||
|
@ -1838,6 +1861,20 @@ post_sh_head(POST_ARGS)
|
|||
|
||||
mdoc->lastsec = sec;
|
||||
|
||||
/*
|
||||
* Set the section attribute for the current HEAD, for its
|
||||
* parent BLOCK, and for the HEAD children; the latter can
|
||||
* only be TEXT nodes, so no recursion is needed.
|
||||
* For other blocks and elements, including .Sh BODY, this is
|
||||
* done when allocating the node data structures, but for .Sh
|
||||
* BLOCK and HEAD, the section is still unknown at that time.
|
||||
*/
|
||||
|
||||
mdoc->last->parent->sec = sec;
|
||||
mdoc->last->sec = sec;
|
||||
for (n = mdoc->last->child; n; n = n->next)
|
||||
n->sec = sec;
|
||||
|
||||
/* We don't care about custom sections after this. */
|
||||
|
||||
if (SEC_CUSTOM == sec)
|
||||
|
@ -1969,25 +2006,28 @@ post_dd(POST_ARGS)
|
|||
{
|
||||
char buf[DATESIZE];
|
||||
struct mdoc_node *n;
|
||||
int c;
|
||||
|
||||
if (mdoc->meta.date)
|
||||
free(mdoc->meta.date);
|
||||
|
||||
n = mdoc->last;
|
||||
|
||||
if (NULL == n->child) {
|
||||
mdoc->meta.date = time(NULL);
|
||||
if (NULL == n->child || '\0' == n->child->string[0]) {
|
||||
mdoc->meta.date = mandoc_normdate
|
||||
(mdoc->parse, NULL, n->line, n->pos);
|
||||
return(1);
|
||||
}
|
||||
|
||||
if ( ! concat(mdoc, buf, n->child, DATESIZE))
|
||||
buf[0] = '\0';
|
||||
if (-1 == (c = concat(buf, n->child, DATESIZE))) {
|
||||
mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);
|
||||
return(0);
|
||||
|
||||
mdoc->meta.date = mandoc_a2time
|
||||
(MTIME_MDOCDATE | MTIME_CANONICAL, buf);
|
||||
|
||||
if (0 == mdoc->meta.date) {
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_BADDATE);
|
||||
mdoc->meta.date = time(NULL);
|
||||
}
|
||||
|
||||
assert(c);
|
||||
mdoc->meta.date = mandoc_normdate
|
||||
(mdoc->parse, buf, n->line, n->pos);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -2013,7 +2053,7 @@ post_dt(POST_ARGS)
|
|||
|
||||
if (NULL != (nn = n->child))
|
||||
for (p = nn->string; *p; p++) {
|
||||
if (toupper((u_char)*p) == *p)
|
||||
if (toupper((unsigned char)*p) == *p)
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@ -2059,7 +2099,7 @@ post_dt(POST_ARGS)
|
|||
* arch = NULL
|
||||
*/
|
||||
|
||||
cp = mdoc_a2msec(nn->string);
|
||||
cp = mandoc_a2msec(nn->string);
|
||||
if (cp) {
|
||||
mdoc->meta.vol = mandoc_strdup(cp);
|
||||
mdoc->meta.msec = mandoc_strdup(nn->string);
|
||||
|
@ -2115,11 +2155,31 @@ post_prol(POST_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_bx(POST_ARGS)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
/*
|
||||
* Make `Bx's second argument always start with an uppercase
|
||||
* letter. Groff checks if it's an "accepted" term, but we just
|
||||
* uppercase blindly.
|
||||
*/
|
||||
|
||||
n = mdoc->last->child;
|
||||
if (n && NULL != (n = n->next))
|
||||
*n->string = (char)toupper
|
||||
((unsigned char)*n->string);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_os(POST_ARGS)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
char buf[BUFSIZ];
|
||||
int c;
|
||||
#ifndef OSNAME
|
||||
struct utsname utsname;
|
||||
#endif
|
||||
|
@ -2136,8 +2196,13 @@ post_os(POST_ARGS)
|
|||
if (mdoc->meta.os)
|
||||
free(mdoc->meta.os);
|
||||
|
||||
if ( ! concat(mdoc, buf, n->child, BUFSIZ))
|
||||
buf[0] = '\0';
|
||||
if (-1 == (c = concat(buf, n->child, BUFSIZ))) {
|
||||
mdoc_nmsg(mdoc, n->child, MANDOCERR_MEM);
|
||||
return(0);
|
||||
}
|
||||
|
||||
assert(c);
|
||||
|
||||
/* XXX: yes, these can all be dynamically-adjusted buffers, but
|
||||
* it's really not worth the extra hackery.
|
||||
|
@ -2150,7 +2215,7 @@ post_os(POST_ARGS)
|
|||
return(0);
|
||||
}
|
||||
#else /*!OSNAME */
|
||||
if (uname(&utsname)) {
|
||||
if (-1 == uname(&utsname)) {
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_UNAME);
|
||||
mdoc->meta.os = mandoc_strdup("UNKNOWN");
|
||||
return(post_prol(mdoc));
|
||||
|
@ -2204,36 +2269,130 @@ post_std(POST_ARGS)
|
|||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenate a node, stopping at the first non-text.
|
||||
* Concatenation is separated by a single whitespace.
|
||||
* Returns -1 on fatal (string overrun) error, 0 if child nodes were
|
||||
* encountered, 1 otherwise.
|
||||
*/
|
||||
static int
|
||||
concat(struct mdoc *m, char *p, const struct mdoc_node *n, size_t sz)
|
||||
concat(char *p, const struct mdoc_node *n, size_t sz)
|
||||
{
|
||||
|
||||
p[0] = '\0';
|
||||
|
||||
/*
|
||||
* Concatenate sibling nodes together. All siblings must be of
|
||||
* type MDOC_TEXT or an assertion is raised. Concatenation is
|
||||
* separated by a single whitespace. Returns 0 on fatal (string
|
||||
* overrun) error.
|
||||
*/
|
||||
|
||||
for ( ; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
|
||||
if (strlcat(p, n->string, sz) >= sz) {
|
||||
mdoc_nmsg(m, n, MANDOCERR_MEM);
|
||||
for ( ; NULL != n; n = n->next) {
|
||||
if (MDOC_TEXT != n->type)
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (NULL == n->next)
|
||||
continue;
|
||||
|
||||
if (strlcat(p, " ", sz) >= sz) {
|
||||
mdoc_nmsg(m, n, MANDOCERR_MEM);
|
||||
return(0);
|
||||
}
|
||||
if ('\0' != p[0] && strlcat(p, " ", sz) >= sz)
|
||||
return(-1);
|
||||
if (strlcat(p, n->string, sz) >= sz)
|
||||
return(-1);
|
||||
concat(p, n->child, sz);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static enum mdoc_sec
|
||||
a2sec(const char *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)SEC__MAX; i++)
|
||||
if (secnames[i] && 0 == strcmp(p, secnames[i]))
|
||||
return((enum mdoc_sec)i);
|
||||
|
||||
return(SEC_CUSTOM);
|
||||
}
|
||||
|
||||
static size_t
|
||||
macro2len(enum mdoct macro)
|
||||
{
|
||||
|
||||
switch (macro) {
|
||||
case(MDOC_Ad):
|
||||
return(12);
|
||||
case(MDOC_Ao):
|
||||
return(12);
|
||||
case(MDOC_An):
|
||||
return(12);
|
||||
case(MDOC_Aq):
|
||||
return(12);
|
||||
case(MDOC_Ar):
|
||||
return(12);
|
||||
case(MDOC_Bo):
|
||||
return(12);
|
||||
case(MDOC_Bq):
|
||||
return(12);
|
||||
case(MDOC_Cd):
|
||||
return(12);
|
||||
case(MDOC_Cm):
|
||||
return(10);
|
||||
case(MDOC_Do):
|
||||
return(10);
|
||||
case(MDOC_Dq):
|
||||
return(12);
|
||||
case(MDOC_Dv):
|
||||
return(12);
|
||||
case(MDOC_Eo):
|
||||
return(12);
|
||||
case(MDOC_Em):
|
||||
return(10);
|
||||
case(MDOC_Er):
|
||||
return(17);
|
||||
case(MDOC_Ev):
|
||||
return(15);
|
||||
case(MDOC_Fa):
|
||||
return(12);
|
||||
case(MDOC_Fl):
|
||||
return(10);
|
||||
case(MDOC_Fo):
|
||||
return(16);
|
||||
case(MDOC_Fn):
|
||||
return(16);
|
||||
case(MDOC_Ic):
|
||||
return(10);
|
||||
case(MDOC_Li):
|
||||
return(16);
|
||||
case(MDOC_Ms):
|
||||
return(6);
|
||||
case(MDOC_Nm):
|
||||
return(10);
|
||||
case(MDOC_No):
|
||||
return(12);
|
||||
case(MDOC_Oo):
|
||||
return(10);
|
||||
case(MDOC_Op):
|
||||
return(14);
|
||||
case(MDOC_Pa):
|
||||
return(32);
|
||||
case(MDOC_Pf):
|
||||
return(12);
|
||||
case(MDOC_Po):
|
||||
return(12);
|
||||
case(MDOC_Pq):
|
||||
return(12);
|
||||
case(MDOC_Ql):
|
||||
return(16);
|
||||
case(MDOC_Qo):
|
||||
return(12);
|
||||
case(MDOC_So):
|
||||
return(12);
|
||||
case(MDOC_Sq):
|
||||
return(12);
|
||||
case(MDOC_Sy):
|
||||
return(6);
|
||||
case(MDOC_Sx):
|
||||
return(16);
|
||||
case(MDOC_Tn):
|
||||
return(10);
|
||||
case(MDOC_Va):
|
||||
return(12);
|
||||
case(MDOC_Vt):
|
||||
return(12);
|
||||
case(MDOC_Xr):
|
||||
return(10);
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return(0);
|
||||
}
|
||||
|
|
6
external/bsd/mdocml/dist/msec.c
vendored
6
external/bsd/mdocml/dist/msec.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: msec.c,v 1.8 2010/05/17 22:11:42 kristaps Exp $ */
|
||||
/* $Vendor-Id: msec.c,v 1.10 2011/12/02 01:37:14 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -22,13 +22,13 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2msec(const char *p)
|
||||
mandoc_a2msec(const char *p)
|
||||
{
|
||||
|
||||
#include "msec.in"
|
||||
|
|
18
external/bsd/mdocml/dist/msec.in
vendored
18
external/bsd/mdocml/dist/msec.in
vendored
|
@ -22,16 +22,16 @@
|
|||
* Be sure to escape strings.
|
||||
*/
|
||||
|
||||
LINE("1", "NetBSD General Commands Manual")
|
||||
LINE("2", "NetBSD System Calls Manual")
|
||||
LINE("3", "NetBSD Library Functions Manual")
|
||||
LINE("1", "General Commands Manual")
|
||||
LINE("2", "System Calls Manual")
|
||||
LINE("3", "Library Functions Manual")
|
||||
LINE("3p", "Perl Library Functions Manual")
|
||||
LINE("4", "NetBSD Kernel Interfaces Manual")
|
||||
LINE("5", "NetBSD File Formats Manual")
|
||||
LINE("6", "NetBSD Games Manual")
|
||||
LINE("7", "NetBSD Miscellaneous Information Manual")
|
||||
LINE("8", "NetBSD System Manager\'s Manual")
|
||||
LINE("9", "NetBSD Kernel Developer\'s Manual")
|
||||
LINE("4", "Kernel Interfaces Manual")
|
||||
LINE("5", "File Formats Manual")
|
||||
LINE("6", "Games Manual")
|
||||
LINE("7", "Miscellaneous Information Manual")
|
||||
LINE("8", "System Manager\'s Manual")
|
||||
LINE("9", "Kernel Developer\'s Manual")
|
||||
LINE("X11", "X11 Developer\'s Manual")
|
||||
LINE("X11R6", "X11 Developer\'s Manual")
|
||||
LINE("unass", "Unassociated")
|
||||
|
|
311
external/bsd/mdocml/dist/out.c
vendored
311
external/bsd/mdocml/dist/out.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: out.c,v 1.30 2011/01/05 15:37:23 kristaps Exp $ */
|
||||
/* $Vendor-Id: out.c,v 1.43 2011/09/20 23:05:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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
|
||||
|
@ -68,7 +69,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||
return(0);
|
||||
|
||||
while (i < BUFSIZ) {
|
||||
if ( ! isdigit((u_char)*src)) {
|
||||
if ( ! isdigit((unsigned char)*src)) {
|
||||
if ('.' != *src)
|
||||
break;
|
||||
else if (hasd)
|
||||
|
@ -131,242 +132,6 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Correctly writes the time in nroff form, which differs from standard
|
||||
* form in that a space isn't printed in lieu of the extra %e field for
|
||||
* single-digit dates.
|
||||
*/
|
||||
void
|
||||
time2a(time_t t, char *dst, size_t sz)
|
||||
{
|
||||
struct tm tm;
|
||||
char buf[5];
|
||||
char *p;
|
||||
size_t nsz;
|
||||
|
||||
assert(sz > 1);
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
p = dst;
|
||||
nsz = 0;
|
||||
|
||||
dst[0] = '\0';
|
||||
|
||||
if (0 == (nsz = strftime(p, sz, "%B ", &tm)))
|
||||
return;
|
||||
|
||||
p += (int)nsz;
|
||||
sz -= nsz;
|
||||
|
||||
if (0 == strftime(buf, sizeof(buf), "%e, ", &tm))
|
||||
return;
|
||||
|
||||
nsz = strlcat(p, buf + (' ' == buf[0] ? 1 : 0), sz);
|
||||
|
||||
if (nsz >= sz)
|
||||
return;
|
||||
|
||||
p += (int)nsz;
|
||||
sz -= nsz;
|
||||
|
||||
(void)strftime(p, sz, "%Y", &tm);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
a2roffdeco(enum roffdeco *d, const char **word, size_t *sz)
|
||||
{
|
||||
int i, j, lim;
|
||||
char term, c;
|
||||
const char *wp;
|
||||
enum roffdeco dd;
|
||||
|
||||
*d = DECO_NONE;
|
||||
lim = i = 0;
|
||||
term = '\0';
|
||||
wp = *word;
|
||||
|
||||
switch ((c = wp[i++])) {
|
||||
case ('('):
|
||||
*d = DECO_SPECIAL;
|
||||
lim = 2;
|
||||
break;
|
||||
case ('F'):
|
||||
/* FALLTHROUGH */
|
||||
case ('f'):
|
||||
*d = 'F' == c ? DECO_FFONT : DECO_FONT;
|
||||
|
||||
switch (wp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('3'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
*d = DECO_BOLD;
|
||||
return(i);
|
||||
case ('2'):
|
||||
/* FALLTHROUGH */
|
||||
case ('I'):
|
||||
*d = DECO_ITALIC;
|
||||
return(i);
|
||||
case ('P'):
|
||||
*d = DECO_PREVIOUS;
|
||||
return(i);
|
||||
case ('1'):
|
||||
/* FALLTHROUGH */
|
||||
case ('R'):
|
||||
*d = DECO_ROMAN;
|
||||
return(i);
|
||||
default:
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ('k'):
|
||||
/* FALLTHROUGH */
|
||||
case ('M'):
|
||||
/* FALLTHROUGH */
|
||||
case ('m'):
|
||||
/* FALLTHROUGH */
|
||||
case ('*'):
|
||||
if ('*' == c)
|
||||
*d = DECO_RESERVED;
|
||||
|
||||
switch (wp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* FALLTHROUGH */
|
||||
case ('s'):
|
||||
j = 0;
|
||||
if ('+' == wp[i] || '-' == wp[i]) {
|
||||
i++;
|
||||
j = 1;
|
||||
}
|
||||
|
||||
switch (wp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('\''):
|
||||
term = '\'';
|
||||
break;
|
||||
case ('0'):
|
||||
j = 1;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ('+' == wp[i] || '-' == wp[i]) {
|
||||
if (j)
|
||||
return(i);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Handle embedded numerical subexp or escape. */
|
||||
|
||||
if ('(' == wp[i]) {
|
||||
while (wp[i] && ')' != wp[i])
|
||||
if ('\\' == wp[i++]) {
|
||||
/* Handle embedded escape. */
|
||||
*word = &wp[i];
|
||||
i += a2roffdeco(&dd, word, sz);
|
||||
}
|
||||
|
||||
if (')' == wp[i++])
|
||||
break;
|
||||
|
||||
*d = DECO_NONE;
|
||||
return(i - 1);
|
||||
} else if ('\\' == wp[i]) {
|
||||
*word = &wp[++i];
|
||||
i += a2roffdeco(&dd, word, sz);
|
||||
}
|
||||
|
||||
break;
|
||||
case ('['):
|
||||
*d = DECO_SPECIAL;
|
||||
term = ']';
|
||||
break;
|
||||
case ('c'):
|
||||
*d = DECO_NOSPACE;
|
||||
return(i);
|
||||
case ('z'):
|
||||
*d = DECO_NONE;
|
||||
if ('\\' == wp[i]) {
|
||||
*word = &wp[++i];
|
||||
return(i + a2roffdeco(&dd, word, sz));
|
||||
} else
|
||||
lim = 1;
|
||||
break;
|
||||
case ('o'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
if ('\'' == wp[i++]) {
|
||||
term = '\'';
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
*d = DECO_SSPECIAL;
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(term || lim);
|
||||
*word = &wp[i];
|
||||
|
||||
if (term) {
|
||||
j = i;
|
||||
while (wp[i] && wp[i] != term)
|
||||
i++;
|
||||
if ('\0' == wp[i]) {
|
||||
*d = DECO_NONE;
|
||||
return(i);
|
||||
}
|
||||
|
||||
assert(i >= j);
|
||||
*sz = (size_t)(i - j);
|
||||
|
||||
return(i + 1);
|
||||
}
|
||||
|
||||
assert(lim > 0);
|
||||
*sz = (size_t)lim;
|
||||
|
||||
for (j = 0; wp[i] && j < lim; j++)
|
||||
i++;
|
||||
if (j < lim)
|
||||
*d = DECO_NONE;
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the abstract widths and decimal positions of columns in a
|
||||
* table. This routine allocates the columns structures then runs over
|
||||
|
@ -379,6 +144,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
|||
const struct tbl_dat *dp;
|
||||
const struct tbl_head *hp;
|
||||
struct roffcol *col;
|
||||
int spans;
|
||||
|
||||
/*
|
||||
* Allocate the master column specifiers. These will hold the
|
||||
|
@ -387,20 +153,27 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
|||
*/
|
||||
|
||||
assert(NULL == tbl->cols);
|
||||
tbl->cols = calloc(sp->tbl->cols, sizeof(struct roffcol));
|
||||
tbl->cols = mandoc_calloc
|
||||
((size_t)sp->tbl->cols, sizeof(struct roffcol));
|
||||
|
||||
hp = sp->head;
|
||||
|
||||
for ( ; sp; sp = sp->next) {
|
||||
if (TBL_SPAN_DATA != sp->pos)
|
||||
continue;
|
||||
spans = 1;
|
||||
/*
|
||||
* Account for the data cells in the layout, matching it
|
||||
* to data cells in the data section.
|
||||
*/
|
||||
for (dp = sp->first; dp; dp = dp->next) {
|
||||
if (NULL == dp->layout)
|
||||
/* Do not used spanned cells in the calculation. */
|
||||
if (0 < --spans)
|
||||
continue;
|
||||
spans = dp->spans;
|
||||
if (1 < spans)
|
||||
continue;
|
||||
assert(dp->layout);
|
||||
col = &tbl->cols[dp->layout->head->ident];
|
||||
tblcalc_data(tbl, col, sp->tbl, dp);
|
||||
}
|
||||
|
@ -454,6 +227,8 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
|||
case (TBL_CELL_NUMBER):
|
||||
tblcalc_number(tbl, col, tp, dp);
|
||||
break;
|
||||
case (TBL_CELL_DOWN):
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
|
@ -464,36 +239,12 @@ static void
|
|||
tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl_dat *dp)
|
||||
{
|
||||
size_t sz, bufsz, spsz;
|
||||
size_t sz;
|
||||
const char *str;
|
||||
|
||||
/*
|
||||
* Calculate our width and use the spacing, with a minimum
|
||||
* spacing dictated by position (centre, e.g,. gets a space on
|
||||
* either side, while right/left get a single adjacent space).
|
||||
*/
|
||||
str = dp->string ? dp->string : "";
|
||||
sz = (*tbl->slen)(str, tbl->arg);
|
||||
|
||||
sz = bufsz = spsz = 0;
|
||||
if (dp->string)
|
||||
sz = (*tbl->slen)(dp->string, tbl->arg);
|
||||
|
||||
assert(dp->layout);
|
||||
switch (dp->layout->pos) {
|
||||
case (TBL_CELL_LONG):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_CENTRE):
|
||||
bufsz = (*tbl->len)(2, tbl->arg);
|
||||
break;
|
||||
default:
|
||||
bufsz = (*tbl->len)(1, tbl->arg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dp->layout->spacing) {
|
||||
spsz = (*tbl->len)(dp->layout->spacing, tbl->arg);
|
||||
bufsz = bufsz > spsz ? bufsz : spsz;
|
||||
}
|
||||
|
||||
sz += bufsz;
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
}
|
||||
|
@ -504,33 +255,30 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
|||
{
|
||||
int i;
|
||||
size_t sz, psz, ssz, d;
|
||||
char *cp;
|
||||
const char *str;
|
||||
char *cp;
|
||||
char buf[2];
|
||||
|
||||
/* TODO: use spacing modifier. */
|
||||
|
||||
/*
|
||||
* First calculate number width and decimal place (last + 1 for
|
||||
* no-decimal numbers). If the stored decimal is subsequent
|
||||
* non-decimal numbers). If the stored decimal is subsequent to
|
||||
* ours, make our size longer by that difference
|
||||
* (right-"shifting"); similarly, if ours is subsequent the
|
||||
* stored, then extend the stored size by the difference.
|
||||
* Finally, re-assign the stored values.
|
||||
*/
|
||||
|
||||
str = "";
|
||||
if (dp->string)
|
||||
str = dp->string;
|
||||
|
||||
str = dp->string ? dp->string : "";
|
||||
sz = (*tbl->slen)(str, tbl->arg);
|
||||
|
||||
/* FIXME: TBL_DATA_HORIZ et al.? */
|
||||
|
||||
buf[0] = tp->decimal;
|
||||
buf[1] = '\0';
|
||||
|
||||
psz = (*tbl->slen)(buf, tbl->arg);
|
||||
|
||||
if (NULL != (cp = strchr(str, tp->decimal))) {
|
||||
if (NULL != (cp = strrchr(str, tp->decimal))) {
|
||||
buf[1] = '\0';
|
||||
for (ssz = 0, i = 0; cp != &str[i]; i++) {
|
||||
buf[0] = str[i];
|
||||
|
@ -540,11 +288,6 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
|||
} else
|
||||
d = sz + psz;
|
||||
|
||||
/* Padding. */
|
||||
|
||||
sz += (*tbl->len)(2, tbl->arg);
|
||||
d += (*tbl->len)(1, tbl->arg);
|
||||
|
||||
/* Adjust the settings for this column. */
|
||||
|
||||
if (col->decimal > d) {
|
||||
|
@ -558,5 +301,3 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
|||
if (d > col->decimal)
|
||||
col->decimal = d;
|
||||
}
|
||||
|
||||
|
||||
|
|
61
external/bsd/mdocml/dist/out.h
vendored
61
external/bsd/mdocml/dist/out.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: out.h,v 1.15 2011/01/05 15:37:23 kristaps Exp $ */
|
||||
/* $Vendor-Id: out.h,v 1.21 2011/07/17 15:24:25 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -17,15 +17,30 @@
|
|||
#ifndef OUT_H
|
||||
#define OUT_H
|
||||
|
||||
#define DATESIZ 24
|
||||
|
||||
__BEGIN_DECLS
|
||||
enum roffscale {
|
||||
SCALE_CM, /* centimeters (c) */
|
||||
SCALE_IN, /* inches (i) */
|
||||
SCALE_PC, /* pica (P) */
|
||||
SCALE_PT, /* points (p) */
|
||||
SCALE_EM, /* ems (m) */
|
||||
SCALE_MM, /* mini-ems (M) */
|
||||
SCALE_EN, /* ens (n) */
|
||||
SCALE_BU, /* default horizontal (u) */
|
||||
SCALE_VS, /* default vertical (v) */
|
||||
SCALE_FS, /* syn. for u (f) */
|
||||
SCALE_MAX
|
||||
};
|
||||
|
||||
struct roffcol {
|
||||
size_t width; /* width of cell */
|
||||
size_t decimal; /* decimal position in cell */
|
||||
};
|
||||
|
||||
struct roffsu {
|
||||
enum roffscale unit;
|
||||
double scale;
|
||||
};
|
||||
|
||||
typedef size_t (*tbl_strlen)(const char *, void *);
|
||||
typedef size_t (*tbl_len)(size_t, void *);
|
||||
|
||||
|
@ -36,39 +51,7 @@ struct rofftbl {
|
|||
void *arg; /* passed to slen and len */
|
||||
};
|
||||
|
||||
enum roffscale {
|
||||
SCALE_CM,
|
||||
SCALE_IN,
|
||||
SCALE_PC,
|
||||
SCALE_PT,
|
||||
SCALE_EM,
|
||||
SCALE_MM,
|
||||
SCALE_EN,
|
||||
SCALE_BU,
|
||||
SCALE_VS,
|
||||
SCALE_FS,
|
||||
SCALE_MAX
|
||||
};
|
||||
|
||||
enum roffdeco {
|
||||
DECO_NONE,
|
||||
DECO_SPECIAL, /* special character */
|
||||
DECO_SSPECIAL, /* single-char special */
|
||||
DECO_RESERVED, /* reserved word */
|
||||
DECO_BOLD, /* bold font */
|
||||
DECO_ITALIC, /* italic font */
|
||||
DECO_ROMAN, /* "normal" undecorated font */
|
||||
DECO_PREVIOUS, /* revert to previous font */
|
||||
DECO_NOSPACE, /* suppress spacing */
|
||||
DECO_FONT, /* font */
|
||||
DECO_FFONT, /* font family */
|
||||
DECO_MAX
|
||||
};
|
||||
|
||||
struct roffsu {
|
||||
enum roffscale unit;
|
||||
double scale;
|
||||
};
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define SCALE_VS_INIT(p, v) \
|
||||
do { (p)->unit = SCALE_VS; \
|
||||
|
@ -81,8 +64,6 @@ struct roffsu {
|
|||
while (/* CONSTCOND */ 0)
|
||||
|
||||
int a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
int a2roffdeco(enum roffdeco *, const char **, size_t *);
|
||||
void time2a(time_t, char *, size_t);
|
||||
void tblcalc(struct rofftbl *tbl, const struct tbl_span *);
|
||||
|
||||
__END_DECLS
|
||||
|
|
158
external/bsd/mdocml/dist/preconv.1
vendored
Normal file
158
external/bsd/mdocml/dist/preconv.1
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
.\" $Vendor-Id: preconv.1,v 1.6 2011/12/25 19:35:44 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd December 25, 2011
|
||||
.Dt PRECONV 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm preconv
|
||||
.Nd recode multibyte UNIX manuals
|
||||
.Sh SYNOPSIS
|
||||
.Nm preconv
|
||||
.Op Fl D Ar enc
|
||||
.Op Fl e Ar enc
|
||||
.Op Ar file
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility recodes multibyte
|
||||
.Ux
|
||||
manual files into
|
||||
.Xr mandoc 1
|
||||
.Po
|
||||
or other troff system supporting the
|
||||
.Sq \e[uNNNN]
|
||||
escape sequence
|
||||
.Pc
|
||||
input.
|
||||
.Pp
|
||||
By default, it parses from standard output, determining encoding as
|
||||
described in
|
||||
.Sx Algorithm .
|
||||
.Pp
|
||||
Its arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl D Ar enc
|
||||
The default encoding.
|
||||
.It Fl e Ar enc
|
||||
The document's encoding.
|
||||
.It Ar file
|
||||
The input file.
|
||||
.El
|
||||
.Pp
|
||||
The recoded input is written to standard output: Unicode characters in
|
||||
the ASCII range are printed as regular ASCII characters, while those
|
||||
above this range are printed using the
|
||||
.Sq \e[uNNNN]
|
||||
format documented in
|
||||
.Xr mandoc_char 7 .
|
||||
.Pp
|
||||
If input bytes are improperly formed in the current encoding, they're
|
||||
passed unmodified to standard output.
|
||||
For some encodings, such as UTF-8, unrecoverable input sequences will
|
||||
cause
|
||||
.Nm
|
||||
to stop processing and exit.
|
||||
.Ss Algorithm
|
||||
An encoding is chosen according to the following steps:
|
||||
.Bl -enum
|
||||
.It
|
||||
From the argument passed to
|
||||
.Fl e Ar enc .
|
||||
.It
|
||||
If a BOM exists, UTF\-8 encoding is selected.
|
||||
.It
|
||||
From the coding tags parsed from
|
||||
.Qq File Variables
|
||||
on the first two lines of input.
|
||||
A file variable is an input line of the form
|
||||
.Pp
|
||||
.Dl \%.\e\(dq -*- key: val [; key: val ]* -*-
|
||||
.Pp
|
||||
A coding tag variable is where
|
||||
.Cm key
|
||||
is
|
||||
.Qq coding
|
||||
and
|
||||
.Cm val
|
||||
is the name of the encoding.
|
||||
A typical file variable with a coding tag is
|
||||
.Pp
|
||||
.Dl \%.\e\(dq -*- mode: troff; coding: utf-8 -*-
|
||||
.It
|
||||
From the argument passed to
|
||||
.Fl D Ar enc .
|
||||
.It
|
||||
If all else fails, Latin\-1 is used.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility recognises the UTF\-8, us\-ascii, and latin\-1 encodings as
|
||||
passed to the
|
||||
.Fl e
|
||||
and
|
||||
.Fl D
|
||||
arguments, or as coding tags.
|
||||
Encodings are matched case-insensitively.
|
||||
.\" .Sh IMPLEMENTATION NOTES
|
||||
.\" Not used in OpenBSD.
|
||||
.\" .Sh RETURN VALUES
|
||||
.\" For sections 2, 3, & 9 only.
|
||||
.\" .Sh ENVIRONMENT
|
||||
.\" For sections 1, 6, 7, & 8 only.
|
||||
.\" .Sh FILES
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh EXAMPLES
|
||||
Explicitly page a UTF\-8 manual
|
||||
.Pa foo.1
|
||||
in the current locale:
|
||||
.Pp
|
||||
.Dl $ preconv \-e utf\-8 foo.1 | mandoc -Tlocale | less
|
||||
.\" .Sh DIAGNOSTICS
|
||||
.\" For sections 1, 4, 6, 7, & 8 only.
|
||||
.\" .Sh ERRORS
|
||||
.\" For sections 2, 3, & 9 only.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr mandoc_char 7
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility references the US-ASCII character set standard, ANSI_X3.4\-1968;
|
||||
the Latin\-1 character set standard, ISO/IEC 8859\-1:1998; the UTF\-8
|
||||
character set standard; and UCS (Unicode), ISO/IEC 10646.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in the GNU troff
|
||||
.Pq Dq groff
|
||||
system in December 2005, authored by Tomohiro Kubota and Werner
|
||||
Lemberg.
|
||||
The implementation that is part of the
|
||||
.Xr mandoc 1
|
||||
utility appeared in May 2011.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.\" .Sh CAVEATS
|
||||
.\" .Sh BUGS
|
||||
.\" .Sh SECURITY CONSIDERATIONS
|
||||
.\" Not used in OpenBSD.
|
528
external/bsd/mdocml/dist/preconv.c
vendored
Normal file
528
external/bsd/mdocml/dist/preconv.c
vendored
Normal file
|
@ -0,0 +1,528 @@
|
|||
/* $Vendor-Id: preconv.c,v 1.5 2011/07/24 18:15:14 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* The read_whole_file() and resize_buf() functions are copied from
|
||||
* read.c, including all dependency code (MAP_FILE, etc.).
|
||||
*/
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
|
||||
enum enc {
|
||||
ENC_UTF_8, /* UTF-8 */
|
||||
ENC_US_ASCII, /* US-ASCII */
|
||||
ENC_LATIN_1, /* Latin-1 */
|
||||
ENC__MAX
|
||||
};
|
||||
|
||||
struct buf {
|
||||
char *buf; /* binary input buffer */
|
||||
size_t sz; /* size of binary buffer */
|
||||
size_t offs; /* starting buffer offset */
|
||||
};
|
||||
|
||||
struct encode {
|
||||
const char *name;
|
||||
int (*conv)(const struct buf *);
|
||||
};
|
||||
|
||||
static int cue_enc(const struct buf *, size_t *, enum enc *);
|
||||
static int conv_latin_1(const struct buf *);
|
||||
static int conv_us_ascii(const struct buf *);
|
||||
static int conv_utf_8(const struct buf *);
|
||||
static int read_whole_file(const char *, int,
|
||||
struct buf *, int *);
|
||||
static void resize_buf(struct buf *, size_t);
|
||||
static void usage(void);
|
||||
|
||||
static const struct encode encs[ENC__MAX] = {
|
||||
{ "utf-8", conv_utf_8 }, /* ENC_UTF_8 */
|
||||
{ "us-ascii", conv_us_ascii }, /* ENC_US_ASCII */
|
||||
{ "latin-1", conv_latin_1 }, /* ENC_LATIN_1 */
|
||||
};
|
||||
|
||||
static const char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s "
|
||||
"[-D enc] "
|
||||
"[-e ENC] "
|
||||
"[file]\n", progname);
|
||||
}
|
||||
|
||||
static int
|
||||
conv_latin_1(const struct buf *b)
|
||||
{
|
||||
size_t i;
|
||||
unsigned char cu;
|
||||
const char *cp;
|
||||
|
||||
cp = b->buf + (int)b->offs;
|
||||
|
||||
/*
|
||||
* Latin-1 falls into the first 256 code-points of Unicode, so
|
||||
* there's no need for any sort of translation. Just make the
|
||||
* 8-bit characters use the Unicode escape.
|
||||
* Note that binary values 128 < v < 160 are passed through
|
||||
* unmodified to mandoc.
|
||||
*/
|
||||
|
||||
for (i = b->offs; i < b->sz; i++) {
|
||||
cu = (unsigned char)*cp++;
|
||||
cu < 160U ? putchar(cu) : printf("\\[u%.4X]", cu);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
conv_us_ascii(const struct buf *b)
|
||||
{
|
||||
|
||||
/*
|
||||
* US-ASCII has no conversion since it falls into the first 128
|
||||
* bytes of Unicode.
|
||||
*/
|
||||
|
||||
fwrite(b->buf, 1, b->sz, stdout);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
conv_utf_8(const struct buf *b)
|
||||
{
|
||||
int state, be;
|
||||
unsigned int accum;
|
||||
size_t i;
|
||||
unsigned char cu;
|
||||
const char *cp;
|
||||
const long one = 1L;
|
||||
|
||||
cp = b->buf + (int)b->offs;
|
||||
state = 0;
|
||||
accum = 0U;
|
||||
be = 0;
|
||||
|
||||
/* Quick test for big-endian value. */
|
||||
|
||||
if ( ! (*((const char *)(&one))))
|
||||
be = 1;
|
||||
|
||||
for (i = b->offs; i < b->sz; i++) {
|
||||
cu = (unsigned char)*cp++;
|
||||
if (state) {
|
||||
if ( ! (cu & 128) || (cu & 64)) {
|
||||
/* Bad sequence header. */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Accept only legitimate bit patterns. */
|
||||
|
||||
if (cu > 191 || cu < 128) {
|
||||
/* Bad in-sequence bits. */
|
||||
return(0);
|
||||
}
|
||||
|
||||
accum |= (cu & 63) << --state * 6;
|
||||
|
||||
/*
|
||||
* Accum is held in little-endian order as
|
||||
* stipulated by the UTF-8 sequence coding. We
|
||||
* need to convert to a native big-endian if our
|
||||
* architecture requires it.
|
||||
*/
|
||||
|
||||
if (0 == state && be)
|
||||
accum = (accum >> 24) |
|
||||
((accum << 8) & 0x00FF0000) |
|
||||
((accum >> 8) & 0x0000FF00) |
|
||||
(accum << 24);
|
||||
|
||||
if (0 == state) {
|
||||
accum < 128U ? putchar(accum) :
|
||||
printf("\\[u%.4X]", accum);
|
||||
accum = 0U;
|
||||
}
|
||||
} else if (cu & (1 << 7)) {
|
||||
/*
|
||||
* Entering a UTF-8 state: if we encounter a
|
||||
* UTF-8 bitmask, calculate the expected UTF-8
|
||||
* state from it.
|
||||
*/
|
||||
for (state = 0; state < 7; state++)
|
||||
if ( ! (cu & (1 << (7 - state))))
|
||||
break;
|
||||
|
||||
/* Accept only legitimate bit patterns. */
|
||||
|
||||
switch (state) {
|
||||
case (4):
|
||||
if (cu <= 244 && cu >= 240) {
|
||||
accum = (cu & 7) << 18;
|
||||
break;
|
||||
}
|
||||
/* Bad 4-sequence start bits. */
|
||||
return(0);
|
||||
case (3):
|
||||
if (cu <= 239 && cu >= 224) {
|
||||
accum = (cu & 15) << 12;
|
||||
break;
|
||||
}
|
||||
/* Bad 3-sequence start bits. */
|
||||
return(0);
|
||||
case (2):
|
||||
if (cu <= 223 && cu >= 194) {
|
||||
accum = (cu & 31) << 6;
|
||||
break;
|
||||
}
|
||||
/* Bad 2-sequence start bits. */
|
||||
return(0);
|
||||
default:
|
||||
/* Bad sequence bit mask. */
|
||||
return(0);
|
||||
}
|
||||
state--;
|
||||
} else
|
||||
putchar(cu);
|
||||
}
|
||||
|
||||
if (0 != state) {
|
||||
/* Bad trailing bits. */
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
resize_buf(struct buf *buf, size_t initial)
|
||||
{
|
||||
|
||||
buf->sz = buf->sz > initial / 2 ?
|
||||
2 * buf->sz : initial;
|
||||
|
||||
buf->buf = realloc(buf->buf, buf->sz);
|
||||
if (NULL == buf->buf) {
|
||||
perror(NULL);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
read_whole_file(const char *f, int fd,
|
||||
struct buf *fb, int *with_mmap)
|
||||
{
|
||||
size_t off;
|
||||
ssize_t ssz;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
struct stat st;
|
||||
if (-1 == fstat(fd, &st)) {
|
||||
perror(f);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're a regular file, try just reading in the whole entry
|
||||
* via mmap(). This is faster than reading it into blocks, and
|
||||
* since each file is only a few bytes to begin with, I'm not
|
||||
* concerned that this is going to tank any machines.
|
||||
*/
|
||||
|
||||
if (S_ISREG(st.st_mode) && st.st_size >= (1U << 31)) {
|
||||
fprintf(stderr, "%s: input too large\n", f);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
*with_mmap = 1;
|
||||
fb->sz = (size_t)st.st_size;
|
||||
fb->buf = mmap(NULL, fb->sz, PROT_READ,
|
||||
MAP_FILE|MAP_SHARED, fd, 0);
|
||||
if (fb->buf != MAP_FAILED)
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this isn't a regular file (like, say, stdin), then we must
|
||||
* go the old way and just read things in bit by bit.
|
||||
*/
|
||||
|
||||
*with_mmap = 0;
|
||||
off = 0;
|
||||
fb->sz = 0;
|
||||
fb->buf = NULL;
|
||||
for (;;) {
|
||||
if (off == fb->sz && fb->sz == (1U << 31)) {
|
||||
fprintf(stderr, "%s: input too large\n", f);
|
||||
break;
|
||||
}
|
||||
|
||||
if (off == fb->sz)
|
||||
resize_buf(fb, 65536);
|
||||
|
||||
ssz = read(fd, fb->buf + (int)off, fb->sz - off);
|
||||
if (ssz == 0) {
|
||||
fb->sz = off;
|
||||
return(1);
|
||||
}
|
||||
if (ssz == -1) {
|
||||
perror(f);
|
||||
break;
|
||||
}
|
||||
off += (size_t)ssz;
|
||||
}
|
||||
|
||||
free(fb->buf);
|
||||
fb->buf = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
cue_enc(const struct buf *b, size_t *offs, enum enc *enc)
|
||||
{
|
||||
const char *ln, *eoln, *eoph;
|
||||
size_t sz, phsz, nsz;
|
||||
int i;
|
||||
|
||||
ln = b->buf + (int)*offs;
|
||||
sz = b->sz - *offs;
|
||||
|
||||
/* Look for the end-of-line. */
|
||||
|
||||
if (NULL == (eoln = memchr(ln, '\n', sz)))
|
||||
return(-1);
|
||||
|
||||
/* Set next-line marker. */
|
||||
|
||||
*offs = (size_t)((eoln + 1) - b->buf);
|
||||
|
||||
/* Check if we have the correct header/trailer. */
|
||||
|
||||
if ((sz = (size_t)(eoln - ln)) < 10 ||
|
||||
memcmp(ln, ".\\\" -*-", 7) ||
|
||||
memcmp(eoln - 3, "-*-", 3))
|
||||
return(0);
|
||||
|
||||
/* Move after the header and adjust for the trailer. */
|
||||
|
||||
ln += 7;
|
||||
sz -= 10;
|
||||
|
||||
while (sz > 0) {
|
||||
while (sz > 0 && ' ' == *ln) {
|
||||
ln++;
|
||||
sz--;
|
||||
}
|
||||
if (0 == sz)
|
||||
break;
|
||||
|
||||
/* Find the end-of-phrase marker (or eoln). */
|
||||
|
||||
if (NULL == (eoph = memchr(ln, ';', sz)))
|
||||
eoph = eoln - 3;
|
||||
else
|
||||
eoph++;
|
||||
|
||||
/* Only account for the "coding" phrase. */
|
||||
|
||||
if ((phsz = (size_t)(eoph - ln)) < 7 ||
|
||||
strncasecmp(ln, "coding:", 7)) {
|
||||
sz -= phsz;
|
||||
ln += phsz;
|
||||
continue;
|
||||
}
|
||||
|
||||
sz -= 7;
|
||||
ln += 7;
|
||||
|
||||
while (sz > 0 && ' ' == *ln) {
|
||||
ln++;
|
||||
sz--;
|
||||
}
|
||||
if (0 == sz)
|
||||
break;
|
||||
|
||||
/* Check us against known encodings. */
|
||||
|
||||
for (i = 0; i < (int)ENC__MAX; i++) {
|
||||
nsz = strlen(encs[i].name);
|
||||
if (phsz < nsz)
|
||||
continue;
|
||||
if (strncasecmp(ln, encs[i].name, nsz))
|
||||
continue;
|
||||
|
||||
*enc = (enum enc)i;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Unknown encoding. */
|
||||
|
||||
*enc = ENC__MAX;
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i, ch, map, fd, rc;
|
||||
struct buf b;
|
||||
const char *fn;
|
||||
enum enc enc, def;
|
||||
unsigned char bom[3] = { 0xEF, 0xBB, 0xBF };
|
||||
size_t offs;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
++progname;
|
||||
|
||||
fn = "<stdin>";
|
||||
fd = STDIN_FILENO;
|
||||
rc = EXIT_FAILURE;
|
||||
enc = def = ENC__MAX;
|
||||
map = 0;
|
||||
|
||||
memset(&b, 0, sizeof(struct buf));
|
||||
|
||||
while (-1 != (ch = getopt(argc, argv, "D:e:rdvh")))
|
||||
switch (ch) {
|
||||
case ('D'):
|
||||
/* FALLTHROUGH */
|
||||
case ('e'):
|
||||
for (i = 0; i < (int)ENC__MAX; i++) {
|
||||
if (strcasecmp(optarg, encs[i].name))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (i < (int)ENC__MAX) {
|
||||
if ('D' == ch)
|
||||
def = (enum enc)i;
|
||||
else
|
||||
enc = (enum enc)i;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: Bad encoding\n", optarg);
|
||||
return(EXIT_FAILURE);
|
||||
case ('r'):
|
||||
/* FALLTHROUGH */
|
||||
case ('d'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* Compatibility with GNU preconv. */
|
||||
break;
|
||||
case ('h'):
|
||||
/* Compatibility with GNU preconv. */
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
usage();
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/*
|
||||
* Open and read the first argument on the command-line.
|
||||
* If we don't have one, we default to stdin.
|
||||
*/
|
||||
|
||||
if (argc > 0) {
|
||||
fn = *argv;
|
||||
fd = open(fn, O_RDONLY, 0);
|
||||
if (-1 == fd) {
|
||||
perror(fn);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! read_whole_file(fn, fd, &b, &map))
|
||||
goto out;
|
||||
|
||||
/* Try to read the UTF-8 BOM. */
|
||||
|
||||
if (ENC__MAX == enc)
|
||||
if (b.sz > 3 && 0 == memcmp(b.buf, bom, 3)) {
|
||||
b.offs = 3;
|
||||
enc = ENC_UTF_8;
|
||||
}
|
||||
|
||||
/* Try reading from the "-*-" cue. */
|
||||
|
||||
if (ENC__MAX == enc) {
|
||||
offs = b.offs;
|
||||
ch = cue_enc(&b, &offs, &enc);
|
||||
if (0 == ch)
|
||||
ch = cue_enc(&b, &offs, &enc);
|
||||
}
|
||||
|
||||
/*
|
||||
* No encoding has been detected.
|
||||
* Thus, we either fall into our default encoder, if specified,
|
||||
* or use Latin-1 if all else fails.
|
||||
*/
|
||||
|
||||
if (ENC__MAX == enc)
|
||||
enc = ENC__MAX == def ? ENC_LATIN_1 : def;
|
||||
|
||||
if ( ! (*encs[(int)enc].conv)(&b)) {
|
||||
fprintf(stderr, "%s: Bad encoding\n", fn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = EXIT_SUCCESS;
|
||||
out:
|
||||
#ifdef HAVE_MMAP
|
||||
if (map)
|
||||
munmap(b.buf, b.sz);
|
||||
else
|
||||
#endif
|
||||
free(b.buf);
|
||||
|
||||
if (fd > STDIN_FILENO)
|
||||
close(fd);
|
||||
|
||||
return(rc);
|
||||
}
|
65
external/bsd/mdocml/dist/predefs.in
vendored
Normal file
65
external/bsd/mdocml/dist/predefs.in
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* $Vendor-Id: predefs.in,v 1.3 2011/07/31 11:36:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The predefined-string translation tables. Each corresponds to a
|
||||
* predefined strings from (e.g.) tmac/mdoc/doc-nroff. The left-hand
|
||||
* side corresponds to the input sequence (\*x, \*(xx and so on). The
|
||||
* right-hand side is what's produced by libroff.
|
||||
*
|
||||
* XXX - C-escape strings!
|
||||
* XXX - update PREDEF_MAX in roff.c if adding more!
|
||||
*/
|
||||
|
||||
PREDEF("Am", "&")
|
||||
PREDEF("Ba", "|")
|
||||
PREDEF("Ge", "\\(>=")
|
||||
PREDEF("Gt", ">")
|
||||
PREDEF("If", "infinity")
|
||||
PREDEF("Le", "\\(<=")
|
||||
PREDEF("Lq", "\\(lq")
|
||||
PREDEF("Lt", "<")
|
||||
PREDEF("Na", "NaN")
|
||||
PREDEF("Ne", "\\(!=")
|
||||
PREDEF("Pi", "pi")
|
||||
PREDEF("Pm", "\\(+-")
|
||||
PREDEF("Rq", "\\(rq")
|
||||
PREDEF("left-bracket", "[")
|
||||
PREDEF("left-parenthesis", "(")
|
||||
PREDEF("lp", "(")
|
||||
PREDEF("left-singlequote", "\\(oq")
|
||||
PREDEF("q", "\\(dq")
|
||||
PREDEF("quote-left", "\\(oq")
|
||||
PREDEF("quote-right", "\\(cq")
|
||||
PREDEF("R", "\\(rg")
|
||||
PREDEF("right-bracket", "]")
|
||||
PREDEF("right-parenthesis", ")")
|
||||
PREDEF("rp", ")")
|
||||
PREDEF("right-singlequote", "\\(cq")
|
||||
PREDEF("Tm", "(Tm)")
|
||||
PREDEF("Px", "POSIX")
|
||||
PREDEF("Ai", "ANSI")
|
||||
PREDEF("\'", "\\\'")
|
||||
PREDEF("aa", "\\(aa")
|
||||
PREDEF("ga", "\\(ga")
|
||||
PREDEF("`", "\\`")
|
||||
PREDEF("lq", "\\(lq")
|
||||
PREDEF("rq", "\\(rq")
|
||||
PREDEF("ua", "\\(ua")
|
||||
PREDEF("va", "\\(va")
|
||||
PREDEF("<=", "\\(<=")
|
||||
PREDEF(">=", "\\(>=")
|
846
external/bsd/mdocml/dist/read.c
vendored
Normal file
846
external/bsd/mdocml/dist/read.c
vendored
Normal file
|
@ -0,0 +1,846 @@
|
|||
/* $Vendor-Id: read.c,v 1.28 2012/02/16 20:51:31 joerg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
# include <sys/stat.h>
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
|
||||
#define REPARSE_LIMIT 1000
|
||||
|
||||
struct buf {
|
||||
char *buf; /* binary input buffer */
|
||||
size_t sz; /* size of binary buffer */
|
||||
};
|
||||
|
||||
struct mparse {
|
||||
enum mandoclevel file_status; /* status of current parse */
|
||||
enum mandoclevel wlevel; /* ignore messages below this */
|
||||
int line; /* line number in the file */
|
||||
enum mparset inttype; /* which parser to use */
|
||||
struct man *pman; /* persistent man parser */
|
||||
struct mdoc *pmdoc; /* persistent mdoc parser */
|
||||
struct man *man; /* man parser */
|
||||
struct mdoc *mdoc; /* mdoc parser */
|
||||
struct roff *roff; /* roff parser (!NULL) */
|
||||
int reparse_count; /* finite interp. stack */
|
||||
mandocmsg mmsg; /* warning/error message handler */
|
||||
void *arg; /* argument to mmsg */
|
||||
const char *file;
|
||||
struct buf *secondary;
|
||||
};
|
||||
|
||||
static void resize_buf(struct buf *, size_t);
|
||||
static void mparse_buf_r(struct mparse *, struct buf, int);
|
||||
static void mparse_readfd_r(struct mparse *, int, const char *, int);
|
||||
static void pset(const char *, int, struct mparse *);
|
||||
static int read_whole_file(const char *, int, struct buf *, int *);
|
||||
static void mparse_end(struct mparse *);
|
||||
|
||||
static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = {
|
||||
MANDOCERR_OK,
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_ERROR,
|
||||
MANDOCERR_FATAL,
|
||||
MANDOCERR_MAX,
|
||||
MANDOCERR_MAX
|
||||
};
|
||||
|
||||
static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"ok",
|
||||
|
||||
"generic warning",
|
||||
|
||||
/* related to the prologue */
|
||||
"no title in document",
|
||||
"document title should be all caps",
|
||||
"unknown manual section",
|
||||
"date missing, using today's date",
|
||||
"cannot parse date, using it verbatim",
|
||||
"prologue macros out of order",
|
||||
"duplicate prologue macro",
|
||||
"macro not allowed in prologue",
|
||||
"macro not allowed in body",
|
||||
|
||||
/* related to document structure */
|
||||
".so is fragile, better use ln(1)",
|
||||
"NAME section must come first",
|
||||
"bad NAME section contents",
|
||||
"manual name not yet set",
|
||||
"sections out of conventional order",
|
||||
"duplicate section name",
|
||||
"section not in conventional manual section",
|
||||
|
||||
/* related to macros and nesting */
|
||||
"skipping obsolete macro",
|
||||
"skipping paragraph macro",
|
||||
"skipping no-space macro",
|
||||
"blocks badly nested",
|
||||
"child violates parent syntax",
|
||||
"nested displays are not portable",
|
||||
"already in literal mode",
|
||||
"line scope broken",
|
||||
|
||||
/* related to missing macro arguments */
|
||||
"skipping empty macro",
|
||||
"argument count wrong",
|
||||
"missing display type",
|
||||
"list type must come first",
|
||||
"tag lists require a width argument",
|
||||
"missing font type",
|
||||
"skipping end of block that is not open",
|
||||
|
||||
/* related to bad macro arguments */
|
||||
"skipping argument",
|
||||
"duplicate argument",
|
||||
"duplicate display type",
|
||||
"duplicate list type",
|
||||
"unknown AT&T UNIX version",
|
||||
"bad Boolean value",
|
||||
"unknown font",
|
||||
"unknown standard specifier",
|
||||
"bad width argument",
|
||||
|
||||
/* related to plain text */
|
||||
"blank line in non-literal context",
|
||||
"tab in non-literal context",
|
||||
"end of line whitespace",
|
||||
"bad comment style",
|
||||
"bad escape sequence",
|
||||
"unterminated quoted string",
|
||||
|
||||
/* related to equations */
|
||||
"unexpected literal in equation",
|
||||
|
||||
"generic error",
|
||||
|
||||
/* related to equations */
|
||||
"unexpected equation scope closure",
|
||||
"equation scope open on exit",
|
||||
"overlapping equation scopes",
|
||||
"unexpected end of equation",
|
||||
"equation syntax error",
|
||||
|
||||
/* related to tables */
|
||||
"bad table syntax",
|
||||
"bad table option",
|
||||
"bad table layout",
|
||||
"no table layout cells specified",
|
||||
"no table data cells specified",
|
||||
"ignore data in cell",
|
||||
"data block still open",
|
||||
"ignoring extra data cells",
|
||||
|
||||
"input stack limit exceeded, infinite loop?",
|
||||
"skipping bad character",
|
||||
"escaped character not allowed in a name",
|
||||
"skipping text before the first section header",
|
||||
"skipping unknown macro",
|
||||
"NOT IMPLEMENTED, please use groff: skipping request",
|
||||
"argument count wrong",
|
||||
"skipping end of block that is not open",
|
||||
"missing end of block",
|
||||
"scope open on exit",
|
||||
"uname(3) system call failed",
|
||||
"macro requires line argument(s)",
|
||||
"macro requires body argument(s)",
|
||||
"macro requires argument(s)",
|
||||
"missing list type",
|
||||
"line argument(s) will be lost",
|
||||
"body argument(s) will be lost",
|
||||
|
||||
"generic fatal error",
|
||||
|
||||
"not a manual",
|
||||
"column syntax is inconsistent",
|
||||
"NOT IMPLEMENTED: .Bd -file",
|
||||
"argument count wrong, violates syntax",
|
||||
"child violates parent syntax",
|
||||
"argument count wrong, violates syntax",
|
||||
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
|
||||
"no document body",
|
||||
"no document prologue",
|
||||
"static buffer exhausted",
|
||||
};
|
||||
|
||||
static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
||||
"SUCCESS",
|
||||
"RESERVED",
|
||||
"WARNING",
|
||||
"ERROR",
|
||||
"FATAL",
|
||||
"BADARG",
|
||||
"SYSERR"
|
||||
};
|
||||
|
||||
static void
|
||||
resize_buf(struct buf *buf, size_t initial)
|
||||
{
|
||||
|
||||
buf->sz = buf->sz > initial/2 ? 2 * buf->sz : initial;
|
||||
buf->buf = mandoc_realloc(buf->buf, buf->sz);
|
||||
}
|
||||
|
||||
static void
|
||||
pset(const char *buf, int pos, struct mparse *curp)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Try to intuit which kind of manual parser should be used. If
|
||||
* passed in by command-line (-man, -mdoc), then use that
|
||||
* explicitly. If passed as -mandoc, then try to guess from the
|
||||
* line: either skip dot-lines, use -mdoc when finding `.Dt', or
|
||||
* default to -man, which is more lenient.
|
||||
*
|
||||
* Separate out pmdoc/pman from mdoc/man: the first persists
|
||||
* through all parsers, while the latter is used per-parse.
|
||||
*/
|
||||
|
||||
if ('.' == buf[0] || '\'' == buf[0]) {
|
||||
for (i = 1; buf[i]; i++)
|
||||
if (' ' != buf[i] && '\t' != buf[i])
|
||||
break;
|
||||
if ('\0' == buf[i])
|
||||
return;
|
||||
}
|
||||
|
||||
switch (curp->inttype) {
|
||||
case (MPARSE_MDOC):
|
||||
if (NULL == curp->pmdoc)
|
||||
curp->pmdoc = mdoc_alloc(curp->roff, curp);
|
||||
assert(curp->pmdoc);
|
||||
curp->mdoc = curp->pmdoc;
|
||||
return;
|
||||
case (MPARSE_MAN):
|
||||
if (NULL == curp->pman)
|
||||
curp->pman = man_alloc(curp->roff, curp);
|
||||
assert(curp->pman);
|
||||
curp->man = curp->pman;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
|
||||
if (NULL == curp->pmdoc)
|
||||
curp->pmdoc = mdoc_alloc(curp->roff, curp);
|
||||
assert(curp->pmdoc);
|
||||
curp->mdoc = curp->pmdoc;
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL == curp->pman)
|
||||
curp->pman = man_alloc(curp->roff, curp);
|
||||
assert(curp->pman);
|
||||
curp->man = curp->pman;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main parse routine for an opened file. This is called for each
|
||||
* opened file and simply loops around the full input file, possibly
|
||||
* nesting (i.e., with `so').
|
||||
*/
|
||||
static void
|
||||
mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
||||
{
|
||||
const struct tbl_span *span;
|
||||
struct buf ln;
|
||||
enum rofferr rr;
|
||||
int i, of, rc;
|
||||
int pos; /* byte number in the ln buffer */
|
||||
int lnn; /* line number in the real file */
|
||||
unsigned char c;
|
||||
|
||||
memset(&ln, 0, sizeof(struct buf));
|
||||
|
||||
lnn = curp->line;
|
||||
pos = 0;
|
||||
|
||||
for (i = 0; i < (int)blk.sz; ) {
|
||||
if (0 == pos && '\0' == blk.buf[i])
|
||||
break;
|
||||
|
||||
if (start) {
|
||||
curp->line = lnn;
|
||||
curp->reparse_count = 0;
|
||||
}
|
||||
|
||||
while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) {
|
||||
|
||||
/*
|
||||
* When finding an unescaped newline character,
|
||||
* leave the character loop to process the line.
|
||||
* Skip a preceding carriage return, if any.
|
||||
*/
|
||||
|
||||
if ('\r' == blk.buf[i] && i + 1 < (int)blk.sz &&
|
||||
'\n' == blk.buf[i + 1])
|
||||
++i;
|
||||
if ('\n' == blk.buf[i]) {
|
||||
++i;
|
||||
++lnn;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warn about bogus characters. If you're using
|
||||
* non-ASCII encoding, you're screwing your
|
||||
* readers. Since I'd rather this not happen,
|
||||
* I'll be helpful and replace these characters
|
||||
* with "?", so we don't display gibberish.
|
||||
* Note to manual writers: use special characters.
|
||||
*/
|
||||
|
||||
c = (unsigned char) blk.buf[i];
|
||||
|
||||
if ( ! (isascii(c) &&
|
||||
(isgraph(c) || isblank(c)))) {
|
||||
mandoc_msg(MANDOCERR_BADCHAR, curp,
|
||||
curp->line, pos, NULL);
|
||||
i++;
|
||||
if (pos >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
ln.buf[pos++] = '?';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Trailing backslash = a plain char. */
|
||||
|
||||
if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) {
|
||||
if (pos >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Found escape and at least one other character.
|
||||
* When it's a newline character, skip it.
|
||||
* When there is a carriage return in between,
|
||||
* skip that one as well.
|
||||
*/
|
||||
|
||||
if ('\r' == blk.buf[i + 1] && i + 2 < (int)blk.sz &&
|
||||
'\n' == blk.buf[i + 2])
|
||||
++i;
|
||||
if ('\n' == blk.buf[i + 1]) {
|
||||
i += 2;
|
||||
++lnn;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
|
||||
i += 2;
|
||||
/* Comment, skip to end of line */
|
||||
for (; i < (int)blk.sz; ++i) {
|
||||
if ('\n' == blk.buf[i]) {
|
||||
++i;
|
||||
++lnn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Backout trailing whitespaces */
|
||||
for (; pos > 0; --pos) {
|
||||
if (ln.buf[pos - 1] != ' ')
|
||||
break;
|
||||
if (pos > 2 && ln.buf[pos - 2] == '\\')
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some other escape sequence, copy & cont. */
|
||||
|
||||
if (pos + 1 >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
}
|
||||
|
||||
if (pos >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
|
||||
ln.buf[pos] = '\0';
|
||||
|
||||
/*
|
||||
* A significant amount of complexity is contained by
|
||||
* the roff preprocessor. It's line-oriented but can be
|
||||
* expressed on one line, so we need at times to
|
||||
* readjust our starting point and re-run it. The roff
|
||||
* preprocessor can also readjust the buffers with new
|
||||
* data, so we pass them in wholesale.
|
||||
*/
|
||||
|
||||
of = 0;
|
||||
|
||||
/*
|
||||
* Maintain a lookaside buffer of all parsed lines. We
|
||||
* only do this if mparse_keep() has been invoked (the
|
||||
* buffer may be accessed with mparse_getkeep()).
|
||||
*/
|
||||
|
||||
if (curp->secondary) {
|
||||
curp->secondary->buf =
|
||||
mandoc_realloc
|
||||
(curp->secondary->buf,
|
||||
curp->secondary->sz + pos + 2);
|
||||
memcpy(curp->secondary->buf +
|
||||
curp->secondary->sz,
|
||||
ln.buf, pos);
|
||||
curp->secondary->sz += pos;
|
||||
curp->secondary->buf
|
||||
[curp->secondary->sz] = '\n';
|
||||
curp->secondary->sz++;
|
||||
curp->secondary->buf
|
||||
[curp->secondary->sz] = '\0';
|
||||
}
|
||||
rerun:
|
||||
rr = roff_parseln
|
||||
(curp->roff, curp->line,
|
||||
&ln.buf, &ln.sz, of, &of);
|
||||
|
||||
switch (rr) {
|
||||
case (ROFF_REPARSE):
|
||||
if (REPARSE_LIMIT >= ++curp->reparse_count)
|
||||
mparse_buf_r(curp, ln, 0);
|
||||
else
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP, curp,
|
||||
curp->line, pos, NULL);
|
||||
pos = 0;
|
||||
continue;
|
||||
case (ROFF_APPEND):
|
||||
pos = (int)strlen(ln.buf);
|
||||
continue;
|
||||
case (ROFF_RERUN):
|
||||
goto rerun;
|
||||
case (ROFF_IGN):
|
||||
pos = 0;
|
||||
continue;
|
||||
case (ROFF_ERR):
|
||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||
break;
|
||||
case (ROFF_SO):
|
||||
/*
|
||||
* We remove `so' clauses from our lookaside
|
||||
* buffer because we're going to descend into
|
||||
* the file recursively.
|
||||
*/
|
||||
if (curp->secondary)
|
||||
curp->secondary->sz -= pos + 1;
|
||||
mparse_readfd_r(curp, -1, ln.buf + of, 1);
|
||||
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
||||
break;
|
||||
pos = 0;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we encounter errors in the recursive parse, make
|
||||
* sure we don't continue parsing.
|
||||
*/
|
||||
|
||||
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If input parsers have not been allocated, do so now.
|
||||
* We keep these instanced between parsers, but set them
|
||||
* locally per parse routine since we can use different
|
||||
* parsers with each one.
|
||||
*/
|
||||
|
||||
if ( ! (curp->man || curp->mdoc))
|
||||
pset(ln.buf + of, pos - of, curp);
|
||||
|
||||
/*
|
||||
* Lastly, push down into the parsers themselves. One
|
||||
* of these will have already been set in the pset()
|
||||
* routine.
|
||||
* If libroff returns ROFF_TBL, then add it to the
|
||||
* currently open parse. Since we only get here if
|
||||
* there does exist data (see tbl_data.c), we're
|
||||
* guaranteed that something's been allocated.
|
||||
* Do the same for ROFF_EQN.
|
||||
*/
|
||||
|
||||
rc = -1;
|
||||
|
||||
if (ROFF_TBL == rr)
|
||||
while (NULL != (span = roff_span(curp->roff))) {
|
||||
rc = curp->man ?
|
||||
man_addspan(curp->man, span) :
|
||||
mdoc_addspan(curp->mdoc, span);
|
||||
if (0 == rc)
|
||||
break;
|
||||
}
|
||||
else if (ROFF_EQN == rr)
|
||||
rc = curp->mdoc ?
|
||||
mdoc_addeqn(curp->mdoc,
|
||||
roff_eqn(curp->roff)) :
|
||||
man_addeqn(curp->man,
|
||||
roff_eqn(curp->roff));
|
||||
else if (curp->man || curp->mdoc)
|
||||
rc = curp->man ?
|
||||
man_parseln(curp->man,
|
||||
curp->line, ln.buf, of) :
|
||||
mdoc_parseln(curp->mdoc,
|
||||
curp->line, ln.buf, of);
|
||||
|
||||
if (0 == rc) {
|
||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Temporary buffers typically are not full. */
|
||||
|
||||
if (0 == start && '\0' == blk.buf[i])
|
||||
break;
|
||||
|
||||
/* Start the next input line. */
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
free(ln.buf);
|
||||
}
|
||||
|
||||
static int
|
||||
read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
||||
{
|
||||
size_t off;
|
||||
ssize_t ssz;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
struct stat st;
|
||||
if (-1 == fstat(fd, &st)) {
|
||||
perror(file);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're a regular file, try just reading in the whole entry
|
||||
* via mmap(). This is faster than reading it into blocks, and
|
||||
* since each file is only a few bytes to begin with, I'm not
|
||||
* concerned that this is going to tank any machines.
|
||||
*/
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (st.st_size >= (1U << 31)) {
|
||||
fprintf(stderr, "%s: input too large\n", file);
|
||||
return(0);
|
||||
}
|
||||
*with_mmap = 1;
|
||||
fb->sz = (size_t)st.st_size;
|
||||
fb->buf = mmap(NULL, fb->sz, PROT_READ,
|
||||
MAP_FILE|MAP_SHARED, fd, 0);
|
||||
if (fb->buf != MAP_FAILED)
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this isn't a regular file (like, say, stdin), then we must
|
||||
* go the old way and just read things in bit by bit.
|
||||
*/
|
||||
|
||||
*with_mmap = 0;
|
||||
off = 0;
|
||||
fb->sz = 0;
|
||||
fb->buf = NULL;
|
||||
for (;;) {
|
||||
if (off == fb->sz) {
|
||||
if (fb->sz == (1U << 31)) {
|
||||
fprintf(stderr, "%s: input too large\n", file);
|
||||
break;
|
||||
}
|
||||
resize_buf(fb, 65536);
|
||||
}
|
||||
ssz = read(fd, fb->buf + (int)off, fb->sz - off);
|
||||
if (ssz == 0) {
|
||||
fb->sz = off;
|
||||
return(1);
|
||||
}
|
||||
if (ssz == -1) {
|
||||
perror(file);
|
||||
break;
|
||||
}
|
||||
off += (size_t)ssz;
|
||||
}
|
||||
|
||||
free(fb->buf);
|
||||
fb->buf = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
mparse_end(struct mparse *curp)
|
||||
{
|
||||
|
||||
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
||||
return;
|
||||
|
||||
if (curp->mdoc && ! mdoc_endparse(curp->mdoc)) {
|
||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (curp->man && ! man_endparse(curp->man)) {
|
||||
assert(MANDOCLEVEL_FATAL <= curp->file_status);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! (curp->man || curp->mdoc)) {
|
||||
mandoc_msg(MANDOCERR_NOTMANUAL, curp, 1, 0, NULL);
|
||||
curp->file_status = MANDOCLEVEL_FATAL;
|
||||
return;
|
||||
}
|
||||
|
||||
roff_endparse(curp->roff);
|
||||
}
|
||||
|
||||
static void
|
||||
mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file,
|
||||
int re)
|
||||
{
|
||||
const char *svfile;
|
||||
|
||||
/* Line number is per-file. */
|
||||
svfile = curp->file;
|
||||
curp->file = file;
|
||||
curp->line = 1;
|
||||
|
||||
mparse_buf_r(curp, blk, 1);
|
||||
|
||||
if (0 == re && MANDOCLEVEL_FATAL > curp->file_status)
|
||||
mparse_end(curp);
|
||||
|
||||
curp->file = svfile;
|
||||
}
|
||||
|
||||
enum mandoclevel
|
||||
mparse_readmem(struct mparse *curp, const void *buf, size_t len,
|
||||
const char *file)
|
||||
{
|
||||
struct buf blk;
|
||||
|
||||
blk.buf = UNCONST(buf);
|
||||
blk.sz = len;
|
||||
|
||||
mparse_parse_buffer(curp, blk, file, 0);
|
||||
return(curp->file_status);
|
||||
}
|
||||
|
||||
static void
|
||||
mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re)
|
||||
{
|
||||
struct buf blk;
|
||||
int with_mmap;
|
||||
|
||||
if (-1 == fd)
|
||||
if (-1 == (fd = open(file, O_RDONLY, 0))) {
|
||||
perror(file);
|
||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Run for each opened file; may be called more than once for
|
||||
* each full parse sequence if the opened file is nested (i.e.,
|
||||
* from `so'). Simply sucks in the whole file and moves into
|
||||
* the parse phase for the file.
|
||||
*/
|
||||
|
||||
if ( ! read_whole_file(file, fd, &blk, &with_mmap)) {
|
||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||
return;
|
||||
}
|
||||
|
||||
mparse_parse_buffer(curp, blk, file, re);
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
if (with_mmap)
|
||||
munmap(blk.buf, blk.sz);
|
||||
else
|
||||
#endif
|
||||
free(blk.buf);
|
||||
|
||||
if (STDIN_FILENO != fd && -1 == close(fd))
|
||||
perror(file);
|
||||
}
|
||||
|
||||
enum mandoclevel
|
||||
mparse_readfd(struct mparse *curp, int fd, const char *file)
|
||||
{
|
||||
|
||||
mparse_readfd_r(curp, fd, file, 0);
|
||||
return(curp->file_status);
|
||||
}
|
||||
|
||||
struct mparse *
|
||||
mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, mandocmsg mmsg, void *arg)
|
||||
{
|
||||
struct mparse *curp;
|
||||
|
||||
assert(wlevel <= MANDOCLEVEL_FATAL);
|
||||
|
||||
curp = mandoc_calloc(1, sizeof(struct mparse));
|
||||
|
||||
curp->wlevel = wlevel;
|
||||
curp->mmsg = mmsg;
|
||||
curp->arg = arg;
|
||||
curp->inttype = inttype;
|
||||
|
||||
curp->roff = roff_alloc(curp);
|
||||
return(curp);
|
||||
}
|
||||
|
||||
void
|
||||
mparse_reset(struct mparse *curp)
|
||||
{
|
||||
|
||||
roff_reset(curp->roff);
|
||||
|
||||
if (curp->mdoc)
|
||||
mdoc_reset(curp->mdoc);
|
||||
if (curp->man)
|
||||
man_reset(curp->man);
|
||||
if (curp->secondary)
|
||||
curp->secondary->sz = 0;
|
||||
|
||||
curp->file_status = MANDOCLEVEL_OK;
|
||||
curp->mdoc = NULL;
|
||||
curp->man = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mparse_free(struct mparse *curp)
|
||||
{
|
||||
|
||||
if (curp->pmdoc)
|
||||
mdoc_free(curp->pmdoc);
|
||||
if (curp->pman)
|
||||
man_free(curp->pman);
|
||||
if (curp->roff)
|
||||
roff_free(curp->roff);
|
||||
if (curp->secondary)
|
||||
free(curp->secondary->buf);
|
||||
|
||||
free(curp->secondary);
|
||||
free(curp);
|
||||
}
|
||||
|
||||
void
|
||||
mparse_result(struct mparse *curp, struct mdoc **mdoc, struct man **man)
|
||||
{
|
||||
|
||||
if (mdoc)
|
||||
*mdoc = curp->mdoc;
|
||||
if (man)
|
||||
*man = curp->man;
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_vmsg(enum mandocerr t, struct mparse *m,
|
||||
int ln, int pos, const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
mandoc_msg(t, m, ln, pos, buf);
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_msg(enum mandocerr er, struct mparse *m,
|
||||
int ln, int col, const char *msg)
|
||||
{
|
||||
enum mandoclevel level;
|
||||
|
||||
level = MANDOCLEVEL_FATAL;
|
||||
while (er < mandoclimits[level])
|
||||
level--;
|
||||
|
||||
if (level < m->wlevel)
|
||||
return;
|
||||
|
||||
if (m->mmsg)
|
||||
(*m->mmsg)(er, level, m->file, ln, col, msg);
|
||||
|
||||
if (m->file_status < level)
|
||||
m->file_status = level;
|
||||
}
|
||||
|
||||
const char *
|
||||
mparse_strerror(enum mandocerr er)
|
||||
{
|
||||
|
||||
return(mandocerrs[er]);
|
||||
}
|
||||
|
||||
const char *
|
||||
mparse_strlevel(enum mandoclevel lvl)
|
||||
{
|
||||
return(mandoclevels[lvl]);
|
||||
}
|
||||
|
||||
void
|
||||
mparse_keep(struct mparse *p)
|
||||
{
|
||||
|
||||
assert(NULL == p->secondary);
|
||||
p->secondary = mandoc_calloc(1, sizeof(struct buf));
|
||||
}
|
||||
|
||||
const char *
|
||||
mparse_getkeep(const struct mparse *p)
|
||||
{
|
||||
|
||||
assert(p->secondary);
|
||||
return(p->secondary->sz ? p->secondary->buf : NULL);
|
||||
}
|
177
external/bsd/mdocml/dist/roff.3
vendored
177
external/bsd/mdocml/dist/roff.3
vendored
|
@ -1,177 +0,0 @@
|
|||
.\" $Vendor-Id: roff.3,v 1.10 2011/01/01 16:18:39 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 1, 2011
|
||||
.Dt ROFF 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm roff ,
|
||||
.Nm roff_alloc ,
|
||||
.Nm roff_endparse ,
|
||||
.Nm roff_free ,
|
||||
.Nm roff_parseln ,
|
||||
.Nm roff_reset ,
|
||||
.Nm roff_span
|
||||
.Nd roff macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In mandoc.h
|
||||
.In roff.h
|
||||
.Ft "struct roff *"
|
||||
.Fo roff_alloc
|
||||
.Fa "struct regset *regs"
|
||||
.Fa "void *data"
|
||||
.Fa "mandocmsg msgs"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn roff_endparse "struct roff *roff"
|
||||
.Ft void
|
||||
.Fn roff_free "struct roff *roff"
|
||||
.Ft "enum rofferr"
|
||||
.Fo roff_parseln
|
||||
.Fa "struct roff *roff"
|
||||
.Fa "int line"
|
||||
.Fa "char **bufp"
|
||||
.Fa "size_t *bufsz"
|
||||
.Fa "int pos"
|
||||
.Fa "int *offs"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn roff_reset "struct roff *roff"
|
||||
.Ft "const struct tbl_span *"
|
||||
.Fn roff_span "const struct roff *roff"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
library processes lines of
|
||||
.Xr roff 7
|
||||
input.
|
||||
.Pp
|
||||
In general, applications initiate a parsing sequence with
|
||||
.Fn roff_alloc ,
|
||||
parse each line in a document with
|
||||
.Fn roff_parseln ,
|
||||
close the parsing session with
|
||||
.Fn roff_endparse ,
|
||||
and finally free all allocated memory with
|
||||
.Fn roff_free .
|
||||
The
|
||||
.Fn roff_reset
|
||||
function may be used in order to reset the parser for another input
|
||||
sequence.
|
||||
.Pp
|
||||
The
|
||||
.Fn roff_parseln
|
||||
function should be invoked before passing a line into the
|
||||
.Xr mdoc 3
|
||||
or
|
||||
.Xr man 3
|
||||
libraries.
|
||||
.Pp
|
||||
See the
|
||||
.Sx EXAMPLES
|
||||
section for a full example.
|
||||
.Sh REFERENCE
|
||||
This section further defines the
|
||||
.Sx Types
|
||||
and
|
||||
.Sx Functions
|
||||
available to programmers.
|
||||
.Ss Types
|
||||
Functions (see
|
||||
.Sx Functions )
|
||||
may use the following types:
|
||||
.Bl -ohang
|
||||
.It Vt "enum rofferr"
|
||||
Instructions for further processing to the caller of
|
||||
.Fn roff_parseln .
|
||||
.It Vt struct roff
|
||||
An opaque type defined in
|
||||
.Pa roff.c .
|
||||
Its values are only used privately within the library.
|
||||
.It Vt mandocmsg
|
||||
A function callback type defined in
|
||||
.Pa mandoc.h .
|
||||
.El
|
||||
.Ss Functions
|
||||
Function descriptions follow:
|
||||
.Bl -ohang
|
||||
.It Fn roff_alloc
|
||||
Allocates a parsing structure.
|
||||
The
|
||||
.Fa data
|
||||
pointer is passed to
|
||||
.Fa msgs .
|
||||
Returns NULL on failure.
|
||||
If non-NULL, the pointer must be freed with
|
||||
.Fn roff_free .
|
||||
.It Fn roff_reset
|
||||
Reset the parser for another parse routine.
|
||||
After its use,
|
||||
.Fn roff_parseln
|
||||
behaves as if invoked for the first time.
|
||||
.It Fn roff_free
|
||||
Free all resources of a parser.
|
||||
The pointer is no longer valid after invocation.
|
||||
.It Fn roff_parseln
|
||||
Parse a nil-terminated line of input.
|
||||
The character array
|
||||
.Fa bufp
|
||||
may be modified or reallocated within this function.
|
||||
In the latter case,
|
||||
.Fa bufsz
|
||||
will be modified accordingly.
|
||||
The
|
||||
.Fa offs
|
||||
pointer will be modified if the line start during subsequent processing
|
||||
of the line is not at the zeroth index.
|
||||
This line should not contain the trailing newline.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn roff_endparse
|
||||
Signals that the parse is complete.
|
||||
.It Fn roff_span
|
||||
If
|
||||
.Fn roff_parseln
|
||||
returned
|
||||
.Va ROFF_TBL ,
|
||||
return the last parsed table row.
|
||||
Returns NULL otherwise.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
See
|
||||
.Pa main.c
|
||||
in the source distribution for an example of usage.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 3 ,
|
||||
.Xr mdoc 3 ,
|
||||
.Xr roff 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.Sh BUGS
|
||||
The implementation of user-defined strings needs improvement:
|
||||
.Bl -dash
|
||||
.It
|
||||
String values are taken literally and are not interpreted.
|
||||
.It
|
||||
Parsing of quoted strings is incomplete.
|
||||
.It
|
||||
The stings are stored internally using a singly linked list,
|
||||
which is fine for small numbers of strings,
|
||||
but ineffient when handling many strings.
|
||||
.El
|
488
external/bsd/mdocml/dist/roff.7
vendored
488
external/bsd/mdocml/dist/roff.7
vendored
|
@ -1,7 +1,7 @@
|
|||
.\" $Vendor-Id: roff.7,v 1.23 2011/01/04 23:32:21 kristaps Exp $
|
||||
.\" $Vendor-Id: roff.7,v 1.37 2011/12/11 00:38:11 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011 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 January 4, 2011
|
||||
.Dd December 11, 2011
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -25,42 +25,281 @@
|
|||
The
|
||||
.Nm roff
|
||||
language is a general purpose text formatting language.
|
||||
In particular, it serves as the basis for the
|
||||
Since traditional implementations of the
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
manual formatting macro languages.
|
||||
This manual describes the subset of the
|
||||
manual formatting languages are based on it,
|
||||
many real-world manuals use small numbers of
|
||||
.Nm
|
||||
language accepted by the
|
||||
.Xr mandoc 1
|
||||
utility.
|
||||
.Pp
|
||||
Input lines beginning with the control characters
|
||||
.Sq \&.
|
||||
requests intermixed with their
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Sq \(aq
|
||||
are parsed for requests and macros.
|
||||
These define the document structure, change the processing state
|
||||
and manipulate the formatting.
|
||||
Some requests and macros also produce formatted output,
|
||||
while others do not.
|
||||
.Xr man 7
|
||||
code.
|
||||
To properly format such manuals, the
|
||||
.Xr mandoc 1
|
||||
utility supports a tiny subset of
|
||||
.Nm
|
||||
requests.
|
||||
Only these requests supported by
|
||||
.Xr mandoc 1
|
||||
are documented in the present manual,
|
||||
together with the basic language syntax shared by
|
||||
.Nm ,
|
||||
.Xr mdoc 7 ,
|
||||
and
|
||||
.Xr man 7 .
|
||||
For complete
|
||||
.Nm
|
||||
manuals, consult the
|
||||
.Sx SEE ALSO
|
||||
section.
|
||||
.Pp
|
||||
All other input lines provide free-form text to be printed;
|
||||
the formatting of free-form text depends on the respective
|
||||
processing context.
|
||||
Input lines beginning with the control character
|
||||
.Sq \&.
|
||||
are parsed for requests and macros.
|
||||
Such lines are called
|
||||
.Dq request lines
|
||||
or
|
||||
.Dq macro lines ,
|
||||
respectively.
|
||||
Requests change the processing state and manipulate the formatting;
|
||||
some macros also define the document structure and produce formatted
|
||||
output.
|
||||
The single quote
|
||||
.Pq Qq \(aq
|
||||
is accepted as an alternative control character,
|
||||
treated by
|
||||
.Xr mandoc 1
|
||||
just like
|
||||
.Ql \&.
|
||||
.Pp
|
||||
Lines not beginning with control characters are called
|
||||
.Dq text lines .
|
||||
They provide free-form text to be printed; the formatting of the text
|
||||
depends on the respective processing context.
|
||||
.Sh LANGUAGE SYNTAX
|
||||
.Nm
|
||||
documents may contain only graphable 7-bit ASCII characters, the space
|
||||
character, and, in certain circumstances, the tab character.
|
||||
To produce other characters in the output, use the escape sequences
|
||||
documented in the
|
||||
.Xr mandoc_char 7
|
||||
manual.
|
||||
The back-space character
|
||||
.Sq \e
|
||||
indicates the start of an escape sequence for
|
||||
.Sx Comments ,
|
||||
.Sx Special Characters ,
|
||||
.Sx Predefined Strings ,
|
||||
and
|
||||
user-defined strings defined using the
|
||||
.Sx ds
|
||||
request.
|
||||
.Ss Comments
|
||||
Text following an escaped double-quote
|
||||
.Sq \e\(dq ,
|
||||
whether in a request, macro, or text line, is ignored to the end of the line.
|
||||
A request line beginning with a control character and comment escape
|
||||
.Sq \&.\e\(dq
|
||||
is also ignored.
|
||||
Furthermore, request lines with only a control character and optional
|
||||
trailing whitespace are stripped from input.
|
||||
.Pp
|
||||
All manuals must have
|
||||
.Ux
|
||||
line terminators.
|
||||
Examples:
|
||||
.Bd -literal -offset indent -compact
|
||||
\&.\e\(dq This is a comment line.
|
||||
\&.\e\(dq The next line is ignored:
|
||||
\&.
|
||||
\&.Sh EXAMPLES \e\(dq This is a comment, too.
|
||||
\&example text \e\(dq And so is this.
|
||||
.Ed
|
||||
.Ss Special Characters
|
||||
Special characters are used to encode special glyphs and are rendered
|
||||
differently across output media.
|
||||
They may occur in request, macro, and text lines.
|
||||
Sequences begin with the escape character
|
||||
.Sq \e
|
||||
followed by either an open-parenthesis
|
||||
.Sq \&(
|
||||
for two-character sequences; an open-bracket
|
||||
.Sq \&[
|
||||
for n-character sequences (terminated at a close-bracket
|
||||
.Sq \&] ) ;
|
||||
or a single one character sequence.
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Li \e(em
|
||||
Two-letter em dash escape.
|
||||
.It Li \ee
|
||||
One-letter backslash escape.
|
||||
.El
|
||||
.Pp
|
||||
See
|
||||
.Xr mandoc_char 7
|
||||
for a complete list.
|
||||
.Ss Text Decoration
|
||||
Terms may be text-decorated using the
|
||||
.Sq \ef
|
||||
escape followed by an indicator: B (bold), I (italic), R (regular), or P
|
||||
(revert to previous mode).
|
||||
A numerical representation 3, 2, or 1 (bold, italic, and regular,
|
||||
respectively) may be used instead.
|
||||
The indicator or numerical representative may be preceded by C
|
||||
(constant-width), which is ignored.
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Li \efBbold\efR
|
||||
Write in bold, then switch to regular font mode.
|
||||
.It Li \efIitalic\efP
|
||||
Write in italic, then return to previous font mode.
|
||||
.El
|
||||
.Pp
|
||||
Text decoration is
|
||||
.Em not
|
||||
recommended for
|
||||
.Xr mdoc 7 ,
|
||||
which encourages semantic annotation.
|
||||
.Ss Predefined Strings
|
||||
Predefined strings, like
|
||||
.Sx Special Characters ,
|
||||
mark special output glyphs.
|
||||
Predefined strings are escaped with the slash-asterisk,
|
||||
.Sq \e* :
|
||||
single-character
|
||||
.Sq \e*X ,
|
||||
two-character
|
||||
.Sq \e*(XX ,
|
||||
and N-character
|
||||
.Sq \e*[N] .
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Li \e*(Am
|
||||
Two-letter ampersand predefined string.
|
||||
.It Li \e*q
|
||||
One-letter double-quote predefined string.
|
||||
.El
|
||||
.Pp
|
||||
Predefined strings are not recommended for use,
|
||||
as they differ across implementations.
|
||||
Those supported by
|
||||
.Xr mandoc 1
|
||||
are listed in
|
||||
.Xr mandoc_char 7 .
|
||||
Manuals using these predefined strings are almost certainly not portable.
|
||||
.Ss Whitespace
|
||||
Whitespace consists of the space character.
|
||||
In text lines, whitespace is preserved within a line.
|
||||
In request and macro lines, whitespace delimits arguments and is discarded.
|
||||
.Pp
|
||||
Unescaped trailing spaces are stripped from text line input unless in a
|
||||
literal context.
|
||||
In general, trailing whitespace on any input line is discouraged for
|
||||
reasons of portability.
|
||||
In the rare case that a blank character is needed at the end of an
|
||||
input line, it may be forced by
|
||||
.Sq \e\ \e& .
|
||||
.Pp
|
||||
Literal space characters can be produced in the output
|
||||
using escape sequences.
|
||||
In macro lines, they can also be included in arguments using quotation; see
|
||||
.Sx MACRO SYNTAX
|
||||
for details.
|
||||
.Pp
|
||||
Blank text lines, which may include whitespace, are only permitted
|
||||
within literal contexts.
|
||||
If the first character of a text line is a space, that line is printed
|
||||
with a leading newline.
|
||||
.Ss Scaling Widths
|
||||
Many requests and macros support scaled widths for their arguments.
|
||||
The syntax for a scaled width is
|
||||
.Sq Li [+-]?[0-9]*.[0-9]*[:unit:] ,
|
||||
where a decimal must be preceded or followed by at least one digit.
|
||||
Negative numbers, while accepted, are truncated to zero.
|
||||
.Pp
|
||||
The following scaling units are accepted:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It c
|
||||
centimetre
|
||||
.It i
|
||||
inch
|
||||
.It P
|
||||
pica (~1/6 inch)
|
||||
.It p
|
||||
point (~1/72 inch)
|
||||
.It f
|
||||
synonym for
|
||||
.Sq u
|
||||
.It v
|
||||
default vertical span
|
||||
.It m
|
||||
width of rendered
|
||||
.Sq m
|
||||
.Pq em
|
||||
character
|
||||
.It n
|
||||
width of rendered
|
||||
.Sq n
|
||||
.Pq en
|
||||
character
|
||||
.It u
|
||||
default horizontal span
|
||||
.It M
|
||||
mini-em (~1/100 em)
|
||||
.El
|
||||
.Pp
|
||||
Using anything other than
|
||||
.Sq m ,
|
||||
.Sq n ,
|
||||
.Sq u ,
|
||||
or
|
||||
.Sq v
|
||||
is necessarily non-portable across output media.
|
||||
See
|
||||
.Sx COMPATIBILITY .
|
||||
.Pp
|
||||
If a scaling unit is not provided, the numerical value is interpreted
|
||||
under the default rules of
|
||||
.Sq v
|
||||
for vertical spaces and
|
||||
.Sq u
|
||||
for horizontal ones.
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width ".Bl -tag -width 2i" -offset indent -compact
|
||||
.It Li \&.Bl -tag -width 2i
|
||||
two-inch tagged list indentation in
|
||||
.Xr mdoc 7
|
||||
.It Li \&.HP 2i
|
||||
two-inch tagged list indentation in
|
||||
.Xr man 7
|
||||
.It Li \&.sp 2v
|
||||
two vertical spaces
|
||||
.El
|
||||
.Ss Sentence Spacing
|
||||
Each sentence should terminate at the end of an input line.
|
||||
By doing this, a formatter will be able to apply the proper amount of
|
||||
spacing after the end of sentence (unescaped) period, exclamation mark,
|
||||
or question mark followed by zero or more non-sentence closing
|
||||
delimiters
|
||||
.Po
|
||||
.Sq \&) ,
|
||||
.Sq \&] ,
|
||||
.Sq \&' ,
|
||||
.Sq \&"
|
||||
.Pc .
|
||||
.Pp
|
||||
The proper spacing is also intelligently preserved if a sentence ends at
|
||||
the boundary of a macro line.
|
||||
.Pp
|
||||
Examples:
|
||||
.Bd -literal -offset indent -compact
|
||||
Do not end sentences mid-line like this. Instead,
|
||||
end a sentence like this.
|
||||
A macro would end like this:
|
||||
\&.Xr mandoc 1 \&.
|
||||
.Ed
|
||||
.Sh REQUEST SYNTAX
|
||||
A request or macro line consists of:
|
||||
.Pp
|
||||
|
@ -86,11 +325,66 @@ Thus, the following request lines are all equivalent:
|
|||
\&.ig end
|
||||
\&. ig end
|
||||
.Ed
|
||||
.Sh MACRO SYNTAX
|
||||
Macros are provided by the
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
languages and can be defined by the
|
||||
.Sx \&de
|
||||
request.
|
||||
When called, they follow the same syntax as requests, except that
|
||||
macro arguments may optionally be quoted by enclosing them
|
||||
in double quote characters
|
||||
.Pq Sq \(dq .
|
||||
Quoted text, even if it contains whitespace or would cause
|
||||
a macro invocation when unquoted, is always considered literal text.
|
||||
Inside quoted text, pairs of double quote characters
|
||||
.Pq Sq Qq
|
||||
resolve to single double quote characters.
|
||||
.Pp
|
||||
To be recognised as the beginning of a quoted argument, the opening
|
||||
quote character must be preceded by a space character.
|
||||
A quoted argument extends to the next double quote character that is not
|
||||
part of a pair, or to the end of the input line, whichever comes earlier.
|
||||
Leaving out the terminating double quote character at the end of the line
|
||||
is discouraged.
|
||||
For clarity, if more arguments follow on the same input line,
|
||||
it is recommended to follow the terminating double quote character
|
||||
by a space character; in case the next character after the terminating
|
||||
double quote character is anything else, it is regarded as the beginning
|
||||
of the next, unquoted argument.
|
||||
.Pp
|
||||
Both in quoted and unquoted arguments, pairs of backslashes
|
||||
.Pq Sq \e\e
|
||||
resolve to single backslashes.
|
||||
In unquoted arguments, space characters can alternatively be included
|
||||
by preceding them with a backslash
|
||||
.Pq Sq \e\~ ,
|
||||
but quoting is usually better for clarity.
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Li .Fn strlen \(dqconst char *s\(dq
|
||||
Group arguments
|
||||
.Qq const char *s
|
||||
into one function argument.
|
||||
If unspecified,
|
||||
.Qq const ,
|
||||
.Qq char ,
|
||||
and
|
||||
.Qq *s
|
||||
would be considered separate arguments.
|
||||
.It Li .Op \(dqFl a\(dq
|
||||
Consider
|
||||
.Qq \&Fl a
|
||||
as literal text instead of a flag macro.
|
||||
.El
|
||||
.Sh REQUEST REFERENCE
|
||||
The
|
||||
.Xr mandoc 1
|
||||
.Nm
|
||||
parser recognizes the following requests.
|
||||
parser recognises the following requests.
|
||||
Note that the
|
||||
.Nm
|
||||
language defines many more requests not implemented in
|
||||
|
@ -98,7 +392,7 @@ language defines many more requests not implemented in
|
|||
.Ss \&ad
|
||||
Set line adjustment mode.
|
||||
This line-scoped request is intended to have one argument to select
|
||||
normal, left, right, or center adjustment for subsequent text.
|
||||
normal, left, right, or centre adjustment for subsequent text.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&am
|
||||
|
@ -174,12 +468,9 @@ The macro can be invoked later using the syntax
|
|||
.Pp
|
||||
.D1 Pf . Ar name Op Ar argument Op Ar argument ...
|
||||
.Pp
|
||||
Arguments are separated by blank characters and can be quoted
|
||||
using double-quotes
|
||||
.Pq Sq \(dq
|
||||
to allow inclusion of blank characters into arguments.
|
||||
To include the double-quote character into a quoted argument,
|
||||
escape it from ending the argument by doubling it.
|
||||
Regarding argument parsing, see
|
||||
.Sx MACRO SYNTAX
|
||||
above.
|
||||
.Pp
|
||||
The line invoking the macro will be replaced
|
||||
in the input stream by the
|
||||
|
@ -319,6 +610,15 @@ then false is assumed.
|
|||
The syntax of this request is similar to
|
||||
.Sx \&if
|
||||
except that the conditional is missing.
|
||||
.Ss \&EN
|
||||
End an equation block.
|
||||
See
|
||||
.Sx \&EQ .
|
||||
.Ss \&EQ
|
||||
Begin an equation block.
|
||||
See
|
||||
.Xr eqn 7
|
||||
for a description of the equation language.
|
||||
.Ss \&hy
|
||||
Set automatic hyphenation mode.
|
||||
This line-scoped request is currently ignored.
|
||||
|
@ -414,15 +714,20 @@ than having the request or macro follow as
|
|||
The scope of a conditional is always parsed, but only executed if the
|
||||
conditional evaluates to true.
|
||||
.Pp
|
||||
Note that text following an
|
||||
.Sq \&.\e}
|
||||
escape sequence is discarded.
|
||||
Furthermore, if an explicit closing sequence
|
||||
Note that the
|
||||
.Sq \e}
|
||||
is specified in a free-form line, the entire line is accepted within the
|
||||
scope of the prior request, not only the text preceding the close, with the
|
||||
is converted into a zero-width escape sequence if not passed as a
|
||||
standalone macro
|
||||
.Sq \&.\e} .
|
||||
For example,
|
||||
.Pp
|
||||
.D1 \&.Fl a \e} b
|
||||
.Pp
|
||||
will result in
|
||||
.Sq \e}
|
||||
collapsing into a zero-width space.
|
||||
being considered an argument of the
|
||||
.Sq \&Fl
|
||||
macro.
|
||||
.Ss \&ig
|
||||
Ignore input.
|
||||
Its syntax can be either
|
||||
|
@ -512,6 +817,16 @@ section with the
|
|||
.Cm \&Sh
|
||||
macro will reset this register.
|
||||
.El
|
||||
.Ss \&ns
|
||||
Turn on no-space mode.
|
||||
This line-scoped request is intended to take no arguments.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&ps
|
||||
Change point size.
|
||||
This line-scoped request is intended to take one numerical argument.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&so
|
||||
Include a source file.
|
||||
Its syntax is as follows:
|
||||
|
@ -523,18 +838,49 @@ The
|
|||
will be read and its contents processed as input in place of the
|
||||
.Sq \&.so
|
||||
request line.
|
||||
To avoid inadvertant inclusion of unrelated files,
|
||||
To avoid inadvertent inclusion of unrelated files,
|
||||
.Xr mandoc 1
|
||||
only accepts relative paths not containing the strings
|
||||
.Qq ../
|
||||
and
|
||||
.Qq /.. .
|
||||
.Pp
|
||||
This request requires
|
||||
.Xr man 1
|
||||
to change to the right directory before calling
|
||||
.Xr mandoc 1 ,
|
||||
per convention to the root of the manual tree.
|
||||
Typical usage looks like:
|
||||
.Pp
|
||||
.Dl \&.so man3/Xcursor.3
|
||||
.Pp
|
||||
As the whole concept is rather fragile, the use of
|
||||
.Sx \&so
|
||||
is discouraged.
|
||||
Use
|
||||
.Xr ln 1
|
||||
instead.
|
||||
.Ss \&ta
|
||||
Set tab stops.
|
||||
This line-scoped request can take an arbitrary number of arguments.
|
||||
Currently, it is ignored including its arguments.
|
||||
.Ss \&tr
|
||||
Output character translation.
|
||||
This request is intended to have one argument,
|
||||
consisting of an even number of characters.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Cm \&tr Ar [ab]+
|
||||
.Pp
|
||||
Pairs of
|
||||
.Ar ab
|
||||
characters are replaced
|
||||
.Ar ( a
|
||||
for
|
||||
.Ar b ) .
|
||||
Replacement (or origin) characters may also be character escapes; thus,
|
||||
.Pp
|
||||
.Dl tr \e(xx\e(yy
|
||||
.Pp
|
||||
replaces all invocations of \e(xx with \e(yy.
|
||||
.Ss \&T&
|
||||
Re-start a table layout, retaining the options of the prior table
|
||||
invocation.
|
||||
|
@ -560,6 +906,19 @@ refers to groff version 1.15.
|
|||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
In mandoc, the
|
||||
.Sx \&EQ ,
|
||||
.Sx \&TE ,
|
||||
.Sx \&TS ,
|
||||
and
|
||||
.Sx \&T& ,
|
||||
macros are considered regular macros.
|
||||
In all other
|
||||
.Nm
|
||||
implementations, these are special macros that must be specified without
|
||||
spacing between the control character (which must be a period) and the
|
||||
macro name.
|
||||
.It
|
||||
The
|
||||
.Cm nS
|
||||
register is only compatible with OpenBSD's groff-1.15.
|
||||
|
@ -577,6 +936,7 @@ using the next-line syntax.
|
|||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr eqn 7 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
|
@ -601,19 +961,29 @@ using the next-line syntax.
|
|||
.%U http://heirloom.sourceforge.net/doctools/troff.pdf
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The RUNOFF typesetting system was written in PL/1 for the CTSS
|
||||
operating system by Jerome ("Jerry") E. Saltzer in 1961.
|
||||
It was first used as the main documentation tool by Multics since 1963.
|
||||
Robert ("Bob") H. Morris ported it to the GE-635 and called it
|
||||
The RUNOFF typesetting system, whose input forms the basis for
|
||||
.Nm ,
|
||||
Doug McIlroy rewrote it in BCPL in 1969,
|
||||
Joseph F. Ossanna rewrote it in PDP-11 assembly in 1973,
|
||||
and Brian W. Kernighan rewrote it in C in 1975.
|
||||
was written in MAD and FAP for the CTSS operating system by Jerome E.
|
||||
Saltzer in 1964.
|
||||
Doug McIlroy rewrote it in BCPL in 1969, renaming it
|
||||
.Nm .
|
||||
Dennis M. Ritchie rewrote McIlroy's
|
||||
.Nm
|
||||
in PDP-11 assembly for
|
||||
.At v1 ,
|
||||
Joseph F. Ossanna improved roff and renamed it nroff
|
||||
for
|
||||
.At v2 ,
|
||||
then ported nroff to C as troff, which Brian W. Kernighan released with
|
||||
.At v7 .
|
||||
In 1989, James Clarke re-implemented troff in C++, naming it groff.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
This partial
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv ;
|
||||
and
|
||||
.An Ingo Schwarze Aq schwarze@openbsd.org .
|
||||
.An Ingo Schwarze ,
|
||||
.Mt schwarze@openbsd.org .
|
||||
|
|
984
external/bsd/mdocml/dist/roff.c
vendored
984
external/bsd/mdocml/dist/roff.c
vendored
File diff suppressed because it is too large
Load diff
45
external/bsd/mdocml/dist/roff.h
vendored
45
external/bsd/mdocml/dist/roff.h
vendored
|
@ -1,45 +0,0 @@
|
|||
/* $Vendor-Id: roff.h,v 1.22 2011/01/01 16:18:39 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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.
|
||||
*/
|
||||
#ifndef ROFF_H
|
||||
#define ROFF_H
|
||||
|
||||
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 */
|
||||
ROFF_TBL, /* a table row was successfully parsed */
|
||||
ROFF_ERR /* badness: puke and stop */
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct roff;
|
||||
|
||||
void roff_free(struct roff *);
|
||||
struct roff *roff_alloc(struct regset *, void *, mandocmsg);
|
||||
void roff_reset(struct roff *);
|
||||
enum rofferr roff_parseln(struct roff *, int,
|
||||
char **, size_t *, int, int *);
|
||||
void roff_endparse(struct roff *);
|
||||
const struct tbl_span *roff_span(const struct roff *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!ROFF_H*/
|
3
external/bsd/mdocml/dist/st.c
vendored
3
external/bsd/mdocml/dist/st.c
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: st.c,v 1.8 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/* $Vendor-Id: st.c,v 1.9 2011/03/22 14:33:05 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mdoc.h"
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
|
|
52
external/bsd/mdocml/dist/st.in
vendored
52
external/bsd/mdocml/dist/st.in
vendored
|
@ -1,4 +1,4 @@
|
|||
/* $Vendor-Id: st.in,v 1.15 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/* $Vendor-Id: st.in,v 1.18 2012/01/03 10:18:05 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -22,6 +22,8 @@
|
|||
* the formatted output string.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
* The non-breaking blanks prevent ending an output line right before
|
||||
* a number. Groff prevent line breaks at the same places.
|
||||
*
|
||||
* REMEMBER TO ADD NEW STANDARDS TO MDOC.7!
|
||||
*/
|
||||
|
@ -43,32 +45,34 @@ LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)")
|
|||
LINE("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1387.2", "IEEE Std 1387.2 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(lqISO C99\\(rq)")
|
||||
LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
||||
LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
||||
LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO\\~C90, Amendment 1\\(rq)")
|
||||
LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(lqISO\\~C90, Technical Corrigendum 1\\(rq)")
|
||||
LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(lqISO\\~C90, Technical Corrigendum 2\\(rq)")
|
||||
LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(lqISO\\~C99\\(rq)")
|
||||
LINE("-isoC-2011", "ISO/IEC 9899:2011 (\\(lqISO\\~C11\\(rq)")
|
||||
LINE("-iso9945-1-90", "ISO/IEC 9945-1:1990 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI C\\(rq)")
|
||||
LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI C\\(rq)")
|
||||
LINE("-ansiC-99", "ANSI/ISO/IEC 9899-1999 (\\(lqANSI C99\\(rq)")
|
||||
LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
|
||||
LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
|
||||
LINE("-ansiC-99", "ANSI/ISO/IEC 9899-1999 (\\(lqANSI\\~C99\\(rq)")
|
||||
LINE("-ieee754", "IEEE Std 754-1985")
|
||||
LINE("-iso8802-3", "ISO 8802-3: 1989")
|
||||
LINE("-iso8601", "ISO 8601")
|
||||
LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)")
|
||||
LINE("-xpg3", "X/Open Portability Guide Issue 3 (\\(lqXPG3\\(rq)")
|
||||
LINE("-xpg4", "X/Open Portability Guide Issue 4 (\\(lqXPG4\\(rq)")
|
||||
LINE("-xpg4.2", "X/Open Portability Guide Issue 4.2 (\\(lqXPG4.2\\(rq)")
|
||||
LINE("-xpg4.3", "X/Open Portability Guide Issue 4.3 (\\(lqXPG4.3\\(rq)")
|
||||
LINE("-xbd5", "X/Open System Interface Definitions Issue 5 (\\(lqXBD5\\(rq)")
|
||||
LINE("-xcu5", "X/Open Commands and Utilities Issue 5 (\\(lqXCU5\\(rq)")
|
||||
LINE("-xsh5", "X/Open System Interfaces and Headers Issue 5 (\\(lqXSH5\\(rq)")
|
||||
LINE("-xns5", "X/Open Networking Services Issue 5 (\\(lqXNS5\\(rq)")
|
||||
LINE("-xns5.2", "X/Open Networking Services Issue 5.2 (\\(lqXNS5.2\\(rq)")
|
||||
LINE("-xns5.2d2.0", "X/Open Networking Services Issue 5.2 Draft 2.0 (\\(lqXNS5.2D2.0\\(rq)")
|
||||
LINE("-xcurses4.2", "X/Open Curses Issue 4 Version 2 (\\(lqXCURSES4.2\\(rq)")
|
||||
LINE("-susv2", "Version 2 of the Single UNIX Specification")
|
||||
LINE("-susv3", "Version 3 of the Single UNIX Specification")
|
||||
LINE("-svid4", "System V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
|
||||
LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)")
|
||||
LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)")
|
||||
LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)")
|
||||
LINE("-xpg4.3", "X/Open Portability Guide Issue\\~4, Version\\~3 (\\(lqXPG4.3\\(rq)")
|
||||
LINE("-xbd5", "X/Open System Interface Definitions Issue\\~5 (\\(lqXBD5\\(rq)")
|
||||
LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)")
|
||||
LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)")
|
||||
LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)")
|
||||
LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)")
|
||||
LINE("-xns5.2d2.0", "X/Open Networking Services Issue\\~5.2 Draft\\~2.0 (\\(lqXNS5.2D2.0\\(rq)")
|
||||
LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)")
|
||||
LINE("-susv2", "Version\\~2 of the Single UNIX Specification")
|
||||
LINE("-susv3", "Version\\~3 of the Single UNIX Specification")
|
||||
LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
|
||||
|
|
74
external/bsd/mdocml/dist/tbl.7
vendored
74
external/bsd/mdocml/dist/tbl.7
vendored
|
@ -1,6 +1,6 @@
|
|||
.\" $Vendor-Id: tbl.7,v 1.4 2011/01/07 14:59:52 kristaps Exp $
|
||||
.\" $Vendor-Id: tbl.7,v 1.16 2011/09/03 00:29:21 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -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 January 7, 2011
|
||||
.Dd September 3, 2011
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -49,7 +49,7 @@ macro tags, whose precise syntax is documented in
|
|||
Tables consist of a series of options on a single line, followed by the
|
||||
table layout, followed by data.
|
||||
.Pp
|
||||
For example, the following creates a boxed table with digits centered in
|
||||
For example, the following creates a boxed table with digits centred in
|
||||
the cells.
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
|
@ -69,6 +69,13 @@ c5 c5 c5.
|
|||
4:5:6
|
||||
.TE
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
implementation in
|
||||
.Xr mandoc 1
|
||||
is
|
||||
.Ud
|
||||
.Sh TABLE STRUCTURE
|
||||
Tables are enclosed by the
|
||||
.Sq TS
|
||||
|
@ -180,8 +187,6 @@ Accepts a single-character argument.
|
|||
This character will be used as the decimal point with the
|
||||
.Cm n
|
||||
layout key.
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm nospaces
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
|
@ -205,18 +210,29 @@ Right-justify a literal string within its column.
|
|||
.It Cm l
|
||||
Left-justify a literal string within its column.
|
||||
.It Cm n
|
||||
Justify a number around its decimal point.
|
||||
Justify a number around its last decimal point.
|
||||
If the decimal point is not found on the number, it's assumed to trail
|
||||
the number.
|
||||
.It Cm s
|
||||
Horizontally span columns from the last
|
||||
.No non- Ns Cm s
|
||||
data cell.
|
||||
It is an error if spanning columns follow a
|
||||
.Cm \-
|
||||
or
|
||||
.Cm \(ba
|
||||
cell, or come first.
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm a
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
Left-justify a literal string and pad with one space.
|
||||
.It Cm ^
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
Vertically span rows from the last
|
||||
.No non- Ns Cm ^
|
||||
data cell.
|
||||
It is an error to invoke a vertical span on the first layout row.
|
||||
Unlike a horizontal spanner, you must specify an empty cell (if it not
|
||||
empty, the data is discarded) in the corresponding data cell.
|
||||
.It Cm \-
|
||||
Replace the data cell (its contents will be lost) with a single
|
||||
horizontal line.
|
||||
|
@ -231,30 +247,39 @@ Emit a vertical bar instead of data.
|
|||
Emit a double-vertical bar instead of data.
|
||||
.El
|
||||
.Pp
|
||||
For example, the following layout specifies a centre-justified column of
|
||||
minimum width 10, followed by vertical bar, followed by a left-justified
|
||||
column of minimum width 10, another vertical bar, then a column
|
||||
justified about the decimal point in numbers:
|
||||
.Pp
|
||||
.Dl c10 | l10 | n
|
||||
.Pp
|
||||
Keys may be followed by a set of modifiers.
|
||||
A modifier is either a modifier key or a natural number for specifying
|
||||
spacing.
|
||||
the minimum width of a column.
|
||||
The following case-insensitive modifier keys are available:
|
||||
.Cm z ,
|
||||
.Cm u ,
|
||||
.Cm e ,
|
||||
.Cm t ,
|
||||
.Cm d ,
|
||||
.Cm f ,
|
||||
.Cm b ,
|
||||
.Cm i ,
|
||||
.Cm b ,
|
||||
.Cm r ,
|
||||
and
|
||||
.Cm i .
|
||||
.Cm f
|
||||
.Po
|
||||
followed by
|
||||
.Cm b ,
|
||||
.Cm i ,
|
||||
.Cm r ,
|
||||
.Cm 3 ,
|
||||
.Cm 2 ,
|
||||
or
|
||||
.Cm 1
|
||||
.Pc .
|
||||
All of these are ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Pp
|
||||
For example, the following layout specifies a centre-justified column of
|
||||
minimum width 10, followed by vertical bar, followed by a left-justified
|
||||
column of minimum width 10, another vertical bar, then a column
|
||||
justified about the decimal point in numbers:
|
||||
.Pp
|
||||
.Dl c10 | l10 | n
|
||||
.Ss Data
|
||||
The data section follows the last layout row.
|
||||
By default, cells in a data section are delimited by a tab.
|
||||
|
@ -316,7 +341,8 @@ This formed the basis of the implementation that is part of the
|
|||
.Xr mandoc 1
|
||||
utility.
|
||||
.Sh AUTHORS
|
||||
This partial
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
|
|
42
external/bsd/mdocml/dist/tbl.c
vendored
42
external/bsd/mdocml/dist/tbl.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: tbl.c,v 1.21 2011/01/04 15:02:00 kristaps Exp $ */
|
||||
/* $Vendor-Id: tbl.c,v 1.26 2011/07/25 15:37:00 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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 +15,10 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -21,7 +26,6 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
|
@ -66,15 +70,14 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
|
|||
}
|
||||
|
||||
struct tbl_node *
|
||||
tbl_alloc(int pos, int line, void *data, const mandocmsg msg)
|
||||
tbl_alloc(int pos, int line, struct mparse *parse)
|
||||
{
|
||||
struct tbl_node *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct tbl_node));
|
||||
p->line = line;
|
||||
p->pos = pos;
|
||||
p->data = data;
|
||||
p->msg = msg;
|
||||
p->parse = parse;
|
||||
p->part = TBL_PART_OPTS;
|
||||
p->opts.tab = '\t';
|
||||
p->opts.linesize = 12;
|
||||
|
@ -125,35 +128,48 @@ void
|
|||
tbl_restart(int line, int pos, struct tbl_node *tbl)
|
||||
{
|
||||
if (TBL_PART_CDATA == tbl->part)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
|
||||
mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
|
||||
tbl->line, tbl->pos, NULL);
|
||||
|
||||
tbl->part = TBL_PART_LAYOUT;
|
||||
tbl->line = line;
|
||||
tbl->pos = pos;
|
||||
|
||||
if (NULL == tbl->first_span || NULL == tbl->first_span->first)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
|
||||
mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,
|
||||
tbl->line, tbl->pos, NULL);
|
||||
}
|
||||
|
||||
const struct tbl_span *
|
||||
tbl_span(const struct tbl_node *tbl)
|
||||
tbl_span(struct tbl_node *tbl)
|
||||
{
|
||||
struct tbl_span *span;
|
||||
|
||||
assert(tbl);
|
||||
return(tbl->last_span);
|
||||
span = tbl->current_span ? tbl->current_span->next
|
||||
: tbl->first_span;
|
||||
if (span)
|
||||
tbl->current_span = span;
|
||||
return(span);
|
||||
}
|
||||
|
||||
void
|
||||
tbl_end(struct tbl_node *tbl)
|
||||
tbl_end(struct tbl_node **tblp)
|
||||
{
|
||||
struct tbl_node *tbl;
|
||||
|
||||
tbl = *tblp;
|
||||
*tblp = NULL;
|
||||
|
||||
if (NULL == tbl->first_span || NULL == tbl->first_span->first)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
|
||||
mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,
|
||||
tbl->line, tbl->pos, NULL);
|
||||
|
||||
if (tbl->last_span)
|
||||
tbl->last_span->flags |= TBL_SPAN_LAST;
|
||||
|
||||
if (TBL_PART_CDATA == tbl->part)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
|
||||
mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
|
||||
tbl->line, tbl->pos, NULL);
|
||||
}
|
||||
|
||||
|
|
118
external/bsd/mdocml/dist/tbl_data.c
vendored
118
external/bsd/mdocml/dist/tbl_data.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: tbl_data.c,v 1.15 2011/01/09 23:14:41 kristaps Exp $ */
|
||||
/* $Vendor-Id: tbl_data.c,v 1.24 2011/03/20 16:02:05 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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,6 +31,8 @@
|
|||
|
||||
static int data(struct tbl_node *, struct tbl_span *,
|
||||
int, const char *, int *);
|
||||
static struct tbl_span *newspan(struct tbl_node *, int,
|
||||
struct tbl_row *);
|
||||
|
||||
static int
|
||||
data(struct tbl_node *tbl, struct tbl_span *dp,
|
||||
|
@ -37,7 +40,7 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
{
|
||||
struct tbl_dat *dat;
|
||||
struct tbl_cell *cp;
|
||||
int sv;
|
||||
int sv, spans;
|
||||
|
||||
cp = NULL;
|
||||
if (dp->last && dp->last->layout)
|
||||
|
@ -55,12 +58,33 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
TBL_CELL_SPAN == cp->pos))
|
||||
cp = cp->next;
|
||||
|
||||
/*
|
||||
* Stop processing when we reach the end of the available layout
|
||||
* cells. This means that we have extra input.
|
||||
*/
|
||||
|
||||
if (NULL == cp) {
|
||||
mandoc_msg(MANDOCERR_TBLEXTRADAT,
|
||||
tbl->parse, ln, *pos, NULL);
|
||||
/* Skip to the end... */
|
||||
while (p[*pos])
|
||||
(*pos)++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
dat = mandoc_calloc(1, sizeof(struct tbl_dat));
|
||||
dat->layout = cp;
|
||||
dat->pos = TBL_DATA_NONE;
|
||||
|
||||
if (NULL == dat->layout)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos);
|
||||
assert(TBL_CELL_SPAN != cp->pos);
|
||||
|
||||
for (spans = 0, cp = cp->next; cp; cp = cp->next)
|
||||
if (TBL_CELL_SPAN == cp->pos)
|
||||
spans++;
|
||||
else
|
||||
break;
|
||||
|
||||
dat->spans = spans;
|
||||
|
||||
if (dp->last) {
|
||||
dp->last->next = dat;
|
||||
|
@ -83,8 +107,10 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
return(0);
|
||||
}
|
||||
|
||||
dat->string = mandoc_malloc(*pos - sv + 1);
|
||||
memcpy(dat->string, &p[sv], *pos - sv);
|
||||
assert(*pos - sv >= 0);
|
||||
|
||||
dat->string = mandoc_malloc((size_t)(*pos - sv + 1));
|
||||
memcpy(dat->string, &p[sv], (size_t)(*pos - sv));
|
||||
dat->string[*pos - sv] = '\0';
|
||||
|
||||
if (p[*pos])
|
||||
|
@ -101,13 +127,12 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
|||
else
|
||||
dat->pos = TBL_DATA_DATA;
|
||||
|
||||
if (NULL == dat->layout)
|
||||
return(1);
|
||||
|
||||
if (TBL_CELL_HORIZ == dat->layout->pos ||
|
||||
TBL_CELL_DHORIZ == dat->layout->pos)
|
||||
TBL_CELL_DHORIZ == dat->layout->pos ||
|
||||
TBL_CELL_DOWN == dat->layout->pos)
|
||||
if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLIGNDATA, ln, sv);
|
||||
mandoc_msg(MANDOCERR_TBLIGNDATA,
|
||||
tbl->parse, ln, sv, NULL);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -123,7 +148,6 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
|||
pos = 0;
|
||||
|
||||
dat = tbl->last_span->last;
|
||||
dat->pos = TBL_DATA_DATA;
|
||||
|
||||
if (p[pos] == 'T' && p[pos + 1] == '}') {
|
||||
pos += 2;
|
||||
|
@ -139,6 +163,8 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
|||
/* Fallthrough: T} is part of a word. */
|
||||
}
|
||||
|
||||
dat->pos = TBL_DATA_DATA;
|
||||
|
||||
if (dat->string) {
|
||||
sz = strlen(p) + strlen(dat->string) + 2;
|
||||
dat->string = mandoc_realloc(dat->string, sz);
|
||||
|
@ -147,9 +173,36 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
|||
} else
|
||||
dat->string = mandoc_strdup(p);
|
||||
|
||||
if (TBL_CELL_DOWN == dat->layout->pos)
|
||||
mandoc_msg(MANDOCERR_TBLIGNDATA,
|
||||
tbl->parse, ln, pos, NULL);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static struct tbl_span *
|
||||
newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
|
||||
{
|
||||
struct tbl_span *dp;
|
||||
|
||||
dp = mandoc_calloc(1, sizeof(struct tbl_span));
|
||||
dp->line = line;
|
||||
dp->tbl = &tbl->opts;
|
||||
dp->layout = rp;
|
||||
dp->head = tbl->first_head;
|
||||
|
||||
if (tbl->last_span) {
|
||||
tbl->last_span->next = dp;
|
||||
tbl->last_span = dp;
|
||||
} else {
|
||||
tbl->last_span = tbl->first_span = dp;
|
||||
tbl->current_span = NULL;
|
||||
dp->flags |= TBL_SPAN_FIRST;
|
||||
}
|
||||
|
||||
return(dp);
|
||||
}
|
||||
|
||||
int
|
||||
tbl_data(struct tbl_node *tbl, int ln, const char *p)
|
||||
{
|
||||
|
@ -160,7 +213,7 @@ tbl_data(struct tbl_node *tbl, int ln, const char *p)
|
|||
pos = 0;
|
||||
|
||||
if ('\0' == p[pos]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, pos);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse, ln, pos, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -170,33 +223,38 @@ tbl_data(struct tbl_node *tbl, int ln, const char *p)
|
|||
* If there's no last parsed span, use the first row. Lastly,
|
||||
* if the last span was a horizontal line, use the same layout
|
||||
* (it doesn't "consume" the layout).
|
||||
*
|
||||
* In the end, this can be NULL!
|
||||
*/
|
||||
|
||||
if (tbl->last_span) {
|
||||
assert(tbl->last_span->layout);
|
||||
if (tbl->last_span->pos == TBL_SPAN_DATA)
|
||||
rp = tbl->last_span->layout->next;
|
||||
else
|
||||
if (tbl->last_span->pos == TBL_SPAN_DATA) {
|
||||
for (rp = tbl->last_span->layout->next;
|
||||
rp && rp->first; rp = rp->next) {
|
||||
switch (rp->first->pos) {
|
||||
case (TBL_CELL_HORIZ):
|
||||
dp = newspan(tbl, ln, rp);
|
||||
dp->pos = TBL_SPAN_HORIZ;
|
||||
continue;
|
||||
case (TBL_CELL_DHORIZ):
|
||||
dp = newspan(tbl, ln, rp);
|
||||
dp->pos = TBL_SPAN_DHORIZ;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
rp = tbl->last_span->layout;
|
||||
|
||||
if (NULL == rp)
|
||||
rp = tbl->last_span->layout;
|
||||
} else
|
||||
rp = tbl->first_row;
|
||||
|
||||
dp = mandoc_calloc(1, sizeof(struct tbl_span));
|
||||
dp->tbl = &tbl->opts;
|
||||
dp->layout = rp;
|
||||
dp->head = tbl->first_head;
|
||||
assert(rp);
|
||||
|
||||
if (tbl->last_span) {
|
||||
tbl->last_span->next = dp;
|
||||
tbl->last_span = dp;
|
||||
} else {
|
||||
tbl->last_span = tbl->first_span = dp;
|
||||
dp->flags |= TBL_SPAN_FIRST;
|
||||
}
|
||||
dp = newspan(tbl, ln, rp);
|
||||
|
||||
if ( ! strcmp(p, "_")) {
|
||||
dp->pos = TBL_SPAN_HORIZ;
|
||||
|
|
107
external/bsd/mdocml/dist/tbl_html.c
vendored
107
external/bsd/mdocml/dist/tbl_html.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: tbl_html.c,v 1.5 2011/01/06 12:31:39 kristaps Exp $ */
|
||||
/* $Vendor-Id: tbl_html.c,v 1.9 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
||||
static void html_tblopen(struct html *, const struct tbl_span *);
|
||||
static size_t html_tbl_len(size_t, void *);
|
||||
static size_t html_tbl_strlen(const char *, void *);
|
||||
|
||||
|
@ -46,81 +47,105 @@ html_tbl_strlen(const char *p, void *arg)
|
|||
return(strlen(p));
|
||||
}
|
||||
|
||||
void
|
||||
print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
static void
|
||||
html_tblopen(struct html *h, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
const struct tbl_dat *dp;
|
||||
struct tag *tt;
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
struct roffcol *col;
|
||||
|
||||
/* Inhibit printing of spaces: we do padding ourselves. */
|
||||
|
||||
h->flags |= HTML_NONOSPACE;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
/* First pass: calculate widths. */
|
||||
|
||||
if (TBL_SPAN_FIRST & sp->flags) {
|
||||
h->tbl.len = html_tbl_len;
|
||||
h->tbl.slen = html_tbl_strlen;
|
||||
tblcalc(&h->tbl, sp);
|
||||
}
|
||||
|
||||
assert(NULL == h->tblt);
|
||||
PAIR_CLASS_INIT(&tag, "tbl");
|
||||
h->tblt = print_otag(h, TAG_TABLE, 1, &tag);
|
||||
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
bufinit(h);
|
||||
col = &h->tbl.cols[hp->ident];
|
||||
SCALE_HS_INIT(&su, col->width);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
}
|
||||
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
print_tblclose(struct html *h)
|
||||
{
|
||||
|
||||
assert(h->tblt);
|
||||
print_tagq(h, h->tblt);
|
||||
h->tblt = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
const struct tbl_dat *dp;
|
||||
struct htmlpair tag;
|
||||
struct tag *tt;
|
||||
|
||||
/* Inhibit printing of spaces: we do padding ourselves. */
|
||||
|
||||
if (NULL == h->tblt)
|
||||
html_tblopen(h, sp);
|
||||
|
||||
assert(h->tblt);
|
||||
|
||||
h->flags |= HTML_NONOSPACE;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
switch (sp->pos) {
|
||||
case (TBL_SPAN_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_SPAN_DHORIZ):
|
||||
PAIR_INIT(&tag, ATTR_COLSPAN, "0");
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
break;
|
||||
default:
|
||||
PAIR_CLASS_INIT(&tag, "tbl");
|
||||
print_otag(h, TAG_TABLE, 1, &tag);
|
||||
print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
/* Iterate over template headers. */
|
||||
|
||||
dp = sp->first;
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
print_stagq(h, tt);
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_DVERT):
|
||||
continue;
|
||||
case (TBL_HEAD_DATA):
|
||||
if (NULL == dp)
|
||||
break;
|
||||
if (TBL_CELL_DOWN != dp->layout->pos)
|
||||
if (dp->string)
|
||||
print_text(h, dp->string);
|
||||
dp = dp->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the time being, use the simplest possible
|
||||
* table styling: setting the widths of data
|
||||
* columns.
|
||||
*/
|
||||
|
||||
col = &h->tbl.cols[hp->ident];
|
||||
SCALE_HS_INIT(&su, col->width);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
tt = print_otag(h, TAG_TD, 1, &tag);
|
||||
|
||||
if (dp && dp->string)
|
||||
print_text(h, dp->string);
|
||||
if (dp)
|
||||
dp = dp->next;
|
||||
|
||||
print_tagq(h, tt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
h->flags &= ~HTML_NONOSPACE;
|
||||
|
||||
/* Close out column specifiers on the last span. */
|
||||
|
||||
if (TBL_SPAN_LAST & sp->flags) {
|
||||
assert(h->tbl.cols);
|
||||
free(h->tbl.cols);
|
||||
h->tbl.cols = NULL;
|
||||
print_tblclose(h);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
100
external/bsd/mdocml/dist/tbl_layout.c
vendored
100
external/bsd/mdocml/dist/tbl_layout.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: tbl_layout.c,v 1.13 2011/01/09 05:38:23 joerg Exp $ */
|
||||
/* $Vendor-Id: tbl_layout.c,v 1.22 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,10 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -68,6 +72,23 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
|||
char buf[5];
|
||||
int i;
|
||||
|
||||
/* Not all types accept modifiers. */
|
||||
|
||||
switch (cp->pos) {
|
||||
case (TBL_CELL_DOWN):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_DHORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_DVERT):
|
||||
return(1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mod:
|
||||
/*
|
||||
* XXX: since, at least for now, modifiers are non-conflicting
|
||||
|
@ -100,7 +121,8 @@ mod:
|
|||
(*pos)++;
|
||||
goto mod;
|
||||
}
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT,
|
||||
tbl->parse, ln, *pos, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -117,12 +139,13 @@ mod:
|
|||
/* No greater than 4 digits. */
|
||||
|
||||
if (4 == i) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
ln, *pos, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
*pos += i;
|
||||
cp->spacing = atoi(buf);
|
||||
cp->spacing = (size_t)atoi(buf);
|
||||
|
||||
goto mod;
|
||||
/* NOTREACHED */
|
||||
|
@ -150,28 +173,40 @@ mod:
|
|||
goto mod;
|
||||
case ('f'):
|
||||
break;
|
||||
case ('r'):
|
||||
/* FALLTHROUGH */
|
||||
case ('b'):
|
||||
/* FALLTHROUGH */
|
||||
case ('i'):
|
||||
(*pos)--;
|
||||
break;
|
||||
default:
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
switch (tolower((unsigned char)p[(*pos)++])) {
|
||||
case ('3'):
|
||||
/* FALLTHROUGH */
|
||||
case ('b'):
|
||||
cp->flags |= TBL_CELL_BOLD;
|
||||
goto mod;
|
||||
case ('2'):
|
||||
/* FALLTHROUGH */
|
||||
case ('i'):
|
||||
cp->flags |= TBL_CELL_ITALIC;
|
||||
goto mod;
|
||||
case ('1'):
|
||||
/* FALLTHROUGH */
|
||||
case ('r'):
|
||||
goto mod;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -189,7 +224,8 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
|||
break;
|
||||
|
||||
if (KEYS_MAX == i) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
ln, *pos, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -197,11 +233,38 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
|||
|
||||
/*
|
||||
* If a span cell is found first, raise a warning and abort the
|
||||
* parse. FIXME: recover from this somehow?
|
||||
* parse. If a span cell is found and the last layout element
|
||||
* isn't a "normal" layout, bail.
|
||||
*
|
||||
* FIXME: recover from this somehow?
|
||||
*/
|
||||
|
||||
if (NULL == rp->first && TBL_CELL_SPAN == c) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
if (TBL_CELL_SPAN == c) {
|
||||
if (NULL == rp->first) {
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
ln, *pos, NULL);
|
||||
return(0);
|
||||
} else if (rp->last)
|
||||
switch (rp->last->pos) {
|
||||
case (TBL_CELL_VERT):
|
||||
case (TBL_CELL_DVERT):
|
||||
case (TBL_CELL_HORIZ):
|
||||
case (TBL_CELL_DHORIZ):
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
ln, *pos, NULL);
|
||||
return(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If a vertical spanner is found, we may not be in the first
|
||||
* row.
|
||||
*/
|
||||
|
||||
if (TBL_CELL_DOWN == c && rp == tbl->first_row) {
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -219,7 +282,7 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
|||
if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) &&
|
||||
(TBL_CELL_VERT == rp->last->pos ||
|
||||
TBL_CELL_DVERT == rp->last->pos)) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -260,7 +323,8 @@ cell:
|
|||
if ('.' == p[*pos]) {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
if (NULL == tbl->first_row)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLNOLAYOUT, ln, *pos);
|
||||
mandoc_msg(MANDOCERR_TBLNOLAYOUT, tbl->parse,
|
||||
ln, *pos, NULL);
|
||||
(*pos)++;
|
||||
return;
|
||||
}
|
||||
|
@ -390,19 +454,19 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
|
|||
}
|
||||
|
||||
static void
|
||||
head_adjust(const struct tbl_cell *cell, struct tbl_head *head)
|
||||
head_adjust(const struct tbl_cell *cellp, struct tbl_head *head)
|
||||
{
|
||||
if (TBL_CELL_VERT != cell->pos &&
|
||||
TBL_CELL_DVERT != cell->pos) {
|
||||
if (TBL_CELL_VERT != cellp->pos &&
|
||||
TBL_CELL_DVERT != cellp->pos) {
|
||||
head->pos = TBL_HEAD_DATA;
|
||||
return;
|
||||
}
|
||||
|
||||
if (TBL_CELL_VERT == cell->pos)
|
||||
if (TBL_CELL_VERT == cellp->pos)
|
||||
if (TBL_HEAD_DVERT != head->pos)
|
||||
head->pos = TBL_HEAD_VERT;
|
||||
|
||||
if (TBL_CELL_DVERT == cell->pos)
|
||||
if (TBL_CELL_DVERT == cellp->pos)
|
||||
head->pos = TBL_HEAD_DVERT;
|
||||
}
|
||||
|
||||
|
|
34
external/bsd/mdocml/dist/tbl_opts.c
vendored
34
external/bsd/mdocml/dist/tbl_opts.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: tbl_opts.c,v 1.8 2011/01/09 05:38:23 joerg Exp $ */
|
||||
/* $Vendor-Id: tbl_opts.c,v 1.12 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,12 +14,17 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
enum tbl_ident {
|
||||
|
@ -88,7 +93,8 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||
/* Arguments always begin with a parenthesis. */
|
||||
|
||||
if ('(' != p[*pos]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||
ln, *pos, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -103,12 +109,14 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||
switch (key) {
|
||||
case (KEY_DELIM):
|
||||
if ('\0' == p[(*pos)++]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||
ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ('\0' == p[(*pos)++]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||
ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
|
@ -116,7 +124,8 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||
if ('\0' != (tbl->opts.tab = p[(*pos)++]))
|
||||
break;
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||
ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
case (KEY_LINESIZE):
|
||||
for (i = 0; i < KEY_MAXNUMSZ && p[*pos]; i++, (*pos)++) {
|
||||
|
@ -131,13 +140,14 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||
break;
|
||||
}
|
||||
|
||||
(*tbl->msg)(MANDOCERR_TBL, tbl->data, ln, *pos, NULL);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse, ln, *pos, NULL);
|
||||
return(0);
|
||||
case (KEY_DPOINT):
|
||||
if ('\0' != (tbl->opts.decimal = p[(*pos)++]))
|
||||
break;
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse,
|
||||
ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
default:
|
||||
abort();
|
||||
|
@ -149,7 +159,7 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
|||
if (')' == p[(*pos)++])
|
||||
return(1);
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse, ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -188,7 +198,7 @@ again: /*
|
|||
/* Copy up to first non-alpha character. */
|
||||
|
||||
for (sv = *pos, i = 0; i < KEY_MAXNAME; i++, (*pos)++) {
|
||||
buf[i] = tolower((unsigned char)p[*pos]);
|
||||
buf[i] = (char)tolower((unsigned char)p[*pos]);
|
||||
if ( ! isalpha((unsigned char)buf[i]))
|
||||
break;
|
||||
}
|
||||
|
@ -196,7 +206,7 @@ again: /*
|
|||
/* Exit if buffer is empty (or overrun). */
|
||||
|
||||
if (KEY_MAXNAME == i || 0 == i) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos);
|
||||
mandoc_msg(MANDOCERR_TBL, tbl->parse, ln, *pos, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -235,7 +245,7 @@ again: /*
|
|||
*/
|
||||
|
||||
if (KEY_MAXKEYS == i)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLOPT, ln, sv);
|
||||
mandoc_msg(MANDOCERR_TBLOPT, tbl->parse, ln, sv, NULL);
|
||||
|
||||
goto again;
|
||||
/* NOTREACHED */
|
||||
|
|
253
external/bsd/mdocml/dist/tbl_term.c
vendored
253
external/bsd/mdocml/dist/tbl_term.c
vendored
|
@ -1,6 +1,7 @@
|
|||
/* $Vendor-Id: tbl_term.c,v 1.13 2011/01/07 14:59:52 kristaps Exp $ */
|
||||
/* $Vendor-Id: tbl_term.c,v 1.21 2011/09/20 23:05:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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,23 +28,20 @@
|
|||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
/* FIXME: `n' modifier doesn't always do the right thing. */
|
||||
/* FIXME: `n' modifier doesn't use the cell-spacing buffer. */
|
||||
|
||||
static size_t term_tbl_len(size_t, void *);
|
||||
static size_t term_tbl_strlen(const char *, void *);
|
||||
static void tbl_char(struct termp *, char, size_t);
|
||||
static void tbl_data(struct termp *, const struct tbl *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_hframe(struct termp *, const struct tbl_span *);
|
||||
static size_t tbl_rulewidth(struct termp *, const struct tbl_head *);
|
||||
static void tbl_hframe(struct termp *, const struct tbl_span *, int);
|
||||
static void tbl_literal(struct termp *, const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_number(struct termp *, const struct tbl *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_hrule(struct termp *, const struct tbl_span *);
|
||||
static void tbl_vframe(struct termp *, const struct tbl *);
|
||||
static void tbl_vrule(struct termp *, const struct tbl_head *);
|
||||
|
||||
|
||||
|
@ -67,6 +65,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
const struct tbl_head *hp;
|
||||
const struct tbl_dat *dp;
|
||||
struct roffcol *col;
|
||||
int spans;
|
||||
size_t rmargin, maxrmargin;
|
||||
|
||||
rmargin = tp->rmargin;
|
||||
|
@ -96,12 +95,19 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
|
||||
/* Horizontal frame at the start of boxed tables. */
|
||||
|
||||
if (TBL_SPAN_FIRST & sp->flags)
|
||||
tbl_hframe(tp, sp);
|
||||
if (TBL_SPAN_FIRST & sp->flags) {
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts)
|
||||
tbl_hframe(tp, sp, 1);
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts ||
|
||||
TBL_OPT_BOX & sp->tbl->opts)
|
||||
tbl_hframe(tp, sp, 0);
|
||||
}
|
||||
|
||||
/* Vertical frame at the start of each row. */
|
||||
|
||||
tbl_vframe(tp, sp->tbl);
|
||||
if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts)
|
||||
term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
|
||||
TBL_SPAN_DHORIZ == sp->pos ? "+" : "|");
|
||||
|
||||
/*
|
||||
* Now print the actual data itself depending on the span type.
|
||||
|
@ -118,28 +124,70 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
case (TBL_SPAN_DATA):
|
||||
/* Iterate over template headers. */
|
||||
dp = sp->first;
|
||||
spans = 0;
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
/*
|
||||
* If the current data header is invoked during
|
||||
* a spanner ("spans" > 0), don't emit anything
|
||||
* at all.
|
||||
*/
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_DVERT):
|
||||
if (spans <= 0)
|
||||
tbl_vrule(tp, hp);
|
||||
continue;
|
||||
case (TBL_HEAD_DATA):
|
||||
break;
|
||||
}
|
||||
|
||||
if (--spans >= 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* All cells get a leading blank, except the
|
||||
* first one and those after double rulers.
|
||||
*/
|
||||
|
||||
if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
|
||||
tbl_char(tp, ASCII_NBRSP, 1);
|
||||
|
||||
col = &tp->tbl.cols[hp->ident];
|
||||
tbl_data(tp, sp->tbl, dp, col);
|
||||
|
||||
/* Go to the next data cell. */
|
||||
if (dp)
|
||||
/* No trailing blanks. */
|
||||
|
||||
if (NULL == hp->next)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Add another blank between cells,
|
||||
* or two when there is no vertical ruler.
|
||||
*/
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP,
|
||||
TBL_HEAD_VERT == hp->next->pos ||
|
||||
TBL_HEAD_DVERT == hp->next->pos ? 1 : 2);
|
||||
|
||||
/*
|
||||
* Go to the next data cell and assign the
|
||||
* number of subsequent spans, if applicable.
|
||||
*/
|
||||
|
||||
if (dp) {
|
||||
spans = dp->spans;
|
||||
dp = dp->next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
tbl_vframe(tp, sp->tbl);
|
||||
/* Vertical frame at the end of each row. */
|
||||
|
||||
if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts)
|
||||
term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
|
||||
TBL_SPAN_DHORIZ == sp->pos ? "+" : " |");
|
||||
term_flushln(tp);
|
||||
|
||||
/*
|
||||
|
@ -148,7 +196,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
*/
|
||||
|
||||
if (TBL_SPAN_LAST & sp->flags) {
|
||||
tbl_hframe(tp, sp);
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts ||
|
||||
TBL_OPT_BOX & sp->tbl->opts)
|
||||
tbl_hframe(tp, sp, 0);
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts)
|
||||
tbl_hframe(tp, sp, 1);
|
||||
assert(tp->tbl.cols);
|
||||
free(tp->tbl.cols);
|
||||
tp->tbl.cols = NULL;
|
||||
|
@ -160,84 +212,66 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizontal rules extend across the entire table.
|
||||
* Calculate the width by iterating over columns.
|
||||
*/
|
||||
static size_t
|
||||
tbl_rulewidth(struct termp *tp, const struct tbl_head *hp)
|
||||
{
|
||||
size_t width;
|
||||
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
if (TBL_HEAD_DATA == hp->pos) {
|
||||
/* Account for leading blanks. */
|
||||
if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
|
||||
width++;
|
||||
/* Account for trailing blanks. */
|
||||
width++;
|
||||
if (hp->next &&
|
||||
TBL_HEAD_VERT != hp->next->pos &&
|
||||
TBL_HEAD_DVERT != hp->next->pos)
|
||||
width++;
|
||||
}
|
||||
return(width);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rules inside the table can be single or double
|
||||
* and have crossings with vertical rules marked with pluses.
|
||||
*/
|
||||
static void
|
||||
tbl_hrule(struct termp *tp, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
char c;
|
||||
size_t width;
|
||||
|
||||
/*
|
||||
* An hrule extends across the entire table and is demarked by a
|
||||
* standalone `_' or whatnot in lieu of a table row. Spanning
|
||||
* headers are marked by a `+', as are table boundaries.
|
||||
*/
|
||||
|
||||
c = '-';
|
||||
if (TBL_SPAN_DHORIZ == sp->pos)
|
||||
c = '=';
|
||||
|
||||
/* FIXME: don't use `+' between data and a spanner! */
|
||||
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_DATA):
|
||||
tbl_char(tp, c, width);
|
||||
break;
|
||||
case (TBL_HEAD_DVERT):
|
||||
tbl_char(tp, '+', width);
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_VERT):
|
||||
tbl_char(tp, '+', width);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
for (hp = sp->head; hp; hp = hp->next)
|
||||
tbl_char(tp,
|
||||
TBL_HEAD_DATA == hp->pos ? c : '+',
|
||||
tbl_rulewidth(tp, hp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Rules above and below the table are always single
|
||||
* and have an additional plus at the beginning and end.
|
||||
* For double frames, this function is called twice,
|
||||
* and the outer one does not have crossings.
|
||||
*/
|
||||
static void
|
||||
tbl_hframe(struct termp *tp, const struct tbl_span *sp)
|
||||
tbl_hframe(struct termp *tp, const struct tbl_span *sp, int outer)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
size_t width;
|
||||
|
||||
if ( ! (TBL_OPT_BOX & sp->tbl->opts ||
|
||||
TBL_OPT_DBOX & sp->tbl->opts))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Print out the horizontal part of a frame or double frame. A
|
||||
* double frame has an unbroken `-' outer line the width of the
|
||||
* table, bordered by `+'. The frame (or inner frame, in the
|
||||
* case of the double frame) is a `-' bordered by `+' and broken
|
||||
* by `+' whenever a span is encountered.
|
||||
*/
|
||||
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts) {
|
||||
term_word(tp, "+");
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
tbl_char(tp, '-', width);
|
||||
}
|
||||
term_word(tp, "+");
|
||||
term_flushln(tp);
|
||||
}
|
||||
|
||||
term_word(tp, "+");
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_DATA):
|
||||
tbl_char(tp, '-', width);
|
||||
break;
|
||||
default:
|
||||
tbl_char(tp, '+', width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (hp = sp->head; hp; hp = hp->next)
|
||||
tbl_char(tp,
|
||||
outer || TBL_HEAD_DATA == hp->pos ? '-' : '+',
|
||||
tbl_rulewidth(tp, hp));
|
||||
term_word(tp, "+");
|
||||
term_flushln(tp);
|
||||
}
|
||||
|
@ -247,12 +281,12 @@ tbl_data(struct termp *tp, const struct tbl *tbl,
|
|||
const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
enum tbl_cellt pos;
|
||||
|
||||
if (NULL == dp) {
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
return;
|
||||
}
|
||||
assert(dp->layout);
|
||||
|
||||
switch (dp->pos) {
|
||||
case (TBL_DATA_NONE):
|
||||
|
@ -272,9 +306,7 @@ tbl_data(struct termp *tp, const struct tbl *tbl,
|
|||
break;
|
||||
}
|
||||
|
||||
pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT;
|
||||
|
||||
switch (pos) {
|
||||
switch (dp->layout->pos) {
|
||||
case (TBL_CELL_HORIZ):
|
||||
tbl_char(tp, '-', col->width);
|
||||
break;
|
||||
|
@ -293,6 +325,9 @@ tbl_data(struct termp *tp, const struct tbl *tbl,
|
|||
case (TBL_CELL_NUMBER):
|
||||
tbl_number(tp, tbl, dp, col);
|
||||
break;
|
||||
case (TBL_CELL_DOWN):
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
|
@ -315,14 +350,6 @@ tbl_vrule(struct termp *tp, const struct tbl_head *hp)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_vframe(struct termp *tp, const struct tbl *tbl)
|
||||
{
|
||||
|
||||
if (TBL_OPT_BOX & tbl->opts || TBL_OPT_DBOX & tbl->opts)
|
||||
term_word(tp, "|");
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_char(struct termp *tp, char c, size_t len)
|
||||
{
|
||||
|
@ -342,39 +369,34 @@ static void
|
|||
tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
size_t padl, padr, ssz;
|
||||
enum tbl_cellt pos;
|
||||
const char *str;
|
||||
size_t len, padl, padr;
|
||||
|
||||
padl = padr = 0;
|
||||
assert(dp->string);
|
||||
len = term_strlen(tp, dp->string);
|
||||
padr = col->width > len ? col->width - len : 0;
|
||||
padl = 0;
|
||||
|
||||
pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT;
|
||||
str = dp && dp->string ? dp->string : "";
|
||||
|
||||
ssz = term_len(tp, 1);
|
||||
|
||||
switch (pos) {
|
||||
switch (dp->layout->pos) {
|
||||
case (TBL_CELL_LONG):
|
||||
padl = ssz;
|
||||
padr = col->width - term_strlen(tp, str) - ssz;
|
||||
padl = term_len(tp, 1);
|
||||
padr = padr > padl ? padr - padl : 0;
|
||||
break;
|
||||
case (TBL_CELL_CENTRE):
|
||||
padl = col->width - term_strlen(tp, str);
|
||||
if (padl % 2)
|
||||
padr++;
|
||||
padl /= 2;
|
||||
padr += padl;
|
||||
if (2 > padr)
|
||||
break;
|
||||
padl = padr / 2;
|
||||
padr -= padl;
|
||||
break;
|
||||
case (TBL_CELL_RIGHT):
|
||||
padl = col->width - term_strlen(tp, str);
|
||||
padl = padr;
|
||||
padr = 0;
|
||||
break;
|
||||
default:
|
||||
padr = col->width - term_strlen(tp, str);
|
||||
break;
|
||||
}
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP, padl);
|
||||
term_word(tp, str);
|
||||
term_word(tp, dp->string);
|
||||
tbl_char(tp, ASCII_NBRSP, padr);
|
||||
}
|
||||
|
||||
|
@ -385,7 +407,6 @@ tbl_number(struct termp *tp, const struct tbl *tbl,
|
|||
{
|
||||
char *cp;
|
||||
char buf[2];
|
||||
const char *str;
|
||||
size_t sz, psz, ssz, d, padl;
|
||||
int i;
|
||||
|
||||
|
@ -394,32 +415,30 @@ tbl_number(struct termp *tp, const struct tbl *tbl,
|
|||
* and the maximum decimal; right-pad by the remaining amount.
|
||||
*/
|
||||
|
||||
str = dp && dp->string ? dp->string : "";
|
||||
assert(dp->string);
|
||||
|
||||
sz = term_strlen(tp, str);
|
||||
sz = term_strlen(tp, dp->string);
|
||||
|
||||
buf[0] = tbl->decimal;
|
||||
buf[1] = '\0';
|
||||
|
||||
psz = term_strlen(tp, buf);
|
||||
|
||||
if (NULL != (cp = strchr(str, tbl->decimal))) {
|
||||
if (NULL != (cp = strrchr(dp->string, tbl->decimal))) {
|
||||
buf[1] = '\0';
|
||||
for (ssz = 0, i = 0; cp != &str[i]; i++) {
|
||||
buf[0] = str[i];
|
||||
for (ssz = 0, i = 0; cp != &dp->string[i]; i++) {
|
||||
buf[0] = dp->string[i];
|
||||
ssz += term_strlen(tp, buf);
|
||||
}
|
||||
d = ssz + psz;
|
||||
} else
|
||||
d = sz + psz;
|
||||
|
||||
sz += term_len(tp, 2);
|
||||
d += term_len(tp, 1);
|
||||
|
||||
padl = col->decimal - d;
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP, padl);
|
||||
term_word(tp, str);
|
||||
term_word(tp, dp->string);
|
||||
if (col->width > sz + padl)
|
||||
tbl_char(tp, ASCII_NBRSP, col->width - sz - padl);
|
||||
}
|
||||
|
||||
|
|
408
external/bsd/mdocml/dist/term.c
vendored
408
external/bsd/mdocml/dist/term.c
vendored
|
@ -1,7 +1,7 @@
|
|||
/* $Vendor-Id: term.c,v 1.176 2011/01/04 13:14:26 kristaps Exp $ */
|
||||
/* $Vendor-Id: term.c,v 1.201 2011/09/21 09:57:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 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
|
||||
|
@ -29,18 +29,14 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "chars.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "main.h"
|
||||
|
||||
static void spec(struct termp *, enum roffdeco,
|
||||
const char *, size_t);
|
||||
static void res(struct termp *, const char *, size_t);
|
||||
static void adjbuf(struct termp *p, int);
|
||||
static void bufferc(struct termp *, char);
|
||||
static void adjbuf(struct termp *p, size_t);
|
||||
static void encode(struct termp *, const char *, size_t);
|
||||
|
||||
static void encode1(struct termp *, int);
|
||||
|
||||
void
|
||||
term_free(struct termp *p)
|
||||
|
@ -49,7 +45,7 @@ term_free(struct termp *p)
|
|||
if (p->buf)
|
||||
free(p->buf);
|
||||
if (p->symtab)
|
||||
chars_free(p->symtab);
|
||||
mchars_free(p->symtab);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
@ -74,23 +70,6 @@ term_end(struct termp *p)
|
|||
(*p->end)(p);
|
||||
}
|
||||
|
||||
|
||||
struct termp *
|
||||
term_alloc(enum termenc enc)
|
||||
{
|
||||
struct termp *p;
|
||||
|
||||
p = calloc(1, sizeof(struct termp));
|
||||
if (NULL == p) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
p->enc = enc;
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flush a line of text. A "line" is loosely defined as being something
|
||||
* that should be followed by a newline, regardless of whether it's
|
||||
|
@ -100,22 +79,18 @@ term_alloc(enum termenc enc)
|
|||
*
|
||||
* The following flags may be specified:
|
||||
*
|
||||
* - TERMP_NOLPAD: when beginning to write the line, don't left-pad the
|
||||
* offset value. This is useful when doing columnar lists where the
|
||||
* prior column has right-padded.
|
||||
*
|
||||
* - TERMP_NOBREAK: this is the most important and is used when making
|
||||
* columns. In short: don't print a newline and instead pad to the
|
||||
* right margin. Used in conjunction with TERMP_NOLPAD.
|
||||
* columns. In short: don't print a newline and instead expect the
|
||||
* next call to do the padding up to the start of the next column.
|
||||
*
|
||||
* - TERMP_TWOSPACE: when padding, make sure there are at least two
|
||||
* space characters of padding. Otherwise, rather break the line.
|
||||
* - TERMP_TWOSPACE: make sure there is room for at least two space
|
||||
* characters of padding. Otherwise, rather break the line.
|
||||
*
|
||||
* - TERMP_DANGLE: don't newline when TERMP_NOBREAK is specified and
|
||||
* the line is overrun, and don't pad-right if it's underrun.
|
||||
*
|
||||
* - TERMP_HANG: like TERMP_DANGLE, but doesn't newline when
|
||||
* overruning, instead save the position and continue at that point
|
||||
* overrunning, instead save the position and continue at that point
|
||||
* when the next invocation.
|
||||
*
|
||||
* In-line line breaking:
|
||||
|
@ -155,19 +130,20 @@ term_flushln(struct termp *p)
|
|||
bp = TERMP_NOBREAK & p->flags ? mmax : maxvis;
|
||||
|
||||
/*
|
||||
* Indent the first line of a paragraph.
|
||||
* Calculate the required amount of padding.
|
||||
*/
|
||||
vbl = p->flags & TERMP_NOLPAD ? (size_t)0 : p->offset;
|
||||
vbl = p->offset + p->overstep > p->viscol ?
|
||||
p->offset + p->overstep - p->viscol : 0;
|
||||
|
||||
vis = vend = 0;
|
||||
i = 0;
|
||||
|
||||
while (i < (int)p->col) {
|
||||
while (i < p->col) {
|
||||
/*
|
||||
* Handle literal tab characters: collapse all
|
||||
* subsequent tabs into a single huge set of spaces.
|
||||
*/
|
||||
while (i < (int)p->col && '\t' == p->buf[i]) {
|
||||
while (i < p->col && '\t' == p->buf[i]) {
|
||||
vend = (vis / p->tabwidth + 1) * p->tabwidth;
|
||||
vbl += vend - vis;
|
||||
vis = vend;
|
||||
|
@ -181,7 +157,7 @@ term_flushln(struct termp *p)
|
|||
* space is printed according to regular spacing rules).
|
||||
*/
|
||||
|
||||
for (j = i, jhy = 0; j < (int)p->col; j++) {
|
||||
for (j = i, jhy = 0; j < p->col; j++) {
|
||||
if ((j && ' ' == p->buf[j]) || '\t' == p->buf[j])
|
||||
break;
|
||||
|
||||
|
@ -208,14 +184,12 @@ term_flushln(struct termp *p)
|
|||
if (vend > bp && 0 == jhy && vis > 0) {
|
||||
vend -= vis;
|
||||
(*p->endline)(p);
|
||||
if (TERMP_NOBREAK & p->flags) {
|
||||
p->viscol = p->rmargin;
|
||||
(*p->advance)(p, p->rmargin);
|
||||
vend += p->rmargin - p->offset;
|
||||
} else {
|
||||
p->viscol = 0;
|
||||
if (TERMP_NOBREAK & p->flags) {
|
||||
vbl = p->rmargin;
|
||||
vend += p->rmargin - p->offset;
|
||||
} else
|
||||
vbl = p->offset;
|
||||
}
|
||||
|
||||
/* Remove the p->overstep width. */
|
||||
|
||||
|
@ -224,7 +198,7 @@ term_flushln(struct termp *p)
|
|||
}
|
||||
|
||||
/* Write out the [remaining] word. */
|
||||
for ( ; i < (int)p->col; i++) {
|
||||
for ( ; i < p->col; i++) {
|
||||
if (vend > bp && jhy > 0 && i > jhy)
|
||||
break;
|
||||
if ('\t' == p->buf[i])
|
||||
|
@ -257,10 +231,14 @@ term_flushln(struct termp *p)
|
|||
if (ASCII_HYPH == p->buf[i]) {
|
||||
(*p->letter)(p, '-');
|
||||
p->viscol += (*p->width)(p, '-');
|
||||
} else {
|
||||
(*p->letter)(p, p->buf[i]);
|
||||
p->viscol += (*p->width)(p, p->buf[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
(*p->letter)(p, p->buf[i]);
|
||||
if (8 == p->buf[i])
|
||||
p->viscol -= (*p->width)(p, p->buf[i-1]);
|
||||
else
|
||||
p->viscol += (*p->width)(p, p->buf[i]);
|
||||
}
|
||||
vis = vend;
|
||||
}
|
||||
|
@ -269,6 +247,7 @@ term_flushln(struct termp *p)
|
|||
* If there was trailing white space, it was not printed;
|
||||
* so reset the cursor position accordingly.
|
||||
*/
|
||||
if (vis)
|
||||
vis -= vbl;
|
||||
|
||||
p->col = 0;
|
||||
|
@ -294,25 +273,18 @@ term_flushln(struct termp *p)
|
|||
* move it one step LEFT and flag the rest of the line
|
||||
* to be longer.
|
||||
*/
|
||||
if (p->overstep >= -1) {
|
||||
assert((int)maxvis + p->overstep >= 0);
|
||||
maxvis += (size_t)p->overstep;
|
||||
} else
|
||||
if (p->overstep < -1)
|
||||
p->overstep = 0;
|
||||
return;
|
||||
|
||||
} else if (TERMP_DANGLE & p->flags)
|
||||
return;
|
||||
|
||||
/* Right-pad. */
|
||||
if (maxvis > vis +
|
||||
/* If the column was overrun, break the line. */
|
||||
if (maxvis <= vis +
|
||||
((TERMP_TWOSPACE & p->flags) ? (*p->width)(p, ' ') : 0)) {
|
||||
p->viscol += maxvis - vis;
|
||||
(*p->advance)(p, maxvis - vis);
|
||||
vis += (maxvis - vis);
|
||||
} else { /* ...or newline break. */
|
||||
(*p->endline)(p);
|
||||
p->viscol = p->rmargin;
|
||||
(*p->advance)(p, p->rmargin);
|
||||
p->viscol = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,12 +299,8 @@ term_newln(struct termp *p)
|
|||
{
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (0 == p->col && 0 == p->viscol) {
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
return;
|
||||
}
|
||||
if (p->col || p->viscol)
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
}
|
||||
|
||||
|
||||
|
@ -351,33 +319,6 @@ term_vspace(struct termp *p)
|
|||
(*p->endline)(p);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
spec(struct termp *p, enum roffdeco d, const char *word, size_t len)
|
||||
{
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
rhs = chars_spec2str(p->symtab, word, len, &sz);
|
||||
if (rhs)
|
||||
encode(p, rhs, sz);
|
||||
else if (DECO_SSPECIAL == d)
|
||||
encode(p, word, len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
res(struct termp *p, const char *word, size_t len)
|
||||
{
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
rhs = chars_res2str(p->symtab, word, len, &sz);
|
||||
if (rhs)
|
||||
encode(p, rhs, sz);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_fontlast(struct termp *p)
|
||||
{
|
||||
|
@ -442,7 +383,6 @@ term_fontpop(struct termp *p)
|
|||
p->fonti--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle pwords, partial words, which may be either a single word or a
|
||||
* phrase that cannot be broken down (such as a literal string). This
|
||||
|
@ -451,35 +391,11 @@ term_fontpop(struct termp *p)
|
|||
void
|
||||
term_word(struct termp *p, const char *word)
|
||||
{
|
||||
const char *sv, *seq;
|
||||
const char *seq, *cp;
|
||||
char c;
|
||||
int sz, uc;
|
||||
size_t ssz;
|
||||
enum roffdeco deco;
|
||||
|
||||
sv = word;
|
||||
|
||||
if (word[0] && '\0' == word[1])
|
||||
switch (word[0]) {
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
if ( ! (TERMP_IGNDELIM & p->flags))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
enum mandoc_esc esc;
|
||||
|
||||
if ( ! (TERMP_NOSPACE & p->flags)) {
|
||||
if ( ! (TERMP_KEEP & p->flags)) {
|
||||
|
@ -499,65 +415,79 @@ term_word(struct termp *p, const char *word)
|
|||
|
||||
p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
|
||||
|
||||
while (*word) {
|
||||
while ('\0' != *word) {
|
||||
if ((ssz = strcspn(word, "\\")) > 0)
|
||||
encode(p, word, ssz);
|
||||
|
||||
word += ssz;
|
||||
word += (int)ssz;
|
||||
if ('\\' != *word)
|
||||
continue;
|
||||
|
||||
seq = ++word;
|
||||
word += a2roffdeco(&deco, &seq, &ssz);
|
||||
word++;
|
||||
esc = mandoc_escape(&word, &seq, &sz);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
break;
|
||||
|
||||
switch (deco) {
|
||||
case (DECO_RESERVED):
|
||||
res(p, seq, ssz);
|
||||
if (TERMENC_ASCII != p->enc)
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
uc = mchars_num2uc(seq + 1, sz - 1);
|
||||
if ('\0' == uc)
|
||||
break;
|
||||
case (DECO_SPECIAL):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_SSPECIAL):
|
||||
spec(p, deco, seq, ssz);
|
||||
encode1(p, uc);
|
||||
continue;
|
||||
case (ESCAPE_SPECIAL):
|
||||
uc = mchars_spec2cp(p->symtab, seq, sz);
|
||||
if (uc <= 0)
|
||||
break;
|
||||
case (DECO_BOLD):
|
||||
encode1(p, uc);
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
encode1(p, '?');
|
||||
break;
|
||||
case (ESCAPE_NUMBERED):
|
||||
c = mchars_num2char(seq, sz);
|
||||
if ('\0' != c)
|
||||
encode(p, &c, 1);
|
||||
break;
|
||||
case (ESCAPE_SPECIAL):
|
||||
cp = mchars_spec2str(p->symtab, seq, sz, &ssz);
|
||||
if (NULL != cp)
|
||||
encode(p, cp, ssz);
|
||||
else if (1 == ssz)
|
||||
encode(p, seq, sz);
|
||||
break;
|
||||
case (ESCAPE_FONTBOLD):
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case (DECO_ITALIC):
|
||||
case (ESCAPE_FONTITALIC):
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
break;
|
||||
case (DECO_ROMAN):
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
break;
|
||||
case (DECO_PREVIOUS):
|
||||
case (ESCAPE_FONTPREV):
|
||||
term_fontlast(p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (DECO_NOSPACE == deco && '\0' == *word)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that we don't process the pipe: the parser sees it as
|
||||
* punctuation, but we don't in terms of typography.
|
||||
*/
|
||||
if (sv[0] && '\0' == sv[1])
|
||||
switch (sv[0]) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
case (ESCAPE_NOSPACE):
|
||||
if ('\0' == *word)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
adjbuf(struct termp *p, size_t sz)
|
||||
adjbuf(struct termp *p, int sz)
|
||||
{
|
||||
|
||||
if (0 == p->maxcols)
|
||||
|
@ -565,14 +495,10 @@ adjbuf(struct termp *p, size_t sz)
|
|||
while (sz >= p->maxcols)
|
||||
p->maxcols <<= 2;
|
||||
|
||||
p->buf = realloc(p->buf, p->maxcols);
|
||||
if (NULL == p->buf) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
p->buf = mandoc_realloc
|
||||
(p->buf, sizeof(int) * (size_t)p->maxcols);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bufferc(struct termp *p, char c)
|
||||
{
|
||||
|
@ -580,15 +506,44 @@ bufferc(struct termp *p, char c)
|
|||
if (p->col + 1 >= p->maxcols)
|
||||
adjbuf(p, p->col + 1);
|
||||
|
||||
p->buf[(int)p->col++] = c;
|
||||
p->buf[p->col++] = c;
|
||||
}
|
||||
|
||||
/*
|
||||
* See encode().
|
||||
* Do this for a single (probably unicode) value.
|
||||
* Does not check for non-decorated glyphs.
|
||||
*/
|
||||
static void
|
||||
encode1(struct termp *p, int c)
|
||||
{
|
||||
enum termfont f;
|
||||
|
||||
if (p->col + 4 >= p->maxcols)
|
||||
adjbuf(p, p->col + 4);
|
||||
|
||||
f = term_fonttop(p);
|
||||
|
||||
if (TERMFONT_NONE == f) {
|
||||
p->buf[p->col++] = c;
|
||||
return;
|
||||
} else if (TERMFONT_UNDER == f) {
|
||||
p->buf[p->col++] = '_';
|
||||
} else
|
||||
p->buf[p->col++] = c;
|
||||
|
||||
p->buf[p->col++] = 8;
|
||||
p->buf[p->col++] = c;
|
||||
}
|
||||
|
||||
static void
|
||||
encode(struct termp *p, const char *word, size_t sz)
|
||||
{
|
||||
enum termfont f;
|
||||
int i;
|
||||
int i, len;
|
||||
|
||||
/* LINTED */
|
||||
len = sz;
|
||||
|
||||
/*
|
||||
* Encode and buffer a string of characters. If the current
|
||||
|
@ -597,35 +552,37 @@ encode(struct termp *p, const char *word, size_t sz)
|
|||
*/
|
||||
|
||||
if (TERMFONT_NONE == (f = term_fonttop(p))) {
|
||||
if (p->col + sz >= p->maxcols)
|
||||
adjbuf(p, p->col + sz);
|
||||
memcpy(&p->buf[(int)p->col], word, sz);
|
||||
p->col += sz;
|
||||
if (p->col + len >= p->maxcols)
|
||||
adjbuf(p, p->col + len);
|
||||
for (i = 0; i < len; i++)
|
||||
p->buf[p->col++] = word[i];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pre-buffer, assuming worst-case. */
|
||||
|
||||
if (p->col + 1 + (sz * 3) >= p->maxcols)
|
||||
adjbuf(p, p->col + 1 + (sz * 3));
|
||||
if (p->col + 1 + (len * 3) >= p->maxcols)
|
||||
adjbuf(p, p->col + 1 + (len * 3));
|
||||
|
||||
for (i = 0; i < (int)sz; i++) {
|
||||
if ( ! isgraph((u_char)word[i])) {
|
||||
p->buf[(int)p->col++] = word[i];
|
||||
for (i = 0; i < len; i++) {
|
||||
if (ASCII_HYPH != word[i] &&
|
||||
! isgraph((unsigned char)word[i])) {
|
||||
p->buf[p->col++] = word[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TERMFONT_UNDER == f)
|
||||
p->buf[(int)p->col++] = '_';
|
||||
p->buf[p->col++] = '_';
|
||||
else if (ASCII_HYPH == word[i])
|
||||
p->buf[p->col++] = '-';
|
||||
else
|
||||
p->buf[(int)p->col++] = word[i];
|
||||
p->buf[p->col++] = word[i];
|
||||
|
||||
p->buf[(int)p->col++] = 8;
|
||||
p->buf[(int)p->col++] = word[i];
|
||||
p->buf[p->col++] = 8;
|
||||
p->buf[p->col++] = word[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
term_len(const struct termp *p, size_t sz)
|
||||
{
|
||||
|
@ -637,59 +594,99 @@ term_len(const struct termp *p, size_t sz)
|
|||
size_t
|
||||
term_strlen(const struct termp *p, const char *cp)
|
||||
{
|
||||
size_t sz, ssz, rsz, i;
|
||||
enum roffdeco d;
|
||||
size_t sz, rsz, i;
|
||||
int ssz, c;
|
||||
const char *seq, *rhs;
|
||||
enum mandoc_esc esc;
|
||||
static const char rej[] = { '\\', ASCII_HYPH, ASCII_NBRSP, '\0' };
|
||||
|
||||
for (sz = 0; '\0' != *cp; )
|
||||
/*
|
||||
* Account for escaped sequences within string length
|
||||
* calculations. This follows the logic in term_word()
|
||||
* as we must calculate the width of produced strings.
|
||||
* calculations. This follows the logic in term_word() as we
|
||||
* must calculate the width of produced strings.
|
||||
*/
|
||||
if ('\\' == *cp) {
|
||||
seq = ++cp;
|
||||
cp += a2roffdeco(&d, &seq, &ssz);
|
||||
|
||||
switch (d) {
|
||||
case (DECO_RESERVED):
|
||||
rhs = chars_res2str
|
||||
(p->symtab, seq, ssz, &rsz);
|
||||
sz = 0;
|
||||
while ('\0' != *cp) {
|
||||
rsz = strcspn(cp, rej);
|
||||
for (i = 0; i < rsz; i++)
|
||||
sz += (*p->width)(p, *cp++);
|
||||
|
||||
c = 0;
|
||||
switch (*cp) {
|
||||
case ('\\'):
|
||||
cp++;
|
||||
esc = mandoc_escape(&cp, &seq, &ssz);
|
||||
if (ESCAPE_ERROR == esc)
|
||||
return(sz);
|
||||
|
||||
if (TERMENC_ASCII != p->enc)
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
c = mchars_num2uc
|
||||
(seq + 1, ssz - 1);
|
||||
if ('\0' == c)
|
||||
break;
|
||||
case (DECO_SPECIAL):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_SSPECIAL):
|
||||
rhs = chars_spec2str
|
||||
sz += (*p->width)(p, c);
|
||||
continue;
|
||||
case (ESCAPE_SPECIAL):
|
||||
c = mchars_spec2cp
|
||||
(p->symtab, seq, ssz);
|
||||
if (c <= 0)
|
||||
break;
|
||||
sz += (*p->width)(p, c);
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rhs = NULL;
|
||||
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
sz += (*p->width)(p, '?');
|
||||
break;
|
||||
case (ESCAPE_NUMBERED):
|
||||
c = mchars_num2char(seq, ssz);
|
||||
if ('\0' != c)
|
||||
sz += (*p->width)(p, c);
|
||||
break;
|
||||
case (ESCAPE_SPECIAL):
|
||||
rhs = mchars_spec2str
|
||||
(p->symtab, seq, ssz, &rsz);
|
||||
|
||||
/* Allow for one-char escapes. */
|
||||
if (DECO_SSPECIAL != d || rhs)
|
||||
if (ssz != 1 || rhs)
|
||||
break;
|
||||
|
||||
rhs = seq;
|
||||
rsz = ssz;
|
||||
break;
|
||||
default:
|
||||
rhs = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rhs)
|
||||
if (NULL == rhs)
|
||||
break;
|
||||
|
||||
for (i = 0; i < rsz; i++)
|
||||
sz += (*p->width)(p, *rhs++);
|
||||
} else if (ASCII_NBRSP == *cp) {
|
||||
break;
|
||||
case (ASCII_NBRSP):
|
||||
sz += (*p->width)(p, ' ');
|
||||
cp++;
|
||||
} else if (ASCII_HYPH == *cp) {
|
||||
break;
|
||||
case (ASCII_HYPH):
|
||||
sz += (*p->width)(p, '-');
|
||||
cp++;
|
||||
} else
|
||||
sz += (*p->width)(p, *cp++);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(sz);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
size_t
|
||||
term_vspan(const struct termp *p, const struct roffsu *su)
|
||||
|
@ -726,7 +723,6 @@ term_vspan(const struct termp *p, const struct roffsu *su)
|
|||
r);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
term_hspan(const struct termp *p, const struct roffsu *su)
|
||||
{
|
||||
|
|
58
external/bsd/mdocml/dist/term.h
vendored
58
external/bsd/mdocml/dist/term.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: term.h,v 1.79 2011/01/05 15:37:23 kristaps Exp $ */
|
||||
/* $Vendor-Id: term.h,v 1.90 2011/12/04 23:10:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -22,7 +22,9 @@ __BEGIN_DECLS
|
|||
struct termp;
|
||||
|
||||
enum termenc {
|
||||
TERMENC_ASCII
|
||||
TERMENC_ASCII,
|
||||
TERMENC_LOCALE,
|
||||
TERMENC_UTF8
|
||||
};
|
||||
|
||||
enum termtype {
|
||||
|
@ -42,35 +44,6 @@ enum termfont {
|
|||
|
||||
typedef void (*term_margin)(struct termp *, const void *);
|
||||
|
||||
struct termp_ps {
|
||||
int flags;
|
||||
#define PS_INLINE (1 << 0) /* we're in a word */
|
||||
#define PS_MARGINS (1 << 1) /* we're in the margins */
|
||||
#define PS_NEWPAGE (1 << 2) /* new page, no words yet */
|
||||
size_t pscol; /* visible column (AFM units) */
|
||||
size_t psrow; /* visible row (AFM units) */
|
||||
char *psmarg; /* margin buf */
|
||||
size_t psmargsz; /* margin buf size */
|
||||
size_t psmargcur; /* cur index in margin buf */
|
||||
char last; /* character buffer */
|
||||
enum termfont lastf; /* last set font */
|
||||
size_t scale; /* font scaling factor */
|
||||
size_t pages; /* number of pages shown */
|
||||
size_t lineheight; /* line height (AFM units) */
|
||||
size_t top; /* body top (AFM units) */
|
||||
size_t bottom; /* body bottom (AFM units) */
|
||||
size_t height; /* page height (AFM units */
|
||||
size_t width; /* page width (AFM units) */
|
||||
size_t left; /* body left (AFM units) */
|
||||
size_t header; /* header pos (AFM units) */
|
||||
size_t footer; /* footer pos (AFM units) */
|
||||
size_t pdfbytes; /* current output byte */
|
||||
size_t pdflastpg; /* byte of last page mark */
|
||||
size_t pdfbody; /* start of body object */
|
||||
size_t *pdfobjs; /* table of object offsets */
|
||||
size_t pdfobjsz; /* size of pdfobjs */
|
||||
};
|
||||
|
||||
struct termp_tbl {
|
||||
int width; /* width in fixed chars */
|
||||
int decimal; /* decimal point position */
|
||||
|
@ -79,19 +52,20 @@ struct termp_tbl {
|
|||
struct termp {
|
||||
enum termtype type;
|
||||
struct rofftbl tbl; /* table configuration */
|
||||
int mdocstyle; /* imitate mdoc(7) output */
|
||||
size_t defindent; /* Default indent for text. */
|
||||
size_t defrmargin; /* Right margin of the device. */
|
||||
size_t rmargin; /* Current right margin. */
|
||||
size_t maxrmargin; /* Max right margin. */
|
||||
size_t maxcols; /* Max size of buf. */
|
||||
int maxcols; /* Max size of buf. */
|
||||
size_t offset; /* Margin offest. */
|
||||
size_t tabwidth; /* Distance of tab positions. */
|
||||
size_t col; /* Bytes in buf. */
|
||||
int col; /* Bytes in buf. */
|
||||
size_t viscol; /* Chars on current line. */
|
||||
int overstep; /* See termp_flushln(). */
|
||||
int flags;
|
||||
#define TERMP_SENTENCE (1 << 1) /* Space before a sentence. */
|
||||
#define TERMP_NOSPACE (1 << 2) /* No space before words. */
|
||||
#define TERMP_NOLPAD (1 << 3) /* See term_flushln(). */
|
||||
#define TERMP_NOBREAK (1 << 4) /* See term_flushln(). */
|
||||
#define TERMP_IGNDELIM (1 << 6) /* Delims like regulars. */
|
||||
#define TERMP_NONOSPACE (1 << 7) /* No space (no autounset). */
|
||||
|
@ -103,29 +77,27 @@ struct termp {
|
|||
#define TERMP_ANPREC (1 << 13) /* See termp_an_pre(). */
|
||||
#define TERMP_KEEP (1 << 14) /* Keep words together. */
|
||||
#define TERMP_PREKEEP (1 << 15) /* ...starting with the next one. */
|
||||
char *buf; /* Output buffer. */
|
||||
int *buf; /* Output buffer. */
|
||||
enum termenc enc; /* Type of encoding. */
|
||||
void *symtab; /* Encoded-symbol table. */
|
||||
struct mchars *symtab; /* Encoded-symbol table. */
|
||||
enum termfont fontl; /* Last font set. */
|
||||
enum termfont fontq[10]; /* Symmetric fonts. */
|
||||
int fonti; /* Index of font stack. */
|
||||
term_margin headf; /* invoked to print head */
|
||||
term_margin footf; /* invoked to print foot */
|
||||
void (*letter)(struct termp *, char);
|
||||
void (*letter)(struct termp *, int);
|
||||
void (*begin)(struct termp *);
|
||||
void (*end)(struct termp *);
|
||||
void (*endline)(struct termp *);
|
||||
void (*advance)(struct termp *, size_t);
|
||||
size_t (*width)(const struct termp *, char);
|
||||
size_t (*width)(const struct termp *, int);
|
||||
double (*hspan)(const struct termp *,
|
||||
const struct roffsu *);
|
||||
const void *argf; /* arg for headf/footf */
|
||||
union {
|
||||
struct termp_ps ps;
|
||||
} engine;
|
||||
struct termp_ps *ps;
|
||||
};
|
||||
|
||||
struct termp *term_alloc(enum termenc);
|
||||
void term_eqn(struct termp *, const struct eqn *);
|
||||
void term_tbl(struct termp *, const struct tbl_span *);
|
||||
void term_free(struct termp *);
|
||||
void term_newln(struct termp *);
|
||||
|
|
154
external/bsd/mdocml/dist/term_ascii.c
vendored
154
external/bsd/mdocml/dist/term_ascii.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/* $Vendor-Id: term_ascii.c,v 1.11 2011/01/02 12:21:07 kristaps Exp $ */
|
||||
/* $Vendor-Id: term_ascii.c,v 1.20 2011/12/04 23:10:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -21,56 +21,110 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef USE_WCHAR
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#ifdef USE_WCHAR
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "main.h"
|
||||
|
||||
/*
|
||||
* Sadly, this doesn't seem to be defined on systems even when they
|
||||
* support it. For the time being, remove it and let those compiling
|
||||
* the software decide for themselves what to use.
|
||||
*/
|
||||
#if 0
|
||||
#if ! defined(__STDC_ISO_10646__)
|
||||
# undef USE_WCHAR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static struct termp *ascii_init(enum termenc, char *);
|
||||
static double ascii_hspan(const struct termp *,
|
||||
const struct roffsu *);
|
||||
static size_t ascii_width(const struct termp *, char);
|
||||
static size_t ascii_width(const struct termp *, int);
|
||||
static void ascii_advance(struct termp *, size_t);
|
||||
static void ascii_begin(struct termp *);
|
||||
static void ascii_end(struct termp *);
|
||||
static void ascii_endline(struct termp *);
|
||||
static void ascii_letter(struct termp *, char);
|
||||
static void ascii_letter(struct termp *, int);
|
||||
|
||||
#ifdef USE_WCHAR
|
||||
static void locale_advance(struct termp *, size_t);
|
||||
static void locale_endline(struct termp *);
|
||||
static void locale_letter(struct termp *, int);
|
||||
static size_t locale_width(const struct termp *, int);
|
||||
#endif
|
||||
|
||||
void *
|
||||
ascii_alloc(char *outopts)
|
||||
static struct termp *
|
||||
ascii_init(enum termenc enc, char *outopts)
|
||||
{
|
||||
struct termp *p;
|
||||
const char *toks[2];
|
||||
const char *toks[4];
|
||||
char *v;
|
||||
struct termp *p;
|
||||
|
||||
if (NULL == (p = term_alloc(TERMENC_ASCII)))
|
||||
return(NULL);
|
||||
p = mandoc_calloc(1, sizeof(struct termp));
|
||||
p->enc = enc;
|
||||
|
||||
p->tabwidth = 5;
|
||||
p->defrmargin = 78;
|
||||
|
||||
p->advance = ascii_advance;
|
||||
p->begin = ascii_begin;
|
||||
p->end = ascii_end;
|
||||
p->endline = ascii_endline;
|
||||
p->hspan = ascii_hspan;
|
||||
p->letter = ascii_letter;
|
||||
p->type = TERMTYPE_CHAR;
|
||||
|
||||
p->enc = TERMENC_ASCII;
|
||||
p->advance = ascii_advance;
|
||||
p->endline = ascii_endline;
|
||||
p->letter = ascii_letter;
|
||||
p->width = ascii_width;
|
||||
|
||||
toks[0] = "width";
|
||||
toks[1] = NULL;
|
||||
#ifdef USE_WCHAR
|
||||
if (TERMENC_ASCII != enc) {
|
||||
v = TERMENC_LOCALE == enc ?
|
||||
setlocale(LC_ALL, "") :
|
||||
setlocale(LC_CTYPE, "UTF-8");
|
||||
if (NULL != v && MB_CUR_MAX > 1) {
|
||||
p->enc = enc;
|
||||
p->advance = locale_advance;
|
||||
p->endline = locale_endline;
|
||||
p->letter = locale_letter;
|
||||
p->width = locale_width;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
toks[0] = "indent";
|
||||
toks[1] = "width";
|
||||
toks[2] = "mdoc";
|
||||
toks[3] = NULL;
|
||||
|
||||
while (outopts && *outopts)
|
||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||
case (0):
|
||||
p->defindent = (size_t)atoi(v);
|
||||
break;
|
||||
case (1):
|
||||
p->defrmargin = (size_t)atoi(v);
|
||||
break;
|
||||
case (2):
|
||||
/*
|
||||
* Temporary, undocumented mode
|
||||
* to imitate mdoc(7) output style.
|
||||
*/
|
||||
p->mdocstyle = 1;
|
||||
p->defindent = 5;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -82,16 +136,36 @@ ascii_alloc(char *outopts)
|
|||
return(p);
|
||||
}
|
||||
|
||||
void *
|
||||
ascii_alloc(char *outopts)
|
||||
{
|
||||
|
||||
return(ascii_init(TERMENC_ASCII, outopts));
|
||||
}
|
||||
|
||||
void *
|
||||
utf8_alloc(char *outopts)
|
||||
{
|
||||
|
||||
return(ascii_init(TERMENC_UTF8, outopts));
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
locale_alloc(char *outopts)
|
||||
{
|
||||
|
||||
return(ascii_init(TERMENC_LOCALE, outopts));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static size_t
|
||||
ascii_width(const struct termp *p, char c)
|
||||
ascii_width(const struct termp *p, int c)
|
||||
{
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ascii_free(void *arg)
|
||||
{
|
||||
|
@ -99,17 +173,14 @@ ascii_free(void *arg)
|
|||
term_free((struct termp *)arg);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ascii_letter(struct termp *p, char c)
|
||||
ascii_letter(struct termp *p, int c)
|
||||
{
|
||||
|
||||
/* LINTED */
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ascii_begin(struct termp *p)
|
||||
{
|
||||
|
@ -117,7 +188,6 @@ ascii_begin(struct termp *p)
|
|||
(*p->headf)(p, p->argf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ascii_end(struct termp *p)
|
||||
{
|
||||
|
@ -125,7 +195,6 @@ ascii_end(struct termp *p)
|
|||
(*p->footf)(p, p->argf);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ascii_endline(struct termp *p)
|
||||
|
@ -134,19 +203,16 @@ ascii_endline(struct termp *p)
|
|||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ascii_advance(struct termp *p, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Just print whitespace on the terminal. */
|
||||
for (i = 0; i < len; i++)
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static double
|
||||
ascii_hspan(const struct termp *p, const struct roffsu *su)
|
||||
|
@ -185,3 +251,39 @@ ascii_hspan(const struct termp *p, const struct roffsu *su)
|
|||
return(r);
|
||||
}
|
||||
|
||||
#ifdef USE_WCHAR
|
||||
/* ARGSUSED */
|
||||
static size_t
|
||||
locale_width(const struct termp *p, int c)
|
||||
{
|
||||
int rc;
|
||||
|
||||
return((rc = wcwidth(c)) < 0 ? 0 : rc);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
locale_advance(struct termp *p, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
putwchar(L' ');
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
locale_endline(struct termp *p)
|
||||
{
|
||||
|
||||
putwchar(L'\n');
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
locale_letter(struct termp *p, int c)
|
||||
{
|
||||
|
||||
putwchar(c);
|
||||
}
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue