Import mdocml-1.12.2
authorFranco Fichtner <franco@lastsummer.de>
Sun, 6 Oct 2013 07:47:07 +0000 (09:47 +0200)
committerFranco Fichtner <franco@lastsummer.de>
Sun, 6 Oct 2013 07:47:07 +0000 (09:47 +0200)
73 files changed:
contrib/mdocml/Makefile
contrib/mdocml/NEWS [new file with mode: 0644]
contrib/mdocml/TODO
contrib/mdocml/apropos.1
contrib/mdocml/apropos.c
contrib/mdocml/apropos_db.c
contrib/mdocml/arch.in
contrib/mdocml/catman.c
contrib/mdocml/cgi.c
contrib/mdocml/chars.c
contrib/mdocml/chars.in
contrib/mdocml/config.h.post
contrib/mdocml/demandoc.1
contrib/mdocml/demandoc.c
contrib/mdocml/eqn.7
contrib/mdocml/gmdiff [new file with mode: 0644]
contrib/mdocml/html.c
contrib/mdocml/html.h
contrib/mdocml/index.sgml
contrib/mdocml/libman.h
contrib/mdocml/libmandoc.h
contrib/mdocml/libmdoc.h
contrib/mdocml/libroff.h
contrib/mdocml/main.c
contrib/mdocml/man.7
contrib/mdocml/man.c
contrib/mdocml/man.cgi.7
contrib/mdocml/man.h
contrib/mdocml/man_html.c
contrib/mdocml/man_macro.c
contrib/mdocml/man_term.c
contrib/mdocml/man_validate.c
contrib/mdocml/mandoc.1
contrib/mdocml/mandoc.3
contrib/mdocml/mandoc.c
contrib/mdocml/mandoc.h
contrib/mdocml/mandoc_char.7
contrib/mdocml/mandocdb.8
contrib/mdocml/mandocdb.c
contrib/mdocml/mandocdb.h
contrib/mdocml/manpath.c
contrib/mdocml/manpath.h
contrib/mdocml/mdoc.7
contrib/mdocml/mdoc.c
contrib/mdocml/mdoc.h
contrib/mdocml/mdoc_argv.c
contrib/mdocml/mdoc_html.c
contrib/mdocml/mdoc_macro.c
contrib/mdocml/mdoc_man.c
contrib/mdocml/mdoc_term.c
contrib/mdocml/mdoc_validate.c
contrib/mdocml/out.c
contrib/mdocml/preconv.1
contrib/mdocml/preconv.c
contrib/mdocml/predefs.in
contrib/mdocml/read.c
contrib/mdocml/roff.7
contrib/mdocml/roff.c
contrib/mdocml/st.in
contrib/mdocml/tbl.3 [new file with mode: 0644]
contrib/mdocml/tbl.7
contrib/mdocml/tbl.c
contrib/mdocml/tbl_data.c
contrib/mdocml/tbl_html.c
contrib/mdocml/tbl_layout.c
contrib/mdocml/tbl_term.c
contrib/mdocml/term.c
contrib/mdocml/term.h
contrib/mdocml/term_ascii.c
contrib/mdocml/test-betoh64.c [new file with mode: 0644]
contrib/mdocml/test-mmap.c
contrib/mdocml/tree.c
contrib/mdocml/whatis.1

index 304237b..044d087 100644 (file)
@@ -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 (file)
index 0000000..784b89b
--- /dev/null
@@ -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/ .
index a870136..0aebbd3 100644 (file)
@@ -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
 
 --- 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 <mail at andreasvoegele dot com>
   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)
   .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 <http://docbook.sf.net/>
-  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 <iam at juanfra dot info>
+           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
 
 - 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
 
 
 --- 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
       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.
   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 Authentication<tab>Key Length
   ought to render "Key Length" with emphasis, too,
   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
 ************************************************************************
   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
   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).
   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,
   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
-    <blank line>
-    .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
   in dig(1).
 
 ************************************************************************
-* error reporting issues
-************************************************************************
-
-- .TP directly followed by .RS gives an assertion.
-
-************************************************************************
 * performance issues
 ************************************************************************
 
