From f88b6c166601db65e30d49d360aeb63cd0a021ea Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Sun, 6 Oct 2013 09:47:07 +0200 Subject: [PATCH] Import mdocml-1.12.2 --- contrib/mdocml/Makefile | 302 ++----- contrib/mdocml/NEWS | 331 ++++++++ contrib/mdocml/TODO | 165 ++-- contrib/mdocml/apropos.1 | 55 +- contrib/mdocml/apropos.c | 137 +--- contrib/mdocml/apropos_db.c | 6 +- contrib/mdocml/arch.in | 5 +- contrib/mdocml/catman.c | 5 +- contrib/mdocml/cgi.c | 39 +- contrib/mdocml/chars.c | 6 +- contrib/mdocml/chars.in | 3 +- contrib/mdocml/config.h.post | 15 +- contrib/mdocml/demandoc.1 | 7 +- contrib/mdocml/demandoc.c | 4 +- contrib/mdocml/eqn.7 | 7 +- contrib/mdocml/gmdiff | 35 + contrib/mdocml/html.c | 124 ++- contrib/mdocml/html.h | 4 +- contrib/mdocml/index.sgml | 167 ++-- contrib/mdocml/libman.h | 12 +- contrib/mdocml/libmandoc.h | 11 +- contrib/mdocml/libmdoc.h | 19 +- contrib/mdocml/libroff.h | 4 +- contrib/mdocml/main.c | 30 +- contrib/mdocml/man.7 | 90 ++- contrib/mdocml/man.c | 255 +++--- contrib/mdocml/man.cgi.7 | 5 +- contrib/mdocml/man.h | 4 +- contrib/mdocml/man_html.c | 62 +- contrib/mdocml/man_macro.c | 162 ++-- contrib/mdocml/man_term.c | 201 +++-- contrib/mdocml/man_validate.c | 199 +++-- contrib/mdocml/mandoc.1 | 22 +- contrib/mdocml/mandoc.3 | 94 ++- contrib/mdocml/mandoc.c | 334 +++----- contrib/mdocml/mandoc.h | 34 +- contrib/mdocml/mandoc_char.7 | 9 +- contrib/mdocml/mandocdb.8 | 53 +- contrib/mdocml/mandocdb.c | 373 +++++---- contrib/mdocml/mandocdb.h | 6 +- contrib/mdocml/manpath.c | 20 +- contrib/mdocml/manpath.h | 4 +- contrib/mdocml/mdoc.7 | 80 +- contrib/mdocml/mdoc.c | 295 +++---- contrib/mdocml/mdoc.h | 4 +- contrib/mdocml/mdoc_argv.c | 111 +-- contrib/mdocml/mdoc_html.c | 65 +- contrib/mdocml/mdoc_macro.c | 386 ++++----- contrib/mdocml/mdoc_man.c | 1352 +++++++++++++++++++++++++++----- contrib/mdocml/mdoc_term.c | 189 ++--- contrib/mdocml/mdoc_validate.c | 198 +++-- contrib/mdocml/out.c | 39 +- contrib/mdocml/preconv.1 | 7 +- contrib/mdocml/preconv.c | 11 +- contrib/mdocml/predefs.in | 4 +- contrib/mdocml/read.c | 98 ++- contrib/mdocml/roff.7 | 37 +- contrib/mdocml/roff.c | 344 +++++--- contrib/mdocml/st.in | 19 +- contrib/mdocml/tbl.3 | 295 +++++++ contrib/mdocml/tbl.7 | 14 +- contrib/mdocml/tbl.c | 40 +- contrib/mdocml/tbl_data.c | 12 +- contrib/mdocml/tbl_html.c | 20 +- contrib/mdocml/tbl_layout.c | 154 +--- contrib/mdocml/tbl_term.c | 138 ++-- contrib/mdocml/term.c | 172 ++-- contrib/mdocml/term.h | 9 +- contrib/mdocml/term_ascii.c | 5 +- contrib/mdocml/test-betoh64.c | 18 + contrib/mdocml/test-mmap.c | 2 +- contrib/mdocml/tree.c | 16 +- contrib/mdocml/whatis.1 | 53 +- 73 files changed, 4701 insertions(+), 2906 deletions(-) create mode 100644 contrib/mdocml/NEWS create mode 100644 contrib/mdocml/gmdiff create mode 100644 contrib/mdocml/tbl.3 create mode 100644 contrib/mdocml/test-betoh64.c diff --git a/contrib/mdocml/Makefile b/contrib/mdocml/Makefile index 304237b478..044d087281 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mdocml/Makefile @@ -1,19 +1,15 @@ .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\"" +# CFLAGS += -DOSNAME="\"OpenBSD 5.4\"" -VERSION = 1.12.1 -VDATE = 23 March 2012 +VERSION = 1.12.2 +VDATE = 05 October 2013 # IFF your system supports multi-byte functions (setlocale(), wcwidth(), # putwchar()) AND has __STDC_ISO_10646__ (that is, wchar_t is simply a @@ -29,10 +25,11 @@ CFLAGS += -DUSE_WCHAR # 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). +# If your system does not support static binaries, comment this, +# for example on Mac OS X. STATIC = -static +# Linux requires -pthread to statically link with libdb. +#STATIC += -pthread CFLAGS += -g -DHAVE_CONFIG_H -DVERSION="\"$(VERSION)\"" CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings @@ -64,6 +61,7 @@ DBLN = llib-lapropos.ln llib-lmandocdb.ln llib-lman.cgi.ln llib-lcatman.ln all: mandoc preconv demandoc $(DBBIN) SRCS = Makefile \ + NEWS \ TODO \ apropos.1 \ apropos.c \ @@ -92,6 +90,7 @@ SRCS = Makefile \ eqn_term.c \ example.style.css \ external.png \ + gmdiff \ html.c \ html.h \ index.css \ @@ -147,6 +146,7 @@ SRCS = Makefile \ st.c \ st.in \ style.css \ + tbl.3 \ tbl.7 \ tbl.c \ tbl_data.c \ @@ -158,6 +158,7 @@ SRCS = Makefile \ term.h \ term_ascii.c \ term_ps.c \ + test-betoh64.c \ test-fgetln.c \ test-getsubopt.c \ test-mmap.c \ @@ -173,10 +174,6 @@ 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 LIBMDOC_OBJS = arch.o \ att.o \ @@ -188,16 +185,6 @@ LIBMDOC_OBJS = arch.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 LIBROFF_OBJS = eqn.o \ roff.o \ @@ -205,12 +192,6 @@ LIBROFF_OBJS = eqn.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 LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ $(LIBMDOC_OBJS) \ @@ -219,52 +200,35 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ mandoc.o \ msec.o \ read.o -LIBMANDOC_LNS = $(LIBMAN_LNS) \ - $(LIBMDOC_LNS) \ - $(LIBROFF_LNS) \ - chars.ln \ - mandoc.ln \ - msec.ln \ - read.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 - -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 - -$(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 - -$(COMPAT_OBJS) $(COMPAT_LNS): config.h + +arch.o: arch.in +att.o: att.in +chars.o: chars.in +lib.o: lib.in +msec.o: msec.in +roff.o: predefs.in +st.o: st.in +vol.o: vol.in + +$(LIBMAN_OBJS): libman.h +$(LIBMDOC_OBJS): libmdoc.h +$(LIBROFF_OBJS): libroff.h +$(LIBMANDOC_OBJS): mandoc.h mdoc.h man.h libmandoc.h config.h +$(COMPAT_OBJS): config.h 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 +$(MANDOC_HTML_OBJS): html.h MANDOC_MAN_OBJS = mdoc_man.o -MANDOC_MAN_LNS = mdoc_man.ln MANDOC_TERM_OBJS = eqn_term.o \ man_term.o \ @@ -273,13 +237,7 @@ MANDOC_TERM_OBJS = eqn_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 +$(MANDOC_TERM_OBJS): term.h MANDOC_OBJS = $(MANDOC_HTML_OBJS) \ $(MANDOC_MAN_OBJS) \ @@ -287,31 +245,16 @@ MANDOC_OBJS = $(MANDOC_HTML_OBJS) \ main.o \ out.o \ tree.o -MANDOC_LNS = $(MANDOC_HTML_LNS) \ - $(MANDOC_MAN_LNS) \ - $(MANDOC_TERM_LNS) \ - main.ln \ - out.ln \ - tree.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 +$(MANDOC_OBJS): main.h mandoc.h mdoc.h man.h config.h out.h MANDOCDB_OBJS = mandocdb.o manpath.o -MANDOCDB_LNS = mandocdb.ln manpath.ln - -$(MANDOCDB_OBJS) $(MANDOCDB_LNS): mandocdb.h mandoc.h mdoc.h man.h config.h manpath.h +$(MANDOCDB_OBJS): mandocdb.h mandoc.h mdoc.h man.h config.h manpath.h PRECONV_OBJS = preconv.o -PRECONV_LNS = preconv.ln - -$(PRECONV_OBJS) $(PRECONV_LNS): config.h +$(PRECONV_OBJS): config.h APROPOS_OBJS = apropos.o apropos_db.o manpath.o -APROPOS_LNS = apropos.ln apropos_db.ln manpath.ln - -$(APROPOS_OBJS) $(APROPOS_LNS): config.h mandoc.h apropos_db.h manpath.h mandocdb.h +$(APROPOS_OBJS): config.h mandoc.h apropos_db.h manpath.h mandocdb.h CGI_OBJS = $(MANDOC_HTML_OBJS) \ $(MANDOC_MAN_OBJS) \ @@ -321,103 +264,30 @@ CGI_OBJS = $(MANDOC_HTML_OBJS) \ manpath.o \ out.o \ tree.o - -CGI_LNS = $(MANDOC_HTML_LNS) \ - $(MANDOC_MAN_LNS) \ - $(MANDOC_TERM_LNS) \ - cgi.ln \ - apropos_db.ln \ - manpath.ln \ - out.ln \ - tree.ln - -$(CGI_OBJS) $(CGI_LNS): main.h mdoc.h man.h out.h config.h mandoc.h apropos_db.h manpath.h mandocdb.h +$(CGI_OBJS): main.h mdoc.h man.h out.h config.h mandoc.h apropos_db.h manpath.h mandocdb.h CATMAN_OBJS = catman.o manpath.o -CATMAN_LNS = catman.ln manpath.ln - -$(CATMAN_OBJS) $(CATMAN_LNS): config.h mandoc.h manpath.h mandocdb.h +$(CATMAN_OBJS): config.h mandoc.h manpath.h mandocdb.h DEMANDOC_OBJS = demandoc.o -DEMANDOC_LNS = demandoc.ln - -$(DEMANDOC_OBJS) $(DEMANDOC_LNS): config.h +$(DEMANDOC_OBJS): config.h 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 \ + tbl.3.html \ 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 + mandocdb.8.html $(INDEX_MANS): mandoc @@ -430,38 +300,19 @@ INDEX_OBJS = $(INDEX_MANS) \ www: index.html -lint: llib-lmandoc.ln llib-lpreconv.ln llib-ldemandoc.ln $(DBLN) - clean: 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 config.h config.log $(COMPAT_OBJS) + rm -f mdocml.tar.gz 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 - rm -rf apropos.dSYM - rm -rf catman.dSYM - rm -rf mandocdb.dSYM - rm -rf whatis.dSYM + rm -rf *.dSYM install: all mkdir -p $(DESTDIR)$(BINDIR) @@ -475,7 +326,7 @@ install: all $(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) mandoc.3 tbl.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) @@ -500,54 +351,30 @@ installwww: www libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS) $(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS) -llib-llibmandoc.ln: $(COMPAT_LNS) $(LIBMANDOC_LNS) - $(LINT) $(LINTFLAGS) -Clibmandoc $(COMPAT_LNS) $(LIBMANDOC_LNS) - mandoc: $(MANDOC_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(MANDOC_OBJS) libmandoc.a -llib-lmandoc.ln: $(MANDOC_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cmandoc $(MANDOC_LNS) llib-llibmandoc.ln - mandocdb: $(MANDOCDB_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(MANDOCDB_OBJS) libmandoc.a $(DBLIB) -llib-lmandocdb.ln: $(MANDOCDB_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cmandocdb $(MANDOCDB_LNS) llib-llibmandoc.ln - preconv: $(PRECONV_OBJS) $(CC) $(LDFLAGS) -o $@ $(PRECONV_OBJS) -llib-lpreconv.ln: $(PRECONV_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cpreconv $(PRECONV_LNS) llib-llibmandoc.ln - whatis: apropos cp -f apropos whatis apropos: $(APROPOS_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(APROPOS_OBJS) libmandoc.a $(DBLIB) -llib-lapropos.ln: $(APROPOS_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Capropos $(APROPOS_LNS) llib-llibmandoc.ln - catman: $(CATMAN_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(CATMAN_OBJS) libmandoc.a $(DBLIB) -llib-lcatman.ln: $(CATMAN_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Ccatman $(CATMAN_LNS) llib-llibmandoc.ln - man.cgi: $(CGI_OBJS) libmandoc.a $(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB) -llib-lman.cgi.ln: $(CGI_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cman.cgi $(CGI_LNS) llib-llibmandoc.ln - demandoc: $(DEMANDOC_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a -llib-ldemandoc.ln: $(DEMANDOC_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cdemandoc $(DEMANDOC_LNS) llib-llibmandoc.ln - mdocml.md5: mdocml.tar.gz md5 mdocml.tar.gz >$@ @@ -557,37 +384,6 @@ mdocml.tar.gz: $(SRCS) ( cd .dist/ && tar zcf ../$@ ./ ) rm -rf .dist/ -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 - -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 - -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 - index.html: $(INDEX_OBJS) config.h: config.h.pre config.h.post @@ -618,6 +414,10 @@ config.h: config.h.pre config.h.post echo '#define HAVE_STRLCPY'; \ rm test-strlcpy; \ fi; \ + if $(CC) $(CFLAGS) -Werror -o test-betoh64 test-betoh64.c >> config.log 2>&1; then \ + echo '#define HAVE_BETOH64'; \ + rm test-betoh64; \ + fi; \ echo; \ cat config.h.post \ ) > $@ @@ -625,21 +425,9 @@ config.h: config.h.pre 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)!" $< >$@ diff --git a/contrib/mdocml/NEWS b/contrib/mdocml/NEWS new file mode 100644 index 0000000000..784b89b0eb --- /dev/null +++ b/contrib/mdocml/NEWS @@ -0,0 +1,331 @@ +$Id: NEWS,v 1.2 2013/10/05 13:15:51 schwarze Exp $ + +This file lists the most important changes in the mdocml.bsd.lv distribution. + +Changes in version 1.12.2, released on Oktober 5, 2013 + + * The mdoc(7) to man(7) converter, to be called as mandoc -Tman, + is now fully functional. + * The mandoc(1) utility now supports the -Ios (default operating system) + input option, and the -Tutf8 output mode now actually works. + * The mandocdb(8) utility no longer truncates existing databases when + starting to build new ones, but only replaces them when the build + actually succeeds. + * The man(7) parser now supports the PD macro (paragraph distance), + and (for GNU man-ext compatibility only) EX (example block) and EE + (example end). Plus several bugfixes regarding indentation, line + breaks, and vertical spacing, and regarding RS following TP. + * The roff(7) parser now supports the \f(BI (bold+italic) font escape, + the \z (zero cursor advance) escape and the cc (change control + character) and it (input line trap) requests. Plus bugfixes regarding + the \t (tab) escape, nested escape sequences, and conditional requests. + * In mdoc(7), several bugs were fixed related to UTF-8 output of quoting + enclosures, delimiter handling, list indentation and horizontal and + vertical spacing, formatting of the Lk, %U, and %C macros, plus some + bugfixes related to the handling of syntax errors like badly nested + font blocks, stray Ta macros outside column lists, unterminated It Xo + blocks, and non-text children of Nm blocks. + * In tbl(7), the width of horizontal spans and the vertical spacing + around tables was corrected, and in man(7) files, a crash was fixed + that was triggered by some particular unclosed T{ macros. + * For mandoc developers, we now provide a tbl(3) library manual and + gmdiff, a very small, very simplistic groff-versus-mandoc output + comparison tool. + * Provide this NEWS file. + +Changes in version 1.12.1, released on March 23, 2012 + + * Significant work on apropos(1) and mandocdb(8). These tools are now + much more robust. A whatis(1) implementation is now handled as an + apropos(1) mode. These tools are also able to minimally handle + pre-formatted pages, that is, those already formatted by another + utility such as GNU troff. + * The man.cgi(7) script is also now available for wider testing. + It interfaces with mandocdb(8) manuals cached by catman(8). + HTML output is generated on-the-fly by libmandoc or internal + methods to convert pre-formatted pages. + * The mailing list archive for the discuss and tech lists are being + hosted by Gmane at gmane.comp.tools.mdocml.user and + gmane.comp.tools.mdocml.devel, respectively. + +Changes in version 1.12.0, released on October 8, 2011 + + * This version features a new, work-in-progress mandoc(1) output mode: + -Tman. This mode allows a system maintainer to distribute man(7) + media for older systems that may not natively support mdoc(7), such + as old Solaris systems. + * The -Ofragment option was added to mandoc(1)'s -Thtml and -Txhtml modes. + * While adding features, an apropos(1) utility has been merged from the + mandoc-tools sandbox. This interfaces with mandocdb(8) for semantic + search of manual content. apropos(1) is different from the traditional + apropos primarily in allowing keyword search (such as for functions, + utilities, etc.) and regular expressions. Note that the calling + syntax for apropos is likely to change as it settles down. + * In documentation news, the mdoc(7) and man(7) manuals have been + made considerably more readable by adding MACRO OVERVIEW sections, by + moving the gory details of the LANGUAGE SYNTAX to the roff(7) manual, + and by moving the very technical MACRO SYNTAX sections down to the + bottom of the page. + * Furthermore, for tbl(7), the -Tascii mode horizontal spacing of tables + was rewritten completely. It is now compatible with groff(1), both + with and without frames and rulers. + * Nesting of indented blocks is now supported in man(7), and several + bugs were fixed regarding indentation and alignment. + * The page headers in mdoc(7) are now nicer for very long titles. + +Changes in version 1.11.7, released on September 2, 2011 + + * Added demandoc(1) utility for stripping away macros and escapes. + This replaces the historical deroff(1) utility. + * Also improved the mdoc(7) and man(7) manuals. + +Changes in version 1.11.6, released on August 16, 2011 + + * Handling of tr macro in roff(7) implemented. This makes Perl + documentation much more readable. Hyphenation is also now enabled in + man(7) format documents. Many other general improvements have been + implemented. + +Changes in version 1.11.5, released on July 24, 2011 + + * Significant eqn(7) improvements. mdocml can now parse arbitrary eqn + input (although few GNU extensions are accepted, nor is mixing + low-level roff with eqn). See the eqn(7) manual for details. + For the time being, equations are rendered as simple in-line text. + The equation parser satisfies the language specified in the + Second Edition User's Guide: + http://www.kohala.com/start/troff/v7man/eqn/eqn2e.ps + +Changes in version 1.11.4, released on July 12, 2011 + + * Bug-fixes and clean-ups across all systems, especially in mandocdb(8) + and the man(7) parser. This release was significantly assisted by + participants in OpenBSD's c2k11. Thanks! + +Changes in version 1.11.3, released on May 26, 2011 + + * Introduce locale-encoding of output with the -Tlocale output option and + Unicode escaped-character input. See mandoc(1) and mandoc_char(7), + respectively, for details. This allows for non-ASCII characters (e.g., + \[u5000]) to be rendered in the locale's encoding, if said environment + supports wide-character encoding (if it does not, -Tascii is used + instead). Locale support can be turned off at compile time by removing + -DUSE_WCHAR in the Makefile, in which case -Tlocale is always a synonym + for -Tascii. + * Furthermore, multibyte-encoded documents, such as those in UTF-8, may + be on-the-fly recoded into mandoc(1) input by using the newly-added + preconv(1) utility. Note: in the future, this feature may be + integrated into mandoc(1). + +Changes in version 1.11.2, released on May 12, 2011 + + * Corrected some installation issues in version 1.11.1. + * Further migration to libmandoc. + * Initial public release (this utility is very much under development) + of mandocdb(8). This utility produces keyword databases of manual + content, which features semantic querying of manual content. + +Changes in version 1.11.1, released on April 4, 2011 + + * The earlier libroff, libmdoc, and libman soup have been merged into + a single library, libmandoc, which manages all aspects of parsing + real manuals, from line-handling to tbl(7) parsing. + * Beyond this structural change, initial eqn(7) functionality is in + place. For the time being, this is limited to the recognition of + equation blocks; future version of mdocml will expand upon this + framework. + * As usual, many general fixes and improvements have also occurred. + In particular, a great deal of redundancy and superfluous code has + been removed with the merging of the backend libraries. + +Changes in version 1.10.9, released on January 7, 2011 + + * Many back-end fixes have been implemented: argument handling (quoting), + man(7) improvements, error/warning classes, and many more. + * Initial tbl(7) functionality (see the "TS", "TE", and "T&" macros in + the roff(7) manual) has been merged from tbl.bsd.lv. Output is still + minimal, especially for -Thtml and -Txhtml, but manages to at least + display data. This means that mandoc(1) now has built-in support + for two troff preprocessors via libroff: soelim(1) and tbl(1). + +Changes in version 1.10.8, released on December 24, 2010 + + * Significant improvements merged from OpenBSD downstream, including + - many new roff(7) components, + - in-line implementation of troff's soelim(1), + - broken-block handling, + - overhauled error classifications, and + - cleaned up handling of error conditions. + * Also overhauled the -Thtml and -Txhtml output modes. They now display + readable output in arbitrary browsers, including text-based ones like + lynx(1). See HTML and XHTML manuals in the DOCUMENTATION section + for examples. Attention: available style-sheet classes have been + considerably changed! See the example.style.css file for details. + Lastly, libmdoc and libman have been cleaned up and reduced in size + and complexity. + +Changes in version 1.10.6, released on September 27, 2010 + + * Calling conventions for mandoc(1) have changed: -W improved and -f + deprecated. + * Non-ASCII characters are also now uniformly discarded. + * Lots of documentation improvements. + * Many incremental fixes accomodating for groff's more interesting + productions. + * Lastly, pod2man(1) preambles are now fully accepted after some + considerable roff(7) and special character support. + +Changes in version 1.10.5, released on July 27, 2010 + + * Primarily a bug-fix and polish release, but including -Tpdf support + in mandoc(1) by way of "Summer of Code". Highlights: + * fix "Sm" and "Bd" handling + * fix end-of-sentence handling for embedded sentences + * polish man(7) documentation + * document all mdoc(7) macros + * polish mandoc(1) -Tps output + * lots of internal clean-ups in character escapes + * un-break literal contexts in man(7) documents + * improve -Thtml output for -man + * add mandoc(1) -Tpdf support + +Changes in version 1.10.4, released on July 12, 2010 + + * Lots of features developed during both "Summer of Code" and the + OpenBSD c2k10 hackathon: + * minimal "ds" roff(7) symbols are supported + * "Bk" mdoc(7) support + * beautified SYNOPSIS section output + * variable font-width and paper-size support in mandoc(1) -Tps output + * acceptance of scope-block breakage in mdoc(7) + * clarify error message status + * many minor bug-fixes and formatting issues resolved + +Changes in version 1.10.2, released on June 19, 2010 + + * Small release featuring text-decoration in -Tps output, + a few minor relaxations of errors, and some optimisations. + +Changes in version 1.10.1, released on June 7, 2010 + + * This primarily focusses on the "Bl" and "It" macros described in + mdoc(7). Multi-line column support is now fully compatible with groff, + as are implicit list entries for columns. + * Removed manuals(7) in favour of http://manpages.bsd.lv. + * The way we handle the SYNOPSIS section (see the SYNOPSIS documentation + in MANUAL STRUCTURE) has also been considerably simplified compared + to groff's method. + * Furthermore, the -Owidth=width output option has been added to -Tascii, + see mandoc(1). + * Lastly, initial PostScript output has been added with the -Tps option + to mandoc(1). It's brutally simple at the moment: fixed-font, with no + font decorations. + +Changes in version 1.10.0, released on May 29, 2010 + + * Release consisting of the results from the m2k10 hackathon and up-merge + from OpenBSD. This requires a significant note of thanks to Ingo + Schwarze (OpenBSD) and Joerg Sonnenberger (NetBSD) for their hard work, + and again to Joerg for hosting m2k10. Highlights (mostly cribbed from + Ingo's m2k10 report) follow in no particular order: + * a libroff preprocessor in front of libmdoc and libman stripping out + roff(7) instructions; + * end-of-sentence (EOS) detection in free-form and macro lines; + * correct handling of tab-separated columnar lists in mdoc(7); + * improved main calling routines to optionally use mmap(3) for better + performance; + * cleaned up exiting when invoked as -Tlint or over multiple files + with -fign-errors; + * error and warning message handling re-written to be unified for + libroff, libmdoc, and libman; + * handling of badly-nested explicit-scoped macros; + * improved free-form text parsing in libman and libmdoc; + * significant GNU troff compatibility improvements in -Tascii, + largely in terms of spacing; + * a regression framework for making sure the many fragilities of GNU + troff aren't trampled in subsequent work; + * support for -Tascii breaking at hyphens encountered in free-form text; + * and many more minor fixes and improvements + +Changes in version 1.9.25, released on May 13, 2010 + + * Fixed handling of "\*(Ba" escape. + * Backed out -fno-ign-chars (pointless complexity). + * Fixed erroneous breaking of literal lines. + * Fixed SYNOPSIS breaking lines before non-initial macros. + * Changed default section ordering. + * Most importantly, the framework for end-of-sentence double-spacing is + in place, now implemented for the "end-of-sentence, end-of-line" rule. + * This is a stable roll-back point before the mandoc hackathon in Rostock! + +Changes in version 1.9.24, released on May 9, 2010 + + * Rolled back break-at-hyphen. + * -DUGLY is now the default (no feature splits!). + * Free-form text is not de-chunked any more: lines are passed + whole-sale into the front-end, including whitespace. + * Added mailing lists. + +Changes in version 1.9.23, released on April 7, 2010 + + * mdocml has been linked to the OpenBSD build. + * This version incorporates many small changes, mostly from patches + by OpenBSD, allowing crufty manuals to slip by with warnings instead + of erroring-out. + * Some subtle semantic issues, such as punctuation scope, have also + been fixed. + * Lastly, some issues with -Thtml have been fixed, which prompted an + update to the online manual pages style layout. + +Changes in version 1.9.22, released on March 31, 2010 + + * Adjusted merge of the significant work by Ingo Schwarze + in getting "Xo" blocks (block full implicit, e.g., "It" + for non-columnar lists) to work properly. This isn't + enabled by default: you must specify -DUGLY as a compiler + flag (see the Makefile for details). + +Changes in version 1.9.20, released on March 30, 2010 + + * More efforts to get roff instructions in man(7) documents under + control. Note that roff instructions embedded in line-scoped, + next-line macros (e.g. "B") are not supported. + * Leading punctuation for mdoc(7) macros, such as "Fl ( ( a", + are now correctly handled. + +Changes in version 1.9.18, released on March 27, 2010 + + * Many fixes (largely pertaining to scope) + and improvements (e.g., handling of apostrophe-control macros, + which fixes the strange "BR" seen in some macro output) + to handling roff instructions in man(7) documents. + +Changes in version 1.9.17, released on March 25, 2010 + + * Accept perlpod(1) standard preamble. + * Also accept (and discard) "de", "dei", "am", "ami", and "ig" + roff macro blocks. + +Changes in version 1.9.16, released on March 22, 2010 + + * Inspired by patches and bug reports by Ingo Schwarze, + allowed man(7) to accept non-printing elements to be nested + within next-line scopes, such as "br" within "B" or "TH", + which is valid roff. + * Longsoon architecture also noted and Makefile cleaned up. + +Changes in version 1.9.15, released on February 18, 2010 + + * Moved to our new BSD.lv home. + * XHTML is now an acceptable output mode for mandoc(1); + * "Xr" made more compatible with groff; + * "Vt" fixed when invoked in SYNOPSIS; + * "\\" escape removed; + * end-of-line white-space detected for all lines; + * subtle bug fixed in list display for some modes; + * compatibility layer checked in for compilation in diverse + UNIX systems; + * and column lengths handled correctly. + +For older releases, see the ChangeLog files +in http://mdocml.bsd.lv/snapshots/ . diff --git a/contrib/mdocml/TODO b/contrib/mdocml/TODO index a870136129..0aebbd38b4 100644 --- a/contrib/mdocml/TODO +++ b/contrib/mdocml/TODO @@ -1,25 +1,19 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.129 2012/03/04 23:53:37 schwarze Exp $ +* $Id: TODO,v 1.157 2013/09/27 21:12:34 schwarze Exp $ ************************************************************************ ************************************************************************ -* parser bugs +* crashes ************************************************************************ -- ".\}" on its own line gets translated to bare ".\&" - which forces pset() into man(7) - and then triggers an unknown macro error - reported by naddy@ Sun, 3 Jul 2011 21:52:24 +0200 - -************************************************************************ -* formatter bugs -************************************************************************ - -- tbl(7): Horizontal and vertical lines are formatted badly: - With the box option, there is too much white space at the end of cells. - Horizontal lines from "=" lines are a bit too long. - yuri dot pankov at gmail dot com Thu, 14 Apr 2011 05:45:26 +0400 +- .Bl -tag followed by a text node preceding the first .It should not + throw a FATAL error, but only a normal ERROR. Putting this into the + HEAD of an implicit .It might be cleanest, inserting an implicit .Pp + or just dumping the orphan stuff directly into the BODY of the .Bl + might be easier to implement, and all options can no doubt be made + to yield correct (i.e. groff bug-compatible) rendering. + Anthony J. Bentley on discuss@ Sun, 22 Sep 2013 16:33:21 -0600 ************************************************************************ * missing features @@ -27,15 +21,11 @@ --- missing roff features ---------------------------------------------- -- The pod2man preamble wants \h'...' with quoted numerical arguments, - see for example AUTHORS in MooseX::Getopt.3p, p5-MooseX-Getopt. +- roff.c should treat \n(.H>23 and \n(.V>19 in the pod2man(1) + preamble as true, see for example AUTHORS in MooseX::Getopt.3p reported by Andreas Voegele Tue, 22 Nov 2011 15:34:47 +0100 on ports@ -- .if n \{ - .br\} - should cause an extra space to be raised. - - .ad (adjust margins) .ad l -- adjust left margin only (flush left) .ad r -- adjust right margin only (flush right) @@ -45,19 +35,37 @@ .ad -- re-enable adjustment without changing the mode Adjustment mode is ignored while in no-fill mode (.nf). -- .it (line traps) occur in mysql(1), yasm_arch(7) - generated by DocBook XSL Stylesheets v1.71.1 - reported by brad@ Sat, 15 Jan 2011 15:48:18 -0500 - +- .as (append to string) + found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200 + +- .ce (center N lines) + found by naddy@ in xloadimage(1) + found by Juan Francisco Cantero Hurtado + in lang/racket(1) Thu, 20 Jun 2013 03:19:11 +0200 + +- .fc (field control) + found by naddy@ in xloadimage(1) + - .ns (no-space mode) occurs in xine-config(1) reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500 -- xloadimage(1) wants .ti (temporary indent), rep by naddy@ - - .ta (tab settings) occurs in ircbug(1) and probably gnats(1) reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500 -- \c (interrupted text) occurs in chat(8) +- .ti (temporary indent) + found by naddy@ in xloadimage(1) + found by bentley@ in nmh(1) Mon, 23 Apr 2012 13:38:28 -0600 + +- .while and .shift + found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200 + +- \c (interrupted text) should prevent the line break + even inside .Bd literal; that occurs in chat(8) + also found in cclive(1) - DocBook output + +- \h horizontal move + found in cclive(1) DocBook output + Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600 - using undefined strings or macros defines them to be empty wl@ Mon, 14 Nov 2011 14:37:01 +0000 @@ -134,6 +142,8 @@ - groff an-ext.tmac macros (.UR, .UE) occur in xine(5) reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500 + also occur in freeciv-client(6) freeciv-server(6) freeciv-modpack(6) + reported by bentley@ Tue, 30 Oct 2012 01:05:57 -0600 - -T[x]html doesn't stipulate non-collapsing spaces in literal mode @@ -149,6 +159,15 @@ --- missing misc features ---------------------------------------------- +- The whatis(1) utility looks for whole words in Nm. + If the file name of a page does not agree with the contents of any + of its Nm macros (e.g. pool(9)), add the file name as an Nm entry + to the mandoc.db as well, such that whatis(1) finds it. + If there is a page with a file name that does not appear as a substring + neither in Nm nor in Nd, the same fix would allow finding that page + with apropos(1) using the file name as a key, as well. + Issue reported by tedu@ Fri, 05 Jul 2013 21:15:23 -0400 + - clean up escape sequence handling, creating three classes: (1) fully implemented, or parsed and ignored without loss of content (2) unimplemented, potentially causing loss of content @@ -156,14 +175,6 @@ see textproc/mgdiff(1) for nice examples (3) undefined, just output the character -> perhaps WARNING -- The \t escape sequence is the same as a literal tab, see for example - the ASCII table in hexdump(1) where - .Bl -column \&000_nu \&001_so \&002_st \&003_et \&004_eo - .It \&000\ nul\t001\ soh\t002\ stx\t003\ etx\t004\ eot\t005\ enq - produces - 000 nul 001 soh 002 stx 003 etx 004 eot 005 enq - and the example in oldrdist(1) - - look at pages generated from reStructeredText, e.g. devel/mercurial hg(1) These are a weird mixture of man(7) and custom autogenerated low-level roff stuff. Figure out to what extent we can cope. @@ -188,9 +199,6 @@ so far, we only have it in roff(7) and man(7) reminded by millert@ Thu, 09 Dec 2010 17:29:52 -0500 -- perl(1) SYNOPSIS looks bad; reported by deraadt@ - 1) man(7) seems to need SYNOPSIS .Nm blocks, too - - In .Bl -column, .It Em AuthenticationKey Length ought to render "Key Length" with emphasis, too, @@ -210,9 +218,18 @@ of in_line() - put trailing punctuation out of scope. Found in mount_nfs(8) and exports(5), search for "Appendix". +- Trailing punctuation after .%T triggers EOS spacing, at least + outside .Rs (eek!). Simply setting ARGSFL_DELIM for .%T is not + the right solution, it sends mandoc into an endless loop. + reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100 + - in enclosures, mandoc sometimes fancies a bogus end of sentence reminded by jmc@ Thu, 23 Sep 2010 18:13:39 +0059 +- formatting /usr/local/man/man1/latex2man.1 with groff and mandoc + reveals lots of bugs both in groff and mandoc... + reported by bentley@ Wed, 22 May 2013 23:49:30 -0600 + ************************************************************************ * formatting issues: gratuitous differences ************************************************************************ @@ -225,18 +242,6 @@ is just "o\bo". see for example OpenBSD ksh(1) -- The characters "|" and "\*(Ba" should never be bold, - not even in the middle of a word, e.g. ".Cm b\*(Bac" in - "mknod [-m mode] name b|c major minor" - in OpenBSD ksh(1) - -- A bogus .Pp between two .It must not produce a double blank line, - see between -R and -r in OpenBSD rm(1), before "update" in mount(8), - or in DIAGNOSTICS in init(8), or before "is always true" in ksh(1). - The same happens with .Pp just before .El, see bgpd.conf(5). - Also have `It' complain if `Pp' is invoked at certain times (not - -compact?). - - .Pp between two .It in .Bl -column should produce one, not two blank lines, see e.g. login.conf(5). reported by jmc@ Sun, 17 Apr 2011 14:04:58 +0059 @@ -250,6 +255,10 @@ in between, see for example tmux(1). reported by nicm@ 13 Jan 2011 00:18:57 +0000 +- Trailing punctuation after .It should trigger EOS spacing. + reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100 + Probably, this should be fixed somewhere in termp_it_pre(), not sure. + - .Nx 1.0a should be "NetBSD 1.0A", not "NetBSD 1.0a", see OpenBSD ccdconfig(8). @@ -265,6 +274,9 @@ as -width 7n, not -width 11n. The same applies to .Bl -column column widths; reported again by Nicolas Joly Thu, 1 Mar 2012 13:41:26 +0100 via wiz@ 5 Mar + reported again by Franco Fichtner Fri, 27 Sep 2013 21:02:28 +0200 + An easy partial fix would be to just skip the first word if it starts + with a dot, including any following white space, when measuring. - The \& zero-width character counts as output. That is, when it is alone on a line between two .Pp, @@ -277,56 +289,11 @@ Also, we don't want to break the line within the argument of: .Fa "chtype tl" -- .Ns should work when called at the end of an input line, see - the following code in vi(1): - .It Xo - .Op Ar line - .Cm a Ns Op Cm ppend Ns - .Op Cm !\& - .Xc - The input text is appended after the specified line. - - Header lines of excessive length: Port OpenBSD man_term.c rev. 1.25 to mdoc_term.c and document it in mdoc(7) and man(7) COMPATIBILITY found while talking to Chris Bennett -- In man(7), the sequence - .HP - one line of regular text - .SH - should not produce two blank lines before the .SH, - see for example named-checkconf(8). - -- In man(7), the sequence - .SH HEADER - - .PP - regular text - should not produce any blank lines between the header and the text, - see for example rsync(1). - Reported by naddy@ Mon, 28 Mar 2011 20:45:42 +0200 - -- In man(7), the sequence - regular text - .IP - .IP "tag" - indented text - should produce one, not four blank lines between the regular text - and the tag, see for example rsync(1). - Likewise, - regular text - .IP - indented text - should produce one, not two blank lines in between, and - regular text - .IP - .RS - .IP tag - indented text - should produce one, not three blank lines. - Reported by naddy@ Mon, 28 Mar 2011 20:45:42 +0200 - - trailing whitespace must be ignored even when followed by a font escape, see for example makes @@ -334,12 +301,6 @@ operate in batch mode in dig(1). -************************************************************************ -* error reporting issues -************************************************************************ - -- .TP directly followed by .RS gives an assertion. - ************************************************************************ * performance issues ************************************************************************ diff --git a/contrib/mdocml/apropos.1 b/contrib/mdocml/apropos.1 index 7dea132a46..5adfeb6c31 100644 --- a/contrib/mdocml/apropos.1 +++ b/contrib/mdocml/apropos.1 @@ -1,6 +1,6 @@ -.\" $Id: apropos.1,v 1.17 2012/03/24 01:46:25 kristaps Exp $ +.\" $Id: apropos.1,v 1.16.2.3 2013/10/05 01:25:20 schwarze Exp $ .\" -.\" Copyright (c) 2011, 2012 Kristaps Dzonsons +.\" Copyright (c) 2011 Kristaps Dzonsons .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 24 2012 $ +.Dd $Mdocdate: October 5 2013 $ .Dt APROPOS 1 .Os .Sh NAME @@ -23,8 +23,8 @@ .Sh SYNOPSIS .Nm .Op Fl C Ar file -.Op Fl M Ar manpath -.Op Fl m Ar manpath +.Op Fl M Ar path +.Op Fl m Ar path .Op Fl S Ar arch .Op Fl s Ar section .Ar expression ... @@ -44,11 +44,11 @@ searches for databases in the default paths stipulated by .Xr man 1 , parses terms as case-sensitive regular expressions -over manual names and descriptions. +.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 . -If standard output is a TTY, a result may be selected from a list and -its manual displayed with the pager. .Pp Its arguments are as follows: .Bl -tag -width Ds @@ -58,13 +58,13 @@ Specify an alternative configuration in .Xr man.conf 5 format. -.It Fl M Ar manpath +.It Fl M Ar path 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 +.It Fl m Ar path Prepend the colon-separated paths to the list of paths searched for .Xr mandocdb 8 @@ -156,21 +156,13 @@ If an architecture is specified for the manual, it is displayed as .Pp .D1 title(cat/arch) \- description .Pp -If on a TTY, results are prefixed with a numeric identifier. +Resulting manuals may be accessed as .Pp -.D1 [index] title(cat) \- description +.Dl $ man \-s sec title .Pp -One may choose a manual be entering the index at the prompt. -Valid choices are displayed using -.Ev MANPAGER , -or failing that , -.Ev PAGER -or just -.Xr more 1 . -Source pages are formatted with -.Xr mandoc 1 ; -preformatted pages with -.Xr cat 1 . +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 @@ -248,14 +240,6 @@ Text production: .El .Sh ENVIRONMENT .Bl -tag -width Ds -.It Ev MANPAGER -Default pager for manuals. -If this is unset, falls back to -.Ev Pager . -.It Ev PAGER -The second choice for a manual pager. -If this is unset, use -.Xr more 1 . .It Ev MANPATH Colon-separated paths modifying the default list of paths searched for manual databases. @@ -276,11 +260,11 @@ 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 +.It Pa mandoc.db name of the .Xr mandocdb 8 keyword database -.It Pa whatis.index +.It Pa mandoc.index name of the .Xr mandocdb 8 filename database @@ -317,12 +301,11 @@ as variable names in the library category: .Pp .Dl $ apropos \-s 3 Va~^optind \-a Va~^optarg$ .Sh SEE ALSO -.Xr more 1 +.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 . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/apropos.c b/contrib/mdocml/apropos.c index 9c3cae96af..f5d1425f86 100644 --- a/contrib/mdocml/apropos.c +++ b/contrib/mdocml/apropos.c @@ -1,4 +1,4 @@ -/* $Id: apropos.c,v 1.30 2012/03/24 02:18:51 kristaps Exp $ */ +/* $Id: apropos.c,v 1.27.2.1 2013/09/17 23:23:10 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -25,40 +25,29 @@ #include #include #include -#include #include "apropos_db.h" #include "mandoc.h" #include "manpath.h" -#define SINGLETON(_res, _sz) \ - ((_sz) && (_res)[0].matched && \ - (1 == (_sz) || 0 == (_res)[1].matched)) -#define EMPTYSET(_res, _sz) \ - ((0 == (_sz)) || 0 == (_res)[0].matched) - 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, usecat; + int ch, rc, whatis; struct res *res; struct manpaths paths; - const char *prog; - pid_t pid; - char path[PATH_MAX]; - int fds[2]; - size_t terms, ressz, sz; + size_t terms, ressz; struct opts opts; struct expr *e; - char *defpaths, *auxpaths, *conf_file, *cp; - extern int optind; + char *defpaths, *auxpaths; + char *conf_file; extern char *optarg; + extern int optind; progname = strrchr(argv[0], '/'); if (progname == NULL) @@ -66,18 +55,16 @@ main(int argc, char *argv[]) else ++progname; - whatis = 0 == strncmp(progname, "whatis", 6); + whatis = (0 == strncmp(progname, "whatis", 6)); memset(&paths, 0, sizeof(struct manpaths)); memset(&opts, 0, sizeof(struct opts)); - usecat = 0; ressz = 0; res = NULL; auxpaths = defpaths = NULL; conf_file = NULL; e = NULL; - path[0] = '\0'; while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:"))) switch (ch) { @@ -97,15 +84,14 @@ main(int argc, char *argv[]) opts.cat = optarg; break; default: - usage(); - return(EXIT_FAILURE); + goto usage; } argc -= optind; argv += optind; - if (0 == argc) - return(EXIT_SUCCESS); + if (0 == argc) + goto usage; rc = 0; @@ -123,63 +109,21 @@ main(int argc, char *argv[]) (paths.sz, paths.paths, &opts, e, terms, NULL, &ressz, &res, list); - terms = 1; - if (0 == rc) { fprintf(stderr, "%s: Bad database\n", progname); goto out; - } else if ( ! isatty(STDOUT_FILENO) || EMPTYSET(res, ressz)) - goto out; - - if ( ! SINGLETON(res, ressz)) { - printf("Which manpage would you like [1]? "); - fflush(stdout); - if (NULL != (cp = fgetln(stdin, &sz)) && - sz > 1 && '\n' == cp[--sz]) { - if ((ch = atoi(cp)) <= 0) - goto out; - terms = (size_t)ch; - } } - if (--terms < ressz && res[terms].matched) { - chdir(paths.paths[res[terms].volume]); - strlcpy(path, res[terms].file, PATH_MAX); - usecat = RESTYPE_CAT == res[terms].type; - } out: manpath_free(&paths); resfree(res, ressz); exprfree(e); + return(rc ? EXIT_SUCCESS : EXIT_FAILURE); - if ('\0' == path[0]) - return(rc ? EXIT_SUCCESS : EXIT_FAILURE); - - if (-1 == pipe(fds)) { - perror(NULL); - exit(EXIT_FAILURE); - } - - if (-1 == (pid = fork())) { - perror(NULL); - exit(EXIT_FAILURE); - } else if (pid > 0) { - dup2(fds[0], STDIN_FILENO); - close(fds[1]); - prog = NULL != getenv("MANPAGER") ? - getenv("MANPAGER") : - (NULL != getenv("PAGER") ? - getenv("PAGER") : "more"); - execlp(prog, prog, (char *)NULL); - perror(prog); - return(EXIT_FAILURE); - } - - dup2(fds[1], STDOUT_FILENO); - close(fds[0]); - prog = usecat ? "cat" : "mandoc"; - execlp(prog, prog, path, (char *)NULL); - perror(prog); +usage: + fprintf(stderr, "usage: %s [-C file] [-M path] [-m path] " + "[-S arch] [-s section]%s ...\n", progname, + whatis ? " name" : "\n expression"); return(EXIT_FAILURE); } @@ -191,49 +135,22 @@ list(struct res *res, size_t sz, void *arg) qsort(res, sz, sizeof(struct res), cmp); - if (EMPTYSET(res, sz) || SINGLETON(res, sz)) - return; - - if ( ! isatty(STDOUT_FILENO)) - for (i = 0; i < sz && res[i].matched; 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); - else - for (i = 0; i < sz && res[i].matched; i++) - printf("[%zu] %s(%s%s%s) - %.70s\n", i + 1, - res[i].title, res[i].cat, - *res[i].arch ? "/" : "", - *res[i].arch ? res[i].arch : "", - res[i].desc); + for (i = 0; i < sz; i++) { + if ( ! res[i].matched) + continue; + 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) -{ - const struct res *r1 = p1; - const struct res *r2 = p2; - - if (0 == r1->matched) - return(1); - else if (0 == r2->matched) - return(1); - - return(strcasecmp(r1->title, r2->title)); -} - -static void -usage(void) { - fprintf(stderr, "usage: %s " - "[-C file] " - "[-M manpath] " - "[-m manpath] " - "[-S arch] " - "[-s section] " - "expression ...\n", - progname); + return(strcasecmp(((const struct res *)p1)->title, + ((const struct res *)p2)->title)); } diff --git a/contrib/mdocml/apropos_db.c b/contrib/mdocml/apropos_db.c index 8aea771da7..61002ee5d3 100644 --- a/contrib/mdocml/apropos_db.c +++ b/contrib/mdocml/apropos_db.c @@ -1,4 +1,4 @@ -/* $Id: apropos_db.c,v 1.31 2012/03/24 01:46:25 kristaps Exp $ */ +/* $Id: apropos_db.c,v 1.32.2.1 2013/10/02 21:03:26 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -19,6 +19,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -35,6 +37,7 @@ # include # include #else +# include # include #endif @@ -426,6 +429,7 @@ apropos_search(int pathsz, char **paths, const struct opts *opts, */ for (i = 0; i < pathsz; i++) { + assert('/' == paths[i][0]); if (chdir(paths[i])) continue; if (single_search(&tree, opts, expr, terms, mc, i)) diff --git a/contrib/mdocml/arch.in b/contrib/mdocml/arch.in index 5113446e46..d0c445f308 100644 --- a/contrib/mdocml/arch.in +++ b/contrib/mdocml/arch.in @@ -1,4 +1,4 @@ -/* $Id: arch.in,v 1.12 2012/01/28 14:02:17 joerg Exp $ */ +/* $Id: arch.in,v 1.14 2013/09/16 22:12:57 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons * @@ -38,9 +38,9 @@ LINE("arm", "ARM") LINE("arm26", "ARM26") LINE("arm32", "ARM32") LINE("armish", "ARMISH") +LINE("armv7", "ARMv7") LINE("aviion", "AViiON") LINE("atari", "ATARI") -LINE("beagle", "Beagle") LINE("bebox", "BeBox") LINE("cats", "cats") LINE("cesfic", "CESFIC") @@ -81,6 +81,7 @@ LINE("netwinder", "NetWinder") LINE("news68k", "NeWS68k") LINE("newsmips", "NeWSMIPS") LINE("next68k", "NeXT68k") +LINE("octeon", "OCTEON") LINE("ofppc", "OFPPC") LINE("palm", "Palm") LINE("pc532", "PC532") diff --git a/contrib/mdocml/catman.c b/contrib/mdocml/catman.c index 1d313ea6e0..c755d27057 100644 --- a/contrib/mdocml/catman.c +++ b/contrib/mdocml/catman.c @@ -1,4 +1,4 @@ -/* $Id: catman.c,v 1.10 2012/01/03 15:17:20 kristaps Exp $ */ +/* $Id: catman.c,v 1.11 2012/06/08 10:33:48 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -380,7 +380,8 @@ manup(const struct manpaths *dirs, char *base) char dst[MAXPATHLEN], src[MAXPATHLEN]; const char *path; - int i, c; + size_t i; + int c; size_t sz; FILE *f; diff --git a/contrib/mdocml/cgi.c b/contrib/mdocml/cgi.c index 2f5870ff8e..6d40fcde42 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mdocml/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.42 2012/03/24 01:46:25 kristaps Exp $ */ +/* $Id: cgi.c,v 1.45 2013/06/05 02:00:26 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * @@ -18,7 +18,6 @@ #include "config.h" #endif -#include #include #include @@ -726,14 +725,14 @@ format(const struct req *req, const char *file) struct man *man; void *vp; enum mandoclevel rc; - char opts[MAXPATHLEN + 128]; + char opts[PATH_MAX + 128]; if (-1 == (fd = open(file, O_RDONLY, 0))) { resp_baddb(); return; } - mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL); + mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL, NULL); rc = mparse_readfd(mp, fd, file); close(fd); @@ -743,7 +742,7 @@ format(const struct req *req, const char *file) } snprintf(opts, sizeof(opts), "fragment," - "man=%s/search.html?sec=%%S&expr=%%N," + "man=%s/search.html?sec=%%S&expr=Nm~^%%N$," /*"includes=/cgi-bin/man.cgi/usr/include/%%I"*/, progname); @@ -777,7 +776,7 @@ pg_show(const struct req *req, char *path) struct manpaths ps; size_t sz; char *sub; - char file[MAXPATHLEN]; + char file[PATH_MAX]; const char *cp; int rc, catm; unsigned int vol, rec, mr; @@ -831,10 +830,10 @@ pg_show(const struct req *req, char *path) goto out; } - sz = strlcpy(file, ps.paths[vol], MAXPATHLEN); - assert(sz < MAXPATHLEN); - strlcat(file, "/", MAXPATHLEN); - strlcat(file, MANDOC_IDX, MAXPATHLEN); + sz = strlcpy(file, ps.paths[vol], PATH_MAX); + assert(sz < PATH_MAX); + strlcat(file, "/", PATH_MAX); + strlcat(file, MANDOC_IDX, PATH_MAX); /* Open the index recno(3) database. */ @@ -863,8 +862,8 @@ pg_show(const struct req *req, char *path) resp_baddb(); else { file[(int)sz] = '\0'; - strlcat(file, "/", MAXPATHLEN); - strlcat(file, cp, MAXPATHLEN); + strlcat(file, "/", PATH_MAX); + strlcat(file, cp, PATH_MAX); if (catm) catman(req, file); else @@ -973,7 +972,7 @@ int main(void) { int i; - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; DIR *cwd; struct req req; char *p, *path, *subpath; @@ -1010,7 +1009,7 @@ main(void) memset(&req, 0, sizeof(struct req)); - strlcpy(buf, ".", MAXPATHLEN); + strlcpy(buf, ".", PATH_MAX); pathgen(cwd, buf, &req); closedir(cwd); @@ -1120,8 +1119,8 @@ pathgen(DIR *dir, char *path, struct req *req) int rc; size_t sz, ssz; - sz = strlcat(path, "/", MAXPATHLEN); - if (sz >= MAXPATHLEN) { + sz = strlcat(path, "/", PATH_MAX); + if (sz >= PATH_MAX) { fprintf(stderr, "%s: Path too long", path); return; } @@ -1138,9 +1137,9 @@ pathgen(DIR *dir, char *path, struct req *req) continue; path[(int)sz] = '\0'; - ssz = strlcat(path, d->d_name, MAXPATHLEN); + ssz = strlcat(path, d->d_name, PATH_MAX); - if (ssz >= MAXPATHLEN) { + if (ssz >= PATH_MAX) { fprintf(stderr, "%s: Path too long", path); return; } else if (NULL == (cd = opendir(path))) { @@ -1187,9 +1186,9 @@ pathgen(DIR *dir, char *path, struct req *req) continue; path[(int)sz] = '\0'; - ssz = strlcat(path, d->d_name, MAXPATHLEN); + ssz = strlcat(path, d->d_name, PATH_MAX); - if (ssz >= MAXPATHLEN) { + if (ssz >= PATH_MAX) { fprintf(stderr, "%s: Path too long", path); return; } else if (NULL == (cd = opendir(path))) { diff --git a/contrib/mdocml/chars.c b/contrib/mdocml/chars.c index ce03347b5d..3ad1f57471 100644 --- a/contrib/mdocml/chars.c +++ b/contrib/mdocml/chars.c @@ -1,4 +1,4 @@ -/* $Id: chars.c,v 1.52 2011/11/08 00:15:23 kristaps Exp $ */ +/* $Id: chars.c,v 1.54 2013/06/20 22:39:30 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -37,7 +37,7 @@ struct ln { int unicode; }; -#define LINES_MAX 328 +#define LINES_MAX 329 #define CHAR(in, ch, code) \ { NULL, (in), (ch), (code) }, @@ -77,7 +77,7 @@ mchars_alloc(void) */ tab = mandoc_malloc(sizeof(struct mchars)); - htab = mandoc_calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **)); + 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; diff --git a/contrib/mdocml/chars.in b/contrib/mdocml/chars.in index a4c45b3c43..cc6549e7e5 100644 --- a/contrib/mdocml/chars.in +++ b/contrib/mdocml/chars.in @@ -1,4 +1,4 @@ -/* $Id: chars.in,v 1.42 2011/10/02 10:02:26 kristaps Exp $ */ +/* $Id: chars.in,v 1.43 2013/06/20 22:39:30 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -42,6 +42,7 @@ CHAR("&", "", 0) CHAR("^", "", 0) CHAR("|", "", 0) CHAR("}", "", 0) +CHAR("t", "", 0) /* Accents. */ CHAR("a\"", "\"", 779) diff --git a/contrib/mdocml/config.h.post b/contrib/mdocml/config.h.post index 39da2b2f06..cee82aa1c3 100644 --- a/contrib/mdocml/config.h.post +++ b/contrib/mdocml/config.h.post @@ -15,14 +15,13 @@ # 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) +#ifndef HAVE_BETOH64 +# if defined(__APPLE__) +# define betoh64(x) OSSwapBigToHostInt64(x) +# define htobe64(x) OSSwapHostToBigInt64(x) +# else +# define betoh64(x) be64toh(x) +# endif #endif #ifndef HAVE_STRLCAT diff --git a/contrib/mdocml/demandoc.1 b/contrib/mdocml/demandoc.1 index 845b9c14b5..84571baf30 100644 --- a/contrib/mdocml/demandoc.1 +++ b/contrib/mdocml/demandoc.1 @@ -1,4 +1,4 @@ -.\" $Id: demandoc.1,v 1.6 2011/12/25 19:35:44 kristaps Exp $ +.\" $Id: demandoc.1,v 1.7 2013/07/13 19:41:16 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 25 2011 $ +.Dd $Mdocdate: July 13 2013 $ .Dt DEMANDOC 1 .Os .Sh NAME @@ -105,5 +105,4 @@ documents. The .Nm utility was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/demandoc.c b/contrib/mdocml/demandoc.c index 2474a358e2..aad42085b1 100644 --- a/contrib/mdocml/demandoc.c +++ b/contrib/mdocml/demandoc.c @@ -1,4 +1,4 @@ -/* $Id: demandoc.c,v 1.6 2011/09/01 22:25:53 kristaps Exp $ */ +/* $Id: demandoc.c,v 1.7 2012/05/31 22:27:14 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -76,7 +76,7 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL); + mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL, NULL); assert(mp); if (0 == argc) diff --git a/contrib/mdocml/eqn.7 b/contrib/mdocml/eqn.7 index f86b9c496b..dcbad41cc1 100644 --- a/contrib/mdocml/eqn.7 +++ b/contrib/mdocml/eqn.7 @@ -1,4 +1,4 @@ -.\" $Id: eqn.7,v 1.28 2011/09/25 18:37:09 schwarze Exp $ +.\" $Id: eqn.7,v 1.29 2013/07/13 19:41:16 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 25 2011 $ +.Dd $Mdocdate: July 13 2013 $ .Dt EQN 7 .Os .Sh NAME @@ -276,5 +276,4 @@ was added in 2011. This .Nm reference was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/gmdiff b/contrib/mdocml/gmdiff new file mode 100644 index 0000000000..a5bca9d31c --- /dev/null +++ b/contrib/mdocml/gmdiff @@ -0,0 +1,35 @@ +#!/bin/sh +# Copyright (c) 2013 Ingo Schwarze +# +# 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. + +if [ `id -u` -eq 0 ]; then + echo "$0: do not run me as root" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "usage: $0 manual_source_file ..." + exit 1 +fi + +while [ -n "$1" ]; do + file=$1 + shift + echo " ========== $file ========== " + tbl $file | groff -mandoc -Tascii -P -c 2>&1 > /tmp/groff.out + mandoc -Ios='OpenBSD ports' -Werror $file 2>&1 > /tmp/mandoc.out + diff -au /tmp/groff.out /tmp/mandoc.out 2>&1 +done + +exit 0 diff --git a/contrib/mdocml/html.c b/contrib/mdocml/html.c index 326df035fc..9d28b4270e 100644 --- a/contrib/mdocml/html.c +++ b/contrib/mdocml/html.c @@ -1,7 +1,7 @@ -/* $Id: html.c,v 1.150 2011/10/05 21:35:17 kristaps Exp $ */ +/* $Id: html.c,v 1.152 2013/08/08 20:07:47 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2011, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -235,6 +235,9 @@ print_metaf(struct html *h, enum mandoc_esc deco) case (ESCAPE_FONTBOLD): font = HTMLFONT_BOLD; break; + case (ESCAPE_FONTBI): + font = HTMLFONT_BI; + break; case (ESCAPE_FONT): /* FALLTHROUGH */ case (ESCAPE_FONTROMAN): @@ -253,17 +256,27 @@ print_metaf(struct html *h, enum mandoc_esc deco) h->metal = h->metac; h->metac = font; - if (HTMLFONT_NONE != font) - h->metaf = HTMLFONT_BOLD == font ? - print_otag(h, TAG_B, 0, NULL) : - print_otag(h, TAG_I, 0, NULL); + switch (font) { + case (HTMLFONT_ITALIC): + h->metaf = print_otag(h, TAG_I, 0, NULL); + break; + case (HTMLFONT_BOLD): + h->metaf = print_otag(h, TAG_B, 0, NULL); + break; + case (HTMLFONT_BI): + h->metaf = print_otag(h, TAG_B, 0, NULL); + print_otag(h, TAG_I, 0, NULL); + break; + default: + break; + } } int html_strlen(const char *cp) { - int ssz, sz; - const char *seq, *p; + size_t rsz; + int skip, sz; /* * Account for escaped sequences within string length @@ -274,10 +287,21 @@ html_strlen(const char *cp) */ sz = 0; - while (NULL != (p = strchr(cp, '\\'))) { - sz += (int)(p - cp); - ++cp; - switch (mandoc_escape(&cp, &seq, &ssz)) { + skip = 0; + while (1) { + rsz = strcspn(cp, "\\"); + if (rsz) { + cp += rsz; + if (skip) { + skip = 0; + rsz--; + } + sz += rsz; + } + if ('\0' == *cp) + break; + cp++; + switch (mandoc_escape(&cp, NULL, NULL)) { case (ESCAPE_ERROR): return(sz); case (ESCAPE_UNICODE): @@ -285,15 +309,19 @@ html_strlen(const char *cp) case (ESCAPE_NUMBERED): /* FALLTHROUGH */ case (ESCAPE_SPECIAL): - sz++; + if (skip) + skip = 0; + else + sz++; + break; + case (ESCAPE_SKIPCHAR): + skip = 1; break; default: break; } } - - assert(sz >= 0); - return(sz + strlen(cp)); + return(sz); } static int @@ -308,6 +336,12 @@ print_encode(struct html *h, const char *p, int norecurse) nospace = 0; while ('\0' != *p) { + if (HTML_SKIPCHAR & h->flags && '\\' != *p) { + h->flags &= ~HTML_SKIPCHAR; + p++; + continue; + } + sz = strcspn(p, rejs); fwrite(p, 1, sz, stdout); @@ -337,6 +371,33 @@ print_encode(struct html *h, const char *p, int norecurse) if (ESCAPE_ERROR == esc) break; + switch (esc) { + case (ESCAPE_FONT): + /* FALLTHROUGH */ + case (ESCAPE_FONTPREV): + /* FALLTHROUGH */ + case (ESCAPE_FONTBOLD): + /* FALLTHROUGH */ + case (ESCAPE_FONTITALIC): + /* FALLTHROUGH */ + case (ESCAPE_FONTBI): + /* FALLTHROUGH */ + case (ESCAPE_FONTROMAN): + if (0 == norecurse) + print_metaf(h, esc); + continue; + case (ESCAPE_SKIPCHAR): + h->flags |= HTML_SKIPCHAR; + continue; + default: + break; + } + + if (h->flags & HTML_SKIPCHAR) { + h->flags &= ~HTML_SKIPCHAR; + continue; + } + switch (esc) { case (ESCAPE_UNICODE): /* Skip passed "u" header. */ @@ -356,19 +417,6 @@ print_encode(struct html *h, const char *p, int norecurse) 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; @@ -511,10 +559,20 @@ print_text(struct html *h, const char *word) } assert(NULL == h->metaf); - if (HTMLFONT_NONE != h->metac) - h->metaf = HTMLFONT_BOLD == h->metac ? - print_otag(h, TAG_B, 0, NULL) : - print_otag(h, TAG_I, 0, NULL); + switch (h->metac) { + case (HTMLFONT_ITALIC): + h->metaf = print_otag(h, TAG_I, 0, NULL); + break; + case (HTMLFONT_BOLD): + h->metaf = print_otag(h, TAG_B, 0, NULL); + break; + case (HTMLFONT_BI): + h->metaf = print_otag(h, TAG_B, 0, NULL); + print_otag(h, TAG_I, 0, NULL); + break; + default: + break; + } assert(word); if ( ! print_encode(h, word, 0)) { diff --git a/contrib/mdocml/html.h b/contrib/mdocml/html.h index 60960702f1..894cfc4cff 100644 --- a/contrib/mdocml/html.h +++ b/contrib/mdocml/html.h @@ -1,4 +1,4 @@ -/* $Id: html.h,v 1.47 2011/10/05 21:35:17 kristaps Exp $ */ +/* $Id: html.h,v 1.49 2013/08/08 20:07:47 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -75,6 +75,7 @@ enum htmlfont { HTMLFONT_NONE = 0, HTMLFONT_BOLD, HTMLFONT_ITALIC, + HTMLFONT_BI, HTMLFONT_MAX }; @@ -117,6 +118,7 @@ struct html { #define HTML_PREKEEP (1 << 3) #define HTML_NONOSPACE (1 << 4) /* never add spaces */ #define HTML_LITERAL (1 << 5) /* literal (e.g.,
) context */
+#define	HTML_SKIPCHAR	 (1 << 6) /* skip the next character */
 	struct tagq	  tags; /* stack of open tags */
 	struct rofftbl	  tbl; /* current table */
 	struct tag	 *tblt; /* current open table scope */
diff --git a/contrib/mdocml/index.sgml b/contrib/mdocml/index.sgml
index 4386a9ebd9..e716635702 100644
--- a/contrib/mdocml/index.sgml
+++ b/contrib/mdocml/index.sgml
@@ -25,7 +25,7 @@
 			pages whilst providing token support for man.
 		

- Why? groff amounts to over 5 MB of source code, most of which is C++ and all of which is GPL. It runs slowly, produces + Why? groff amounts to over 5 MB of source code, most of which is C++ and GPL version 3. It runs slowly, produces uncertain output, and varies in operation from system to system. mdocml strives to fix this (respectively small, C, ISC-licensed, fast and regular).

@@ -55,15 +55,6 @@ run make install. Be careful: the preconv, apropos, and whatis binary names are usually taken by existing utilities.

-

- Binaries -

-

- Binary archives consist of pre-compiled binaries, manuals, and other necessary files. - Universal (Mac OS X) binaries are compiled for the PCC, i386, and x86_64 architectures. - Windows binaries are compiled with MingW for the 32-bit (i686) and - 64-bit (x86_64) architectures. -

Downstream

@@ -80,37 +71,52 @@ DragonFly BSD - usr.bin/mandoc + contrib/mdocml (1.12.1 sources) + lib/libmandoc + usr.bin/mandoc (build system) + + + + FreeBSD 10.0, -CURRENT + + contrib/mdocml (1.12.1 sources) + usr.bin/mandoc (build system) - FreeBSD + FreeBSD 9.x, 8.x - ports/textproc/mdocml + ports/textproc/mdocml (1.12.1 port) NetBSD - src/external/bsd/mdocml + src/external/bsd/mdocml (1.12.1 sources plus patches and build system) OpenBSD - src/usr.bin/mandoc + src/usr.bin/mandoc (1.12.2 sources and build system) pkgsrc - textproc/mdocml + textproc/mdocml (1.12.0 port) Minix3 - external/bsd/mdocml + external/bsd/mdocml (1.10.9 sources and build system) + + + + Alpine Linux + + aports/main/mdocml (1.12.1 port) @@ -131,150 +137,96 @@ apropos(1) search the manual page database - (text | - xhtml | - pdf | - ps) demandoc(1) emit only text of UNIX manuals - (text | - xhtml | - pdf | - ps) mandoc(1) format and display UNIX manuals - (text | - xhtml | - pdf | - ps) preconv(1) recode multibyte UNIX manuals - (text | - xhtml | - pdf | - ps) whatis(1) search the manual page database - (text | - xhtml | - pdf | - ps) mandoc(3) mandoc macro compiler library - (text | - xhtml | - pdf | - ps) - man(7) + tbl(3) - man language reference - (text | - xhtml | - pdf | - ps) + roff table parser library for mandoc - man.cgi(7) + eqn(7) - cgi for manpage query and display - (text | - xhtml | - pdf | - ps) + eqn-mandoc language reference - eqn(7) + man(7) - eqn-mandoc language reference - (text | - xhtml | - pdf | - ps) + man language reference + + + + man.cgi(7) + + cgi for manpage query and display mandoc_char(7) mandoc special characters - (text | - xhtml | - pdf | - ps) mdoc(7) mdoc language reference - (text | - xhtml | - pdf | - ps) roff(7) roff-mandoc language reference - (text | - xhtml | - pdf | - ps) tbl(7) tbl-mandoc language reference - (text | - xhtml | - pdf | - ps) catman(8) update a man.cgi manpage cache - (text | - xhtml | - pdf | - ps) mandocdb(8) index UNIX manuals - (text | - xhtml | - pdf | - ps) @@ -325,6 +277,52 @@

News

+

+ 02-10-2013: version 1.12.2 +

+

+ The mdoc(7) to man(7) converter, + to be called as mandoc -Tman, is now fully functional. +

+

+ The mandoc(1) utility now supports the -Ios (default operating system) + input option, and the -Tutf8 output mode now actually works. +

+

+ The mandocdb(8) utility no longer truncates existing databases when starting to build new ones, + but only replaces them when the build actually succeeds. +

+

+ The man(7) parser now supports the PD macro (paragraph distance), + and (for GNU man-ext compatibility only) EX (example block) and EE (example end). + Plus several bugfixes regarding indentation, line breaks, and vertical spacing, + and regarding RS following TP. +

+

+ The roff(7) parser now supports the \f(BI (bold+italic) font escape, + the \z (zero cursor advance) escape and the cc (change control character) + and it (input line trap) requests. + Plus bugfixes regarding the \t (tab) escape, nested escape sequences, and conditional requests. +

+

+ In mdoc(7), several bugs were fixed related to UTF-8 output of quoting enclosures, + delimiter handling, list indentation and horizontal and vertical spacing, + formatting of the Lk, %U, and %C macros, + plus some bugfixes related to the handling of syntax errors like badly nested font blocks, + stray Ta macros outside column lists, unterminated It Xo blocks, + and non-text children of Nm blocks. +

+

+ In tbl(7), the width of horizontal spans and the vertical spacing around tables was corrected, + and in man(7) files, a crash was fixed that was triggered by some particular unclosed T{ macros. +

+

+ For mandoc developers, we now provide a tbl(3) library manual and gmdiff, + a very small, very simplistic groff-versus-mandoc output comparison tool. +

+

+ See NEWS for historical notes. +

23-03-2011: version 1.12.1

@@ -357,7 +355,8 @@ Copyright © 2008–2011 Kristaps Dzonsons, - $Date: 2012/03/24 02:07:32 $ + © 2013 Ingo Schwarze, + $Date: 2013/10/05 14:05:09 $

diff --git a/contrib/mdocml/libman.h b/contrib/mdocml/libman.h index 4bc5128204..f2ba6a1256 100644 --- a/contrib/mdocml/libman.h +++ b/contrib/mdocml/libman.h @@ -1,4 +1,4 @@ -/* $Id: libman.h,v 1.55 2011/11/07 01:24:40 schwarze Exp $ */ +/* $Id: libman.h,v 1.56 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -39,7 +39,7 @@ struct man { struct roff *roff; }; -#define MACRO_PROT_ARGS struct man *m, \ +#define MACRO_PROT_ARGS struct man *man, \ enum mant tok, \ int line, \ int ppos, \ @@ -61,10 +61,10 @@ extern const struct man_macro *const man_macros; __BEGIN_DECLS -#define man_pmsg(m, l, p, t) \ - mandoc_msg((t), (m)->parse, (l), (p), NULL) -#define man_nmsg(m, n, t) \ - mandoc_msg((t), (m)->parse, (n)->line, (n)->pos, NULL) +#define man_pmsg(man, l, p, t) \ + mandoc_msg((t), (man)->parse, (l), (p), NULL) +#define man_nmsg(man, n, t) \ + mandoc_msg((t), (man)->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); diff --git a/contrib/mdocml/libmandoc.h b/contrib/mdocml/libmandoc.h index de422884a2..9b3ffee179 100644 --- a/contrib/mdocml/libmandoc.h +++ b/contrib/mdocml/libmandoc.h @@ -1,6 +1,6 @@ -/* $Id: libmandoc.h,v 1.29 2011/12/02 01:37:14 schwarze Exp $ */ +/* $Id: libmandoc.h,v 1.32 2012/11/19 17:57:23 schwarze Exp $ */ /* - * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -47,12 +47,11 @@ void mandoc_vmsg(enum mandocerr, struct mparse *, 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_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 *); +struct mdoc *mdoc_alloc(struct roff *, struct mparse *, char *); void mdoc_reset(struct mdoc *); int mdoc_parseln(struct mdoc *, int, char *, int); int mdoc_endparse(struct mdoc *); @@ -68,7 +67,7 @@ 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 *); +struct roff *roff_alloc(enum mparset, struct mparse *); void roff_reset(struct roff *); enum rofferr roff_parseln(struct roff *, int, char **, size_t *, int, int *); @@ -77,6 +76,8 @@ 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 *); +int roff_getcontrol(const struct roff *, + const char *, int *); #if 0 char roff_eqndelim(const struct roff *); void roff_openeqn(struct roff *, const char *, diff --git a/contrib/mdocml/libmdoc.h b/contrib/mdocml/libmdoc.h index af1729268a..8a389a4a56 100644 --- a/contrib/mdocml/libmdoc.h +++ b/contrib/mdocml/libmdoc.h @@ -1,4 +1,4 @@ -/* $Id: libmdoc.h,v 1.78 2011/12/02 01:37:14 schwarze Exp $ */ +/* $Id: libmdoc.h,v 1.81 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -24,6 +24,7 @@ enum mdoc_next { struct mdoc { struct mparse *parse; /* parse pointer */ + char *defos; /* default argument for .Os */ int flags; /* parse flags */ #define MDOC_HALT (1 << 0) /* error in parse: halt */ #define MDOC_LITERAL (1 << 1) /* in a literal scope */ @@ -42,7 +43,7 @@ struct mdoc { struct roff *roff; }; -#define MACRO_PROT_ARGS struct mdoc *m, \ +#define MACRO_PROT_ARGS struct mdoc *mdoc, \ enum mdoct tok, \ int line, \ int ppos, \ @@ -99,10 +100,10 @@ extern const struct mdoc_macro *const mdoc_macros; __BEGIN_DECLS -#define mdoc_pmsg(m, l, p, t) \ - mandoc_msg((t), (m)->parse, (l), (p), NULL) -#define mdoc_nmsg(m, n, t) \ - mandoc_msg((t), (m)->parse, (n)->line, (n)->pos, NULL) +#define mdoc_pmsg(mdoc, l, p, t) \ + mandoc_msg((t), (mdoc)->parse, (l), (p), NULL) +#define mdoc_nmsg(mdoc, n, t) \ + mandoc_msg((t), (mdoc)->parse, (n)->line, (n)->pos, NULL) int mdoc_macro(MACRO_PROT_ARGS); int mdoc_word_alloc(struct mdoc *, int, int, const char *); @@ -113,10 +114,10 @@ int mdoc_block_alloc(struct mdoc *, int, int, int mdoc_head_alloc(struct mdoc *, int, int, enum mdoct); int mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct); int mdoc_body_alloc(struct mdoc *, int, int, enum mdoct); -int mdoc_endbody_alloc(struct mdoc *m, int line, int pos, - enum mdoct tok, struct mdoc_node *body, - enum mdoc_endbody end); +int mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct, + struct mdoc_node *, enum mdoc_endbody); void mdoc_node_delete(struct mdoc *, struct mdoc_node *); +int mdoc_node_relink(struct mdoc *, struct mdoc_node *); void mdoc_hash_init(void); enum mdoct mdoc_hash_find(const char *); const char *mdoc_a2att(const char *); diff --git a/contrib/mdocml/libroff.h b/contrib/mdocml/libroff.h index 0bdd5a3604..5b84c5fc45 100644 --- a/contrib/mdocml/libroff.h +++ b/contrib/mdocml/libroff.h @@ -1,4 +1,4 @@ -/* $Id: libroff.h,v 1.27 2011/07/25 15:37:00 kristaps Exp $ */ +/* $Id: libroff.h,v 1.28 2013/05/31 21:37:17 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -31,7 +31,7 @@ struct tbl_node { int pos; /* invocation column */ int line; /* invocation line */ enum tbl_part part; - struct tbl opts; + struct tbl_opts opts; struct tbl_row *first_row; struct tbl_row *last_row; struct tbl_span *first_span; diff --git a/contrib/mdocml/main.c b/contrib/mdocml/main.c index fec83fba51..7e5c7a98ae 100644 --- a/contrib/mdocml/main.c +++ b/contrib/mdocml/main.c @@ -1,7 +1,7 @@ -/* $Id: main.c,v 1.165 2011/10/06 22:29:12 kristaps Exp $ */ +/* $Id: main.c,v 1.167 2012/11/19 17:22:26 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2011 Ingo Schwarze + * Copyright (c) 2010, 2011, 2012 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -85,6 +85,7 @@ main(int argc, char *argv[]) struct curparse curp; enum mparset type; enum mandoclevel rc; + char *defos; progname = strrchr(argv[0], '/'); if (progname == NULL) @@ -97,10 +98,24 @@ main(int argc, char *argv[]) type = MPARSE_AUTO; curp.outtype = OUTT_ASCII; curp.wlevel = MANDOCLEVEL_FATAL; + defos = NULL; /* LINTED */ - while (-1 != (c = getopt(argc, argv, "m:O:T:VW:"))) + while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:"))) switch (c) { + case ('I'): + if (strncmp(optarg, "os=", 3)) { + fprintf(stderr, "-I%s: Bad argument\n", + optarg); + return((int)MANDOCLEVEL_BADARG); + } + if (defos) { + fprintf(stderr, "-I%s: Duplicate argument\n", + optarg); + return((int)MANDOCLEVEL_BADARG); + } + defos = mandoc_strdup(optarg + 3); + break; case ('m'): if ( ! moptions(&type, optarg)) return((int)MANDOCLEVEL_BADARG); @@ -125,7 +140,7 @@ main(int argc, char *argv[]) /* NOTREACHED */ } - curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp); + curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp, defos); /* * Conditionally start up the lookaside buffer before parsing. @@ -152,6 +167,7 @@ main(int argc, char *argv[]) (*curp.outfree)(curp.outdata); if (curp.mp) mparse_free(curp.mp); + free(defos); return((int)rc); } @@ -170,12 +186,12 @@ usage(void) fprintf(stderr, "usage: %s " "[-V] " - "[-foption] " + "[-Ios=name] " "[-mformat] " "[-Ooption] " "[-Toutput] " - "[-Wlevel] " - "[file...]\n", + "[-Wlevel]\n" + "\t [file ...]\n", progname); exit((int)MANDOCLEVEL_BADARG); diff --git a/contrib/mdocml/man.7 b/contrib/mdocml/man.7 index 1715a7ca11..f2f4d1d8c0 100644 --- a/contrib/mdocml/man.7 +++ b/contrib/mdocml/man.7 @@ -1,7 +1,7 @@ -.\" $Id: man.7,v 1.113 2012/01/03 15:16:24 kristaps Exp $ +.\" $Id: man.7,v 1.120 2013/09/16 22:58:57 schwarze Exp $ .\" -.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons -.\" Copyright (c) 2011 Ingo Schwarze +.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons +.\" Copyright (c) 2011, 2012 Ingo Schwarze .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 3 2012 $ +.Dd $Mdocdate: September 16 2013 $ .Dt MAN 7 .Os .Sh NAME @@ -253,6 +253,7 @@ in the alphabetical reference below. .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 PD Ta set vertical paragraph distance: Op Ar height .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) @@ -272,10 +273,6 @@ in the alphabetical reference below. .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. @@ -343,6 +340,18 @@ and .Ss \&DT Has no effect. Included for compatibility. +.Ss \&EE +This is a non-standard GNU extension, included only for compatibility. +In +.Xr mandoc 1 , +it does the same as +.Sx \&fi . +.Ss \&EX +This is a non-standard GNU extension, included only for compatibility. +In +.Xr mandoc 1 , +it does the same as +.Sx \&nf . .Ss \&HP Begin a paragraph whose initial output line is left-justified, but subsequent output lines are indented, with the following syntax: @@ -353,8 +362,9 @@ subsequent output lines are indented, with the following syntax: .Pp The .Cm width -argument must conform to -.Sx Scaling Widths . +argument is a +.Xr roff 7 +scaling width. If specified, it's saved for later paragraph left-margins; if unspecified, the saved or default width is used. .Pp @@ -396,8 +406,9 @@ Begin an indented paragraph with the following syntax: .Pp The .Cm width -argument defines the width of the left margin and is defined by -.Sx Scaling Widths . +argument is a +.Xr roff 7 +scaling width defining the left margin. It's saved for later paragraph left-margins; if unspecified, the saved or default width is used. .Pp @@ -443,7 +454,8 @@ and .Sx \&TP . .Ss \&OP Optional command-line argument. -This has the following syntax: +This is a non-standard GNU extension, included only for compatibility. +It has the following syntax: .Bd -filled -offset indent .Pf \. Sx \&OP .Cm key Op Cm value @@ -465,6 +477,36 @@ See also .Sx \&PP , and .Sx \&TP . +.Ss \&PD +Specify the vertical space to be inserted before each new paragraph. +.br +The syntax is as follows: +.Bd -filled -offset indent +.Pf \. Sx \&PD +.Op Cm height +.Ed +.Pp +The +.Cm height +argument is a +.Xr roff 7 +scaling width. +It defaults to +.Cm 1v . +If the unit is omitted, +.Cm v +is assumed. +.Pp +This macro affects the spacing before any subsequent instances of +.Sx \&HP , +.Sx \&IP , +.Sx \&LP , +.Sx \&P , +.Sx \&PP , +.Sx \&SH , +.Sx \&SS , +and +.Sx \&TP . .Ss \&PP Synonym for .Sx \&LP . @@ -529,8 +571,9 @@ This has the following syntax: .Pp The .Cm width -argument must conform to -.Sx Scaling Widths . +argument is a +.Xr roff 7 +scaling width. If not specified, the saved or default width is used. .Pp See also @@ -595,8 +638,9 @@ The syntax is as follows: .Pp The .Cm width -argument must conform to -.Sx Scaling Widths . +argument is a +.Xr roff 7 +scaling width. If specified, it's saved for later paragraph left-margins; if unspecified, the saved or default width is used. .Pp @@ -609,7 +653,8 @@ and .Sx \&PP . .Ss \&UC Sets the volume for the footer for compatibility with man pages from -BSD releases. +.Bx +releases. The optional first argument specifies which release it is from. .Ss \&br Breaks the current line. @@ -653,10 +698,10 @@ Insert vertical spaces into output with the following syntax: .Op Cm height .Ed .Pp -Insert +The .Cm height -spaces, which must conform to -.Sx Scaling Widths . +argument is a scaling width as described in +.Xr roff 7 . If 0, this is equivalent to the .Sx \&br macro. @@ -904,8 +949,7 @@ utility written by Kristaps Dzonsons appeared in This .Nm reference was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . .Sh CAVEATS Do not use this language. Use diff --git a/contrib/mdocml/man.c b/contrib/mdocml/man.c index 1bea5610e3..24ffc6389f 100644 --- a/contrib/mdocml/man.c +++ b/contrib/mdocml/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.115 2012/01/03 15:16:24 kristaps Exp $ */ +/* $Id: man.c,v 1.119 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -40,7 +40,7 @@ const char *const __man_macronames[MAN_MAX] = { "RI", "na", "sp", "nf", "fi", "RE", "RS", "DT", "UC", "PD", "AT", "in", - "ft", "OP" + "ft", "OP", "EX", "EE" }; const char * const *man_macronames = __man_macronames; @@ -60,20 +60,20 @@ static int man_descope(struct man *, int, int); const struct man_node * -man_node(const struct man *m) +man_node(const struct man *man) { - assert( ! (MAN_HALT & m->flags)); - return(m->first); + assert( ! (MAN_HALT & man->flags)); + return(man->first); } const struct man_meta * -man_meta(const struct man *m) +man_meta(const struct man *man) { - assert( ! (MAN_HALT & m->flags)); - return(&m->meta); + assert( ! (MAN_HALT & man->flags)); + return(&man->meta); } @@ -112,28 +112,28 @@ man_alloc(struct roff *roff, struct mparse *parse) int -man_endparse(struct man *m) +man_endparse(struct man *man) { - assert( ! (MAN_HALT & m->flags)); - if (man_macroend(m)) + assert( ! (MAN_HALT & man->flags)); + if (man_macroend(man)) return(1); - m->flags |= MAN_HALT; + man->flags |= MAN_HALT; return(0); } int -man_parseln(struct man *m, int ln, char *buf, int offs) +man_parseln(struct man *man, int ln, char *buf, int offs) { - m->flags |= MAN_NEWLINE; + man->flags |= MAN_NEWLINE; - assert( ! (MAN_HALT & m->flags)); + assert( ! (MAN_HALT & man->flags)); - return (mandoc_getcontrol(buf, &offs) ? - man_pmacro(m, ln, buf, offs) : - man_ptext(m, ln, buf, offs)); + return (roff_getcontrol(man->roff, buf, &offs) ? + man_pmacro(man, ln, buf, offs) : + man_ptext(man, ln, buf, offs)); } @@ -157,16 +157,16 @@ man_free1(struct man *man) static void -man_alloc1(struct man *m) +man_alloc1(struct man *man) { - memset(&m->meta, 0, sizeof(struct man_meta)); - m->flags = 0; - m->last = mandoc_calloc(1, sizeof(struct man_node)); - m->first = m->last; - m->last->type = MAN_ROOT; - m->last->tok = MAN_MAX; - m->next = MAN_NEXT_CHILD; + memset(&man->meta, 0, sizeof(struct man_meta)); + man->flags = 0; + man->last = mandoc_calloc(1, sizeof(struct man_node)); + man->first = man->last; + man->last->type = MAN_ROOT; + man->last->tok = MAN_MAX; + man->next = MAN_NEXT_CHILD; } @@ -234,7 +234,7 @@ man_node_append(struct man *man, struct man_node *p) static struct man_node * -man_node_alloc(struct man *m, int line, int pos, +man_node_alloc(struct man *man, int line, int pos, enum man_type type, enum mant tok) { struct man_node *p; @@ -245,89 +245,89 @@ man_node_alloc(struct man *m, int line, int pos, p->type = type; p->tok = tok; - if (MAN_NEWLINE & m->flags) + if (MAN_NEWLINE & man->flags) p->flags |= MAN_LINE; - m->flags &= ~MAN_NEWLINE; + man->flags &= ~MAN_NEWLINE; return(p); } int -man_elem_alloc(struct man *m, int line, int pos, enum mant tok) +man_elem_alloc(struct man *man, int line, int pos, enum mant tok) { struct man_node *p; - p = man_node_alloc(m, line, pos, MAN_ELEM, tok); - if ( ! man_node_append(m, p)) + p = man_node_alloc(man, line, pos, MAN_ELEM, tok); + if ( ! man_node_append(man, p)) return(0); - m->next = MAN_NEXT_CHILD; + man->next = MAN_NEXT_CHILD; return(1); } int -man_tail_alloc(struct man *m, int line, int pos, enum mant tok) +man_tail_alloc(struct man *man, 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)) + p = man_node_alloc(man, line, pos, MAN_TAIL, tok); + if ( ! man_node_append(man, p)) return(0); - m->next = MAN_NEXT_CHILD; + man->next = MAN_NEXT_CHILD; return(1); } int -man_head_alloc(struct man *m, int line, int pos, enum mant tok) +man_head_alloc(struct man *man, int line, int pos, enum mant tok) { struct man_node *p; - p = man_node_alloc(m, line, pos, MAN_HEAD, tok); - if ( ! man_node_append(m, p)) + p = man_node_alloc(man, line, pos, MAN_HEAD, tok); + if ( ! man_node_append(man, p)) return(0); - m->next = MAN_NEXT_CHILD; + man->next = MAN_NEXT_CHILD; return(1); } int -man_body_alloc(struct man *m, int line, int pos, enum mant tok) +man_body_alloc(struct man *man, int line, int pos, enum mant tok) { struct man_node *p; - p = man_node_alloc(m, line, pos, MAN_BODY, tok); - if ( ! man_node_append(m, p)) + p = man_node_alloc(man, line, pos, MAN_BODY, tok); + if ( ! man_node_append(man, p)) return(0); - m->next = MAN_NEXT_CHILD; + man->next = MAN_NEXT_CHILD; return(1); } int -man_block_alloc(struct man *m, int line, int pos, enum mant tok) +man_block_alloc(struct man *man, int line, int pos, enum mant tok) { struct man_node *p; - p = man_node_alloc(m, line, pos, MAN_BLOCK, tok); - if ( ! man_node_append(m, p)) + p = man_node_alloc(man, line, pos, MAN_BLOCK, tok); + if ( ! man_node_append(man, p)) return(0); - m->next = MAN_NEXT_CHILD; + man->next = MAN_NEXT_CHILD; return(1); } int -man_word_alloc(struct man *m, int line, int pos, const char *word) +man_word_alloc(struct man *man, int line, int pos, const char *word) { struct man_node *n; - n = man_node_alloc(m, line, pos, MAN_TEXT, MAN_MAX); - n->string = roff_strdup(m->roff, word); + n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX); + n->string = roff_strdup(man->roff, word); - if ( ! man_node_append(m, n)) + if ( ! man_node_append(man, n)) return(0); - m->next = MAN_NEXT_SIBLING; + man->next = MAN_NEXT_SIBLING; return(1); } @@ -347,52 +347,52 @@ man_node_free(struct man_node *p) void -man_node_delete(struct man *m, struct man_node *p) +man_node_delete(struct man *man, struct man_node *p) { while (p->child) - man_node_delete(m, p->child); + man_node_delete(man, p->child); - man_node_unlink(m, p); + man_node_unlink(man, p); man_node_free(p); } int -man_addeqn(struct man *m, const struct eqn *ep) +man_addeqn(struct man *man, const struct eqn *ep) { struct man_node *n; - assert( ! (MAN_HALT & m->flags)); + assert( ! (MAN_HALT & man->flags)); - n = man_node_alloc(m, ep->ln, ep->pos, MAN_EQN, MAN_MAX); + n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX); n->eqn = ep; - if ( ! man_node_append(m, n)) + if ( ! man_node_append(man, n)) return(0); - m->next = MAN_NEXT_SIBLING; - return(man_descope(m, ep->ln, ep->pos)); + man->next = MAN_NEXT_SIBLING; + return(man_descope(man, ep->ln, ep->pos)); } int -man_addspan(struct man *m, const struct tbl_span *sp) +man_addspan(struct man *man, const struct tbl_span *sp) { struct man_node *n; - assert( ! (MAN_HALT & m->flags)); + assert( ! (MAN_HALT & man->flags)); - n = man_node_alloc(m, sp->line, 0, MAN_TBL, MAN_MAX); + n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX); n->span = sp; - if ( ! man_node_append(m, n)) + if ( ! man_node_append(man, n)) return(0); - m->next = MAN_NEXT_SIBLING; - return(man_descope(m, sp->line, 0)); + man->next = MAN_NEXT_SIBLING; + return(man_descope(man, sp->line, 0)); } static int -man_descope(struct man *m, int line, int offs) +man_descope(struct man *man, int line, int offs) { /* * Co-ordinate what happens with having a next-line scope open: @@ -400,32 +400,32 @@ man_descope(struct man *m, int line, int offs) * out the block scope (also if applicable). */ - if (MAN_ELINE & m->flags) { - m->flags &= ~MAN_ELINE; - if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX)) + if (MAN_ELINE & man->flags) { + man->flags &= ~MAN_ELINE; + if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX)) return(0); } - if ( ! (MAN_BLINE & m->flags)) + if ( ! (MAN_BLINE & man->flags)) return(1); - m->flags &= ~MAN_BLINE; + man->flags &= ~MAN_BLINE; - if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX)) + if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX)) return(0); - return(man_body_alloc(m, line, offs, m->last->tok)); + return(man_body_alloc(man, line, offs, man->last->tok)); } static int -man_ptext(struct man *m, int line, char *buf, int offs) +man_ptext(struct man *man, int line, char *buf, int offs) { int i; /* Literal free-form text whitespace is preserved. */ - if (MAN_LITERAL & m->flags) { - if ( ! man_word_alloc(m, line, offs, buf + offs)) + if (MAN_LITERAL & man->flags) { + if ( ! man_word_alloc(man, line, offs, buf + offs)) return(0); - return(man_descope(m, line, offs)); + return(man_descope(man, line, offs)); } /* Pump blank lines directly into the backend. */ @@ -435,9 +435,10 @@ man_ptext(struct man *m, int line, char *buf, int offs) if ('\0' == buf[i]) { /* Allocate a blank entry. */ - if ( ! man_word_alloc(m, line, offs, "")) + if ( ! man_elem_alloc(man, line, offs, MAN_sp)) return(0); - return(man_descope(m, line, offs)); + man->next = MAN_NEXT_SIBLING; + return(1); } /* @@ -450,7 +451,7 @@ man_ptext(struct man *m, int line, char *buf, int offs) if (' ' == buf[i - 1] || '\t' == buf[i - 1]) { if (i > 1 && '\\' != buf[i - 2]) - man_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE); + man_pmsg(man, line, i - 1, MANDOCERR_EOLNSPACE); for (--i; i && ' ' == buf[i]; i--) /* Spin back to non-space. */ ; @@ -461,7 +462,7 @@ man_ptext(struct man *m, int line, char *buf, int offs) buf[i] = '\0'; } - if ( ! man_word_alloc(m, line, offs, buf + offs)) + if ( ! man_word_alloc(man, line, offs, buf + offs)) return(0); /* @@ -472,13 +473,13 @@ man_ptext(struct man *m, int line, char *buf, int offs) assert(i); if (mandoc_eos(buf, (size_t)i, 0)) - m->last->flags |= MAN_EOS; + man->last->flags |= MAN_EOS; - return(man_descope(m, line, offs)); + return(man_descope(man, line, offs)); } static int -man_pmacro(struct man *m, int ln, char *buf, int offs) +man_pmacro(struct man *man, int ln, char *buf, int offs) { int i, ppos; enum mant tok; @@ -486,7 +487,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) struct man_node *n; if ('"' == buf[offs]) { - man_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT); + man_pmsg(man, ln, offs, MANDOCERR_BADCOMMENT); return(1); } else if ('\0' == buf[offs]) return(1); @@ -508,7 +509,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX; if (MAN_MAX == tok) { - mandoc_vmsg(MANDOCERR_MACRO, m->parse, ln, + mandoc_vmsg(MANDOCERR_MACRO, man->parse, ln, ppos, "%s", buf + ppos - 1); return(1); } @@ -524,7 +525,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) */ if ('\0' == buf[offs] && ' ' == buf[offs - 1]) - man_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE); + man_pmsg(man, ln, offs - 1, MANDOCERR_EOLNSPACE); /* * Remove prior ELINE macro, as it's being clobbered by a new @@ -533,8 +534,8 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) */ if ( ! (MAN_NSCOPED & man_macros[tok].flags) && - m->flags & MAN_ELINE) { - n = m->last; + man->flags & MAN_ELINE) { + n = man->last; assert(MAN_TEXT != n->type); /* Remove repeated NSCOPED macros causing ELINE. */ @@ -542,20 +543,20 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) if (MAN_NSCOPED & man_macros[n->tok].flags) n = n->parent; - mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line, + mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line, n->pos, "%s breaks %s", man_macronames[tok], man_macronames[n->tok]); - man_node_delete(m, n); - m->flags &= ~MAN_ELINE; + man_node_delete(man, n); + man->flags &= ~MAN_ELINE; } /* * Remove prior BLINE macro that is being clobbered. */ - if ((m->flags & MAN_BLINE) && + if ((man->flags & MAN_BLINE) && (MAN_BSCOPE & man_macros[tok].flags)) { - n = m->last; + n = man->last; /* Might be a text node like 8 in * .TP 8 @@ -573,12 +574,12 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) assert(MAN_BLOCK == n->type); assert(MAN_SCOPED & man_macros[n->tok].flags); - mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line, + mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line, n->pos, "%s breaks %s", man_macronames[tok], man_macronames[n->tok]); - man_node_delete(m, n); - m->flags &= ~MAN_BLINE; + man_node_delete(man, n); + man->flags &= ~MAN_BLINE; } /* @@ -587,13 +588,13 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) * when they exit. */ - if (MAN_BLINE & m->flags) - m->flags |= MAN_BPLINE; + if (MAN_BLINE & man->flags) + man->flags |= MAN_BPLINE; /* Call to handler... */ assert(man_macros[tok].fp); - if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &offs, buf)) + if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf)) goto err; /* @@ -601,19 +602,19 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) * above-parsed macro, so return. */ - if ( ! (MAN_BPLINE & m->flags)) { - m->flags &= ~MAN_ILINE; + if ( ! (MAN_BPLINE & man->flags)) { + man->flags &= ~MAN_ILINE; return(1); } - m->flags &= ~MAN_BPLINE; + man->flags &= ~MAN_BPLINE; /* * If we're in a block scope, then allow this macro to slip by * without closing scope around it. */ - if (MAN_ILINE & m->flags) { - m->flags &= ~MAN_ILINE; + if (MAN_ILINE & man->flags) { + man->flags &= ~MAN_ILINE; return(1); } @@ -622,30 +623,30 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) * now, as the next line will close out the block scope. */ - if (MAN_ELINE & m->flags) + if (MAN_ELINE & man->flags) return(1); /* Close out the block scope opened in the prior line. */ - assert(MAN_BLINE & m->flags); - m->flags &= ~MAN_BLINE; + assert(MAN_BLINE & man->flags); + man->flags &= ~MAN_BLINE; - if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX)) + if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX)) return(0); - return(man_body_alloc(m, ln, ppos, m->last->tok)); + return(man_body_alloc(man, ln, ppos, man->last->tok)); err: /* Error out. */ - m->flags |= MAN_HALT; + man->flags |= MAN_HALT; return(0); } /* - * Unlink a node from its context. If "m" is provided, the last parse + * Unlink a node from its context. If "man" is provided, the last parse * point will also be adjusted accordingly. */ static void -man_node_unlink(struct man *m, struct man_node *n) +man_node_unlink(struct man *man, struct man_node *n) { /* Adjust siblings. */ @@ -665,26 +666,26 @@ man_node_unlink(struct man *m, struct man_node *n) /* Adjust parse point, if applicable. */ - if (m && m->last == n) { + if (man && man->last == n) { /*XXX: this can occur when bailing from validation. */ /*assert(NULL == n->next);*/ if (n->prev) { - m->last = n->prev; - m->next = MAN_NEXT_SIBLING; + man->last = n->prev; + man->next = MAN_NEXT_SIBLING; } else { - m->last = n->parent; - m->next = MAN_NEXT_CHILD; + man->last = n->parent; + man->next = MAN_NEXT_CHILD; } } - if (m && m->first == n) - m->first = NULL; + if (man && man->first == n) + man->first = NULL; } const struct mparse * -man_mparse(const struct man *m) +man_mparse(const struct man *man) { - assert(m && m->parse); - return(m->parse); + assert(man && man->parse); + return(man->parse); } diff --git a/contrib/mdocml/man.cgi.7 b/contrib/mdocml/man.cgi.7 index b7afd84b90..ec927ca9b1 100644 --- a/contrib/mdocml/man.cgi.7 +++ b/contrib/mdocml/man.cgi.7 @@ -1,4 +1,4 @@ -.Dd $Mdocdate: March 24 2012 $ +.Dd $Mdocdate: July 13 2013 $ .Dt MAN.CGI 7 .Os .Sh NAME @@ -114,8 +114,7 @@ However, the results may not be quite the same. The .Nm utility was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . .Sh CAVEATS If you're running in a jailed web-server, make sure the .Pa /tmp diff --git a/contrib/mdocml/man.h b/contrib/mdocml/man.h index 4fc3934e6f..e85da9aef0 100644 --- a/contrib/mdocml/man.h +++ b/contrib/mdocml/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.60 2012/01/03 15:16:24 kristaps Exp $ */ +/* $Id: man.h,v 1.61 2012/06/02 20:16:23 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -52,6 +52,8 @@ enum mant { MAN_in, MAN_ft, MAN_OP, + MAN_EX, + MAN_EE, MAN_MAX }; diff --git a/contrib/mdocml/man_html.c b/contrib/mdocml/man_html.c index a76ea2d707..100188bd52 100644 --- a/contrib/mdocml/man_html.c +++ b/contrib/mdocml/man_html.c @@ -1,6 +1,6 @@ -/* $Id: man_html.c,v 1.86 2012/01/03 15:16:24 kristaps Exp $ */ +/* $Id: man_html.c,v 1.89 2012/11/17 00:26:33 schwarze Exp $ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2008-2012 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,7 +37,7 @@ #define INDENT 5 -#define MAN_ARGS const struct man_meta *m, \ +#define MAN_ARGS const struct man_meta *man, \ const struct man_node *n, \ struct mhtml *mh, \ struct html *h @@ -113,6 +113,8 @@ static const struct htmlman mans[MAN_MAX] = { { man_in_pre, NULL }, /* in */ { man_ign_pre, NULL }, /* ft */ { man_OP_pre, NULL }, /* OP */ + { man_literal_pre, NULL }, /* EX */ + { man_literal_pre, NULL }, /* EE */ }; /* @@ -139,12 +141,12 @@ print_bvspace(struct html *h, const struct man_node *n) } void -html_man(void *arg, const struct man *m) +html_man(void *arg, const struct man *man) { struct mhtml mh; memset(&mh, 0, sizeof(struct mhtml)); - print_man(man_meta(m), man_node(m), &mh, (struct html *)arg); + print_man(man_meta(man), man_node(man), &mh, (struct html *)arg); putchar('\n'); } @@ -160,14 +162,14 @@ print_man(MAN_ARGS) 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_man_head(man, n, mh, h); 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); - print_man_nodelist(m, n, mh, h); + print_man_nodelist(man, n, mh, h); print_tagq(h, t); } @@ -178,9 +180,9 @@ print_man_head(MAN_ARGS) { print_gen_head(h); - assert(m->title); - assert(m->msec); - bufcat_fmt(h, "%s(%s)", m->title, m->msec); + assert(man->title); + assert(man->msec); + bufcat_fmt(h, "%s(%s)", man->title, man->msec); print_otag(h, TAG_TITLE, 0, NULL); print_text(h, h->buf); } @@ -190,9 +192,9 @@ static void print_man_nodelist(MAN_ARGS) { - print_man_node(m, n, mh, h); + print_man_node(man, n, mh, h); if (n->next) - print_man_nodelist(m, n->next, mh, h); + print_man_nodelist(man, n->next, mh, h); } @@ -207,7 +209,7 @@ print_man_node(MAN_ARGS) switch (n->type) { case (MAN_ROOT): - man_root_pre(m, n, mh, h); + man_root_pre(man, n, mh, h); break; case (MAN_TEXT): /* @@ -258,25 +260,25 @@ print_man_node(MAN_ARGS) t = h->tags.head; } if (mans[n->tok].pre) - child = (*mans[n->tok].pre)(m, n, mh, h); + child = (*mans[n->tok].pre)(man, n, mh, h); break; } if (child && n->child) - print_man_nodelist(m, n->child, mh, h); + print_man_nodelist(man, n->child, mh, h); /* This will automatically close out any font scope. */ print_stagq(h, t); switch (n->type) { case (MAN_ROOT): - man_root_post(m, n, mh, h); + man_root_post(man, n, mh, h); break; case (MAN_EQN): break; default: if (mans[n->tok].post) - (*mans[n->tok].post)(m, n, mh, h); + (*mans[n->tok].post)(man, n, mh, h); break; } } @@ -304,12 +306,12 @@ man_root_pre(MAN_ARGS) char b[BUFSIZ], title[BUFSIZ]; b[0] = 0; - if (m->vol) - (void)strlcat(b, m->vol, BUFSIZ); + if (man->vol) + (void)strlcat(b, man->vol, BUFSIZ); - assert(m->title); - assert(m->msec); - snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec); + assert(man->title); + assert(man->msec); + snprintf(title, BUFSIZ - 1, "%s(%s)", man->title, man->msec); PAIR_SUMMARY_INIT(&tag[0], "Document Header"); PAIR_CLASS_INIT(&tag[1], "head"); @@ -363,16 +365,16 @@ man_root_post(MAN_ARGS) PAIR_CLASS_INIT(&tag[0], "foot-date"); print_otag(h, TAG_TD, 1, tag); - assert(m->date); - print_text(h, m->date); + assert(man->date); + print_text(h, man->date); print_stagq(h, tt); PAIR_CLASS_INIT(&tag[0], "foot-os"); PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); print_otag(h, TAG_TD, 2, tag); - if (m->source) - print_text(h, m->source); + if (man->source) + print_text(h, man->source); print_tagq(h, t); } @@ -468,7 +470,7 @@ man_alt_pre(MAN_ARGS) if (TAG_MAX != fp) t = print_otag(h, fp, 0, NULL); - print_man_node(m, nn, mh, h); + print_man_node(man, nn, mh, h); if (t) print_tagq(h, t); @@ -543,14 +545,14 @@ man_IP_pre(MAN_ARGS) /* For IP, only print the first header element. */ if (MAN_IP == n->tok && n->child) - print_man_node(m, n->child, mh, h); + print_man_node(man, n->child, mh, h); /* For TP, only print next-line header elements. */ if (MAN_TP == n->tok) for (nn = n->child; nn; nn = nn->next) if (nn->line > n->line) - print_man_node(m, nn, mh, h); + print_man_node(man, nn, mh, h); return(0); } @@ -638,7 +640,7 @@ static int man_literal_pre(MAN_ARGS) { - if (MAN_nf != n->tok) { + if (MAN_fi == n->tok || MAN_EE == n->tok) { print_otag(h, TAG_BR, 0, NULL); mh->fl &= ~MANH_LITERAL; } else diff --git a/contrib/mdocml/man_macro.c b/contrib/mdocml/man_macro.c index 4bbbc4fa7f..6631f14db4 100644 --- a/contrib/mdocml/man_macro.c +++ b/contrib/mdocml/man_macro.c @@ -1,6 +1,7 @@ -/* $Id: man_macro.c,v 1.71 2012/01/03 15:16:24 kristaps Exp $ */ +/* $Id: man_macro.c,v 1.75 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2012 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -77,7 +78,7 @@ const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, MAN_BSCOPE }, /* nf */ { in_line_eoln, MAN_BSCOPE }, /* fi */ { blk_close, 0 }, /* RE */ - { blk_exp, MAN_EXPLICIT }, /* RS */ + { blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* RS */ { in_line_eoln, 0 }, /* DT */ { in_line_eoln, 0 }, /* UC */ { in_line_eoln, 0 }, /* PD */ @@ -85,6 +86,8 @@ const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, 0 }, /* in */ { in_line_eoln, 0 }, /* ft */ { in_line_eoln, 0 }, /* OP */ + { in_line_eoln, MAN_BSCOPE }, /* EX */ + { in_line_eoln, MAN_BSCOPE }, /* EE */ }; const struct man_macro * const man_macros = __man_macros; @@ -94,7 +97,7 @@ const struct man_macro * const man_macros = __man_macros; * Warn when "n" is an explicit non-roff macro. */ static void -rew_warn(struct man *m, struct man_node *n, enum mandocerr er) +rew_warn(struct man *man, struct man_node *n, enum mandocerr er) { if (er == MANDOCERR_MAX || MAN_BLOCK != n->type) @@ -105,7 +108,7 @@ rew_warn(struct man *m, struct man_node *n, enum mandocerr er) return; assert(er < MANDOCERR_FATAL); - man_nmsg(m, n, er); + man_nmsg(man, n, er); } @@ -114,33 +117,33 @@ 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 *to, +man_unscope(struct man *man, const struct man_node *to, enum mandocerr er) { struct man_node *n; assert(to); - m->next = MAN_NEXT_SIBLING; + man->next = MAN_NEXT_SIBLING; /* LINTED */ - while (m->last != to) { + while (man->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 + * man->last node in the post-validation phase and reset + * it to man->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)) + n = man->last->parent; + rew_warn(man, man->last, er); + if ( ! man_valid_post(man)) return(0); - m->last = n; - assert(m->last); + man->last = n; + assert(man->last); } - rew_warn(m, m->last, er); - if ( ! man_valid_post(m)) + rew_warn(man, man->last, er); + if ( ! man_valid_post(man)) return(0); return(1); @@ -183,8 +186,12 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n) return(REW_NOHALT); /* First: rewind to ourselves. */ - if (type == n->type && tok == n->tok) - return(REW_REWIND); + if (type == n->type && tok == n->tok) { + if (MAN_EXPLICIT & man_macros[n->tok].flags) + return(REW_HALT); + else + return(REW_REWIND); + } /* * Next follow the implicit scope-smashings as defined by man.7: @@ -200,6 +207,10 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n) return(c); break; case (MAN_RS): + /* Preserve empty paragraphs before RS. */ + if (0 == n->nchild && (MAN_P == n->tok || + MAN_PP == n->tok || MAN_LP == n->tok)) + return(REW_HALT); /* Rewind to a subsection, if a block. */ if (REW_NOHALT != (c = rew_block(MAN_SS, type, n))) return(c); @@ -230,13 +241,13 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n) * scopes. When a scope is closed, it must be validated and actioned. */ static int -rew_scope(enum man_type type, struct man *m, enum mant tok) +rew_scope(enum man_type type, struct man *man, enum mant tok) { struct man_node *n; enum rew c; /* LINTED */ - for (n = m->last; n; n = n->parent) { + for (n = man->last; n; n = n->parent) { /* * Whether we should stop immediately (REW_HALT), stop * and rewind until this point (REW_REWIND), or keep @@ -255,7 +266,7 @@ rew_scope(enum man_type type, struct man *m, enum mant tok) */ assert(n); - return(man_unscope(m, n, MANDOCERR_MAX)); + return(man_unscope(man, n, MANDOCERR_MAX)); } @@ -278,17 +289,14 @@ blk_close(MACRO_PROT_ARGS) /* NOTREACHED */ } - for (nn = m->last->parent; nn; nn = nn->parent) - if (ntok == nn->tok) + for (nn = man->last->parent; nn; nn = nn->parent) + if (ntok == nn->tok && MAN_BLOCK == nn->type) break; - if (NULL == nn) - man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE); - - if ( ! rew_scope(MAN_BODY, m, ntok)) - return(0); - if ( ! rew_scope(MAN_BLOCK, m, ntok)) - return(0); + if (NULL != nn) + man_unscope(man, nn, MANDOCERR_MAX); + else + man_pmsg(man, line, ppos, MANDOCERR_NOSCOPE); return(1); } @@ -298,34 +306,40 @@ blk_close(MACRO_PROT_ARGS) int blk_exp(MACRO_PROT_ARGS) { + struct man_node *n; int la; char *p; - /* - * Close out prior scopes. "Regular" explicit macros cannot be - * nested, but we allow roff macros to be placed just about - * anywhere. - */ + /* Close out prior implicit scopes. */ + + if ( ! rew_scope(MAN_BLOCK, man, tok)) + return(0); - if ( ! man_block_alloc(m, line, ppos, tok)) + if ( ! man_block_alloc(man, line, ppos, tok)) return(0); - if ( ! man_head_alloc(m, line, ppos, tok)) + if ( ! man_head_alloc(man, line, ppos, tok)) return(0); for (;;) { la = *pos; - if ( ! man_args(m, line, pos, buf, &p)) + if ( ! man_args(man, line, pos, buf, &p)) break; - if ( ! man_word_alloc(m, line, la, p)) + if ( ! man_word_alloc(man, line, la, p)) return(0); } - assert(m); + assert(man); assert(tok != MAN_MAX); - if ( ! rew_scope(MAN_HEAD, m, tok)) - return(0); - return(man_body_alloc(m, line, ppos, tok)); + for (n = man->last; n; n = n->parent) { + if (n->tok != tok) + continue; + assert(MAN_HEAD == n->type); + man_unscope(man, n, MANDOCERR_MAX); + break; + } + + return(man_body_alloc(man, line, ppos, tok)); } @@ -346,27 +360,27 @@ blk_imp(MACRO_PROT_ARGS) /* Close out prior scopes. */ - if ( ! rew_scope(MAN_BODY, m, tok)) + if ( ! rew_scope(MAN_BODY, man, tok)) return(0); - if ( ! rew_scope(MAN_BLOCK, m, tok)) + if ( ! rew_scope(MAN_BLOCK, man, tok)) return(0); /* Allocate new block & head scope. */ - if ( ! man_block_alloc(m, line, ppos, tok)) + if ( ! man_block_alloc(man, line, ppos, tok)) return(0); - if ( ! man_head_alloc(m, line, ppos, tok)) + if ( ! man_head_alloc(man, line, ppos, tok)) return(0); - n = m->last; + n = man->last; /* Add line arguments. */ for (;;) { la = *pos; - if ( ! man_args(m, line, pos, buf, &p)) + if ( ! man_args(man, line, pos, buf, &p)) break; - if ( ! man_word_alloc(m, line, la, p)) + if ( ! man_word_alloc(man, line, la, p)) return(0); } @@ -375,17 +389,17 @@ blk_imp(MACRO_PROT_ARGS) if (MAN_SCOPED & man_macros[tok].flags) { /* If we're forcing scope (`TP'), keep it open. */ if (MAN_FSCOPED & man_macros[tok].flags) { - m->flags |= MAN_BLINE; + man->flags |= MAN_BLINE; return(1); - } else if (n == m->last) { - m->flags |= MAN_BLINE; + } else if (n == man->last) { + man->flags |= MAN_BLINE; return(1); } } - if ( ! rew_scope(MAN_HEAD, m, tok)) + if ( ! rew_scope(MAN_HEAD, man, tok)) return(0); - return(man_body_alloc(m, line, ppos, tok)); + return(man_body_alloc(man, line, ppos, tok)); } @@ -397,16 +411,16 @@ in_line_eoln(MACRO_PROT_ARGS) char *p; struct man_node *n; - if ( ! man_elem_alloc(m, line, ppos, tok)) + if ( ! man_elem_alloc(man, line, ppos, tok)) return(0); - n = m->last; + n = man->last; for (;;) { la = *pos; - if ( ! man_args(m, line, pos, buf, &p)) + if ( ! man_args(man, line, pos, buf, &p)) break; - if ( ! man_word_alloc(m, line, la, p)) + if ( ! man_word_alloc(man, line, la, p)) return(0); } @@ -416,9 +430,9 @@ in_line_eoln(MACRO_PROT_ARGS) * waiting for terms to load into our context. */ - if (n == m->last && MAN_SCOPED & man_macros[tok].flags) { + if (n == man->last && MAN_SCOPED & man_macros[tok].flags) { assert( ! (MAN_NSCOPED & man_macros[tok].flags)); - m->flags |= MAN_ELINE; + man->flags |= MAN_ELINE; return(1); } @@ -426,11 +440,11 @@ in_line_eoln(MACRO_PROT_ARGS) if (MAN_NSCOPED & man_macros[tok].flags) { assert( ! (MAN_SCOPED & man_macros[tok].flags)); - m->flags |= MAN_ILINE; + man->flags |= MAN_ILINE; } - assert(MAN_ROOT != m->last->type); - m->next = MAN_NEXT_SIBLING; + assert(MAN_ROOT != man->last->type); + man->next = MAN_NEXT_SIBLING; /* * Rewind our element scope. Note that when TH is pruned, we'll @@ -438,22 +452,22 @@ in_line_eoln(MACRO_PROT_ARGS) * its sibling. */ - for ( ; m->last; m->last = m->last->parent) { - if (m->last == n) + for ( ; man->last; man->last = man->last->parent) { + if (man->last == n) break; - if (m->last->type == MAN_ROOT) + if (man->last->type == MAN_ROOT) break; - if ( ! man_valid_post(m)) + if ( ! man_valid_post(man)) return(0); } - assert(m->last); + assert(man->last); /* * Same here regarding whether we're back at the root. */ - if (m->last->type != MAN_ROOT && ! man_valid_post(m)) + if (man->last->type != MAN_ROOT && ! man_valid_post(man)) return(0); return(1); @@ -461,14 +475,14 @@ in_line_eoln(MACRO_PROT_ARGS) int -man_macroend(struct man *m) +man_macroend(struct man *man) { - return(man_unscope(m, m->first, MANDOCERR_SCOPEEXIT)); + return(man_unscope(man, man->first, MANDOCERR_SCOPEEXIT)); } static int -man_args(struct man *m, int line, int *pos, char *buf, char **v) +man_args(struct man *man, int line, int *pos, char *buf, char **v) { char *start; @@ -479,6 +493,6 @@ man_args(struct man *m, int line, int *pos, char *buf, char **v) if ('\0' == *start) return(0); - *v = mandoc_getarg(m->parse, v, line, pos); + *v = mandoc_getarg(man->parse, v, line, pos); return(1); } diff --git a/contrib/mdocml/man_term.c b/contrib/mdocml/man_term.c index 69c5c95e44..db5719ce1a 100644 --- a/contrib/mdocml/man_term.c +++ b/contrib/mdocml/man_term.c @@ -1,7 +1,7 @@ -/* $Id: man_term.c,v 1.127 2012/01/03 15:16:24 kristaps Exp $ */ +/* $Id: man_term.c,v 1.136 2013/01/05 22:19:12 schwarze Exp $ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2011 Ingo Schwarze + * Copyright (c) 2008-2012 Kristaps Dzonsons + * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,8 +35,6 @@ #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) @@ -44,12 +42,13 @@ struct mtermp { int lmargincur; /* index of current margin */ int lmarginsz; /* actual number of nested margins */ size_t offset; /* default offset to visible page */ + int pardist; /* vert. space before par., unit: [v] */ }; #define DECL_ARGS struct termp *p, \ struct mtermp *mt, \ const struct man_node *n, \ - const struct man_meta *m + const struct man_meta *meta struct termact { int (*pre)(DECL_ARGS); @@ -66,13 +65,14 @@ static void print_man_node(DECL_ARGS); static void print_man_head(struct termp *, const void *); static void print_man_foot(struct termp *, const void *); static void print_bvspace(struct termp *, - const struct man_node *); + const struct man_node *, int); 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_PD(DECL_ARGS); static int pre_PP(DECL_ARGS); static int pre_RS(DECL_ARGS); static int pre_SH(DECL_ARGS); @@ -122,11 +122,13 @@ static const struct termact termacts[MAN_MAX] = { { pre_RS, post_RS, 0 }, /* RS */ { pre_ign, NULL, 0 }, /* DT */ { pre_ign, NULL, 0 }, /* UC */ - { pre_ign, NULL, 0 }, /* PD */ + { pre_PD, NULL, MAN_NOTEXT }, /* PD */ { pre_ign, NULL, 0 }, /* AT */ { pre_in, NULL, MAN_NOTEXT }, /* in */ { pre_ft, NULL, MAN_NOTEXT }, /* ft */ { pre_OP, NULL, 0 }, /* OP */ + { pre_literal, NULL, 0 }, /* EX */ + { pre_literal, NULL, 0 }, /* EE */ }; @@ -136,7 +138,7 @@ terminal_man(void *arg, const struct man *man) { struct termp *p; const struct man_node *n; - const struct man_meta *m; + const struct man_meta *meta; struct mtermp mt; p = (struct termp *)arg; @@ -152,18 +154,19 @@ terminal_man(void *arg, const struct man *man) p->symtab = mchars_alloc(); n = man_node(man); - m = man_meta(man); + meta = man_meta(man); - term_begin(p, print_man_head, print_man_foot, m); + term_begin(p, print_man_head, print_man_foot, meta); p->flags |= TERMP_NOSPACE; memset(&mt, 0, sizeof(struct mtermp)); mt.lmargin[mt.lmargincur] = term_len(p, p->defindent); mt.offset = term_len(p, p->defindent); + mt.pardist = 1; if (n->child) - print_man_nodelist(p, &mt, n->child, m); + print_man_nodelist(p, &mt, n->child, meta); term_end(p); } @@ -201,8 +204,9 @@ a2width(const struct termp *p, const char *cp) * first, print it. */ static void -print_bvspace(struct termp *p, const struct man_node *n) +print_bvspace(struct termp *p, const struct man_node *n, int pardist) { + int i; term_newln(p); @@ -214,7 +218,8 @@ print_bvspace(struct termp *p, const struct man_node *n) if (NULL == n->prev) return; - term_vspace(p); + for (i = 0; i < pardist; i++) + term_vspace(p); } /* ARGSUSED */ @@ -243,7 +248,7 @@ pre_literal(DECL_ARGS) term_newln(p); - if (MAN_nf == n->tok) + if (MAN_nf == n->tok || MAN_EX == n->tok) mt->fl |= MANT_LITERAL; else mt->fl &= ~MANT_LITERAL; @@ -263,6 +268,21 @@ pre_literal(DECL_ARGS) return(0); } +/* ARGSUSED */ +static int +pre_PD(DECL_ARGS) +{ + + n = n->child; + if (0 == n) { + mt->pardist = 1; + return(0); + } + assert(MAN_TEXT == n->type); + mt->pardist = atoi(n->string); + return(0); +} + /* ARGSUSED */ static int pre_alternate(DECL_ARGS) @@ -307,7 +327,7 @@ pre_alternate(DECL_ARGS) term_fontrepl(p, font[i]); if (savelit && NULL == nn->next) mt->fl |= MANT_LITERAL; - print_man_node(p, mt, nn, m); + print_man_node(p, mt, nn, meta); if (nn->next) p->flags |= TERMP_NOSPACE; } @@ -438,28 +458,54 @@ pre_in(DECL_ARGS) static int pre_sp(DECL_ARGS) { + char *s; size_t i, len; + int neg; if ((NULL == n->prev && n->parent)) { - if (MAN_SS == n->parent->tok) - return(0); - if (MAN_SH == n->parent->tok) + switch (n->parent->tok) { + case (MAN_SH): + /* FALLTHROUGH */ + case (MAN_SS): + /* FALLTHROUGH */ + case (MAN_PP): + /* FALLTHROUGH */ + case (MAN_LP): + /* FALLTHROUGH */ + case (MAN_P): + /* FALLTHROUGH */ return(0); + default: + break; + } } + neg = 0; switch (n->tok) { case (MAN_br): len = 0; break; default: - len = n->child ? a2height(p, n->child->string) : 1; + if (NULL == n->child) { + len = 1; + break; + } + s = n->child->string; + if ('-' == *s) { + neg = 1; + s++; + } + len = a2height(p, s); break; } if (0 == len) term_newln(p); - for (i = 0; i < len; i++) - term_vspace(p); + else if (neg) + p->skipvsp += len; + else + for (i = 0; i < len; i++) + term_vspace(p); return(0); } @@ -475,16 +521,19 @@ pre_HP(DECL_ARGS) switch (n->type) { case (MAN_BLOCK): - print_bvspace(p, n); + print_bvspace(p, n, mt->pardist); return(1); case (MAN_BODY): - p->flags |= TERMP_NOBREAK; - p->flags |= TERMP_TWOSPACE; break; default: return(0); } + if ( ! (MANT_LITERAL & mt->fl)) { + p->flags |= TERMP_NOBREAK; + p->flags |= TERMP_TWOSPACE; + } + len = mt->lmargin[mt->lmargincur]; ival = -1; @@ -514,11 +563,8 @@ post_HP(DECL_ARGS) { switch (n->type) { - case (MAN_BLOCK): - term_flushln(p); - break; case (MAN_BODY): - term_flushln(p); + term_newln(p); p->flags &= ~TERMP_NOBREAK; p->flags &= ~TERMP_TWOSPACE; p->offset = mt->offset; @@ -538,7 +584,7 @@ pre_PP(DECL_ARGS) switch (n->type) { case (MAN_BLOCK): mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); - print_bvspace(p, n); + print_bvspace(p, n, mt->pardist); break; default: p->offset = mt->offset; @@ -565,7 +611,7 @@ pre_IP(DECL_ARGS) p->flags |= TERMP_NOBREAK; break; case (MAN_BLOCK): - print_bvspace(p, n); + print_bvspace(p, n, mt->pardist); /* FALLTHROUGH */ default: return(1); @@ -598,7 +644,7 @@ pre_IP(DECL_ARGS) mt->fl &= ~MANT_LITERAL; if (n->child) - print_man_node(p, mt, n->child, m); + print_man_node(p, mt, n->child, meta); if (savelit) mt->fl |= MANT_LITERAL; @@ -652,7 +698,7 @@ pre_TP(DECL_ARGS) p->flags |= TERMP_NOSPACE; break; case (MAN_BLOCK): - print_bvspace(p, n); + print_bvspace(p, n, mt->pardist); /* FALLTHROUGH */ default: return(1); @@ -683,7 +729,7 @@ pre_TP(DECL_ARGS) /* Don't print same-line elements. */ for (nn = n->child; nn; nn = nn->next) if (nn->line > n->line) - print_man_node(p, mt, nn, m); + print_man_node(p, mt, nn, meta); if (savelit) mt->fl |= MANT_LITERAL; @@ -694,6 +740,8 @@ pre_TP(DECL_ARGS) case (MAN_BODY): p->offset = mt->offset + len; p->rmargin = p->maxrmargin; + p->flags &= ~TERMP_NOBREAK; + p->flags &= ~TERMP_TWOSPACE; break; default: break; @@ -711,9 +759,6 @@ post_TP(DECL_ARGS) switch (n->type) { case (MAN_HEAD): term_flushln(p); - p->flags &= ~TERMP_NOBREAK; - p->flags &= ~TERMP_TWOSPACE; - p->rmargin = p->maxrmargin; break; case (MAN_BODY): term_newln(p); @@ -728,6 +773,7 @@ post_TP(DECL_ARGS) static int pre_SS(DECL_ARGS) { + int i; switch (n->type) { case (MAN_BLOCK): @@ -740,11 +786,12 @@ pre_SS(DECL_ARGS) break; if (NULL == n->prev) break; - term_vspace(p); + for (i = 0; i < mt->pardist; i++) + term_vspace(p); break; case (MAN_HEAD): term_fontrepl(p, TERMFONT_BOLD); - p->offset = term_len(p, p->defindent/2); + p->offset = term_len(p, 3); break; case (MAN_BODY): p->offset = mt->offset; @@ -779,6 +826,7 @@ post_SS(DECL_ARGS) static int pre_SH(DECL_ARGS) { + int i; switch (n->type) { case (MAN_BLOCK): @@ -792,7 +840,8 @@ pre_SH(DECL_ARGS) /* If the first macro, no vspae. */ if (NULL == n->prev) break; - term_vspace(p); + for (i = 0; i < mt->pardist; i++) + term_vspace(p); break; case (MAN_HEAD): term_fontrepl(p, TERMFONT_BOLD); @@ -910,29 +959,8 @@ print_man_node(DECL_ARGS) term_newln(p); term_word(p, n->string); + goto out; - /* - * 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->rmargin = rm; - p->maxrmargin = rmax; - } - - if (MAN_EOS & n->flags) - p->flags |= TERMP_SENTENCE; - return; case (MAN_EQN): term_eqn(p, n->eqn); return; @@ -954,16 +982,41 @@ print_man_node(DECL_ARGS) c = 1; if (termacts[n->tok].pre) - c = (*termacts[n->tok].pre)(p, mt, n, m); + c = (*termacts[n->tok].pre)(p, mt, n, meta); if (c && n->child) - print_man_nodelist(p, mt, n->child, m); + print_man_nodelist(p, mt, n->child, meta); if (termacts[n->tok].post) - (*termacts[n->tok].post)(p, mt, n, m); + (*termacts[n->tok].post)(p, mt, n, meta); if ( ! (MAN_NOTEXT & termacts[n->tok].flags)) term_fontrepl(p, TERMFONT_NONE); +out: + /* + * If we're in a literal context, make sure that words + * together on the same line stay together. This is a + * POST-printing call, so we check the NEXT word. Since + * -man doesn't have nested macros, we don't need to be + * more specific than this. + */ + if (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; + if (NULL != n->string && '\0' != *n->string) + term_flushln(p); + else + term_newln(p); + if (rm < rmax && n->parent->tok == MAN_HP) { + p->offset = rm; + p->rmargin = rmax; + } else + p->rmargin = rm; + p->maxrmargin = rmax; + } if (MAN_EOS & n->flags) p->flags |= TERMP_SENTENCE; } @@ -973,10 +1026,10 @@ static void print_man_nodelist(DECL_ARGS) { - print_man_node(p, mt, n, m); + print_man_node(p, mt, n, meta); if ( ! n->next) return; - print_man_nodelist(p, mt, n->next, m); + print_man_nodelist(p, mt, n->next, meta); } @@ -1051,21 +1104,21 @@ print_man_head(struct termp *p, const void *arg) { char buf[BUFSIZ], title[BUFSIZ]; size_t buflen, titlen; - const struct man_meta *m; + const struct man_meta *meta; - m = (const struct man_meta *)arg; - assert(m->title); - assert(m->msec); + meta = (const struct man_meta *)arg; + assert(meta->title); + assert(meta->msec); - if (m->vol) - strlcpy(buf, m->vol, BUFSIZ); + if (meta->vol) + strlcpy(buf, meta->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); + snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec); titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; diff --git a/contrib/mdocml/man_validate.c b/contrib/mdocml/man_validate.c index e40b089f53..7a9deede11 100644 --- a/contrib/mdocml/man_validate.c +++ b/contrib/mdocml/man_validate.c @@ -1,7 +1,7 @@ -/* $Id: man_validate.c,v 1.80 2012/01/03 15:16:24 kristaps Exp $ */ +/* $Id: man_validate.c,v 1.85 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010 Ingo Schwarze + * Copyright (c) 2010, 2012 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,7 +35,7 @@ #include "libman.h" #include "libmandoc.h" -#define CHKARGS struct man *m, struct man_node *n +#define CHKARGS struct man *man, struct man_node *n typedef int (*v_check)(CHKARGS); @@ -55,6 +55,7 @@ static int check_root(CHKARGS); static void check_text(CHKARGS); static int post_AT(CHKARGS); +static int post_IP(CHKARGS); static int post_vs(CHKARGS); static int post_fi(CHKARGS); static int post_ft(CHKARGS); @@ -70,6 +71,8 @@ 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_ft[] = { post_ft, NULL }; +static v_check posts_ip[] = { post_IP, NULL }; +static v_check posts_le1[] = { check_le1, 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 }; @@ -88,7 +91,7 @@ static const struct man_valid man_valids[MAN_MAX] = { { NULL, posts_par }, /* LP */ { NULL, posts_par }, /* PP */ { NULL, posts_par }, /* P */ - { NULL, NULL }, /* IP */ + { NULL, posts_ip }, /* IP */ { NULL, NULL }, /* HP */ { NULL, NULL }, /* SM */ { NULL, NULL }, /* SB */ @@ -109,16 +112,18 @@ static const struct man_valid man_valids[MAN_MAX] = { { NULL, posts_part }, /* RS */ { NULL, NULL }, /* DT */ { NULL, posts_uc }, /* UC */ - { NULL, NULL }, /* PD */ + { NULL, posts_le1 }, /* PD */ { NULL, posts_at }, /* AT */ { NULL, NULL }, /* in */ { NULL, posts_ft }, /* ft */ { NULL, posts_eq2 }, /* OP */ + { NULL, posts_nf }, /* EX */ + { NULL, posts_fi }, /* EE */ }; int -man_valid_pre(struct man *m, struct man_node *n) +man_valid_pre(struct man *man, struct man_node *n) { v_check *cp; @@ -138,27 +143,27 @@ man_valid_pre(struct man *m, struct man_node *n) if (NULL == (cp = man_valids[n->tok].pres)) return(1); for ( ; *cp; cp++) - if ( ! (*cp)(m, n)) + if ( ! (*cp)(man, n)) return(0); return(1); } int -man_valid_post(struct man *m) +man_valid_post(struct man *man) { v_check *cp; - if (MAN_VALID & m->last->flags) + if (MAN_VALID & man->last->flags) return(1); - m->last->flags |= MAN_VALID; + man->last->flags |= MAN_VALID; - switch (m->last->type) { + switch (man->last->type) { case (MAN_TEXT): - check_text(m, m->last); + check_text(man, man->last); return(1); case (MAN_ROOT): - return(check_root(m, m->last)); + return(check_root(man, man->last)); case (MAN_EQN): /* FALLTHROUGH */ case (MAN_TBL): @@ -167,10 +172,10 @@ man_valid_post(struct man *m) break; } - if (NULL == (cp = man_valids[m->last->tok].posts)) + if (NULL == (cp = man_valids[man->last->tok].posts)) return(1); for ( ; *cp; cp++) - if ( ! (*cp)(m, m->last)) + if ( ! (*cp)(man, man->last)) return(0); return(1); @@ -181,29 +186,29 @@ static int check_root(CHKARGS) { - if (MAN_BLINE & m->flags) - man_nmsg(m, n, MANDOCERR_SCOPEEXIT); - else if (MAN_ELINE & m->flags) - man_nmsg(m, n, MANDOCERR_SCOPEEXIT); + if (MAN_BLINE & man->flags) + man_nmsg(man, n, MANDOCERR_SCOPEEXIT); + else if (MAN_ELINE & man->flags) + man_nmsg(man, n, MANDOCERR_SCOPEEXIT); - m->flags &= ~MAN_BLINE; - m->flags &= ~MAN_ELINE; + man->flags &= ~MAN_BLINE; + man->flags &= ~MAN_ELINE; - if (NULL == m->first->child) { - man_nmsg(m, n, MANDOCERR_NODOCBODY); + if (NULL == man->first->child) { + man_nmsg(man, n, MANDOCERR_NODOCBODY); return(0); - } else if (NULL == m->meta.title) { - man_nmsg(m, n, MANDOCERR_NOTITLE); + } else if (NULL == man->meta.title) { + man_nmsg(man, n, MANDOCERR_NOTITLE); /* * If a title hasn't been set, do so now (by * implication, date and section also aren't set). */ - m->meta.title = mandoc_strdup("unknown"); - m->meta.msec = mandoc_strdup("1"); - m->meta.date = mandoc_normdate - (m->parse, NULL, n->line, n->pos); + man->meta.title = mandoc_strdup("unknown"); + man->meta.msec = mandoc_strdup("1"); + man->meta.date = mandoc_normdate + (man->parse, NULL, n->line, n->pos); } return(1); @@ -214,12 +219,12 @@ check_text(CHKARGS) { char *cp, *p; - if (MAN_LITERAL & m->flags) + if (MAN_LITERAL & man->flags) return; cp = n->string; for (p = cp; NULL != (p = strchr(p, '\t')); p++) - man_pmsg(m, n->line, (int)(p - cp), MANDOCERR_BADTAB); + man_pmsg(man, n->line, (int)(p - cp), MANDOCERR_BADTAB); } #define INEQ_DEFINE(x, ineq, name) \ @@ -228,7 +233,7 @@ check_##name(CHKARGS) \ { \ if (n->nchild ineq (x)) \ return(1); \ - mandoc_vmsg(MANDOCERR_ARGCOUNT, m->parse, n->line, n->pos, \ + mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \ "line arguments %s %d (have %d)", \ #ineq, (x), n->nchild); \ return(1); \ @@ -282,14 +287,14 @@ post_ft(CHKARGS) if (0 == ok) { mandoc_vmsg - (MANDOCERR_BADFONT, m->parse, + (MANDOCERR_BADFONT, man->parse, n->line, n->pos, "%s", cp); *cp = '\0'; } if (1 < n->nchild) mandoc_vmsg - (MANDOCERR_ARGCOUNT, m->parse, n->line, + (MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, "want one child (have %d)", n->nchild); @@ -301,7 +306,7 @@ pre_sec(CHKARGS) { if (MAN_BLOCK == n->type) - m->flags &= ~MAN_LITERAL; + man->flags &= ~MAN_LITERAL; return(1); } @@ -312,7 +317,7 @@ post_sec(CHKARGS) if ( ! (MAN_HEAD == n->type && 0 == n->nchild)) return(1); - man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT); + man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT); return(0); } @@ -321,7 +326,7 @@ check_part(CHKARGS) { if (MAN_BODY == n->type && 0 == n->nchild) - mandoc_msg(MANDOCERR_ARGCWARN, m->parse, n->line, + mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line, n->pos, "want children (have none)"); return(1); @@ -335,15 +340,15 @@ check_par(CHKARGS) switch (n->type) { case (MAN_BLOCK): if (0 == n->body->nchild) - man_node_delete(m, n); + man_node_delete(man, n); break; case (MAN_BODY): if (0 == n->nchild) - man_nmsg(m, n, MANDOCERR_IGNPAR); + man_nmsg(man, n, MANDOCERR_IGNPAR); break; case (MAN_HEAD): if (n->nchild) - man_nmsg(m, n, MANDOCERR_ARGSLOST); + man_nmsg(man, n, MANDOCERR_ARGSLOST); break; default: break; @@ -352,6 +357,24 @@ check_par(CHKARGS) return(1); } +static int +post_IP(CHKARGS) +{ + + switch (n->type) { + case (MAN_BLOCK): + if (0 == n->head->nchild && 0 == n->body->nchild) + man_node_delete(man, n); + break; + case (MAN_BODY): + if (0 == n->parent->head->nchild && 0 == n->nchild) + man_nmsg(man, n, MANDOCERR_IGNPAR); + break; + default: + break; + } + return(1); +} static int post_TH(CHKARGS) @@ -359,21 +382,16 @@ post_TH(CHKARGS) const char *p; int line, pos; - if (m->meta.title) - free(m->meta.title); - if (m->meta.vol) - free(m->meta.vol); - if (m->meta.source) - free(m->meta.source); - if (m->meta.msec) - free(m->meta.msec); - if (m->meta.date) - free(m->meta.date); + free(man->meta.title); + free(man->meta.vol); + free(man->meta.source); + free(man->meta.msec); + free(man->meta.date); line = n->line; pos = n->pos; - m->meta.title = m->meta.vol = m->meta.date = - m->meta.msec = m->meta.source = NULL; + man->meta.title = man->meta.vol = man->meta.date = + man->meta.msec = man->meta.source = NULL; /* ->TITLE<- MSEC DATE SOURCE VOL */ @@ -383,22 +401,22 @@ post_TH(CHKARGS) /* Only warn about this once... */ if (isalpha((unsigned char)*p) && ! isupper((unsigned char)*p)) { - man_nmsg(m, n, MANDOCERR_UPPERCASE); + man_nmsg(man, n, MANDOCERR_UPPERCASE); break; } } - m->meta.title = mandoc_strdup(n->string); + man->meta.title = mandoc_strdup(n->string); } else - m->meta.title = mandoc_strdup(""); + man->meta.title = mandoc_strdup(""); /* TITLE ->MSEC<- DATE SOURCE VOL */ if (n) n = n->next; if (n && n->string) - m->meta.msec = mandoc_strdup(n->string); + man->meta.msec = mandoc_strdup(n->string); else - m->meta.msec = mandoc_strdup(""); + man->meta.msec = mandoc_strdup(""); /* TITLE MSEC ->DATE<- SOURCE VOL */ @@ -406,30 +424,30 @@ post_TH(CHKARGS) n = n->next; if (n && n->string && '\0' != n->string[0]) { pos = n->pos; - m->meta.date = mandoc_normdate - (m->parse, n->string, line, pos); + man->meta.date = mandoc_normdate + (man->parse, n->string, line, pos); } else - m->meta.date = mandoc_strdup(""); + man->meta.date = mandoc_strdup(""); /* TITLE MSEC DATE ->SOURCE<- VOL */ if (n && (n = n->next)) - m->meta.source = mandoc_strdup(n->string); + man->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); + man->meta.vol = mandoc_strdup(n->string); + else if ('\0' != man->meta.msec[0] && + (NULL != (p = mandoc_a2msec(man->meta.msec)))) + man->meta.vol = mandoc_strdup(p); /* * Remove the `TH' node after we've processed it for our * meta-data. */ - man_node_delete(m, m->last); + man_node_delete(man, man->last); return(1); } @@ -437,10 +455,10 @@ static int post_nf(CHKARGS) { - if (MAN_LITERAL & m->flags) - man_nmsg(m, n, MANDOCERR_SCOPEREP); + if (MAN_LITERAL & man->flags) + man_nmsg(man, n, MANDOCERR_SCOPEREP); - m->flags |= MAN_LITERAL; + man->flags |= MAN_LITERAL; return(1); } @@ -448,10 +466,10 @@ static int post_fi(CHKARGS) { - if ( ! (MAN_LITERAL & m->flags)) - man_nmsg(m, n, MANDOCERR_WNOSCOPE); + if ( ! (MAN_LITERAL & man->flags)) + man_nmsg(man, n, MANDOCERR_WNOSCOPE); - m->flags &= ~MAN_LITERAL; + man->flags &= ~MAN_LITERAL; return(1); } @@ -488,10 +506,8 @@ post_UC(CHKARGS) p = bsd_versions[0]; } - if (m->meta.source) - free(m->meta.source); - - m->meta.source = mandoc_strdup(p); + free(man->meta.source); + man->meta.source = mandoc_strdup(p); return(1); } @@ -528,10 +544,8 @@ post_AT(CHKARGS) p = unix_versions[0]; } - if (m->meta.source) - free(m->meta.source); - - m->meta.source = mandoc_strdup(p); + free(man->meta.source); + man->meta.source = mandoc_strdup(p); return(1); } @@ -539,12 +553,25 @@ 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); + if (NULL != n->prev) + return(1); + + switch (n->parent->tok) { + case (MAN_SH): + /* FALLTHROUGH */ + case (MAN_SS): + man_nmsg(man, n, MANDOCERR_IGNPAR); + /* FALLTHROUGH */ + case (MAN_MAX): + /* + * Don't warn about this because it occurs in pod2man + * and would cause considerable (unfixable) warnage. + */ + man_node_delete(man, n); + break; + default: + break; + } return(1); } diff --git a/contrib/mdocml/mandoc.1 b/contrib/mdocml/mandoc.1 index dbff0e31ca..0657bc66c5 100644 --- a/contrib/mdocml/mandoc.1 +++ b/contrib/mdocml/mandoc.1 @@ -1,6 +1,7 @@ -.\" $Id: mandoc.1,v 1.100 2011/12/25 19:35:44 kristaps Exp $ +.\" $Id: mandoc.1,v 1.103 2013/07/13 19:41:16 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons +.\" Copyright (c) 2012 Ingo Schwarze .\" .\" 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 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 25 2011 $ +.Dd $Mdocdate: July 13 2013 $ .Dt MANDOC 1 .Os .Sh NAME @@ -23,6 +24,9 @@ .Sh SYNOPSIS .Nm mandoc .Op Fl V +.Sm off +.Op Fl I Cm os Li = Ar name +.Sm on .Op Fl m Ns Ar format .Op Fl O Ns Ar option .Op Fl T Ns Ar output @@ -49,6 +53,15 @@ output. .Pp The arguments are as follows: .Bl -tag -width Ds +.Sm off +.It Fl I Cm os Li = Ar name +.Sm on +Override the default operating system +.Ar name +for the +.Xr mdoc 7 +.Sq \&Os +macro. .It Fl m Ns Ar format Input format. See @@ -334,7 +347,7 @@ for font style specification and available command-line arguments. Translate input format into .Xr man 7 output format. -This is useful for distributing manual sources to legancy systems +This is useful for distributing manual sources to legacy systems lacking .Xr mdoc 7 formatters. @@ -637,8 +650,7 @@ lists render similarly. The .Nm utility was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . .Sh CAVEATS In .Fl T Ns Cm html diff --git a/contrib/mdocml/mandoc.3 b/contrib/mdocml/mandoc.3 index 4d0b20d650..bc6aa904d3 100644 --- a/contrib/mdocml/mandoc.3 +++ b/contrib/mdocml/mandoc.3 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.3,v 1.17 2012/01/13 15:27:14 joerg Exp $ +.\" $Id: mandoc.3,v 1.20 2013/09/16 22:54:38 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 13 2012 $ +.Dd $Mdocdate: September 16 2013 $ .Dt MANDOC 3 .Os .Sh NAME @@ -67,7 +67,7 @@ .Fa "const struct man *man" .Fc .Ft "struct mchars *" -.Fn mchars_alloc +.Fn mchars_alloc "void" .Ft void .Fn mchars_free "struct mchars *p" .Ft char @@ -86,7 +86,6 @@ .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 @@ -257,16 +256,32 @@ and .Va sz may be .Dv NULL . +Declared in +.In mandoc.h , +implemented in +.Pa mandoc.c . .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 . +Declared in +.In man.h , +implemented in +.Pa man.c . .It Fn man_mparse Get the parser used for the current output. +Declared in +.In man.h , +implemented in +.Pa man.c . .It Fn man_node Obtain the root node of a successful parse. This may only be used on a pointer returned by .Fn mparse_result . +Declared in +.In man.h , +implemented in +.Pa man.c . .It Fn mchars_alloc Allocate an .Vt "struct mchars *" @@ -276,33 +291,65 @@ See for an overview of special characters. The object must be freed with .Fn mchars_free . +Declared in +.In mandoc.h , +implemented in +.Pa chars.c . .It Fn mchars_free Free an object created with .Fn mchars_alloc . +Declared in +.In mandoc.h , +implemented in +.Pa chars.c . .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. +Declared in +.In mandoc.h , +implemented in +.Pa chars.c . .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. +Declared in +.In mandoc.h , +implemented in +.Pa chars.c . .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. +Declared in +.In mandoc.h , +implemented in +.Pa chars.c . .It Fn mchars_spec2str Convert a special character into an ASCII string. Returns .Dv NULL on failure. +Declared in +.In mandoc.h , +implemented in +.Pa chars.c . .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 . +Declared in +.In mdoc.h , +implemented in +.Pa mdoc.c . .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 . +Declared in +.In mdoc.h , +implemented in +.Pa mdoc.c . .It Fn mparse_alloc Allocate a parser. The same parser may be used for multiple files so long as @@ -310,18 +357,34 @@ The same parser may be used for multiple files so long as is called between parses. .Fn mparse_free must be called to free the memory allocated by this function. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_free Free all memory allocated by .Fn mparse_alloc . +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_getkeep Acquire the keep buffer. Must follow a call of .Fn mparse_keep . +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_keep Instruct the parser to retain a copy of its parsed input. This can be acquired with subsequent .Fn mparse_getkeep calls. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_readfd Parse a file or file descriptor. If @@ -336,10 +399,18 @@ is assumed to be the name associated with This may be called multiple times with different parameters; however, .Fn mparse_reset should be invoked between parses. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_reset Reset a parser so that .Fn mparse_readfd may be used again. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_result Obtain the result of a parse. Only successful parses @@ -350,10 +421,22 @@ returned less than MANDOCLEVEL_FATAL .Pc should invoke this function, in which case one of the two pointers will be filled in. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_strerror Return a statically-allocated string representation of an error code. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .It Fn mparse_strlevel Return a statically-allocated string representation of a level code. +Declared in +.In mandoc.h , +implemented in +.Pa read.c . .El .Ss Variables .Bl -ohang @@ -596,5 +679,4 @@ levels of badly-nested blocks. The .Nm library was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/mandoc.c b/contrib/mdocml/mandoc.c index 604bb67e6a..df510226c4 100644 --- a/contrib/mdocml/mandoc.c +++ b/contrib/mdocml/mandoc.c @@ -1,7 +1,7 @@ -/* $Id: mandoc.c,v 1.62 2011/12/03 16:08:51 schwarze Exp $ */ +/* $Id: mandoc.c,v 1.68 2013/08/08 20:07:47 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2011, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,83 +37,38 @@ static int a2time(time_t *, const char *, const char *); static char *time2a(time_t); -static int numescape(const char *); -/* - * 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 i; - size_t sz; - const char *cp; - - i = 0; - - /* 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]); - } - - if ('(' != start[i++]) - return(0); +enum mandoc_esc +mandoc_escape(const char **end, const char **start, int *sz) +{ + const char *local_start; + int local_sz; + char term; + enum mandoc_esc gly; /* - * A parenthesised subexpression. Read until the closing - * parenthesis, making sure to handle any nested subexpressions - * that might ruin our parse. + * When the caller doesn't provide return storage, + * use local storage. */ - while (')' != start[i]) { - sz = strcspn(&start[i], ")\\"); - i += (int)sz; - - if ('\0' == start[i]) - return(-1); - else if ('\\' != start[i]) - continue; + if (NULL == start) + start = &local_start; + if (NULL == sz) + sz = &local_sz; - 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; + /* + * Beyond the backslash, at least one input character + * is part of the escape sequence. With one exception + * (see below), that character won't be returned. + */ - cp = *end; - rstart = cp; - if (start) - *start = rstart; - i = lim = 0; gly = ESCAPE_ERROR; - term = numeric = '\0'; + *start = ++*end; + *sz = 0; + term = '\0'; - switch ((c = cp[i++])) { + switch ((*start)[-1]) { /* * First the glyphs. There are several different forms of * these, but each eventually returns a substring of the glyph @@ -121,7 +76,7 @@ mandoc_escape(const char **end, const char **start, int *sz) */ case ('('): gly = ESCAPE_SPECIAL; - lim = 2; + *sz = 2; break; case ('['): gly = ESCAPE_SPECIAL; @@ -131,17 +86,27 @@ mandoc_escape(const char **end, const char **start, int *sz) * Unicode codepoint. Here, however, only check whether * it's not a zero-width escape. */ - if ('u' == cp[i] && ']' != cp[i + 1]) + if ('u' == (*start)[0] && ']' != (*start)[1]) gly = ESCAPE_UNICODE; term = ']'; break; case ('C'): - if ('\'' != cp[i]) + if ('\'' != **start) return(ESCAPE_ERROR); gly = ESCAPE_SPECIAL; + *start = ++*end; term = '\''; break; + /* + * The \z escape is supposed to output the following + * character without advancing the cursor position. + * Since we are mostly dealing with terminal mode, + * let us just skip the next character. + */ + case ('z'): + return(ESCAPE_SKIPCHAR); + /* * Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where * 'X' is the trigger. These have opaque sub-strings. @@ -166,21 +131,17 @@ mandoc_escape(const char **end, const char **start, int *sz) case ('f'): if (ESCAPE_ERROR == gly) gly = ESCAPE_FONT; - - rstart= &cp[i]; - if (start) - *start = rstart; - - switch (cp[i++]) { + switch (**start) { case ('('): - lim = 2; + *start = ++*end; + *sz = 2; break; case ('['): + *start = ++*end; term = ']'; break; default: - lim = 1; - i--; + *sz = 1; break; } break; @@ -202,9 +163,10 @@ mandoc_escape(const char **end, const char **start, int *sz) case ('X'): /* FALLTHROUGH */ case ('Z'): - if ('\'' != cp[i++]) + if ('\'' != **start) return(ESCAPE_ERROR); gly = ESCAPE_IGNORE; + *start = ++*end; term = '\''; break; @@ -230,11 +192,12 @@ mandoc_escape(const char **end, const char **start, int *sz) case ('w'): /* FALLTHROUGH */ case ('x'): + if ('\'' != **start) + return(ESCAPE_ERROR); if (ESCAPE_ERROR == gly) gly = ESCAPE_IGNORE; - if ('\'' != cp[i++]) - return(ESCAPE_ERROR); - term = numeric = '\''; + *start = ++*end; + term = '\''; break; /* @@ -242,17 +205,17 @@ mandoc_escape(const char **end, const char **start, int *sz) * XXX Do any other escapes need similar handling? */ case ('N'): - if ('\0' == cp[i]) + if ('\0' == **start) return(ESCAPE_ERROR); - *end = &cp[++i]; - if (isdigit((unsigned char)cp[i-1])) + (*end)++; + if (isdigit((unsigned char)**start)) { + *sz = 1; return(ESCAPE_IGNORE); + } + (*start)++; while (isdigit((unsigned char)**end)) (*end)++; - if (start) - *start = &cp[i]; - if (sz) - *sz = *end - &cp[i]; + *sz = *end - *start; if ('\0' != **end) (*end)++; return(ESCAPE_NUMBERED); @@ -263,122 +226,93 @@ mandoc_escape(const char **end, const char **start, int *sz) 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; + if ('+' == **end || '-' == **end || ASCII_HYPH == **end) + (*end)++; - switch (cp[i++]) { + switch (**end) { case ('('): - lim = 2; + *start = ++*end; + *sz = 2; break; case ('['): - term = numeric = ']'; + *start = ++*end; + term = ']'; break; case ('\''): - term = numeric = '\''; + *start = ++*end; + term = '\''; break; default: - lim = 1; - i--; + *sz = 1; break; } - /* See +/- counts as a sign. */ - c = cp[i]; - if ('+' == c || '-' == c || ASCII_HYPH == c) - ++i; - break; /* * Anything else is assumed to be a glyph. + * In this case, pass back the character after the backslash. */ default: gly = ESCAPE_SPECIAL; - lim = 1; - i--; + *start = --*end; + *sz = 1; break; } 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. + * Read up to the terminating character, + * paying attention to nested escapes. */ if ('\0' != term) { - *end = strchr(&cp[i], term); - if ('\0' == *end) + while (**end != term) { + switch (**end) { + case ('\0'): + return(ESCAPE_ERROR); + case ('\\'): + (*end)++; + if (ESCAPE_ERROR == + mandoc_escape(end, NULL, NULL)) + return(ESCAPE_ERROR); + break; + default: + (*end)++; + break; + } + } + *sz = (*end)++ - *start; + } else { + assert(*sz > 0); + if ((size_t)*sz > strlen(*start)) return(ESCAPE_ERROR); - - rlim = *end - &cp[i]; - if (sz) - *sz = rlim; - (*end)++; - goto out; + *end += *sz; } - 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) + if (2 == *sz) { + if ('C' == **start) { + /* + * Treat constant-width font modes + * just like regular font modes. + */ + (*start)++; + (*sz)--; + } else { + if ('B' == (*start)[0] && 'I' == (*start)[1]) + gly = ESCAPE_FONTBI; + break; + } + } else if (1 != *sz) break; - switch (*rstart) { + switch (**start) { case ('3'): /* FALLTHROUGH */ case ('B'): @@ -400,9 +334,7 @@ out: } break; case (ESCAPE_SPECIAL): - if (1 != rlim) - break; - if ('c' == *rstart) + if (1 == *sz && 'c' == **start) gly = ESCAPE_NOSPACE; break; default: @@ -506,17 +438,35 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos) pairs = 0; white = 0; for (cp = start; '\0' != *cp; cp++) { - /* Move left after quoted quotes and escaped backslashes. */ + + /* + * Move the following text left + * after quoted quotes and after "\\" and "\t". + */ if (pairs) cp[-pairs] = cp[0]; + if ('\\' == cp[0]) { - if ('\\' == cp[1]) { - /* Poor man's copy mode. */ + /* + * In copy mode, translate double to single + * backslashes and backslash-t to literal tabs. + */ + switch (cp[1]) { + case ('t'): + cp[0] = '\t'; + /* FALLTHROUGH */ + case ('\\'): pairs++; cp++; - } else if (0 == quoted && ' ' == cp[1]) + break; + case (' '): /* Skip escaped blanks. */ - cp++; + if (0 == quoted) + cp++; + break; + default: + break; + } } else if (0 == quoted) { if (' ' == cp[0]) { /* Unescaped blanks end unquoted args. */ @@ -677,32 +627,6 @@ mandoc_eos(const char *p, size_t sz, int enclosed) return(found && !enclosed); } -/* - * 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; - - 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. diff --git a/contrib/mdocml/mandoc.h b/contrib/mdocml/mandoc.h index a37effc5f5..c2406e952c 100644 --- a/contrib/mdocml/mandoc.h +++ b/contrib/mdocml/mandoc.h @@ -1,6 +1,7 @@ -/* $Id: mandoc.h,v 1.99 2012/02/16 20:51:31 joerg Exp $ */ +/* $Id: mandoc.h,v 1.110 2013/09/16 00:25:07 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -50,6 +51,7 @@ enum mandocerr { MANDOCERR_NOTITLE, /* no title in document */ MANDOCERR_UPPERCASE, /* document title should be all caps */ MANDOCERR_BADMSEC, /* unknown manual section */ + MANDOCERR_BADVOLARCH, /* unknown manual volume or arch */ MANDOCERR_NODATE, /* date missing, using today's date */ MANDOCERR_BADDATE, /* cannot parse date, using it verbatim */ MANDOCERR_PROLOGOOO, /* prologue macros out of order */ @@ -61,14 +63,14 @@ enum mandocerr { MANDOCERR_SO, /* .so is fragile, better use ln(1) */ MANDOCERR_NAMESECFIRST, /* NAME section must come first */ MANDOCERR_BADNAMESEC, /* bad NAME section contents */ - MANDOCERR_NONAME, /* manual name not yet set */ MANDOCERR_SECOOO, /* sections out of conventional order */ MANDOCERR_SECREP, /* duplicate section name */ - MANDOCERR_SECMSEC, /* section not in conventional manual section */ + MANDOCERR_SECMSEC, /* section header suited to sections ... */ /* related to macros and nesting */ MANDOCERR_MACROOBS, /* skipping obsolete macro */ MANDOCERR_IGNPAR, /* skipping paragraph macro */ + MANDOCERR_MOVEPAR, /* moving paragraph macro out of list */ MANDOCERR_IGNNS, /* skipping no-space macro */ MANDOCERR_SCOPENEST, /* blocks badly nested */ MANDOCERR_CHILD, /* child violates parent syntax */ @@ -129,10 +131,12 @@ enum mandocerr { MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */ MANDOCERR_BADCHAR, /* skipping bad character */ MANDOCERR_NAMESC, /* escaped character not allowed in a name */ + MANDOCERR_NONAME, /* manual name not yet set */ MANDOCERR_NOTEXT, /* skipping text before the first section header */ MANDOCERR_MACRO, /* skipping unknown macro */ MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */ MANDOCERR_ARGCOUNT, /* argument count wrong */ + MANDOCERR_STRAYTA, /* skipping column outside column list */ MANDOCERR_NOSCOPE, /* skipping end of block that is not open */ MANDOCERR_SCOPEBROKEN, /* missing end of block */ MANDOCERR_SCOPEEXIT, /* scope open on exit */ @@ -141,6 +145,7 @@ enum mandocerr { MANDOCERR_NOARGS, /* macro requires line argument(s) */ MANDOCERR_NOBODY, /* macro requires body argument(s) */ MANDOCERR_NOARGV, /* macro requires argument(s) */ + MANDOCERR_NUMERIC, /* request requires a numeric argument */ MANDOCERR_LISTTYPE, /* missing list type */ MANDOCERR_ARGSLOST, /* line argument(s) will be lost */ MANDOCERR_BODYLOST, /* body argument(s) will be lost */ @@ -160,7 +165,7 @@ enum mandocerr { MANDOCERR_MAX }; -struct tbl { +struct tbl_opts { char tab; /* cell-separator */ char decimal; /* decimal point */ int linesize; @@ -175,20 +180,14 @@ struct tbl { int cols; /* number of columns */ }; -enum tbl_headt { - TBL_HEAD_DATA, /* plug in data from tbl_dat */ - TBL_HEAD_VERT, /* vertical spacer */ - TBL_HEAD_DVERT /* double-vertical spacer */ -}; - /* * The head of a table specifies all of its columns. When formatting a * tbl_span, iterate over these and plug in data from the tbl_span when * appropriate, using tbl_cell as a guide to placement. */ struct tbl_head { - enum tbl_headt pos; int ident; /* 0 <= unique id < cols */ + int vert; /* width of preceding vertical line */ struct tbl_head *next; struct tbl_head *prev; }; @@ -203,8 +202,6 @@ enum tbl_cellt { TBL_CELL_DOWN, /* ^ */ TBL_CELL_HORIZ, /* _, - */ TBL_CELL_DHORIZ, /* = */ - TBL_CELL_VERT, /* | */ - TBL_CELL_DVERT, /* || */ TBL_CELL_MAX }; @@ -213,6 +210,7 @@ enum tbl_cellt { */ struct tbl_cell { struct tbl_cell *next; + int vert; /* width of preceding vertical line */ enum tbl_cellt pos; size_t spacing; int flags; @@ -266,7 +264,7 @@ enum tbl_spant { * A row of data in a table. */ struct tbl_span { - struct tbl *tbl; + struct tbl_opts *opts; struct tbl_head *head; struct tbl_row *layout; /* layout row */ struct tbl_dat *first; @@ -382,11 +380,13 @@ enum mandoc_esc { ESCAPE_FONT, /* a generic font mode */ ESCAPE_FONTBOLD, /* bold font mode */ ESCAPE_FONTITALIC, /* italic font mode */ + ESCAPE_FONTBI, /* bold italic font mode */ ESCAPE_FONTROMAN, /* roman font mode */ ESCAPE_FONTPREV, /* previous font mode */ ESCAPE_NUMBERED, /* a numbered glyph */ ESCAPE_UNICODE, /* a unicode codepoint */ - ESCAPE_NOSPACE /* suppress space if the last on a line */ + ESCAPE_NOSPACE, /* suppress space if the last on a line */ + ESCAPE_SKIPCHAR /* skip the next character */ }; typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel, @@ -413,8 +413,8 @@ 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 *); +struct mparse *mparse_alloc(enum mparset, enum mandoclevel, + mandocmsg, void *, char *); void mparse_free(struct mparse *); void mparse_keep(struct mparse *); enum mandoclevel mparse_readfd(struct mparse *, int, const char *); diff --git a/contrib/mdocml/mandoc_char.7 b/contrib/mdocml/mandoc_char.7 index acc1b6100d..23ccc0aa03 100644 --- a/contrib/mdocml/mandoc_char.7 +++ b/contrib/mdocml/mandoc_char.7 @@ -1,4 +1,4 @@ -.\" $Id: mandoc_char.7,v 1.51 2011/11/23 10:09:30 kristaps Exp $ +.\" $Id: mandoc_char.7,v 1.53 2013/07/13 19:41:16 schwarze Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 23 2011 $ +.Dd $Mdocdate: July 13 2013 $ .Dt MANDOC_CHAR 7 .Os .Sh NAME @@ -684,7 +684,7 @@ 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 +This section documents compatibility between mandoc and other troff implementations, at this time limited to GNU troff .Pq Qq groff . .Pp @@ -728,8 +728,7 @@ known representation. The .Nm manual page was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . .Sh CAVEATS The .Sq \e*(Ba diff --git a/contrib/mdocml/mandocdb.8 b/contrib/mdocml/mandocdb.8 index cb48359b34..83b6a0102e 100644 --- a/contrib/mdocml/mandocdb.8 +++ b/contrib/mdocml/mandocdb.8 @@ -1,4 +1,4 @@ -.\" $Id: mandocdb.8,v 1.17 2011/12/25 21:00:23 schwarze Exp $ +.\" $Id: mandocdb.8,v 1.17.2.1 2013/09/18 01:04:07 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 25 2011 $ +.Dd $Mdocdate: September 18 2013 $ .Dt MANDOCDB 8 .Os .Sh NAME @@ -125,7 +125,7 @@ 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 , +.Pa mandoc.index , is a .Xr recno 3 database with record values consisting of @@ -161,7 +161,7 @@ Each of the above is NUL-terminated. If the record value is zero-length, it is unassigned. .Ss Keyword Database The keyword database, -.Pa whatis.db , +.Pa mandoc.db , is a .Xr btree 3 database of NUL-terminated keywords (record length is non-zero string @@ -225,12 +225,12 @@ or respectively, grows as a multiple of the index length and input size. .Sh FILES .Bl -tag -width Ds -.It Pa whatis.db +.It Pa mandoc.db A .Xr btree 3 keyword database mapping keywords to a type and file reference in -.Pa whatis.index . -.It Pa whatis.index +.Pa mandoc.index . +.It Pa mandoc.index A .Xr recno 3 database of indexed file-names. @@ -285,9 +285,40 @@ arguments. .Xr btree 3 , .Xr recno 3 , .Xr man.conf 5 -.Sh AUTHORS +.Sh HISTORY +A +.Nm makewhatis +utility first appeared in +.Bx 2 . +It was rewritten in +.Xr perl 1 +for +.Ox 2.7 +and in C for +.Ox 5.1 . +.Pp The +.Ar dir +argument first appeared in +.Nx 1.0 ; +the options +.Fl dtu +in +.Ox 2.7 ; +and the options +.Fl aCvW +in +.Ox 5.1 . +.Sh AUTHORS +.An -nosplit +.An Bill Joy +wrote the original +.Bx +.Nm makewhatis +in February 1979, +.An Marc Espie +started the Perl version in 2000, +and the current version of .Nm -utility was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +was written by +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/mandocdb.c b/contrib/mdocml/mandocdb.c index e621c1d2a2..028377ccb7 100644 --- a/contrib/mdocml/mandocdb.c +++ b/contrib/mdocml/mandocdb.c @@ -1,7 +1,7 @@ -/* $Id: mandocdb.c,v 1.46 2012/03/23 06:52:17 kristaps Exp $ */ +/* $Id: mandocdb.c,v 1.49.2.7 2013/10/02 21:03:26 schwarze Exp $ */ /* - * Copyright (c) 2011 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2011, 2012 Kristaps Dzonsons + * Copyright (c) 2011, 2012 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,7 +19,6 @@ #include "config.h" #endif -#include #include #include @@ -28,22 +27,28 @@ #include #include #include +#include #include #include #include #include #include -#if defined(__linux__) +#if defined(__linux__) || defined(__sun) # include # include #elif defined(__APPLE__) # include # include #else +# include # include #endif +#if defined(__sun) +#include +#endif + #include "man.h" #include "mdoc.h" #include "mandoc.h" @@ -56,20 +61,11 @@ #define MANDOC_SRC 0x1 #define MANDOC_FORM 0x2 -#define WARNING(_f, _b, _fmt, _args...) \ - do if (warnings) { \ - fprintf(stderr, "%s: ", (_b)); \ - fprintf(stderr, (_fmt), ##_args); \ - if ('\0' != *(_f)) \ - fprintf(stderr, ": %s", (_f)); \ - fprintf(stderr, "\n"); \ - } while (/* CONSTCOND */ 0) - /* Access to the mandoc database on disk. */ struct mdb { - char idxn[MAXPATHLEN]; /* index db filename */ - char dbn[MAXPATHLEN]; /* keyword db filename */ + char idxn[PATH_MAX]; /* index db filename */ + char dbn[PATH_MAX]; /* keyword db filename */ DB *idx; /* index recno database */ DB *db; /* keyword btree database */ }; @@ -133,17 +129,16 @@ static void hash_put(DB *, const struct buf *, uint64_t); static void hash_reset(DB **); static void index_merge(const struct of *, struct mparse *, struct buf *, struct buf *, DB *, - struct mdb *, struct recs *, - const char *); + struct mdb *, struct recs *); static void index_prune(const struct of *, struct mdb *, - struct recs *, const char *); -static void ofile_argbuild(int, char *[], - struct of **, const char *); + struct recs *); +static void ofile_argbuild(int, char *[], struct of **, + const char *); static void ofile_dirbuild(const char *, const char *, - const char *, int, struct of **, char *); + const char *, int, struct of **); static void ofile_free(struct of *); -static void pformatted(DB *, struct buf *, struct buf *, - const struct of *, const char *); +static void pformatted(DB *, struct buf *, + struct buf *, const struct of *); static int pman_node(MAN_ARGS); static void pmdoc_node(MDOC_ARGS); static int pmdoc_head(MDOC_ARGS); @@ -304,11 +299,12 @@ main(int argc, char *argv[]) struct recs recs; enum op op; /* current operation */ const char *dir; + char *cp; + char pbuf[PATH_MAX]; int ch, i, flags; - char dirbuf[MAXPATHLEN]; DB *hash; /* temporary keyword hashtable */ BTREEINFO info; /* btree configuration */ - size_t sz1, sz2; + size_t sz1, sz2, ipath; struct buf buf, /* keyword buffer */ dbuf; /* description buffer */ struct of *of; /* list of files for processing */ @@ -396,7 +392,7 @@ main(int argc, char *argv[]) info.lorder = 4321; info.flags = R_DUP; - mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL); + mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL, NULL); memset(&buf, 0, sizeof(struct buf)); memset(&dbuf, 0, sizeof(struct buf)); @@ -407,25 +403,31 @@ main(int argc, char *argv[]) dbuf.cp = mandoc_malloc(dbuf.size); if (OP_TEST == op) { - ofile_argbuild(argc, argv, &of, "."); + ofile_argbuild(argc, argv, &of, NULL); if (NULL == of) goto out; - index_merge(of, mp, &dbuf, &buf, - hash, &mdb, &recs, "."); + index_merge(of, mp, &dbuf, &buf, hash, &mdb, &recs); goto out; } if (OP_UPDATE == op || OP_DELETE == op) { - strlcat(mdb.dbn, dir, MAXPATHLEN); - strlcat(mdb.dbn, "/", MAXPATHLEN); - sz1 = strlcat(mdb.dbn, MANDOC_DB, MAXPATHLEN); + if (NULL == realpath(dir, pbuf)) { + perror(dir); + exit((int)MANDOCLEVEL_BADARG); + } + if (strlcat(pbuf, "/", PATH_MAX) >= PATH_MAX) { + fprintf(stderr, "%s: path too long\n", pbuf); + exit((int)MANDOCLEVEL_BADARG); + } - strlcat(mdb.idxn, dir, MAXPATHLEN); - strlcat(mdb.idxn, "/", MAXPATHLEN); - sz2 = strlcat(mdb.idxn, MANDOC_IDX, MAXPATHLEN); + strlcat(mdb.dbn, pbuf, PATH_MAX); + sz1 = strlcat(mdb.dbn, MANDOC_DB, PATH_MAX); - if (sz1 >= MAXPATHLEN || sz2 >= MAXPATHLEN) { - fprintf(stderr, "%s: path too long\n", dir); + strlcat(mdb.idxn, pbuf, PATH_MAX); + sz2 = strlcat(mdb.idxn, MANDOC_IDX, PATH_MAX); + + if (sz1 >= PATH_MAX || sz2 >= PATH_MAX) { + fprintf(stderr, "%s: path too long\n", mdb.idxn); exit((int)MANDOCLEVEL_BADARG); } @@ -441,12 +443,12 @@ main(int argc, char *argv[]) exit((int)MANDOCLEVEL_SYSERR); } - ofile_argbuild(argc, argv, &of, dir); + ofile_argbuild(argc, argv, &of, pbuf); if (NULL == of) goto out; - index_prune(of, &mdb, &recs, dir); + index_prune(of, &mdb, &recs); /* * Go to the root of the respective manual tree. @@ -460,7 +462,7 @@ main(int argc, char *argv[]) exit((int)MANDOCLEVEL_SYSERR); } index_merge(of, mp, &dbuf, &buf, hash, - &mdb, &recs, dir); + &mdb, &recs); } goto out; @@ -475,48 +477,72 @@ main(int argc, char *argv[]) if (argc > 0) { dirs.paths = mandoc_calloc(argc, sizeof(char *)); dirs.sz = argc; - for (i = 0; i < argc; i++) - dirs.paths[i] = mandoc_strdup(argv[i]); + for (i = 0; i < argc; i++) { + if (NULL == (cp = realpath(argv[i], pbuf))) { + perror(argv[i]); + goto out; + } + dirs.paths[i] = mandoc_strdup(cp); + } } else manpath_parse(&dirs, dir, NULL, NULL); - for (i = 0; i < dirs.sz; i++) { + for (ipath = 0; ipath < dirs.sz; ipath++) { + /* * Go to the root of the respective manual tree. * This must work or no manuals may be found: * They are indexed relative to the root. */ - if (-1 == chdir(dirs.paths[i])) { - perror(dirs.paths[i]); + if (-1 == chdir(dirs.paths[ipath])) { + perror(dirs.paths[ipath]); exit((int)MANDOCLEVEL_SYSERR); } - strlcpy(mdb.dbn, MANDOC_DB, MAXPATHLEN); - strlcpy(mdb.idxn, MANDOC_IDX, MAXPATHLEN); + /* Create a new database in two temporary files. */ - flags = O_CREAT | O_TRUNC | O_RDWR; - mdb.db = dbopen(mdb.dbn, flags, 0644, DB_BTREE, &info); - mdb.idx = dbopen(mdb.idxn, flags, 0644, DB_RECNO, NULL); - - if (NULL == mdb.db) { - perror(mdb.dbn); - exit((int)MANDOCLEVEL_SYSERR); - } else if (NULL == mdb.idx) { - perror(mdb.idxn); - exit((int)MANDOCLEVEL_SYSERR); + flags = O_CREAT | O_EXCL | O_RDWR; + while (NULL == mdb.db) { + strlcpy(mdb.dbn, MANDOC_DB, PATH_MAX); + strlcat(mdb.dbn, ".XXXXXXXXXX", PATH_MAX); + if (NULL == mktemp(mdb.dbn)) { + perror(mdb.dbn); + exit((int)MANDOCLEVEL_SYSERR); + } + mdb.db = dbopen(mdb.dbn, flags, 0644, + DB_BTREE, &info); + if (NULL == mdb.db && EEXIST != errno) { + perror(mdb.dbn); + exit((int)MANDOCLEVEL_SYSERR); + } + } + while (NULL == mdb.idx) { + strlcpy(mdb.idxn, MANDOC_IDX, PATH_MAX); + strlcat(mdb.idxn, ".XXXXXXXXXX", PATH_MAX); + if (NULL == mktemp(mdb.idxn)) { + perror(mdb.idxn); + unlink(mdb.dbn); + exit((int)MANDOCLEVEL_SYSERR); + } + mdb.idx = dbopen(mdb.idxn, flags, 0644, + DB_RECNO, NULL); + if (NULL == mdb.idx && EEXIST != errno) { + perror(mdb.idxn); + unlink(mdb.dbn); + exit((int)MANDOCLEVEL_SYSERR); + } } /* * Search for manuals and fill the new database. */ - strlcpy(dirbuf, dirs.paths[i], MAXPATHLEN); - ofile_dirbuild(".", "", "", 0, &of, dirbuf); + ofile_dirbuild(".", "", "", 0, &of); if (NULL != of) { index_merge(of, mp, &dbuf, &buf, hash, - &mdb, &recs, dirs.paths[i]); + &mdb, &recs); ofile_free(of); of = NULL; } @@ -525,6 +551,26 @@ main(int argc, char *argv[]) (*mdb.idx->close)(mdb.idx); mdb.db = NULL; mdb.idx = NULL; + + /* + * Replace the old database with the new one. + * This is not perfectly atomic, + * but i cannot think of a better way. + */ + + if (-1 == rename(mdb.dbn, MANDOC_DB)) { + perror(MANDOC_DB); + unlink(mdb.dbn); + unlink(mdb.idxn); + exit((int)MANDOCLEVEL_SYSERR); + } + if (-1 == rename(mdb.idxn, MANDOC_IDX)) { + perror(MANDOC_IDX); + unlink(MANDOC_DB); + unlink(MANDOC_IDX); + unlink(mdb.idxn); + exit((int)MANDOCLEVEL_SYSERR); + } } out: @@ -547,7 +593,7 @@ out: usage: fprintf(stderr, - "usage: %s [-av] [-C file] | dir ... | -t file ...\n" + "usage: %s [-avvv] [-C file] | dir ... | -t file ...\n" " -d dir [file ...] | " "-u dir [file ...]\n", progname); @@ -558,18 +604,16 @@ usage: void index_merge(const struct of *of, struct mparse *mp, struct buf *dbuf, struct buf *buf, DB *hash, - struct mdb *mdb, struct recs *recs, - const char *basedir) + struct mdb *mdb, struct recs *recs) { recno_t rec; int ch, skip; DBT key, val; DB *files; /* temporary file name table */ - char emptystring[1] = {'\0'}; struct mdoc *mdoc; struct man *man; - char *p; const char *fn, *msec, *march, *mtitle; + char *p; uint64_t mask; size_t sv; unsigned seq; @@ -629,9 +673,13 @@ index_merge(const struct of *of, struct mparse *mp, skip = 0; assert(of->sec); assert(msec); - if (strcasecmp(msec, of->sec)) - WARNING(fn, basedir, "Section \"%s\" manual " - "in \"%s\" directory", msec, of->sec); + if (warnings) + if (strcasecmp(msec, of->sec)) + fprintf(stderr, "%s: " + "section \"%s\" manual " + "in \"%s\" directory\n", + fn, msec, of->sec); + /* * Manual page directories exist for each kernel * architecture as returned by machine(1). @@ -649,10 +697,12 @@ index_merge(const struct of *of, struct mparse *mp, assert(of->arch); assert(march); - if (strcasecmp(march, of->arch)) - WARNING(fn, basedir, "Architecture \"%s\" " - "manual in \"%s\" directory", - march, of->arch); + if (warnings) + if (strcasecmp(march, of->arch)) + fprintf(stderr, "%s: " + "architecture \"%s\" manual " + "in \"%s\" directory\n", + fn, march, of->arch); /* * By default, skip a file if the title given @@ -688,7 +738,7 @@ index_merge(const struct of *of, struct mparse *mp, val.data = NULL; val.size = 0; if (0 == skip) - val.data = emptystring; + val.data = ""; else { ch = (*files->get)(files, &key, &val, 0); if (ch < 0) { @@ -742,7 +792,7 @@ index_merge(const struct of *of, struct mparse *mp, else if (man) pman_node(hash, buf, dbuf, man_node(man)); else - pformatted(hash, buf, dbuf, of, basedir); + pformatted(hash, buf, dbuf, of); /* Test mode, do not access any database. */ @@ -789,6 +839,8 @@ index_merge(const struct of *of, struct mparse *mp, } if (ch < 0) { perror("hash"); + unlink(mdb->dbn); + unlink(mdb->idxn); exit((int)MANDOCLEVEL_SYSERR); } @@ -807,7 +859,7 @@ index_merge(const struct of *of, struct mparse *mp, val.size = dbuf->len; if (verb) - printf("%s: Adding to index: %s\n", basedir, fn); + printf("%s: adding to index\n", fn); dbt_put(mdb->idx, mdb->idxn, &key, &val); } @@ -822,9 +874,9 @@ index_merge(const struct of *of, struct mparse *mp, while (0 == (*files->seq)(files, &key, &val, seq)) { seq = R_NEXT; if (val.size) - WARNING((char *)val.data, basedir, - "Probably unreachable, title " - "is %s", (char *)key.data); + fprintf(stderr, "%s: probably " + "unreachable, title is %s\n", + (char *)val.data, (char *)key.data); } (*files->close)(files); } @@ -837,8 +889,7 @@ index_merge(const struct of *of, struct mparse *mp, * in `idx' (zeroing its value size). */ static void -index_prune(const struct of *ofile, struct mdb *mdb, - struct recs *recs, const char *basedir) +index_prune(const struct of *ofile, struct mdb *mdb, struct recs *recs) { const struct of *of; const char *fn; @@ -913,8 +964,7 @@ index_prune(const struct of *ofile, struct mdb *mdb, } if (verb) - printf("%s: Deleting from index: %s\n", - basedir, fn); + printf("%s: deleting from index\n", fn); val.size = 0; ch = (*mdb->idx->put)(mdb->idx, &key, &val, R_CURSOR); @@ -1474,15 +1524,16 @@ pman_node(MAN_ARGS) * By necessity, this involves rather crude guesswork. */ static void -pformatted(DB *hash, struct buf *buf, struct buf *dbuf, - const struct of *of, const char *basedir) +pformatted(DB *hash, struct buf *buf, + struct buf *dbuf, const struct of *of) { FILE *stream; char *line, *p, *title; size_t len, plen, titlesz; if (NULL == (stream = fopen(of->fname, "r"))) { - WARNING(of->fname, basedir, "%s", strerror(errno)); + if (warnings) + perror(of->fname); return; } @@ -1537,6 +1588,7 @@ pformatted(DB *hash, struct buf *buf, struct buf *dbuf, title[(int)titlesz - 1] = ' '; } + /* * If no page content can be found, or the input line * is already the next section header, or there is no @@ -1545,8 +1597,9 @@ pformatted(DB *hash, struct buf *buf, struct buf *dbuf, */ if (NULL == title || '\0' == *title) { - WARNING(of->fname, basedir, - "Cannot find NAME section"); + if (warnings) + fprintf(stderr, "%s: cannot find NAME section\n", + of->fname); buf_appendb(dbuf, buf->cp, buf->size); hash_put(hash, buf, TYPE_Nd); fclose(stream); @@ -1567,8 +1620,9 @@ pformatted(DB *hash, struct buf *buf, struct buf *dbuf, for (p += 2; ' ' == *p || '\b' == *p; p++) /* Skip to next word. */ ; } else { - WARNING(of->fname, basedir, - "No dash in title line"); + if (warnings) + fprintf(stderr, "%s: no dash in title line\n", + of->fname); p = title; } @@ -1595,16 +1649,30 @@ pformatted(DB *hash, struct buf *buf, struct buf *dbuf, } static void -ofile_argbuild(int argc, char *argv[], - struct of **of, const char *basedir) +ofile_argbuild(int argc, char *argv[], struct of **of, + const char *basedir) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; + char pbuf[PATH_MAX]; const char *sec, *arch, *title; - char *p; + char *relpath, *p; int i, src_form; struct of *nof; for (i = 0; i < argc; i++) { + if (NULL == (relpath = realpath(argv[i], pbuf))) { + perror(argv[i]); + continue; + } + if (NULL != basedir) { + if (strstr(pbuf, basedir) != pbuf) { + fprintf(stderr, "%s: file outside " + "base directory %s\n", + pbuf, basedir); + continue; + } + relpath = pbuf + strlen(basedir); + } /* * Try to infer the manual section, architecture and @@ -1613,8 +1681,8 @@ ofile_argbuild(int argc, char *argv[], * cat
[/]/.0 */ - if (strlcpy(buf, argv[i], sizeof(buf)) >= sizeof(buf)) { - fprintf(stderr, "%s: Path too long\n", argv[i]); + if (strlcpy(buf, relpath, sizeof(buf)) >= sizeof(buf)) { + fprintf(stderr, "%s: path too long\n", relpath); continue; } sec = arch = title = ""; @@ -1646,8 +1714,11 @@ ofile_argbuild(int argc, char *argv[], break; } if ('\0' == *title) { - WARNING(argv[i], basedir, - "Cannot deduce title from filename"); + if (warnings) + fprintf(stderr, + "%s: cannot deduce title " + "from filename\n", + relpath); title = buf; } @@ -1656,7 +1727,7 @@ ofile_argbuild(int argc, char *argv[], */ nof = mandoc_calloc(1, sizeof(struct of)); - nof->fname = mandoc_strdup(argv[i]); + nof->fname = mandoc_strdup(relpath); nof->sec = mandoc_strdup(sec); nof->arch = mandoc_strdup(arch); nof->title = mandoc_strdup(title); @@ -1681,15 +1752,18 @@ ofile_argbuild(int argc, char *argv[], * Recursively build up a list of files to parse. * We use this instead of ftw() and so on because I don't want global * variables hanging around. - * This ignores the mandocdb.db and mandocdb.index files, but assumes that + * This ignores the mandoc.db and mandoc.index files, but assumes that * everything else is a manual. * Pass in a pointer to a NULL structure for the first invocation. */ static void ofile_dirbuild(const char *dir, const char* psec, const char *parch, - int p_src_form, struct of **of, char *basedir) + int p_src_form, struct of **of) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; +#if defined(__sun) + struct stat sb; +#endif size_t sz; DIR *d; const char *fn, *sec, *arch; @@ -1699,7 +1773,8 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, int src_form; if (NULL == (d = opendir(dir))) { - WARNING("", dir, "%s", strerror(errno)); + if (warnings) + perror(dir); return; } @@ -1711,7 +1786,12 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, src_form = p_src_form; +#if defined(__sun) + stat(dp->d_name, &sb); + if (S_IFDIR & sb.st_mode) { +#else if (DT_DIR == dp->d_type) { +#endif sec = psec; arch = parch; @@ -1729,7 +1809,9 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, src_form |= MANDOC_FORM; sec = fn + 3; } else { - WARNING(fn, basedir, "Bad section"); + if (warnings) fprintf(stderr, + "%s/%s: bad section\n", + dir, fn); if (use_all) sec = fn; else @@ -1737,45 +1819,53 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, } } else if ('\0' == *arch) { if (NULL != strchr(fn, '.')) { - WARNING(fn, basedir, "Bad architecture"); + if (warnings) fprintf(stderr, + "%s/%s: bad architecture\n", + dir, fn); if (0 == use_all) continue; } arch = fn; } else { - WARNING(fn, basedir, "Excessive subdirectory"); + if (warnings) fprintf(stderr, "%s/%s: " + "excessive subdirectory\n", dir, fn); if (0 == use_all) continue; } buf[0] = '\0'; - strlcat(buf, dir, MAXPATHLEN); - strlcat(buf, "/", MAXPATHLEN); - strlcat(basedir, "/", MAXPATHLEN); - strlcat(basedir, fn, MAXPATHLEN); - sz = strlcat(buf, fn, MAXPATHLEN); - - if (MAXPATHLEN <= sz) { - WARNING(fn, basedir, "Path too long"); + strlcat(buf, dir, PATH_MAX); + strlcat(buf, "/", PATH_MAX); + sz = strlcat(buf, fn, PATH_MAX); + + if (PATH_MAX <= sz) { + if (warnings) fprintf(stderr, "%s/%s: " + "path too long\n", dir, fn); continue; } - ofile_dirbuild(buf, sec, arch, - src_form, of, basedir); - - p = strrchr(basedir, '/'); - *p = '\0'; + ofile_dirbuild(buf, sec, arch, src_form, of); continue; } +#if defined(__sun) + if (0 == S_IFREG & sb.st_mode) { +#else if (DT_REG != dp->d_type) { - WARNING(fn, basedir, "Not a regular file"); +#endif + if (warnings) + fprintf(stderr, + "%s/%s: not a regular file\n", + dir, fn); continue; } if (!strcmp(MANDOC_DB, fn) || !strcmp(MANDOC_IDX, fn)) continue; if ('\0' == *psec) { - WARNING(fn, basedir, "File outside section"); + if (warnings) + fprintf(stderr, + "%s/%s: file outside section\n", + dir, fn); if (0 == use_all) continue; } @@ -1788,14 +1878,20 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, suffix = strrchr(fn, '.'); if (NULL == suffix) { - WARNING(fn, basedir, "No filename suffix"); + if (warnings) + fprintf(stderr, + "%s/%s: no filename suffix\n", + dir, fn); if (0 == use_all) continue; } else if ((MANDOC_SRC & src_form && strcmp(suffix + 1, psec)) || (MANDOC_FORM & src_form && strcmp(suffix + 1, "0"))) { - WARNING(fn, basedir, "Wrong filename suffix"); + if (warnings) + fprintf(stderr, + "%s/%s: wrong filename suffix\n", + dir, fn); if (0 == use_all) continue; if ('0' == suffix[1]) @@ -1814,7 +1910,7 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, if (0 == use_all && MANDOC_FORM & src_form && '\0' != *psec) { buf[0] = '\0'; - strlcat(buf, dir, MAXPATHLEN); + strlcat(buf, dir, PATH_MAX); p = strrchr(buf, '/'); if ('\0' != *parch && NULL != p) for (p--; p > buf; p--) @@ -1826,18 +1922,22 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, p++; if (0 == strncmp("cat", p, 3)) memcpy(p, "man", 3); - strlcat(buf, "/", MAXPATHLEN); - sz = strlcat(buf, fn, MAXPATHLEN); - if (sz >= MAXPATHLEN) { - WARNING(fn, basedir, "Path too long"); + strlcat(buf, "/", PATH_MAX); + sz = strlcat(buf, fn, PATH_MAX); + if (sz >= PATH_MAX) { + if (warnings) fprintf(stderr, + "%s/%s: path too long\n", + dir, fn); continue; } q = strrchr(buf, '.'); if (NULL != q && p < q++) { *q = '\0'; - sz = strlcat(buf, psec, MAXPATHLEN); - if (sz >= MAXPATHLEN) { - WARNING(fn, basedir, "Path too long"); + sz = strlcat(buf, psec, PATH_MAX); + if (sz >= PATH_MAX) { + if (warnings) fprintf(stderr, + "%s/%s: path too long\n", + dir, fn); continue; } if (0 == access(buf, R_OK)) @@ -1848,12 +1948,13 @@ ofile_dirbuild(const char *dir, const char* psec, const char *parch, buf[0] = '\0'; assert('.' == dir[0]); if ('/' == dir[1]) { - strlcat(buf, dir + 2, MAXPATHLEN); - strlcat(buf, "/", MAXPATHLEN); + strlcat(buf, dir + 2, PATH_MAX); + strlcat(buf, "/", PATH_MAX); } - sz = strlcat(buf, fn, MAXPATHLEN); - if (sz >= MAXPATHLEN) { - WARNING(fn, basedir, "Path too long"); + sz = strlcat(buf, fn, PATH_MAX); + if (sz >= PATH_MAX) { + if (warnings) fprintf(stderr, + "%s/%s: path too long\n", dir, fn); continue; } diff --git a/contrib/mdocml/mandocdb.h b/contrib/mdocml/mandocdb.h index bda0536e79..1bfd686ffc 100644 --- a/contrib/mdocml/mandocdb.h +++ b/contrib/mdocml/mandocdb.h @@ -1,4 +1,4 @@ -/* $Id: mandocdb.h,v 1.6 2012/03/23 02:52:33 kristaps Exp $ */ +/* $Id: mandocdb.h,v 1.6.2.1 2013/09/18 00:54:20 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -17,8 +17,8 @@ #ifndef MANDOCDB_H #define MANDOCDB_H -#define MANDOC_DB "mandocdb.db" -#define MANDOC_IDX "mandocdb.index" +#define MANDOC_DB "mandoc.db" +#define MANDOC_IDX "mandoc.index" #define TYPE_An 0x0000000000000001ULL #define TYPE_Ar 0x0000000000000002ULL diff --git a/contrib/mdocml/manpath.c b/contrib/mdocml/manpath.c index b6d9574e30..90089323e3 100644 --- a/contrib/mdocml/manpath.c +++ b/contrib/mdocml/manpath.c @@ -1,4 +1,4 @@ -/* $Id: manpath.c,v 1.8 2011/12/24 22:37:16 kristaps Exp $ */ +/* $Id: manpath.c,v 1.11 2013/06/05 02:00:26 schwarze Exp $ */ /* * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> @@ -19,8 +19,6 @@ #include "config.h" #endif -#include <sys/param.h> - #include <assert.h> #include <ctype.h> #include <limits.h> @@ -42,7 +40,7 @@ manpath_parse(struct manpaths *dirs, const char *file, char *defp, char *auxp) { #ifdef USE_MANPATH - char cmd[(MAXPATHLEN * 3) + 20]; + char cmd[(PATH_MAX * 3) + 20]; FILE *stream; char *buf; size_t sz, bsz; @@ -74,7 +72,7 @@ manpath_parse(struct manpaths *dirs, const char *file, do { buf = mandoc_realloc(buf, bsz + 1024); - sz = fread(buf + (int)bsz, 1, 1024, stream); + sz = fread(buf + bsz, 1, 1024, stream); bsz += sz; } while (sz > 0); @@ -90,8 +88,8 @@ manpath_parse(struct manpaths *dirs, const char *file, char *insert; /* Always prepend -m. */ - manpath_parseline(dirs, auxp); - + manpath_parseline(dirs, auxp); + /* If -M is given, it overrides everything else. */ if (NULL != defp) { manpath_parseline(dirs, defp); @@ -117,7 +115,7 @@ manpath_parse(struct manpaths *dirs, const char *file, } /* Append man.conf(5) to MANPATH. */ - if (':' == defp[(int)strlen(defp) - 1]) { + if (':' == defp[strlen(defp) - 1]) { manpath_parseline(dirs, defp); manpath_manconf(dirs, file); return; @@ -162,7 +160,7 @@ manpath_add(struct manpaths *dirs, const char *dir) { char buf[PATH_MAX]; char *cp; - int i; + size_t i; if (NULL == (cp = realpath(dir, buf))) return; @@ -173,7 +171,7 @@ manpath_add(struct manpaths *dirs, const char *dir) dirs->paths = mandoc_realloc (dirs->paths, - ((size_t)dirs->sz + 1) * sizeof(char *)); + (dirs->sz + 1) * sizeof(char *)); dirs->paths[dirs->sz++] = mandoc_strdup(cp); } @@ -181,7 +179,7 @@ manpath_add(struct manpaths *dirs, const char *dir) void manpath_free(struct manpaths *p) { - int i; + size_t i; for (i = 0; i < p->sz; i++) free(p->paths[i]); diff --git a/contrib/mdocml/manpath.h b/contrib/mdocml/manpath.h index 167ee01021..2fe1b36e15 100644 --- a/contrib/mdocml/manpath.h +++ b/contrib/mdocml/manpath.h @@ -1,4 +1,4 @@ -/* $Id: manpath.h,v 1.5 2011/12/13 20:56:46 kristaps Exp $ */ +/* $Id: manpath.h,v 1.6 2012/06/08 10:32:40 kristaps Exp $ */ /* * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> @@ -23,7 +23,7 @@ * databases. */ struct manpaths { - int sz; + size_t sz; char **paths; }; diff --git a/contrib/mdocml/mdoc.7 b/contrib/mdocml/mdoc.7 index 44d927b56b..00e1a1ae4a 100644 --- a/contrib/mdocml/mdoc.7 +++ b/contrib/mdocml/mdoc.7 @@ -1,4 +1,4 @@ -.\" $Id: mdoc.7,v 1.214 2012/01/03 10:18:05 kristaps Exp $ +.\" $Id: mdoc.7,v 1.220 2013/08/14 15:08:31 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 3 2012 $ +.Dd $Mdocdate: August 14 2013 $ .Dt MDOC 7 .Os .Sh NAME @@ -657,7 +657,7 @@ for all other author listings. .Pp Examples: .Dl \&.An -nosplit -.Dl \&.An Kristaps Dzonsons \&Aq kristaps@bsd.lv +.Dl \&.An Kristaps Dzonsons \&Aq \&Mt kristaps@bsd.lv .Ss \&Ao Begin a block enclosed by angle brackets. Does not have any head arguments. @@ -711,7 +711,9 @@ for fixed strings to be passed verbatim as arguments, use or .Sx \&Cm . .Ss \&At -Formats an AT&T version. +Formats an +.At +version. Accepts one optional argument: .Pp .Bl -tag -width "v[1-7] | 32vX" -offset indent -compact @@ -820,8 +822,8 @@ The most popular is the imaginary macro which resolves to .Sy 6n . .It -A width using the syntax described in -.Sx Scaling Widths . +A scaling width as described in +.Xr roff 7 . .It An arbitrary string, which indents by the length of this string. .El @@ -926,8 +928,8 @@ The .Fl width and .Fl offset -arguments accept -.Sx Scaling Widths +arguments accept scaling widths as described in +.Xr roff 7 or use the length of the given string. The .Fl offset @@ -956,9 +958,9 @@ A columnated list. The .Fl width argument has no effect; instead, each argument specifies the width -of one column, using either the -.Sx Scaling Widths -syntax or the string length of the argument. +of one column, using either the scaling width syntax described in +.Xr roff 7 +or the string length of the argument. If the first line of the body of a .Fl column list is not an @@ -1089,7 +1091,9 @@ Examples: See also .Sx \&Bro . .Ss \&Bsx -Format the BSD/OS version provided as an argument, or a default value if +Format the +.Bsx +version provided as an argument, or a default value if no argument is provided. .Pp Examples: @@ -1109,7 +1113,9 @@ and Prints .Dq is currently in beta test. .Ss \&Bx -Format the BSD version provided as an argument, or a default value if no +Format the +.Bx +version provided as an argument, or a default value if no argument is provided. .Pp Examples: @@ -1405,7 +1411,9 @@ for special-purpose constants and .Sx \&Va for variable symbols. .Ss \&Dx -Format the DragonFly BSD version provided as an argument, or a default +Format the +.Dx +version provided as an argument, or a default value if no argument is provided. .Pp Examples: @@ -1902,6 +1910,7 @@ Its syntax is as follows: .Pp Examples: .Dl \&.Mt discuss@manpages.bsd.lv +.Dl \&.An Kristaps Dzonsons \&Aq \&Mt kristaps@bsd.lv .Ss \&Nd A one line description of the manual's content. This may only be invoked in the @@ -2083,7 +2092,7 @@ This macro is obsolete and not implemented in .Xr mandoc 1 . .Pp Historical -.Xr mdoc 7 +.Nm packages described it as .Dq "old function type (FORTRAN)" . .Ss \&Ox @@ -2347,20 +2356,26 @@ The following standards are recognised: .St -p1003.1b-93 .It \-p1003.1c-95 .St -p1003.1c-95 +.It \-p1003.1d-99 +.St -p1003.1d-99 .It \-p1003.1g-2000 .St -p1003.1g-2000 .It \-p1003.1i-95 .St -p1003.1i-95 +.It \-p1003.1j-2000 +.St -p1003.1j-2000 +.It \-p1003.1q-2000 +.St -p1003.1q-2000 +.It \-p1003.2 +.St -p1003.2 .It \-p1003.2-92 .St -p1003.2-92 .It \-p1003.2a-92 .St -p1003.2a-92 -.It \-p1387.2-95 -.St -p1387.2-95 -.It \-p1003.2 -.St -p1003.2 .It \-p1387.2 .St -p1387.2 +.It \-p1387.2-95 +.St -p1387.2-95 .It \-isoC .St -isoC .It \-isoC-90 @@ -2467,7 +2482,9 @@ Examples: Prints out .Dq currently under development. .Ss \&Ux -Format the UNIX name. +Format the +.Ux +name. Accepts no argument. .Pp Examples: @@ -2532,20 +2549,14 @@ Link to another manual .Pq Qq cross-reference . Its syntax is as follows: .Pp -.D1 Pf \. Sx \&Xr Ar name section +.D1 Pf \. Sx \&Xr Ar name Op section .Pp -The +Cross reference the .Ar name and .Ar section -are the name and section of the linked manual. -If -.Ar section -is followed by non-punctuation, an -.Sx \&Ns -is inserted into the token stream. -This behaviour is for compatibility with -GNU troff. +number of another man page; +omitting the section number is rarely useful. .Pp Examples: .Dl \&.Xr mandoc 1 @@ -2569,8 +2580,8 @@ Its syntax is as follows: .Pp The .Ar height -argument must be formatted as described in -.Sx Scaling Widths . +argument is a scaling width as described in +.Xr roff 7 . If unspecified, .Sx \&sp asserts a single vertical space. @@ -2964,7 +2975,7 @@ Manually switching the font using the .Ql \ef font escape sequences is never required. .Sh COMPATIBILITY -This section documents compatibility between mandoc and other other +This section documents compatibility between mandoc and other troff implementations, at this time limited to GNU troff .Pq Qq groff . The term @@ -3168,5 +3179,4 @@ utility written by Kristaps Dzonsons appeared in The .Nm reference was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/mdoc.c b/contrib/mdocml/mdoc.c index 81a4ffc96f..df68229cfd 100644 --- a/contrib/mdocml/mdoc.c +++ b/contrib/mdocml/mdoc.c @@ -1,7 +1,7 @@ -/* $Id: mdoc.c,v 1.196 2011/09/30 00:13:28 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.203 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012 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 @@ -104,20 +104,20 @@ static int mdoc_ptext(struct mdoc *, int, char *, int); static int mdoc_pmacro(struct mdoc *, int, char *, int); const struct mdoc_node * -mdoc_node(const struct mdoc *m) +mdoc_node(const struct mdoc *mdoc) { - assert( ! (MDOC_HALT & m->flags)); - return(m->first); + assert( ! (MDOC_HALT & mdoc->flags)); + return(mdoc->first); } const struct mdoc_meta * -mdoc_meta(const struct mdoc *m) +mdoc_meta(const struct mdoc *mdoc) { - assert( ! (MDOC_HALT & m->flags)); - return(&m->meta); + assert( ! (MDOC_HALT & mdoc->flags)); + return(&mdoc->meta); } @@ -197,13 +197,14 @@ mdoc_free(struct mdoc *mdoc) * Allocate volatile and non-volatile parse resources. */ struct mdoc * -mdoc_alloc(struct roff *roff, struct mparse *parse) +mdoc_alloc(struct roff *roff, struct mparse *parse, char *defos) { struct mdoc *p; p = mandoc_calloc(1, sizeof(struct mdoc)); p->parse = parse; + p->defos = defos; p->roff = roff; mdoc_hash_init(); @@ -217,61 +218,61 @@ mdoc_alloc(struct roff *roff, struct mparse *parse) * through to macro_end() in macro.c. */ int -mdoc_endparse(struct mdoc *m) +mdoc_endparse(struct mdoc *mdoc) { - assert( ! (MDOC_HALT & m->flags)); - if (mdoc_macroend(m)) + assert( ! (MDOC_HALT & mdoc->flags)); + if (mdoc_macroend(mdoc)) return(1); - m->flags |= MDOC_HALT; + mdoc->flags |= MDOC_HALT; return(0); } int -mdoc_addeqn(struct mdoc *m, const struct eqn *ep) +mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep) { struct mdoc_node *n; - assert( ! (MDOC_HALT & m->flags)); + assert( ! (MDOC_HALT & mdoc->flags)); /* No text before an initial macro. */ - if (SEC_NONE == m->lastnamed) { - mdoc_pmsg(m, ep->ln, ep->pos, MANDOCERR_NOTEXT); + if (SEC_NONE == mdoc->lastnamed) { + mdoc_pmsg(mdoc, ep->ln, ep->pos, MANDOCERR_NOTEXT); return(1); } - n = node_alloc(m, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN); + n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN); n->eqn = ep; - if ( ! node_append(m, n)) + if ( ! node_append(mdoc, n)) return(0); - m->next = MDOC_NEXT_SIBLING; + mdoc->next = MDOC_NEXT_SIBLING; return(1); } int -mdoc_addspan(struct mdoc *m, const struct tbl_span *sp) +mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp) { struct mdoc_node *n; - assert( ! (MDOC_HALT & m->flags)); + assert( ! (MDOC_HALT & mdoc->flags)); /* No text before an initial macro. */ - if (SEC_NONE == m->lastnamed) { - mdoc_pmsg(m, sp->line, 0, MANDOCERR_NOTEXT); + if (SEC_NONE == mdoc->lastnamed) { + mdoc_pmsg(mdoc, sp->line, 0, MANDOCERR_NOTEXT); return(1); } - n = node_alloc(m, sp->line, 0, MDOC_MAX, MDOC_TBL); + n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL); n->span = sp; - if ( ! node_append(m, n)) + if ( ! node_append(mdoc, n)) return(0); - m->next = MDOC_NEXT_SIBLING; + mdoc->next = MDOC_NEXT_SIBLING; return(1); } @@ -281,12 +282,12 @@ mdoc_addspan(struct mdoc *m, const struct tbl_span *sp) * the macro (mdoc_pmacro()) or text parser (mdoc_ptext()). */ int -mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs) +mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs) { - assert( ! (MDOC_HALT & m->flags)); + assert( ! (MDOC_HALT & mdoc->flags)); - m->flags |= MDOC_NEWLINE; + mdoc->flags |= MDOC_NEWLINE; /* * Let the roff nS register switch SYNOPSIS mode early, @@ -294,16 +295,16 @@ 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 (roff_regisset(m->roff, REG_nS)) { - if (roff_regget(m->roff, REG_nS)) - m->flags |= MDOC_SYNOPSIS; + if (roff_regisset(mdoc->roff, REG_nS)) { + if (roff_regget(mdoc->roff, REG_nS)) + mdoc->flags |= MDOC_SYNOPSIS; else - m->flags &= ~MDOC_SYNOPSIS; + mdoc->flags &= ~MDOC_SYNOPSIS; } - return(mandoc_getcontrol(buf, &offs) ? - mdoc_pmacro(m, ln, buf, offs) : - mdoc_ptext(m, ln, buf, offs)); + return(roff_getcontrol(mdoc->roff, buf, &offs) ? + mdoc_pmacro(mdoc, ln, buf, offs) : + mdoc_ptext(mdoc, ln, buf, offs)); } int @@ -314,31 +315,31 @@ mdoc_macro(MACRO_PROT_ARGS) /* If we're in the body, deny prologue calls. */ if (MDOC_PROLOGUE & mdoc_macros[tok].flags && - MDOC_PBODY & m->flags) { - mdoc_pmsg(m, line, ppos, MANDOCERR_BADBODY); + MDOC_PBODY & mdoc->flags) { + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADBODY); return(1); } /* If we're in the prologue, deny "body" macros. */ if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && - ! (MDOC_PBODY & m->flags)) { - mdoc_pmsg(m, line, ppos, MANDOCERR_BADPROLOG); - if (NULL == m->meta.msec) - m->meta.msec = mandoc_strdup("1"); - if (NULL == m->meta.title) - m->meta.title = mandoc_strdup("UNKNOWN"); - if (NULL == m->meta.vol) - m->meta.vol = mandoc_strdup("LOCAL"); - if (NULL == m->meta.os) - m->meta.os = mandoc_strdup("LOCAL"); - if (NULL == m->meta.date) - m->meta.date = mandoc_normdate - (m->parse, NULL, line, ppos); - m->flags |= MDOC_PBODY; + ! (MDOC_PBODY & mdoc->flags)) { + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADPROLOG); + if (NULL == mdoc->meta.msec) + mdoc->meta.msec = mandoc_strdup("1"); + if (NULL == mdoc->meta.title) + mdoc->meta.title = mandoc_strdup("UNKNOWN"); + if (NULL == mdoc->meta.vol) + mdoc->meta.vol = mandoc_strdup("LOCAL"); + if (NULL == mdoc->meta.os) + mdoc->meta.os = mandoc_strdup("LOCAL"); + if (NULL == mdoc->meta.date) + mdoc->meta.date = mandoc_normdate + (mdoc->parse, NULL, line, ppos); + mdoc->flags |= MDOC_PBODY; } - return((*mdoc_macros[tok].fp)(m, tok, line, ppos, pos, buf)); + return((*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf)); } @@ -374,6 +375,8 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p) switch (p->type) { case (MDOC_BODY): + if (ENDBODY_NOT != p->end) + break; /* FALLTHROUGH */ case (MDOC_TAIL): /* FALLTHROUGH */ @@ -424,13 +427,13 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p) static struct mdoc_node * -node_alloc(struct mdoc *m, int line, int pos, +node_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok, enum mdoc_type type) { struct mdoc_node *p; p = mandoc_calloc(1, sizeof(struct mdoc_node)); - p->sec = m->lastsec; + p->sec = mdoc->lastsec; p->line = line; p->pos = pos; p->tok = tok; @@ -438,83 +441,84 @@ node_alloc(struct mdoc *m, int line, int pos, /* Flag analysis. */ - if (MDOC_SYNOPSIS & m->flags) + if (MDOC_SYNOPSIS & mdoc->flags) p->flags |= MDOC_SYNPRETTY; else p->flags &= ~MDOC_SYNPRETTY; - if (MDOC_NEWLINE & m->flags) + if (MDOC_NEWLINE & mdoc->flags) p->flags |= MDOC_LINE; - m->flags &= ~MDOC_NEWLINE; + mdoc->flags &= ~MDOC_NEWLINE; return(p); } int -mdoc_tail_alloc(struct mdoc *m, int line, int pos, enum mdoct tok) +mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok) { struct mdoc_node *p; - p = node_alloc(m, line, pos, tok, MDOC_TAIL); - if ( ! node_append(m, p)) + p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL); + if ( ! node_append(mdoc, p)) return(0); - m->next = MDOC_NEXT_CHILD; + mdoc->next = MDOC_NEXT_CHILD; return(1); } int -mdoc_head_alloc(struct mdoc *m, int line, int pos, enum mdoct tok) +mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok) { struct mdoc_node *p; - assert(m->first); - assert(m->last); + assert(mdoc->first); + assert(mdoc->last); - p = node_alloc(m, line, pos, tok, MDOC_HEAD); - if ( ! node_append(m, p)) + p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD); + if ( ! node_append(mdoc, p)) return(0); - m->next = MDOC_NEXT_CHILD; + mdoc->next = MDOC_NEXT_CHILD; return(1); } int -mdoc_body_alloc(struct mdoc *m, int line, int pos, enum mdoct tok) +mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok) { struct mdoc_node *p; - p = node_alloc(m, line, pos, tok, MDOC_BODY); - if ( ! node_append(m, p)) + p = node_alloc(mdoc, line, pos, tok, MDOC_BODY); + if ( ! node_append(mdoc, p)) return(0); - m->next = MDOC_NEXT_CHILD; + mdoc->next = MDOC_NEXT_CHILD; return(1); } int -mdoc_endbody_alloc(struct mdoc *m, int line, int pos, enum mdoct tok, +mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok, struct mdoc_node *body, enum mdoc_endbody end) { struct mdoc_node *p; - p = node_alloc(m, line, pos, tok, MDOC_BODY); + p = node_alloc(mdoc, line, pos, tok, MDOC_BODY); p->pending = body; + p->norm = body->norm; p->end = end; - if ( ! node_append(m, p)) + if ( ! node_append(mdoc, p)) return(0); - m->next = MDOC_NEXT_SIBLING; + mdoc->next = MDOC_NEXT_SIBLING; return(1); } int -mdoc_block_alloc(struct mdoc *m, int line, int pos, +mdoc_block_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok, struct mdoc_arg *args) { struct mdoc_node *p; - p = node_alloc(m, line, pos, tok, MDOC_BLOCK); + p = node_alloc(mdoc, line, pos, tok, MDOC_BLOCK); p->args = args; if (p->args) (args->refcnt)++; @@ -533,20 +537,20 @@ mdoc_block_alloc(struct mdoc *m, int line, int pos, break; } - if ( ! node_append(m, p)) + if ( ! node_append(mdoc, p)) return(0); - m->next = MDOC_NEXT_CHILD; + mdoc->next = MDOC_NEXT_CHILD; return(1); } int -mdoc_elem_alloc(struct mdoc *m, int line, int pos, +mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok, struct mdoc_arg *args) { struct mdoc_node *p; - p = node_alloc(m, line, pos, tok, MDOC_ELEM); + p = node_alloc(mdoc, line, pos, tok, MDOC_ELEM); p->args = args; if (p->args) (args->refcnt)++; @@ -559,24 +563,24 @@ mdoc_elem_alloc(struct mdoc *m, int line, int pos, break; } - if ( ! node_append(m, p)) + if ( ! node_append(mdoc, p)) return(0); - m->next = MDOC_NEXT_CHILD; + mdoc->next = MDOC_NEXT_CHILD; return(1); } int -mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p) +mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p) { struct mdoc_node *n; - n = node_alloc(m, line, pos, MDOC_MAX, MDOC_TEXT); - n->string = roff_strdup(m->roff, p); + n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT); + n->string = roff_strdup(mdoc->roff, p); - if ( ! node_append(m, n)) + if ( ! node_append(mdoc, n)) return(0); - m->next = MDOC_NEXT_SIBLING; + mdoc->next = MDOC_NEXT_SIBLING; return(1); } @@ -596,7 +600,7 @@ mdoc_node_free(struct mdoc_node *p) static void -mdoc_node_unlink(struct mdoc *m, struct mdoc_node *n) +mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n) { /* Adjust siblings. */ @@ -618,35 +622,43 @@ mdoc_node_unlink(struct mdoc *m, struct mdoc_node *n) /* Adjust parse point, if applicable. */ - if (m && m->last == n) { + if (mdoc && mdoc->last == n) { if (n->prev) { - m->last = n->prev; - m->next = MDOC_NEXT_SIBLING; + mdoc->last = n->prev; + mdoc->next = MDOC_NEXT_SIBLING; } else { - m->last = n->parent; - m->next = MDOC_NEXT_CHILD; + mdoc->last = n->parent; + mdoc->next = MDOC_NEXT_CHILD; } } - if (m && m->first == n) - m->first = NULL; + if (mdoc && mdoc->first == n) + mdoc->first = NULL; } void -mdoc_node_delete(struct mdoc *m, struct mdoc_node *p) +mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p) { while (p->child) { assert(p->nchild); - mdoc_node_delete(m, p->child); + mdoc_node_delete(mdoc, p->child); } assert(0 == p->nchild); - mdoc_node_unlink(m, p); + mdoc_node_unlink(mdoc, p); mdoc_node_free(p); } +int +mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p) +{ + + mdoc_node_unlink(mdoc, p); + return(node_append(mdoc, p)); +} + #if 0 /* * Pre-treat a text line. @@ -658,7 +670,7 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p) * 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) +mdoc_preptext(struct mdoc *mdoc, int line, char *buf, int offs) { char *start, *end; char delim; @@ -666,12 +678,12 @@ mdoc_preptext(struct mdoc *m, int line, char *buf, int offs) while ('\0' != buf[offs]) { /* Mark starting position if eqn is set. */ start = NULL; - if ('\0' != (delim = roff_eqndelim(m->roff))) + if ('\0' != (delim = roff_eqndelim(mdoc->roff))) if (NULL != (start = strchr(buf + offs, delim))) *start++ = '\0'; /* Parse text as normal. */ - if ( ! mdoc_ptext(m, line, buf, offs)) + if ( ! mdoc_ptext(mdoc, line, buf, offs)) return(0); /* Continue only if an equation exists. */ @@ -688,11 +700,11 @@ mdoc_preptext(struct mdoc *m, int line, char *buf, int offs) } /* Parse the equation itself. */ - roff_openeqn(m->roff, NULL, line, offs, buf); + roff_openeqn(mdoc->roff, NULL, line, offs, buf); /* Process a finished equation? */ - if (roff_closeeqn(m->roff)) - if ( ! mdoc_addeqn(m, roff_eqn(m->roff))) + if (roff_closeeqn(mdoc->roff)) + if ( ! mdoc_addeqn(mdoc, roff_eqn(mdoc->roff))) return(0); offs += (end - (buf + offs)); } @@ -706,20 +718,20 @@ mdoc_preptext(struct mdoc *m, int line, char *buf, int offs) * control character. */ static int -mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) +mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs) { char *c, *ws, *end; struct mdoc_node *n; /* No text before an initial macro. */ - if (SEC_NONE == m->lastnamed) { - mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT); + if (SEC_NONE == mdoc->lastnamed) { + mdoc_pmsg(mdoc, line, offs, MANDOCERR_NOTEXT); return(1); } - assert(m->last); - n = m->last; + assert(mdoc->last); + n = mdoc->last; /* * Divert directly to list processing if we're encountering a @@ -731,8 +743,8 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) if (MDOC_Bl == n->tok && MDOC_BODY == n->type && LIST_column == n->norm->Bl.type) { /* `Bl' is open without any children. */ - m->flags |= MDOC_FREECOL; - return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf)); + mdoc->flags |= MDOC_FREECOL; + return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf)); } if (MDOC_It == n->tok && MDOC_BLOCK == n->type && @@ -740,8 +752,8 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) MDOC_Bl == n->parent->tok && LIST_column == n->parent->norm->Bl.type) { /* `Bl' has block-level `It' children. */ - m->flags |= MDOC_FREECOL; - return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf)); + mdoc->flags |= MDOC_FREECOL; + return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf)); } /* @@ -769,7 +781,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) * Strip trailing tabs in literal context only; * outside, they affect the next line. */ - if (MDOC_LITERAL & m->flags) + if (MDOC_LITERAL & mdoc->flags) continue; break; case '\\': @@ -786,27 +798,28 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) *end = '\0'; if (ws) - mdoc_pmsg(m, line, (int)(ws-buf), MANDOCERR_EOLNSPACE); + mdoc_pmsg(mdoc, line, (int)(ws-buf), MANDOCERR_EOLNSPACE); - if ('\0' == buf[offs] && ! (MDOC_LITERAL & m->flags)) { - mdoc_pmsg(m, line, (int)(c-buf), MANDOCERR_NOBLANKLN); + if ('\0' == buf[offs] && ! (MDOC_LITERAL & mdoc->flags)) { + mdoc_pmsg(mdoc, line, (int)(c-buf), MANDOCERR_NOBLANKLN); /* * Insert a `sp' in the case of a blank line. Technically, * blank lines aren't allowed, but enough manuals assume this * behaviour that we want to work around it. */ - if ( ! mdoc_elem_alloc(m, line, offs, MDOC_sp, NULL)) + if ( ! mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL)) return(0); - m->next = MDOC_NEXT_SIBLING; - return(1); + mdoc->next = MDOC_NEXT_SIBLING; + + return(mdoc_valid_post(mdoc)); } - if ( ! mdoc_word_alloc(m, line, offs, buf+offs)) + if ( ! mdoc_word_alloc(mdoc, line, offs, buf+offs)) return(0); - if (MDOC_LITERAL & m->flags) + if (MDOC_LITERAL & mdoc->flags) return(1); /* @@ -818,7 +831,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) assert(buf < end); if (mandoc_eos(buf+offs, (size_t)(end-buf-offs), 0)) - m->last->flags |= MDOC_EOS; + mdoc->last->flags |= MDOC_EOS; return(1); } @@ -829,7 +842,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) * character. */ static int -mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) +mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) { enum mdoct tok; int i, sv; @@ -839,7 +852,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) /* Empty post-control lines are ignored. */ if ('"' == buf[offs]) { - mdoc_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT); + mdoc_pmsg(mdoc, ln, offs, MANDOCERR_BADCOMMENT); return(1); } else if ('\0' == buf[offs]) return(1); @@ -861,7 +874,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) tok = (i > 1 || i < 4) ? mdoc_hash_find(mac) : MDOC_MAX; if (MDOC_MAX == tok) { - mandoc_vmsg(MANDOCERR_MACRO, m->parse, + mandoc_vmsg(MANDOCERR_MACRO, mdoc->parse, ln, sv, "%s", buf + sv - 1); return(1); } @@ -882,21 +895,21 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) */ if ('\0' == buf[offs] && ' ' == buf[offs - 1]) - mdoc_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE); + mdoc_pmsg(mdoc, ln, offs - 1, MANDOCERR_EOLNSPACE); /* * If an initial macro or a list invocation, divert directly * into macro processing. */ - if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) { - if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) + if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) { + if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf)) goto err; return(1); } - n = m->last; - assert(m->last); + n = mdoc->last; + assert(mdoc->last); /* * If the first macro of a `Bl -column', open an `It' block @@ -905,8 +918,8 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) if (MDOC_Bl == n->tok && MDOC_BODY == n->type && LIST_column == n->norm->Bl.type) { - m->flags |= MDOC_FREECOL; - if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf)) + mdoc->flags |= MDOC_FREECOL; + if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf)) goto err; return(1); } @@ -921,22 +934,22 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) NULL != n->parent && MDOC_Bl == n->parent->tok && LIST_column == n->parent->norm->Bl.type) { - m->flags |= MDOC_FREECOL; - if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf)) + mdoc->flags |= MDOC_FREECOL; + if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf)) goto err; return(1); } /* Normal processing of a macro. */ - if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) + if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf)) goto err; return(1); err: /* Error out. */ - m->flags |= MDOC_HALT; + mdoc->flags |= MDOC_HALT; return(0); } @@ -980,7 +993,7 @@ mdoc_isdelim(const char *p) if (0 == strcmp(p + 1, ".")) return(DELIM_CLOSE); - if (0 == strcmp(p + 1, "*(Ba")) + if (0 == strcmp(p + 1, "fR|\\fP")) return(DELIM_MIDDLE); return(DELIM_NONE); diff --git a/contrib/mdocml/mdoc.h b/contrib/mdocml/mdoc.h index 9cee098e7f..cc807d778e 100644 --- a/contrib/mdocml/mdoc.h +++ b/contrib/mdocml/mdoc.h @@ -1,4 +1,4 @@ -/* $Id: mdoc.h,v 1.122 2011/03/22 14:05:45 kristaps Exp $ */ +/* $Id: mdoc.h,v 1.124 2012/11/16 17:16:55 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -311,6 +311,7 @@ struct mdoc_bl { int comp; /* -compact */ size_t ncols; /* -column arg count */ const char **cols; /* -column val ptr */ + int count; /* -enum counter */ }; struct mdoc_bf { @@ -362,6 +363,7 @@ struct mdoc_node { enum mdoc_type type; /* AST node type */ enum mdoc_sec sec; /* current named section */ union mdoc_data *norm; /* normalised args */ + const void *prev_font; /* before entering this node */ /* FIXME: these can be union'd to shave a few bytes. */ struct mdoc_arg *args; /* BLOCK/ELEM */ struct mdoc_node *pending; /* BLOCK */ diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mdocml/mdoc_argv.c index 08386e09b1..220260a6f0 100644 --- a/contrib/mdocml/mdoc_argv.c +++ b/contrib/mdocml/mdoc_argv.c @@ -1,6 +1,7 @@ -/* $Id: mdoc_argv.c,v 1.82 2012/03/23 05:50:24 kristaps Exp $ */ +/* $Id: mdoc_argv.c,v 1.86 2012/11/18 00:05:35 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2012 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 @@ -42,8 +43,7 @@ enum argsflag { 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]) */ + ARGV_MULTI /* multiple args (e.g., -column xxx yyy) */ }; struct mdocarg { @@ -57,8 +57,6 @@ static enum margserr args(struct mdoc *, int, int *, 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_single(struct mdoc *, int, struct mdoc_argv *, int *, char *); @@ -69,7 +67,7 @@ static const enum argvflag argvflags[MDOC_ARG_MAX] = { ARGV_NONE, /* MDOC_Unfilled */ ARGV_NONE, /* MDOC_Literal */ ARGV_SINGLE, /* MDOC_File */ - ARGV_OPT_SINGLE, /* MDOC_Offset */ + ARGV_SINGLE, /* MDOC_Offset */ ARGV_NONE, /* MDOC_Bullet */ ARGV_NONE, /* MDOC_Dash */ ARGV_NONE, /* MDOC_Hyphen */ @@ -81,7 +79,7 @@ static const enum argvflag argvflags[MDOC_ARG_MAX] = { ARGV_NONE, /* MDOC_Ohang */ ARGV_NONE, /* MDOC_Inset */ ARGV_MULTI, /* MDOC_Column */ - ARGV_OPT_SINGLE, /* MDOC_Width */ + ARGV_SINGLE, /* MDOC_Width */ ARGV_NONE, /* MDOC_Compact */ ARGV_NONE, /* MDOC_Std */ ARGV_NONE, /* MDOC_Filled */ @@ -146,7 +144,7 @@ static const enum mdocargt args_Bl[] = { }; static const struct mdocarg mdocargs[MDOC_MAX] = { - { ARGSFL_NONE, NULL }, /* Ap */ + { ARGSFL_DELIM, NULL }, /* Ap */ { ARGSFL_NONE, NULL }, /* Dd */ { ARGSFL_NONE, NULL }, /* Dt */ { ARGSFL_NONE, NULL }, /* Os */ @@ -163,7 +161,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = { { ARGSFL_DELIM, NULL }, /* Ad */ { ARGSFL_DELIM, args_An }, /* An */ { ARGSFL_DELIM, NULL }, /* Ar */ - { ARGSFL_NONE, NULL }, /* Cd */ + { ARGSFL_DELIM, NULL }, /* Cd */ { ARGSFL_DELIM, NULL }, /* Cm */ { ARGSFL_DELIM, NULL }, /* Dv */ { ARGSFL_DELIM, NULL }, /* Er */ @@ -175,7 +173,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = { { ARGSFL_DELIM, NULL }, /* Fn */ { ARGSFL_DELIM, NULL }, /* Ft */ { ARGSFL_DELIM, NULL }, /* Ic */ - { ARGSFL_NONE, NULL }, /* In */ + { ARGSFL_DELIM, NULL }, /* In */ { ARGSFL_DELIM, NULL }, /* Li */ { ARGSFL_NONE, NULL }, /* Nd */ { ARGSFL_DELIM, NULL }, /* Nm */ @@ -243,7 +241,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = { { ARGSFL_DELIM, NULL }, /* Xc */ { ARGSFL_NONE, NULL }, /* Xo */ { ARGSFL_NONE, NULL }, /* Fo */ - { ARGSFL_NONE, NULL }, /* Fc */ + { ARGSFL_DELIM, NULL }, /* Fc */ { ARGSFL_NONE, NULL }, /* Oo */ { ARGSFL_DELIM, NULL }, /* Oc */ { ARGSFL_NONE, args_Bk }, /* Bk */ @@ -252,7 +250,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = { { ARGSFL_NONE, NULL }, /* Hf */ { ARGSFL_NONE, NULL }, /* Fr */ { ARGSFL_NONE, NULL }, /* Ud */ - { ARGSFL_NONE, NULL }, /* Lb */ + { ARGSFL_DELIM, NULL }, /* Lb */ { ARGSFL_NONE, NULL }, /* Lp */ { ARGSFL_DELIM, NULL }, /* Lk */ { ARGSFL_DELIM, NULL }, /* Mt */ @@ -277,7 +275,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = { * one mandatory value, an optional single value, or no value. */ enum margverr -mdoc_argv(struct mdoc *m, int line, enum mdoct tok, +mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok, struct mdoc_arg **v, int *pos, char *buf) { char *p, sv; @@ -344,15 +342,11 @@ mdoc_argv(struct mdoc *m, int line, enum mdoct tok, switch (argvflags[tmp.arg]) { case (ARGV_SINGLE): - if ( ! argv_single(m, line, &tmp, pos, buf)) + if ( ! argv_single(mdoc, 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)) + if ( ! argv_multi(mdoc, line, &tmp, pos, buf)) return(ARGV_ERROR); break; case (ARGV_NONE): @@ -413,14 +407,14 @@ argn_free(struct mdoc_arg *p, int iarg) } enum margserr -mdoc_zargs(struct mdoc *m, int line, int *pos, char *buf, char **v) +mdoc_zargs(struct mdoc *mdoc, int line, int *pos, char *buf, char **v) { - return(args(m, line, pos, buf, ARGSFL_NONE, v)); + return(args(mdoc, line, pos, buf, ARGSFL_NONE, v)); } enum margserr -mdoc_args(struct mdoc *m, int line, int *pos, +mdoc_args(struct mdoc *mdoc, int line, int *pos, char *buf, enum mdoct tok, char **v) { enum argsflag fl; @@ -429,7 +423,7 @@ mdoc_args(struct mdoc *m, int line, int *pos, fl = mdocargs[tok].flags; if (MDOC_It != tok) - return(args(m, line, pos, buf, fl, v)); + return(args(mdoc, line, pos, buf, fl, v)); /* * We know that we're in an `It', so it's reasonable to expect @@ -438,35 +432,35 @@ mdoc_args(struct mdoc *m, int line, int *pos, * safe fall-back into the default behaviour. */ - for (n = m->last; n; n = n->parent) + for (n = mdoc->last; n; n = n->parent) if (MDOC_Bl == n->tok) if (LIST_column == n->norm->Bl.type) { fl = ARGSFL_TABSEP; break; } - return(args(m, line, pos, buf, fl, v)); + return(args(mdoc, line, pos, buf, fl, v)); } static enum margserr -args(struct mdoc *m, int line, int *pos, +args(struct mdoc *mdoc, int line, int *pos, char *buf, enum argsflag fl, char **v) { char *p, *pp; enum margserr rc; if ('\0' == buf[*pos]) { - if (MDOC_PPHRASE & m->flags) + if (MDOC_PPHRASE & mdoc->flags) return(ARGS_EOLN); /* * If we're not in a partial phrase and the flag for * being a phrase literal is still set, the punctuation * is unterminated. */ - if (MDOC_PHRASELIT & m->flags) - mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE); + if (MDOC_PHRASELIT & mdoc->flags) + mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE); - m->flags &= ~MDOC_PHRASELIT; + mdoc->flags &= ~MDOC_PHRASELIT; return(ARGS_EOLN); } @@ -489,7 +483,7 @@ args(struct mdoc *m, int line, int *pos, pp = NULL; /* Scan ahead to unescaped `Ta'. */ - if ( ! (MDOC_PHRASELIT & m->flags)) + if ( ! (MDOC_PHRASELIT & mdoc->flags)) for (pp = *v; ; pp++) { if (NULL == (pp = strstr(pp, "Ta"))) break; @@ -523,7 +517,7 @@ args(struct mdoc *m, int line, int *pos, /* Whitespace check for eoln case... */ if ('\0' == *p && ' ' == *(p - 1)) - mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE); + mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE); *pos += (int)(p - *v); @@ -549,12 +543,12 @@ args(struct mdoc *m, int line, int *pos, * Whitespace is NOT involved in literal termination. */ - if (MDOC_PHRASELIT & m->flags || '\"' == buf[*pos]) { - if ( ! (MDOC_PHRASELIT & m->flags)) + if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) { + if ( ! (MDOC_PHRASELIT & mdoc->flags)) *v = &buf[++(*pos)]; - if (MDOC_PPHRASE & m->flags) - m->flags |= MDOC_PHRASELIT; + if (MDOC_PPHRASE & mdoc->flags) + mdoc->flags |= MDOC_PHRASELIT; for ( ; buf[*pos]; (*pos)++) { if ('\"' != buf[*pos]) @@ -565,13 +559,13 @@ args(struct mdoc *m, int line, int *pos, } if ('\0' == buf[*pos]) { - if (MDOC_PPHRASE & m->flags) + if (MDOC_PPHRASE & mdoc->flags) return(ARGS_QWORD); - mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE); + mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE); return(ARGS_QWORD); } - m->flags &= ~MDOC_PHRASELIT; + mdoc->flags &= ~MDOC_PHRASELIT; buf[(*pos)++] = '\0'; if ('\0' == buf[*pos]) @@ -581,13 +575,13 @@ args(struct mdoc *m, int line, int *pos, (*pos)++; if ('\0' == buf[*pos]) - mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE); + mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE); return(ARGS_QWORD); } p = &buf[*pos]; - *v = mandoc_getarg(m->parse, &p, line, pos); + *v = mandoc_getarg(mdoc->parse, &p, line, pos); return(ARGS_WORD); } @@ -643,7 +637,7 @@ args_checkpunct(const char *buf, int i) } static int -argv_multi(struct mdoc *m, int line, +argv_multi(struct mdoc *mdoc, int line, struct mdoc_argv *v, int *pos, char *buf) { enum margserr ac; @@ -652,7 +646,7 @@ argv_multi(struct mdoc *m, int line, for (v->sz = 0; ; v->sz++) { if ('-' == buf[*pos]) break; - ac = args(m, line, pos, buf, ARGSFL_NONE, &p); + ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p); if (ARGS_ERROR == ac) return(0); else if (ARGS_EOLN == ac) @@ -669,16 +663,13 @@ argv_multi(struct mdoc *m, int line, } static int -argv_opt_single(struct mdoc *m, int line, +argv_single(struct mdoc *mdoc, int line, struct mdoc_argv *v, int *pos, char *buf) { enum margserr ac; char *p; - if ('-' == buf[*pos]) - return(1); - - ac = args(m, line, pos, buf, ARGSFL_NONE, &p); + ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p); if (ARGS_ERROR == ac) return(0); if (ARGS_EOLN == ac) @@ -690,27 +681,3 @@ argv_opt_single(struct mdoc *m, int line, return(1); } - -static int -argv_single(struct mdoc *m, int line, - struct mdoc_argv *v, int *pos, char *buf) -{ - int ppos; - enum margserr ac; - char *p; - - ppos = *pos; - - ac = args(m, line, pos, buf, ARGSFL_NONE, &p); - if (ARGS_EOLN == ac) { - mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT); - return(0); - } else if (ARGS_ERROR == ac) - return(0); - - v->sz = 1; - v->value = mandoc_malloc(sizeof(char *)); - v->value[0] = mandoc_strdup(p); - - return(1); -} diff --git a/contrib/mdocml/mdoc_html.c b/contrib/mdocml/mdoc_html.c index 60ea6dc738..ba93749b54 100644 --- a/contrib/mdocml/mdoc_html.c +++ b/contrib/mdocml/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.182 2011/11/03 20:37:00 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.184 2012/11/17 00:26:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -35,7 +35,7 @@ #define INDENT 5 -#define MDOC_ARGS const struct mdoc_meta *m, \ +#define MDOC_ARGS const struct mdoc_meta *meta, \ const struct mdoc_node *n, \ struct html *h @@ -260,10 +260,11 @@ static const char * const lists[LIST_MAX] = { }; void -html_mdoc(void *arg, const struct mdoc *m) +html_mdoc(void *arg, const struct mdoc *mdoc) { - print_mdoc(mdoc_meta(m), mdoc_node(m), (struct html *)arg); + print_mdoc(mdoc_meta(mdoc), mdoc_node(mdoc), + (struct html *)arg); putchar('\n'); } @@ -361,14 +362,14 @@ print_mdoc(MDOC_ARGS) 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_mdoc_head(meta, n, h); 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); - print_mdoc_nodelist(m, n, h); + print_mdoc_nodelist(meta, n, h); print_tagq(h, t); } @@ -380,10 +381,10 @@ print_mdoc_head(MDOC_ARGS) print_gen_head(h); bufinit(h); - bufcat_fmt(h, "%s(%s)", m->title, m->msec); + bufcat_fmt(h, "%s(%s)", meta->title, meta->msec); - if (m->arch) - bufcat_fmt(h, " (%s)", m->arch); + if (meta->arch) + bufcat_fmt(h, " (%s)", meta->arch); print_otag(h, TAG_TITLE, 0, NULL); print_text(h, h->buf); @@ -394,9 +395,9 @@ static void print_mdoc_nodelist(MDOC_ARGS) { - print_mdoc_node(m, n, h); + print_mdoc_node(meta, n, h); if (n->next) - print_mdoc_nodelist(m, n->next, h); + print_mdoc_nodelist(meta, n->next, h); } @@ -411,7 +412,7 @@ print_mdoc_node(MDOC_ARGS) switch (n->type) { case (MDOC_ROOT): - child = mdoc_root_pre(m, n, h); + child = mdoc_root_pre(meta, n, h); break; case (MDOC_TEXT): /* No tables in this mode... */ @@ -454,7 +455,7 @@ print_mdoc_node(MDOC_ARGS) assert(NULL == h->tblt); if (mdocs[n->tok].pre && ENDBODY_NOT == n->end) - child = (*mdocs[n->tok].pre)(m, n, h); + child = (*mdocs[n->tok].pre)(meta, n, h); break; } @@ -471,19 +472,19 @@ print_mdoc_node(MDOC_ARGS) } if (child && n->child) - print_mdoc_nodelist(m, n->child, h); + print_mdoc_nodelist(meta, n->child, h); print_stagq(h, t); switch (n->type) { case (MDOC_ROOT): - mdoc_root_post(m, n, h); + mdoc_root_post(meta, n, h); break; case (MDOC_EQN): break; default: if (mdocs[n->tok].post && ENDBODY_NOT == n->end) - (*mdocs[n->tok].post)(m, n, h); + (*mdocs[n->tok].post)(meta, n, h); break; } } @@ -509,13 +510,13 @@ mdoc_root_post(MDOC_ARGS) PAIR_CLASS_INIT(&tag[0], "foot-date"); print_otag(h, TAG_TD, 1, tag); - print_text(h, m->date); + print_text(h, meta->date); print_stagq(h, tt); PAIR_CLASS_INIT(&tag[0], "foot-os"); PAIR_INIT(&tag[1], ATTR_ALIGN, "right"); print_otag(h, TAG_TD, 2, tag); - print_text(h, m->os); + print_text(h, meta->os); print_tagq(h, t); } @@ -528,15 +529,15 @@ mdoc_root_pre(MDOC_ARGS) struct tag *t, *tt; char b[BUFSIZ], title[BUFSIZ]; - strlcpy(b, m->vol, BUFSIZ); + strlcpy(b, meta->vol, BUFSIZ); - if (m->arch) { + if (meta->arch) { strlcat(b, " (", BUFSIZ); - strlcat(b, m->arch, BUFSIZ); + strlcat(b, meta->arch, BUFSIZ); strlcat(b, ")", BUFSIZ); } - snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec); + snprintf(title, BUFSIZ - 1, "%s(%s)", meta->title, meta->msec); PAIR_SUMMARY_INIT(&tag[0], "Document Header"); PAIR_CLASS_INIT(&tag[1], "head"); @@ -689,13 +690,13 @@ mdoc_nm_pre(MDOC_ARGS) synopsis_pre(h, n); PAIR_CLASS_INIT(&tag, "name"); print_otag(h, TAG_B, 1, &tag); - if (NULL == n->child && m->name) - print_text(h, m->name); + if (NULL == n->child && meta->name) + print_text(h, meta->name); return(1); case (MDOC_HEAD): print_otag(h, TAG_TD, 0, NULL); - if (NULL == n->child && m->name) - print_text(h, m->name); + if (NULL == n->child && meta->name) + print_text(h, meta->name); return(1); case (MDOC_BODY): print_otag(h, TAG_TD, 0, NULL); @@ -712,8 +713,8 @@ mdoc_nm_pre(MDOC_ARGS) if (MDOC_TEXT == n->type) len += html_strlen(n->string); - if (0 == len && m->name) - len = html_strlen(m->name); + if (0 == len && meta->name) + len = html_strlen(meta->name); SCALE_HS_INIT(&su, (double)len); bufinit(h); @@ -981,8 +982,6 @@ 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); @@ -1001,6 +1000,7 @@ mdoc_bl_pre(MDOC_ARGS) */ for (i = 0; i < (int)n->norm->Bl.ncols; i++) { + bufinit(h); a2width(n->norm->Bl.cols[i], &su); if (i < (int)n->norm->Bl.ncols - 1) bufcat_su(h, "width", &su); @@ -1014,6 +1014,7 @@ mdoc_bl_pre(MDOC_ARGS) } 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); @@ -1225,7 +1226,7 @@ mdoc_bd_pre(MDOC_ARGS) h->flags |= HTML_LITERAL; for (nn = n->child; nn; nn = nn->next) { - print_mdoc_node(m, nn, h); + print_mdoc_node(meta, nn, h); /* * If the printed node flushes its own line, then we * needn't do it here as well. This is hacky, but the @@ -2273,7 +2274,7 @@ mdoc_quote_post(MDOC_ARGS) case (MDOC_So): /* FALLTHROUGH */ case (MDOC_Sq): - print_text(h, "\\(aq"); + print_text(h, "\\(cq"); break; default: abort(); diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mdocml/mdoc_macro.c index 11d147399e..0a5048649d 100644 --- a/contrib/mdocml/mdoc_macro.c +++ b/contrib/mdocml/mdoc_macro.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_macro.c,v 1.115 2012/01/05 00:43:51 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.122 2013/09/15 18:26:46 schwarze Exp $ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2010, 2012 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 @@ -203,22 +203,23 @@ const struct mdoc_macro * const mdoc_macros = __mdoc_macros; * are errors. */ int -mdoc_macroend(struct mdoc *m) +mdoc_macroend(struct mdoc *mdoc) { struct mdoc_node *n; /* Scan for open explicit scopes. */ - n = MDOC_VALID & m->last->flags ? m->last->parent : m->last; + n = MDOC_VALID & mdoc->last->flags ? + mdoc->last->parent : mdoc->last; for ( ; n; n = n->parent) if (MDOC_BLOCK == n->type && MDOC_EXPLICIT & mdoc_macros[n->tok].flags) - mdoc_nmsg(m, n, MANDOCERR_SCOPEEXIT); + mdoc_nmsg(mdoc, n, MANDOCERR_SCOPEEXIT); /* Rewind to the first. */ - return(rew_last(m, m->first)); + return(rew_last(mdoc, mdoc->first)); } @@ -263,8 +264,8 @@ rew_last(struct mdoc *mdoc, const struct mdoc_node *to) 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 + * mdoc->last node in the post-validation phase and reset + * it to mdoc->last->parent, causing a step in the closing * out to be lost. */ np = mdoc->last->parent; @@ -460,7 +461,7 @@ rew_elem(struct mdoc *mdoc, enum mdoct tok) */ static int make_pending(struct mdoc_node *broken, enum mdoct tok, - struct mdoc *m, int line, int ppos) + struct mdoc *mdoc, int line, int ppos) { struct mdoc_node *breaker; @@ -515,7 +516,7 @@ make_pending(struct mdoc_node *broken, enum mdoct tok, taker->pending = broken->pending; } broken->pending = breaker; - mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos, + mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos, "%s breaks %s", mdoc_macronames[tok], mdoc_macronames[broken->tok]); return(1); @@ -530,12 +531,12 @@ make_pending(struct mdoc_node *broken, enum mdoct tok, static int -rew_sub(enum mdoc_type t, struct mdoc *m, +rew_sub(enum mdoc_type t, struct mdoc *mdoc, enum mdoct tok, int line, int ppos) { struct mdoc_node *n; - n = m->last; + n = mdoc->last; while (n) { switch (rew_dohalt(tok, t, n)) { case (REWIND_NONE): @@ -543,7 +544,7 @@ rew_sub(enum mdoc_type t, struct mdoc *m, case (REWIND_THIS): break; case (REWIND_FORCE): - mandoc_vmsg(MANDOCERR_SCOPEBROKEN, m->parse, + mandoc_vmsg(MANDOCERR_SCOPEBROKEN, mdoc->parse, line, ppos, "%s breaks %s", mdoc_macronames[tok], mdoc_macronames[n->tok]); @@ -552,19 +553,19 @@ rew_sub(enum mdoc_type t, struct mdoc *m, n = n->parent; continue; case (REWIND_LATER): - if (make_pending(n, tok, m, line, ppos) || + if (make_pending(n, tok, mdoc, line, ppos) || MDOC_BLOCK != t) return(1); /* FALLTHROUGH */ case (REWIND_ERROR): - mdoc_pmsg(m, line, ppos, MANDOCERR_NOSCOPE); + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_NOSCOPE); return(1); } break; } assert(n); - if ( ! rew_last(m, n)) + if ( ! rew_last(mdoc, n)) return(0); /* @@ -572,10 +573,10 @@ rew_sub(enum mdoc_type t, struct mdoc *m, * Now that the current block ends, close the enclosing block, too. */ while (NULL != (n = n->pending)) { - if ( ! rew_last(m, n)) + if ( ! rew_last(mdoc, n)) return(0); if (MDOC_HEAD == n->type && - ! mdoc_body_alloc(m, n->line, n->pos, n->tok)) + ! mdoc_body_alloc(mdoc, n->line, n->pos, n->tok)) return(0); } @@ -587,18 +588,18 @@ rew_sub(enum mdoc_type t, struct mdoc *m, * Punctuation consists of those tokens found in mdoc_isdelim(). */ static int -dword(struct mdoc *m, int line, +dword(struct mdoc *mdoc, 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)) + if ( ! mdoc_word_alloc(mdoc, line, col, p)) return(0); if (DELIM_OPEN == d) - m->last->flags |= MDOC_DELIMO; + mdoc->last->flags |= MDOC_DELIMO; /* * Closing delimiters only suppress the preceding space @@ -610,15 +611,16 @@ dword(struct mdoc *m, int line, * 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; + else if (DELIM_CLOSE == d && mdoc->last->prev && + mdoc->last->prev->tok != MDOC_No && + mdoc->last->parent->tok != MDOC_Fd) + mdoc->last->flags |= MDOC_DELIMC; return(1); } static int -append_delims(struct mdoc *m, int line, int *pos, char *buf) +append_delims(struct mdoc *mdoc, int line, int *pos, char *buf) { int la; enum margserr ac; @@ -629,14 +631,14 @@ append_delims(struct mdoc *m, int line, int *pos, char *buf) for (;;) { la = *pos; - ac = mdoc_zargs(m, line, pos, buf, &p); + ac = mdoc_zargs(mdoc, line, pos, buf, &p); if (ARGS_ERROR == ac) return(0); else if (ARGS_EOLN == ac) break; - dword(m, line, la, p, DELIM_MAX); + dword(mdoc, line, la, p, DELIM_MAX); /* * If we encounter end-of-sentence symbols, then trigger @@ -650,7 +652,7 @@ append_delims(struct mdoc *m, int line, int *pos, char *buf) * example, `. ;' shouldn't propagate the double-space. */ if (mandoc_eos(p, strlen(p), 0)) - m->last->flags |= MDOC_EOS; + mdoc->last->flags |= MDOC_EOS; } return(1); @@ -672,7 +674,7 @@ blk_exp_close(MACRO_PROT_ARGS) enum mdoct atok, ntok; char *p; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; switch (tok) { case (MDOC_Ec): @@ -689,7 +691,7 @@ blk_exp_close(MACRO_PROT_ARGS) */ atok = rew_alt(tok); body = later = NULL; - for (n = m->last; n; n = n->parent) { + for (n = mdoc->last; n; n = n->parent) { if (MDOC_VALID & n->flags) continue; @@ -718,13 +720,13 @@ blk_exp_close(MACRO_PROT_ARGS) * postpone closing out the current block * until the rew_sub() closing out the sub-block. */ - make_pending(later, tok, m, line, ppos); + make_pending(later, tok, mdoc, line, ppos); /* * Mark the place where the formatting - but not * the scope - of the current block ends. */ - if ( ! mdoc_endbody_alloc(m, line, ppos, + if ( ! mdoc_endbody_alloc(mdoc, line, ppos, atok, body, ENDBODY_SPACE)) return(0); break; @@ -738,37 +740,37 @@ blk_exp_close(MACRO_PROT_ARGS) if (later && MDOC_EXPLICIT & mdoc_macros[later->tok].flags) continue; - if (MDOC_CALLABLE & mdoc_macros[n->tok].flags) + if (MDOC_It != n->tok) later = n; } if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { /* FIXME: do this in validate */ if (buf[*pos]) - mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST); + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_ARGSLOST); - if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); - return(rew_sub(MDOC_BLOCK, m, tok, line, ppos)); + return(rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)); } - if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); if (NULL == later && maxargs > 0) - if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok))) + if ( ! mdoc_tail_alloc(mdoc, line, ppos, rew_alt(tok))) return(0); for (flushed = j = 0; ; j++) { lastarg = *pos; if (j == maxargs && ! flushed) { - if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); flushed = 1; } - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_ERROR == ac) return(0); @@ -780,27 +782,30 @@ blk_exp_close(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, lastarg, p, DELIM_MAX)) + if ( ! dword(mdoc, line, lastarg, p, DELIM_MAX)) return(0); continue; } if ( ! flushed) { - if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); flushed = 1; } - if ( ! mdoc_macro(m, ntok, line, lastarg, pos, buf)) + + mdoc->flags &= ~MDOC_NEWLINE; + + if ( ! mdoc_macro(mdoc, ntok, line, lastarg, pos, buf)) return(0); break; } - if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) + if ( ! flushed && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); if ( ! nl) return(1); - return(append_delims(m, line, pos, buf)); + return(append_delims(mdoc, line, pos, buf)); } @@ -815,7 +820,7 @@ in_line(MACRO_PROT_ARGS) struct mdoc_arg *arg; char *p; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; /* * Whether we allow ignored elements (those without content, @@ -843,7 +848,7 @@ in_line(MACRO_PROT_ARGS) for (arg = NULL;; ) { la = *pos; - av = mdoc_argv(m, line, tok, &arg, pos, buf); + av = mdoc_argv(mdoc, line, tok, &arg, pos, buf); if (ARGV_WORD == av) { *pos = la; @@ -860,7 +865,7 @@ in_line(MACRO_PROT_ARGS) for (cnt = scope = 0;; ) { la = *pos; - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_ERROR == ac) return(0); @@ -879,23 +884,25 @@ in_line(MACRO_PROT_ARGS) */ if (MDOC_MAX != ntok) { - if (scope && ! rew_elem(m, tok)) + if (scope && ! rew_elem(mdoc, tok)) return(0); if (nc && 0 == cnt) { - if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) + if ( ! mdoc_elem_alloc(mdoc, line, + ppos, tok, arg)) return(0); - if ( ! rew_last(m, m->last)) + if ( ! rew_last(mdoc, mdoc->last)) return(0); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); - mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY); + mdoc_pmsg(mdoc, line, ppos, + MANDOCERR_MACROEMPTY); } - if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); if ( ! nl) return(1); - return(append_delims(m, line, pos, buf)); + return(append_delims(mdoc, line, pos, buf)); } /* @@ -917,7 +924,8 @@ in_line(MACRO_PROT_ARGS) */ if (0 == cnt && (nc || MDOC_Li == tok) && DELIM_CLOSE == d && ! scope) { - if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) + if ( ! mdoc_elem_alloc(mdoc, line, + ppos, tok, arg)) return(0); if (MDOC_Ar == tok || MDOC_Li == tok || MDOC_Fl == tok) @@ -928,11 +936,11 @@ in_line(MACRO_PROT_ARGS) * Close out our scope, if one is open, before * any punctuation. */ - if (scope && ! rew_elem(m, tok)) + if (scope && ! rew_elem(mdoc, tok)) return(0); scope = 0; } else if ( ! scope) { - if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) + if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) return(0); scope = 1; } @@ -940,7 +948,7 @@ in_line(MACRO_PROT_ARGS) if (DELIM_NONE == d) cnt++; - if ( ! dword(m, line, la, p, d)) + if ( ! dword(mdoc, line, la, p, d)) return(0); /* @@ -949,13 +957,13 @@ in_line(MACRO_PROT_ARGS) * having to parse out spaces. */ if (scope && MDOC_Fl == tok) { - if ( ! rew_elem(m, tok)) + if ( ! rew_elem(mdoc, tok)) return(0); scope = 0; } } - if (scope && ! rew_elem(m, tok)) + if (scope && ! rew_elem(mdoc, tok)) return(0); /* @@ -965,18 +973,18 @@ in_line(MACRO_PROT_ARGS) */ if (nc && 0 == cnt) { - if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) + if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) return(0); - if ( ! rew_last(m, m->last)) + if ( ! rew_last(mdoc, mdoc->last)) return(0); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); - mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY); + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROEMPTY); } if ( ! nl) return(1); - return(append_delims(m, line, pos, buf)); + return(append_delims(mdoc, line, pos, buf)); } @@ -994,14 +1002,14 @@ blk_full(MACRO_PROT_ARGS) enum margverr av; char *p; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; /* Close out prior implicit scope. */ if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) { - if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); - if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); } @@ -1016,7 +1024,7 @@ blk_full(MACRO_PROT_ARGS) for (arg = NULL;; ) { la = *pos; - av = mdoc_argv(m, line, tok, &arg, pos, buf); + av = mdoc_argv(mdoc, line, tok, &arg, pos, buf); if (ARGV_WORD == av) { *pos = la; @@ -1032,7 +1040,7 @@ blk_full(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_block_alloc(m, line, ppos, tok, arg)) + if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, arg)) return(0); head = body = NULL; @@ -1042,8 +1050,8 @@ blk_full(MACRO_PROT_ARGS) * 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; + MDOC_Bl == mdoc->last->parent->tok && + LIST_diag == mdoc->last->parent->norm->Bl.type; /* * The `Nd' macro has all arguments in its body: it's a hybrid @@ -1051,14 +1059,14 @@ blk_full(MACRO_PROT_ARGS) */ if (MDOC_Nd == tok) { - if ( ! mdoc_head_alloc(m, line, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) return(0); - head = m->last; - if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) + head = mdoc->last; + if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - body = m->last; + body = mdoc->last; } ac = ARGS_ERROR; @@ -1067,7 +1075,7 @@ blk_full(MACRO_PROT_ARGS) la = *pos; /* Initialise last-phrase-type with ARGS_PEND. */ lac = ARGS_ERROR == ac ? ARGS_PEND : ac; - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_PUNCT == ac) break; @@ -1085,11 +1093,11 @@ blk_full(MACRO_PROT_ARGS) * reopen our scope if the last parse was a * phrase or partial phrase. */ - if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - body = m->last; + body = mdoc->last; break; } @@ -1104,7 +1112,7 @@ blk_full(MACRO_PROT_ARGS) ARGS_PPHRASE != ac && ARGS_QWORD != ac && DELIM_OPEN == mdoc_isdelim(p)) { - if ( ! dword(m, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) return(0); continue; } @@ -1112,9 +1120,9 @@ blk_full(MACRO_PROT_ARGS) /* Open a head if one hasn't been opened. */ if (NULL == head) { - if ( ! mdoc_head_alloc(m, line, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) return(0); - head = m->last; + head = mdoc->last; } if (ARGS_PHRASE == ac || @@ -1126,14 +1134,14 @@ blk_full(MACRO_PROT_ARGS) */ mtt = body ? MDOC_BODY : MDOC_HEAD; - if ( ! rew_sub(mtt, m, tok, line, ppos)) + if ( ! rew_sub(mtt, mdoc, tok, line, ppos)) return(0); /* Then allocate our body context. */ - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - body = m->last; + body = mdoc->last; /* * Process phrases: set whether we're in a @@ -1142,14 +1150,14 @@ blk_full(MACRO_PROT_ARGS) */ if (ARGS_PPHRASE == ac) - m->flags |= MDOC_PPHRASE; + mdoc->flags |= MDOC_PPHRASE; if (ARGS_PEND == ac && ARGS_PPHRASE == lac) - m->flags |= MDOC_PPHRASE; + mdoc->flags |= MDOC_PPHRASE; - if ( ! phrase(m, line, la, buf)) + if ( ! phrase(mdoc, line, la, buf)) return(0); - m->flags &= ~MDOC_PPHRASE; + mdoc->flags &= ~MDOC_PPHRASE; continue; } @@ -1157,23 +1165,23 @@ blk_full(MACRO_PROT_ARGS) MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); continue; } - if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); break; } if (NULL == head) { - if ( ! mdoc_head_alloc(m, line, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) return(0); - head = m->last; + head = mdoc->last; } - if (nl && ! append_delims(m, line, pos, buf)) + if (nl && ! append_delims(mdoc, line, pos, buf)) return(0); /* If we've already opened our body, exit now. */ @@ -1187,7 +1195,7 @@ blk_full(MACRO_PROT_ARGS) * head to body until the rew_sub() call closing out that * sub-block. */ - for (n = m->last; n && n != head; n = n->parent) { + for (n = mdoc->last; n && n != head; n = n->parent) { if (MDOC_BLOCK == n->type && MDOC_EXPLICIT & mdoc_macros[n->tok].flags && ! (MDOC_VALID & n->flags)) { @@ -1198,21 +1206,21 @@ blk_full(MACRO_PROT_ARGS) /* Close out scopes to remain in a consistent state. */ - if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); out: - if ( ! (MDOC_FREECOL & m->flags)) + if ( ! (MDOC_FREECOL & mdoc->flags)) return(1); - if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); - if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); - m->flags &= ~MDOC_FREECOL; + mdoc->flags &= ~MDOC_FREECOL; return(1); } @@ -1228,7 +1236,7 @@ blk_part_imp(MACRO_PROT_ARGS) struct mdoc_node *body; /* saved body context */ struct mdoc_node *n; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; /* * A macro that spans to the end of the line. This is generally @@ -1239,14 +1247,14 @@ blk_part_imp(MACRO_PROT_ARGS) * or more closing punctuation nodes. */ - if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) + if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL)) return(0); - blk = m->last; + blk = mdoc->last; - if ( ! mdoc_head_alloc(m, line, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) return(0); - if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos)) return(0); /* @@ -1257,7 +1265,7 @@ blk_part_imp(MACRO_PROT_ARGS) for (body = NULL; ; ) { la = *pos; - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_ERROR == ac) return(0); @@ -1268,26 +1276,26 @@ blk_part_imp(MACRO_PROT_ARGS) if (NULL == body && ARGS_QWORD != ac && DELIM_OPEN == mdoc_isdelim(p)) { - if ( ! dword(m, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) return(0); continue; } if (NULL == body) { - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - body = m->last; + body = mdoc->last; } ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); continue; } - if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); break; } @@ -1295,9 +1303,9 @@ blk_part_imp(MACRO_PROT_ARGS) /* Clean-ups to leave in a consistent state. */ if (NULL == body) { - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - body = m->last; + body = mdoc->last; } for (n = body->child; n && n->next; n = n->next) @@ -1324,12 +1332,13 @@ blk_part_imp(MACRO_PROT_ARGS) * postpone closing out the current block * until the rew_sub() call closing out the sub-block. */ - for (n = m->last; n && n != body && n != blk->parent; n = n->parent) { + for (n = mdoc->last; n && n != body && n != blk->parent; + n = n->parent) { if (MDOC_BLOCK == n->type && MDOC_EXPLICIT & mdoc_macros[n->tok].flags && ! (MDOC_VALID & n->flags)) { - make_pending(n, tok, m, line, ppos); - if ( ! mdoc_endbody_alloc(m, line, ppos, + make_pending(n, tok, mdoc, line, ppos); + if ( ! mdoc_endbody_alloc(mdoc, line, ppos, tok, body, ENDBODY_NOSPACE)) return(0); return(1); @@ -1343,22 +1352,29 @@ blk_part_imp(MACRO_PROT_ARGS) * crufty use of `Op' breakage. */ if (n != body) - mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos, + mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos, "%s broken", mdoc_macronames[tok]); - if (n && ! rew_sub(MDOC_BODY, m, tok, line, ppos)) + if (n && ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); /* Standard appending of delimiters. */ - if (nl && ! append_delims(m, line, pos, buf)) + if (nl && ! append_delims(mdoc, line, pos, buf)) return(0); /* Rewind scope, if applicable. */ - if (n && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) + if (n && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); + /* Move trailing .Ns out of scope. */ + + for (n = body->child; n && n->next; n = n->next) + /* Do nothing. */ ; + if (n && MDOC_Ns == n->tok) + mdoc_node_relink(mdoc, n); + return(1); } @@ -1373,7 +1389,7 @@ blk_part_exp(MACRO_PROT_ARGS) char *p; enum mdoct ntok; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; /* * The opening of an explicit macro having zero or more leading @@ -1381,12 +1397,12 @@ blk_part_exp(MACRO_PROT_ARGS) * case of `Eo'); and a body that may be empty. */ - if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) + if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL)) return(0); for (head = body = NULL; ; ) { la = *pos; - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_ERROR == ac) return(0); @@ -1400,16 +1416,16 @@ blk_part_exp(MACRO_PROT_ARGS) if (NULL == head && ARGS_QWORD != ac && DELIM_OPEN == mdoc_isdelim(p)) { assert(NULL == body); - if ( ! dword(m, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) return(0); continue; } if (NULL == head) { assert(NULL == body); - if ( ! mdoc_head_alloc(m, line, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) return(0); - head = m->last; + head = mdoc->last; } /* @@ -1421,14 +1437,14 @@ blk_part_exp(MACRO_PROT_ARGS) assert(head); /* No check whether it's a macro! */ if (MDOC_Eo == tok) - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); - if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - body = m->last; + body = mdoc->last; if (MDOC_Eo == tok) continue; @@ -1439,12 +1455,12 @@ blk_part_exp(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); continue; } - if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); break; } @@ -1452,13 +1468,13 @@ blk_part_exp(MACRO_PROT_ARGS) /* Clean-up to leave in a consistent state. */ if (NULL == head) - if ( ! mdoc_head_alloc(m, line, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) return(0); if (NULL == body) { - if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(m, line, ppos, tok)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); } @@ -1466,7 +1482,7 @@ blk_part_exp(MACRO_PROT_ARGS) if ( ! nl) return(1); - return(append_delims(m, line, pos, buf)); + return(append_delims(mdoc, line, pos, buf)); } @@ -1481,7 +1497,7 @@ in_line_argn(MACRO_PROT_ARGS) char *p; enum mdoct ntok; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; /* * A line macro that has a fixed number of arguments (maxargs). @@ -1513,7 +1529,7 @@ in_line_argn(MACRO_PROT_ARGS) for (arg = NULL; ; ) { la = *pos; - av = mdoc_argv(m, line, tok, &arg, pos, buf); + av = mdoc_argv(mdoc, line, tok, &arg, pos, buf); if (ARGV_WORD == av) { *pos = la; @@ -1531,7 +1547,7 @@ in_line_argn(MACRO_PROT_ARGS) for (flushed = j = 0; ; ) { la = *pos; - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_ERROR == ac) return(0); @@ -1543,15 +1559,15 @@ in_line_argn(MACRO_PROT_ARGS) if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && ARGS_QWORD != ac && 0 == j && DELIM_OPEN == mdoc_isdelim(p)) { - if ( ! dword(m, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) return(0); continue; } else if (0 == j) - if ( ! mdoc_elem_alloc(m, line, la, tok, arg)) + if ( ! mdoc_elem_alloc(mdoc, line, la, tok, arg)) return(0); if (j == maxargs && ! flushed) { - if ( ! rew_elem(m, tok)) + if ( ! rew_elem(mdoc, tok)) return(0); flushed = 1; } @@ -1559,10 +1575,10 @@ in_line_argn(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX != ntok) { - if ( ! flushed && ! rew_elem(m, tok)) + if ( ! flushed && ! rew_elem(mdoc, tok)) return(0); flushed = 1; - if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); j++; break; @@ -1572,26 +1588,26 @@ in_line_argn(MACRO_PROT_ARGS) ARGS_QWORD != ac && ! flushed && DELIM_NONE != mdoc_isdelim(p)) { - if ( ! rew_elem(m, tok)) + if ( ! rew_elem(mdoc, tok)) return(0); flushed = 1; } - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); j++; } - if (0 == j && ! mdoc_elem_alloc(m, line, la, tok, arg)) + if (0 == j && ! mdoc_elem_alloc(mdoc, line, la, tok, arg)) return(0); /* Close out in a consistent state. */ - if ( ! flushed && ! rew_elem(m, tok)) + if ( ! flushed && ! rew_elem(mdoc, tok)) return(0); if ( ! nl) return(1); - return(append_delims(m, line, pos, buf)); + return(append_delims(mdoc, line, pos, buf)); } @@ -1608,13 +1624,13 @@ in_line_eoln(MACRO_PROT_ARGS) assert( ! (MDOC_PARSED & mdoc_macros[tok].flags)); if (tok == MDOC_Pp) - rew_sub(MDOC_BLOCK, m, MDOC_Nm, line, ppos); + rew_sub(MDOC_BLOCK, mdoc, MDOC_Nm, line, ppos); /* Parse macro arguments. */ for (arg = NULL; ; ) { la = *pos; - av = mdoc_argv(m, line, tok, &arg, pos, buf); + av = mdoc_argv(mdoc, line, tok, &arg, pos, buf); if (ARGV_WORD == av) { *pos = la; @@ -1631,14 +1647,14 @@ in_line_eoln(MACRO_PROT_ARGS) /* Open element scope. */ - if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) + if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) return(0); /* Parse argument terms. */ for (;;) { la = *pos; - ac = mdoc_args(m, line, pos, buf, tok, &p); + ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ARGS_ERROR == ac) return(0); @@ -1648,19 +1664,19 @@ in_line_eoln(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); continue; } - if ( ! rew_elem(m, tok)) + if ( ! rew_elem(mdoc, tok)) return(0); - return(mdoc_macro(m, ntok, line, la, pos, buf)); + return(mdoc_macro(mdoc, ntok, line, la, pos, buf)); } /* Close out (no delimiters). */ - return(rew_elem(m, tok)); + return(rew_elem(mdoc, tok)); } @@ -1670,15 +1686,15 @@ ctx_synopsis(MACRO_PROT_ARGS) { int nl; - nl = MDOC_NEWLINE & m->flags; + nl = MDOC_NEWLINE & mdoc->flags; /* If we're not in the SYNOPSIS, go straight to in-line. */ - if ( ! (MDOC_SYNOPSIS & m->flags)) - return(in_line(m, tok, line, ppos, pos, buf)); + if ( ! (MDOC_SYNOPSIS & mdoc->flags)) + return(in_line(mdoc, tok, line, ppos, pos, buf)); /* If we're a nested call, same place. */ if ( ! nl) - return(in_line(m, tok, line, ppos, pos, buf)); + return(in_line(mdoc, tok, line, ppos, pos, buf)); /* * XXX: this will open a block scope; however, if later we end @@ -1686,9 +1702,9 @@ ctx_synopsis(MACRO_PROT_ARGS) * the formatting. Be careful. */ if (MDOC_Nm == tok) - return(blk_full(m, tok, line, ppos, pos, buf)); + return(blk_full(mdoc, tok, line, ppos, pos, buf)); assert(MDOC_Vt == tok); - return(blk_part_imp(m, tok, line, ppos, pos, buf)); + return(blk_part_imp(mdoc, tok, line, ppos, pos, buf)); } @@ -1697,7 +1713,7 @@ static int obsolete(MACRO_PROT_ARGS) { - mdoc_pmsg(m, line, ppos, MANDOCERR_MACROOBS); + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROOBS); return(1); } @@ -1708,7 +1724,7 @@ obsolete(MACRO_PROT_ARGS) * macro is encountered. */ static int -phrase(struct mdoc *m, int line, int ppos, char *buf) +phrase(struct mdoc *mdoc, int line, int ppos, char *buf) { int la, pos; enum margserr ac; @@ -1718,7 +1734,7 @@ phrase(struct mdoc *m, int line, int ppos, char *buf) for (pos = ppos; ; ) { la = pos; - ac = mdoc_zargs(m, line, &pos, buf, &p); + ac = mdoc_zargs(mdoc, line, &pos, buf, &p); if (ARGS_ERROR == ac) return(0); @@ -1728,14 +1744,14 @@ phrase(struct mdoc *m, int line, int ppos, char *buf) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); continue; } - if ( ! mdoc_macro(m, ntok, line, la, &pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, &pos, buf)) return(0); - return(append_delims(m, line, &pos, buf)); + return(append_delims(mdoc, line, &pos, buf)); } return(1); @@ -1746,24 +1762,30 @@ phrase(struct mdoc *m, int line, int ppos, char *buf) static int phrase_ta(MACRO_PROT_ARGS) { + struct mdoc_node *n; int la; enum mdoct ntok; enum margserr ac; char *p; - /* - * FIXME: this is overly restrictive: if the `Ta' is unexpected, - * it should simply error out with ARGSLOST. - */ + /* Make sure we are in a column list or ignore this macro. */ + n = mdoc->last; + while (NULL != n && MDOC_Bl != n->tok) + n = n->parent; + if (NULL == n || LIST_column != n->norm->Bl.type) { + mdoc_pmsg(mdoc, line, ppos, MANDOCERR_STRAYTA); + return(1); + } - if ( ! rew_sub(MDOC_BODY, m, MDOC_It, line, ppos)) + /* Advance to the next column. */ + if ( ! rew_sub(MDOC_BODY, mdoc, MDOC_It, line, ppos)) return(0); - if ( ! mdoc_body_alloc(m, line, ppos, MDOC_It)) + if ( ! mdoc_body_alloc(mdoc, line, ppos, MDOC_It)) return(0); for (;;) { la = *pos; - ac = mdoc_zargs(m, line, pos, buf, &p); + ac = mdoc_zargs(mdoc, line, pos, buf, &p); if (ARGS_ERROR == ac) return(0); @@ -1773,14 +1795,14 @@ phrase_ta(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { - if ( ! dword(m, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX)) return(0); continue; } - if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) + if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); - return(append_delims(m, line, pos, buf)); + return(append_delims(mdoc, line, pos, buf)); } return(1); diff --git a/contrib/mdocml/mdoc_man.c b/contrib/mdocml/mdoc_man.c index 9d7d2ca238..336791dd7a 100644 --- a/contrib/mdocml/mdoc_man.c +++ b/contrib/mdocml/mdoc_man.c @@ -1,6 +1,6 @@ -/* $Id: mdoc_man.c,v 1.9 2011/10/24 21:47:59 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.52 2013/09/15 18:48:31 schwarze Exp $ */ /* - * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,22 +18,18 @@ #include "config.h" #endif +#include <assert.h> #include <stdio.h> #include <string.h> #include "mandoc.h" +#include "out.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 */ -}; +#define DECL_ARGS const struct mdoc_meta *meta, \ + const struct mdoc_node *n struct manact { int (*cond)(DECL_ARGS); /* DON'T run actions */ @@ -45,29 +41,74 @@ struct manact { static int cond_body(DECL_ARGS); static int cond_head(DECL_ARGS); +static void font_push(char); +static void font_pop(void); +static void mid_it(void); +static void post__t(DECL_ARGS); static void post_bd(DECL_ARGS); +static void post_bf(DECL_ARGS); +static void post_bk(DECL_ARGS); +static void post_bl(DECL_ARGS); static void post_dl(DECL_ARGS); static void post_enc(DECL_ARGS); +static void post_eo(DECL_ARGS); +static void post_fa(DECL_ARGS); +static void post_fd(DECL_ARGS); +static void post_fl(DECL_ARGS); +static void post_fn(DECL_ARGS); +static void post_fo(DECL_ARGS); +static void post_font(DECL_ARGS); +static void post_in(DECL_ARGS); +static void post_it(DECL_ARGS); +static void post_lb(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 void post_vt(DECL_ARGS); +static int pre__t(DECL_ARGS); +static int pre_an(DECL_ARGS); static int pre_ap(DECL_ARGS); static int pre_bd(DECL_ARGS); +static int pre_bf(DECL_ARGS); +static int pre_bk(DECL_ARGS); +static int pre_bl(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_em(DECL_ARGS); +static int pre_fa(DECL_ARGS); +static int pre_fd(DECL_ARGS); +static int pre_fl(DECL_ARGS); +static int pre_fn(DECL_ARGS); +static int pre_fo(DECL_ARGS); +static int pre_ft(DECL_ARGS); +static int pre_in(DECL_ARGS); static int pre_it(DECL_ARGS); +static int pre_lk(DECL_ARGS); +static int pre_li(DECL_ARGS); static int pre_nm(DECL_ARGS); +static int pre_no(DECL_ARGS); static int pre_ns(DECL_ARGS); static int pre_pp(DECL_ARGS); +static int pre_rs(DECL_ARGS); +static int pre_sm(DECL_ARGS); static int pre_sp(DECL_ARGS); static int pre_sect(DECL_ARGS); +static int pre_sy(DECL_ARGS); +static void pre_syn(const struct mdoc_node *); +static int pre_vt(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_word(const char *); +static void print_line(const char *, int); +static void print_block(const char *, int); +static void print_offs(const char *); +static void print_width(const char *, + const struct mdoc_node *, size_t); +static void print_count(int *); static void print_node(DECL_ARGS); static const struct manact manacts[MDOC_MAX + 1] = { @@ -82,74 +123,74 @@ static const struct manact manacts[MDOC_MAX + 1] = { { 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 */ + { cond_body, pre_bl, post_bl, 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_it, post_it, NULL, NULL }, /* It */ + { NULL, pre_em, post_font, NULL, NULL }, /* Ad */ + { NULL, pre_an, NULL, NULL, NULL }, /* An */ + { NULL, pre_em, post_font, NULL, NULL }, /* Ar */ + { NULL, pre_sy, post_font, NULL, NULL }, /* Cd */ + { NULL, pre_sy, post_font, NULL, NULL }, /* Cm */ + { NULL, pre_li, post_font, NULL, NULL }, /* Dv */ + { NULL, pre_li, post_font, NULL, NULL }, /* Er */ + { NULL, pre_li, post_font, NULL, NULL }, /* 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 */ + { NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */ + { NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */ + { NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */ + { NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */ + { NULL, pre_ft, post_font, NULL, NULL }, /* Ft */ + { NULL, pre_sy, post_font, NULL, NULL }, /* Ic */ + { NULL, pre_in, post_in, NULL, NULL }, /* In */ + { NULL, pre_li, post_font, NULL, NULL }, /* 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_em, post_font, NULL, NULL }, /* 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_em, post_font, NULL, NULL }, /* Va */ + { NULL, pre_vt, post_vt, 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, post_percent, NULL, NULL }, /* %A */ + { NULL, pre_em, post_percent, NULL, NULL }, /* %B */ + { NULL, NULL, post_percent, NULL, NULL }, /* %D */ + { NULL, pre_em, post_percent, NULL, NULL }, /* %I */ + { NULL, pre_em, post_percent, NULL, NULL }, /* %J */ + { NULL, NULL, post_percent, NULL, NULL }, /* %N */ + { NULL, NULL, post_percent, NULL, NULL }, /* %O */ + { NULL, NULL, post_percent, NULL, NULL }, /* %P */ + { NULL, NULL, post_percent, NULL, NULL }, /* %R */ + { NULL, pre__t, post__t, NULL, NULL }, /* %T */ + { NULL, NULL, post_percent, 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 */ + { NULL, pre_bf, post_bf, 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 */ + { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */ + { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */ + { NULL, NULL, NULL, NULL, NULL }, /* Ec */ + { NULL, NULL, NULL, NULL, NULL }, /* Ef */ + { NULL, pre_em, post_font, NULL, NULL }, /* Em */ + { NULL, NULL, post_eo, 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_sy, post_font, NULL, NULL }, /* Ms */ + { NULL, pre_no, 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 */ @@ -158,82 +199,167 @@ static const struct manact manacts[MDOC_MAX + 1] = { { 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, "\\(oq", "\\(cq" }, /* 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 */ + { cond_body, pre_rs, 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 */ + { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* So */ + { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Sq */ + { NULL, pre_sm, NULL, NULL, NULL }, /* Sm */ + { NULL, pre_em, post_font, NULL, NULL }, /* Sx */ + { NULL, pre_sy, post_font, NULL, NULL }, /* Sy */ + { NULL, pre_li, post_font, NULL, NULL }, /* 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 */ + { NULL, NULL, NULL, NULL, NULL }, /* Xc */ + { NULL, NULL, NULL, NULL, NULL }, /* Xo */ + { NULL, pre_fo, post_fo, 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_bk, post_bk, 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, NULL, post_lb, NULL, NULL }, /* Lb */ { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */ - { NULL, NULL, NULL, NULL, NULL }, /* _Lk */ - { NULL, NULL, NULL, NULL, NULL }, /* _Mt */ + { NULL, pre_lk, NULL, NULL, NULL }, /* Lk */ + { NULL, pre_em, post_font, 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, NULL, post_percent, 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, NULL, post_percent, 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, post_percent, NULL, NULL }, /* %U */ + { NULL, NULL, NULL, NULL, NULL }, /* Ta */ { NULL, NULL, NULL, NULL, NULL }, /* ROOT */ }; +static int outflags; +#define MMAN_spc (1 << 0) /* blank character before next word */ +#define MMAN_spc_force (1 << 1) /* even before trailing punctuation */ +#define MMAN_nl (1 << 2) /* break man(7) code line */ +#define MMAN_br (1 << 3) /* break output line */ +#define MMAN_sp (1 << 4) /* insert a blank output line */ +#define MMAN_PP (1 << 5) /* reset indentation etc. */ +#define MMAN_Sm (1 << 6) /* horizontal spacing mode */ +#define MMAN_Bk (1 << 7) /* word keep mode */ +#define MMAN_Bk_susp (1 << 8) /* suspend this (after a macro) */ +#define MMAN_An_split (1 << 9) /* author mode is "split" */ +#define MMAN_An_nosplit (1 << 10) /* author mode is "nosplit" */ +#define MMAN_PD (1 << 11) /* inter-paragraph spacing disabled */ + +#define BL_STACK_MAX 32 + +static size_t Bl_stack[BL_STACK_MAX]; /* offsets [chars] */ +static int Bl_stack_post[BL_STACK_MAX]; /* add final .RE */ +static int Bl_stack_len; /* number of nested Bl blocks */ +static int TPremain; /* characters before tag is full */ + +static struct { + char *head; + char *tail; + size_t size; +} fontqueue; + +static void +font_push(char newfont) +{ + + if (fontqueue.head + fontqueue.size <= ++fontqueue.tail) { + fontqueue.size += 8; + fontqueue.head = mandoc_realloc(fontqueue.head, + fontqueue.size); + } + *fontqueue.tail = newfont; + print_word(""); + printf("\\f"); + putchar(newfont); + outflags &= ~MMAN_spc; +} + static void -print_word(struct mman *mm, const char *s) +font_pop(void) { - if (mm->need_nl) { + if (fontqueue.tail > fontqueue.head) + fontqueue.tail--; + outflags &= ~MMAN_spc; + print_word(""); + printf("\\f"); + putchar(*fontqueue.tail); +} + +static void +print_word(const char *s) +{ + + if ((MMAN_PP | MMAN_sp | MMAN_br | MMAN_nl) & outflags) { /* * 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 (MMAN_PP & outflags) { + if (MMAN_sp & outflags) { + if (MMAN_PD & outflags) { + printf("\n.PD"); + outflags &= ~MMAN_PD; + } + } else if ( ! (MMAN_PD & outflags)) { + printf("\n.PD 0"); + outflags |= MMAN_PD; + } + printf("\n.PP\n"); + } else if (MMAN_sp & outflags) + printf("\n.sp\n"); + else if (MMAN_br & outflags) + printf("\n.br\n"); + else if (MMAN_nl & outflags) + putchar('\n'); + outflags &= ~(MMAN_PP|MMAN_sp|MMAN_br|MMAN_nl|MMAN_spc); + if (1 == TPremain) + printf(".br\n"); + TPremain = 0; + } else if (MMAN_spc & outflags) { /* - * 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 we need a space, only print it if + * (1) it is forced by `No' or + * (2) what follows is not terminating punctuation or + * (3) what follows is longer than one character. */ - if (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) + if (MMAN_spc_force & outflags || '\0' == s[0] || + NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) { + if (MMAN_Bk & outflags && + ! (MMAN_Bk_susp & outflags)) + putchar('\\'); putchar(' '); + if (TPremain) + TPremain--; + } + } /* * Reassign needing space if we're not following opening * punctuation. */ - mm->need_space = - ('(' != s[0] && '[' != s[0]) || '\0' != s[1]; + if (MMAN_Sm & outflags && ('\0' == s[0] || + (('(' != s[0] && '[' != s[0]) || '\0' != s[1]))) + outflags |= MMAN_spc; + else + outflags &= ~MMAN_spc; + outflags &= ~(MMAN_spc_force | MMAN_Bk_susp); for ( ; *s; s++) { switch (*s) { case (ASCII_NBRSP): - printf("\\~"); + printf("\\ "); break; case (ASCII_HYPH): putchar('-'); @@ -242,7 +368,147 @@ print_word(struct mman *mm, const char *s) putchar((unsigned char)*s); break; } + if (TPremain) + TPremain--; + } +} + +static void +print_line(const char *s, int newflags) +{ + + outflags &= ~MMAN_br; + outflags |= MMAN_nl; + print_word(s); + outflags |= newflags; +} + +static void +print_block(const char *s, int newflags) +{ + + outflags &= ~MMAN_PP; + if (MMAN_sp & outflags) { + outflags &= ~(MMAN_sp | MMAN_br); + if (MMAN_PD & outflags) { + print_line(".PD", 0); + outflags &= ~MMAN_PD; + } + } else if (! (MMAN_PD & outflags)) + print_line(".PD 0", MMAN_PD); + outflags |= MMAN_nl; + print_word(s); + outflags |= MMAN_Bk_susp | newflags; +} + +static void +print_offs(const char *v) +{ + char buf[24]; + struct roffsu su; + size_t sz; + + print_line(".RS", MMAN_Bk_susp); + + /* Convert v into a number (of characters). */ + if (NULL == v || '\0' == *v || 0 == strcmp(v, "left")) + sz = 0; + else if (0 == strcmp(v, "indent")) + sz = 6; + else if (0 == strcmp(v, "indent-two")) + sz = 12; + else if (a2roffsu(v, &su, SCALE_MAX)) { + if (SCALE_EN == su.unit) + sz = su.scale; + else { + /* + * XXX + * If we are inside an enclosing list, + * there is no easy way to add the two + * indentations because they are provided + * in terms of different units. + */ + print_word(v); + outflags |= MMAN_nl; + return; + } + } else + sz = strlen(v); + + /* + * We are inside an enclosing list. + * Add the two indentations. + */ + if (Bl_stack_len) + sz += Bl_stack[Bl_stack_len - 1]; + + snprintf(buf, sizeof(buf), "%ldn", sz); + print_word(buf); + outflags |= MMAN_nl; +} + +/* + * Set up the indentation for a list item; used from pre_it(). + */ +void +print_width(const char *v, const struct mdoc_node *child, size_t defsz) +{ + char buf[24]; + struct roffsu su; + size_t sz, chsz; + int numeric, remain; + + numeric = 1; + remain = 0; + + /* Convert v into a number (of characters). */ + if (NULL == v) + sz = defsz; + else if (a2roffsu(v, &su, SCALE_MAX)) { + if (SCALE_EN == su.unit) + sz = su.scale; + else { + sz = 0; + numeric = 0; + } + } else + sz = strlen(v); + + /* XXX Rough estimation, might have multiple parts. */ + chsz = (NULL != child && MDOC_TEXT == child->type) ? + strlen(child->string) : 0; + + /* Maybe we are inside an enclosing list? */ + mid_it(); + + /* + * Save our own indentation, + * such that child lists can use it. + */ + Bl_stack[Bl_stack_len++] = sz + 2; + + /* Set up the current list. */ + if (defsz && chsz > sz) + print_block(".HP", 0); + else { + print_block(".TP", 0); + remain = sz + 2; } + if (numeric) { + snprintf(buf, sizeof(buf), "%ldn", sz + 2); + print_word(buf); + } else + print_word(v); + TPremain = remain; +} + +void +print_count(int *count) +{ + char buf[12]; + + snprintf(buf, sizeof(buf), "%d.", ++*count); + print_word(buf); } void @@ -261,37 +527,42 @@ man_man(void *arg, const struct man *man) void man_mdoc(void *arg, const struct mdoc *mdoc) { - const struct mdoc_meta *m; + const struct mdoc_meta *meta; const struct mdoc_node *n; - struct mman mm; - m = mdoc_meta(mdoc); + meta = mdoc_meta(mdoc); n = mdoc_node(mdoc); - printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", - m->title, m->msec, m->date, m->os, m->vol); + printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n", + meta->title, meta->msec, meta->date, + meta->os, meta->vol); - memset(&mm, 0, sizeof(struct mman)); + /* Disable hyphenation and if nroff, disable justification. */ + printf(".nh\n.if n .ad l"); - mm.need_nl = 1; - print_node(m, n, &mm); + outflags = MMAN_nl | MMAN_Sm; + if (0 == fontqueue.size) { + fontqueue.size = 8; + fontqueue.head = fontqueue.tail = mandoc_malloc(8); + *fontqueue.tail = 'R'; + } + print_node(meta, n); putchar('\n'); } static void print_node(DECL_ARGS) { - const struct mdoc_node *prev, *sub; + const struct mdoc_node *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; + if (MMAN_spc & outflags && MDOC_LINE & n->flags) + outflags |= MMAN_nl; act = NULL; cond = 0; @@ -302,21 +573,22 @@ print_node(DECL_ARGS) * 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 || + if (MMAN_nl & outflags && ('.' == *n->string || '\'' == *n->string)) { - print_word(mm, "\\&"); - mm->need_space = 0; + print_word(""); + printf("\\&"); + outflags &= ~MMAN_spc; } - print_word(mm, n->string); + print_word(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); + cond = NULL == act->cond || (*act->cond)(meta, n); if (cond && act->pre) - do_sub = (*act->pre)(m, n, mm); + do_sub = (*act->pre)(meta, n); } /* @@ -326,13 +598,13 @@ print_node(DECL_ARGS) */ if (do_sub) for (sub = n->child; sub; sub = sub->next) - print_node(m, sub, mm); + print_node(meta, sub); /* * Lastly, conditionally run the post-node handler. */ if (cond && act->post) - (*act->post)(m, n, mm); + (*act->post)(meta, n); } static int @@ -349,10 +621,6 @@ 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) { @@ -361,14 +629,11 @@ pre_enc(DECL_ARGS) prefix = manacts[n->tok].prefix; if (NULL == prefix) return(1); - print_word(mm, prefix); - mm->need_space = 0; + print_word(prefix); + outflags &= ~MMAN_spc; return(1); } -/* - * Output a font encoding subsequent a node, e.g., \fP. - */ static void post_enc(DECL_ARGS) { @@ -377,28 +642,62 @@ post_enc(DECL_ARGS) suffix = manacts[n->tok].suffix; if (NULL == suffix) return; - mm->need_space = 0; - print_word(mm, suffix); + outflags &= ~MMAN_spc; + print_word(suffix); +} + +static void +post_font(DECL_ARGS) +{ + + font_pop(); } -/* - * 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; + if (pre_em == manacts[n->tok].pre) + font_pop(); + if (n->next) { + print_word(","); + if (n->prev && n->prev->tok == n->tok && + n->next->tok == n->tok) + print_word("and"); + } else { + print_word("."); + outflags |= MMAN_nl; } } +static int +pre__t(DECL_ARGS) +{ + + if (n->parent && MDOC_Rs == n->parent->tok && + n->parent->norm->Rs.quote_T) { + print_word(""); + putchar('\"'); + outflags &= ~MMAN_spc; + } else + font_push('I'); + return(1); +} + +static void +post__t(DECL_ARGS) +{ + + if (n->parent && MDOC_Rs == n->parent->tok && + n->parent->norm->Rs.quote_T) { + outflags &= ~MMAN_spc; + print_word(""); + putchar('\"'); + } else + font_pop(); + post_percent(meta, n); +} + /* * Print before a section header. */ @@ -406,12 +705,25 @@ 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; + switch (n->type) { + case (MDOC_HEAD): + outflags |= MMAN_sp; + print_block(manacts[n->tok].prefix, 0); + print_word(""); + putchar('\"'); + outflags &= ~MMAN_spc; + break; + case (MDOC_BODY): + if (MDOC_Sh == n->tok) { + if (MDOC_SYNPRETTY & n->flags) + outflags |= MMAN_Bk; + else + outflags &= ~MMAN_Bk; + } + break; + default: + break; + } return(1); } @@ -424,18 +736,84 @@ post_sect(DECL_ARGS) if (MDOC_HEAD != n->type) return; - mm->need_space = 0; - print_word(mm, "\""); - mm->need_nl = 1; + outflags &= ~MMAN_spc; + print_word(""); + putchar('\"'); + outflags |= MMAN_nl; + if (MDOC_Sh == n->tok && SEC_AUTHORS == n->sec) + outflags &= ~(MMAN_An_split | MMAN_An_nosplit); +} + +/* See mdoc_term.c, synopsis_pre() for comments. */ +static void +pre_syn(const struct mdoc_node *n) +{ + + if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) + return; + + if (n->prev->tok == n->tok && + MDOC_Ft != n->tok && + MDOC_Fo != n->tok && + MDOC_Fn != n->tok) { + outflags |= MMAN_br; + return; + } + + switch (n->prev->tok) { + case (MDOC_Fd): + /* FALLTHROUGH */ + case (MDOC_Fn): + /* FALLTHROUGH */ + case (MDOC_Fo): + /* FALLTHROUGH */ + case (MDOC_In): + /* FALLTHROUGH */ + case (MDOC_Vt): + outflags |= MMAN_sp; + break; + case (MDOC_Ft): + if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) { + outflags |= MMAN_sp; + break; + } + /* FALLTHROUGH */ + default: + outflags |= MMAN_br; + break; + } +} + +static int +pre_an(DECL_ARGS) +{ + + switch (n->norm->An.auth) { + case (AUTH_split): + outflags &= ~MMAN_An_nosplit; + outflags |= MMAN_An_split; + return(0); + case (AUTH_nosplit): + outflags &= ~MMAN_An_split; + outflags |= MMAN_An_nosplit; + return(0); + default: + if (MMAN_An_split & outflags) + outflags |= MMAN_br; + else if (SEC_AUTHORS == n->sec && + ! (MMAN_An_nosplit & outflags)) + outflags |= MMAN_An_split; + return(1); + } } static int pre_ap(DECL_ARGS) { - mm->need_space = 0; - print_word(mm, "'"); - mm->need_space = 0; + outflags &= ~MMAN_spc; + print_word("'"); + outflags &= ~MMAN_spc; return(0); } @@ -443,12 +821,14 @@ static int pre_bd(DECL_ARGS) { + outflags &= ~(MMAN_PP | MMAN_sp | MMAN_br); + if (DISP_unfilled == n->norm->Bd.type || - DISP_literal == n->norm->Bd.type) { - mm->need_nl = 1; - print_word(mm, ".nf"); - } - mm->need_nl = 1; + DISP_literal == n->norm->Bd.type) + print_line(".nf", 0); + if (0 == n->norm->Bd.comp && NULL != n->parent->prev) + outflags |= MMAN_sp; + print_offs(n->norm->Bd.offs); return(1); } @@ -456,21 +836,143 @@ static void post_bd(DECL_ARGS) { + /* Close out this display. */ + print_line(".RE", MMAN_nl); if (DISP_unfilled == n->norm->Bd.type || - DISP_literal == n->norm->Bd.type) { - mm->need_nl = 1; - print_word(mm, ".fi"); + DISP_literal == n->norm->Bd.type) + print_line(".fi", MMAN_nl); + + /* Maybe we are inside an enclosing list? */ + if (NULL != n->parent->next) + mid_it(); +} + +static int +pre_bf(DECL_ARGS) +{ + + switch (n->type) { + case (MDOC_BLOCK): + return(1); + case (MDOC_BODY): + break; + default: + return(0); + } + switch (n->norm->Bf.font) { + case (FONT_Em): + font_push('I'); + break; + case (FONT_Sy): + font_push('B'); + break; + default: + font_push('R'); + break; + } + return(1); +} + +static void +post_bf(DECL_ARGS) +{ + + if (MDOC_BODY == n->type) + font_pop(); +} + +static int +pre_bk(DECL_ARGS) +{ + + switch (n->type) { + case (MDOC_BLOCK): + return(1); + case (MDOC_BODY): + outflags |= MMAN_Bk; + return(1); + default: + return(0); + } +} + +static void +post_bk(DECL_ARGS) +{ + + if (MDOC_BODY == n->type && ! (MDOC_SYNPRETTY & n->flags)) + outflags &= ~MMAN_Bk; +} + +static int +pre_bl(DECL_ARGS) +{ + size_t icol; + + /* + * print_offs() will increase the -offset to account for + * a possible enclosing .It, but any enclosed .It blocks + * just nest and do not add up their indentation. + */ + if (n->norm->Bl.offs) { + print_offs(n->norm->Bl.offs); + Bl_stack[Bl_stack_len++] = 0; + } + + switch (n->norm->Bl.type) { + case (LIST_enum): + n->norm->Bl.count = 0; + return(1); + case (LIST_column): + break; + default: + return(1); + } + + print_line(".TS", MMAN_nl); + for (icol = 0; icol < n->norm->Bl.ncols; icol++) + print_word("l"); + print_word("."); + outflags |= MMAN_nl; + return(1); +} + +static void +post_bl(DECL_ARGS) +{ + + switch (n->norm->Bl.type) { + case (LIST_column): + print_line(".TE", 0); + break; + case (LIST_enum): + n->norm->Bl.count = 0; + break; + default: + break; + } + + if (n->norm->Bl.offs) { + print_line(".RE", MMAN_nl); + assert(Bl_stack_len); + Bl_stack_len--; + assert(0 == Bl_stack[Bl_stack_len]); + } else { + outflags |= MMAN_PP | MMAN_nl; + outflags &= ~(MMAN_sp | MMAN_br); } - mm->need_nl = 1; + + /* Maybe we are inside an enclosing list? */ + if (NULL != n->parent->next) + mid_it(); + } static int pre_br(DECL_ARGS) { - mm->need_nl = 1; - print_word(mm, ".br"); - mm->need_nl = 1; + outflags |= MMAN_br; return(0); } @@ -480,17 +982,17 @@ pre_bx(DECL_ARGS) n = n->child; if (n) { - print_word(mm, n->string); - mm->need_space = 0; + print_word(n->string); + outflags &= ~MMAN_spc; n = n->next; } - print_word(mm, "BSD"); + print_word("BSD"); if (NULL == n) return(0); - mm->need_space = 0; - print_word(mm, "-"); - mm->need_space = 0; - print_word(mm, n->string); + outflags &= ~MMAN_spc; + print_word("-"); + outflags &= ~MMAN_spc; + print_word(n->string); return(0); } @@ -498,9 +1000,7 @@ static int pre_dl(DECL_ARGS) { - mm->need_nl = 1; - print_word(mm, ".RS 6n"); - mm->need_nl = 1; + print_offs("6n"); return(1); } @@ -508,9 +1008,203 @@ static void post_dl(DECL_ARGS) { - mm->need_nl = 1; - print_word(mm, ".RE"); - mm->need_nl = 1; + print_line(".RE", MMAN_nl); + + /* Maybe we are inside an enclosing list? */ + if (NULL != n->parent->next) + mid_it(); +} + +static int +pre_em(DECL_ARGS) +{ + + font_push('I'); + return(1); +} + +static void +post_eo(DECL_ARGS) +{ + + if (MDOC_HEAD == n->type || MDOC_BODY == n->type) + outflags &= ~MMAN_spc; +} + +static int +pre_fa(DECL_ARGS) +{ + + if (MDOC_Fa == n->tok) + n = n->child; + + while (NULL != n) { + font_push('I'); + print_node(meta, n); + font_pop(); + if (NULL != (n = n->next)) + print_word(","); + } + return(0); +} + +static void +post_fa(DECL_ARGS) +{ + + if (NULL != n->next && MDOC_Fa == n->next->tok) + print_word(","); +} + +static int +pre_fd(DECL_ARGS) +{ + + pre_syn(n); + font_push('B'); + return(1); +} + +static void +post_fd(DECL_ARGS) +{ + + font_pop(); + outflags |= MMAN_br; +} + +static int +pre_fl(DECL_ARGS) +{ + + font_push('B'); + print_word("\\-"); + outflags &= ~MMAN_spc; + return(1); +} + +static void +post_fl(DECL_ARGS) +{ + + font_pop(); + if (0 == n->nchild && NULL != n->next && + n->next->line == n->line) + outflags &= ~MMAN_spc; +} + +static int +pre_fn(DECL_ARGS) +{ + + pre_syn(n); + + n = n->child; + if (NULL == n) + return(0); + + font_push('B'); + print_node(meta, n); + font_pop(); + outflags &= ~MMAN_spc; + print_word("("); + outflags &= ~MMAN_spc; + + n = n->next; + if (NULL != n) + pre_fa(meta, n); + return(0); +} + +static void +post_fn(DECL_ARGS) +{ + + print_word(")"); + if (MDOC_SYNPRETTY & n->flags) { + print_word(";"); + outflags |= MMAN_br; + } +} + +static int +pre_fo(DECL_ARGS) +{ + + switch (n->type) { + case (MDOC_BLOCK): + pre_syn(n); + break; + case (MDOC_HEAD): + font_push('B'); + break; + case (MDOC_BODY): + outflags &= ~MMAN_spc; + print_word("("); + outflags &= ~MMAN_spc; + break; + default: + break; + } + return(1); +} + +static void +post_fo(DECL_ARGS) +{ + + switch (n->type) { + case (MDOC_HEAD): + font_pop(); + break; + case (MDOC_BODY): + post_fn(meta, n); + break; + default: + break; + } +} + +static int +pre_ft(DECL_ARGS) +{ + + pre_syn(n); + font_push('I'); + return(1); +} + +static int +pre_in(DECL_ARGS) +{ + + if (MDOC_SYNPRETTY & n->flags) { + pre_syn(n); + font_push('B'); + print_word("#include <"); + outflags &= ~MMAN_spc; + } else { + print_word("<"); + outflags &= ~MMAN_spc; + font_push('I'); + } + return(1); +} + +static void +post_in(DECL_ARGS) +{ + + if (MDOC_SYNPRETTY & n->flags) { + outflags &= ~MMAN_spc; + print_word(">"); + font_pop(); + outflags |= MMAN_br; + } else { + font_pop(); + outflags &= ~MMAN_spc; + print_word(">"); + } } static int @@ -518,36 +1212,219 @@ 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 (n->type) { + case (MDOC_HEAD): + outflags |= MMAN_PP | MMAN_nl; + bln = n->parent->parent; + if (0 == bln->norm->Bl.comp || + (NULL == n->parent->prev && + NULL == bln->parent->prev)) + outflags |= MMAN_sp; + outflags &= ~MMAN_br; switch (bln->norm->Bl.type) { + case (LIST_item): + return(0); + case (LIST_inset): + /* FALLTHROUGH */ + case (LIST_diag): + /* FALLTHROUGH */ + case (LIST_ohang): + if (bln->norm->Bl.type == LIST_diag) + print_line(".B \"", 0); + else + print_line(".R \"", 0); + outflags &= ~MMAN_spc; + return(1); case (LIST_bullet): - print_word(mm, "4n"); - mm->need_nl = 1; - print_word(mm, "\\fBo\\fP"); + /* FALLTHROUGH */ + case (LIST_dash): + /* FALLTHROUGH */ + case (LIST_hyphen): + print_width(bln->norm->Bl.width, NULL, 0); + TPremain = 0; + outflags |= MMAN_nl; + font_push('B'); + if (LIST_bullet == bln->norm->Bl.type) + print_word("o"); + else + print_word("-"); + font_pop(); + break; + case (LIST_enum): + print_width(bln->norm->Bl.width, NULL, 0); + TPremain = 0; + outflags |= MMAN_nl; + print_count(&bln->norm->Bl.count); + break; + case (LIST_hang): + print_width(bln->norm->Bl.width, n->child, 6); + TPremain = 0; + break; + case (LIST_tag): + print_width(bln->norm->Bl.width, n->child, 0); + putchar('\n'); + outflags &= ~MMAN_spc; + return(1); + default: + return(1); + } + outflags |= MMAN_nl; + default: + break; + } + return(1); +} + +/* + * This function is called after closing out an indented block. + * If we are inside an enclosing list, restore its indentation. + */ +static void +mid_it(void) +{ + char buf[24]; + + /* Nothing to do outside a list. */ + if (0 == Bl_stack_len || 0 == Bl_stack[Bl_stack_len - 1]) + return; + + /* The indentation has already been set up. */ + if (Bl_stack_post[Bl_stack_len - 1]) + return; + + /* Restore the indentation of the enclosing list. */ + print_line(".RS", MMAN_Bk_susp); + snprintf(buf, sizeof(buf), "%ldn", Bl_stack[Bl_stack_len - 1]); + print_word(buf); + + /* Remeber to close out this .RS block later. */ + Bl_stack_post[Bl_stack_len - 1] = 1; +} + +static void +post_it(DECL_ARGS) +{ + const struct mdoc_node *bln; + + bln = n->parent->parent; + + switch (n->type) { + case (MDOC_HEAD): + switch (bln->norm->Bl.type) { + case (LIST_diag): + outflags &= ~MMAN_spc; + print_word("\\ "); + break; + case (LIST_ohang): + outflags |= MMAN_br; + break; + default: + break; + } + break; + case (MDOC_BODY): + switch (bln->norm->Bl.type) { + case (LIST_bullet): + /* FALLTHROUGH */ + case (LIST_dash): + /* FALLTHROUGH */ + case (LIST_hyphen): + /* FALLTHROUGH */ + case (LIST_enum): + /* FALLTHROUGH */ + case (LIST_hang): + /* FALLTHROUGH */ + case (LIST_tag): + assert(Bl_stack_len); + Bl_stack[--Bl_stack_len] = 0; + + /* + * Our indentation had to be restored + * after a child display or child list. + * Close out that indentation block now. + */ + if (Bl_stack_post[Bl_stack_len]) { + print_line(".RE", MMAN_nl); + Bl_stack_post[Bl_stack_len] = 0; + } + break; + case (LIST_column): + if (NULL != n->next) { + putchar('\t'); + outflags &= ~MMAN_spc; + } break; default: - if (bln->norm->Bl.width) - print_word(mm, bln->norm->Bl.width); break; } - mm->need_nl = 1; + break; + default: + break; } +} + +static void +post_lb(DECL_ARGS) +{ + + if (SEC_LIBRARY == n->sec) + outflags |= MMAN_br; +} + +static int +pre_lk(DECL_ARGS) +{ + const struct mdoc_node *link, *descr; + + if (NULL == (link = n->child)) + return(0); + + if (NULL != (descr = link->next)) { + font_push('I'); + while (NULL != descr) { + print_word(descr->string); + descr = descr->next; + } + print_word(":"); + font_pop(); + } + + font_push('B'); + print_word(link->string); + font_pop(); + return(0); +} + +static int +pre_li(DECL_ARGS) +{ + + font_push('R'); return(1); } static int pre_nm(DECL_ARGS) { + char *name; + if (MDOC_BLOCK == n->type) + pre_syn(n); if (MDOC_ELEM != n->type && MDOC_HEAD != n->type) return(1); - print_word(mm, "\\fB"); - mm->need_space = 0; + name = n->child ? n->child->string : meta->name; + if (NULL == name) + return(0); + if (MDOC_HEAD == n->type) { + if (NULL == n->parent->prev) + outflags |= MMAN_sp; + print_block(".HP", 0); + printf(" %ldn", strlen(name) + 1); + outflags |= MMAN_nl; + } + font_push('B'); if (NULL == n->child) - print_word(mm, m->name); + print_word(meta->name); return(1); } @@ -557,15 +1434,22 @@ post_nm(DECL_ARGS) if (MDOC_ELEM != n->type && MDOC_HEAD != n->type) return; - mm->need_space = 0; - print_word(mm, "\\fP"); + font_pop(); +} + +static int +pre_no(DECL_ARGS) +{ + + outflags |= MMAN_spc_force; + return(1); } static int pre_ns(DECL_ARGS) { - mm->need_space = 0; + outflags &= ~MMAN_spc; return(0); } @@ -573,28 +1457,52 @@ static void post_pf(DECL_ARGS) { - mm->need_space = 0; + outflags &= ~MMAN_spc; } 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; + if (MDOC_It != n->parent->tok) + outflags |= MMAN_PP; + outflags |= MMAN_sp | MMAN_nl; + outflags &= ~MMAN_br; + return(0); +} + +static int +pre_rs(DECL_ARGS) +{ + + if (SEC_SEE_ALSO == n->sec) { + outflags |= MMAN_PP | MMAN_sp | MMAN_nl; + outflags &= ~MMAN_br; + } return(1); } +static int +pre_sm(DECL_ARGS) +{ + + assert(n->child && MDOC_TEXT == n->child->type); + if (0 == strcmp("on", n->child->string)) + outflags |= MMAN_Sm | MMAN_spc; + else + outflags &= ~MMAN_Sm; + return(0); +} + static int pre_sp(DECL_ARGS) { - mm->need_nl = 1; - print_word(mm, ".sp"); + if (MMAN_PP & outflags) { + outflags &= ~MMAN_PP; + print_line(".PP", 0); + } else + print_line(".sp", 0); return(1); } @@ -602,7 +1510,43 @@ static void post_sp(DECL_ARGS) { - mm->need_nl = 1; + outflags |= MMAN_nl; +} + +static int +pre_sy(DECL_ARGS) +{ + + font_push('B'); + return(1); +} + +static int +pre_vt(DECL_ARGS) +{ + + if (MDOC_SYNPRETTY & n->flags) { + switch (n->type) { + case (MDOC_BLOCK): + pre_syn(n); + return(1); + case (MDOC_BODY): + break; + default: + return(0); + } + } + font_push('I'); + return(1); +} + +static void +post_vt(DECL_ARGS) +{ + + if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type) + return; + font_pop(); } static int @@ -612,14 +1556,14 @@ pre_xr(DECL_ARGS) n = n->child; if (NULL == n) return(0); - print_node(m, n, mm); + print_node(meta, n); n = n->next; if (NULL == n) return(0); - mm->need_space = 0; - print_word(mm, "("); - print_node(m, n, mm); - print_word(mm, ")"); + outflags &= ~MMAN_spc; + print_word("("); + print_node(meta, n); + print_word(")"); return(0); } @@ -627,11 +1571,11 @@ static int pre_ux(DECL_ARGS) { - print_word(mm, manacts[n->tok].prefix); + print_word(manacts[n->tok].prefix); if (NULL == n->child) return(0); - mm->need_space = 0; - print_word(mm, "\\~"); - mm->need_space = 0; + outflags &= ~MMAN_spc; + print_word("\\ "); + outflags &= ~MMAN_spc; return(1); } diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mdocml/mdoc_term.c index 5333566444..99c595393a 100644 --- a/contrib/mdocml/mdoc_term.c +++ b/contrib/mdocml/mdoc_term.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_term.c,v 1.238 2011/11/13 13:15:14 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.249 2013/06/02 18:16:57 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012 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 @@ -41,8 +41,8 @@ struct termpair { #define DECL_ARGS struct termp *p, \ struct termpair *pair, \ - const struct mdoc_meta *m, \ - const struct mdoc_node *n + const struct mdoc_meta *meta, \ + struct mdoc_node *n struct termact { int (*pre)(DECL_ARGS); @@ -69,7 +69,7 @@ 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_d1_post(DECL_ARGS); +static void termp_fd_post(DECL_ARGS); static void termp_fo_post(DECL_ARGS); static void termp_in_post(DECL_ARGS); static void termp_it_post(DECL_ARGS); @@ -129,8 +129,8 @@ static const struct termact termacts[MDOC_MAX] = { { termp_sh_pre, termp_sh_post }, /* Sh */ { termp_ss_pre, termp_ss_post }, /* Ss */ { termp_sp_pre, NULL }, /* Pp */ - { termp_d1_pre, termp_d1_post }, /* D1 */ - { termp_d1_pre, termp_d1_post }, /* Dl */ + { termp_d1_pre, termp_bl_post }, /* D1 */ + { termp_d1_pre, termp_bl_post }, /* Dl */ { termp_bd_pre, termp_bd_post }, /* Bd */ { NULL, NULL }, /* Ed */ { termp_bl_pre, termp_bl_post }, /* Bl */ @@ -146,7 +146,7 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* Ev */ { termp_ex_pre, NULL }, /* Ex */ { termp_fa_pre, NULL }, /* Fa */ - { termp_fd_pre, NULL }, /* Fd */ + { termp_fd_pre, termp_fd_post }, /* Fd */ { termp_fl_pre, NULL }, /* Fl */ { termp_fn_pre, NULL }, /* Fn */ { termp_ft_pre, NULL }, /* Ft */ @@ -242,7 +242,7 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, termp____post }, /* %Q */ { termp_sp_pre, NULL }, /* br */ { termp_sp_pre, NULL }, /* sp */ - { termp_under_pre, termp____post }, /* %U */ + { NULL, termp____post }, /* %U */ { NULL, NULL }, /* Ta */ }; @@ -251,7 +251,7 @@ void terminal_mdoc(void *arg, const struct mdoc *mdoc) { const struct mdoc_node *n; - const struct mdoc_meta *m; + const struct mdoc_meta *meta; struct termp *p; p = (struct termp *)arg; @@ -267,12 +267,12 @@ terminal_mdoc(void *arg, const struct mdoc *mdoc) p->symtab = mchars_alloc(); n = mdoc_node(mdoc); - m = mdoc_meta(mdoc); + meta = mdoc_meta(mdoc); - term_begin(p, print_mdoc_head, print_mdoc_foot, m); + term_begin(p, print_mdoc_head, print_mdoc_foot, meta); if (n->child) - print_mdoc_nodelist(p, NULL, m, n->child); + print_mdoc_nodelist(p, NULL, meta, n->child); term_end(p); } @@ -282,9 +282,9 @@ static void print_mdoc_nodelist(DECL_ARGS) { - print_mdoc_node(p, pair, m, n); + print_mdoc_node(p, pair, meta, n); if (n->next) - print_mdoc_nodelist(p, pair, m, n->next); + print_mdoc_nodelist(p, pair, meta, n->next); } @@ -293,14 +293,13 @@ static void print_mdoc_node(DECL_ARGS) { int chld; - const void *font; struct termpair npair; size_t offset, rmargin; chld = 1; offset = p->offset; rmargin = p->rmargin; - font = term_fontq(p); + n->prev_font = term_fontq(p); memset(&npair, 0, sizeof(struct termpair)); npair.ppair = pair; @@ -314,14 +313,10 @@ print_mdoc_node(DECL_ARGS) */ if (TERMP_KEEP & p->flags || MDOC_SYNPRETTY & n->flags) { - if (n->prev && n->prev->line != n->line) { + if (n->prev ? (n->prev->line != n->line) : + (n->parent && n->parent->line != n->line)) { p->flags &= ~TERMP_KEEP; p->flags |= TERMP_PREKEEP; - } else if (NULL == n->prev) { - if (n->parent && n->parent->line != n->line) { - p->flags &= ~TERMP_KEEP; - p->flags |= TERMP_PREKEEP; - } } } @@ -359,14 +354,15 @@ print_mdoc_node(DECL_ARGS) default: if (termacts[n->tok].pre && ENDBODY_NOT == n->end) chld = (*termacts[n->tok].pre) - (p, &npair, m, n); + (p, &npair, meta, n); break; } if (chld && n->child) - print_mdoc_nodelist(p, &npair, m, n->child); + print_mdoc_nodelist(p, &npair, meta, n->child); - term_fontpopq(p, font); + term_fontpopq(p, + (ENDBODY_NOT == n->end ? n : n->pending)->prev_font); switch (n->type) { case (MDOC_TEXT): @@ -378,7 +374,7 @@ print_mdoc_node(DECL_ARGS) default: if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) break; - (void)(*termacts[n->tok].post)(p, &npair, m, n); + (void)(*termacts[n->tok].post)(p, &npair, meta, n); /* * Explicit end tokens not only call the post @@ -409,9 +405,9 @@ print_mdoc_node(DECL_ARGS) static void print_mdoc_foot(struct termp *p, const void *arg) { - const struct mdoc_meta *m; + const struct mdoc_meta *meta; - m = (const struct mdoc_meta *)arg; + meta = (const struct mdoc_meta *)arg; term_fontrepl(p, TERMFONT_NONE); @@ -427,17 +423,17 @@ print_mdoc_foot(struct termp *p, const void *arg) p->offset = 0; p->rmargin = (p->maxrmargin - - term_strlen(p, m->date) + term_len(p, 1)) / 2; + term_strlen(p, meta->date) + term_len(p, 1)) / 2; p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; - term_word(p, m->os); + term_word(p, meta->os); term_flushln(p); p->offset = p->rmargin; - p->rmargin = p->maxrmargin - term_strlen(p, m->os); + p->rmargin = p->maxrmargin - term_strlen(p, meta->os); p->flags |= TERMP_NOSPACE; - term_word(p, m->date); + term_word(p, meta->date); term_flushln(p); p->offset = p->rmargin; @@ -445,7 +441,7 @@ print_mdoc_foot(struct termp *p, const void *arg) p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; - term_word(p, m->os); + term_word(p, meta->os); term_flushln(p); p->offset = 0; @@ -459,9 +455,9 @@ print_mdoc_head(struct termp *p, const void *arg) { char buf[BUFSIZ], title[BUFSIZ]; size_t buflen, titlen; - const struct mdoc_meta *m; + const struct mdoc_meta *meta; - m = (const struct mdoc_meta *)arg; + meta = (const struct mdoc_meta *)arg; /* * The header is strange. It has three components, which are @@ -479,17 +475,17 @@ print_mdoc_head(struct termp *p, const void *arg) p->offset = 0; p->rmargin = p->maxrmargin; - assert(m->vol); - strlcpy(buf, m->vol, BUFSIZ); + assert(meta->vol); + strlcpy(buf, meta->vol, BUFSIZ); buflen = term_strlen(p, buf); - if (m->arch) { + if (meta->arch) { strlcat(buf, " (", BUFSIZ); - strlcat(buf, m->arch, BUFSIZ); + strlcat(buf, meta->arch, BUFSIZ); strlcat(buf, ")", BUFSIZ); } - snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec); + snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec); titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; @@ -727,12 +723,10 @@ termp_it_pre(DECL_ARGS) case (LIST_dash): /* FALLTHROUGH */ case (LIST_hyphen): - if (width < term_len(p, 4)) - width = term_len(p, 4); - break; + /* FALLTHROUGH */ case (LIST_enum): - if (width < term_len(p, 5)) - width = term_len(p, 5); + if (width < term_len(p, 2)) + width = term_len(p, 2); break; case (LIST_hang): if (0 == width) @@ -787,12 +781,18 @@ termp_it_pre(DECL_ARGS) */ switch (type) { + case (LIST_enum): + /* + * Weird special case. + * Very narrow enum lists actually hang. + */ + if (width == term_len(p, 2)) + p->flags |= TERMP_HANG; + /* FALLTHROUGH */ case (LIST_bullet): /* FALLTHROUGH */ case (LIST_dash): /* FALLTHROUGH */ - case (LIST_enum): - /* FALLTHROUGH */ case (LIST_hyphen): if (MDOC_HEAD == n->type) p->flags |= TERMP_NOBREAK; @@ -1007,14 +1007,15 @@ termp_nm_pre(DECL_ARGS) return(0); p->flags |= TERMP_NOSPACE; p->offset += term_len(p, 1) + - (NULL == n->prev->child ? term_strlen(p, m->name) : + (NULL == n->prev->child ? + term_strlen(p, meta->name) : MDOC_TEXT == n->prev->child->type ? - term_strlen(p, n->prev->child->string) : + term_strlen(p, n->prev->child->string) : term_len(p, 5)); return(1); } - if (NULL == n->child && NULL == m->name) + if (NULL == n->child && NULL == meta->name) return(0); if (MDOC_HEAD == n->type) @@ -1024,7 +1025,7 @@ termp_nm_pre(DECL_ARGS) p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->rmargin = p->offset + term_len(p, 1); if (NULL == n->child) { - p->rmargin += term_strlen(p, m->name); + p->rmargin += term_strlen(p, meta->name); } else if (MDOC_TEXT == n->child->type) { p->rmargin += term_strlen(p, n->child->string); if (n->child->next) @@ -1037,7 +1038,7 @@ termp_nm_pre(DECL_ARGS) term_fontpush(p, TERMFONT_BOLD); if (NULL == n->child) - term_word(p, m->name); + term_word(p, meta->name); return(1); } @@ -1375,14 +1376,14 @@ termp_vt_pre(DECL_ARGS) if (MDOC_ELEM == n->type) { synopsis_pre(p, n); - return(termp_under_pre(p, pair, m, n)); + return(termp_under_pre(p, pair, meta, n)); } else if (MDOC_BLOCK == n->type) { synopsis_pre(p, n); return(1); } else if (MDOC_HEAD == n->type) return(0); - return(termp_under_pre(p, pair, m, n)); + return(termp_under_pre(p, pair, meta, n)); } @@ -1402,7 +1403,16 @@ termp_fd_pre(DECL_ARGS) { synopsis_pre(p, n); - return(termp_bold_pre(p, pair, m, n)); + return(termp_bold_pre(p, pair, meta, n)); +} + + +/* ARGSUSED */ +static void +termp_fd_post(DECL_ARGS) +{ + + term_newln(p); } @@ -1425,6 +1435,8 @@ termp_sh_pre(DECL_ARGS) break; case (MDOC_BODY): p->offset = term_len(p, p->defindent); + if (SEC_AUTHORS == n->sec) + p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT); break; default: break; @@ -1497,17 +1509,6 @@ termp_d1_pre(DECL_ARGS) } -/* ARGSUSED */ -static void -termp_d1_post(DECL_ARGS) -{ - - if (MDOC_BLOCK != n->type) - return; - term_newln(p); -} - - /* ARGSUSED */ static int termp_ft_pre(DECL_ARGS) @@ -1602,7 +1603,7 @@ static int termp_bd_pre(DECL_ARGS) { size_t tabwidth, rm, rmax; - const struct mdoc_node *nn; + struct mdoc_node *nn; if (MDOC_BLOCK == n->type) { print_bvspace(p, n, n); @@ -1634,7 +1635,7 @@ termp_bd_pre(DECL_ARGS) p->rmargin = p->maxrmargin = TERM_MAXMARGIN; for (nn = n->child; nn; nn = nn->next) { - print_mdoc_node(p, pair, m, nn); + print_mdoc_node(p, pair, meta, nn); /* * If the printed node flushes its own line, then we * needn't do it here as well. This is hacky, but the @@ -1751,7 +1752,8 @@ termp_xx_pre(DECL_ARGS) pp = "UNIX"; break; default: - break; + abort(); + /* NOTREACHED */ } term_word(p, pp); @@ -1923,7 +1925,7 @@ termp_quote_pre(DECL_ARGS) case (MDOC_Do): /* FALLTHROUGH */ case (MDOC_Dq): - term_word(p, "``"); + term_word(p, "\\(lq"); break; case (MDOC_Eo): break; @@ -1944,7 +1946,7 @@ termp_quote_pre(DECL_ARGS) case (MDOC_So): /* FALLTHROUGH */ case (MDOC_Sq): - term_word(p, "`"); + term_word(p, "\\(oq"); break; default: abort(); @@ -1989,7 +1991,7 @@ termp_quote_post(DECL_ARGS) case (MDOC_Do): /* FALLTHROUGH */ case (MDOC_Dq): - term_word(p, "''"); + term_word(p, "\\(rq"); break; case (MDOC_Eo): break; @@ -2010,7 +2012,7 @@ termp_quote_post(DECL_ARGS) case (MDOC_So): /* FALLTHROUGH */ case (MDOC_Sq): - term_word(p, "'"); + term_word(p, "\\(cq"); break; default: abort(); @@ -2071,7 +2073,7 @@ termp_bf_pre(DECL_ARGS) if (MDOC_HEAD == n->type) return(0); - else if (MDOC_BLOCK != n->type) + else if (MDOC_BODY != n->type) return(1); if (FONT_Em == n->norm->Bf.font) @@ -2157,25 +2159,24 @@ termp_li_pre(DECL_ARGS) static int termp_lk_pre(DECL_ARGS) { - const struct mdoc_node *nn, *sv; - - term_fontpush(p, TERMFONT_UNDER); - - nn = sv = n->child; + const struct mdoc_node *link, *descr; - if (NULL == nn || NULL == nn->next) - return(1); - - for (nn = nn->next; nn; nn = nn->next) - term_word(p, nn->string); - - term_fontpop(p); + if (NULL == (link = n->child)) + return(0); - p->flags |= TERMP_NOSPACE; - term_word(p, ":"); + if (NULL != (descr = link->next)) { + term_fontpush(p, TERMFONT_UNDER); + while (NULL != descr) { + term_word(p, descr->string); + descr = descr->next; + } + p->flags |= TERMP_NOSPACE; + term_word(p, ":"); + term_fontpop(p); + } term_fontpush(p, TERMFONT_BOLD); - term_word(p, sv->string); + term_word(p, link->string); term_fontpop(p); return(0); @@ -2210,7 +2211,7 @@ static void termp_bk_post(DECL_ARGS) { - if (MDOC_BODY == n->type) + if (MDOC_BODY == n->type && ! (MDOC_SYNPRETTY & n->flags)) p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); } @@ -2225,9 +2226,9 @@ termp__t_post(DECL_ARGS) */ if (n->parent && MDOC_Rs == n->parent->tok && n->parent->norm->Rs.quote_T) - termp_quote_post(p, pair, m, n); + termp_quote_post(p, pair, meta, n); - termp____post(p, pair, m, n); + termp____post(p, pair, meta, n); } /* ARGSUSED */ @@ -2241,7 +2242,7 @@ termp__t_pre(DECL_ARGS) */ if (n->parent && MDOC_Rs == n->parent->tok && n->parent->norm->Rs.quote_T) - return(termp_quote_pre(p, pair, m, n)); + return(termp_quote_pre(p, pair, meta, n)); term_fontpush(p, TERMFONT_UNDER); return(1); diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mdocml/mdoc_validate.c index 060ccdadec..8ffc393747 100644 --- a/contrib/mdocml/mdoc_validate.c +++ b/contrib/mdocml/mdoc_validate.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.182 2012/03/23 05:50:25 kristaps Exp $ */ +/* $Id: mdoc_validate.c,v 1.193 2013/09/16 00:25:07 schwarze Exp $ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2010, 2011, 2012 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 @@ -107,6 +107,7 @@ 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_par(POST_ARGS); static int post_ignpar(POST_ARGS); static int post_prol(POST_ARGS); static int post_root(POST_ARGS); @@ -152,9 +153,10 @@ 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_pp[] = { post_par, ewarn_eq0, NULL }; static v_post posts_rs[] = { post_rs, 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_sp[] = { post_par, ewarn_le1, 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 }; @@ -185,7 +187,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { pres_os, posts_os }, /* Os */ { pres_sh, posts_sh }, /* Sh */ { pres_ss, posts_ss }, /* Ss */ - { pres_pp, posts_notext }, /* Pp */ + { pres_pp, posts_pp }, /* Pp */ { pres_d1, posts_wline }, /* D1 */ { pres_dl, posts_dl }, /* Dl */ { pres_bd, posts_bd }, /* Bd */ @@ -286,7 +288,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Fr */ { NULL, posts_eoln }, /* Ud */ { NULL, posts_lb }, /* Lb */ - { NULL, posts_notext }, /* Lp */ + { pres_pp, posts_pp }, /* Lp */ { NULL, NULL }, /* Lk */ { NULL, posts_defaults }, /* Mt */ { NULL, NULL }, /* Brq */ @@ -297,8 +299,8 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* En */ { NULL, NULL }, /* Dx */ { NULL, posts_text }, /* %Q */ - { NULL, posts_notext }, /* br */ - { pres_pp, posts_sp }, /* sp */ + { NULL, posts_pp }, /* br */ + { NULL, posts_sp }, /* sp */ { NULL, posts_text1 }, /* %U */ { NULL, NULL }, /* Ta */ }; @@ -314,12 +316,12 @@ static const enum mdoct rsord[RSORD_MAX] = { MDOC__R, MDOC__N, MDOC__V, + MDOC__U, MDOC__P, MDOC__Q, - MDOC__D, - MDOC__O, MDOC__C, - MDOC__U + MDOC__D, + MDOC__O }; static const char * const secnames[SEC__MAX] = { @@ -414,29 +416,29 @@ mdoc_valid_post(struct mdoc *mdoc) } static int -check_count(struct mdoc *m, enum mdoc_type type, +check_count(struct mdoc *mdoc, enum mdoc_type type, enum check_lvl lvl, enum check_ineq ineq, int val) { const char *p; enum mandocerr t; - if (m->last->type != type) + if (mdoc->last->type != type) return(1); switch (ineq) { case (CHECK_LT): p = "less than "; - if (m->last->nchild < val) + if (mdoc->last->nchild < val) return(1); break; case (CHECK_GT): p = "more than "; - if (m->last->nchild > val) + if (mdoc->last->nchild > val) return(1); break; case (CHECK_EQ): p = ""; - if (val == m->last->nchild) + if (val == mdoc->last->nchild) return(1); break; default: @@ -445,9 +447,9 @@ check_count(struct mdoc *m, enum mdoc_type type, } t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT; - mandoc_vmsg(t, m->parse, m->last->line, m->last->pos, + mandoc_vmsg(t, mdoc->parse, mdoc->last->line, mdoc->last->pos, "want %s%d children (have %d)", - p, val, m->last->nchild); + p, val, mdoc->last->nchild); return(1); } @@ -513,7 +515,7 @@ hwarn_le1(POST_ARGS) } static void -check_args(struct mdoc *m, struct mdoc_node *n) +check_args(struct mdoc *mdoc, struct mdoc_node *n) { int i; @@ -522,34 +524,34 @@ check_args(struct mdoc *m, struct mdoc_node *n) assert(n->args->argc); for (i = 0; i < (int)n->args->argc; i++) - check_argv(m, n, &n->args->argv[i]); + check_argv(mdoc, n, &n->args->argv[i]); } static void -check_argv(struct mdoc *m, struct mdoc_node *n, struct mdoc_argv *v) +check_argv(struct mdoc *mdoc, struct mdoc_node *n, struct mdoc_argv *v) { int i; for (i = 0; i < (int)v->sz; i++) - check_text(m, v->line, v->pos, v->value[i]); + check_text(mdoc, v->line, v->pos, v->value[i]); /* FIXME: move to post_std(). */ if (MDOC_Std == v->arg) - if ( ! (v->sz || m->meta.name)) - mdoc_nmsg(m, n, MANDOCERR_NONAME); + if ( ! (v->sz || mdoc->meta.name)) + mdoc_nmsg(mdoc, n, MANDOCERR_NONAME); } static void -check_text(struct mdoc *m, int ln, int pos, char *p) +check_text(struct mdoc *mdoc, int ln, int pos, char *p) { char *cp; - if (MDOC_LITERAL & m->flags) + if (MDOC_LITERAL & mdoc->flags) return; for (cp = p; NULL != (p = strchr(p, '\t')); p++) - mdoc_pmsg(m, ln, pos + (int)(p - cp), MANDOCERR_BADTAB); + mdoc_pmsg(mdoc, ln, pos + (int)(p - cp), MANDOCERR_BADTAB); } static int @@ -733,14 +735,14 @@ pre_bl(PRE_ARGS) /* * Validate the width field. Some list types don't need width * types and should be warned about them. Others should have it - * and must also be warned. + * and must also be warned. Yet others have a default and need + * no warning. */ switch (n->norm->Bl.type) { case (LIST_tag): - if (n->norm->Bl.width) - break; - mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG); + if (NULL == n->norm->Bl.width) + mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG); break; case (LIST_column): /* FALLTHROUGH */ @@ -754,6 +756,18 @@ pre_bl(PRE_ARGS) if (n->norm->Bl.width) mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV); break; + case (LIST_bullet): + /* FALLTHROUGH */ + case (LIST_dash): + /* FALLTHROUGH */ + case (LIST_hyphen): + if (NULL == n->norm->Bl.width) + n->norm->Bl.width = "2n"; + break; + case (LIST_enum): + if (NULL == n->norm->Bl.width) + n->norm->Bl.width = "3n"; + break; default: break; } @@ -1111,24 +1125,29 @@ post_nm(POST_ARGS) char buf[BUFSIZ]; int c; - /* If no child specified, make sure we have the meta name. */ - - if (NULL == mdoc->last->child && NULL == mdoc->meta.name) { - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME); - return(1); - } else if (mdoc->meta.name) + if (NULL != mdoc->meta.name) return(1); - /* If no meta name, set it from the child. */ + /* Try to use our children for setting the meta name. */ - buf[0] = '\0'; - if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) { + if (NULL != mdoc->last->child) { + buf[0] = '\0'; + c = concat(buf, mdoc->last->child, BUFSIZ); + } else + c = 0; + + switch (c) { + case (-1): mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM); return(0); + case (0): + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME); + mdoc->meta.name = mandoc_strdup("UNKNOWN"); + break; + default: + mdoc->meta.name = mandoc_strdup(buf); + break; } - - assert(c); - mdoc->meta.name = mandoc_strdup(buf); return(1); } @@ -1334,7 +1353,7 @@ post_it(POST_ARGS) static int post_bl_block(POST_ARGS) { - struct mdoc_node *n; + struct mdoc_node *n, *ni, *nc; /* * These are fairly complicated, so we've broken them into two @@ -1350,13 +1369,42 @@ post_bl_block(POST_ARGS) NULL == n->norm->Bl.width) { if ( ! post_bl_block_tag(mdoc)) return(0); + assert(n->norm->Bl.width); } else if (NULL != n->norm->Bl.width) { if ( ! post_bl_block_width(mdoc)) return(0); - } else - return(1); + assert(n->norm->Bl.width); + } - assert(n->norm->Bl.width); + for (ni = n->body->child; ni; ni = ni->next) { + if (NULL == ni->body) + continue; + nc = ni->body->last; + while (NULL != nc) { + switch (nc->tok) { + case (MDOC_Pp): + /* FALLTHROUGH */ + case (MDOC_Lp): + /* FALLTHROUGH */ + case (MDOC_br): + break; + default: + nc = NULL; + continue; + } + if (NULL == ni->next) { + mdoc_nmsg(mdoc, nc, MANDOCERR_MOVEPAR); + if ( ! mdoc_node_relink(mdoc, nc)) + return(0); + } else if (0 == n->norm->Bl.comp && + LIST_column != n->norm->Bl.type) { + mdoc_nmsg(mdoc, nc, MANDOCERR_IGNPAR); + mdoc_node_delete(mdoc, nc); + } else + break; + nc = ni->body->last; + } + } return(1); } @@ -1916,7 +1964,8 @@ post_sh_head(POST_ARGS) break; if (*mdoc->meta.msec == '9') break; - mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECMSEC); + mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse, + mdoc->last->line, mdoc->last->pos, buf); break; default: break; @@ -1962,7 +2011,9 @@ pre_par(PRE_ARGS) * block: `Lp', `Pp', or non-compact `Bd' or `Bl'. */ - if (MDOC_Pp != mdoc->last->tok && MDOC_Lp != mdoc->last->tok) + if (MDOC_Pp != mdoc->last->tok && + MDOC_Lp != mdoc->last->tok && + MDOC_br != mdoc->last->tok) return(1); if (MDOC_Bl == n->tok && n->norm->Bl.comp) return(1); @@ -1976,6 +2027,32 @@ pre_par(PRE_ARGS) return(1); } +static int +post_par(POST_ARGS) +{ + + if (MDOC_ELEM != mdoc->last->type && + MDOC_BLOCK != mdoc->last->type) + return(1); + + if (NULL == mdoc->last->prev) { + if (MDOC_Sh != mdoc->last->parent->tok && + MDOC_Ss != mdoc->last->parent->tok) + return(1); + } else { + if (MDOC_Pp != mdoc->last->prev->tok && + MDOC_Lp != mdoc->last->prev->tok && + (MDOC_br != mdoc->last->tok || + (MDOC_sp != mdoc->last->prev->tok && + MDOC_br != mdoc->last->prev->tok))) + return(1); + } + + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNPAR); + mdoc_node_delete(mdoc, mdoc->last); + return(1); +} + static int pre_literal(PRE_ARGS) { @@ -2129,9 +2206,9 @@ post_dt(POST_ARGS) free(mdoc->meta.vol); mdoc->meta.vol = mandoc_strdup(cp); } else { - /* FIXME: warn about bad arch. */ cp = mdoc_a2arch(nn->string); if (NULL == cp) { + mdoc_nmsg(mdoc, nn, MANDOCERR_BADVOLARCH); free(mdoc->meta.vol); mdoc->meta.vol = mandoc_strdup(nn->string); } else @@ -2192,14 +2269,15 @@ post_os(POST_ARGS) n = mdoc->last; /* - * Set the operating system by way of the `Os' macro. Note that - * if an argument isn't provided and -DOSNAME="\"foo\"" is - * provided during compilation, this value will be used instead - * of filling in "sysname release" from uname(). + * Set the operating system by way of the `Os' macro. + * The order of precedence is: + * 1. the argument of the `Os' macro, unless empty + * 2. the -Ios=foo command line argument, if provided + * 3. -DOSNAME="\"foo\"", if provided during compilation + * 4. "sysname release" from uname(3) */ - if (mdoc->meta.os) - free(mdoc->meta.os); + free(mdoc->meta.os); buf[0] = '\0'; if (-1 == (c = concat(buf, n->child, BUFSIZ))) { @@ -2209,11 +2287,11 @@ post_os(POST_ARGS) assert(c); - /* XXX: yes, these can all be dynamically-adjusted buffers, but - * it's really not worth the extra hackery. - */ - if ('\0' == buf[0]) { + if (mdoc->defos) { + mdoc->meta.os = mandoc_strdup(mdoc->defos); + return(1); + } #ifdef OSNAME if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) { mdoc_nmsg(mdoc, n, MANDOCERR_MEM); diff --git a/contrib/mdocml/out.c b/contrib/mdocml/out.c index 8dbd68ac11..1d8c8ab4b6 100644 --- a/contrib/mdocml/out.c +++ b/contrib/mdocml/out.c @@ -1,4 +1,4 @@ -/* $Id: out.c,v 1.43 2011/09/20 23:05:49 schwarze Exp $ */ +/* $Id: out.c,v 1.45 2013/05/31 21:37:17 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -32,11 +32,11 @@ #include "out.h" static void tblcalc_data(struct rofftbl *, struct roffcol *, - const struct tbl *, const struct tbl_dat *); + const struct tbl_opts *, const struct tbl_dat *); static void tblcalc_literal(struct rofftbl *, struct roffcol *, const struct tbl_dat *); static void tblcalc_number(struct rofftbl *, struct roffcol *, - const struct tbl *, const struct tbl_dat *); + const struct tbl_opts *, const struct tbl_dat *); /* * Convert a `scaling unit' to a consistent form, or fail. Scaling @@ -154,7 +154,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) assert(NULL == tbl->cols); tbl->cols = mandoc_calloc - ((size_t)sp->tbl->cols, sizeof(struct roffcol)); + ((size_t)sp->opts->cols, sizeof(struct roffcol)); hp = sp->head; @@ -175,33 +175,14 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) continue; assert(dp->layout); col = &tbl->cols[dp->layout->head->ident]; - tblcalc_data(tbl, col, sp->tbl, dp); - } - } - - /* - * Calculate width of the spanners. These get one space for a - * vertical line, two for a double-vertical line. - */ - - for ( ; hp; hp = hp->next) { - col = &tbl->cols[hp->ident]; - switch (hp->pos) { - case (TBL_HEAD_VERT): - col->width = (*tbl->len)(1, tbl->arg); - break; - case (TBL_HEAD_DVERT): - col->width = (*tbl->len)(2, tbl->arg); - break; - default: - break; + tblcalc_data(tbl, col, sp->opts, dp); } } } static void tblcalc_data(struct rofftbl *tbl, struct roffcol *col, - const struct tbl *tp, const struct tbl_dat *dp) + const struct tbl_opts *opts, const struct tbl_dat *dp) { size_t sz; @@ -225,7 +206,7 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col, tblcalc_literal(tbl, col, dp); break; case (TBL_CELL_NUMBER): - tblcalc_number(tbl, col, tp, dp); + tblcalc_number(tbl, col, opts, dp); break; case (TBL_CELL_DOWN): break; @@ -251,7 +232,7 @@ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col, static void tblcalc_number(struct rofftbl *tbl, struct roffcol *col, - const struct tbl *tp, const struct tbl_dat *dp) + const struct tbl_opts *opts, const struct tbl_dat *dp) { int i; size_t sz, psz, ssz, d; @@ -273,12 +254,12 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col, /* FIXME: TBL_DATA_HORIZ et al.? */ - buf[0] = tp->decimal; + buf[0] = opts->decimal; buf[1] = '\0'; psz = (*tbl->slen)(buf, tbl->arg); - if (NULL != (cp = strrchr(str, tp->decimal))) { + if (NULL != (cp = strrchr(str, opts->decimal))) { buf[1] = '\0'; for (ssz = 0, i = 0; cp != &str[i]; i++) { buf[0] = str[i]; diff --git a/contrib/mdocml/preconv.1 b/contrib/mdocml/preconv.1 index c4cb8c5738..8daee30854 100644 --- a/contrib/mdocml/preconv.1 +++ b/contrib/mdocml/preconv.1 @@ -1,4 +1,4 @@ -.\" $Id: preconv.1,v 1.6 2011/12/25 19:35:44 kristaps Exp $ +.\" $Id: preconv.1,v 1.7 2013/07/13 19:41:16 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 25 2011 $ +.Dd $Mdocdate: July 13 2013 $ .Dt PRECONV 1 .Os .Sh NAME @@ -150,8 +150,7 @@ utility appeared in May 2011. The .Nm utility was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . .\" .Sh CAVEATS .\" .Sh BUGS .\" .Sh SECURITY CONSIDERATIONS diff --git a/contrib/mdocml/preconv.c b/contrib/mdocml/preconv.c index a0b2d6415e..7595887dd2 100644 --- a/contrib/mdocml/preconv.c +++ b/contrib/mdocml/preconv.c @@ -1,4 +1,4 @@ -/* $Id: preconv.c,v 1.5 2011/07/24 18:15:14 kristaps Exp $ */ +/* $Id: preconv.c,v 1.6 2013/06/02 03:52:21 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -32,13 +32,9 @@ /* * The read_whole_file() and resize_buf() functions are copied from - * read.c, including all dependency code (MAP_FILE, etc.). + * read.c, including all dependency code. */ -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - enum enc { ENC_UTF_8, /* UTF-8 */ ENC_US_ASCII, /* US-ASCII */ @@ -271,8 +267,7 @@ read_whole_file(const char *f, int fd, 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); + fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); if (fb->buf != MAP_FAILED) return(1); } diff --git a/contrib/mdocml/predefs.in b/contrib/mdocml/predefs.in index 70074bb617..d1690e3568 100644 --- a/contrib/mdocml/predefs.in +++ b/contrib/mdocml/predefs.in @@ -1,4 +1,4 @@ -/* $Id: predefs.in,v 1.3 2011/07/31 11:36:49 schwarze Exp $ */ +/* $Id: predefs.in,v 1.4 2012/07/18 10:39:19 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -26,7 +26,7 @@ */ PREDEF("Am", "&") -PREDEF("Ba", "|") +PREDEF("Ba", "\\fR|\\fP") PREDEF("Ge", "\\(>=") PREDEF("Gt", ">") PREDEF("If", "infinity") diff --git a/contrib/mdocml/read.c b/contrib/mdocml/read.c index 5b14e357d2..511ba7dc46 100644 --- a/contrib/mdocml/read.c +++ b/contrib/mdocml/read.c @@ -1,7 +1,7 @@ -/* $Id: read.c,v 1.28 2012/02/16 20:51:31 joerg Exp $ */ +/* $Id: read.c,v 1.39 2013/09/16 00:25:07 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2011, 2012, 2013 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 @@ -40,10 +40,6 @@ #include "man.h" #include "main.h" -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - #define REPARSE_LIMIT 1000 struct buf { @@ -66,14 +62,16 @@ struct mparse { void *arg; /* argument to mmsg */ const char *file; struct buf *secondary; + char *defos; /* default operating system */ }; 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 void mparse_parse_buffer(struct mparse *, struct buf, + const char *); static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = { MANDOCERR_OK, @@ -94,6 +92,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "no title in document", "document title should be all caps", "unknown manual section", + "unknown manual volume or arch", "date missing, using today's date", "cannot parse date, using it verbatim", "prologue macros out of order", @@ -105,14 +104,14 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { ".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", + "section header suited to sections 2, 3, and 9 only", /* related to macros and nesting */ "skipping obsolete macro", "skipping paragraph macro", + "moving paragraph macro out of list", "skipping no-space macro", "blocks badly nested", "child violates parent syntax", @@ -173,10 +172,12 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "input stack limit exceeded, infinite loop?", "skipping bad character", "escaped character not allowed in a name", + "manual name not yet set", "skipping text before the first section header", "skipping unknown macro", "NOT IMPLEMENTED, please use groff: skipping request", "argument count wrong", + "skipping column outside column list", "skipping end of block that is not open", "missing end of block", "scope open on exit", @@ -184,6 +185,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "macro requires line argument(s)", "macro requires body argument(s)", "macro requires argument(s)", + "request requires a numeric argument", "missing list type", "line argument(s) will be lost", "body argument(s) will be lost", @@ -247,7 +249,8 @@ pset(const char *buf, int pos, struct mparse *curp) switch (curp->inttype) { case (MPARSE_MDOC): if (NULL == curp->pmdoc) - curp->pmdoc = mdoc_alloc(curp->roff, curp); + curp->pmdoc = mdoc_alloc(curp->roff, curp, + curp->defos); assert(curp->pmdoc); curp->mdoc = curp->pmdoc; return; @@ -263,7 +266,8 @@ pset(const char *buf, int pos, struct mparse *curp) if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) { if (NULL == curp->pmdoc) - curp->pmdoc = mdoc_alloc(curp->roff, curp); + curp->pmdoc = mdoc_alloc(curp->roff, curp, + curp->defos); assert(curp->pmdoc); curp->mdoc = curp->pmdoc; return; @@ -322,6 +326,15 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start) break; } + /* + * Make sure we have space for at least + * one backslash and one other character + * and the trailing NUL byte. + */ + + if (pos + 2 >= (int)ln.sz) + resize_buf(&ln, 256); + /* * Warn about bogus characters. If you're using * non-ASCII encoding, you're screwing your @@ -338,8 +351,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start) mandoc_msg(MANDOCERR_BADCHAR, curp, curp->line, pos, NULL); i++; - if (pos >= (int)ln.sz) - resize_buf(&ln, 256); ln.buf[pos++] = '?'; continue; } @@ -347,8 +358,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start) /* 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; } @@ -390,10 +399,20 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start) break; } - /* Some other escape sequence, copy & cont. */ + /* Catch escaped bogus characters. */ - if (pos + 1 >= (int)ln.sz) - resize_buf(&ln, 256); + c = (unsigned char) blk.buf[i+1]; + + if ( ! (isascii(c) && + (isgraph(c) || isblank(c)))) { + mandoc_msg(MANDOCERR_BADCHAR, curp, + curp->line, pos, NULL); + i += 2; + ln.buf[pos++] = '?'; + continue; + } + + /* Some other escape sequence, copy & cont. */ ln.buf[pos++] = blk.buf[i++]; ln.buf[pos++] = blk.buf[i++]; @@ -469,7 +488,7 @@ rerun: */ if (curp->secondary) curp->secondary->sz -= pos + 1; - mparse_readfd_r(curp, -1, ln.buf + of, 1); + mparse_readfd(curp, -1, ln.buf + of); if (MANDOCLEVEL_FATAL <= curp->file_status) break; pos = 0; @@ -575,8 +594,7 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) } *with_mmap = 1; fb->sz = (size_t)st.st_size; - fb->buf = mmap(NULL, fb->sz, PROT_READ, - MAP_FILE|MAP_SHARED, fd, 0); + fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); if (fb->buf != MAP_FAILED) return(1); } @@ -643,19 +661,25 @@ mparse_end(struct mparse *curp) } static void -mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file, - int re) +mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file) { const char *svfile; + static int recursion_depth; + + if (64 < recursion_depth) { + mandoc_msg(MANDOCERR_ROFFLOOP, curp, curp->line, 0, NULL); + return; + } /* Line number is per-file. */ svfile = curp->file; curp->file = file; curp->line = 1; + recursion_depth++; mparse_buf_r(curp, blk, 1); - if (0 == re && MANDOCLEVEL_FATAL > curp->file_status) + if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status) mparse_end(curp); curp->file = svfile; @@ -670,12 +694,12 @@ mparse_readmem(struct mparse *curp, const void *buf, size_t len, blk.buf = UNCONST(buf); blk.sz = len; - mparse_parse_buffer(curp, blk, file, 0); + mparse_parse_buffer(curp, blk, file); return(curp->file_status); } -static void -mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re) +enum mandoclevel +mparse_readfd(struct mparse *curp, int fd, const char *file) { struct buf blk; int with_mmap; @@ -684,7 +708,7 @@ mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re) if (-1 == (fd = open(file, O_RDONLY, 0))) { perror(file); curp->file_status = MANDOCLEVEL_SYSERR; - return; + goto out; } /* * Run for each opened file; may be called more than once for @@ -695,10 +719,10 @@ mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re) if ( ! read_whole_file(file, fd, &blk, &with_mmap)) { curp->file_status = MANDOCLEVEL_SYSERR; - return; + goto out; } - mparse_parse_buffer(curp, blk, file, re); + mparse_parse_buffer(curp, blk, file); #ifdef HAVE_MMAP if (with_mmap) @@ -709,18 +733,13 @@ mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re) 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); +out: return(curp->file_status); } struct mparse * -mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, mandocmsg mmsg, void *arg) +mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, + mandocmsg mmsg, void *arg, char *defos) { struct mparse *curp; @@ -732,8 +751,9 @@ mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, mandocmsg mmsg, void curp->mmsg = mmsg; curp->arg = arg; curp->inttype = inttype; + curp->defos = defos; - curp->roff = roff_alloc(curp); + curp->roff = roff_alloc(inttype, curp); return(curp); } diff --git a/contrib/mdocml/roff.7 b/contrib/mdocml/roff.7 index dd32a45b29..7c26086e35 100644 --- a/contrib/mdocml/roff.7 +++ b/contrib/mdocml/roff.7 @@ -1,4 +1,4 @@ -.\" $Id: roff.7,v 1.37 2011/12/11 00:38:11 schwarze Exp $ +.\" $Id: roff.7,v 1.42 2013/08/08 20:07:47 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 11 2011 $ +.Dd $Mdocdate: August 8 2013 $ .Dt ROFF 7 .Os .Sh NAME @@ -83,7 +83,7 @@ depends on the respective processing context. .Nm documents may contain only graphable 7-bit ASCII characters, the space character, and, in certain circumstances, the tab character. -The back-space character +The backslash character .Sq \e indicates the start of an escape sequence for .Sx Comments , @@ -146,12 +146,19 @@ respectively) may be used instead. The indicator or numerical representative may be preceded by C (constant-width), which is ignored. .Pp +The two-character indicator +.Sq BI +requests a font that is both bold and italic. +It may not be portable to old roff implementations. +.Pp Examples: .Bl -tag -width Ds -offset indent -compact .It Li \efBbold\efR -Write in bold, then switch to regular font mode. +Write in \fBbold\fP, then switch to regular font mode. .It Li \efIitalic\efP -Write in italic, then return to previous font mode. +Write in \fIitalic\fP, then return to previous font mode. +.It Li \ef(BIbold italic\efP +Write in \f(BIbold italic\fP, then return to previous font mode. .El .Pp Text decoration is @@ -417,6 +424,18 @@ The syntax of this request is the same as that of It is currently ignored by .Xr mandoc 1 , as are its children. +.Ss \&cc +Changes the control character. +Its syntax is as follows: +.Bd -literal -offset indent +.Pf . Cm \&cc Op Ar c +.Ed +.Pp +If +.Ar c +is not specified, the control character is reset to +.Sq \&. . +Trailing characters are ignored. .Ss \&de Define a .Nm @@ -896,7 +915,7 @@ See .Xr tbl 7 for a description of the tbl language. .Sh COMPATIBILITY -This section documents compatibility between mandoc and other other +This section documents compatibility between mandoc and other .Nm implementations, at this time limited to GNU troff .Pq Qq groff . @@ -982,8 +1001,6 @@ In 1989, James Clarke re-implemented troff in C++, naming it groff. This .Nm reference was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv ; +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv and -.An Ingo Schwarze , -.Mt schwarze@openbsd.org . +.An Ingo Schwarze Aq Mt schwarze@openbsd.org . diff --git a/contrib/mdocml/roff.c b/contrib/mdocml/roff.c index b479cc298c..3ee8adfe6d 100644 --- a/contrib/mdocml/roff.c +++ b/contrib/mdocml/roff.c @@ -1,7 +1,7 @@ -/* $Id: roff.c,v 1.172 2011/10/24 21:41:45 schwarze Exp $ */ +/* $Id: roff.c,v 1.178 2013/07/13 12:52:07 schwarze Exp $ */ /* - * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,6 +21,7 @@ #include <assert.h> #include <ctype.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -39,6 +40,7 @@ enum rofft { ROFF_am, ROFF_ami, ROFF_am1, + ROFF_cc, ROFF_de, ROFF_dei, ROFF_de1, @@ -58,6 +60,8 @@ enum rofft { ROFF_so, ROFF_ta, ROFF_tr, + ROFF_Dd, + ROFF_TH, ROFF_TS, ROFF_TE, ROFF_T_, @@ -102,9 +106,11 @@ struct roffkv { }; struct roff { + enum mparset parsetype; /* requested parse type */ struct mparse *parse; /* parse point */ struct roffnode *last; /* leaf of stack */ enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */ + char control; /* control character */ int rstackpos; /* position in rstack */ struct reg regs[REG__MAX]; struct roffkv *strtab; /* user-defined strings & macros */ @@ -169,6 +175,7 @@ static enum rofferr roff_block(ROFF_ARGS); static enum rofferr roff_block_text(ROFF_ARGS); static enum rofferr roff_block_sub(ROFF_ARGS); static enum rofferr roff_cblock(ROFF_ARGS); +static enum rofferr roff_cc(ROFF_ARGS); static enum rofferr roff_ccond(ROFF_ARGS); static enum rofferr roff_cond(ROFF_ARGS); static enum rofferr roff_cond_text(ROFF_ARGS); @@ -180,12 +187,13 @@ static void roff_freestr(struct roffkv *); static char *roff_getname(struct roff *, char **, int, int); static const char *roff_getstrn(const struct roff *, const char *, size_t); +static enum rofferr roff_it(ROFF_ARGS); static enum rofferr roff_line_ignore(ROFF_ARGS); static enum rofferr roff_nr(ROFF_ARGS); static void roff_openeqn(struct roff *, const char *, int, int, const char *); static enum rofft roff_parse(struct roff *, const char *, int *); -static enum rofferr roff_parsetext(char *); +static enum rofferr roff_parsetext(char **, size_t *, int, int *); static enum rofferr roff_res(struct roff *, char **, size_t *, int, int); static enum rofferr roff_rm(ROFF_ARGS); @@ -195,6 +203,8 @@ static void roff_setstrn(struct roffkv **, const char *, size_t, const char *, size_t, int); static enum rofferr roff_so(ROFF_ARGS); static enum rofferr roff_tr(ROFF_ARGS); +static enum rofferr roff_Dd(ROFF_ARGS); +static enum rofferr roff_TH(ROFF_ARGS); static enum rofferr roff_TE(ROFF_ARGS); static enum rofferr roff_TS(ROFF_ARGS); static enum rofferr roff_EQ(ROFF_ARGS); @@ -215,6 +225,7 @@ static struct roffmac roffs[ROFF_MAX] = { { "am", roff_block, roff_block_text, roff_block_sub, 0, NULL }, { "ami", roff_block, roff_block_text, roff_block_sub, 0, NULL }, { "am1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, + { "cc", roff_cc, NULL, NULL, 0, NULL }, { "de", roff_block, roff_block_text, roff_block_sub, 0, NULL }, { "dei", roff_block, roff_block_text, roff_block_sub, 0, NULL }, { "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, @@ -224,7 +235,7 @@ static struct roffmac roffs[ROFF_MAX] = { { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL }, - { "it", roff_line_ignore, NULL, NULL, 0, NULL }, + { "it", roff_it, NULL, NULL, 0, NULL }, { "ne", roff_line_ignore, NULL, NULL, 0, NULL }, { "nh", roff_line_ignore, NULL, NULL, 0, NULL }, { "nr", roff_nr, NULL, NULL, 0, NULL }, @@ -234,6 +245,8 @@ static struct roffmac roffs[ROFF_MAX] = { { "so", roff_so, NULL, NULL, 0, NULL }, { "ta", roff_line_ignore, NULL, NULL, 0, NULL }, { "tr", roff_tr, NULL, NULL, 0, NULL }, + { "Dd", roff_Dd, NULL, NULL, 0, NULL }, + { "TH", roff_TH, NULL, NULL, 0, NULL }, { "TS", roff_TS, NULL, NULL, 0, NULL }, { "TE", roff_TE, NULL, NULL, 0, NULL }, { "T&", roff_T_, NULL, NULL, 0, NULL }, @@ -244,6 +257,37 @@ static struct roffmac roffs[ROFF_MAX] = { { NULL, roff_userdef, NULL, NULL, 0, NULL }, }; +const char *const __mdoc_reserved[] = { + "Ac", "Ad", "An", "Ao", "Ap", "Aq", "Ar", "At", + "Bc", "Bd", "Bf", "Bk", "Bl", "Bo", "Bq", + "Brc", "Bro", "Brq", "Bsx", "Bt", "Bx", + "Cd", "Cm", "Db", "Dc", "Dd", "Dl", "Do", "Dq", + "Ds", "Dt", "Dv", "Dx", "D1", + "Ec", "Ed", "Ef", "Ek", "El", "Em", "em", + "En", "Eo", "Eq", "Er", "Es", "Ev", "Ex", + "Fa", "Fc", "Fd", "Fl", "Fn", "Fo", "Fr", "Ft", "Fx", + "Hf", "Ic", "In", "It", "Lb", "Li", "Lk", "Lp", "LP", + "Me", "Ms", "Mt", "Nd", "Nm", "No", "Ns", "Nx", + "Oc", "Oo", "Op", "Os", "Ot", "Ox", + "Pa", "Pc", "Pf", "Po", "Pp", "PP", "pp", "Pq", + "Qc", "Ql", "Qo", "Qq", "Or", "Rd", "Re", "Rs", "Rv", + "Sc", "Sf", "Sh", "SH", "Sm", "So", "Sq", + "Ss", "St", "Sx", "Sy", + "Ta", "Tn", "Ud", "Ux", "Va", "Vt", "Xc", "Xo", "Xr", + "%A", "%B", "%D", "%I", "%J", "%N", "%O", + "%P", "%Q", "%R", "%T", "%U", "%V", + NULL +}; + +const char *const __man_reserved[] = { + "AT", "B", "BI", "BR", "BT", "DE", "DS", "DT", + "EE", "EN", "EQ", "EX", "HF", "HP", "I", "IB", "IP", "IR", + "LP", "ME", "MT", "OP", "P", "PD", "PP", "PT", + "R", "RB", "RE", "RI", "RS", "SB", "SH", "SM", "SS", "SY", + "TE", "TH", "TP", "TQ", "TS", "T&", "UC", "UE", "UR", "YS", + NULL +}; + /* Array of injected predefined strings. */ #define PREDEFS_MAX 38 static const struct predef predefs[PREDEFS_MAX] = { @@ -253,6 +297,9 @@ static const struct predef predefs[PREDEFS_MAX] = { /* See roffhash_find() */ #define ROFF_HASH(p) (p[0] - ASCII_LO) +static int roffit_lines; /* number of lines to delay */ +static char *roffit_macro; /* nil-terminated macro line */ + static void roffhash_init(void) { @@ -351,13 +398,13 @@ roffnode_push(struct roff *r, enum rofft tok, const char *name, static void roff_free1(struct roff *r) { - struct tbl_node *t; + struct tbl_node *tbl; struct eqn_node *e; int i; - while (NULL != (t = r->first_tbl)) { - r->first_tbl = t->next; - tbl_free(t); + while (NULL != (tbl = r->first_tbl)) { + r->first_tbl = tbl->next; + tbl_free(tbl); } r->first_tbl = r->last_tbl = r->tbl = NULL; @@ -392,6 +439,7 @@ roff_reset(struct roff *r) roff_free1(r); + r->control = 0; memset(&r->regs, 0, sizeof(struct reg) * REG__MAX); for (i = 0; i < PREDEFS_MAX; i++) @@ -409,12 +457,13 @@ roff_free(struct roff *r) struct roff * -roff_alloc(struct mparse *parse) +roff_alloc(enum mparset type, struct mparse *parse) { struct roff *r; int i; r = mandoc_calloc(1, sizeof(struct roff)); + r->parsetype = type; r->parse = parse; r->rstackpos = -1; @@ -552,16 +601,20 @@ again: } /* - * Process text streams: convert all breakable hyphens into ASCII_HYPH. + * Process text streams: + * Convert all breakable hyphens into ASCII_HYPH. + * Decrement and spring input line trap. */ static enum rofferr -roff_parsetext(char *p) +roff_parsetext(char **bufp, size_t *szp, int pos, int *offs) { size_t sz; const char *start; + char *p; + int isz; enum mandoc_esc esc; - start = p; + start = p = *bufp + pos; while ('\0' != *p) { sz = strcspn(p, "-\\"); @@ -589,6 +642,22 @@ roff_parsetext(char *p) p++; } + /* Spring the input line trap. */ + if (1 == roffit_lines) { + isz = asprintf(&p, "%s\n.%s", *bufp, roffit_macro); + if (-1 == isz) { + perror(NULL); + exit((int)MANDOCLEVEL_SYSERR); + } + free(*bufp); + *bufp = p; + *szp = isz + 1; + *offs = 0; + free(roffit_macro); + roffit_lines = 0; + return(ROFF_REPARSE); + } else if (1 < roffit_lines) + --roffit_lines; return(ROFF_CONT); } @@ -611,7 +680,7 @@ roff_parseln(struct roff *r, int ln, char **bufp, assert(ROFF_CONT == e); ppos = pos; - ctl = mandoc_getcontrol(*bufp, &pos); + ctl = roff_getcontrol(r, *bufp, &pos); /* * First, if a scope is open and we're not a macro, pass the @@ -633,13 +702,13 @@ roff_parseln(struct roff *r, int ln, char **bufp, return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); - return(roff_parsetext(*bufp + pos)); + return(roff_parsetext(bufp, szp, pos, offs)); } else if ( ! ctl) { if (r->eqn) return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); - return(roff_parsetext(*bufp + pos)); + return(roff_parsetext(bufp, szp, pos, offs)); } else if (r->eqn) return(eqn_read(&r->eqn, ln, *bufp, ppos, offs)); @@ -778,7 +847,7 @@ roffnode_cleanscope(struct roff *r) { while (r->last) { - if (--r->last->endspan < 0) + if (--r->last->endspan != 0) break; roffnode_pop(r); } @@ -984,57 +1053,45 @@ roff_cond_sub(ROFF_ARGS) rr = r->last->rule; roffnode_cleanscope(r); + t = roff_parse(r, *bufp, &pos); /* - * If the macro is unknown, first check if it contains a closing - * delimiter `\}'. If it does, close out our scope and return - * the currently-scoped rule (ignore or continue). Else, drop - * into the currently-scoped rule. + * Fully handle known macros when they are structurally + * required or when the conditional evaluated to true. */ - if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos))) { - ep = &(*bufp)[pos]; - for ( ; NULL != (ep = strchr(ep, '\\')); ep++) { - ep++; - if ('}' != *ep) - continue; - - /* - * Make the \} go away. - * This is a little haphazard, as it's not quite - * clear how nroff does this. - * If we're at the end of line, then just chop - * off the \} and resize the buffer. - * If we aren't, then conver it to spaces. - */ + if ((ROFF_MAX != t) && + (ROFF_ccond == t || ROFFRULE_ALLOW == rr || + ROFFMAC_STRUCT & roffs[t].flags)) { + assert(roffs[t].proc); + return((*roffs[t].proc)(r, t, bufp, szp, + ln, ppos, pos, offs)); + } - if ('\0' == *(ep + 1)) { - *--ep = '\0'; - *szp -= 2; - } else - *(ep - 1) = *ep = ' '; + /* Always check for the closing delimiter `\}'. */ - roff_ccond(r, ROFF_ccond, bufp, szp, - ln, pos, pos + 2, offs); - break; - } - return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); - } + ep = &(*bufp)[pos]; + while (NULL != (ep = strchr(ep, '\\'))) { + if ('}' != *(++ep)) + continue; - /* - * A denied conditional must evaluate its children if and only - * if they're either structurally required (such as loops and - * conditionals) or a closing macro. - */ + /* + * If we're at the end of line, then just chop + * off the \} and resize the buffer. + * If we aren't, then convert it to spaces. + */ - if (ROFFRULE_DENY == rr) - if ( ! (ROFFMAC_STRUCT & roffs[t].flags)) - if (ROFF_ccond != t) - return(ROFF_IGN); + if ('\0' == *(ep + 1)) { + *--ep = '\0'; + *szp -= 2; + } else + *(ep - 1) = *ep = ' '; - assert(roffs[t].proc); - return((*roffs[t].proc)(r, t, bufp, szp, - ln, ppos, pos, offs)); + roff_ccond(r, ROFF_ccond, bufp, szp, + ln, pos, pos + 2, offs); + break; + } + return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); } /* ARGSUSED */ @@ -1088,9 +1145,6 @@ static enum rofferr roff_line_ignore(ROFF_ARGS) { - if (ROFF_it == tok) - mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, "it"); - return(ROFF_IGN); } @@ -1098,8 +1152,8 @@ roff_line_ignore(ROFF_ARGS) static enum rofferr roff_cond(ROFF_ARGS) { - int sv; - enum roffrule rule; + + roffnode_push(r, tok, NULL, ln, ppos); /* * An `.el' has no conditional body: it will consume the value @@ -1109,31 +1163,11 @@ roff_cond(ROFF_ARGS) * If we're not an `el', however, then evaluate the conditional. */ - rule = ROFF_el == tok ? + r->last->rule = ROFF_el == tok ? (r->rstackpos < 0 ? ROFFRULE_DENY : r->rstack[r->rstackpos--]) : roff_evalcond(*bufp, &pos); - sv = pos; - while (' ' == (*bufp)[pos]) - pos++; - - /* - * Roff is weird. If we have just white-space after the - * conditional, it's considered the BODY and we exit without - * really doing anything. Warn about this. It's probably - * wrong. - */ - - if ('\0' == (*bufp)[pos] && sv != pos) { - mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL); - return(ROFF_IGN); - } - - roffnode_push(r, tok, NULL, ln, ppos); - - r->last->rule = rule; - /* * An if-else will put the NEGATION of the current evaluated * conditional into the stack of rules. @@ -1156,28 +1190,39 @@ roff_cond(ROFF_ARGS) r->last->rule = ROFFRULE_DENY; /* - * Determine scope. If we're invoked with "\{" trailing the - * conditional, then we're in a multiline scope. Else our scope - * expires on the next line. + * Determine scope. + * If there is nothing on the line after the conditional, + * not even whitespace, use next-line scope. */ - r->last->endspan = 1; + if ('\0' == (*bufp)[pos]) { + r->last->endspan = 2; + goto out; + } + + while (' ' == (*bufp)[pos]) + pos++; + + /* An opening brace requests multiline scope. */ if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) { r->last->endspan = -1; pos += 2; + goto out; } /* - * If there are no arguments on the line, the next-line scope is - * assumed. + * Anything else following the conditional causes + * single-line scope. Warn if the scope contains + * nothing but trailing whitespace. */ if ('\0' == (*bufp)[pos]) - return(ROFF_IGN); + mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL); - /* Otherwise re-run the roff parser after recalculating. */ + r->last->endspan = 1; +out: *offs = pos; return(ROFF_RERUN); } @@ -1272,6 +1317,57 @@ roff_rm(ROFF_ARGS) return(ROFF_IGN); } +/* ARGSUSED */ +static enum rofferr +roff_it(ROFF_ARGS) +{ + char *cp; + size_t len; + int iv; + + /* Parse the number of lines. */ + cp = *bufp + pos; + len = strcspn(cp, " \t"); + cp[len] = '\0'; + if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) { + mandoc_msg(MANDOCERR_NUMERIC, r->parse, + ln, ppos, *bufp + 1); + return(ROFF_IGN); + } + cp += len + 1; + + /* Arm the input line trap. */ + roffit_lines = iv; + roffit_macro = mandoc_strdup(cp); + return(ROFF_IGN); +} + +/* ARGSUSED */ +static enum rofferr +roff_Dd(ROFF_ARGS) +{ + const char *const *cp; + + if (MPARSE_MDOC != r->parsetype) + for (cp = __mdoc_reserved; *cp; cp++) + roff_setstr(r, *cp, NULL, 0); + + return(ROFF_CONT); +} + +/* ARGSUSED */ +static enum rofferr +roff_TH(ROFF_ARGS) +{ + const char *const *cp; + + if (MPARSE_MDOC != r->parsetype) + for (cp = __man_reserved; *cp; cp++) + roff_setstr(r, *cp, NULL, 0); + + return(ROFF_CONT); +} + /* ARGSUSED */ static enum rofferr roff_TE(ROFF_ARGS) @@ -1352,21 +1448,38 @@ roff_EN(ROFF_ARGS) static enum rofferr roff_TS(ROFF_ARGS) { - struct tbl_node *t; + struct tbl_node *tbl; if (r->tbl) { mandoc_msg(MANDOCERR_SCOPEBROKEN, r->parse, ln, ppos, NULL); tbl_end(&r->tbl); } - t = tbl_alloc(ppos, ln, r->parse); + tbl = tbl_alloc(ppos, ln, r->parse); if (r->last_tbl) - r->last_tbl->next = t; + r->last_tbl->next = tbl; else - r->first_tbl = r->last_tbl = t; + r->first_tbl = r->last_tbl = tbl; + + r->tbl = r->last_tbl = tbl; + return(ROFF_IGN); +} + +/* ARGSUSED */ +static enum rofferr +roff_cc(ROFF_ARGS) +{ + const char *p; + + p = *bufp + pos; + + if ('\0' == *p || '.' == (r->control = *p++)) + r->control = 0; + + if ('\0' != *p) + mandoc_msg(MANDOCERR_ARGCOUNT, r->parse, ln, ppos, NULL); - r->tbl = r->last_tbl = t; return(ROFF_IGN); } @@ -1766,3 +1879,38 @@ roff_strdup(const struct roff *r, const char *p) res[(int)ssz] = '\0'; return(res); } + +/* + * 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. + * If the control character has been set with `.cc', then let that grain + * precedence. + * This is slighly contrary to groff, where using the non-breaking + * control character when `cc' has been invoked will cause the + * non-breaking macro contents to be printed verbatim. + */ +int +roff_getcontrol(const struct roff *r, const char *cp, int *ppos) +{ + int pos; + + pos = *ppos; + + if (0 != r->control && cp[pos] == r->control) + pos++; + else if (0 != r->control) + return(0); + else 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); +} diff --git a/contrib/mdocml/st.in b/contrib/mdocml/st.in index 3ba41dd359..bedc6a6e4d 100644 --- a/contrib/mdocml/st.in +++ b/contrib/mdocml/st.in @@ -1,4 +1,4 @@ -/* $Id: st.in,v 1.19 2012/02/26 21:47:09 schwarze Exp $ */ +/* $Id: st.in,v 1.20 2013/06/19 21:20:27 schwarze Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -35,16 +35,19 @@ LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)") LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)") LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)") LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)") -LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1\\(rq)") -LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1\\(rq)") -LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1\\(rq)") -LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1\\(rq)") -LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)") +LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)") +LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)") +LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)") +LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)") +LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)") +LINE("-p1003.1j-2000", "IEEE Std 1003.1j-2000 (\\(lqPOSIX.1j\\(rq)") +LINE("-p1003.1q-2000", "IEEE Std 1003.1q-2000 (\\(lqPOSIX.1q\\(rq)") +LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)") LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)") 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("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(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, Amendment 1\\(rq)") diff --git a/contrib/mdocml/tbl.3 b/contrib/mdocml/tbl.3 new file mode 100644 index 0000000000..05e423fe54 --- /dev/null +++ b/contrib/mdocml/tbl.3 @@ -0,0 +1,295 @@ +.\" $Id: tbl.3,v 1.1 2013/06/01 05:44:39 schwarze Exp $ +.\" +.\" Copyright (c) 2013 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 $Mdocdate: June 1 2013 $ +.Dt TBL 3 +.Os +.Sh NAME +.Nm tbl_alloc , +.Nm tbl_read , +.Nm tbl_restart , +.Nm tbl_span , +.Nm tbl_end , +.Nm tbl_free +.Nd roff table parser library for mandoc +.Sh SYNOPSIS +.In mandoc.h +.In libmandoc.h +.In libroff.h +.Ft struct tbl_node * +.Fo tbl_alloc +.Fa "int pos" +.Fa "int line" +.Fa "struct mparse *parse" +.Fc +.Ft enum rofferr +.Fo tbl_read +.Fa "struct tbl_node *tbl" +.Fa "int ln" +.Fa "const char *p" +.Fa "int offs" +.Fc +.Ft void +.Fo tbl_restart +.Fa "int line" +.Fa "int pos" +.Fa "struct tbl_node *tbl" +.Fc +.Ft const struct tbl_span * +.Fo tbl_span +.Fa "struct tbl_node *tbl" +.Fc +.Ft void +.Fo tbl_end +.Fa "struct tbl_node **tblp" +.Fc +.Ft void +.Fo tbl_free +.Fa "struct tbl_node *tbl" +.Fc +.Sh DESCRIPTION +This library is tightly integrated into the +.Xr mandoc 1 +utility and not designed for stand-alone use. +The present manual is intended as a reference for developers working on +.Xr mandoc 1 . +.Ss Data structures +Unless otherwise noted, all of the following data structures are defined in +.In mandoc.h +and are deleted in +.Fn tbl_free . +.Bl -tag -width Ds +.It Vt struct tbl_node +This structure describes a complete table. +It is defined in +.In libroff.h , +created in +.Fn tbl_alloc , +and stored in the members +.Va first_tbl , +.Va last_tbl , +and +.Va tbl +of +.Vt struct roff Bq Pa roff.c . +.It Vt struct tbl_opts +This structure describes the options of one table. +It is used as a substructure of +.Vt struct tbl_node +and thus created and deleted together with it. +It is filled in +.Fn tbl_options . +.It Vt struct tbl_head +This structure describes one layout column in a table, +in particular the vertical line to its left. +It is allocated and filled in +.Fn cell_alloc Bq Pa tbl_layout.c +and referenced from the +.Va first_head +and +.Va last_head +members of +.Vt struct tbl_node . +.It Vt struct tbl_row +This structure describes one layout line in a table +by maintaining a list of all the cells in that line. +It is allocated and filled in +.Fn row Bq Pa tbl_layout.c +and referenced from the +.Va layout +member of +.Vt struct tbl_node . +.It Vt struct tbl_cell +This structure describes one layout cell in a table, +in particular its alignment, membership in spans, and +usage for lines. +It is allocated and filled in +.Fn cell_alloc Bq Pa tbl_layout.c +and referenced from the +.Va first +and +.Va last +members of +.Vt struct tbl_row . +.It Vt struct tbl_span +This structure describes one data line in a table +by maintaining a list of all data cells in that line +or by specifying that it is a horizontal line. +It is allocated and filled in +.Fn newspan Bq Pa tbl_data.c +which is called from +.Fn tbl_data +and referenced from the +.Va first_span , +.Va current_span , +and +.Va last_span +members of +.Vt struct tbl_node , +and from the +.Va span +members of +.Vt struct man_node +and +.Vt struct mdoc_node +from +.In man.h +and +.In mdoc.h . +.It Vt struct tbl_dat +This structure describes one data cell in a table by specifying +whether it contains a line or data, whether it spans additional +layout cells, and by storing the data. +It is allocated and filled in +.Fn data +and referenced from the +.Va first +and +.Va last +members of +.Vt struct tbl_span . +.El +.Ss Interface functions +The following functions are implemented in +.Pa tbl.c , +and all callers in +.Pa roff.c . +.Bl -tag -width Ds +.It Fn tbl_alloc +Allocates, initializes, and returns a new +.Vt struct tbl_node . +Called from +.Fn roff_TS . +.It Fn tbl_read +Dispatches to +.Fn tbl_option , +.Fn tbl_layout , +.Fn tbl_cdata , +and +.Fn tbl_data , +see below. +Called from +.Fn roff_parseln . +.It Fn tbl_restart +Resets the +.Va part +member of +.Vt struct tbl_node +to +.Dv TBL_PART_LAYOUT . +Called from +.Fn roff_T_ . +.It Fn tbl_span +On the first call, return the first +.Vt struct tbl_span ; +for later calls, return the next one or +.Dv NULL . +Called from +.Fn roff_span . +.It Fn tbl_end +Flags the last span as +.Dv TBL_SPAN_LAST +and clears the pointer passed as an argment. +Called from +.Fn roff_TE +and +.Fn roff_endparse . +.It Fn tbl_free +Frees the specified +.Vt struct tbl_node +and all the tbl_row, tbl_cell, tbl_span, tbl_dat and tbl_head structures +referenced from it. +Called from +.Fn roff_free +and +.Fn roff_reset . +.El +.Ss Private functions +.Bl -tag -width Ds +.It Ft int Fn tbl_options "struct tbl_node *tbl" "int ln" "const char *p" +Parses the options line into +.Vt struct tbl_opts . +Implemented in +.Pa tbl_opts.c , +called from +.Fn tbl_read . +.It Ft int Fn tbl_layout "struct tbl_node *tbl" "int ln" "const char *p" +Allocates and fills one +.Vt struct tbl_head +for each layout column, one +.Vt struct tbl_row +for each layout line, and one +.Vt struct tbl_cell +for each layout cell. +Implemented in +.Pa tbl_layout.c , +called from +.Fn tbl_read . +.It Ft int Fn tbl_data "struct tbl_node *tbl" "int ln" "const char *p" +Allocates one +.Vt struct tbl_span +for each data line and calls +.Fn data +on that line. +Implemented in +.Pa tbl_data.c , +called from +.Fn tbl_read . +.It Ft int Fn tbl_cdata "struct tbl_node *tbl" "int ln" "const char *p" +Continues parsing a data line: +When finding +.Sq T} , +switches back to +.Dv TBL_PART_DATA +mode and calls +.Fn data +if there are more data cells on the line. +Otherwise, appends the data to the current data cell. +Implemented in +.Pa tbl_data.c , +called from +.Fn tbl_read . +.It Xo +.Ft int +.Fo data +.Fa "struct tbl_node *tbl" +.Fa "struct tbl_span *dp" +.Fa "int ln" +.Fa "const char *p" +.Fa "int *pos" +.Fc +.Xc +Parses one data cell into one +.Vt struct tbl_dat . +Implemented in +.Pa tbl_data.c , +called from +.Fn tbl_data +and +.Fn tbl_cdata . +.El +.Sh SEE ALSO +.Xr mandoc 1 , +.Xr mandoc 3 , +.Xr tbl 7 +.Sh AUTHORS +.An -nosplit +The +.Nm tbl +library was written by +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv +with contributions from +.An Ingo Schwarze Aq Mt schwarze@openbsd.org . diff --git a/contrib/mdocml/tbl.7 b/contrib/mdocml/tbl.7 index ea3d2ba3a8..d4c829bfdd 100644 --- a/contrib/mdocml/tbl.7 +++ b/contrib/mdocml/tbl.7 @@ -1,4 +1,4 @@ -.\" $Id: tbl.7,v 1.16 2011/09/03 00:29:21 kristaps Exp $ +.\" $Id: tbl.7,v 1.18 2013/09/16 22:39:19 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 3 2011 $ +.Dd $Mdocdate: September 16 2013 $ .Dt TBL 7 .Os .Sh NAME @@ -69,13 +69,6 @@ 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 @@ -344,5 +337,4 @@ utility. This .Nm reference was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . diff --git a/contrib/mdocml/tbl.c b/contrib/mdocml/tbl.c index b3d651be07..b244ac80ac 100644 --- a/contrib/mdocml/tbl.c +++ b/contrib/mdocml/tbl.c @@ -1,4 +1,4 @@ -/* $Id: tbl.c,v 1.26 2011/07/25 15:37:00 kristaps Exp $ */ +/* $Id: tbl.c,v 1.27 2013/05/31 22:08:09 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -72,21 +72,21 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs) struct tbl_node * 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->parse = parse; - p->part = TBL_PART_OPTS; - p->opts.tab = '\t'; - p->opts.linesize = 12; - p->opts.decimal = '.'; - return(p); + struct tbl_node *tbl; + + tbl = mandoc_calloc(1, sizeof(struct tbl_node)); + tbl->line = line; + tbl->pos = pos; + tbl->parse = parse; + tbl->part = TBL_PART_OPTS; + tbl->opts.tab = '\t'; + tbl->opts.linesize = 12; + tbl->opts.decimal = '.'; + return(tbl); } void -tbl_free(struct tbl_node *p) +tbl_free(struct tbl_node *tbl) { struct tbl_row *rp; struct tbl_cell *cp; @@ -94,8 +94,8 @@ tbl_free(struct tbl_node *p) struct tbl_dat *dp; struct tbl_head *hp; - while (NULL != (rp = p->first_row)) { - p->first_row = rp->next; + while (NULL != (rp = tbl->first_row)) { + tbl->first_row = rp->next; while (rp->first) { cp = rp->first; rp->first = cp->next; @@ -104,8 +104,8 @@ tbl_free(struct tbl_node *p) free(rp); } - while (NULL != (sp = p->first_span)) { - p->first_span = sp->next; + while (NULL != (sp = tbl->first_span)) { + tbl->first_span = sp->next; while (sp->first) { dp = sp->first; sp->first = dp->next; @@ -116,12 +116,12 @@ tbl_free(struct tbl_node *p) free(sp); } - while (NULL != (hp = p->first_head)) { - p->first_head = hp->next; + while (NULL != (hp = tbl->first_head)) { + tbl->first_head = hp->next; free(hp); } - free(p); + free(tbl); } void diff --git a/contrib/mdocml/tbl_data.c b/contrib/mdocml/tbl_data.c index 129695d8bb..7413aa2d83 100644 --- a/contrib/mdocml/tbl_data.c +++ b/contrib/mdocml/tbl_data.c @@ -1,4 +1,4 @@ -/* $Id: tbl_data.c,v 1.24 2011/03/20 16:02:05 kristaps Exp $ */ +/* $Id: tbl_data.c,v 1.27 2013/06/01 04:56:50 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -49,13 +49,11 @@ data(struct tbl_node *tbl, struct tbl_span *dp, cp = dp->layout->first; /* - * Skip over spanners and vertical lines to data formats, since + * Skip over spanners, since * we want to match data with data layout cells in the header. */ - while (cp && (TBL_CELL_VERT == cp->pos || - TBL_CELL_DVERT == cp->pos || - TBL_CELL_SPAN == cp->pos)) + while (cp && TBL_CELL_SPAN == cp->pos) cp = cp->next; /* @@ -104,7 +102,7 @@ data(struct tbl_node *tbl, struct tbl_span *dp, if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) { tbl->part = TBL_PART_CDATA; - return(0); + return(1); } assert(*pos - sv >= 0); @@ -187,7 +185,7 @@ newspan(struct tbl_node *tbl, int line, struct tbl_row *rp) dp = mandoc_calloc(1, sizeof(struct tbl_span)); dp->line = line; - dp->tbl = &tbl->opts; + dp->opts = &tbl->opts; dp->layout = rp; dp->head = tbl->first_head; diff --git a/contrib/mdocml/tbl_html.c b/contrib/mdocml/tbl_html.c index 8e7dc05de0..6b8ced716b 100644 --- a/contrib/mdocml/tbl_html.c +++ b/contrib/mdocml/tbl_html.c @@ -1,4 +1,4 @@ -/* $Id: tbl_html.c,v 1.9 2011/09/18 14:14:15 schwarze Exp $ */ +/* $Id: tbl_html.c,v 1.10 2012/05/27 17:54:54 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -119,20 +119,12 @@ print_tbl(struct html *h, const struct tbl_span *sp) 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; + if (NULL == dp) break; - } + if (TBL_CELL_DOWN != dp->layout->pos) + if (dp->string) + print_text(h, dp->string); + dp = dp->next; } break; } diff --git a/contrib/mdocml/tbl_layout.c b/contrib/mdocml/tbl_layout.c index 7601f146ca..6cce977fa2 100644 --- a/contrib/mdocml/tbl_layout.c +++ b/contrib/mdocml/tbl_layout.c @@ -1,6 +1,7 @@ -/* $Id: tbl_layout.c,v 1.22 2011/09/18 14:14:15 schwarze Exp $ */ +/* $Id: tbl_layout.c,v 1.23 2012/05/27 17:54:54 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2012 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 @@ -51,8 +52,7 @@ static const struct tbl_phrase keys[KEYS_MAX] = { { '^', TBL_CELL_DOWN }, { '-', TBL_CELL_HORIZ }, { '_', TBL_CELL_HORIZ }, - { '=', TBL_CELL_DHORIZ }, - { '|', TBL_CELL_VERT } + { '=', TBL_CELL_DHORIZ } }; static int mods(struct tbl_node *, struct tbl_cell *, @@ -60,10 +60,8 @@ static int mods(struct tbl_node *, struct tbl_cell *, static int cell(struct tbl_node *, struct tbl_row *, int, const char *, int *); static void row(struct tbl_node *, int, const char *, int *); -static struct tbl_cell *cell_alloc(struct tbl_node *, - struct tbl_row *, enum tbl_cellt); -static void head_adjust(const struct tbl_cell *, - struct tbl_head *); +static struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *, + enum tbl_cellt, int vert); static int mods(struct tbl_node *tbl, struct tbl_cell *cp, @@ -80,10 +78,6 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp, case (TBL_CELL_HORIZ): /* FALLTHROUGH */ case (TBL_CELL_DHORIZ): - /* FALLTHROUGH */ - case (TBL_CELL_VERT): - /* FALLTHROUGH */ - case (TBL_CELL_DVERT): return(1); default: break; @@ -214,10 +208,17 @@ static int cell(struct tbl_node *tbl, struct tbl_row *rp, int ln, const char *p, int *pos) { - int i; + int vert, i; enum tbl_cellt c; - /* Parse the column position (`r', `R', `|', ...). */ + /* Handle vertical lines. */ + + for (vert = 0; '|' == p[*pos]; ++*pos) + vert++; + while (' ' == p[*pos]) + (*pos)++; + + /* Parse the column position (`c', `l', `r', ...). */ for (i = 0; i < KEYS_MAX; i++) if (tolower((unsigned char)p[*pos]) == keys[i].name) @@ -246,8 +247,6 @@ cell(struct tbl_node *tbl, struct tbl_row *rp, 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, @@ -270,25 +269,16 @@ cell(struct tbl_node *tbl, struct tbl_row *rp, (*pos)++; - /* Extra check for the double-vertical. */ - - if (TBL_CELL_VERT == c && '|' == p[*pos]) { - (*pos)++; - c = TBL_CELL_DVERT; - } - /* Disallow adjacent spacers. */ - if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) && - (TBL_CELL_VERT == rp->last->pos || - TBL_CELL_DVERT == rp->last->pos)) { + if (vert > 2) { mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos - 1, NULL); return(0); } /* Allocate cell then parse its modifiers. */ - return(mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos)); + return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos)); } @@ -308,11 +298,11 @@ row: /* */ rp = mandoc_calloc(1, sizeof(struct tbl_row)); - if (tbl->last_row) { + if (tbl->last_row) tbl->last_row->next = rp; - tbl->last_row = rp; - } else - tbl->last_row = tbl->first_row = rp; + else + tbl->first_row = rp; + tbl->last_row = rp; cell: while (isspace((unsigned char)p[*pos])) @@ -357,7 +347,8 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p) } static struct tbl_cell * -cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos) +cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos, + int vert) { struct tbl_cell *p, *pp; struct tbl_head *h, *hp; @@ -365,108 +356,35 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos) p = mandoc_calloc(1, sizeof(struct tbl_cell)); if (NULL != (pp = rp->last)) { - rp->last->next = p; - rp->last = p; - } else - rp->last = rp->first = p; + pp->next = p; + h = pp->head->next; + } else { + rp->first = p; + h = tbl->first_head; + } + rp->last = p; p->pos = pos; + p->vert = vert; - /* - * This is a little bit complicated. Here we determine the - * header the corresponds to a cell. We add headers dynamically - * when need be or re-use them, otherwise. As an example, given - * the following: - * - * 1 c || l - * 2 | c | l - * 3 l l - * 3 || c | l |. - * - * We first add the new headers (as there are none) in (1); then - * in (2) we insert the first spanner (as it doesn't match up - * with the header); then we re-use the prior data headers, - * skipping over the spanners; then we re-use everything and add - * a last spanner. Note that VERT headers are made into DVERT - * ones. - */ - - h = pp ? pp->head->next : tbl->first_head; + /* Re-use header. */ if (h) { - /* Re-use data header. */ - if (TBL_HEAD_DATA == h->pos && - (TBL_CELL_VERT != p->pos && - TBL_CELL_DVERT != p->pos)) { - p->head = h; - return(p); - } - - /* Re-use spanner header. */ - if (TBL_HEAD_DATA != h->pos && - (TBL_CELL_VERT == p->pos || - TBL_CELL_DVERT == p->pos)) { - head_adjust(p, h); - p->head = h; - return(p); - } - - /* Right-shift headers with a new spanner. */ - if (TBL_HEAD_DATA == h->pos && - (TBL_CELL_VERT == p->pos || - TBL_CELL_DVERT == p->pos)) { - hp = mandoc_calloc(1, sizeof(struct tbl_head)); - hp->ident = tbl->opts.cols++; - hp->prev = h->prev; - if (h->prev) - h->prev->next = hp; - if (h == tbl->first_head) - tbl->first_head = hp; - h->prev = hp; - hp->next = h; - head_adjust(p, hp); - p->head = hp; - return(p); - } - - if (NULL != (h = h->next)) { - head_adjust(p, h); - p->head = h; - return(p); - } - - /* Fall through to default case... */ + p->head = h; + return(p); } hp = mandoc_calloc(1, sizeof(struct tbl_head)); hp->ident = tbl->opts.cols++; + hp->vert = vert; if (tbl->last_head) { hp->prev = tbl->last_head; tbl->last_head->next = hp; - tbl->last_head = hp; } else - tbl->last_head = tbl->first_head = hp; + tbl->first_head = hp; + tbl->last_head = hp; - head_adjust(p, hp); p->head = hp; return(p); } - -static void -head_adjust(const struct tbl_cell *cellp, struct tbl_head *head) -{ - if (TBL_CELL_VERT != cellp->pos && - TBL_CELL_DVERT != cellp->pos) { - head->pos = TBL_HEAD_DATA; - return; - } - - if (TBL_CELL_VERT == cellp->pos) - if (TBL_HEAD_DVERT != head->pos) - head->pos = TBL_HEAD_VERT; - - if (TBL_CELL_DVERT == cellp->pos) - head->pos = TBL_HEAD_DVERT; -} - diff --git a/contrib/mdocml/tbl_term.c b/contrib/mdocml/tbl_term.c index f1928f02cb..e8411ffece 100644 --- a/contrib/mdocml/tbl_term.c +++ b/contrib/mdocml/tbl_term.c @@ -1,7 +1,7 @@ -/* $Id: tbl_term.c,v 1.21 2011/09/20 23:05:49 schwarze Exp $ */ +/* $Id: tbl_term.c,v 1.25 2013/05/31 21:37:17 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2012 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 @@ -31,14 +31,14 @@ 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 *, +static void tbl_data(struct termp *, const struct tbl_opts *, const struct tbl_dat *, const struct roffcol *); 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 *, +static void tbl_number(struct termp *, const struct tbl_opts *, const struct tbl_dat *, const struct roffcol *); static void tbl_hrule(struct termp *, const struct tbl_span *); @@ -96,16 +96,16 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) /* Horizontal frame at the start of boxed tables. */ if (TBL_SPAN_FIRST & sp->flags) { - if (TBL_OPT_DBOX & sp->tbl->opts) + if (TBL_OPT_DBOX & sp->opts->opts) tbl_hframe(tp, sp, 1); - if (TBL_OPT_DBOX & sp->tbl->opts || - TBL_OPT_BOX & sp->tbl->opts) + if (TBL_OPT_DBOX & sp->opts->opts || + TBL_OPT_BOX & sp->opts->opts) tbl_hframe(tp, sp, 0); } /* Vertical frame at the start of each row. */ - if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts) + if (TBL_OPT_BOX & sp->opts->opts || TBL_OPT_DBOX & sp->opts->opts) term_word(tp, TBL_SPAN_HORIZ == sp->pos || TBL_SPAN_DHORIZ == sp->pos ? "+" : "|"); @@ -126,49 +126,23 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) 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. - */ + /* Separate columns. */ - if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos) - tbl_char(tp, ASCII_NBRSP, 1); + if (NULL != hp->prev) + tbl_vrule(tp, hp); col = &tp->tbl.cols[hp->ident]; - tbl_data(tp, sp->tbl, dp, col); - - /* 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); + tbl_data(tp, sp->opts, dp, col); /* * Go to the next data cell and assign the @@ -185,7 +159,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) /* Vertical frame at the end of each row. */ - if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts) + if (TBL_OPT_BOX & sp->opts->opts || TBL_OPT_DBOX & sp->opts->opts) term_word(tp, TBL_SPAN_HORIZ == sp->pos || TBL_SPAN_DHORIZ == sp->pos ? "+" : " |"); term_flushln(tp); @@ -196,11 +170,15 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) */ if (TBL_SPAN_LAST & sp->flags) { - if (TBL_OPT_DBOX & sp->tbl->opts || - TBL_OPT_BOX & sp->tbl->opts) + if (TBL_OPT_DBOX & sp->opts->opts || + TBL_OPT_BOX & sp->opts->opts) { tbl_hframe(tp, sp, 0); - if (TBL_OPT_DBOX & sp->tbl->opts) + tp->skipvsp = 1; + } + if (TBL_OPT_DBOX & sp->opts->opts) { tbl_hframe(tp, sp, 1); + tp->skipvsp = 2; + } assert(tp->tbl.cols); free(tp->tbl.cols); tp->tbl.cols = NULL; @@ -222,17 +200,14 @@ 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++; - } + + /* Account for leading blanks. */ + if (hp->prev) + width += 2 - hp->vert; + + /* Account for trailing blank. */ + width++; + return(width); } @@ -250,10 +225,11 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp) if (TBL_SPAN_DHORIZ == sp->pos) c = '='; - for (hp = sp->head; hp; hp = hp->next) - tbl_char(tp, - TBL_HEAD_DATA == hp->pos ? c : '+', - tbl_rulewidth(tp, hp)); + for (hp = sp->head; hp; hp = hp->next) { + if (hp->prev && hp->vert) + tbl_char(tp, '+', hp->vert); + tbl_char(tp, c, tbl_rulewidth(tp, hp)); + } } /* @@ -268,16 +244,17 @@ tbl_hframe(struct termp *tp, const struct tbl_span *sp, int outer) const struct tbl_head *hp; term_word(tp, "+"); - for (hp = sp->head; hp; hp = hp->next) - tbl_char(tp, - outer || TBL_HEAD_DATA == hp->pos ? '-' : '+', - tbl_rulewidth(tp, hp)); + for (hp = sp->head; hp; hp = hp->next) { + if (hp->prev && hp->vert) + tbl_char(tp, (outer ? '-' : '+'), hp->vert); + tbl_char(tp, '-', tbl_rulewidth(tp, hp)); + } term_word(tp, "+"); term_flushln(tp); } static void -tbl_data(struct termp *tp, const struct tbl *tbl, +tbl_data(struct termp *tp, const struct tbl_opts *opts, const struct tbl_dat *dp, const struct roffcol *col) { @@ -323,7 +300,7 @@ tbl_data(struct termp *tp, const struct tbl *tbl, tbl_literal(tp, dp, col); break; case (TBL_CELL_NUMBER): - tbl_number(tp, tbl, dp, col); + tbl_number(tp, opts, dp, col); break; case (TBL_CELL_DOWN): tbl_char(tp, ASCII_NBRSP, col->width); @@ -338,16 +315,11 @@ static void tbl_vrule(struct termp *tp, const struct tbl_head *hp) { - switch (hp->pos) { - case (TBL_HEAD_VERT): - term_word(tp, "|"); - break; - case (TBL_HEAD_DVERT): - term_word(tp, "||"); - break; - default: - break; - } + tbl_char(tp, ASCII_NBRSP, 1); + if (0 < hp->vert) + tbl_char(tp, '|', hp->vert); + if (2 > hp->vert) + tbl_char(tp, ASCII_NBRSP, 2 - hp->vert); } static void @@ -369,11 +341,19 @@ static void tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { - size_t len, padl, padr; + struct tbl_head *hp; + size_t width, len, padl, padr; + int spans; assert(dp->string); len = term_strlen(tp, dp->string); - padr = col->width > len ? col->width - len : 0; + + hp = dp->layout->head->next; + width = col->width; + for (spans = dp->spans; spans--; hp = hp->next) + width += tp->tbl.cols[hp->ident].width + 3; + + padr = width > len ? width - len : 0; padl = 0; switch (dp->layout->pos) { @@ -401,7 +381,7 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp, } static void -tbl_number(struct termp *tp, const struct tbl *tbl, +tbl_number(struct termp *tp, const struct tbl_opts *opts, const struct tbl_dat *dp, const struct roffcol *col) { @@ -419,12 +399,12 @@ tbl_number(struct termp *tp, const struct tbl *tbl, sz = term_strlen(tp, dp->string); - buf[0] = tbl->decimal; + buf[0] = opts->decimal; buf[1] = '\0'; psz = term_strlen(tp, buf); - if (NULL != (cp = strrchr(dp->string, tbl->decimal))) { + if (NULL != (cp = strrchr(dp->string, opts->decimal))) { buf[1] = '\0'; for (ssz = 0, i = 0; cp != &dp->string[i]; i++) { buf[0] = dp->string[i]; diff --git a/contrib/mdocml/term.c b/contrib/mdocml/term.c index 4ca15ed6fa..16def7879f 100644 --- a/contrib/mdocml/term.c +++ b/contrib/mdocml/term.c @@ -1,7 +1,7 @@ -/* $Id: term.c,v 1.201 2011/09/21 09:57:13 schwarze Exp $ */ +/* $Id: term.c,v 1.210 2013/08/21 21:20:40 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -33,7 +33,8 @@ #include "term.h" #include "main.h" -static void adjbuf(struct termp *p, int); +static size_t cond_width(const struct termp *, int, int *); +static void adjbuf(struct termp *p, size_t); static void bufferc(struct termp *, char); static void encode(struct termp *, const char *, size_t); static void encode1(struct termp *, int); @@ -104,14 +105,15 @@ term_end(struct termp *p) void term_flushln(struct termp *p) { - int i; /* current input position in p->buf */ + size_t i; /* current input position in p->buf */ + int ntab; /* number of tabs to prepend */ size_t vis; /* current visual position on output */ size_t vbl; /* number of blanks to prepend to output */ size_t vend; /* end of word visual position on output */ size_t bp; /* visual right border position */ size_t dv; /* temporary for visual pos calculations */ - int j; /* temporary loop index for p->buf */ - int jhy; /* last hyph before overflow w/r/t j */ + size_t j; /* temporary loop index for p->buf */ + size_t jhy; /* last hyph before overflow w/r/t j */ size_t maxvis; /* output position of visible boundary */ size_t mmax; /* used in calculating bp */ @@ -143,10 +145,12 @@ term_flushln(struct termp *p) * Handle literal tab characters: collapse all * subsequent tabs into a single huge set of spaces. */ + ntab = 0; while (i < p->col && '\t' == p->buf[i]) { vend = (vis / p->tabwidth + 1) * p->tabwidth; vbl += vend - vis; vis = vend; + ntab++; i++; } @@ -158,7 +162,7 @@ term_flushln(struct termp *p) */ for (j = i, jhy = 0; j < p->col; j++) { - if ((j && ' ' == p->buf[j]) || '\t' == p->buf[j]) + if (' ' == p->buf[j] || '\t' == p->buf[j]) break; /* Back over the the last printed character. */ @@ -191,6 +195,11 @@ term_flushln(struct termp *p) } else vbl = p->offset; + /* use pending tabs on the new line */ + + if (0 < ntab) + vbl += ntab * p->tabwidth; + /* Remove the p->overstep width. */ bp += (size_t)p->overstep; @@ -207,7 +216,7 @@ term_flushln(struct termp *p) j = i; while (' ' == p->buf[i]) i++; - dv = (size_t)(i - j) * (*p->width)(p, ' '); + dv = (i - j) * (*p->width)(p, ' '); vbl += dv; vend += dv; break; @@ -264,16 +273,11 @@ term_flushln(struct termp *p) p->overstep = (int)(vis - maxvis + (*p->width)(p, ' ')); /* - * Behave exactly the same way as groff: * If we have overstepped the margin, temporarily move * it to the right and flag the rest of the line to be * shorter. - * If we landed right at the margin, be happy. - * If we are one step before the margin, temporarily - * move it one step LEFT and flag the rest of the line - * to be longer. */ - if (p->overstep < -1) + if (p->overstep < 0) p->overstep = 0; return; @@ -316,7 +320,10 @@ term_vspace(struct termp *p) term_newln(p); p->viscol = 0; - (*p->endline)(p); + if (0 < p->skipvsp) + p->skipvsp--; + else + (*p->endline)(p); } void @@ -369,7 +376,7 @@ void term_fontpopq(struct termp *p, const void *key) { - while (p->fonti >= 0 && key != &p->fontq[p->fonti]) + while (p->fonti >= 0 && key < (void *)(p->fontq + p->fonti)) p->fonti--; assert(p->fonti >= 0); } @@ -399,14 +406,14 @@ term_word(struct termp *p, const char *word) if ( ! (TERMP_NOSPACE & p->flags)) { if ( ! (TERMP_KEEP & p->flags)) { - if (TERMP_PREKEEP & p->flags) - p->flags |= TERMP_KEEP; bufferc(p, ' '); if (TERMP_SENTENCE & p->flags) bufferc(p, ' '); } else bufferc(p, ASCII_NBRSP); } + if (TERMP_PREKEEP & p->flags) + p->flags |= TERMP_KEEP; if ( ! (p->flags & TERMP_NONOSPACE)) p->flags &= ~TERMP_NOSPACE; @@ -416,12 +423,17 @@ term_word(struct termp *p, const char *word) p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM); while ('\0' != *word) { - if ((ssz = strcspn(word, "\\")) > 0) + if ('\\' != *word) { + if (TERMP_SKIPCHAR & p->flags) { + p->flags &= ~TERMP_SKIPCHAR; + word++; + continue; + } + ssz = strcspn(word, "\\"); encode(p, word, ssz); - - word += (int)ssz; - if ('\\' != *word) + word += (int)ssz; continue; + } word++; esc = mandoc_escape(&word, &seq, &sz); @@ -468,6 +480,9 @@ term_word(struct termp *p, const char *word) case (ESCAPE_FONTITALIC): term_fontrepl(p, TERMFONT_UNDER); break; + case (ESCAPE_FONTBI): + term_fontrepl(p, TERMFONT_BI); + break; case (ESCAPE_FONT): /* FALLTHROUGH */ case (ESCAPE_FONTROMAN): @@ -477,9 +492,14 @@ term_word(struct termp *p, const char *word) term_fontlast(p); break; case (ESCAPE_NOSPACE): - if ('\0' == *word) + if (TERMP_SKIPCHAR & p->flags) + p->flags &= ~TERMP_SKIPCHAR; + else if ('\0' == *word) p->flags |= TERMP_NOSPACE; break; + case (ESCAPE_SKIPCHAR): + p->flags |= TERMP_SKIPCHAR; + break; default: break; } @@ -487,7 +507,7 @@ term_word(struct termp *p, const char *word) } static void -adjbuf(struct termp *p, int sz) +adjbuf(struct termp *p, size_t sz) { if (0 == p->maxcols) @@ -495,8 +515,7 @@ adjbuf(struct termp *p, int sz) while (sz >= p->maxcols) p->maxcols <<= 2; - p->buf = mandoc_realloc - (p->buf, sizeof(int) * (size_t)p->maxcols); + p->buf = mandoc_realloc(p->buf, sizeof(int) * p->maxcols); } static void @@ -519,31 +538,39 @@ encode1(struct termp *p, int c) { enum termfont f; - if (p->col + 4 >= p->maxcols) - adjbuf(p, p->col + 4); + if (TERMP_SKIPCHAR & p->flags) { + p->flags &= ~TERMP_SKIPCHAR; + return; + } + + if (p->col + 6 >= p->maxcols) + adjbuf(p, p->col + 6); f = term_fonttop(p); - if (TERMFONT_NONE == f) { - p->buf[p->col++] = c; - return; - } else if (TERMFONT_UNDER == f) { + if (TERMFONT_UNDER == f || TERMFONT_BI == f) { p->buf[p->col++] = '_'; - } else - p->buf[p->col++] = c; - - p->buf[p->col++] = 8; + p->buf[p->col++] = 8; + } + if (TERMFONT_BOLD == f || TERMFONT_BI == f) { + if (ASCII_HYPH == c) + 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, len; + size_t i; - /* LINTED */ - len = sz; + if (TERMP_SKIPCHAR & p->flags) { + p->flags &= ~TERMP_SKIPCHAR; + return; + } /* * Encode and buffer a string of characters. If the current @@ -551,35 +578,25 @@ encode(struct termp *p, const char *word, size_t sz) * character by character. */ - if (TERMFONT_NONE == (f = term_fonttop(p))) { - if (p->col + len >= p->maxcols) - adjbuf(p, p->col + len); - for (i = 0; i < len; i++) + if (TERMFONT_NONE == term_fonttop(p)) { + if (p->col + sz >= p->maxcols) + adjbuf(p, p->col + sz); + for (i = 0; i < sz; i++) p->buf[p->col++] = word[i]; return; } /* Pre-buffer, assuming worst-case. */ - if (p->col + 1 + (len * 3) >= p->maxcols) - adjbuf(p, p->col + 1 + (len * 3)); + if (p->col + 1 + (sz * 5) >= p->maxcols) + adjbuf(p, p->col + 1 + (sz * 5)); - 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[p->col++] = '_'; - else if (ASCII_HYPH == word[i]) - p->buf[p->col++] = '-'; + for (i = 0; i < sz; i++) { + if (ASCII_HYPH == word[i] || + isgraph((unsigned char)word[i])) + encode1(p, word[i]); else p->buf[p->col++] = word[i]; - - p->buf[p->col++] = 8; - p->buf[p->col++] = word[i]; } } @@ -590,12 +607,22 @@ term_len(const struct termp *p, size_t sz) return((*p->width)(p, ' ') * sz); } +static size_t +cond_width(const struct termp *p, int c, int *skip) +{ + + if (*skip) { + (*skip) = 0; + return(0); + } else + return((*p->width)(p, c)); +} size_t term_strlen(const struct termp *p, const char *cp) { size_t sz, rsz, i; - int ssz, c; + int ssz, skip, c; const char *seq, *rhs; enum mandoc_esc esc; static const char rej[] = { '\\', ASCII_HYPH, ASCII_NBRSP, '\0' }; @@ -607,10 +634,11 @@ term_strlen(const struct termp *p, const char *cp) */ sz = 0; + skip = 0; while ('\0' != *cp) { rsz = strcspn(cp, rej); for (i = 0; i < rsz; i++) - sz += (*p->width)(p, *cp++); + sz += cond_width(p, *cp++, &skip); c = 0; switch (*cp) { @@ -627,14 +655,14 @@ term_strlen(const struct termp *p, const char *cp) (seq + 1, ssz - 1); if ('\0' == c) break; - sz += (*p->width)(p, c); + sz += cond_width(p, c, &skip); continue; case (ESCAPE_SPECIAL): c = mchars_spec2cp (p->symtab, seq, ssz); if (c <= 0) break; - sz += (*p->width)(p, c); + sz += cond_width(p, c, &skip); continue; default: break; @@ -644,12 +672,12 @@ term_strlen(const struct termp *p, const char *cp) switch (esc) { case (ESCAPE_UNICODE): - sz += (*p->width)(p, '?'); + sz += cond_width(p, '?', &skip); break; case (ESCAPE_NUMBERED): c = mchars_num2char(seq, ssz); if ('\0' != c) - sz += (*p->width)(p, c); + sz += cond_width(p, c, &skip); break; case (ESCAPE_SPECIAL): rhs = mchars_spec2str @@ -661,6 +689,9 @@ term_strlen(const struct termp *p, const char *cp) rhs = seq; rsz = ssz; break; + case (ESCAPE_SKIPCHAR): + skip = 1; + break; default: break; } @@ -668,15 +699,20 @@ term_strlen(const struct termp *p, const char *cp) if (NULL == rhs) break; + if (skip) { + skip = 0; + break; + } + for (i = 0; i < rsz; i++) sz += (*p->width)(p, *rhs++); break; case (ASCII_NBRSP): - sz += (*p->width)(p, ' '); + sz += cond_width(p, ' ', &skip); cp++; break; case (ASCII_HYPH): - sz += (*p->width)(p, '-'); + sz += cond_width(p, '-', &skip); cp++; break; default: diff --git a/contrib/mdocml/term.h b/contrib/mdocml/term.h index 56d076e54a..6aa9934e95 100644 --- a/contrib/mdocml/term.h +++ b/contrib/mdocml/term.h @@ -1,4 +1,4 @@ -/* $Id: term.h,v 1.90 2011/12/04 23:10:52 schwarze Exp $ */ +/* $Id: term.h,v 1.94 2013/08/21 21:20:40 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -37,6 +37,7 @@ enum termfont { TERMFONT_NONE = 0, TERMFONT_BOLD, TERMFONT_UNDER, + TERMFONT_BI, TERMFONT__MAX }; @@ -57,12 +58,13 @@ struct termp { size_t defrmargin; /* Right margin of the device. */ size_t rmargin; /* Current right margin. */ size_t maxrmargin; /* Max right margin. */ - int maxcols; /* Max size of buf. */ + size_t maxcols; /* Max size of buf. */ size_t offset; /* Margin offest. */ size_t tabwidth; /* Distance of tab positions. */ - int col; /* Bytes in buf. */ + size_t col; /* Bytes in buf. */ size_t viscol; /* Chars on current line. */ int overstep; /* See termp_flushln(). */ + int skipvsp; /* Vertical space to skip. */ int flags; #define TERMP_SENTENCE (1 << 1) /* Space before a sentence. */ #define TERMP_NOSPACE (1 << 2) /* No space before words. */ @@ -77,6 +79,7 @@ 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. */ +#define TERMP_SKIPCHAR (1 << 16) /* Skip the next character. */ int *buf; /* Output buffer. */ enum termenc enc; /* Type of encoding. */ struct mchars *symtab; /* Encoded-symbol table. */ diff --git a/contrib/mdocml/term_ascii.c b/contrib/mdocml/term_ascii.c index 2f114786f6..cb7ac29405 100644 --- a/contrib/mdocml/term_ascii.c +++ b/contrib/mdocml/term_ascii.c @@ -1,4 +1,4 @@ -/* $Id: term_ascii.c,v 1.20 2011/12/04 23:10:52 schwarze Exp $ */ +/* $Id: term_ascii.c,v 1.21 2013/06/01 14:27:20 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -73,7 +73,6 @@ ascii_init(enum termenc enc, char *outopts) struct termp *p; p = mandoc_calloc(1, sizeof(struct termp)); - p->enc = enc; p->tabwidth = 5; p->defrmargin = 78; @@ -93,7 +92,7 @@ ascii_init(enum termenc enc, char *outopts) if (TERMENC_ASCII != enc) { v = TERMENC_LOCALE == enc ? setlocale(LC_ALL, "") : - setlocale(LC_CTYPE, "UTF-8"); + setlocale(LC_CTYPE, "en_US.UTF-8"); if (NULL != v && MB_CUR_MAX > 1) { p->enc = enc; p->advance = locale_advance; diff --git a/contrib/mdocml/test-betoh64.c b/contrib/mdocml/test-betoh64.c new file mode 100644 index 0000000000..d33f401784 --- /dev/null +++ b/contrib/mdocml/test-betoh64.c @@ -0,0 +1,18 @@ +#include <sys/types.h> + +#if defined(__linux__) +# include <endian.h> +#elif defined(__APPLE__) +# include <libkern/OSByteOrder.h> +#else +# include <sys/endian.h> +#endif + +int +main(int argc, char **argv) +{ + u_int64_t hostorder; + u_int64_t bigendian = 1; + hostorder = betoh64(bigendian); + return 0; +} diff --git a/contrib/mdocml/test-mmap.c b/contrib/mdocml/test-mmap.c index db8fd8732e..1e0f94229e 100644 --- a/contrib/mdocml/test-mmap.c +++ b/contrib/mdocml/test-mmap.c @@ -5,6 +5,6 @@ int main(int argc, char **argv) { - mmap(0, 0, PROT_READ, MAP_FILE|MAP_SHARED, -1, 0); + mmap(0, 0, PROT_READ, MAP_SHARED, -1, 0); return 0; } diff --git a/contrib/mdocml/tree.c b/contrib/mdocml/tree.c index 1430c737e0..08a76b80ed 100644 --- a/contrib/mdocml/tree.c +++ b/contrib/mdocml/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.47 2011/09/18 14:14:15 schwarze Exp $ */ +/* $Id: tree.c,v 1.49 2013/09/15 17:33:57 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -58,13 +58,11 @@ print_mdoc(const struct mdoc_node *n, int indent) { const char *p, *t; int i, j; - size_t argc, sz; - char **params; + size_t argc; struct mdoc_argv *argv; argv = NULL; - argc = sz = 0; - params = NULL; + argc = 0; t = p = NULL; switch (n->type) { @@ -161,11 +159,11 @@ print_mdoc(const struct mdoc_node *n, int indent) if (argv[i].sz > 0) printf(" ]"); } - - for (i = 0; i < (int)sz; i++) - printf(" [%s]", params[i]); - printf(" %d:%d\n", n->line, n->pos); + putchar(' '); + if (MDOC_LINE & n->flags) + putchar('*'); + printf("%d:%d\n", n->line, n->pos); } if (n->child) diff --git a/contrib/mdocml/whatis.1 b/contrib/mdocml/whatis.1 index 500b0b6c34..b8071a450d 100644 --- a/contrib/mdocml/whatis.1 +++ b/contrib/mdocml/whatis.1 @@ -1,6 +1,6 @@ -.\" $Id: whatis.1,v 1.8 2012/03/24 01:54:43 kristaps Exp $ +.\" $Id: whatis.1,v 1.7.2.2 2013/10/05 01:25:20 schwarze Exp $ .\" -.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> +.\" 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,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 24 2012 $ +.Dd $Mdocdate: October 5 2013 $ .Dt WHATIS 1 .Os .Sh NAME @@ -23,8 +23,8 @@ .Sh SYNOPSIS .Nm .Op Fl C Ar file -.Op Fl M Ar manpath -.Op Fl m Ar manpath +.Op Fl M Ar path +.Op Fl m Ar path .Op Fl S Ar arch .Op Fl s Ar section .Ar name ... @@ -47,8 +47,6 @@ searches for .Xr mandocdb 8 databases in the default paths stipulated by .Xr man 1 . -If standard output is a TTY, a result may be selected from a list and -its manual displayed with the pager. .Pp The options are as follows: .Bl -tag -width Ds @@ -58,16 +56,16 @@ Specify an alternative configuration in .Xr man.conf 5 format. -.It Fl M Ar manpath +.It Fl M Ar path Use the colon-separated -.Ar manpath +.Ar 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 +.It Fl m Ar path Prepend the colon-separated -.Ar manpath +.Ar path to the list of paths searched for .Xr mandocdb 8 databases. @@ -97,21 +95,13 @@ If an architecture is specified for the manual, it is displayed as .Pp .D1 title(cat/arch) \- description .Pp -If on a TTY, results are prefixed with a numeric identifier. +Resulting manuals may be accessed as .Pp -.D1 [index] title(cat) \- description +.Dl $ man \-s sec title .Pp -One may choose a manual be entering the index at the prompt. -Valid choices are displayed using -.Ev MANPAGER , -or failing that , -.Ev PAGER -or just -.Xr more 1 . -Source pages are formatted with -.Xr mandoc 1 ; -preformatted pages with -.Xr cat 1 . +If an architecture is specified in the output, use +.Pp +.Dl $ man \-s sec \-S arch title .Pp .Nm is identical to running @@ -121,14 +111,6 @@ as follows: .Dl $ apropos -- -i 'Nm~[[:<:]]term[[:>:]]' .Sh ENVIRONMENT .Bl -tag -width Ds -.It Ev MANPAGER -Default pager for manuals. -If this is unset, falls back to -.Ev Pager . -.It Ev PAGER -The second choice for a manual pager. -If this is unset, use -.Xr more 1 . .It Ev MANPATH Colon-separated paths modifying the default list of paths searched for manual databases. @@ -149,11 +131,11 @@ 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 +.It Pa mandoc.db name of the .Xr mandocdb 8 keyword database -.It Pa whatis.index +.It Pa mandoc.index name of the .Xr mandocdb 8 filename database @@ -186,5 +168,4 @@ wrote the original .Nm in 1979. The current version was written by -.An Kristaps Dzonsons , -.Mt kristaps@bsd.lv . +.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv . -- 2.41.0