index 7dea132..5adfeb6 100644 (file)
@@ -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 <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 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 .
index 9c3cae9..f5d1425 100644 (file)
@@ -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 <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #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));
 }
index 8aea771..61002ee 100644 (file)
@@ -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 <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -19,6 +19,8 @@
 #include "config.h"
 #endif
 
+#include <sys/param.h>
+
 #include <assert.h>
 #include <fcntl.h>
 #include <regex.h>
@@ -35,6 +37,7 @@
 # include <libkern/OSByteOrder.h>
 # include <db.h>
 #else
+# include <sys/endian.h>
 # include <db.h>
 #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))
index 5113446..d0c445f 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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")
index 1d313ea..c755d27 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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;
 
index 2f5870f..6d40fcd 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -18,7 +18,6 @@
 #include "config.h"
 #endif
 
-#include <sys/param.h>
 #include <sys/wait.h>
 
 #include <assert.h>
@@ -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))) {
index ce03347..3ad1f57 100644 (file)
@@ -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 <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -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;
index a4c45b3..cc6549e 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -42,6 +42,7 @@ CHAR("&",                     "",             0)
 CHAR("^",                      "",             0)
 CHAR("|",                      "",             0)
 CHAR("}",                      "",             0)
+CHAR("t",                      "",             0)
 
 /* Accents. */
 CHAR("a\"",                    "\"",           779)
index 39da2b2..cee82aa 100644 (file)
 #  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
index 845b9c1..84571ba 100644 (file)
@@ -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 <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 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 .
index 2474a35..aad4208 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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)
index f86b9c4..dcbad41 100644 (file)
@@ -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 <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 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 (file)
index 0000000..a5bca9d
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+# 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.
+
+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
index 326df03..9d28b42 100644 (file)
@@ -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 <kristaps@bsd.lv>
- * 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
@@ -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);
@@ -338,6 +372,33 @@ print_encode(struct html *h, const char *p, int norecurse)
                        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. */
                        c = mchars_num2uc(seq + 1, len - 1);
@@ -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)) {
index 6096070..894cfc4 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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., <PRE>) 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 */
index 4386a9e..e716635 100644 (file)
@@ -25,7 +25,7 @@
                        pages whilst providing token support for <I>man</I>.
                </P>
                <P>
-                       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, <A
                        CLASS="external" HREF="http://www.isc.org/software/license">ISC</A>-licensed, fast and regular).
                </P>
                        usually taken by existing utilities.
                </P>
                <H2>
-                       <A NAME="binaries">Binaries</A>
-               </H2>
-               <P>
-                       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 <A CLASS="external" HREF="http://www.mingw.org">MingW</A> for the 32-bit (i686) and
-                       64-bit (x86_64) architectures.
-               </P>
-               <H2>
                        Downstream
                </H2>
                <P>
                                <TR>
                                        <TD>DragonFly BSD</TD>
                                        <TD>
-                                       <A HREF="http://gitweb.dragonflybsd.org/dragonfly.git/tree/HEAD:/usr.bin/mandoc" CLASS="external">usr.bin/mandoc</A>
+                                       <A HREF="http://gitweb.dragonflybsd.org/dragonfly.git/tree/HEAD:/contrib/mdocml" CLASS="external">contrib/mdocml</A> (1.12.1 sources)
+                                       <A HREF="http://gitweb.dragonflybsd.org/dragonfly.git/tree/HEAD:/lib/libmandoc" CLASS="external">lib/libmandoc</A>
+                                       <A HREF="http://gitweb.dragonflybsd.org/dragonfly.git/tree/HEAD:/usr.bin/mandoc" CLASS="external">usr.bin/mandoc</A> (build system)
+                                       </TD>
+                               </TR>
+                               <TR>
+                                       <TD>FreeBSD 10.0, -CURRENT</TD>
+                                       <TD>
+                                       <A HREF="http://svnweb.freebsd.org/base/head/contrib/mdocml/" CLASS="external">contrib/mdocml</A> (1.12.1 sources)
+                                       <A HREF="http://svnweb.freebsd.org/base/head/usr.bin/mandoc/" CLASS="external">usr.bin/mandoc</A> (build system)
                                        </TD>
                                </TR>
                                <TR>
-                                       <TD>FreeBSD</TD>
+                                       <TD>FreeBSD 9.x, 8.x</TD>
                                        <TD>
-                                       <A HREF="http://www.freebsd.org/cgi/cvsweb.cgi/ports/textproc/mdocml/" CLASS="external">ports/textproc/mdocml</A>
+                                       <A HREF="http://svnweb.freebsd.org/ports/textproc/mdocml/" CLASS="external">ports/textproc/mdocml</A> (1.12.1 port)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD>NetBSD</TD>
                                        <TD>
-                                       <A HREF="http://cvsweb.netbsd.org/bsdweb.cgi/src/external/bsd/mdocml/" CLASS="external">src/external/bsd/mdocml</A>
+                                       <A HREF="http://cvsweb.netbsd.org/bsdweb.cgi/src/external/bsd/mdocml/" CLASS="external">src/external/bsd/mdocml</A> (1.12.1 sources plus patches and build system)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD>OpenBSD</TD>
                                        <TD>
-                                       <A HREF="http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/mandoc/" CLASS="external">src/usr.bin/mandoc</A> 
+                                       <A HREF="http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/mandoc/" CLASS="external">src/usr.bin/mandoc</A> (1.12.2 sources and build system)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD>pkgsrc</TD>
                                        <TD>
-                                       <A HREF="http://pkgsrc.se/textproc/mdocml" CLASS="external">textproc/mdocml</A> 
+                                       <A HREF="http://pkgsrc.se/textproc/mdocml" CLASS="external">textproc/mdocml</A> (1.12.0 port)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD>Minix3</TD>
                                        <TD>
-                                       <A HREF="http://git.minix3.org/?p=minix.git;a=tree;f=external/bsd/mdocml" CLASS="external">external/bsd/mdocml</A>
+                                       <A HREF="http://git.minix3.org/?p=minix.git;a=tree;f=external/bsd/mdocml" CLASS="external">external/bsd/mdocml</A> (1.10.9 sources and build system)
+                                       </TD>
+                               </TR>
+                               <TR>
+                                       <TD>Alpine Linux</TD>
+                                       <TD>
+                                       <A HREF="http://git.alpinelinux.org/cgit/aports/tree/main/mdocml" CLASS="external">aports/main/mdocml</A> (1.12.1 port)
                                        </TD>
                                </TR>
                        </TBODY>
                                        <TD VALIGN="top"><A HREF="apropos.1.html">apropos(1)</A></TD>
                                        <TD VALIGN="top">
                                                search the manual page database
-                                                       (<A HREF="apropos.1.txt">text</A> | 
-                                                       <A HREF="apropos.1.xhtml">xhtml</A> |
-                                                       <A HREF="apropos.1.pdf">pdf</A> |
-                                                       <A HREF="apropos.1.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="demandoc.1.html">demandoc(1)</A></TD>
                                        <TD VALIGN="top">
                                                emit only text of UNIX manuals
-                                                       (<A HREF="demandoc.1.txt">text</A> | 
-                                                       <A HREF="demandoc.1.xhtml">xhtml</A> |
-                                                       <A HREF="demandoc.1.pdf">pdf</A> |
-                                                       <A HREF="demandoc.1.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="mandoc.1.html">mandoc(1)</A></TD>
                                        <TD VALIGN="top">
                                                format and display UNIX manuals
-                                                       (<A HREF="mandoc.1.txt">text</A> | 
-                                                       <A HREF="mandoc.1.xhtml">xhtml</A> |
-                                                       <A HREF="mandoc.1.pdf">pdf</A> |
-                                                       <A HREF="mandoc.1.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="preconv.1.html">preconv(1)</A></TD>
                                        <TD VALIGN="top">
                                                recode multibyte UNIX manuals
-                                                       (<A HREF="preconv.1.txt">text</A> | 
-                                                       <A HREF="preconv.1.xhtml">xhtml</A> |
-                                                       <A HREF="preconv.1.pdf">pdf</A> |
-                                                       <A HREF="preconv.1.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="whatis.1.html">whatis(1)</A></TD>
                                        <TD VALIGN="top">
                                                search the manual page database
-                                                       (<A HREF="whatis.1.txt">text</A> | 
-                                                       <A HREF="whatis.1.xhtml">xhtml</A> |
-                                                       <A HREF="whatis.1.pdf">pdf</A> |
-                                                       <A HREF="whatis.1.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="mandoc.3.html">mandoc(3)</A></TD>
                                        <TD VALIGN="top">
                                                mandoc macro compiler library
-                                                       (<A HREF="mandoc.3.txt">text</A> | 
-                                                       <A HREF="mandoc.3.xhtml">xhtml</A> |
-                                                       <A HREF="mandoc.3.pdf">pdf</A> |
-                                                       <A HREF="mandoc.3.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
-                                       <TD VALIGN="top"><A HREF="man.7.html">man(7)</A></TD>
+                                       <TD VALIGN="top"><A HREF="tbl.3.html">tbl(3)</A></TD>
                                        <TD VALIGN="top">
-                                               man language reference
-                                                       (<A HREF="man.7.txt">text</A> | 
-                                                       <A HREF="man.7.xhtml">xhtml</A> |
-                                                       <A HREF="man.7.pdf">pdf</A> |
-                                                       <A HREF="man.7.ps">ps</A>)
+                                               roff table parser library for mandoc
                                        </TD>
                                </TR>
                                <TR>
-                                       <TD VALIGN="top"><A HREF="man.cgi.7.html">man.cgi(7)</A></TD>
+                                       <TD VALIGN="top"><A HREF="eqn.7.html">eqn(7)</A></TD>
                                        <TD VALIGN="top">
-                                               cgi for manpage query and display
-                                                       (<A HREF="man.cgi.7.txt">text</A> | 
-                                                       <A HREF="man.cgi.7.xhtml">xhtml</A> |
-                                                       <A HREF="man.cgi.7.pdf">pdf</A> |
-                                                       <A HREF="man.cgi.7.ps">ps</A>)
+                                               eqn-mandoc language reference
                                        </TD>
                                </TR>
                                <TR>
-                                       <TD VALIGN="top"><A HREF="eqn.7.html">eqn(7)</A></TD>
+                                       <TD VALIGN="top"><A HREF="man.7.html">man(7)</A></TD>
                                        <TD VALIGN="top">
-                                               eqn-mandoc language reference
-                                                       (<A HREF="eqn.7.txt">text</A> | 
-                                                       <A HREF="eqn.7.xhtml">xhtml</A> |
-                                                       <A HREF="eqn.7.pdf">pdf</A> |
-                                                       <A HREF="eqn.7.ps">ps</A>)
+                                               man language reference
+                                       </TD>
+                               </TR>
+                               <TR>
+                                       <TD VALIGN="top"><A HREF="man.cgi.7.html">man.cgi(7)</A></TD>
+                                       <TD VALIGN="top">
+                                               cgi for manpage query and display
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="mandoc_char.7.html">mandoc_char(7)</A></TD>
                                        <TD VALIGN="top">
                                                mandoc special characters
-                                                       (<A HREF="mandoc_char.7.txt">text</A> | 
-                                                       <A HREF="mandoc_char.7.xhtml">xhtml</A> |
-                                                       <A HREF="mandoc_char.7.pdf">pdf</A> |
-                                                       <A HREF="mandoc_char.7.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="mdoc.7.html">mdoc(7)</A></TD>
                                        <TD VALIGN="top">
                                                mdoc language reference
-                                                       (<A HREF="mdoc.7.txt">text</A> | 
-                                                       <A HREF="mdoc.7.xhtml">xhtml</A> |
-                                                       <A HREF="mdoc.7.pdf">pdf</A> |
-                                                       <A HREF="mdoc.7.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="roff.7.html">roff(7)</A></TD>
                                        <TD VALIGN="top">
                                                roff-mandoc language reference
-                                                       (<A HREF="roff.7.txt">text</A> | 
-                                                       <A HREF="roff.7.xhtml">xhtml</A> |
-                                                       <A HREF="roff.7.pdf">pdf</A> |
-                                                       <A HREF="roff.7.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="tbl.7.html">tbl(7)</A></TD>
                                        <TD VALIGN="top">
                                                tbl-mandoc language reference
-                                                       (<A HREF="tbl.7.txt">text</A> | 
-                                                       <A HREF="tbl.7.xhtml">xhtml</A> |
-                                                       <A HREF="tbl.7.pdf">pdf</A> |
-                                                       <A HREF="tbl.7.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="catman.8.html">catman(8)</A></TD>
                                        <TD VALIGN="top">
                                                update a man.cgi manpage cache
-                                                       (<A HREF="catman.8.txt">text</A> | 
-                                                       <A HREF="catman.8.xhtml">xhtml</A> |
-                                                       <A HREF="catman.8.pdf">pdf</A> |
-                                                       <A HREF="catman.8.ps">ps</A>)
                                        </TD>
                                </TR>
                                <TR>
                                        <TD VALIGN="top"><A HREF="mandocdb.8.html">mandocdb(8)</A></TD>
                                        <TD VALIGN="top">
                                                index UNIX manuals
-                                                       (<A HREF="mandocdb.8.txt">text</A> | 
-                                                       <A HREF="mandocdb.8.xhtml">xhtml</A> |
-                                                       <A HREF="mandocdb.8.pdf">pdf</A> |
-                                                       <A HREF="mandocdb.8.ps">ps</A>)
                                        </TD>
                                </TR>
                        </TBODY>
                        <A NAME="news">News</A>
                </H1>
                <P CLASS="news">
+                       02-10-2013: version 1.12.2
+               </P>
+               <P>
+                       The <A HREF="mdoc.7.html">mdoc(7)</A> to <A HREF="man.7.html">man(7)</A> converter,
+                       to be called as <CODE>mandoc -Tman</CODE>, is now fully functional.
+               </P>
+               <P>
+                       The <A HREF="mandoc.1.html">mandoc(1)</A> utility now supports the <CODE>-Ios</CODE> (default operating system)
+                       input option, and the <CODE>-Tutf8</CODE> output mode now actually works.
+               </P>
+               <P>
+                       The <A HREF="mandocdb.8.html">mandocdb(8)</A> utility no longer truncates existing databases when starting to build new ones,
+                       but only replaces them when the build actually succeeds.
+               </P>
+               <P>
+                       The <A HREF="man.7.html">man(7)</A> parser now supports the <EM>PD</EM> macro (paragraph distance),
+                       and (for GNU man-ext compatibility only) <EM>EX</EM> (example block) and <EM>EE</EM> (example end).
+                       Plus several bugfixes regarding indentation, line breaks, and vertical spacing,
+                       and regarding <EM>RS</EM> following <EM>TP</EM>.
+               </P>
+               <P>
+                       The <A HREF="roff.7.html">roff(7)</A> parser now supports the <EM>\f(BI</EM> (bold+italic) font escape,
+                       the <EM>\z</EM> (zero cursor advance) escape and the <EM>cc</EM> (change control character)
+                       and <EM>it</EM> (input line trap) requests.
+                       Plus bugfixes regarding the <EM>\t</EM> (tab) escape, nested escape sequences, and conditional requests.
+               </P>
+               <P>
+                       In <A HREF="mdoc.7.html">mdoc(7)</A>, several bugs were fixed related to UTF-8 output of quoting enclosures,
+                       delimiter handling, list indentation and horizontal and vertical spacing,
+                       formatting of the <EM>Lk</EM>, <EM>%U</EM>, and <EM>%C</EM> macros,
+                       plus some bugfixes related to the handling of syntax errors like badly nested font blocks,
+                       stray <EM>Ta</EM> macros outside column lists, unterminated <EM>It Xo</EM> blocks,
+                       and non-text children of <EM>Nm</EM> blocks.
+               </P>
+               <P>
+                       In <A HREF="tbl.7.html">tbl(7)</A>, the width of horizontal spans and the vertical spacing around tables was corrected,
+                       and in <A HREF="man.7.html">man(7)</A> files, a crash was fixed that was triggered by some particular unclosed <EM>T{</EM> macros.
+               </P>
+               <P>
+                       For mandoc developers, we now provide a <A HREF="tbl.3.html">tbl(3)</A> library manual and <CODE>gmdiff</CODE>,
+                       a very small, very simplistic groff-versus-mandoc output comparison tool.
+               </P>
+               <P>
+                       See <A HREF="NEWS">NEWS</A> for historical notes.
+               </P>
+               <P CLASS="news">
                        23-03-2011: version 1.12.1
                </P>
                <P>
                        <SMALL>
                                Copyright &#169; 2008&#8211;2011 
                                <A CLASS="external" HREF="http://kristaps.bsd.lv">Kristaps Dzonsons</A>, 
-                               $Date: 2012/03/24 02:07:32 $
+                               &#169; 2013 Ingo Schwarze,
+                               $Date: 2013/10/05 14:05:09 $
                        </SMALL>
                </P>
        </BODY>
index 4bc5128..f2ba6a1 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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);
index de42288..9b3ffee 100644 (file)
@@ -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 <kristaps@bsd.lv>
+ * Copyright (c) 2009, 2010, 2011, 2012 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
@@ -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 *, 
index af17292..8a389a4 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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 *);
index 0bdd5a3..5b84c5f 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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;
index fec83fb..7e5c7a9 100644 (file)
@@ -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 <kristaps@bsd.lv>
- * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * 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
@@ -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);
index 1715a7c..f2f4d1d 100644 (file)
@@ -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 <kristaps@bsd.lv>
-.\" Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" 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
@@ -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
index 1bea561..24ffc63 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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);
 }
index b7afd84..ec927ca 100644 (file)
@@ -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
index 4fc3934..e85da9a 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -52,6 +52,8 @@ enum  mant {
        MAN_in,
        MAN_ft,
        MAN_OP,
+       MAN_EX,
+       MAN_EE,
        MAN_MAX
 };
 
index a76ea2d..100188b 100644 (file)
@@ -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 <kristaps@bsd.lv>
+ * Copyright (c) 2008-2012 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
@@ -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
index 4bbbc4f..6631f14 100644 (file)
@@ -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 <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
@@ -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);
 }
index 69c5c95..db5719c 100644 (file)
@@ -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 <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, 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
@@ -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;
@@ -265,6 +270,21 @@ pre_literal(DECL_ARGS)
 
 /* 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)
 {
        enum termfont            font[2];
@@ -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;
index e40b089..7a9deed 100644 (file)
@@ -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 <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
@@ -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);
 }
index dbff0e3..0657bc6 100644 (file)
@@ -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 <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
@@ -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
index 4d0b20d..bc6aa90 100644 (file)
@@ -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 <kristaps@bsd.lv>
 .\" Copyright (c) 2010 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 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 .
index 604bb67..df51022 100644 (file)
@@ -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 <kristaps@bsd.lv>
- * 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
 
 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,18 +86,28 @@ 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. */
@@ -678,32 +628,6 @@ mandoc_eos(const char *p, size_t sz, int 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.
  */
index a37effc..c2406e9 100644 (file)
@@ -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 <kristaps@bsd.lv>
+ * Copyright (c) 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
@@ -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 *);
index acc1b61..23ccc0a 100644 (file)
@@ -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 <jmc@openbsd.org>
 .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -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
index cb48359..83b6a01 100644 (file)
@@ -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 <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: 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 .
index e621c1d..028377c 100644 (file)
@@ -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 <kristaps@bsd.lv>
- * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
+ * 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
@@ -19,7 +19,6 @@
 #include "config.h"
 #endif
 
-#include <sys/param.h>
 #include <sys/types.h>
 
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__sun)
 # include <endian.h>
 # include <db_185.h>
 #elif defined(__APPLE__)
 # include <libkern/OSByteOrder.h>
 # include <db.h>
 #else
+# include <sys/endian.h>
 # include <db.h>
 #endif
 
+#if defined(__sun)
+#include <sys/stat.h>
+#endif
+
 #include "man.h"
 #include "mdoc.h"
 #include "mandoc.h"
 #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<section>[/<arch>]/<title>.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: "
+   &nb