diff options
author | bapt <bapt@FreeBSD.org> | 2016-01-15 23:28:12 +0000 |
---|---|---|
committer | bapt <bapt@FreeBSD.org> | 2016-01-15 23:28:12 +0000 |
commit | e1581ec0f03f2f2c260785ce05fca5a98c8d65b4 (patch) | |
tree | ae81f04244baa70cf59bab257864c9dd79596a69 /contrib | |
parent | cb734ceab666d0372162796ee007f4777451d293 (diff) | |
parent | e15bccbf37b1a75c96083f38f1d7580cfa8aa1ea (diff) | |
download | FreeBSD-src-e1581ec0f03f2f2c260785ce05fca5a98c8d65b4.zip FreeBSD-src-e1581ec0f03f2f2c260785ce05fca5a98c8d65b4.tar.gz |
Update mandoc to 20160116
Diffstat (limited to 'contrib')
133 files changed, 7831 insertions, 6912 deletions
diff --git a/contrib/mdocml/INSTALL b/contrib/mdocml/INSTALL index eb8b5dd..085fb3e 100644 --- a/contrib/mdocml/INSTALL +++ b/contrib/mdocml/INSTALL @@ -1,4 +1,4 @@ -$Id: INSTALL,v 1.10 2015/03/09 21:00:14 schwarze Exp $ +$Id: INSTALL,v 1.13 2015/11/07 14:01:16 schwarze Exp $ About mdocml, the portable mandoc distribution ---------------------------------------------- @@ -42,6 +42,8 @@ generates. If anything looks wrong or different from what you wish, read the file "configure.local.example", create and edit a file "configure.local", and re-run "./configure" until the result seems right to you. +On Solaris 10 and earlier, you may have to run "ksh ./configure" +because the native /bin/sh lacks some POSIX features. 3. Run "make". Any POSIX-compatible make, in particular both BSD make and GNU make, @@ -82,9 +84,10 @@ manual page source. Understanding mandoc dependencies --------------------------------- -The mandoc(1), man(1), and demandoc(1) utilities have no external -dependencies, but makewhatis(8) and apropos(1) depend on the -following software: +The mandoc(1), man(1), and demandoc(1) utilities only depend +on the zlib library for decompressing gzipped manual pages, +but makewhatis(8) and apropos(1) depend on the following +additional software: 1. The SQLite database system, see <http://sqlite.org/>. The recommended version of SQLite is 3.8.4.3 or newer. The mandoc @@ -107,6 +110,11 @@ If you run into that problem, set "HAVE_FTS=0" in configure.local. If your system does not have it, the bundled compatibility version will be used, so you probably need not worry about it. +One of the chief design goals of the mandoc toolbox is to make +sure that nothing related to documentation requires C++. +Consequently, linking mandoc against any kind of C++ program +would defeat the purpose and is not supported. + Checking autoconfiguration quality ---------------------------------- diff --git a/contrib/mdocml/LICENSE b/contrib/mdocml/LICENSE index 080c04f..ad3cd4b 100644 --- a/contrib/mdocml/LICENSE +++ b/contrib/mdocml/LICENSE @@ -1,4 +1,4 @@ -$Id: LICENSE,v 1.7 2015/02/16 14:56:22 schwarze Exp $ +$Id: LICENSE,v 1.11 2015/11/07 17:58:55 schwarze Exp $ With the exceptions noted below, all code and documentation contained in the mdocml toolkit is protected by the Copyright @@ -8,10 +8,12 @@ Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org> Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> +Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org> Copyright (c) 1998, 2004, 2010 Todd C. Miller <Todd.Miller@courtesan.com> Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> Copyright (c) 2004 Ted Unangst <tedu@openbsd.org> +Copyright (c) 1994 Christos Zoulas <christos@netbsd.org> Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org> See the individual source files for information about who contributed @@ -35,13 +37,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. The following files included from outside sources are protected by -other people's Copyright and are distributed under a 3-clause BSD -license; see these individual files for details. +other people's Copyright and are distributed under various 2-clause +and 3-clause BSD licenses; see these individual files for details. -compat_fts.c, compat_fts.h, +soelim.c, soelim.1: +Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> + +compat_err.c, compat_fts.c, compat_fts.h, compat_getsubopt.c, compat_strcasestr.c, compat_strsep.c, man.1: Copyright (c) 1989,1990,1993,1994 The Regents of the University of California -compat_fgetln.c: -Copyright (c) 1998 The NetBSD Foundation, Inc. +compat_stringlist.c, compat_stringlist.h: +Copyright (c) 1994 Christos Zoulas <christos@netbsd.org> diff --git a/contrib/mdocml/Makefile b/contrib/mdocml/Makefile index d492ce7..9be2bd9 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mdocml/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.457 2015/03/13 12:35:32 schwarze Exp $ +# $Id: Makefile,v 1.480 2015/11/07 21:53:14 schwarze Exp $ # # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> # Copyright (c) 2011, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -20,36 +20,49 @@ VERSION = 1.13.3 # === LIST OF FILES ==================================================== TESTSRCS = test-dirent-namlen.c \ - test-fgetln.c \ + test-err.c \ test-fts.c \ + test-getline.c \ test-getsubopt.c \ + test-isblank.c \ + test-mkdtemp.c \ test-mmap.c \ test-ohash.c \ + test-pledge.c \ + test-progname.c \ test-reallocarray.c \ test-sqlite3.c \ test-sqlite3_errstr.c \ test-strcasestr.c \ + test-stringlist.c \ test-strlcat.c \ test-strlcpy.c \ test-strptime.c \ test-strsep.c \ test-strtonum.c \ + test-vasprintf.c \ test-wchar.c SRCS = att.c \ cgi.c \ chars.c \ - compat_fgetln.c \ + compat_err.c \ compat_fts.c \ + compat_getline.c \ compat_getsubopt.c \ + compat_isblank.c \ + compat_mkdtemp.c \ compat_ohash.c \ + compat_progname.c \ compat_reallocarray.c \ compat_sqlite3_errstr.c \ compat_strcasestr.c \ + compat_stringlist.c \ compat_strlcat.c \ compat_strlcpy.c \ compat_strsep.c \ compat_strtonum.c \ + compat_vasprintf.c \ demandoc.c \ eqn.c \ eqn_html.c \ @@ -65,6 +78,7 @@ SRCS = att.c \ man_validate.c \ mandoc.c \ mandoc_aux.c \ + mandoc_ohash.c \ mandocdb.c \ manpage.c \ manpath.c \ @@ -76,6 +90,7 @@ SRCS = att.c \ mdoc_html.c \ mdoc_macro.c \ mdoc_man.c \ + mdoc_state.c \ mdoc_term.c \ mdoc_validate.c \ msec.c \ @@ -83,7 +98,9 @@ SRCS = att.c \ preconv.c \ read.c \ roff.c \ + soelim.c \ st.c \ + tag.c \ tbl.c \ tbl_data.c \ tbl_html.c \ @@ -93,8 +110,7 @@ SRCS = att.c \ term.c \ term_ascii.c \ term_ps.c \ - tree.c \ - $(TESTSRCS) + tree.c DISTFILES = INSTALL \ LICENSE \ @@ -104,14 +120,13 @@ DISTFILES = INSTALL \ TODO \ apropos.1 \ cgi.h.example \ - chars.in \ compat_fts.h \ compat_ohash.h \ + compat_stringlist.h \ configure \ configure.local.example \ demandoc.1 \ eqn.7 \ - example.style.css \ gmdiff \ html.h \ lib.in \ @@ -121,13 +136,15 @@ DISTFILES = INSTALL \ libroff.h \ main.h \ makewhatis.8 \ - man-cgi.css \ man.1 \ man.7 \ man.cgi.8 \ + man.conf.5 \ man.h \ + manconf.h \ mandoc.1 \ mandoc.3 \ + mandoc.css \ mandoc.db.5 \ mandoc.h \ mandoc_aux.h \ @@ -136,7 +153,7 @@ DISTFILES = INSTALL \ mandoc_headers.3 \ mandoc_html.3 \ mandoc_malloc.3 \ - manpath.h \ + mandoc_ohash.h \ mansearch.3 \ mansearch.h \ mchars_alloc.3 \ @@ -146,12 +163,15 @@ DISTFILES = INSTALL \ out.h \ predefs.in \ roff.7 \ + roff.h \ + soelim.1 \ st.in \ - style.css \ + tag.h \ tbl.3 \ tbl.7 \ term.h \ - $(SRCS) + $(SRCS) \ + $(TESTSRCS) LIBMAN_OBJS = man.o \ man_hash.o \ @@ -164,6 +184,7 @@ LIBMDOC_OBJS = att.o \ mdoc_argv.o \ mdoc_hash.o \ mdoc_macro.o \ + mdoc_state.o \ mdoc_validate.o \ st.o @@ -180,21 +201,27 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ chars.o \ mandoc.o \ mandoc_aux.o \ + mandoc_ohash.o \ msec.o \ preconv.o \ read.o -COMPAT_OBJS = compat_fgetln.o \ +COMPAT_OBJS = compat_err.o \ compat_fts.o \ + compat_getline.o \ compat_getsubopt.o \ + compat_isblank.o \ + compat_mkdtemp.o \ compat_ohash.o \ + compat_progname.o \ compat_reallocarray.o \ compat_sqlite3_errstr.o \ compat_strcasestr.o \ compat_strlcat.o \ compat_strlcpy.o \ compat_strsep.o \ - compat_strtonum.o + compat_strtonum.o \ + compat_vasprintf.o MANDOC_HTML_OBJS = eqn_html.o \ html.o \ @@ -218,6 +245,7 @@ BASE_OBJS = $(MANDOC_HTML_OBJS) \ main.o \ manpath.o \ out.o \ + tag.o \ tree.o MAIN_OBJS = $(BASE_OBJS) @@ -236,10 +264,18 @@ MANPAGE_OBJS = manpage.o mansearch.o mansearch_const.o manpath.o DEMANDOC_OBJS = demandoc.o +SOELIM_OBJS = soelim.o \ + compat_err.o \ + compat_getline.o \ + compat_progname.o \ + compat_reallocarray.o \ + compat_stringlist.o + WWW_MANS = apropos.1.html \ demandoc.1.html \ man.1.html \ mandoc.1.html \ + soelim.1.html \ mandoc.3.html \ mandoc_escape.3.html \ mandoc_headers.3.html \ @@ -248,6 +284,7 @@ WWW_MANS = apropos.1.html \ mansearch.3.html \ mchars_alloc.3.html \ tbl.3.html \ + man.conf.5.html \ mandoc.db.5.html \ eqn.7.html \ man.7.html \ @@ -258,11 +295,12 @@ WWW_MANS = apropos.1.html \ makewhatis.8.html \ man.cgi.8.html \ man.h.html \ + manconf.h.html \ mandoc.h.html \ mandoc_aux.h.html \ - manpath.h.html \ mansearch.h.html \ - mdoc.h.html + mdoc.h.html \ + roff.h.html WWW_OBJS = mdocml.tar.gz \ mdocml.sha256 @@ -275,7 +313,7 @@ include Makefile.local all: base-build $(BUILD_TARGETS) Makefile.local -base-build: mandoc demandoc +base-build: mandoc demandoc soelim cgi-build: man.cgi @@ -301,33 +339,36 @@ clean: rm -f man.cgi $(CGI_OBJS) rm -f manpage $(MANPAGE_OBJS) rm -f demandoc $(DEMANDOC_OBJS) + rm -f soelim $(SOELIM_OBJS) rm -f $(WWW_MANS) $(WWW_OBJS) rm -rf *.dSYM base-install: base-build mkdir -p $(DESTDIR)$(BINDIR) - mkdir -p $(DESTDIR)$(EXAMPLEDIR) mkdir -p $(DESTDIR)$(LIBDIR) mkdir -p $(DESTDIR)$(INCLUDEDIR) mkdir -p $(DESTDIR)$(MANDIR)/man1 mkdir -p $(DESTDIR)$(MANDIR)/man3 + mkdir -p $(DESTDIR)$(MANDIR)/man5 mkdir -p $(DESTDIR)$(MANDIR)/man7 $(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR) + $(INSTALL_PROGRAM) soelim $(DESTDIR)$(BINDIR)/$(BINM_SOELIM) ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN) $(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR) - $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \ + $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h roff.h \ $(DESTDIR)$(INCLUDEDIR) $(INSTALL_MAN) mandoc.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1 + $(INSTALL_MAN) soelim.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_SOELIM).1 $(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1 $(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \ mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3 + $(INSTALL_MAN) man.conf.5 $(DESTDIR)$(MANDIR)/man5/${MANM_MANCONF}.5 $(INSTALL_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MAN}.7 $(INSTALL_MAN) mdoc.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MDOC}.7 $(INSTALL_MAN) roff.7 $(DESTDIR)$(MANDIR)/man7/${MANM_ROFF}.7 $(INSTALL_MAN) eqn.7 $(DESTDIR)$(MANDIR)/man7/${MANM_EQN}.7 $(INSTALL_MAN) tbl.7 $(DESTDIR)$(MANDIR)/man7/${MANM_TBL}.7 $(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7 - $(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR) db-install: base-build mkdir -p $(DESTDIR)$(BINDIR) @@ -354,8 +395,7 @@ cgi-install: cgi-build mkdir -p $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1 mkdir -p $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8 $(INSTALL_PROGRAM) man.cgi $(DESTDIR)$(CGIBINDIR) - $(INSTALL_DATA) example.style.css $(DESTDIR)$(HTDOCDIR)/man.css - $(INSTALL_DATA) man-cgi.css $(DESTDIR)$(HTDOCDIR) + $(INSTALL_DATA) mandoc.css $(DESTDIR)$(HTDOCDIR) $(INSTALL_MAN) apropos.1 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1/ $(INSTALL_MAN) man.cgi.8 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8/ @@ -376,13 +416,16 @@ man.cgi: $(CGI_OBJS) libmandoc.a $(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB) demandoc: $(DEMANDOC_OBJS) libmandoc.a - $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a + $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a $(DBLIB) + +soelim: $(SOELIM_OBJS) + $(CC) $(LDFLAGS) -o $@ $(SOELIM_OBJS) # --- maintainer targets --- www-install: www mkdir -p $(HTDOCDIR)/snapshots - $(INSTALL_DATA) $(WWW_MANS) style.css $(HTDOCDIR) + $(INSTALL_DATA) $(WWW_MANS) mandoc.css $(HTDOCDIR) $(INSTALL_DATA) $(WWW_OBJS) $(HTDOCDIR)/snapshots $(INSTALL_DATA) mdocml.tar.gz \ $(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz @@ -416,4 +459,4 @@ mdocml.tar.gz: $(DISTFILES) .1.1.html .3.3.html .5.5.html .7.7.html .8.8.html: mandoc ./mandoc -Thtml -Wall,stop \ - -Ostyle=style.css,man=%N.%S.html,includes=%I.html $< > $@ + -Ostyle=mandoc.css,man=%N.%S.html,includes=%I.html $< > $@ diff --git a/contrib/mdocml/Makefile.depend b/contrib/mdocml/Makefile.depend index 54af8bc..98a1928 100644 --- a/contrib/mdocml/Makefile.depend +++ b/contrib/mdocml/Makefile.depend @@ -1,51 +1,61 @@ -att.o: att.c config.h mdoc.h libmdoc.h -cgi.o: cgi.c config.h mandoc.h mandoc_aux.h main.h manpath.h mansearch.h cgi.h -chars.o: chars.c config.h mandoc.h mandoc_aux.h libmandoc.h chars.in -compat_fgetln.o: compat_fgetln.c config.h +att.o: att.c config.h roff.h mdoc.h libmdoc.h +cgi.o: cgi.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h main.h manconf.h mansearch.h cgi.h +chars.o: chars.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h libmandoc.h +compat_err.o: compat_err.c config.h compat_fts.o: compat_fts.c config.h compat_fts.h +compat_getline.o: compat_getline.c config.h compat_getsubopt.o: compat_getsubopt.c config.h +compat_isblank.o: compat_isblank.c config.h +compat_mkdtemp.o: compat_mkdtemp.c config.h compat_ohash.o: compat_ohash.c config.h compat_ohash.h +compat_progname.o: compat_progname.c config.h compat_reallocarray.o: compat_reallocarray.c config.h compat_sqlite3_errstr.o: compat_sqlite3_errstr.c config.h compat_strcasestr.o: compat_strcasestr.c config.h +compat_stringlist.o: compat_stringlist.c config.h compat_stringlist.h compat_strlcat.o: compat_strlcat.c config.h compat_strlcpy.o: compat_strlcpy.c config.h compat_strsep.o: compat_strsep.c config.h compat_strtonum.o: compat_strtonum.c config.h -demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h +compat_vasprintf.o: compat_vasprintf.c config.h +demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.h eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h -html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h main.h -lib.o: lib.c config.h mdoc.h libmdoc.h lib.in -main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h manpath.h mansearch.h -man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h -man_hash.o: man_hash.c config.h man.h libman.h -man_html.o: man_html.c config.h mandoc_aux.h man.h out.h html.h main.h -man_macro.o: man_macro.c config.h man.h mandoc.h libmandoc.h libman.h -man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h -man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h +html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h manconf.h main.h +lib.o: lib.c config.h roff.h mdoc.h libmdoc.h lib.in +main.o: main.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h +man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h +man_hash.o: man_hash.c config.h roff.h man.h libman.h +man_html.o: man_html.c config.h mandoc_aux.h roff.h man.h out.h html.h main.h +man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h +man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h main.h +man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h mandoc.o: mandoc.c config.h mandoc.h mandoc_aux.h libmandoc.h mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h -mandocdb.o: mandocdb.c config.h compat_fts.h compat_ohash.h mdoc.h man.h mandoc.h mandoc_aux.h manpath.h mansearch.h -manpage.o: manpage.c config.h manpath.h mansearch.h -manpath.o: manpath.c config.h mandoc_aux.h manpath.h -mansearch.o: mansearch.c config.h compat_ohash.h mandoc.h mandoc_aux.h manpath.h mansearch.h +mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h +mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h +manpage.o: manpage.c config.h manconf.h mansearch.h +manpath.o: manpath.c config.h mandoc_aux.h manconf.h +mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h mansearch_const.o: mansearch_const.c config.h mansearch.h -mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h -mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h -mdoc_hash.o: mdoc_hash.c config.h mdoc.h libmdoc.h -mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mdoc.h out.h html.h main.h -mdoc_macro.o: mdoc_macro.c config.h mdoc.h mandoc.h libmdoc.h libmandoc.h -mdoc_man.o: mdoc_man.c config.h mandoc.h mandoc_aux.h out.h man.h mdoc.h main.h -mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main.h -mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h +mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h +mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h +mdoc_hash.o: mdoc_hash.c config.h roff.h mdoc.h libmdoc.h +mdoc_html.o: mdoc_html.c config.h mandoc_aux.h roff.h mdoc.h out.h html.h main.h +mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h +mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h +mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h +mdoc_term.o: mdoc_term.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h term.h tag.h main.h +mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h msec.o: msec.c config.h mandoc.h libmandoc.h msec.in out.o: out.c config.h mandoc_aux.h mandoc.h out.h preconv.o: preconv.c config.h mandoc.h libmandoc.h -read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h -roff.o: roff.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h predefs.in -st.o: st.c config.h mdoc.h libmdoc.h st.in +read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h roff_int.h +roff.o: roff.c config.h mandoc.h mandoc_aux.h roff.h libmandoc.h roff_int.h libroff.h predefs.in +soelim.o: soelim.c config.h compat_stringlist.h +st.o: st.c config.h roff.h mdoc.h libmdoc.h st.in +tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h tbl_data.o: tbl_data.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h tbl_html.o: tbl_html.c config.h mandoc.h out.h html.h @@ -53,22 +63,6 @@ tbl_layout.o: tbl_layout.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h tbl_opts.o: tbl_opts.c config.h mandoc.h libmandoc.h libroff.h tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h -term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h -term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h main.h -tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h -test-dirent-namlen.o: test-dirent-namlen.c -test-fgetln.o: test-fgetln.c -test-fts.o: test-fts.c -test-getsubopt.o: test-getsubopt.c -test-mmap.o: test-mmap.c -test-ohash.o: test-ohash.c -test-reallocarray.o: test-reallocarray.c -test-sqlite3.o: test-sqlite3.c -test-sqlite3_errstr.o: test-sqlite3_errstr.c -test-strcasestr.o: test-strcasestr.c -test-strlcat.o: test-strlcat.c -test-strlcpy.o: test-strlcpy.c -test-strptime.o: test-strptime.c -test-strsep.o: test-strsep.c -test-strtonum.o: test-strtonum.c -test-wchar.o: test-wchar.c +term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h manconf.h main.h +term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h manconf.h main.h +tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h main.h diff --git a/contrib/mdocml/NEWS b/contrib/mdocml/NEWS index ecbd005..985f265 100644 --- a/contrib/mdocml/NEWS +++ b/contrib/mdocml/NEWS @@ -1,4 +1,4 @@ -$Id: NEWS,v 1.9 2015/03/13 12:35:32 schwarze Exp $ +$Id: NEWS,v 1.10 2015/11/05 16:58:20 schwarze Exp $ This file lists the most important changes in the mdocml.bsd.lv distribution. @@ -93,7 +93,7 @@ Changes in version 1.13.3, released on March 13, 2015 * roff(7): Three minor fixes with respect to evaluation of conditionals. * roff(7): Let .it accept numerical expressions, not just constants. * mandoc_char(7): Correct some character names and renderings. - * If earlier files set a non-zero exit status, never reset it to zero. + * If earlier files set a non-zero exit status, never reset it to zero. --- THANKS TO --- * Jonathan Gray (OpenBSD) for yet more testing with afl (the American Fuzzy Lop security fuzzer), again resulting in many bug reports. diff --git a/contrib/mdocml/TODO b/contrib/mdocml/TODO index 701cd1d..d24c939 100644 --- a/contrib/mdocml/TODO +++ b/contrib/mdocml/TODO @@ -1,6 +1,6 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.202 2015/03/11 13:11:22 schwarze Exp $ +* $Id: TODO,v 1.216 2016/01/08 01:37:32 schwarze Exp $ ************************************************************************ Many issues are annotated for difficulty as follows: @@ -66,6 +66,7 @@ are mere guesses, and some may be wrong. loc * exist * algo * size * imp ** - .ns (no-space mode) occurs in xine-config(1) + when implementing this, also let .TH set it reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500 loc *** exist *** algo *** size ** imp * @@ -105,6 +106,19 @@ are mere guesses, and some may be wrong. needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100 loc ** exist *** algo *** size * imp *** +- \\ in high-level macro arguments + Currently, \\ is expanded in two situations: + 1) macro and string definition (roff.c setstrn()) + 2) macro argument parsing (mandoc.c mandoc_getarg()) + For user defined macros, the second happens in time because of ROFF_REPARSE. + But for standard high-level macros, it only happens after entering the + high level parsers, which is too late because the code doesn't get + back to roff.c roff_res() from that point. Because this requires + distinguishing requests, user-defined macros and standard macros + on the roff_res() level, it is hard to solve without the parser reorg. + Found by naddy@ in devel/cutils cobfusc(1) Mon, 16 Feb 2015 19:10:52 +0100 + loc *** exist *** algo *** size ** imp * + - using undefined strings or macros defines them to be empty wl@ Mon, 14 Nov 2011 14:37:01 +0000 loc * exist * algo * size * imp * @@ -194,6 +208,26 @@ are mere guesses, and some may be wrong. --- missing tbl features ----------------------------------------------- +- horizontal lines in the layout still consume data cells + and can be mixed with actual data on the same table line + synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 + loc ** exist ** algo ** size ** imp *** + +- the "w" layout option is ignored + synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 + loc * exist * algo * size * imp ** + +- the "s" layout column specifier is used for placement of data + into columns, but ignored during column width calculations + synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 + loc * exist ** algo *** size * imp ** + +- support mdoc(7) and man(7) macros inside tbl(7) code; + probably requires the parser reorg and letting tbl(7) + use roff_node such that macro sets can mix; + informed by bapt@ that FreeBSD needs this. + loc *** exist ** algo *** size ** imp *** + - look at the POSIX manuals in the books/man-pages-posix port, they use some unsupported tbl(7) features. loc * exist ** algo ** size ** imp *** @@ -203,13 +237,13 @@ are mere guesses, and some may be wrong. suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600 loc * exist ** algo * size * imp ** -- allow standalone `.' to be interpreted as an end-of-layout - delimiter instead of being thrown away as a no-op roff line - reported by Yuri Pankov, Wed 18 May 2011 11:34:59 CEST - loc ** exist ** algo ** size * imp ** - --- missing eqn features ----------------------------------------------- +- In a matrix, break the output line after each matrix line. + Found in the discussion at CDBUG 2015. + Suggested by Avi Weinstock. + loc * exist * algo * size * imp ** + - The "size" keyword is parsed, but ignored by the formatter. loc * exist * algo * size * imp * @@ -227,13 +261,9 @@ are mere guesses, and some may be wrong. Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46 loc ** exist ** algo * size * imp * -- When makewhatis(8) encounters a FATAL parse error, - it silently treats the file as formatted, which makes no sense - at all for paths like man1/foo.1 - and which also contradicts - what the manual says at the end of the description. - The end result will be ENOENT for file names returned - by mansearch() in manpage.file. - loc * exist * algo * size * imp ** +- change the default PAGER to more -Es and use the pager + even for apropos title line output; req by bapt@ + loc * exist * algo * size * imp *** - makewhatis(8) for preformatted pages: parse the section number from the header line @@ -255,11 +285,13 @@ are mere guesses, and some may be wrong. - kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET) loc ** exist ** algo ** size *** imp * ---- compatibility checks ----------------------------------------------- +- Vsevolod Stakhov (FreeBSD) needs either a markdown output formatter + for mandoc -mdoc or a markdown to mdoc converter because they + have to maintain manuals needed both in markdown and mdoc format. + Look at the libsoldout (markdown -> whatever) + loc * exist * algo * size ** imp ** -- write a configure check for [[:<:]] support and provide some - fallback for whatis(1) when it doesn't work; - Svyatoslav Mishyn Wed, 17 Dec 2014 11:07:10 +0200 +--- compatibility checks ----------------------------------------------- - is .Bk implemented correctly in modern groff? sobrado@ Tue, 19 Apr 2011 22:12:55 +0200 @@ -293,6 +325,9 @@ are mere guesses, and some may be wrong. http://swtch.com/plan9port/man/man7/man.html "Anthony J. Bentley" <anthonyjbentley@gmail.com> 28 Dec 2010 21:58:40 -0700 +- check compatibility with COHERENT troff: + http://www.nesssoftware.com/home/mwc/source.php + - check compatibility with the man(7) formatter https://raw.githubusercontent.com/rofl0r/hardcore-utils/master/man.c @@ -381,6 +416,12 @@ are mere guesses, and some may be wrong. see also matthew@ Fri, 18 Jul 2014 19:25:12 -0700 loc * exist * algo ** size * imp *** +- .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal + space, see for example random(3). Introduced in + http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92 + reported by deraadt@ Mon, 28 Sep 2015 20:14:13 -0600 (MDT) + loc ** exist ** algo ** size * imp * + - jsg on icb, Nov 3, 2014: try to guess Xr in man(7) for hyperlinking @@ -394,6 +435,10 @@ are mere guesses, and some may be wrong. - consider whether <var> can be used for Ar Dv Er Ev Fa Va. from bentley@ Wed, 13 Aug 2014 09:17:55 -0600 +- generate <img> tags in HTML + idea from florian@ Tue, 7 Apr 2015 00:26:28 +0000 + may be possible to implement with .Lk img://something.png alt_text + - check https://github.com/trentm/mdocml ************************************************************************ @@ -466,6 +511,10 @@ are mere guesses, and some may be wrong. found while talking to Chris Bennett loc * exist * algo * size * imp * +- Sequences of multiple man(7) paragraphs (.PP, .IP) interspersed + with .ps and .nf/.fi produce execessive blank lines, see libJudy + and graphics/dcmtk. The parser reorg may help with this. + - trailing whitespace must be ignored even when followed by a font escape, see for example makes @@ -475,9 +524,31 @@ are mere guesses, and some may be wrong. loc ** exist ** algo ** size * imp ** ************************************************************************ +* portability +************************************************************************ + +- systems having UTF-8 but not en_US.UTF-8 + call locale(1) from ./configure, select a UTF-8-locale, + and use that for test-wchar.c and term_ascii.c + to Markus Waldeck Sat, 18 Jul 2015 01:55:37 +0200 + loc * exist * algo * size * imp * + +************************************************************************ * warning issues ************************************************************************ +- provide a way in mandoc(1) to warn about broken .Xr links; + probably cannot be on by default in -Tlint because it needs + to access the manpath and mandoc.db(3) after parsing. + asked for by jmc@ Fri, 4 Dec 2015 22:39:40 +0000 + +- Report errors in -O suboption parsing. + loc * exist * algo * size * imp ** + +- warn when .Sh or .Ss contain other macros + Steffen Nurpmeso, savannah.gnu.org/bugs/index.php?45034 + loc * exist * algo * size * imp ** + - check that MANDOCERR_BADTAB is thrown in the right cases, i.e. when finding a literal tab character in fill mode, and possibly change the wording of the warning message @@ -557,11 +628,6 @@ Several areas can be cleaned up to make mandoc even faster. These are * structural issues ************************************************************************ -- Improve -O suboption parsing. Do it in the main program such that - errors can be reported. Pay attention to distinguishing the - mandoc(1) and apropos(1) styles of both options. - loc ** exist * algo ** size ** imp *** - - Use libz directly instead of forking gunzip(1). Suggested by bapt at FreeBSD among others. diff --git a/contrib/mdocml/apropos.1 b/contrib/mdocml/apropos.1 index 532e4dd..10ba3c6 100644 --- a/contrib/mdocml/apropos.1 +++ b/contrib/mdocml/apropos.1 @@ -1,4 +1,4 @@ -.\" $Id: apropos.1,v 1.37 2015/02/16 16:23:54 schwarze Exp $ +.\" $Id: apropos.1,v 1.39 2015/04/03 08:46:17 schwarze Exp $ .\" .\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2011, 2012, 2014 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: February 16 2015 $ +.Dd $Mdocdate: April 3 2015 $ .Dt APROPOS 1 .Os .Sh NAME @@ -210,7 +210,7 @@ This has syntax .Sm off .Oo .Op Ar key Op , Ar key ... -.Pq Cm = | ~ +.Pq Cm = | \(ti .Oc .Ar val , .Sm on @@ -227,7 +227,7 @@ for a list of available keys. Operator .Cm = evaluates a substring, while -.Cm ~ +.Cm \(ti evaluates a regular expression. .It Fl i Ar term If @@ -365,7 +365,8 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Pa /usr/bin/more Fl s +.Xr more 1 +.Fl s will be used. .El .Sh FILES @@ -398,7 +399,7 @@ as well: .Pp Search in names and descriptions using a regular expression: .Pp -.Dl $ apropos '~set.?[ug]id' +.Dl $ apropos \(aq\(tiset.?[ug]id\(aq .Pp Search for manuals in the library section mentioning both the .Qq optind @@ -413,15 +414,15 @@ Do exactly the same as calling with the argument .Qq ssh : .Pp -.Dl $ apropos \-\- \-i 'Nm~[[:<:]]ssh[[:>:]]' +.Dl $ apropos \-\- \-i \(aqNm\(ti[[:<:]]ssh[[:>:]]\(aq .Pp The following two invocations are equivalent: .Pp .D1 Li $ apropos -S Ar arch Li -s Ar section expression .Bd -ragged -offset indent .Li $ apropos \e( Ar expression Li \e) -.Li -a arch~^( Ns Ar arch Ns Li |any)$ -.Li -a sec~^ Ns Ar section Ns Li $ +.Li -a arch\(ti^( Ns Ar arch Ns Li |any)$ +.Li -a sec\(ti^ Ns Ar section Ns Li $ .Ed .Sh SEE ALSO .Xr man 1 , diff --git a/contrib/mdocml/att.c b/contrib/mdocml/att.c index a1703eb..872f982 100644 --- a/contrib/mdocml/att.c +++ b/contrib/mdocml/att.c @@ -1,4 +1,4 @@ -/* $Id: att.c,v 1.13 2014/11/28 18:57:31 schwarze Exp $ */ +/* $Id: att.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -19,6 +19,7 @@ #include <sys/types.h> #include <string.h> +#include "roff.h" #include "mdoc.h" #include "libmdoc.h" @@ -45,5 +46,5 @@ mdoc_a2att(const char *p) LINE("V.3", "AT&T System\\~V Release\\~3 UNIX"); LINE("V.4", "AT&T System\\~V Release\\~4 UNIX"); - return(NULL); + return NULL; } diff --git a/contrib/mdocml/cgi.c b/contrib/mdocml/cgi.c index 05d1b8a..0b01d06 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mdocml/cgi.c @@ -1,15 +1,15 @@ -/* $Id: cgi.c,v 1.104 2015/02/10 08:05:30 schwarze Exp $ */ +/* $Id: cgi.c,v 1.116 2016/01/04 12:36:26 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de> + * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@usta.de> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -30,10 +30,13 @@ #include <string.h> #include <unistd.h> -#include "mandoc.h" #include "mandoc_aux.h" +#include "mandoc.h" +#include "roff.h" +#include "mdoc.h" +#include "man.h" #include "main.h" -#include "manpath.h" +#include "manconf.h" #include "mansearch.h" #include "cgi.h" @@ -60,9 +63,6 @@ static void html_print(const char *); static void html_putchar(char); static int http_decode(char *); static void http_parse(struct req *, const char *); -static void http_print(const char *); -static void http_putchar(char); -static void http_printquery(const struct req *, const char *); static void pathgen(struct req *); static void pg_error_badrequest(const char *); static void pg_error_internal(void); @@ -74,6 +74,7 @@ static void pg_searchres(const struct req *, static void pg_show(struct req *, const char *); static void resp_begin_html(int, const char *); static void resp_begin_http(int, const char *); +static void resp_copy(const char *); static void resp_end_html(void); static void resp_searchform(const struct req *); static void resp_show(const struct req *, const char *); @@ -145,40 +146,6 @@ html_putchar(char c) } } -static void -http_printquery(const struct req *req, const char *sep) -{ - - if (NULL != req->q.query) { - printf("query="); - http_print(req->q.query); - } - if (0 == req->q.equal) - printf("%sapropos=1", sep); - if (NULL != req->q.sec) { - printf("%ssec=", sep); - http_print(req->q.sec); - } - if (NULL != req->q.arch) { - printf("%sarch=", sep); - http_print(req->q.arch); - } - if (strcmp(req->q.manpath, req->p[0])) { - printf("%smanpath=", sep); - http_print(req->q.manpath); - } -} - -static void -http_print(const char *p) -{ - - if (NULL == p) - return; - while ('\0' != *p) - http_putchar(*p++); -} - /* * Call through to html_putchar(). * Accepts NULL strings. @@ -299,20 +266,6 @@ next: } } -static void -http_putchar(char c) -{ - - if (isalnum((unsigned char)c)) { - putchar((unsigned char)c); - return; - } else if (' ' == c) { - putchar('+'); - return; - } - printf("%%%.2x", c); -} - /* * HTTP-decode a string. The standard explanation is that this turns * "%4e+foo" into "n foo" in the regular way. This is done in-place @@ -331,13 +284,13 @@ http_decode(char *p) for ( ; '\0' != *p; p++, q++) { if ('%' == *p) { if ('\0' == (hex[0] = *(p + 1))) - return(0); + return 0; if ('\0' == (hex[1] = *(p + 2))) - return(0); + return 0; if (1 != sscanf(hex, "%x", &c)) - return(0); + return 0; if ('\0' == c) - return(0); + return 0; *q = (char)c; p += 2; @@ -346,7 +299,7 @@ http_decode(char *p) } *q = '\0'; - return(1); + return 1; } static void @@ -365,6 +318,20 @@ resp_begin_http(int code, const char *msg) } static void +resp_copy(const char *filename) +{ + char buf[4096]; + ssize_t sz; + int fd; + + if ((fd = open(filename, O_RDONLY)) != -1) { + fflush(stdout); + while ((sz = read(fd, buf, sizeof(buf))) > 0) + write(STDOUT_FILENO, buf, sz); + } +} + +static void resp_begin_html(int code, const char *msg) { @@ -374,21 +341,23 @@ resp_begin_html(int code, const char *msg) "<HTML>\n" "<HEAD>\n" "<META CHARSET=\"UTF-8\" />\n" - "<LINK REL=\"stylesheet\" HREF=\"%s/man-cgi.css\"" - " TYPE=\"text/css\" media=\"all\">\n" - "<LINK REL=\"stylesheet\" HREF=\"%s/man.css\"" + "<LINK REL=\"stylesheet\" HREF=\"%s/mandoc.css\"" " TYPE=\"text/css\" media=\"all\">\n" "<TITLE>%s</TITLE>\n" "</HEAD>\n" "<BODY>\n" "<!-- Begin page content. //-->\n", - CSS_DIR, CSS_DIR, CUSTOMIZE_TITLE); + CSS_DIR, CUSTOMIZE_TITLE); + + resp_copy(MAN_DIR "/header.html"); } static void resp_end_html(void) { + resp_copy(MAN_DIR "/footer.html"); + puts("</BODY>\n" "</HTML>"); } @@ -398,7 +367,6 @@ resp_searchform(const struct req *req) { int i; - puts(CUSTOMIZE_BEGIN); puts("<!-- Begin search form. //-->"); printf("<DIV ID=\"mancgi\">\n" "<FORM ACTION=\"%s\" METHOD=\"get\">\n" @@ -498,10 +466,10 @@ validate_urifrag(const char *frag) if ( ! (isalnum((unsigned char)*frag) || '-' == *frag || '.' == *frag || '/' == *frag || '_' == *frag)) - return(0); + return 0; frag++; } - return(1); + return 1; } static int @@ -510,13 +478,13 @@ validate_manpath(const struct req *req, const char* manpath) size_t i; if ( ! strcmp(manpath, "mandoc")) - return(1); + return 1; for (i = 0; i < req->psz; i++) if ( ! strcmp(manpath, req->p[i])) - return(1); + return 1; - return(0); + return 0; } static int @@ -526,8 +494,8 @@ validate_filename(const char *file) if ('.' == file[0] && '/' == file[1]) file += 2; - return ( ! (strstr(file, "../") || strstr(file, "/..") || - (strncmp(file, "man", 3) && strncmp(file, "cat", 3)))); + return ! (strstr(file, "../") || strstr(file, "/..") || + (strncmp(file, "man", 3) && strncmp(file, "cat", 3))); } static void @@ -604,9 +572,8 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz) * without any delay. */ printf("Status: 303 See Other\r\n"); - printf("Location: http://%s%s/%s/%s?", + printf("Location: http://%s%s/%s/%s", HTTP_HOST, scriptname, req->q.manpath, r[0].file); - http_printquery(req, "&"); printf("\r\n" "Content-Type: text/html; charset=utf-8\r\n" "\r\n"); @@ -621,9 +588,8 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz) for (i = 0; i < sz; i++) { printf("<TR>\n" "<TD CLASS=\"title\">\n" - "<A HREF=\"%s/%s/%s?", + "<A HREF=\"%s/%s/%s", scriptname, req->q.manpath, r[i].file); - http_printquery(req, "&"); printf("\">"); html_print(r[i].names); printf("</A>\n" @@ -685,12 +651,13 @@ static void catman(const struct req *req, const char *file) { FILE *f; - size_t len; - int i; char *p; + size_t sz; + ssize_t len; + int i; int italic, bold; - if (NULL == (f = fopen(file, "r"))) { + if ((f = fopen(file, "r")) == NULL) { puts("<P>You specified an invalid manual file.</P>"); return; } @@ -698,9 +665,12 @@ catman(const struct req *req, const char *file) puts("<DIV CLASS=\"catman\">\n" "<PRE>"); - while (NULL != (p = fgetln(f, &len))) { + p = NULL; + sz = 0; + + while ((len = getline(&p, &sz, f)) != -1) { bold = italic = 0; - for (i = 0; i < (int)len - 1; i++) { + for (i = 0; i < len - 1; i++) { /* * This means that the catpage is out of state. * Ignore it and keep going (although the @@ -725,7 +695,7 @@ catman(const struct req *req, const char *file) italic = bold = 0; html_putchar(p[i]); continue; - } else if (i + 2 >= (int)len) + } else if (i + 2 >= len) continue; /* Italic mode. */ @@ -801,11 +771,12 @@ catman(const struct req *req, const char *file) if (bold) printf("</B>"); - if (i == (int)len - 1 && '\n' != p[i]) + if (i == len - 1 && p[i] != '\n') html_putchar(p[i]); putchar('\n'); } + free(p); puts("</PRE>\n" "</DIV>"); @@ -816,12 +787,10 @@ catman(const struct req *req, const char *file) static void format(const struct req *req, const char *file) { + struct manoutput conf; struct mparse *mp; - struct mchars *mchars; - struct mdoc *mdoc; - struct man *man; + struct roff_man *man; void *vp; - char *opts; int fd; int usepath; @@ -830,42 +799,45 @@ format(const struct req *req, const char *file) return; } - mchars = mchars_alloc(); - mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, - mchars, req->q.manpath); + mchars_alloc(); + mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, req->q.manpath); mparse_readfd(mp, fd, file); close(fd); + memset(&conf, 0, sizeof(conf)); + conf.fragment = 1; usepath = strcmp(req->q.manpath, req->p[0]); - mandoc_asprintf(&opts, - "fragment,man=%s?query=%%N&sec=%%S%s%s%s%s", + mandoc_asprintf(&conf.man, "%s?query=%%N&sec=%%S%s%s%s%s", scriptname, req->q.arch ? "&arch=" : "", req->q.arch ? req->q.arch : "", usepath ? "&manpath=" : "", usepath ? req->q.manpath : ""); - mparse_result(mp, &mdoc, &man, NULL); - if (NULL == man && NULL == mdoc) { + mparse_result(mp, &man, NULL); + if (man == NULL) { fprintf(stderr, "fatal mandoc error: %s/%s\n", req->q.manpath, file); pg_error_internal(); mparse_free(mp); - mchars_free(mchars); + mchars_free(); return; } - vp = html_alloc(mchars, opts); + vp = html_alloc(&conf); - if (NULL != mdoc) - html_mdoc(vp, mdoc); - else + if (man->macroset == MACROSET_MDOC) { + mdoc_validate(man); + html_mdoc(vp, man); + } else { + man_validate(man); html_man(vp, man); + } html_free(vp); mparse_free(mp); - mchars_free(mchars); - free(opts); + mchars_free(); + free(conf.man); } static void @@ -1030,7 +1002,7 @@ main(void) if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) { fprintf(stderr, "setitimer: %s\n", strerror(errno)); pg_error_internal(); - return(EXIT_FAILURE); + return EXIT_FAILURE; } /* Scan our run-time environment. */ @@ -1042,7 +1014,7 @@ main(void) fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n", scriptname); pg_error_internal(); - return(EXIT_FAILURE); + return EXIT_FAILURE; } /* @@ -1055,7 +1027,7 @@ main(void) fprintf(stderr, "MAN_DIR: %s: %s\n", MAN_DIR, strerror(errno)); pg_error_internal(); - return(EXIT_FAILURE); + return EXIT_FAILURE; } memset(&req, 0, sizeof(struct req)); @@ -1071,13 +1043,13 @@ main(void) else if ( ! validate_manpath(&req, req.q.manpath)) { pg_error_badrequest( "You specified an invalid manpath."); - return(EXIT_FAILURE); + return EXIT_FAILURE; } if ( ! (NULL == req.q.arch || validate_urifrag(req.q.arch))) { pg_error_badrequest( "You specified an invalid architecture."); - return(EXIT_FAILURE); + return EXIT_FAILURE; } /* Dispatch to the three different pages. */ @@ -1102,7 +1074,7 @@ main(void) for (i = 0; i < (int)req.psz; i++) free(req.p[i]); free(req.p); - return(EXIT_SUCCESS); + return EXIT_SUCCESS; } /* @@ -1114,6 +1086,7 @@ pathgen(struct req *req) FILE *fp; char *dp; size_t dpsz; + ssize_t len; if (NULL == (fp = fopen("manpath.conf", "r"))) { fprintf(stderr, "%s/manpath.conf: %s\n", @@ -1122,12 +1095,14 @@ pathgen(struct req *req) exit(EXIT_FAILURE); } - while (NULL != (dp = fgetln(fp, &dpsz))) { - if ('\n' == dp[dpsz - 1]) - dpsz--; + dp = NULL; + dpsz = 0; + + while ((len = getline(&dp, &dpsz, fp)) != -1) { + if (dp[len - 1] == '\n') + dp[--len] = '\0'; req->p = mandoc_realloc(req->p, (req->psz + 1) * sizeof(char *)); - dp = mandoc_strndup(dp, dpsz); if ( ! validate_urifrag(dp)) { fprintf(stderr, "%s/manpath.conf contains " "unsafe path \"%s\"\n", MAN_DIR, dp); @@ -1141,7 +1116,10 @@ pathgen(struct req *req) exit(EXIT_FAILURE); } req->p[req->psz++] = dp; + dp = NULL; + dpsz = 0; } + free(dp); if ( req->p == NULL ) { fprintf(stderr, "%s/manpath.conf is empty\n", MAN_DIR); diff --git a/contrib/mdocml/cgi.h.example b/contrib/mdocml/cgi.h.example index f4c7831..c4878d3 100644 --- a/contrib/mdocml/cgi.h.example +++ b/contrib/mdocml/cgi.h.example @@ -4,6 +4,4 @@ #define MAN_DIR "/var/www/man" #define CSS_DIR "" #define CUSTOMIZE_TITLE "Manual pages with mandoc" -#define CUSTOMIZE_BEGIN "<H2>\nManual pages with " \ - "<A HREF=\"http://mdocml.bsd.lv/\">mandoc</A>\n</H2>" #define COMPAT_OLDURI Yes diff --git a/contrib/mdocml/chars.c b/contrib/mdocml/chars.c index 6b5eba9..c2cfaf8 100644 --- a/contrib/mdocml/chars.c +++ b/contrib/mdocml/chars.c @@ -1,7 +1,7 @@ -/* $Id: chars.c,v 1.66 2015/02/17 20:37:16 schwarze Exp $ */ +/* $Id: chars.c,v 1.68 2015/10/13 22:59:54 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,90 +21,429 @@ #include <assert.h> #include <ctype.h> +#include <stddef.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include "mandoc.h" #include "mandoc_aux.h" +#include "mandoc_ohash.h" #include "libmandoc.h" -#define PRINT_HI 126 -#define PRINT_LO 32 - struct ln { - struct ln *next; - const char *code; + const char roffcode[16]; const char *ascii; int unicode; }; -#define LINES_MAX 332 - -#define CHAR(in, ch, code) \ - { NULL, (in), (ch), (code) }, - -#define CHAR_TBL_START static struct ln lines[LINES_MAX] = { -#define CHAR_TBL_END }; - -#include "chars.in" - -struct mchars { - struct ln **htab; +/* Special break control characters. */ +static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' }; +static const char ascii_break[2] = { ASCII_BREAK, '\0' }; + +static struct ln lines[] = { + + /* Spacing. */ + { " ", ascii_nbrsp, 0x00a0 }, + { "~", ascii_nbrsp, 0x00a0 }, + { "0", " ", 0x2002 }, + { "|", "", 0 }, + { "^", "", 0 }, + { "&", "", 0 }, + { "%", "", 0 }, + { ":", ascii_break, 0 }, + /* XXX The following three do not really belong here. */ + { "t", "", 0 }, + { "c", "", 0 }, + { "}", "", 0 }, + + /* Lines. */ + { "ba", "|", 0x007c }, + { "br", "|", 0x2502 }, + { "ul", "_", 0x005f }, + { "rn", "-", 0x203e }, + { "bb", "|", 0x00a6 }, + { "sl", "/", 0x002f }, + { "rs", "\\", 0x005c }, + + /* Text markers. */ + { "ci", "O", 0x25cb }, + { "bu", "+\bo", 0x2022 }, + { "dd", "|\b=", 0x2021 }, + { "dg", "|\b-", 0x2020 }, + { "lz", "<>", 0x25ca }, + { "sq", "[]", 0x25a1 }, + { "ps", "<par>", 0x00b6 }, + { "sc", "<sec>", 0x00a7 }, + { "lh", "<=", 0x261c }, + { "rh", "=>", 0x261e }, + { "at", "@", 0x0040 }, + { "sh", "#", 0x0023 }, + { "CR", "_|", 0x21b5 }, + { "OK", "\\/", 0x2713 }, + + /* Legal symbols. */ + { "co", "(C)", 0x00a9 }, + { "rg", "(R)", 0x00ae }, + { "tm", "tm", 0x2122 }, + + /* Punctuation. */ + { "em", "--", 0x2014 }, + { "en", "-", 0x2013 }, + { "hy", "-", 0x2010 }, + { "e", "\\", 0x005c }, + { ".", ".", 0x002e }, + { "r!", "!", 0x00a1 }, + { "r?", "?", 0x00bf }, + + /* Quotes. */ + { "Bq", ",,", 0x201e }, + { "bq", ",", 0x201a }, + { "lq", "\"", 0x201c }, + { "rq", "\"", 0x201d }, + { "Lq", "``", 0x201c }, + { "Rq", "''", 0x201d }, + { "oq", "`", 0x2018 }, + { "cq", "\'", 0x2019 }, + { "aq", "\'", 0x0027 }, + { "dq", "\"", 0x0022 }, + { "Fo", "<<", 0x00ab }, + { "Fc", ">>", 0x00bb }, + { "fo", "<", 0x2039 }, + { "fc", ">", 0x203a }, + + /* Brackets. */ + { "lB", "[", 0x005b }, + { "rB", "]", 0x005d }, + { "lC", "{", 0x007b }, + { "rC", "}", 0x007d }, + { "la", "<", 0x27e8 }, + { "ra", ">", 0x27e9 }, + { "bv", "|", 0x23aa }, + { "braceex", "|", 0x23aa }, + { "bracketlefttp", "|", 0x23a1 }, + { "bracketleftbt", "|", 0x23a3 }, + { "bracketleftex", "|", 0x23a2 }, + { "bracketrighttp", "|", 0x23a4 }, + { "bracketrightbt", "|", 0x23a6 }, + { "bracketrightex", "|", 0x23a5 }, + { "lt", ",-", 0x23a7 }, + { "bracelefttp", ",-", 0x23a7 }, + { "lk", "{", 0x23a8 }, + { "braceleftmid", "{", 0x23a8 }, + { "lb", "`-", 0x23a9 }, + { "braceleftbt", "`-", 0x23a9 }, + { "braceleftex", "|", 0x23aa }, + { "rt", "-.", 0x23ab }, + { "bracerighttp", "-.", 0x23ab }, + { "rk", "}", 0x23ac }, + { "bracerightmid", "}", 0x23ac }, + { "rb", "-\'", 0x23ad }, + { "bracerightbt", "-\'", 0x23ad }, + { "bracerightex", "|", 0x23aa }, + { "parenlefttp", "/", 0x239b }, + { "parenleftbt", "\\", 0x239d }, + { "parenleftex", "|", 0x239c }, + { "parenrighttp", "\\", 0x239e }, + { "parenrightbt", "/", 0x23a0 }, + { "parenrightex", "|", 0x239f }, + + /* Arrows and lines. */ + { "<-", "<-", 0x2190 }, + { "->", "->", 0x2192 }, + { "<>", "<->", 0x2194 }, + { "da", "|\bv", 0x2193 }, + { "ua", "|\b^", 0x2191 }, + { "va", "^v", 0x2195 }, + { "lA", "<=", 0x21d0 }, + { "rA", "=>", 0x21d2 }, + { "hA", "<=>", 0x21d4 }, + { "uA", "=\b^", 0x21d1 }, + { "dA", "=\bv", 0x21d3 }, + { "vA", "^=v", 0x21d5 }, + + /* Logic. */ + { "AN", "^", 0x2227 }, + { "OR", "v", 0x2228 }, + { "no", "~", 0x00ac }, + { "tno", "~", 0x00ac }, + { "te", "3", 0x2203 }, + { "fa", "-\bV", 0x2200 }, + { "st", "-)", 0x220b }, + { "tf", ".:.", 0x2234 }, + { "3d", ".:.", 0x2234 }, + { "or", "|", 0x007c }, + + /* Mathematicals. */ + { "pl", "+", 0x002b }, + { "mi", "-", 0x2212 }, + { "-", "-", 0x002d }, + { "-+", "-+", 0x2213 }, + { "+-", "+-", 0x00b1 }, + { "t+-", "+-", 0x00b1 }, + { "pc", ".", 0x00b7 }, + { "md", ".", 0x22c5 }, + { "mu", "x", 0x00d7 }, + { "tmu", "x", 0x00d7 }, + { "c*", "O\bx", 0x2297 }, + { "c+", "O\b+", 0x2295 }, + { "di", "-:-", 0x00f7 }, + { "tdi", "-:-", 0x00f7 }, + { "f/", "/", 0x2044 }, + { "**", "*", 0x2217 }, + { "<=", "<=", 0x2264 }, + { ">=", ">=", 0x2265 }, + { "<<", "<<", 0x226a }, + { ">>", ">>", 0x226b }, + { "eq", "=", 0x003d }, + { "!=", "!=", 0x2260 }, + { "==", "==", 0x2261 }, + { "ne", "!==", 0x2262 }, + { "ap", "~", 0x223c }, + { "|=", "-~", 0x2243 }, + { "=~", "=~", 0x2245 }, + { "~~", "~~", 0x2248 }, + { "~=", "~=", 0x2248 }, + { "pt", "oc", 0x221d }, + { "es", "{}", 0x2205 }, + { "mo", "E", 0x2208 }, + { "nm", "!E", 0x2209 }, + { "sb", "(=", 0x2282 }, + { "nb", "(!=", 0x2284 }, + { "sp", "=)", 0x2283 }, + { "nc", "!=)", 0x2285 }, + { "ib", "(=\b_", 0x2286 }, + { "ip", "=\b_)", 0x2287 }, + { "ca", "(^)", 0x2229 }, + { "cu", "U", 0x222a }, + { "/_", "_\b/", 0x2220 }, + { "pp", "_\b|", 0x22a5 }, + { "is", "'\b,\bI", 0x222b }, + { "integral", "'\b,\bI", 0x222b }, + { "sum", "E", 0x2211 }, + { "product", "TT", 0x220f }, + { "coproduct", "U", 0x2210 }, + { "gr", "V", 0x2207 }, + { "sr", "\\/", 0x221a }, + { "sqrt", "\\/", 0x221a }, + { "lc", "|~", 0x2308 }, + { "rc", "~|", 0x2309 }, + { "lf", "|_", 0x230a }, + { "rf", "_|", 0x230b }, + { "if", "oo", 0x221e }, + { "Ah", "N", 0x2135 }, + { "Im", "I", 0x2111 }, + { "Re", "R", 0x211c }, + { "pd", "a", 0x2202 }, + { "-h", "/h", 0x210f }, + { "12", "1/2", 0x00bd }, + { "14", "1/4", 0x00bc }, + { "34", "3/4", 0x00be }, + + /* Ligatures. */ + { "ff", "ff", 0xfb00 }, + { "fi", "fi", 0xfb01 }, + { "fl", "fl", 0xfb02 }, + { "Fi", "ffi", 0xfb03 }, + { "Fl", "ffl", 0xfb04 }, + { "AE", "AE", 0x00c6 }, + { "ae", "ae", 0x00e6 }, + { "OE", "OE", 0x0152 }, + { "oe", "oe", 0x0153 }, + { "ss", "ss", 0x00df }, + { "IJ", "IJ", 0x0132 }, + { "ij", "ij", 0x0133 }, + + /* Accents. */ + { "a\"", "\"", 0x02dd }, + { "a-", "-", 0x00af }, + { "a.", ".", 0x02d9 }, + { "a^", "^", 0x005e }, + { "aa", "\'", 0x00b4 }, + { "\'", "\'", 0x00b4 }, + { "ga", "`", 0x0060 }, + { "`", "`", 0x0060 }, + { "ab", "'\b`", 0x02d8 }, + { "ac", ",", 0x00b8 }, + { "ad", "\"", 0x00a8 }, + { "ah", "v", 0x02c7 }, + { "ao", "o", 0x02da }, + { "a~", "~", 0x007e }, + { "ho", ",", 0x02db }, + { "ha", "^", 0x005e }, + { "ti", "~", 0x007e }, + + /* Accented letters. */ + { "'A", "'\bA", 0x00c1 }, + { "'E", "'\bE", 0x00c9 }, + { "'I", "'\bI", 0x00cd }, + { "'O", "'\bO", 0x00d3 }, + { "'U", "'\bU", 0x00da }, + { "'a", "'\ba", 0x00e1 }, + { "'e", "'\be", 0x00e9 }, + { "'i", "'\bi", 0x00ed }, + { "'o", "'\bo", 0x00f3 }, + { "'u", "'\bu", 0x00fa }, + { "`A", "`\bA", 0x00c0 }, + { "`E", "`\bE", 0x00c8 }, + { "`I", "`\bI", 0x00cc }, + { "`O", "`\bO", 0x00d2 }, + { "`U", "`\bU", 0x00d9 }, + { "`a", "`\ba", 0x00e0 }, + { "`e", "`\be", 0x00e8 }, + { "`i", "`\bi", 0x00ec }, + { "`o", "`\bo", 0x00f2 }, + { "`u", "`\bu", 0x00f9 }, + { "~A", "~\bA", 0x00c3 }, + { "~N", "~\bN", 0x00d1 }, + { "~O", "~\bO", 0x00d5 }, + { "~a", "~\ba", 0x00e3 }, + { "~n", "~\bn", 0x00f1 }, + { "~o", "~\bo", 0x00f5 }, + { ":A", "\"\bA", 0x00c4 }, + { ":E", "\"\bE", 0x00cb }, + { ":I", "\"\bI", 0x00cf }, + { ":O", "\"\bO", 0x00d6 }, + { ":U", "\"\bU", 0x00dc }, + { ":a", "\"\ba", 0x00e4 }, + { ":e", "\"\be", 0x00eb }, + { ":i", "\"\bi", 0x00ef }, + { ":o", "\"\bo", 0x00f6 }, + { ":u", "\"\bu", 0x00fc }, + { ":y", "\"\by", 0x00ff }, + { "^A", "^\bA", 0x00c2 }, + { "^E", "^\bE", 0x00ca }, + { "^I", "^\bI", 0x00ce }, + { "^O", "^\bO", 0x00d4 }, + { "^U", "^\bU", 0x00db }, + { "^a", "^\ba", 0x00e2 }, + { "^e", "^\be", 0x00ea }, + { "^i", "^\bi", 0x00ee }, + { "^o", "^\bo", 0x00f4 }, + { "^u", "^\bu", 0x00fb }, + { ",C", ",\bC", 0x00c7 }, + { ",c", ",\bc", 0x00e7 }, + { "/L", "/\bL", 0x0141 }, + { "/l", "/\bl", 0x0142 }, + { "/O", "/\bO", 0x00d8 }, + { "/o", "/\bo", 0x00f8 }, + { "oA", "o\bA", 0x00c5 }, + { "oa", "o\ba", 0x00e5 }, + + /* Special letters. */ + { "-D", "-\bD", 0x00d0 }, + { "Sd", "d", 0x00f0 }, + { "TP", "Th", 0x00de }, + { "Tp", "th", 0x00fe }, + { ".i", "i", 0x0131 }, + { ".j", "j", 0x0237 }, + + /* Currency. */ + { "Do", "$", 0x0024 }, + { "ct", "/\bc", 0x00a2 }, + { "Eu", "EUR", 0x20ac }, + { "eu", "EUR", 0x20ac }, + { "Ye", "=\bY", 0x00a5 }, + { "Po", "GBP", 0x00a3 }, + { "Cs", "o\bx", 0x00a4 }, + { "Fn", ",\bf", 0x0192 }, + + /* Units. */ + { "de", "<deg>", 0x00b0 }, + { "%0", "%o", 0x2030 }, + { "fm", "\'", 0x2032 }, + { "sd", "''", 0x2033 }, + { "mc", ",\bu", 0x00b5 }, + + /* Greek characters. */ + { "*A", "A", 0x0391 }, + { "*B", "B", 0x0392 }, + { "*G", "G", 0x0393 }, + { "*D", "_\b/_\b\\", 0x0394 }, + { "*E", "E", 0x0395 }, + { "*Z", "Z", 0x0396 }, + { "*Y", "H", 0x0397 }, + { "*H", "-\bO", 0x0398 }, + { "*I", "I", 0x0399 }, + { "*K", "K", 0x039a }, + { "*L", "/\\", 0x039b }, + { "*M", "M", 0x039c }, + { "*N", "N", 0x039d }, + { "*C", "_\bH", 0x039e }, + { "*O", "O", 0x039f }, + { "*P", "TT", 0x03a0 }, + { "*R", "P", 0x03a1 }, + { "*S", "S", 0x03a3 }, + { "*T", "T", 0x03a4 }, + { "*U", "Y", 0x03a5 }, + { "*F", "I\bO", 0x03a6 }, + { "*X", "X", 0x03a7 }, + { "*Q", "I\bY", 0x03a8 }, + { "*W", "_\bO", 0x03a9 }, + { "*a", "a", 0x03b1 }, + { "*b", "B", 0x03b2 }, + { "*g", "y", 0x03b3 }, + { "*d", "d", 0x03b4 }, + { "*e", "e", 0x03b5 }, + { "*z", ",\bC", 0x03b6 }, + { "*y", "n", 0x03b7 }, + { "*h", "-\b0", 0x03b8 }, + { "*i", "i", 0x03b9 }, + { "*k", "k", 0x03ba }, + { "*l", ">\b\\", 0x03bb }, + { "*m", ",\bu", 0x03bc }, + { "*n", "v", 0x03bd }, + { "*c", ",\bE", 0x03be }, + { "*o", "o", 0x03bf }, + { "*p", "-\bn", 0x03c0 }, + { "*r", "p", 0x03c1 }, + { "*s", "-\bo", 0x03c3 }, + { "*t", "~\bt", 0x03c4 }, + { "*u", "u", 0x03c5 }, + { "*f", "|\bo", 0x03d5 }, + { "*x", "x", 0x03c7 }, + { "*q", "|\bu", 0x03c8 }, + { "*w", "w", 0x03c9 }, + { "+h", "-\b0", 0x03d1 }, + { "+f", "|\bo", 0x03c6 }, + { "+p", "-\bw", 0x03d6 }, + { "+e", "e", 0x03f5 }, + { "ts", "s", 0x03c2 }, }; -static const struct ln *find(const struct mchars *, - const char *, size_t); +static struct ohash mchars; void -mchars_free(struct mchars *arg) +mchars_free(void) { - free(arg->htab); - free(arg); + ohash_delete(&mchars); } -struct mchars * +void mchars_alloc(void) { - struct mchars *tab; - struct ln **htab; - struct ln *pp; - int i, hash; - - /* - * Constructs a very basic chaining hashtable. The hash routine - * is simply the integral value of the first character. - * Subsequent entries are chained in the order they're processed. - */ - - tab = mandoc_malloc(sizeof(struct mchars)); - htab = mandoc_calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln *)); - - for (i = 0; i < LINES_MAX; i++) { - hash = (int)lines[i].code[0] - PRINT_LO; - - if (NULL == (pp = htab[hash])) { - htab[hash] = &lines[i]; - continue; - } - - for ( ; pp->next; pp = pp->next) - /* Scan ahead. */ ; - pp->next = &lines[i]; + size_t i; + unsigned int slot; + + mandoc_ohash_init(&mchars, 9, offsetof(struct ln, roffcode)); + for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++) { + slot = ohash_qlookup(&mchars, lines[i].roffcode); + assert(ohash_find(&mchars, slot) == NULL); + ohash_insert(&mchars, slot, lines + i); } - - tab->htab = htab; - return(tab); } int -mchars_spec2cp(const struct mchars *arg, const char *p, size_t sz) +mchars_spec2cp(const char *p, size_t sz) { const struct ln *ln; + const char *end; - ln = find(arg, p, sz); - return(ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1); + end = p + sz; + ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end)); + return ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1; } int @@ -113,7 +452,7 @@ mchars_num2char(const char *p, size_t sz) int i; i = mandoc_strntoi(p, sz, 10); - return(i >= 0 && i < 256 ? i : -1); + return i >= 0 && i < 256 ? i : -1; } int @@ -123,53 +462,33 @@ mchars_num2uc(const char *p, size_t sz) i = mandoc_strntoi(p, sz, 16); assert(i >= 0 && i <= 0x10FFFF); - return(i); + return i; } const char * -mchars_spec2str(const struct mchars *arg, - const char *p, size_t sz, size_t *rsz) +mchars_spec2str(const char *p, size_t sz, size_t *rsz) { const struct ln *ln; + const char *end; - ln = find(arg, p, sz); + end = p + sz; + ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end)); if (ln == NULL) { *rsz = 1; - return(sz == 1 ? p : NULL); + return sz == 1 ? p : NULL; } *rsz = strlen(ln->ascii); - return(ln->ascii); + return ln->ascii; } const char * mchars_uc2str(int uc) { - int i; + size_t i; - for (i = 0; i < LINES_MAX; i++) + for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++) if (uc == lines[i].unicode) - return(lines[i].ascii); - return("<?>"); -} - -static const struct ln * -find(const struct mchars *tab, const char *p, size_t sz) -{ - const struct ln *pp; - int hash; - - assert(p); - - if (0 == sz || p[0] < PRINT_LO || p[0] > PRINT_HI) - return(NULL); - - hash = (int)p[0] - PRINT_LO; - - for (pp = tab->htab[hash]; pp; pp = pp->next) - if (0 == strncmp(pp->code, p, sz) && - '\0' == pp->code[(int)sz]) - return(pp); - - return(NULL); + return lines[i].ascii; + return "<?>"; } diff --git a/contrib/mdocml/chars.in b/contrib/mdocml/chars.in deleted file mode 100644 index ac72aba..0000000 --- a/contrib/mdocml/chars.in +++ /dev/null @@ -1,404 +0,0 @@ -/* $Id: chars.in,v 1.52 2015/02/17 20:37:16 schwarze Exp $ */ -/* - * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 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. - */ - -/* - * The ASCII translation tables. - * - * The left-hand side corresponds to the input sequence (\x, \(xx, \*(xx - * and so on) whose length is listed second element. The right-hand - * side is what's produced by the front-end, with the fourth element - * being its length. - * - * XXX - C-escape strings! - * XXX - update LINES_MAX if adding more! - */ - -/* Special break control characters. */ -static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' }; -static const char ascii_break[2] = { ASCII_BREAK, '\0' }; - -CHAR_TBL_START - -/* Spacing. */ -CHAR(" ", ascii_nbrsp, 160) -CHAR("~", ascii_nbrsp, 160) -CHAR("0", " ", 8194) -CHAR("|", "", 0) -CHAR("^", "", 0) -CHAR("&", "", 0) -CHAR("%", "", 0) -CHAR(":", ascii_break, 0) -/* XXX The following three do not really belong into this file. */ -CHAR("t", "", 0) -CHAR("c", "", 0) -CHAR("}", "", 0) - -/* Accents. */ -CHAR("a\"", "\"", 733) -CHAR("a-", "-", 175) -CHAR("a.", ".", 729) -CHAR("a^", "^", 94) -CHAR("\'", "\'", 180) -CHAR("aa", "\'", 180) -CHAR("ga", "`", 96) -CHAR("`", "`", 96) -CHAR("ab", "'\b`", 728) -CHAR("ac", ",", 184) -CHAR("ad", "\"", 168) -CHAR("ah", "v", 711) -CHAR("ao", "o", 730) -CHAR("a~", "~", 126) -CHAR("ho", ",", 731) -CHAR("ha", "^", 94) -CHAR("ti", "~", 126) - -/* Quotes. */ -CHAR("Bq", ",,", 8222) -CHAR("bq", ",", 8218) -CHAR("lq", "\"", 8220) -CHAR("rq", "\"", 8221) -CHAR("Lq", "``", 8220) -CHAR("Rq", "''", 8221) -CHAR("oq", "`", 8216) -CHAR("cq", "\'", 8217) -CHAR("aq", "\'", 39) -CHAR("dq", "\"", 34) -CHAR("Fo", "<<", 171) -CHAR("Fc", ">>", 187) -CHAR("fo", "<", 8249) -CHAR("fc", ">", 8250) - -/* Brackets. */ -CHAR("lB", "[", 91) -CHAR("rB", "]", 93) -CHAR("lC", "{", 123) -CHAR("rC", "}", 125) -CHAR("la", "<", 10216) -CHAR("ra", ">", 10217) -CHAR("bv", "|", 9130) -CHAR("braceex", "|", 9130) -CHAR("bracketlefttp", "|", 9121) -CHAR("bracketleftbt", "|", 9123) -CHAR("bracketleftex", "|", 9122) -CHAR("bracketrighttp", "|", 9124) -CHAR("bracketrightbt", "|", 9126) -CHAR("bracketrightex", "|", 9125) -CHAR("lt", ",-", 9127) -CHAR("bracelefttp", ",-", 9127) -CHAR("lk", "{", 9128) -CHAR("braceleftmid", "{", 9128) -CHAR("lb", "`-", 9129) -CHAR("braceleftbt", "`-", 9129) -CHAR("braceleftex", "|", 9130) -CHAR("rt", "-.", 9131) -CHAR("bracerighttp", "-.", 9131) -CHAR("rk", "}", 9132) -CHAR("bracerightmid", "}", 9132) -CHAR("rb", "-\'", 9133) -CHAR("bracerightbt", "-\'", 9133) -CHAR("bracerightex", "|", 9130) -CHAR("parenlefttp", "/", 9115) -CHAR("parenleftbt", "\\", 9117) -CHAR("parenleftex", "|", 9116) -CHAR("parenrighttp", "\\", 9118) -CHAR("parenrightbt", "/", 9120) -CHAR("parenrightex", "|", 9119) - -/* Greek characters. */ -CHAR("*A", "A", 913) -CHAR("*B", "B", 914) -CHAR("*G", "G", 915) -CHAR("*D", "_\b/_\b\\", 916) -CHAR("*E", "E", 917) -CHAR("*Z", "Z", 918) -CHAR("*Y", "H", 919) -CHAR("*H", "-\bO", 920) -CHAR("*I", "I", 921) -CHAR("*K", "K", 922) -CHAR("*L", "/\\", 923) -CHAR("*M", "M", 924) -CHAR("*N", "N", 925) -CHAR("*C", "_\bH", 926) -CHAR("*O", "O", 927) -CHAR("*P", "TT", 928) -CHAR("*R", "P", 929) -CHAR("*S", "S", 931) -CHAR("*T", "T", 932) -CHAR("*U", "Y", 933) -CHAR("*F", "I\bO", 934) -CHAR("*X", "X", 935) -CHAR("*Q", "I\bY", 936) -CHAR("*W", "_\bO", 937) -CHAR("*a", "a", 945) -CHAR("*b", "B", 946) -CHAR("*g", "y", 947) -CHAR("*d", "d", 948) -CHAR("*e", "e", 949) -CHAR("*z", ",\bC", 950) -CHAR("*y", "n", 951) -CHAR("*h", "-\b0", 952) -CHAR("*i", "i", 953) -CHAR("*k", "k", 954) -CHAR("*l", ">\b\\", 955) -CHAR("*m", ",\bu", 956) -CHAR("*n", "v", 957) -CHAR("*c", ",\bE", 958) -CHAR("*o", "o", 959) -CHAR("*p", "-\bn", 960) -CHAR("*r", "p", 961) -CHAR("*s", "-\bo", 963) -CHAR("*t", "~\bt", 964) -CHAR("*u", "u", 965) -CHAR("*f", "|\bo", 981) -CHAR("*x", "x", 967) -CHAR("*q", "|\bu", 968) -CHAR("*w", "w", 969) -CHAR("+h", "-\b0", 977) -CHAR("+f", "|\bo", 966) -CHAR("+p", "-\bw", 982) -CHAR("+e", "e", 1013) -CHAR("ts", "s", 962) - -/* Accented letters. */ -CHAR(",C", ",\bC", 199) -CHAR(",c", ",\bc", 231) -CHAR("/L", "/\bL", 321) -CHAR("/O", "/\bO", 216) -CHAR("/l", "/\bl", 322) -CHAR("/o", "/\bo", 248) -CHAR("oA", "o\bA", 197) -CHAR("oa", "o\ba", 229) -CHAR(":A", "\"\bA", 196) -CHAR(":E", "\"\bE", 203) -CHAR(":I", "\"\bI", 207) -CHAR(":O", "\"\bO", 214) -CHAR(":U", "\"\bU", 220) -CHAR(":a", "\"\ba", 228) -CHAR(":e", "\"\be", 235) -CHAR(":i", "\"\bi", 239) -CHAR(":o", "\"\bo", 246) -CHAR(":u", "\"\bu", 252) -CHAR(":y", "\"\by", 255) -CHAR("'A", "'\bA", 193) -CHAR("'E", "'\bE", 201) -CHAR("'I", "'\bI", 205) -CHAR("'O", "'\bO", 211) -CHAR("'U", "'\bU", 218) -CHAR("'a", "'\ba", 225) -CHAR("'e", "'\be", 233) -CHAR("'i", "'\bi", 237) -CHAR("'o", "'\bo", 243) -CHAR("'u", "'\bu", 250) -CHAR("^A", "^\bA", 194) -CHAR("^E", "^\bE", 202) -CHAR("^I", "^\bI", 206) -CHAR("^O", "^\bO", 212) -CHAR("^U", "^\bU", 219) -CHAR("^a", "^\ba", 226) -CHAR("^e", "^\be", 234) -CHAR("^i", "^\bi", 238) -CHAR("^o", "^\bo", 244) -CHAR("^u", "^\bu", 251) -CHAR("`A", "`\bA", 192) -CHAR("`E", "`\bE", 200) -CHAR("`I", "`\bI", 204) -CHAR("`O", "`\bO", 210) -CHAR("`U", "`\bU", 217) -CHAR("`a", "`\ba", 224) -CHAR("`e", "`\be", 232) -CHAR("`i", "`\bi", 236) -CHAR("`o", "`\bo", 242) -CHAR("`u", "`\bu", 249) -CHAR("~A", "~\bA", 195) -CHAR("~N", "~\bN", 209) -CHAR("~O", "~\bO", 213) -CHAR("~a", "~\ba", 227) -CHAR("~n", "~\bn", 241) -CHAR("~o", "~\bo", 245) - -/* Arrows and lines. */ -CHAR("<-", "<-", 8592) -CHAR("->", "->", 8594) -CHAR("<>", "<->", 8596) -CHAR("da", "|\bv", 8595) -CHAR("ua", "|\b^", 8593) -CHAR("va", "^v", 8597) -CHAR("lA", "<=", 8656) -CHAR("rA", "=>", 8658) -CHAR("hA", "<=>", 8660) -CHAR("dA", "=\bv", 8659) -CHAR("uA", "=\b^", 8657) -CHAR("vA", "^=v", 8661) - -/* Logic. */ -CHAR("AN", "^", 8743) -CHAR("OR", "v", 8744) -CHAR("no", "~", 172) -CHAR("tno", "~", 172) -CHAR("te", "3", 8707) -CHAR("fa", "-\bV", 8704) -CHAR("st", "-)", 8715) -CHAR("tf", ".:.", 8756) -CHAR("3d", ".:.", 8756) -CHAR("or", "|", 124) - -/* Mathematicals. */ -CHAR("pl", "+", 43) -CHAR("mi", "-", 8722) -CHAR("-", "-", 45) -CHAR("-+", "-+", 8723) -CHAR("+-", "+-", 177) -CHAR("t+-", "+-", 177) -CHAR("pc", ".", 183) -CHAR("md", ".", 8901) -CHAR("mu", "x", 215) -CHAR("tmu", "x", 215) -CHAR("c*", "O\bx", 8855) -CHAR("c+", "O\b+", 8853) -CHAR("di", "-:-", 247) -CHAR("tdi", "-:-", 247) -CHAR("f/", "/", 8260) -CHAR("**", "*", 8727) -CHAR("<=", "<=", 8804) -CHAR(">=", ">=", 8805) -CHAR("<<", "<<", 8810) -CHAR(">>", ">>", 8811) -CHAR("eq", "=", 61) -CHAR("!=", "!=", 8800) -CHAR("==", "==", 8801) -CHAR("ne", "!==", 8802) -CHAR("=~", "=~", 8773) -CHAR("|=", "-~", 8771) -CHAR("ap", "~", 8764) -CHAR("~~", "~~", 8776) -CHAR("~=", "~=", 8776) -CHAR("pt", "oc", 8733) -CHAR("es", "{}", 8709) -CHAR("mo", "E", 8712) -CHAR("nm", "!E", 8713) -CHAR("sb", "(=", 8834) -CHAR("nb", "(!=", 8836) -CHAR("sp", "=)", 8835) -CHAR("nc", "!=)", 8837) -CHAR("ib", "(=\b_", 8838) -CHAR("ip", "=\b_)", 8839) -CHAR("ca", "(^)", 8745) -CHAR("cu", "U", 8746) -CHAR("/_", "_\b/", 8736) -CHAR("pp", "_\b|", 8869) -CHAR("is", "'\b,\bI", 8747) -CHAR("integral", "'\b,\bI", 8747) -CHAR("sum", "E", 8721) -CHAR("product", "TT", 8719) -CHAR("coproduct", "U", 8720) -CHAR("gr", "V", 8711) -CHAR("sr", "\\/", 8730) -CHAR("sqrt", "\\/", 8730) -CHAR("lc", "|~", 8968) -CHAR("rc", "~|", 8969) -CHAR("lf", "|_", 8970) -CHAR("rf", "_|", 8971) -CHAR("if", "oo", 8734) -CHAR("Ah", "N", 8501) -CHAR("Im", "I", 8465) -CHAR("Re", "R", 8476) -CHAR("pd", "a", 8706) -CHAR("-h", "/h", 8463) -CHAR("12", "1/2", 189) -CHAR("14", "1/4", 188) -CHAR("34", "3/4", 190) - -/* Ligatures. */ -CHAR("ff", "ff", 64256) -CHAR("fi", "fi", 64257) -CHAR("fl", "fl", 64258) -CHAR("Fi", "ffi", 64259) -CHAR("Fl", "ffl", 64260) -CHAR("AE", "AE", 198) -CHAR("ae", "ae", 230) -CHAR("OE", "OE", 338) -CHAR("oe", "oe", 339) -CHAR("ss", "ss", 223) -CHAR("IJ", "IJ", 306) -CHAR("ij", "ij", 307) - -/* Special letters. */ -CHAR("-D", "-\bD", 208) -CHAR("Sd", "d", 240) -CHAR("TP", "Th", 222) -CHAR("Tp", "th", 254) -CHAR(".i", "i", 305) -CHAR(".j", "j", 567) - -/* Currency. */ -CHAR("Do", "$", 36) -CHAR("ct", "/\bc", 162) -CHAR("Eu", "EUR", 8364) -CHAR("eu", "EUR", 8364) -CHAR("Ye", "=\bY", 165) -CHAR("Po", "GBP", 163) -CHAR("Cs", "o\bx", 164) -CHAR("Fn", ",\bf", 402) - -/* Lines. */ -CHAR("ba", "|", 124) -CHAR("br", "|", 9474) -CHAR("ul", "_", 95) -CHAR("rn", "-", 8254) -CHAR("bb", "|", 166) -CHAR("sl", "/", 47) -CHAR("rs", "\\", 92) - -/* Text markers. */ -CHAR("ci", "O", 9675) -CHAR("bu", "+\bo", 8226) -CHAR("dd", "|\b=", 8225) -CHAR("dg", "|\b-", 8224) -CHAR("lz", "<>", 9674) -CHAR("sq", "[]", 9633) -CHAR("ps", "<par>", 182) -CHAR("sc", "<sec>", 167) -CHAR("lh", "<=", 9756) -CHAR("rh", "=>", 9758) -CHAR("at", "@", 64) -CHAR("sh", "#", 35) -CHAR("CR", "_|", 8629) -CHAR("OK", "\\/", 10003) - -/* Legal symbols. */ -CHAR("co", "(C)", 169) -CHAR("rg", "(R)", 174) -CHAR("tm", "tm", 8482) - -/* Punctuation. */ -CHAR(".", ".", 46) -CHAR("r!", "!", 161) -CHAR("r?", "?", 191) -CHAR("em", "--", 8212) -CHAR("en", "-", 8211) -CHAR("hy", "-", 8208) -CHAR("e", "\\", 92) - -/* Units. */ -CHAR("de", "<deg>", 176) -CHAR("%0", "%o", 8240) -CHAR("fm", "\'", 8242) -CHAR("sd", "''", 8243) -CHAR("mc", ",\bu", 181) - -CHAR_TBL_END diff --git a/contrib/mdocml/compat_err.c b/contrib/mdocml/compat_err.c new file mode 100644 index 0000000..d8b09cb --- /dev/null +++ b/contrib/mdocml/compat_err.c @@ -0,0 +1,112 @@ +#include "config.h" + +#if HAVE_ERR + +int dummy; + +#else + +/* $Id: compat_err.c,v 1.4 2015/11/26 07:42:11 schwarze Exp $ */ +/* + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static void vwarni(const char *, va_list); +static void vwarnxi(const char *, va_list); + +static void +vwarnxi(const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) + vfprintf(stderr, fmt, ap); +} + +static void +vwarni(const char *fmt, va_list ap) +{ + int sverrno; + + sverrno = errno; + vwarnxi(fmt, ap); + if (fmt != NULL) + fputs(": ", stderr); + fprintf(stderr, "%s\n", strerror(sverrno)); +} + +void +err(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarni(fmt, ap); + va_end(ap); + exit(eval); +} + +void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnxi(fmt, ap); + va_end(ap); + fputc('\n', stderr); + exit(eval); +} + +void +warn(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarni(fmt, ap); + va_end(ap); +} + +void +warnx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnxi(fmt, ap); + va_end(ap); + fputc('\n', stderr); +} + +#endif diff --git a/contrib/mdocml/compat_fgetln.c b/contrib/mdocml/compat_fgetln.c deleted file mode 100644 index 3760ab9..0000000 --- a/contrib/mdocml/compat_fgetln.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "config.h" - -#if HAVE_FGETLN - -int dummy; - -#else - -/* $NetBSD: fgetln.c,v 1.3 2006/09/25 07:18:17 lukem Exp $ */ - -/*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -char * -fgetln(fp, len) - FILE *fp; - size_t *len; -{ - static char *buf = NULL; - static size_t bufsiz = 0; - char *ptr; - - - if (buf == NULL) { - bufsiz = BUFSIZ; - if ((buf = malloc(bufsiz)) == NULL) - return NULL; - } - - if (fgets(buf, bufsiz, fp) == NULL) - return NULL; - - *len = 0; - while ((ptr = strchr(&buf[*len], '\n')) == NULL) { - size_t nbufsiz = bufsiz + BUFSIZ; - char *nbuf = realloc(buf, nbufsiz); - - if (nbuf == NULL) { - int oerrno = errno; - free(buf); - errno = oerrno; - buf = NULL; - return NULL; - } else - buf = nbuf; - - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) - return buf; - - bufsiz = nbufsiz; - } - - *len = (ptr - buf) + 1; - return buf; -} - -#endif diff --git a/contrib/mdocml/compat_fts.c b/contrib/mdocml/compat_fts.c index 194c565..ed95854 100644 --- a/contrib/mdocml/compat_fts.c +++ b/contrib/mdocml/compat_fts.c @@ -6,7 +6,7 @@ int dummy; #else -/* $Id: compat_fts.c,v 1.8 2015/02/07 07:53:01 schwarze Exp $ */ +/* $Id: compat_fts.c,v 1.9 2015/03/18 19:29:48 schwarze Exp $ */ /* $OpenBSD: fts.c,v 1.50 2015/01/16 16:48:51 deraadt Exp $ */ /*- @@ -60,7 +60,6 @@ static size_t fts_maxarglen(char * const *); static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); static unsigned short fts_stat(FTS *, FTSENT *); -static int fts_safe_changedir(FTS *, FTSENT *, int, const char *); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) #ifndef O_DIRECTORY @@ -74,8 +73,6 @@ static int fts_safe_changedir(FTS *, FTSENT *, int, const char *); #define ISSET(opt) (sp->fts_options & (opt)) #define SET(opt) (sp->fts_options |= (opt)) -#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) - FTS * fts_open(char * const *argv, int options, void *dummy) { @@ -146,17 +143,6 @@ fts_open(char * const *argv, int options, void *dummy) sp->fts_cur->fts_link = root; sp->fts_cur->fts_info = FTS_INIT; - /* - * If using chdir(2), grab a file descriptor pointing to dot to ensure - * that we can get back here; this could be avoided for some paths, - * but almost certainly not worth the effort. Slashes, symbolic links, - * and ".." are all fairly nasty problems. Note, if we can't get the - * descriptor we run anyway, just more slowly. - */ - if (!ISSET(FTS_NOCHDIR) && - (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0) - SET(FTS_NOCHDIR); - if (nitems == 0) free(parent); @@ -197,7 +183,6 @@ int fts_close(FTS *sp) { FTSENT *freep, *p; - int rfd, error = 0; /* * This still works if we haven't read anything -- the dummy structure @@ -213,25 +198,13 @@ fts_close(FTS *sp) free(p); } - /* Stash the original directory fd if needed. */ - rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd; - /* Free up child linked list, sort array, path buffer, stream ptr.*/ if (sp->fts_child) fts_lfree(sp->fts_child); free(sp->fts_path); free(sp); - /* Return to original directory, checking for error. */ - if (rfd != -1) { - int saved_errno; - error = fchdir(rfd); - saved_errno = errno; - (void)close(rfd); - errno = saved_errno; - } - - return (error); + return (0); } /* @@ -274,25 +247,11 @@ fts_read(FTS *sp) } /* - * Cd to the subdirectory. - * - * If have already read and now fail to chdir, whack the list - * to make the names come out right, and set the parent errno - * so the application will eventually get an error condition. - * Set the FTS_DONTCHDIR flag so that when we logically change - * directories back to the parent we don't do a chdir. - * * If haven't read do so. If the read fails, fts_build sets * FTS_STOP or the fts_info field of the node. */ if (sp->fts_child) { - if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { - p->fts_errno = errno; - p->fts_flags |= FTS_DONTCHDIR; - for (p = sp->fts_child; p; p = p->fts_link) - p->fts_accpath = - p->fts_parent->fts_accpath; - } + /* nothing */ } else if ((sp->fts_child = fts_build(sp)) == NULL) { if (ISSET(FTS_STOP)) return (NULL); @@ -313,10 +272,6 @@ next: tmp = p; * the root of the tree), and load the paths for the next root. */ if (p->fts_level == FTS_ROOTLEVEL) { - if (FCHDIR(sp, sp->fts_rfd)) { - SET(FTS_STOP); - return (NULL); - } fts_load(sp, p); return (sp->fts_cur = p); } @@ -352,23 +307,6 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); /* NUL terminate the pathname. */ sp->fts_path[p->fts_pathlen] = '\0'; - /* - * Return to the parent directory. If at a root node or came through - * a symlink, go back through the file descriptor. Otherwise, cd up - * one directory. - */ - if (p->fts_level == FTS_ROOTLEVEL) { - if (FCHDIR(sp, sp->fts_rfd)) { - SET(FTS_STOP); - sp->fts_cur = p; - return (NULL); - } - } else if (!(p->fts_flags & FTS_DONTCHDIR) && - fts_safe_changedir(sp, p->fts_parent, -1, "..")) { - SET(FTS_STOP); - sp->fts_cur = p; - return (NULL); - } p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); } @@ -414,7 +352,7 @@ fts_build(FTS *sp) DIR *dirp; void *oldaddr; size_t dlen, len, maxlen; - int nitems, cderrno, descend, level, doadjust; + int nitems, level, doadjust; int saved_errno; char *cp; @@ -432,32 +370,6 @@ fts_build(FTS *sp) } /* - * If we're going to need to stat anything or we want to descend - * and stay in the directory, chdir. If this fails we keep going, - * but set a flag so we don't chdir after the post-order visit. - * We won't be able to stat anything, but we can still return the - * names themselves. Note, that since fts_read won't be able to - * chdir into the directory, it will have to return different path - * names than before, i.e. "a/b" instead of "b". Since the node - * has already been visited in pre-order, have to wait until the - * post-order visit to return the error. There is a special case - * here, if there was nothing to stat then it's not an error to - * not be able to stat. This is all fairly nasty. If a program - * needed sorted entries or stat information, they had better be - * checking FTS_NS on the returned nodes. - */ - cderrno = 0; - if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) { - cur->fts_errno = errno; - cur->fts_flags |= FTS_DONTCHDIR; - descend = 0; - cderrno = errno; - (void)closedir(dirp); - dirp = NULL; - } else - descend = 1; - - /* * Figure out the max file name length that can be stored in the * current path -- the inner loop allocates more path as necessary. * We really wouldn't have to do the maxlen calculations here, we @@ -468,10 +380,8 @@ fts_build(FTS *sp) * each new name into the path. */ len = NAPPEND(cur); - if (ISSET(FTS_NOCHDIR)) { - cp = sp->fts_path + len; - *cp++ = '/'; - } + cp = sp->fts_path + len; + *cp++ = '/'; len++; maxlen = sp->fts_pathlen - len; @@ -518,8 +428,7 @@ mem1: saved_errno = errno; /* Did realloc() change the pointer? */ if (oldaddr != sp->fts_path) { doadjust = 1; - if (ISSET(FTS_NOCHDIR)) - cp = sp->fts_path + len; + cp = sp->fts_path + len; } maxlen = sp->fts_pathlen - len; } @@ -542,20 +451,11 @@ mem1: saved_errno = errno; return (NULL); } - if (cderrno) { - p->fts_info = FTS_NS; - p->fts_errno = cderrno; - p->fts_accpath = cur->fts_accpath; - } else { - /* Build a file name for fts_stat to stat. */ - if (ISSET(FTS_NOCHDIR)) { - p->fts_accpath = p->fts_path; - memmove(cp, p->fts_name, p->fts_namelen + 1); - } else - p->fts_accpath = p->fts_name; - /* Stat it. */ - p->fts_info = fts_stat(sp, p); - } + /* Build a file name for fts_stat to stat. */ + p->fts_accpath = p->fts_path; + memmove(cp, p->fts_name, p->fts_namelen + 1); + /* Stat it. */ + p->fts_info = fts_stat(sp, p); /* We walk in directory order so "ls -f" doesn't get upset. */ p->fts_link = NULL; @@ -581,26 +481,9 @@ mem1: saved_errno = errno; * If not changing directories, reset the path back to original * state. */ - if (ISSET(FTS_NOCHDIR)) { - if (len == sp->fts_pathlen || nitems == 0) - --cp; - *cp = '\0'; - } - - /* - * If descended after called from fts_children or after called from - * fts_read and nothing found, get back. At the root level we use - * the saved fd; if one of fts_open()'s arguments is a relative path - * to an empty directory, we wind up here with no other way back. If - * can't get back, we're done. - */ - if (descend && !nitems && - (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : - fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { - cur->fts_info = FTS_ERR; - SET(FTS_STOP); - return (NULL); - } + if (len == sp->fts_pathlen || nitems == 0) + --cp; + *cp = '\0'; /* If didn't find anything, return NULL. */ if (!nitems) { @@ -771,38 +654,4 @@ fts_maxarglen(char * const *argv) return (max + 1); } -/* - * Change to dir specified by fd or p->fts_accpath without getting - * tricked by someone changing the world out from underneath us. - * Assumes p->fts_dev and p->fts_ino are filled in. - */ -static int -fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path) -{ - int ret, oerrno, newfd; - struct stat sb; - - newfd = fd; - if (ISSET(FTS_NOCHDIR)) - return (0); - if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0) - return (-1); - if (fstat(newfd, &sb)) { - ret = -1; - goto bail; - } - if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { - errno = ENOENT; /* disinformation */ - ret = -1; - goto bail; - } - ret = fchdir(newfd); -bail: - oerrno = errno; - if (fd < 0) - (void)close(newfd); - errno = oerrno; - return (ret); -} - #endif diff --git a/contrib/mdocml/compat_fts.h b/contrib/mdocml/compat_fts.h index ce7ee62..1eed2ae 100644 --- a/contrib/mdocml/compat_fts.h +++ b/contrib/mdocml/compat_fts.h @@ -40,13 +40,12 @@ typedef struct { struct _ftsent *fts_child; /* linked list of children */ dev_t fts_dev; /* starting device # */ char *fts_path; /* path for this descent */ - int fts_rfd; /* fd for root */ size_t fts_pathlen; /* sizeof(path) */ #define FTS_NOCHDIR 0x0004 /* don't change directories */ #define FTS_PHYSICAL 0x0010 /* physical walk */ #define FTS_XDEV 0x0040 /* don't cross devices */ -#define FTS_OPTIONMASK 0x00ff /* valid user option mask */ +#define FTS_OPTIONMASK 0x0054 /* valid user option mask */ #define FTS_STOP 0x2000 /* (private) unrecoverable error */ int fts_options; /* fts_open options, global flags */ @@ -85,9 +84,6 @@ typedef struct _ftsent { #define FTS_SL 12 /* symbolic link */ unsigned short fts_info; /* user flags for FTSENT structure */ -#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ - unsigned short fts_flags; /* private flags for FTSENT structure */ - #define FTS_NOINSTR 3 /* no instructions */ #define FTS_SKIP 4 /* discard node */ unsigned short fts_instr; /* fts_set() instructions */ @@ -96,11 +92,10 @@ typedef struct _ftsent { char fts_name[1]; /* file name */ } FTSENT; -__BEGIN_DECLS + int fts_close(FTS *); FTS *fts_open(char * const *, int, void *); FTSENT *fts_read(FTS *); int fts_set(FTS *, FTSENT *, int); -__END_DECLS #endif /* !_FTS_H_ */ diff --git a/contrib/mdocml/compat_getline.c b/contrib/mdocml/compat_getline.c new file mode 100644 index 0000000..aed4754 --- /dev/null +++ b/contrib/mdocml/compat_getline.c @@ -0,0 +1,68 @@ +#include "config.h" + +#if HAVE_GETLINE + +int dummy; + +#else + +/* $Id: compat_getline.c,v 1.1 2015/11/07 20:52:52 schwarze Exp $ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +ssize_t +getline(char **buf, size_t *bufsz, FILE *fp) +{ + char *nbuf; + size_t nbufsz, pos; + int c; + + if (buf == NULL || bufsz == NULL) { + errno = EINVAL; + return -1; + } + + if (*buf == NULL) + *bufsz = 0; + else + **buf = '\0'; + + pos = 0; + for (;;) { + if (pos + 1 >= *bufsz) { + nbufsz = *bufsz ? *bufsz * 2 : BUFSIZ; + if ((nbuf = realloc(*buf, nbufsz)) == NULL) + return -1; + *buf = nbuf; + *bufsz = nbufsz; + } + if ((c = fgetc(fp)) == EOF) { + (*buf)[pos] = '\0'; + return pos > 0 && feof(fp) ? (ssize_t)pos : -1; + } + (*buf)[pos++] = c; + (*buf)[pos] = '\0'; + if (c == '\n') + return pos; + } +} + +#endif diff --git a/contrib/mdocml/compat_isblank.c b/contrib/mdocml/compat_isblank.c new file mode 100644 index 0000000..9e3c747 --- /dev/null +++ b/contrib/mdocml/compat_isblank.c @@ -0,0 +1,33 @@ +#include "config.h" + +#if HAVE_ISBLANK + +int dummy; + +#else + +/* $Id: compat_isblank.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int +isblank(int c) +{ + + return c == ' ' || c == '\t'; +} + +#endif diff --git a/contrib/mdocml/compat_mkdtemp.c b/contrib/mdocml/compat_mkdtemp.c new file mode 100644 index 0000000..1fcb325 --- /dev/null +++ b/contrib/mdocml/compat_mkdtemp.c @@ -0,0 +1,61 @@ +#include "config.h" + +#if HAVE_MKDTEMP + +int dummy; + +#else + +/* $Id: compat_mkdtemp.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */ +/* + * Copyright (c) 2015 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. + * + * The algorithm of this function is inspired by OpenBSD mkdtemp(3) + * by Theo de Raadt and Todd Miller, but the code differs. + */ + +#include <sys/stat.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +char * +mkdtemp(char *path) +{ + char *start, *cp; + unsigned int tries; + + start = strchr(path, '\0'); + while (start > path && start[-1] == 'X') + start--; + + for (tries = INT_MAX; tries; tries--) { + if (mktemp(path) == NULL) { + errno = EEXIST; + return NULL; + } + if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0) + return path; + if (errno != EEXIST) + return NULL; + for (cp = start; *cp != '\0'; cp++) + *cp = 'X'; + } + errno = EEXIST; + return NULL; +} + +#endif diff --git a/contrib/mdocml/compat_ohash.h b/contrib/mdocml/compat_ohash.h index e3124c9..58fb220 100644 --- a/contrib/mdocml/compat_ohash.h +++ b/contrib/mdocml/compat_ohash.h @@ -49,7 +49,6 @@ struct ohash { * a hashing table index (opaque) to be used in find/insert/remove. * The keys are stored at a known position in the client data. */ -__BEGIN_DECLS void ohash_init(struct ohash *, unsigned, struct ohash_info *); void ohash_delete(struct ohash *); @@ -69,5 +68,5 @@ uint32_t ohash_interval(const char *, const char **); unsigned int ohash_qlookupi(struct ohash *, const char *, const char **); unsigned int ohash_qlookup(struct ohash *, const char *); -__END_DECLS + #endif diff --git a/contrib/mdocml/compat_progname.c b/contrib/mdocml/compat_progname.c new file mode 100644 index 0000000..9840cc7 --- /dev/null +++ b/contrib/mdocml/compat_progname.c @@ -0,0 +1,42 @@ +#include "config.h" + +#if HAVE_PROGNAME + +int dummy; + +#else + +/* $Id: compat_progname.c,v 1.1 2015/11/06 16:30:33 schwarze Exp $ */ +/* + * Copyright (c) 2015 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. + */ + +static const char *progname; + +void +setprogname(const char *name) +{ + + progname = name; +} + +const char * +getprogname(void) +{ + + return progname; +} + +#endif diff --git a/contrib/mdocml/compat_sqlite3_errstr.c b/contrib/mdocml/compat_sqlite3_errstr.c index c623848..8a6ace2 100644 --- a/contrib/mdocml/compat_sqlite3_errstr.c +++ b/contrib/mdocml/compat_sqlite3_errstr.c @@ -10,7 +10,7 @@ const char * sqlite3_errstr(int rc) { - return(rc ? "unknown error" : "not an error"); + return rc ? "unknown error" : "not an error"; } #endif diff --git a/contrib/mdocml/compat_stringlist.c b/contrib/mdocml/compat_stringlist.c new file mode 100644 index 0000000..17eba77 --- /dev/null +++ b/contrib/mdocml/compat_stringlist.c @@ -0,0 +1,119 @@ +#include "config.h" + +#if HAVE_STRINGLIST + +int dummy; + +#else + +/* $Id: compat_stringlist.c,v 1.6 2015/11/07 14:22:29 schwarze Exp $ */ +/* + * Copyright (c) 1994 Christos Zoulas <christos@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if HAVE_ERR +#include <err.h> +#endif +#include <stdlib.h> +#include <string.h> +#include "compat_stringlist.h" + +#define _SL_CHUNKSIZE 20 + +/* + * sl_init(): Initialize a string list + */ +StringList * +sl_init(void) +{ + StringList *sl; + + sl = malloc(sizeof(StringList)); + if (sl == NULL) + err(1, "stringlist"); + + sl->sl_cur = 0; + sl->sl_max = _SL_CHUNKSIZE; + sl->sl_str = reallocarray(NULL, sl->sl_max, sizeof(char *)); + if (sl->sl_str == NULL) + err(1, "stringlist"); + return sl; +} + + +/* + * sl_add(): Add an item to the string list + */ +int +sl_add(StringList *sl, char *name) +{ + if (sl->sl_cur == sl->sl_max - 1) { + sl->sl_max += _SL_CHUNKSIZE; + sl->sl_str = reallocarray(sl->sl_str, + sl->sl_max, sizeof(char *)); + if (sl->sl_str == NULL) + return (-1); + } + sl->sl_str[sl->sl_cur++] = name; + return (0); +} + + +/* + * sl_free(): Free a stringlist + */ +void +sl_free(StringList *sl, int all) +{ + size_t i; + + if (sl == NULL) + return; + if (sl->sl_str) { + if (all) + for (i = 0; i < sl->sl_cur; i++) + free(sl->sl_str[i]); + free(sl->sl_str); + } + free(sl); +} + + +/* + * sl_find(): Find a name in the string list + */ +char * +sl_find(StringList *sl, const char *name) +{ + size_t i; + + for (i = 0; i < sl->sl_cur; i++) + if (strcmp(sl->sl_str[i], name) == 0) + return sl->sl_str[i]; + + return NULL; +} + +#endif diff --git a/contrib/mdocml/compat_stringlist.h b/contrib/mdocml/compat_stringlist.h new file mode 100644 index 0000000..f04e843 --- /dev/null +++ b/contrib/mdocml/compat_stringlist.h @@ -0,0 +1,45 @@ +/* $Id: compat_stringlist.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */ +/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */ + +/* + * Copyright (c) 1994 Christos Zoulas <christos@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> + +/* + * Simple string list + */ +typedef struct _stringlist { + char **sl_str; + size_t sl_max; + size_t sl_cur; +} StringList; + + +StringList *sl_init(void); +int sl_add(StringList *, char *); +void sl_free(StringList *, int); +char *sl_find(StringList *, const char *); diff --git a/contrib/mdocml/compat_vasprintf.c b/contrib/mdocml/compat_vasprintf.c new file mode 100644 index 0000000..9040822 --- /dev/null +++ b/contrib/mdocml/compat_vasprintf.c @@ -0,0 +1,56 @@ +#include "config.h" + +#if HAVE_VASPRINTF + +int dummy; + +#else + +/* $Id: compat_vasprintf.c,v 1.3 2015/10/06 18:32:19 schwarze Exp $ */ +/* + * Copyright (c) 2015 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. + * + * This fallback implementation is not efficient: + * It does the formatting twice. + * Short of fiddling with the unknown internals of the system's + * printf(3) or completely reimplementing printf(3), i can't think + * of another portable solution. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +int +vasprintf(char **ret, const char *format, va_list ap) +{ + char buf[2]; + va_list ap2; + int sz; + + va_copy(ap2, ap); + sz = vsnprintf(buf, sizeof(buf), format, ap2); + va_end(ap2); + + if (sz != -1 && (*ret = malloc(sz + 1)) != NULL) { + if (vsnprintf(*ret, sz + 1, format, ap) == sz) + return sz; + free(*ret); + } + *ret = NULL; + return -1; +} + +#endif diff --git a/contrib/mdocml/config.h b/contrib/mdocml/config.h index e7d3c63..6252b8a 100644 --- a/contrib/mdocml/config.h +++ b/contrib/mdocml/config.h @@ -1,3 +1,7 @@ +#ifdef __cplusplus +#error "Do not use C++. See the INSTALL file." +#endif + #ifndef MANDOC_CONFIG_H #define MANDOC_CONFIG_H @@ -6,19 +10,30 @@ #endif #include <sys/types.h> +#include <stdio.h> +#define MAN_CONF_FILE "/etc/man.conf" #define HAVE_DIRENT_NAMLEN 1 -#define HAVE_FGETLN 1 +#define HAVE_ERR 1 #define HAVE_FTS 1 +#define HAVE_GETLINE 1 #define HAVE_GETSUBOPT 1 +#define HAVE_ISBLANK 1 +#define HAVE_MKDTEMP 1 #define HAVE_MMAP 1 +#define HAVE_PLEDGE 0 +#define HAVE_PROGNAME 1 #define HAVE_REALLOCARRAY 1 +#define HAVE_REWB_BSD 0 +#define HAVE_REWB_SYSV 0 #define HAVE_STRCASESTR 1 +#define HAVE_STRINGLIST 1 #define HAVE_STRLCAT 1 #define HAVE_STRLCPY 1 #define HAVE_STRPTIME 1 #define HAVE_STRSEP 1 #define HAVE_STRTONUM 1 +#define HAVE_VASPRINTF 1 #define HAVE_WCHAR 1 #define HAVE_SQLITE3 1 #define HAVE_SQLITE3_ERRSTR 0 @@ -26,26 +41,12 @@ #define HAVE_MANPATH 1 #define BINM_APROPOS "apropos" +#define BINM_MAKEWHATIS "makewhatis" #define BINM_MAN "man" +#define BINM_SOELIM "soelim" #define BINM_WHATIS "whatis" -#define BINM_MAKEWHATIS "makewhatis" - -#if !defined(__BEGIN_DECLS) -# ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# else -# define __BEGIN_DECLS -# endif -#endif -#if !defined(__END_DECLS) -# ifdef __cplusplus -# define __END_DECLS } -# else -# define __END_DECLS -# endif -#endif -extern void *reallocarray(void *, size_t, size_t); +extern ssize_t getline(char **, size_t *, FILE *); extern const char *sqlite3_errstr(int); #endif /* MANDOC_CONFIG_H */ diff --git a/contrib/mdocml/config.log b/contrib/mdocml/config.log new file mode 100644 index 0000000..1f7e116 --- /dev/null +++ b/contrib/mdocml/config.log @@ -0,0 +1,210 @@ +configure.local: no (fully automatic configuration) + +dirent-namlen: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-dirent-namlen test-dirent-namlen.c +dirent-namlen: cc succeeded +dirent-namlen: yes + +err: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-err test-err.c +err: cc succeeded +test-err: 1. warnx +test-err: 2. warn: No error: 0 +test-err: 3. err: No error: 0 +err: yes + +fts: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-fts test-fts.c +fts: cc succeeded +fts: yes + +getline: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-getline test-getline.c +test-getline.c:12:9: error: implicit declaration of function 'getline' is invalid in C99 [-Werror,-Wimplicit-function-declaration] + return getline(&line, &linesz, stdin) != -1; + ^ +1 error generated. +getline: cc failed with 1 + +getsubopt: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-getsubopt test-getsubopt.c +getsubopt: cc succeeded +getsubopt: yes + +isblank: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-isblank test-isblank.c +isblank: cc succeeded +isblank: yes + +mkdtemp: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-mkdtemp test-mkdtemp.c +mkdtemp: cc succeeded +mkdtemp: yes + +mmap: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-mmap test-mmap.c +mmap: cc succeeded +mmap: yes + +pledge: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-pledge test-pledge.c +test-pledge.c:6:11: error: implicit declaration of function 'pledge' is invalid in C99 [-Werror,-Wimplicit-function-declaration] + return !!pledge("stdio", NULL); + ^ +1 error generated. +pledge: cc failed with 1 + +progname: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-progname test-progname.c +progname: cc succeeded +progname: yes + +reallocarray: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-reallocarray test-reallocarray.c +reallocarray: cc succeeded +reallocarray: yes + +rewb-bsd: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-rewb-bsd test-rewb-bsd.c +test-rewb-bsd.c:11:42: error: use of undeclared identifier 'NULL' + if (regexec(&re, "the word is here", 0, NULL, 0)) + ^ +test-rewb-bsd.c:13:35: error: use of undeclared identifier 'NULL' + if (regexec(&re, "same word", 0, NULL, 0)) + ^ +test-rewb-bsd.c:15:36: error: use of undeclared identifier 'NULL' + if (regexec(&re, "word again", 0, NULL, 0)) + ^ +test-rewb-bsd.c:17:30: error: use of undeclared identifier 'NULL' + if (regexec(&re, "word", 0, NULL, 0)) + ^ +test-rewb-bsd.c:19:31: error: use of undeclared identifier 'NULL' + if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH) + ^ +test-rewb-bsd.c:21:31: error: use of undeclared identifier 'NULL' + if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH) + ^ +test-rewb-bsd.c:23:34: error: use of undeclared identifier 'NULL' + if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH) + ^ +7 errors generated. +rewb-bsd: cc failed with 1 + +rewb-sysv: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-rewb-sysv test-rewb-sysv.c +test-rewb-sysv.c:11:42: error: use of undeclared identifier 'NULL' + if (regexec(&re, "the word is here", 0, NULL, 0)) + ^ +test-rewb-sysv.c:13:35: error: use of undeclared identifier 'NULL' + if (regexec(&re, "same word", 0, NULL, 0)) + ^ +test-rewb-sysv.c:15:36: error: use of undeclared identifier 'NULL' + if (regexec(&re, "word again", 0, NULL, 0)) + ^ +test-rewb-sysv.c:17:30: error: use of undeclared identifier 'NULL' + if (regexec(&re, "word", 0, NULL, 0)) + ^ +test-rewb-sysv.c:19:31: error: use of undeclared identifier 'NULL' + if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH) + ^ +test-rewb-sysv.c:21:31: error: use of undeclared identifier 'NULL' + if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH) + ^ +test-rewb-sysv.c:23:34: error: use of undeclared identifier 'NULL' + if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH) + ^ +7 errors generated. +rewb-sysv: cc failed with 1 + +strcasestr: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strcasestr test-strcasestr.c +strcasestr: cc succeeded +strcasestr: yes + +stringlist: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-stringlist test-stringlist.c +test-stringlist.c:26:26: error: use of undeclared identifier 'NULL' + if ((sl = sl_init()) == NULL) + ^ +1 error generated. +stringlist: cc failed with 1 + +strlcat: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strlcat test-strlcat.c +strlcat: cc succeeded +strlcat: yes + +strlcpy: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strlcpy test-strlcpy.c +strlcpy: cc succeeded +strlcpy: yes + +strptime: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strptime test-strptime.c +strptime: cc succeeded +strptime: yes + +strsep: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strsep test-strsep.c +strsep: cc succeeded +strsep: yes + +strtonum: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-strtonum test-strtonum.c +strtonum: cc succeeded +strtonum: yes + +vasprintf: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-vasprintf test-vasprintf.c +vasprintf: cc succeeded +vasprintf: yes + +wchar: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-wchar test-wchar.c +wchar: cc succeeded +*wchar: yes + +sqlite3: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -lsqlite3 -o test-sqlite3 test-sqlite3.c +test-sqlite3.c:20:10: fatal error: 'sqlite3.h' file not found +#include <sqlite3.h> + ^ +1 error generated. +sqlite3: cc failed with 1 + +sqlite3: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -I/usr/local/include -L/usr/local/lib -lsqlite3 -o test-sqlite3 test-sqlite3.c +sqlite3: cc succeeded +sqlite3: yes + +sqlite3_errstr: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -L/usr/local/lib -lsqlite3 -o test-sqlite3_errstr test-sqlite3_errstr.c +test-sqlite3_errstr.c:2:10: fatal error: 'sqlite3.h' file not found +#include <sqlite3.h> + ^ +1 error generated. +sqlite3_errstr: cc failed with 1 + +ohash: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -o test-ohash test-ohash.c +test-ohash.c:4:10: fatal error: 'ohash.h' file not found +#include <ohash.h> + ^ +1 error generated. +ohash: cc failed with 1 + +ohash: testing... +cc -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -Wno-unused -Werror -lutil -o test-ohash test-ohash.c +test-ohash.c:4:10: fatal error: 'ohash.h' file not found +#include <ohash.h> + ^ +1 error generated. +ohash: cc failed with 1 + +DBLIB="-L/usr/local/lib -lsqlite3 -lz" + +/usr/share/man:/usr/local/man:/usr/share/openssl/man:/usr/local/lib/perl5/site_perl/man:/usr/local/lib/perl5/5.20/perl/man:/usr/local/share/xpdf/man +manpath: yes + +config.h: written +Makefile.local: written diff --git a/contrib/mdocml/configure b/contrib/mdocml/configure index fb2dabc..21997fc 100755 --- a/contrib/mdocml/configure +++ b/contrib/mdocml/configure @@ -16,8 +16,8 @@ set -e -[ -e config.log ] && mv config.log config.log.old -[ -e config.h ] && mv config.h config.h.old +[ -w config.log ] && mv config.log config.log.old +[ -w config.h ] && mv config.h config.h.old # Output file descriptor usage: # 1 (stdout): config.h, Makefile.local @@ -31,6 +31,7 @@ echo "config.log: writing..." # Initialize all variables here, # such that nothing can leak in from the environment. +MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man" OSNAME= CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make -f -` @@ -42,17 +43,26 @@ BUILD_DB=1 BUILD_CGI=0 HAVE_DIRENT_NAMLEN= -HAVE_FGETLN= +HAVE_ERR= HAVE_FTS= +HAVE_GETLINE= HAVE_GETSUBOPT= +HAVE_ISBLANK= +HAVE_MKDTEMP= HAVE_MMAP= +HAVE_PLEDGE= +HAVE_PROGNAME= HAVE_REALLOCARRAY= +HAVE_REWB_BSD= +HAVE_REWB_SYSV= HAVE_STRCASESTR= +HAVE_STRINGLIST= HAVE_STRLCAT= HAVE_STRLCPY= HAVE_STRPTIME= HAVE_STRSEP= HAVE_STRTONUM= +HAVE_VASPRINTF= HAVE_WCHAR= HAVE_SQLITE3= @@ -66,7 +76,6 @@ SBINDIR= INCLUDEDIR= LIBDIR= MANDIR= -EXAMPLEDIR= HOMEBREWDIR= WWWPREFIX="/var/www" @@ -74,10 +83,12 @@ HTDOCDIR= CGIBINDIR= BINM_APROPOS="apropos" +BINM_MAKEWHATIS="makewhatis" BINM_MAN="man" +BINM_SOELIM="soelim" BINM_WHATIS="whatis" -BINM_MAKEWHATIS="makewhatis" MANM_MAN="man" +MANM_MANCONF="man.conf" MANM_MDOC="mdoc" MANM_ROFF="roff" MANM_EQN="eqn" @@ -91,7 +102,7 @@ INSTALL_DATA= # --- manual settings from configure.local ----------------------------- -if [ -e ./configure.local ]; then +if [ -r ./configure.local ]; then echo "configure.local: reading..." 1>&2 echo "configure.local: reading..." 1>&3 cat ./configure.local 1>&3 @@ -164,17 +175,26 @@ runtest() { # --- library functions --- runtest dirent-namlen DIRENT_NAMLEN || true -runtest fgetln FGETLN || true +runtest err ERR || true runtest fts FTS || true +runtest getline GETLINE || true runtest getsubopt GETSUBOPT || true +runtest isblank ISBLANK || true +runtest mkdtemp MKDTEMP || true runtest mmap MMAP || true +runtest pledge PLEDGE || true +runtest progname PROGNAME || true runtest reallocarray REALLOCARRAY || true +runtest rewb-bsd REWB_BSD || true +runtest rewb-sysv REWB_SYSV || true runtest strcasestr STRCASESTR || true +runtest stringlist STRINGLIST || true runtest strlcat STRLCAT || true runtest strlcpy STRLCPY || true runtest strptime STRPTIME || true runtest strsep STRSEP || true runtest strtonum STRTONUM || true +runtest vasprintf VASPRINTF || true runtest wchar WCHAR || true # --- sqlite3 --- @@ -228,9 +248,9 @@ fi # --- DBLIB --- if [ ${BUILD_DB} -eq 0 ]; then - DBLIB= + DBLIB="-lz" elif [ -z "${DBLIB}" ]; then - DBLIB="${DETECTLIB}" + DBLIB="${DETECTLIB} -lz" echo "DBLIB=\"${DBLIB}\"" 1>&2 echo "DBLIB=\"${DBLIB}\"" 1>&3 echo 1>&3 @@ -256,6 +276,10 @@ fi exec > config.h cat << __HEREDOC__ +#ifdef __cplusplus +#error "Do not use C++. See the INSTALL file." +#endif + #ifndef MANDOC_CONFIG_H #define MANDOC_CONFIG_H @@ -265,28 +289,40 @@ cat << __HEREDOC__ __HEREDOC__ -[ ${HAVE_FGETLN} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \ +[ ${HAVE_GETLINE} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \ ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \ && echo "#include <sys/types.h>" -[ ${HAVE_FGETLN} -eq 0 ] && echo "#include <stdio.h>" +[ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>" +[ ${HAVE_GETLINE} -eq 0 ] && echo "#include <stdio.h>" echo +echo "#define MAN_CONF_FILE \"/etc/${MANM_MANCONF}\"" +echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\"" [ -n "${OSNAME}" ] && echo "#define OSNAME \"${OSNAME}\"" [ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\"" cat << __HEREDOC__ #define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN} -#define HAVE_FGETLN ${HAVE_FGETLN} +#define HAVE_ERR ${HAVE_ERR} #define HAVE_FTS ${HAVE_FTS} +#define HAVE_GETLINE ${HAVE_GETLINE} #define HAVE_GETSUBOPT ${HAVE_GETSUBOPT} +#define HAVE_ISBLANK ${HAVE_ISBLANK} +#define HAVE_MKDTEMP ${HAVE_MKDTEMP} #define HAVE_MMAP ${HAVE_MMAP} +#define HAVE_PLEDGE ${HAVE_PLEDGE} +#define HAVE_PROGNAME ${HAVE_PROGNAME} #define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} +#define HAVE_REWB_BSD ${HAVE_REWB_BSD} +#define HAVE_REWB_SYSV ${HAVE_REWB_SYSV} #define HAVE_STRCASESTR ${HAVE_STRCASESTR} +#define HAVE_STRINGLIST ${HAVE_STRINGLIST} #define HAVE_STRLCAT ${HAVE_STRLCAT} #define HAVE_STRLCPY ${HAVE_STRLCPY} #define HAVE_STRPTIME ${HAVE_STRPTIME} #define HAVE_STRSEP ${HAVE_STRSEP} #define HAVE_STRTONUM ${HAVE_STRTONUM} +#define HAVE_VASPRINTF ${HAVE_VASPRINTF} #define HAVE_WCHAR ${HAVE_WCHAR} #define HAVE_SQLITE3 ${HAVE_SQLITE3} #define HAVE_SQLITE3_ERRSTR ${HAVE_SQLITE3_ERRSTR} @@ -294,33 +330,37 @@ cat << __HEREDOC__ #define HAVE_MANPATH ${HAVE_MANPATH} #define BINM_APROPOS "${BINM_APROPOS}" +#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}" #define BINM_MAN "${BINM_MAN}" +#define BINM_SOELIM "${BINM_SOELIM}" #define BINM_WHATIS "${BINM_WHATIS}" -#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}" - -#if !defined(__BEGIN_DECLS) -# ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# else -# define __BEGIN_DECLS -# endif -#endif -#if !defined(__END_DECLS) -# ifdef __cplusplus -# define __END_DECLS } -# else -# define __END_DECLS -# endif -#endif __HEREDOC__ -[ ${HAVE_FGETLN} -eq 0 ] && \ - echo "extern char *fgetln(FILE *, size_t *);" +if [ ${HAVE_ERR} -eq 0 ]; then + echo "extern void err(int, const char *, ...);" + echo "extern void errx(int, const char *, ...);" + echo "extern void warn(const char *, ...);" + echo "extern void warnx(const char *, ...);" +fi + +[ ${HAVE_GETLINE} -eq 0 ] && \ + echo "extern ssize_t getline(char **, size_t *, FILE *);" [ ${HAVE_GETSUBOPT} -eq 0 ] && \ echo "extern int getsubopt(char **, char * const *, char **);" +[ ${HAVE_ISBLANK} -eq 0 ] && \ + echo "extern int isblank(int);" + +[ ${HAVE_MKDTEMP} -eq 0 ] && \ + echo "extern char *mkdtemp(char *);" + +if [ ${HAVE_PROGNAME} -eq 0 ]; then + echo "extern const char *getprogname(void);" + echo "extern void setprogname(const char *);" +fi + [ ${HAVE_REALLOCARRAY} -eq 0 ] && \ echo "extern void *reallocarray(void *, size_t, size_t);" @@ -342,6 +382,9 @@ __HEREDOC__ [ ${HAVE_STRTONUM} -eq 0 ] && \ echo "extern long long strtonum(const char *, long long, long long, const char **);" +[ ${HAVE_VASPRINTF} -eq 0 ] && \ + echo "extern int vasprintf(char **, const char *, va_list);" + echo echo "#endif /* MANDOC_CONFIG_H */" @@ -357,7 +400,6 @@ exec > Makefile.local [ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include/mandoc" [ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib/mandoc" [ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man" -[ -z "${EXAMPLEDIR}" ] && EXAMPLEDIR="${PREFIX}/share/examples/mandoc" [ -z "${HTDOCDIR}" ] && HTDOCDIR="${WWWPREFIX}/htdocs" [ -z "${CGIBINDIR}" ] && CGIBINDIR="${WWWPREFIX}/cgi-bin" @@ -382,6 +424,7 @@ INSTALL_TARGETS="base-install" cat << __HEREDOC__ BUILD_TARGETS = ${BUILD_TARGETS} INSTALL_TARGETS = ${INSTALL_TARGETS} +CC = ${CC} CFLAGS = ${CFLAGS} DBLIB = ${DBLIB} STATIC = ${STATIC} @@ -391,15 +434,16 @@ SBINDIR = ${SBINDIR} INCLUDEDIR = ${INCLUDEDIR} LIBDIR = ${LIBDIR} MANDIR = ${MANDIR} -EXAMPLEDIR = ${EXAMPLEDIR} WWWPREFIX = ${WWWPREFIX} HTDOCDIR = ${HTDOCDIR} CGIBINDIR = ${CGIBINDIR} BINM_APROPOS = ${BINM_APROPOS} +BINM_MAKEWHATIS = ${BINM_MAKEWHATIS} BINM_MAN = ${BINM_MAN} +BINM_SOELIM = ${BINM_SOELIM} BINM_WHATIS = ${BINM_WHATIS} -BINM_MAKEWHATIS = ${BINM_MAKEWHATIS} MANM_MAN = ${MANM_MAN} +MANM_MANCONF = ${MANM_MANCONF} MANM_MDOC = ${MANM_MDOC} MANM_ROFF = ${MANM_ROFF} MANM_EQN = ${MANM_EQN} diff --git a/contrib/mdocml/configure.local.example b/contrib/mdocml/configure.local.example index bb39159..de9f08f 100644 --- a/contrib/mdocml/configure.local.example +++ b/contrib/mdocml/configure.local.example @@ -1,4 +1,4 @@ -# $Id: configure.local.example,v 1.6 2015/02/16 14:56:22 schwarze Exp $ +# $Id: configure.local.example,v 1.10 2015/11/07 13:14:21 schwarze Exp $ # # Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> # @@ -48,6 +48,13 @@ HAVE_WCHAR=1 HAVE_WCHAR=0 +# When man(1) or apropos(1) is called without -m and -M options, +# MANPATH is not set in the environment, man.conf(5) is not available +# and manpath(1) not used, manuals are searched for in the following +# directory trees by default. + +MANPATH_DEFAULT="/usr/share/man:/usr/X11R6/man:/usr/local/man" + # In manual pages written in the mdoc(7) language, the operating system # version is displayed in the page footer line. If an operating system # is specified as an argument to the .Os macro, that is always used. @@ -72,7 +79,6 @@ SBINDIR="${PREFIX}/sbin" INCLUDEDIR="${PREFIX}/include/mandoc" LIBDIR="${PREFIX}/lib/mandoc" MANDIR="${PREFIX}/man" -EXAMPLEDIR="${PREFIX}/share/examples/mandoc" # The man(1) utility needs to know where the manuals reside. # We know of two ways to tell it: via manpath(1) or man.conf(5). @@ -89,6 +95,11 @@ HAVE_MANPATH=1 # man(1), makewhatis(8), and apropos(1) will not work properly. HAVE_MANPATH=0 +# Some distributions may want to avoid naming conflicts +# with the configuration files of other man(1) implementations. +# This changes the name of the installed section 5 manual page as well. +MANM_MANCONF="mandoc.conf" # default is "man.conf" + # Some distributions may want to avoid naming conflicts among manuals. # If you want to change the names of installed section 7 manual pages, # the following alternative names are suggested. @@ -103,13 +114,14 @@ MANM_EQN="mandoc_eqn" # default is "eqn" MANM_TBL="mandoc_tbl" # default is "tbl" # Some distributions may want to avoid naming conflicts -# with another man(1) utility. -# If you want to change the name of the binary program, -# the following alternative name is suggested. -# Using a different name is possible as well. -# This changes the name of the installed section 1 manual page as well. +# with other man(1) and soelim(1) utilities. +# If you want to change the names of binary programs, +# the following alternative names are suggested. +# Using different names is possible as well. +# This changes the names of the installed section 1 manual pages as well. BINM_MAN=mman # default is "man" +BINM_SOELIM=msoelim # default is "soelim" # It is possible to change the utility program used for installation # and the modes files are installed with. The defaults are: diff --git a/contrib/mdocml/demandoc.c b/contrib/mdocml/demandoc.c index f515931..13b7890 100644 --- a/contrib/mdocml/demandoc.c +++ b/contrib/mdocml/demandoc.c @@ -1,4 +1,4 @@ -/* $Id: demandoc.c,v 1.15 2015/02/10 08:05:30 schwarze Exp $ */ +/* $Id: demandoc.c,v 1.26 2016/01/08 02:53:13 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -26,14 +26,15 @@ #include <string.h> #include <unistd.h> +#include "roff.h" #include "man.h" #include "mdoc.h" #include "mandoc.h" static void pline(int, int *, int *, int); -static void pman(const struct man_node *, int *, int *, int); +static void pman(const struct roff_node *, int *, int *, int); static void pmandoc(struct mparse *, int, const char *, int); -static void pmdoc(const struct mdoc_node *, int *, int *, int); +static void pmdoc(const struct roff_node *, int *, int *, int); static void pstring(const char *, int, int *, int); static void usage(void); @@ -43,7 +44,6 @@ int main(int argc, char *argv[]) { struct mparse *mp; - struct mchars *mchars; int ch, fd, i, list; extern int optind; @@ -72,14 +72,14 @@ main(int argc, char *argv[]) break; default: usage(); - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; } argc -= optind; argv += optind; - mchars = mchars_alloc(); - mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, NULL); + mchars_alloc(); + mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, NULL); assert(mp); if (argc < 1) @@ -87,7 +87,7 @@ main(int argc, char *argv[]) for (i = 0; i < argc; i++) { mparse_reset(mp); - if (mparse_open(mp, &fd, argv[i]) != MANDOCLEVEL_OK) { + if ((fd = mparse_open(mp, argv[i])) == -1) { perror(argv[i]); continue; } @@ -95,8 +95,8 @@ main(int argc, char *argv[]) } mparse_free(mp); - mchars_free(mchars); - return((int)MANDOCLEVEL_OK); + mchars_free(); + return (int)MANDOCLEVEL_OK; } static void @@ -109,21 +109,24 @@ usage(void) static void pmandoc(struct mparse *mp, int fd, const char *fn, int list) { - struct mdoc *mdoc; - struct man *man; + struct roff_man *man; int line, col; mparse_readfd(mp, fd, fn); - mparse_result(mp, &mdoc, &man, NULL); + close(fd); + mparse_result(mp, &man, NULL); line = 1; col = 0; - if (mdoc) - pmdoc(mdoc_node(mdoc), &line, &col, list); - else if (man) - pman(man_node(man), &line, &col, list); - else + if (man == NULL) return; + if (man->macroset == MACROSET_MDOC) { + mdoc_validate(man); + pmdoc(man->first->child, &line, &col, list); + } else { + man_validate(man); + pman(man->first->child, &line, &col, list); + } if ( ! list) putchar('\n'); @@ -233,13 +236,13 @@ pline(int line, int *linep, int *col, int list) } static void -pmdoc(const struct mdoc_node *p, int *line, int *col, int list) +pmdoc(const struct roff_node *p, int *line, int *col, int list) { for ( ; p; p = p->next) { if (MDOC_LINE & p->flags) pline(p->line, line, col, list); - if (MDOC_TEXT == p->type) + if (ROFFT_TEXT == p->type) pstring(p->string, p->pos, col, list); if (p->child) pmdoc(p->child, line, col, list); @@ -247,13 +250,13 @@ pmdoc(const struct mdoc_node *p, int *line, int *col, int list) } static void -pman(const struct man_node *p, int *line, int *col, int list) +pman(const struct roff_node *p, int *line, int *col, int list) { for ( ; p; p = p->next) { if (MAN_LINE & p->flags) pline(p->line, line, col, list); - if (MAN_TEXT == p->type) + if (ROFFT_TEXT == p->type) pstring(p->string, p->pos, col, list); if (p->child) pman(p->child, line, col, list); diff --git a/contrib/mdocml/eqn.7 b/contrib/mdocml/eqn.7 index 73c4885..e3aad72 100644 --- a/contrib/mdocml/eqn.7 +++ b/contrib/mdocml/eqn.7 @@ -1,4 +1,4 @@ -.\" $Id: eqn.7,v 1.34 2015/03/09 20:17:23 schwarze Exp $ +.\" $Id: eqn.7,v 1.35 2015/03/30 16:06:14 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2014 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: March 9 2015 $ +.Dd $Mdocdate: March 30 2015 $ .Dt EQN 7 .Os .Sh NAME @@ -146,7 +146,7 @@ is used as the delimiter for the value .Ar val . This allows for arbitrary enclosure of terms (not just quotes), such as .Pp -.D1 Cm define Ar foo 'bar baz' +.D1 Cm define Ar foo \(aqbar baz\(aq .D1 Cm define Ar foo cbar bazc .Pp It is an error to have an empty @@ -166,8 +166,8 @@ created. Definitions can create arbitrary strings, for example, the following is a legal construction. .Bd -literal -offset indent -define foo 'define' -foo bar 'baz' +define foo \(aqdefine\(aq +foo bar \(aqbaz\(aq .Ed .Pp Self-referencing definitions will raise an error. diff --git a/contrib/mdocml/eqn.c b/contrib/mdocml/eqn.c index 9da57f0..e9fbdec 100644 --- a/contrib/mdocml/eqn.c +++ b/contrib/mdocml/eqn.c @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.58 2015/03/04 12:19:49 schwarze Exp $ */ +/* $Id: eqn.c,v 1.61 2016/01/08 00:50:45 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -302,10 +302,10 @@ eqn_read(struct eqn_node **epp, int ln, while (' ' == *p || '\t' == *p) p++; if ('\0' == *p) - return(er); + return er; mandoc_vmsg(MANDOCERR_ARG_SKIP, ep->parse, ln, pos, "EN %s", p); - return(er); + return er; } /* @@ -324,7 +324,7 @@ eqn_read(struct eqn_node **epp, int ln, ep->sz += sz; strlcat(ep->data, p + pos, ep->sz + 1); strlcat(ep->data, " ", ep->sz + 1); - return(ROFF_IGN); + return ROFF_IGN; } struct eqn_node * @@ -339,7 +339,7 @@ eqn_alloc(int pos, int line, struct mparse *parse) p->eqn.pos = pos; p->gsize = EQN_DEFSIZE; - return(p); + return p; } /* @@ -353,9 +353,9 @@ eqn_def_find(struct eqn_node *ep, const char *key, size_t sz) for (i = 0; i < (int)ep->defsz; i++) if (ep->defs[i].keysz && STRNEQ(ep->defs[i].key, ep->defs[i].keysz, key, sz)) - return(&ep->defs[i]); + return &ep->defs[i]; - return(NULL); + return NULL; } /* @@ -382,7 +382,7 @@ again: if (lim >= EQN_NEST_MAX) { mandoc_msg(MANDOCERR_ROFFLOOP, ep->parse, ep->eqn.ln, ep->eqn.pos, NULL); - return(NULL); + return NULL; } ep->cur = ep->rew; @@ -390,7 +390,7 @@ again: q = 0; if ('\0' == *start) - return(NULL); + return NULL; if (quote == *start) { ep->cur++; @@ -432,7 +432,7 @@ again: /* Quotes aren't expanded for values. */ if (q || ! repl) - return(start); + return start; if (NULL != (def = eqn_def_find(ep, start, *sz))) { diff = def->valsz - *sz; @@ -448,10 +448,11 @@ again: memmove(start + *sz + diff, start + *sz, (strlen(start) - *sz) + 1); memcpy(start, def->val, def->valsz); + lim++; goto again; } - return(start); + return start; } /* @@ -462,7 +463,7 @@ static const char * eqn_nexttok(struct eqn_node *ep, size_t *sz) { - return(eqn_next(ep, '"', sz, 1)); + return eqn_next(ep, '"', sz, 1); } /* @@ -472,7 +473,7 @@ static const char * eqn_nextrawtok(struct eqn_node *ep, size_t *sz) { - return(eqn_next(ep, '"', sz, 0)); + return eqn_next(ep, '"', sz, 0); } /* @@ -498,12 +499,12 @@ eqn_tok_parse(struct eqn_node *ep, char **p) quoted = ep->data[ep->cur] == '"'; if (NULL == (start = eqn_nexttok(ep, &sz))) - return(EQN_TOK_EOF); + return EQN_TOK_EOF; if (quoted) { if (p != NULL) *p = mandoc_strndup(start, sz); - return(EQN_TOK__MAX); + return EQN_TOK__MAX; } for (i = 0; i < EQN_TOK__MAX; i++) { @@ -516,7 +517,7 @@ eqn_tok_parse(struct eqn_node *ep, char **p) if (i == EQN_TOK__MAX && NULL != p) *p = mandoc_strndup(start, sz); - return(i); + return i; } static void @@ -557,7 +558,7 @@ eqn_box_alloc(struct eqn_node *ep, struct eqn_box *parent) parent->first = bp; parent->last = bp; - return(bp); + return bp; } /* @@ -587,7 +588,7 @@ eqn_box_makebinary(struct eqn_node *ep, newb->first = newb->last = b; newb->first->next = NULL; b->parent = newb; - return(newb); + return newb; } /* @@ -712,7 +713,7 @@ eqn_parse(struct eqn_node *ep, struct eqn_box *parent) */ if (ep->data == NULL) - return(ROFF_IGN); + return ROFF_IGN; next_tok: tok = eqn_tok_parse(ep, &p); @@ -986,7 +987,7 @@ this_tok: parent->right = mandoc_strndup(start, sz); } parent = parent->parent; - if (EQN_TOK_BRACE_CLOSE == tok && parent && + if (tok == EQN_TOK_BRACE_CLOSE && (parent->type == EQN_PILE || parent->type == EQN_MATRIX)) parent = parent->parent; @@ -1060,7 +1061,7 @@ this_tok: * End of file! * TODO: make sure we're not in an open subexpression. */ - return(ROFF_EQN); + return ROFF_EQN; default: assert(tok == EQN_TOK__MAX); assert(NULL != p); @@ -1104,7 +1105,7 @@ eqn_end(struct eqn_node **epp) ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box)); ep->eqn.root->expectargs = UINT_MAX; - return(eqn_parse(ep, ep->eqn.root)); + return eqn_parse(ep, ep->eqn.root); } void diff --git a/contrib/mdocml/example.style.css b/contrib/mdocml/example.style.css deleted file mode 100644 index 90eb4a2..0000000 --- a/contrib/mdocml/example.style.css +++ /dev/null @@ -1,114 +0,0 @@ -/* $Id: example.style.css,v 1.55 2015/02/10 08:05:30 schwarze Exp $ */ -/* - * This is an example style-sheet provided for mandoc(1) and the -Thtml - * or -Txhtml output mode. - * It mimics the appearance of the legacy man.cgi output. - * See mdoc(7) and man(7) for macro explanations. - */ - -div.mandoc { min-width: 102ex; - width: 102ex; - font-family: monospace; } /* This is the outer node of all mandoc -T[x]html documents. */ -div.mandoc h1 { margin-bottom: 0ex; font-size: inherit; margin-left: -4ex; } /* Section header (Sh, SH). */ -div.mandoc h2 { margin-bottom: 0ex; font-size: inherit; margin-left: -2ex; } /* Sub-section header (Ss, SS). */ -div.mandoc table { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */ -div.mandoc td { vertical-align: top; } /* All table cells. */ -div.mandoc p { } /* Paragraph: Pp, Lp. */ -div.mandoc blockquote { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1, Dl. */ -div.mandoc div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */ -div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */ -div.mandoc table.synopsis { } /* SYNOPSIS section table. */ -div.mandoc table.foot { } /* Document footer. */ -div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */ -div.mandoc td.foot-os { width: 50%; - text-align: right; } /* Document footer: OS/source. */ -div.mandoc table.head { } /* Document header. */ -div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */ -div.mandoc td.head-vol { width: 80%; - text-align: center; } /* Document header: volume. */ -div.mandoc td.head-rtitle { width: 10%; - text-align: right; } /* Document header: right-title. */ -div.mandoc .display { } /* All Bd, D1, Dl. */ -div.mandoc .list { } /* All Bl. */ -div.mandoc i { } /* Italic: BI, IB, I, (implicit). */ -div.mandoc b { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */ -div.mandoc small { } /* Small: SB, SM. */ -div.mandoc .emph { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */ -div.mandoc .symb { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */ -div.mandoc .lit { font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */ -div.mandoc i.addr { font-weight: normal; } /* Address (Ad). */ -div.mandoc i.arg { font-weight: normal; } /* Command argument (Ar). */ -div.mandoc span.author { } /* Author name (An). */ -div.mandoc b.cmd { font-style: normal; } /* Command (Cm). */ -div.mandoc b.config { font-style: normal; } /* Config statement (Cd). */ -div.mandoc span.define { } /* Defines (Dv). */ -div.mandoc span.desc { } /* Nd. After em-dash. */ -div.mandoc b.diag { font-style: normal; } /* Diagnostic (Bl -diag). */ -div.mandoc span.env { } /* Environment variables (Ev). */ -div.mandoc span.errno { } /* Error string (Er). */ -div.mandoc i.farg { font-weight: normal; } /* Function argument (Fa, Fn). */ -div.mandoc i.file { font-weight: normal; } /* File (Pa). */ -div.mandoc b.flag { font-style: normal; } /* Flag (Fl, Cm). */ -div.mandoc b.fname { font-style: normal; } /* Function name (Fa, Fn, Rv). */ -div.mandoc i.ftype { font-weight: normal; } /* Function types (Ft, Fn). */ -div.mandoc b.includes { font-style: normal; } /* Header includes (In). */ -div.mandoc span.lib { } /* Library (Lb). */ -div.mandoc i.link-sec { font-weight: normal; } /* Section links (Sx). */ -div.mandoc b.macro { font-style: normal; } /* Macro-ish thing (Fd). */ -div.mandoc b.name { font-style: normal; } /* Name of utility (Nm). */ -div.mandoc span.opt { } /* Options (Op, Oo/Oc). */ -div.mandoc span.ref { } /* Citations (Rs). */ -div.mandoc span.ref-auth { } /* Reference author (%A). */ -div.mandoc i.ref-book { font-weight: normal; } /* Reference book (%B). */ -div.mandoc span.ref-city { } /* Reference city (%C). */ -div.mandoc span.ref-date { } /* Reference date (%D). */ -div.mandoc i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */ -div.mandoc i.ref-jrnl { font-weight: normal; } /* Reference journal (%J). */ -div.mandoc span.ref-num { } /* Reference number (%N). */ -div.mandoc span.ref-opt { } /* Reference optionals (%O). */ -div.mandoc span.ref-page { } /* Reference page (%P). */ -div.mandoc span.ref-corp { } /* Reference corporate/foreign author (%Q). */ -div.mandoc span.ref-rep { } /* Reference report (%R). */ -div.mandoc span.ref-title { text-decoration: underline; } /* Reference title (%T). */ -div.mandoc span.ref-vol { } /* Reference volume (%V). */ -div.mandoc span.type { font-style: italic; font-weight: normal; } /* Variable types (Vt). */ -div.mandoc span.unix { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */ -div.mandoc b.utility { font-style: normal; } /* Name of utility (Ex). */ -div.mandoc b.var { font-style: normal; } /* Variables (Rv). */ -div.mandoc a.link-ext { } /* Off-site link (Lk). */ -div.mandoc a.link-includes { } /* Include-file link (In). */ -div.mandoc a.link-mail { } /* Mailto links (Mt). */ -div.mandoc a.link-man { } /* Manual links (Xr). */ -div.mandoc a.link-ref { } /* Reference section links (%Q). */ -div.mandoc a.link-sec { } /* Section links (Sx). */ -div.mandoc dl.list-diag { } /* Formatting for lists. See mdoc(7). */ -div.mandoc dt.list-diag { } -div.mandoc dd.list-diag { } -div.mandoc dl.list-hang { } -div.mandoc dt.list-hang { } -div.mandoc dd.list-hang { } -div.mandoc dl.list-inset { } -div.mandoc dt.list-inset { } -div.mandoc dd.list-inset { } -div.mandoc dl.list-ohang { } -div.mandoc dt.list-ohang { } -div.mandoc dd.list-ohang { margin-left: 0ex; } -div.mandoc dl.list-tag { } -div.mandoc dt.list-tag { } -div.mandoc dd.list-tag { } -div.mandoc table.list-col { } -div.mandoc tr.list-col { } -div.mandoc td.list-col { } -div.mandoc ul.list-bul { list-style-type: disc; padding-left: 1em; } -div.mandoc li.list-bul { } -div.mandoc ul.list-dash { list-style-type: none; padding-left: 0em; } -div.mandoc li.list-dash:before { content: "\2014 "; } -div.mandoc ul.list-hyph { list-style-type: none; padding-left: 0em; } -div.mandoc li.list-hyph:before { content: "\2013 "; } -div.mandoc ul.list-item { list-style-type: none; padding-left: 0em; } -div.mandoc li.list-item { } -div.mandoc ol.list-enum { padding-left: 2em; } -div.mandoc li.list-enum { } -div.mandoc span.eqn { } /* Equation modes. See eqn(7). */ -div.mandoc table.tbl { } /* Table modes. See tbl(7). */ -div.mandoc div.spacer { margin: 1em 0; } diff --git a/contrib/mdocml/gmdiff b/contrib/mdocml/gmdiff index ae27726..8d24fa7 100644 --- a/contrib/mdocml/gmdiff +++ b/contrib/mdocml/gmdiff @@ -40,7 +40,8 @@ while [ -n "$1" ]; do shift echo " ========== $file ========== " tbl $file | $EQN | $ROFF -mandoc 2> /tmp/roff.err > /tmp/roff.out - mandoc -Ios='OpenBSD ports' $MOPT $file 2> /tmp/mandoc.err > /tmp/mandoc.out + ${MANDOC:=mandoc} -Ios='OpenBSD ports' $MOPT $file \ + 2> /tmp/mandoc.err > /tmp/mandoc.out for i in roff mandoc; do [[ -s /tmp/$i.err ]] && echo "$i errors:" && cat /tmp/$i.err done diff --git a/contrib/mdocml/html.c b/contrib/mdocml/html.c index 487dacd..adff053 100644 --- a/contrib/mdocml/html.c +++ b/contrib/mdocml/html.c @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.185 2015/01/21 20:33:25 schwarze Exp $ */ +/* $Id: html.c,v 1.192 2016/01/04 12:45:29 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -32,6 +32,7 @@ #include "mandoc_aux.h" #include "out.h" #include "html.h" +#include "manconf.h" #include "main.h" struct htmldata { @@ -129,42 +130,20 @@ static void print_attr(struct html *, const char *, const char *); void * -html_alloc(const struct mchars *mchars, char *outopts) +html_alloc(const struct manoutput *outopts) { struct html *h; - const char *toks[5]; - char *v; - - toks[0] = "style"; - toks[1] = "man"; - toks[2] = "includes"; - toks[3] = "fragment"; - toks[4] = NULL; h = mandoc_calloc(1, sizeof(struct html)); h->tags.head = NULL; - h->symtab = mchars; + h->style = outopts->style; + h->base_man = outopts->man; + h->base_includes = outopts->includes; + if (outopts->fragment) + h->oflags |= HTML_FRAGMENT; - while (outopts && *outopts) - switch (getsubopt(&outopts, UNCONST(toks), &v)) { - case 0: - h->style = v; - break; - case 1: - h->base_man = v; - break; - case 2: - h->base_includes = v; - break; - case 3: - h->oflags |= HTML_FRAGMENT; - break; - default: - break; - } - - return(h); + return h; } void @@ -237,13 +216,11 @@ print_metaf(struct html *h, enum mandoc_esc deco) font = HTMLFONT_BI; break; case ESCAPE_FONT: - /* FALLTHROUGH */ case ESCAPE_FONTROMAN: font = HTMLFONT_NONE; break; default: abort(); - /* NOTREACHED */ } if (h->metaf) { @@ -301,13 +278,10 @@ html_strlen(const char *cp) cp++; switch (mandoc_escape(&cp, NULL, NULL)) { case ESCAPE_ERROR: - return(sz); + return sz; case ESCAPE_UNICODE: - /* FALLTHROUGH */ case ESCAPE_NUMBERED: - /* FALLTHROUGH */ case ESCAPE_SPECIAL: - /* FALLTHROUGH */ case ESCAPE_OVERSTRIKE: if (skip) skip = 0; @@ -321,7 +295,7 @@ html_strlen(const char *cp) break; } } - return(sz); + return sz; } static int @@ -342,17 +316,17 @@ print_escape(char c) printf("""); break; case ASCII_NBRSP: - putchar('-'); + printf(" "); break; case ASCII_HYPH: putchar('-'); - /* FALLTHROUGH */ + break; case ASCII_BREAK: break; default: - return(0); + return 0; } - return(1); + return 1; } static int @@ -391,15 +365,10 @@ print_encode(struct html *h, const char *p, int norecurse) 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); @@ -427,7 +396,7 @@ print_encode(struct html *h, const char *p, int norecurse) continue; break; case ESCAPE_SPECIAL: - c = mchars_spec2cp(h->symtab, seq, len); + c = mchars_spec2cp(seq, len); if (c <= 0) continue; break; @@ -452,7 +421,7 @@ print_encode(struct html *h, const char *p, int norecurse) putchar(c); } - return(nospace); + return nospace; } static void @@ -514,7 +483,7 @@ print_otag(struct html *h, enum htmltag tag, if ((HTML_AUTOCLOSE | HTML_CLRLINE) & htmltags[tag].flags) putchar('\n'); - return(t); + return t; } static void @@ -751,8 +720,8 @@ void bufcat_id(struct html *h, const char *src) { - /* Cf. <http://www.w3.org/TR/html4/types.html#h-6.2>. */ + /* Cf. <http://www.w3.org/TR/html5/dom.html#the-id-attribute>. */ - while ('\0' != *src) - bufcat_fmt(h, "%.2x", *src++); + for (; '\0' != *src; src++) + bufncat(h, *src == ' ' ? "_" : src, 1); } diff --git a/contrib/mdocml/html.h b/contrib/mdocml/html.h index bbf6183..27dc140 100644 --- a/contrib/mdocml/html.h +++ b/contrib/mdocml/html.h @@ -1,4 +1,4 @@ -/* $Id: html.h,v 1.70 2014/12/02 10:08:06 schwarze Exp $ */ +/* $Id: html.h,v 1.72 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -130,7 +130,6 @@ struct html { struct tagq tags; /* stack of open tags */ struct rofftbl tbl; /* current table */ struct tag *tblt; /* current open table scope */ - const struct mchars *symtab; /* character table */ char *base_man; /* base for manpage href */ char *base_includes; /* base for include href */ char *style; /* style-sheet URI */ @@ -143,7 +142,6 @@ struct html { #define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */ }; -__BEGIN_DECLS struct tbl_span; struct eqn; @@ -176,5 +174,3 @@ void buffmt_man(struct html *, void buffmt_includes(struct html *, const char *); int html_strlen(const char *); - -__END_DECLS diff --git a/contrib/mdocml/lib.c b/contrib/mdocml/lib.c index 17ce529..5295950 100644 --- a/contrib/mdocml/lib.c +++ b/contrib/mdocml/lib.c @@ -1,4 +1,4 @@ -/* $Id: lib.c,v 1.11 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: lib.c,v 1.13 2015/10/06 18:32:19 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -20,6 +20,7 @@ #include <string.h> +#include "roff.h" #include "mdoc.h" #include "libmdoc.h" @@ -32,5 +33,5 @@ mdoc_a2lib(const char *p) #include "lib.in" - return(NULL); + return NULL; } diff --git a/contrib/mdocml/libman.h b/contrib/mdocml/libman.h index 8d115b3..6584960 100644 --- a/contrib/mdocml/libman.h +++ b/contrib/mdocml/libman.h @@ -1,44 +1,23 @@ -/* $Id: libman.h,v 1.67 2014/12/28 14:42:27 schwarze Exp $ */ +/* $Id: libman.h,v 1.79 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -enum man_next { - MAN_NEXT_SIBLING = 0, - MAN_NEXT_CHILD -}; - -struct man { - struct mparse *parse; /* parse pointer */ - const char *defos; /* default OS argument for .TH */ - int quick; /* abort parse early */ - int flags; /* parse flags */ -#define MAN_ELINE (1 << 1) /* Next-line element scope. */ -#define MAN_BLINE (1 << 2) /* Next-line block scope. */ -#define MAN_LITERAL (1 << 4) /* Literal input. */ -#define MAN_NEWLINE (1 << 6) /* first macro/text in a line */ - enum man_next next; /* where to put the next node */ - struct man_node *last; /* the last parsed node */ - struct man_node *first; /* the first parsed node */ - struct man_meta meta; /* document meta-data */ - struct roff *roff; -}; - -#define MACRO_PROT_ARGS struct man *man, \ - enum mant tok, \ +#define MACRO_PROT_ARGS struct roff_man *man, \ + int tok, \ int line, \ int ppos, \ int *pos, \ @@ -47,30 +26,16 @@ struct man { struct man_macro { void (*fp)(MACRO_PROT_ARGS); int flags; -#define MAN_SCOPED (1 << 0) -#define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */ -#define MAN_FSCOPED (1 << 2) /* See blk_imp(). */ -#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */ -#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */ -#define MAN_BSCOPE (1 << 5) /* Break BLINE scope. */ -#define MAN_JOIN (1 << 6) /* Join arguments together. */ +#define MAN_SCOPED (1 << 0) /* Optional next-line scope. */ +#define MAN_NSCOPED (1 << 1) /* Allowed in next-line element scope. */ +#define MAN_BSCOPE (1 << 2) /* Break next-line block scope. */ +#define MAN_JOIN (1 << 3) /* Join arguments together. */ }; extern const struct man_macro *const man_macros; -__BEGIN_DECLS - -void man_word_alloc(struct man *, int, int, const char *); -void man_word_append(struct man *, const char *); -void man_block_alloc(struct man *, int, int, enum mant); -void man_head_alloc(struct man *, int, int, enum mant); -void man_body_alloc(struct man *, int, int, enum mant); -void man_elem_alloc(struct man *, int, int, enum mant); -void man_node_delete(struct man *, struct man_node *); -void man_hash_init(void); -enum mant man_hash_find(const char *); -void man_macroend(struct man *); -void man_valid_post(struct man *); -void man_unscope(struct man *, const struct man_node *); -__END_DECLS +int man_hash_find(const char *); +void man_node_validate(struct roff_man *); +void man_state(struct roff_man *, struct roff_node *); +void man_unscope(struct roff_man *, const struct roff_node *); diff --git a/contrib/mdocml/libmandoc.h b/contrib/mdocml/libmandoc.h index 11feebd..939ec83 100644 --- a/contrib/mdocml/libmandoc.h +++ b/contrib/mdocml/libmandoc.h @@ -1,15 +1,15 @@ -/* $Id: libmandoc.h,v 1.55 2015/01/15 04:26:39 schwarze Exp $ */ +/* $Id: libmandoc.h,v 1.62 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2013, 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -32,15 +32,13 @@ struct buf { size_t sz; }; -__BEGIN_DECLS struct mparse; -struct mchars; struct tbl_span; struct eqn; struct roff; -struct mdoc; -struct man; +struct roff_man; +struct roff_node; void mandoc_msg(enum mandocerr, struct mparse *, int, int, const char *); @@ -55,31 +53,25 @@ int mandoc_eos(const char *, size_t); 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 *, - const char *, int); -void mdoc_reset(struct mdoc *); -int mdoc_parseln(struct mdoc *, int, char *, int); -void mdoc_endparse(struct mdoc *); -void mdoc_addspan(struct mdoc *, const struct tbl_span *); -void mdoc_addeqn(struct mdoc *, const struct eqn *); +void mdoc_hash_init(void); +int mdoc_parseln(struct roff_man *, int, char *, int); +void mdoc_endparse(struct roff_man *); -void man_free(struct man *); -struct man *man_alloc(struct roff *, struct mparse *, - const char *, int); -void man_reset(struct man *); -int man_parseln(struct man *, int, char *, int); -void man_endparse(struct man *); -void man_addspan(struct man *, const struct tbl_span *); -void man_addeqn(struct man *, const struct eqn *); +void man_hash_init(void); +int man_parseln(struct roff_man *, int, char *, int); +void man_endparse(struct roff_man *); int preconv_cue(const struct buf *, size_t); int preconv_encode(struct buf *, size_t *, struct buf *, size_t *, int *); void roff_free(struct roff *); -struct roff *roff_alloc(struct mparse *, const struct mchars *, int); +struct roff *roff_alloc(struct mparse *, int); void roff_reset(struct roff *); +void roff_man_free(struct roff_man *); +struct roff_man *roff_man_alloc(struct roff *, struct mparse *, + const char *, int); +void roff_man_reset(struct roff_man *); enum rofferr roff_parseln(struct roff *, int, struct buf *, int *); void roff_endparse(struct roff *); void roff_setreg(struct roff *, const char *, int, char sign); @@ -91,5 +83,3 @@ int roff_getformat(const struct roff *); const struct tbl_span *roff_span(const struct roff *); const struct eqn *roff_eqn(const struct roff *); - -__END_DECLS diff --git a/contrib/mdocml/libmdoc.h b/contrib/mdocml/libmdoc.h index 527fe02..5a6cc3e 100644 --- a/contrib/mdocml/libmdoc.h +++ b/contrib/mdocml/libmdoc.h @@ -1,53 +1,23 @@ -/* $Id: libmdoc.h,v 1.97 2015/02/02 04:26:44 schwarze Exp $ */ +/* $Id: libmdoc.h,v 1.108 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2013, 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -enum mdoc_next { - MDOC_NEXT_SIBLING = 0, - MDOC_NEXT_CHILD -}; - -struct mdoc { - struct mparse *parse; /* parse pointer */ - const char *defos; /* default argument for .Os */ - int quick; /* abort parse early */ - int flags; /* parse flags */ -#define MDOC_LITERAL (1 << 1) /* in a literal scope */ -#define MDOC_PBODY (1 << 2) /* in the document body */ -#define MDOC_NEWLINE (1 << 3) /* first macro/text in a line */ -#define MDOC_PHRASELIT (1 << 4) /* literal within a partila phrase */ -#define MDOC_PPHRASE (1 << 5) /* within a partial phrase */ -#define MDOC_FREECOL (1 << 6) /* `It' invocation should close */ -#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */ -#define MDOC_KEEP (1 << 8) /* in a word keep */ -#define MDOC_SMOFF (1 << 9) /* spacing is off */ -#define MDOC_NODELIMC (1 << 10) /* disable closing delimiter handling */ - enum mdoc_next next; /* where to put the next node */ - struct mdoc_node *last; /* the last node parsed */ - struct mdoc_node *first; /* the first node parsed */ - struct mdoc_node *last_es; /* the most recent Es node */ - struct mdoc_meta meta; /* document meta-data */ - enum mdoc_sec lastnamed; - enum mdoc_sec lastsec; - struct roff *roff; -}; - -#define MACRO_PROT_ARGS struct mdoc *mdoc, \ - enum mdoct tok, \ +#define MACRO_PROT_ARGS struct roff_man *mdoc, \ + int tok, \ int line, \ int ppos, \ int *pos, \ @@ -70,9 +40,7 @@ enum margserr { ARGS_WORD, /* normal word */ ARGS_PUNCT, /* series of punctuation */ ARGS_QWORD, /* quoted word */ - ARGS_PHRASE, /* Ta'd phrase (-column) */ - ARGS_PPHRASE, /* tabbed phrase (-column) */ - ARGS_PEND /* last phrase (-column) */ + ARGS_PHRASE /* Bl -column phrase */ }; /* @@ -94,36 +62,27 @@ enum mdelim { extern const struct mdoc_macro *const mdoc_macros; -__BEGIN_DECLS void mdoc_macro(MACRO_PROT_ARGS); -void mdoc_word_alloc(struct mdoc *, int, int, const char *); -void mdoc_word_append(struct mdoc *, const char *); -void mdoc_elem_alloc(struct mdoc *, int, int, - enum mdoct, struct mdoc_arg *); -struct mdoc_node *mdoc_block_alloc(struct mdoc *, int, int, - enum mdoct, struct mdoc_arg *); -struct mdoc_node *mdoc_head_alloc(struct mdoc *, int, int, enum mdoct); -void mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct); -struct mdoc_node *mdoc_body_alloc(struct mdoc *, int, int, enum mdoct); -struct mdoc_node *mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct, - struct mdoc_node *, enum mdoc_endbody); -void mdoc_node_delete(struct mdoc *, struct mdoc_node *); -void mdoc_node_relink(struct mdoc *, struct mdoc_node *); -void mdoc_hash_init(void); -enum mdoct mdoc_hash_find(const char *); +void mdoc_elem_alloc(struct roff_man *, int, int, + int, struct mdoc_arg *); +struct roff_node *mdoc_block_alloc(struct roff_man *, int, int, + int, struct mdoc_arg *); +void mdoc_tail_alloc(struct roff_man *, int, int, int); +struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int, int, + struct roff_node *, enum mdoc_endbody); +void mdoc_node_relink(struct roff_man *, struct roff_node *); +void mdoc_node_validate(struct roff_man *); +void mdoc_state(struct roff_man *, struct roff_node *); +void mdoc_state_reset(struct roff_man *); +int mdoc_hash_find(const char *); +const char *mdoc_a2arch(const char *); const char *mdoc_a2att(const char *); const char *mdoc_a2lib(const char *); +enum roff_sec mdoc_a2sec(const char *); const char *mdoc_a2st(const char *); -const char *mdoc_a2arch(const char *); -void mdoc_valid_pre(struct mdoc *, struct mdoc_node *); -void mdoc_valid_post(struct mdoc *); -void mdoc_argv(struct mdoc *, int, enum mdoct, +void mdoc_argv(struct roff_man *, int, int, struct mdoc_arg **, int *, char *); -void mdoc_argv_free(struct mdoc_arg *); -enum margserr mdoc_args(struct mdoc *, int, - int *, char *, enum mdoct, char **); -void mdoc_macroend(struct mdoc *); +enum margserr mdoc_args(struct roff_man *, int, + int *, char *, int, char **); enum mdelim mdoc_isdelim(const char *); - -__END_DECLS diff --git a/contrib/mdocml/libroff.h b/contrib/mdocml/libroff.h index 08ed1f7..897a55a 100644 --- a/contrib/mdocml/libroff.h +++ b/contrib/mdocml/libroff.h @@ -1,4 +1,4 @@ -/* $Id: libroff.h,v 1.38 2015/01/30 04:11:50 schwarze Exp $ */ +/* $Id: libroff.h,v 1.39 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -60,7 +60,6 @@ struct eqn_def { size_t valsz; }; -__BEGIN_DECLS struct tbl_node *tbl_alloc(int, int, struct mparse *); void tbl_restart(int, int, struct tbl_node *); @@ -78,5 +77,3 @@ enum rofferr eqn_end(struct eqn_node **); void eqn_free(struct eqn_node *); enum rofferr eqn_read(struct eqn_node **, int, const char *, int, int *); - -__END_DECLS diff --git a/contrib/mdocml/main.c b/contrib/mdocml/main.c index f0cd8ca..3c4ff2a 100644 --- a/contrib/mdocml/main.c +++ b/contrib/mdocml/main.c @@ -1,16 +1,16 @@ -/* $Id: main.c,v 1.225 2015/03/10 13:50:03 schwarze Exp $ */ +/* $Id: main.c,v 1.262 2016/01/08 02:53:13 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2012, 2014-2016 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -24,21 +24,27 @@ #include <assert.h> #include <ctype.h> +#if HAVE_ERR +#include <err.h> +#endif #include <errno.h> #include <fcntl.h> #include <glob.h> +#include <signal.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "mandoc.h" #include "mandoc_aux.h" -#include "main.h" +#include "mandoc.h" +#include "roff.h" #include "mdoc.h" #include "man.h" -#include "manpath.h" +#include "tag.h" +#include "main.h" +#include "manconf.h" #include "mansearch.h" #if !defined(__GNUC__) || (__GNUC__ < 2) @@ -56,10 +62,6 @@ enum outmode { OUTMODE_ONE }; -typedef void (*out_mdoc)(void *, const struct mdoc *); -typedef void (*out_man)(void *, const struct man *); -typedef void (*out_free)(void *); - enum outt { OUTT_ASCII = 0, /* -Tascii */ OUTT_LOCALE, /* -Tlocale */ @@ -74,15 +76,11 @@ enum outt { struct curparse { struct mparse *mp; - struct mchars *mchars; /* character table */ enum mandoclevel wlevel; /* ignore messages below this */ int wstop; /* stop after a file with a warning */ enum outt outtype; /* which output to use */ - out_mdoc outmdoc; /* mdoc output ptr */ - out_man outman; /* man output ptr */ - out_free outfree; /* free output ptr */ void *outdata; /* data for output */ - char outopts[BUFSIZ]; /* buf of output opts */ + struct manoutput *outopts; /* output options */ }; static int fs_lookup(const struct manpaths *, @@ -99,10 +97,9 @@ int mandocdb(int, char**); static int moptions(int *, char *); static void mmsg(enum mandocerr, enum mandoclevel, const char *, int, int, const char *); -static void parse(struct curparse *, int, - const char *, enum mandoclevel *); -static enum mandoclevel passthrough(const char *, int, int); -static pid_t spawn_pager(void); +static void parse(struct curparse *, int, const char *); +static void passthrough(const char *, int, int); +static pid_t spawn_pager(struct tag_files *); static int toptions(struct curparse *, char *); static void usage(enum argmode) __attribute__((noreturn)); static int woptions(struct curparse *, char *); @@ -110,46 +107,60 @@ static int woptions(struct curparse *, char *); static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9}; static char help_arg[] = "help"; static char *help_argv[] = {help_arg, NULL}; -static const char *progname; +static enum mandoclevel rc; int main(int argc, char *argv[]) { + struct manconf conf; struct curparse curp; struct mansearch search; - struct manpaths paths; + struct tag_files *tag_files; + const char *progname; char *auxpaths; char *defos; unsigned char *uc; struct manpage *res, *resp; char *conf_file, *defpaths; size_t isec, i, sz; - int prio, best_prio, synopsis_only; + int prio, best_prio; char sec; - enum mandoclevel rc, rctmp; enum outmode outmode; int fd; int show_usage; int options; + int use_pager; + int status, signum; int c; - pid_t pager_pid; /* 0: don't use; 1: not yet spawned. */ + pid_t pager_pid, tc_pgid, man_pgid, pid; +#if HAVE_PROGNAME + progname = getprogname(); +#else if (argc < 1) - progname = "mandoc"; + progname = mandoc_strdup("mandoc"); else if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else ++progname; + setprogname(progname); +#endif #if HAVE_SQLITE3 - if (strcmp(progname, BINM_MAKEWHATIS) == 0) - return(mandocdb(argc, argv)); + if (strncmp(progname, "mandocdb", 8) == 0 || + strcmp(progname, BINM_MAKEWHATIS) == 0) + return mandocdb(argc, argv); +#endif + +#if HAVE_PLEDGE + if (pledge("stdio rpath tmppath tty proc exec flock", NULL) == -1) + err((int)MANDOCLEVEL_SYSERR, "pledge"); #endif /* Search options. */ - memset(&paths, 0, sizeof(struct manpaths)); + memset(&conf, 0, sizeof(conf)); conf_file = defpaths = NULL; auxpaths = NULL; @@ -172,12 +183,13 @@ main(int argc, char *argv[]) memset(&curp, 0, sizeof(struct curparse)); curp.outtype = OUTT_LOCALE; curp.wlevel = MANDOCLEVEL_BADARG; + curp.outopts = &conf.output; options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1; defos = NULL; - pager_pid = 1; + use_pager = 1; + tag_files = NULL; show_usage = 0; - synopsis_only = 0; outmode = OUTMODE_DEF; while (-1 != (c = getopt(argc, argv, @@ -190,29 +202,24 @@ main(int argc, char *argv[]) conf_file = optarg; break; case 'c': - pager_pid = 0; + use_pager = 0; break; case 'f': search.argmode = ARG_WORD; break; case 'h': - (void)strlcat(curp.outopts, "synopsis,", BUFSIZ); - synopsis_only = 1; - pager_pid = 0; + conf.output.synopsisonly = 1; + use_pager = 0; outmode = OUTMODE_ALL; break; case 'I': if (strncmp(optarg, "os=", 3)) { - fprintf(stderr, - "%s: -I %s: Bad argument\n", - progname, optarg); - return((int)MANDOCLEVEL_BADARG); + warnx("-I %s: Bad argument", optarg); + return (int)MANDOCLEVEL_BADARG; } if (defos) { - fprintf(stderr, - "%s: -I %s: Duplicate argument\n", - progname, optarg); - return((int)MANDOCLEVEL_BADARG); + warnx("-I %s: Duplicate argument", optarg); + return (int)MANDOCLEVEL_BADARG; } defos = mandoc_strdup(optarg + 3); break; @@ -221,7 +228,7 @@ main(int argc, char *argv[]) break; case 'K': if ( ! koptions(&options, optarg)) - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; break; case 'k': search.argmode = ARG_EXPR; @@ -238,8 +245,9 @@ main(int argc, char *argv[]) break; case 'O': search.outkey = optarg; - (void)strlcat(curp.outopts, optarg, BUFSIZ); - (void)strlcat(curp.outopts, ",", BUFSIZ); + while (optarg != NULL) + manconf_output(&conf.output, + strsep(&optarg, ",")); break; case 'S': search.arch = optarg; @@ -249,11 +257,11 @@ main(int argc, char *argv[]) break; case 'T': if ( ! toptions(&curp, optarg)) - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; break; case 'W': if ( ! woptions(&curp, optarg)) - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; break; case 'w': outmode = OUTMODE_FLN; @@ -273,7 +281,7 @@ main(int argc, char *argv[]) switch (search.argmode) { case ARG_FILE: outmode = OUTMODE_ALL; - pager_pid = 0; + use_pager = 0; break; case ARG_NAME: outmode = OUTMODE_ONE; @@ -284,6 +292,17 @@ main(int argc, char *argv[]) } } + if (outmode == OUTMODE_FLN || + outmode == OUTMODE_LST || + !isatty(STDOUT_FILENO)) + use_pager = 0; + +#if HAVE_PLEDGE + if (!use_pager) + if (pledge("stdio rpath flock", NULL) == -1) + err((int)MANDOCLEVEL_SYSERR, "pledge"); +#endif + /* Parse arguments. */ if (argc > 0) { @@ -334,22 +353,28 @@ main(int argc, char *argv[]) /* Access the mandoc database. */ - manpath_parse(&paths, conf_file, defpaths, auxpaths); + manconf_parse(&conf, conf_file, defpaths, auxpaths); #if HAVE_SQLITE3 mansearch_setup(1); - if( ! mansearch(&search, &paths, argc, argv, &res, &sz)) + if ( ! mansearch(&search, &conf.manpath, + argc, argv, &res, &sz)) usage(search.argmode); #else if (search.argmode != ARG_NAME) { fputs("mandoc: database support not compiled in\n", stderr); - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; } sz = 0; #endif - if (sz == 0 && search.argmode == ARG_NAME) - fs_search(&search, &paths, argc, argv, &res, &sz); + if (sz == 0) { + if (search.argmode == ARG_NAME) + fs_search(&search, &conf.manpath, + argc, argv, &res, &sz); + else + warnx("nothing appropriate"); + } if (sz == 0) { rc = MANDOCLEVEL_BADARG; @@ -404,12 +429,21 @@ main(int argc, char *argv[]) /* mandoc(1) */ +#if HAVE_PLEDGE + if (use_pager) { + if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1) + err((int)MANDOCLEVEL_SYSERR, "pledge"); + } else { + if (pledge("stdio rpath", NULL) == -1) + err((int)MANDOCLEVEL_SYSERR, "pledge"); + } +#endif + if (search.argmode == ARG_FILE && ! moptions(&options, auxpaths)) - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; - curp.mchars = mchars_alloc(); - curp.mp = mparse_alloc(options, curp.wlevel, mmsg, - curp.mchars, defos); + mchars_alloc(); + curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos); /* * Conditionally start up the lookaside buffer before parsing. @@ -418,41 +452,33 @@ main(int argc, char *argv[]) mparse_keep(curp.mp); if (argc < 1) { - if (pager_pid == 1 && isatty(STDOUT_FILENO)) - pager_pid = spawn_pager(); - parse(&curp, STDIN_FILENO, "<stdin>", &rc); + if (use_pager) + tag_files = tag_init(); + parse(&curp, STDIN_FILENO, "<stdin>"); } while (argc > 0) { - rctmp = mparse_open(curp.mp, &fd, - resp != NULL ? resp->file : *argv); - if (rc < rctmp) - rc = rctmp; - + fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv); if (fd != -1) { - if (pager_pid == 1 && isatty(STDOUT_FILENO)) - pager_pid = spawn_pager(); + if (use_pager) { + tag_files = tag_init(); + use_pager = 0; + } if (resp == NULL) - parse(&curp, fd, *argv, &rc); + parse(&curp, fd, *argv); else if (resp->form & FORM_SRC) { /* For .so only; ignore failure. */ - chdir(paths.paths[resp->ipath]); - parse(&curp, fd, resp->file, &rc); - } else { - rctmp = passthrough(resp->file, fd, - synopsis_only); - if (rc < rctmp) - rc = rctmp; - } - - rctmp = mparse_wait(curp.mp); - if (rc < rctmp) - rc = rctmp; + chdir(conf.manpath.paths[resp->ipath]); + parse(&curp, fd, resp->file); + } else + passthrough(resp->file, fd, + conf.output.synopsisonly); if (argc > 1 && curp.outtype <= OUTT_UTF8) ascii_sepline(curp.outdata); - } + } else if (rc < MANDOCLEVEL_ERROR) + rc = MANDOCLEVEL_ERROR; if (MANDOCLEVEL_OK != rc && curp.wstop) break; @@ -465,14 +491,30 @@ main(int argc, char *argv[]) mparse_reset(curp.mp); } - if (curp.outfree) - (*curp.outfree)(curp.outdata); + if (curp.outdata != NULL) { + switch (curp.outtype) { + case OUTT_HTML: + html_free(curp.outdata); + break; + case OUTT_UTF8: + case OUTT_LOCALE: + case OUTT_ASCII: + ascii_free(curp.outdata); + break; + case OUTT_PDF: + case OUTT_PS: + pspdf_free(curp.outdata); + break; + default: + break; + } + } mparse_free(curp.mp); - mchars_free(curp.mchars); + mchars_free(); out: if (search.argmode != ARG_FILE) { - manpath_free(&paths); + manconf_free(&conf); #if HAVE_SQLITE3 mansearch_free(res, sz); mansearch_setup(0); @@ -482,17 +524,63 @@ out: free(defos); /* - * If a pager is attached, flush the pipe leading to it - * and signal end of file such that the user can browse - * to the end. Then wait for the user to close the pager. + * When using a pager, finish writing both temporary files, + * fork it, wait for the user to close it, and clean up. */ - if (pager_pid != 0 && pager_pid != 1) { + if (tag_files != NULL) { fclose(stdout); - waitpid(pager_pid, NULL, 0); + tag_write(); + man_pgid = getpgid(0); + tag_files->tcpgid = man_pgid == getpid() ? + getpgid(getppid()) : man_pgid; + pager_pid = 0; + signum = SIGSTOP; + for (;;) { + + /* Stop here until moved to the foreground. */ + + tc_pgid = tcgetpgrp(STDIN_FILENO); + if (tc_pgid != man_pgid) { + if (tc_pgid == pager_pid) { + (void)tcsetpgrp(STDIN_FILENO, + man_pgid); + if (signum == SIGTTIN) + continue; + } else + tag_files->tcpgid = tc_pgid; + kill(0, signum); + continue; + } + + /* Once in the foreground, activate the pager. */ + + if (pager_pid) { + (void)tcsetpgrp(STDIN_FILENO, pager_pid); + kill(pager_pid, SIGCONT); + } else + pager_pid = spawn_pager(tag_files); + + /* Wait for the pager to stop or exit. */ + + while ((pid = waitpid(pager_pid, &status, + WUNTRACED)) == -1 && errno == EINTR) + continue; + + if (pid == -1) { + warn("wait"); + rc = MANDOCLEVEL_SYSERR; + break; + } + if (!WIFSTOPPED(status)) + break; + + signum = WSTOPSIG(status); + } + tag_unlink(); } - return((int)rc); + return (int)rc; } static void @@ -501,9 +589,9 @@ usage(enum argmode argmode) switch (argmode) { case ARG_FILE: - fputs("usage: mandoc [-acfhkl] [-Ios=name] " - "[-Kencoding] [-mformat] [-Ooption]\n" - "\t [-Toutput] [-Wlevel] [file ...]\n", stderr); + fputs("usage: mandoc [-acfhkl] [-I os=name] " + "[-K encoding] [-mformat] [-O option]\n" + "\t [-T output] [-W level] [file ...]\n", stderr); break; case ARG_NAME: fputs("usage: man [-acfhklw] [-C file] [-I os=name] " @@ -559,26 +647,23 @@ fs_lookup(const struct manpaths *paths, size_t ipath, free(file); } - mandoc_asprintf(&file, "%s/man%s/%s.*", + mandoc_asprintf(&file, "%s/man%s/%s.[01-9]*", paths->paths[ipath], sec, name); globres = glob(file, 0, NULL, &globinfo); if (globres != 0 && globres != GLOB_NOMATCH) - fprintf(stderr, "%s: %s: glob: %s\n", - progname, file, strerror(errno)); + warn("%s: glob", file); free(file); if (globres == 0) file = mandoc_strdup(*globinfo.gl_pathv); globfree(&globinfo); if (globres != 0) - return(0); + return 0; found: #if HAVE_SQLITE3 - fprintf(stderr, "%s: outdated mandoc.db lacks %s(%s) entry,\n" - " consider running # makewhatis %s\n", - progname, name, sec, paths->paths[ipath]); + warnx("outdated mandoc.db lacks %s(%s) entry, run makewhatis %s", + name, sec, paths->paths[ipath]); #endif - *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage)); page = *res + (*ressz - 1); page->file = file; @@ -588,7 +673,7 @@ found: page->bits = NAME_FILE & NAME_MASK; page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10; page->form = form; - return(1); + return 1; } static void @@ -619,9 +704,7 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths, return; } if (*ressz == lastsz) - fprintf(stderr, - "%s: No entry for %s in the manual.\n", - progname, *argv); + warnx("No entry for %s in the manual.", *argv); lastsz = *ressz; argv++; argc--; @@ -629,111 +712,112 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths, } static void -parse(struct curparse *curp, int fd, const char *file, - enum mandoclevel *level) +parse(struct curparse *curp, int fd, const char *file) { - enum mandoclevel rc; - struct mdoc *mdoc; - struct man *man; + enum mandoclevel rctmp; + struct roff_man *man; /* Begin by parsing the file itself. */ assert(file); - assert(fd >= -1); + assert(fd > 0); - rc = mparse_readfd(curp->mp, fd, file); + rctmp = mparse_readfd(curp->mp, fd, file); + if (fd != STDIN_FILENO) + close(fd); + if (rc < rctmp) + rc = rctmp; /* * With -Wstop and warnings or errors of at least the requested * level, do not produce output. */ - if (MANDOCLEVEL_OK != rc && curp->wstop) - goto cleanup; + if (rctmp != MANDOCLEVEL_OK && curp->wstop) + return; /* If unset, allocate output dev now (if applicable). */ - if ( ! (curp->outman && curp->outmdoc)) { + if (curp->outdata == NULL) { switch (curp->outtype) { case OUTT_HTML: - curp->outdata = html_alloc(curp->mchars, - curp->outopts); - curp->outfree = html_free; + curp->outdata = html_alloc(curp->outopts); break; case OUTT_UTF8: - curp->outdata = utf8_alloc(curp->mchars, - curp->outopts); - curp->outfree = ascii_free; + curp->outdata = utf8_alloc(curp->outopts); break; case OUTT_LOCALE: - curp->outdata = locale_alloc(curp->mchars, - curp->outopts); - curp->outfree = ascii_free; + curp->outdata = locale_alloc(curp->outopts); break; case OUTT_ASCII: - curp->outdata = ascii_alloc(curp->mchars, - curp->outopts); - curp->outfree = ascii_free; + curp->outdata = ascii_alloc(curp->outopts); break; case OUTT_PDF: - curp->outdata = pdf_alloc(curp->mchars, - curp->outopts); - curp->outfree = pspdf_free; + curp->outdata = pdf_alloc(curp->outopts); break; case OUTT_PS: - curp->outdata = ps_alloc(curp->mchars, - curp->outopts); - curp->outfree = pspdf_free; + curp->outdata = ps_alloc(curp->outopts); break; default: break; } + } + + mparse_result(curp->mp, &man, NULL); + /* Execute the out device, if it exists. */ + + if (man == NULL) + return; + if (man->macroset == MACROSET_MDOC) { + mdoc_validate(man); switch (curp->outtype) { case OUTT_HTML: - curp->outman = html_man; - curp->outmdoc = html_mdoc; + html_mdoc(curp->outdata, man); break; case OUTT_TREE: - curp->outman = tree_man; - curp->outmdoc = tree_mdoc; + tree_mdoc(curp->outdata, man); break; case OUTT_MAN: - curp->outmdoc = man_mdoc; - curp->outman = man_man; + man_mdoc(curp->outdata, man); break; case OUTT_PDF: - /* FALLTHROUGH */ case OUTT_ASCII: - /* FALLTHROUGH */ case OUTT_UTF8: - /* FALLTHROUGH */ case OUTT_LOCALE: - /* FALLTHROUGH */ case OUTT_PS: - curp->outman = terminal_man; - curp->outmdoc = terminal_mdoc; + terminal_mdoc(curp->outdata, man); + break; + default: + break; + } + } + if (man->macroset == MACROSET_MAN) { + man_validate(man); + switch (curp->outtype) { + case OUTT_HTML: + html_man(curp->outdata, man); + break; + case OUTT_TREE: + tree_man(curp->outdata, man); + break; + case OUTT_MAN: + man_man(curp->outdata, man); + break; + case OUTT_PDF: + case OUTT_ASCII: + case OUTT_UTF8: + case OUTT_LOCALE: + case OUTT_PS: + terminal_man(curp->outdata, man); break; default: break; } } - - mparse_result(curp->mp, &mdoc, &man, NULL); - - /* Execute the out device, if it exists. */ - - if (man && curp->outman) - (*curp->outman)(curp->outdata, man); - if (mdoc && curp->outmdoc) - (*curp->outmdoc)(curp->outdata, mdoc); - -cleanup: - if (*level < rc) - *level = rc; } -static enum mandoclevel +static void passthrough(const char *file, int fd, int synopsis_only) { const char synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"; @@ -741,12 +825,12 @@ passthrough(const char *file, int fd, int synopsis_only) FILE *stream; const char *syscall; - char *line; - size_t len, off; - ssize_t nw; + char *line, *cp; + size_t linesz; int print; - fflush(stdout); + line = NULL; + linesz = 0; if ((stream = fdopen(fd, "r")) == NULL) { close(fd); @@ -755,48 +839,44 @@ passthrough(const char *file, int fd, int synopsis_only) } print = 0; - while ((line = fgetln(stream, &len)) != NULL) { + while (getline(&line, &linesz, stream) != -1) { + cp = line; if (synopsis_only) { if (print) { - if ( ! isspace((unsigned char)*line)) + if ( ! isspace((unsigned char)*cp)) goto done; - while (len && - isspace((unsigned char)*line)) { - line++; - len--; - } + while (isspace((unsigned char)*cp)) + cp++; } else { - if ((len == sizeof(synb) && - ! strncmp(line, synb, len - 1)) || - (len == sizeof(synr) && - ! strncmp(line, synr, len - 1))) + if (strcmp(cp, synb) == 0 || + strcmp(cp, synr) == 0) print = 1; continue; } } - for (off = 0; off < len; off += nw) - if ((nw = write(STDOUT_FILENO, line + off, - len - off)) == -1 || nw == 0) { - fclose(stream); - syscall = "write"; - goto fail; - } + if (fputs(cp, stdout)) { + fclose(stream); + syscall = "fputs"; + goto fail; + } } if (ferror(stream)) { fclose(stream); - syscall = "fgetln"; + syscall = "getline"; goto fail; } done: + free(line); fclose(stream); - return(MANDOCLEVEL_OK); + return; fail: - fprintf(stderr, "%s: %s: SYSERR: %s: %s", - progname, file, syscall, strerror(errno)); - return(MANDOCLEVEL_SYSERR); + free(line); + warn("%s: SYSERR: %s", file, syscall); + if (rc < MANDOCLEVEL_SYSERR) + rc = MANDOCLEVEL_SYSERR; } static int @@ -812,11 +892,10 @@ koptions(int *options, char *arg) } else if ( ! strcmp(arg, "us-ascii")) { *options &= ~(MPARSE_UTF8 | MPARSE_LATIN1); } else { - fprintf(stderr, "%s: -K %s: Bad argument\n", - progname, arg); - return(0); + warnx("-K %s: Bad argument", arg); + return 0; } - return(1); + return 1; } static int @@ -832,12 +911,11 @@ moptions(int *options, char *arg) else if (0 == strcmp(arg, "an")) *options |= MPARSE_MAN; else { - fprintf(stderr, "%s: -m %s: Bad argument\n", - progname, arg); - return(0); + warnx("-m %s: Bad argument", arg); + return 0; } - return(1); + return 1; } static int @@ -866,12 +944,11 @@ toptions(struct curparse *curp, char *arg) else if (0 == strcmp(arg, "pdf")) curp->outtype = OUTT_PDF; else { - fprintf(stderr, "%s: -T %s: Bad argument\n", - progname, arg); - return(0); + warnx("-T %s: Bad argument", arg); + return 0; } - return(1); + return 1; } static int @@ -895,7 +972,6 @@ woptions(struct curparse *curp, char *arg) curp->wstop = 1; break; case 1: - /* FALLTHROUGH */ case 2: curp->wlevel = MANDOCLEVEL_WARNING; break; @@ -909,13 +985,12 @@ woptions(struct curparse *curp, char *arg) curp->wlevel = MANDOCLEVEL_BADARG; break; default: - fprintf(stderr, "%s: -W %s: Bad argument\n", - progname, o); - return(0); + warnx("-W %s: Bad argument", o); + return 0; } } - return(1); + return 1; } static void @@ -924,7 +999,7 @@ mmsg(enum mandocerr t, enum mandoclevel lvl, { const char *mparse_msg; - fprintf(stderr, "%s: %s:", progname, file); + fprintf(stderr, "%s: %s:", getprogname(), file); if (line) fprintf(stderr, "%d:%d:", line, col + 1); @@ -941,55 +1016,21 @@ mmsg(enum mandocerr t, enum mandoclevel lvl, } static pid_t -spawn_pager(void) +spawn_pager(struct tag_files *tag_files) { #define MAX_PAGER_ARGS 16 char *argv[MAX_PAGER_ARGS]; const char *pager; char *cp; - int fildes[2]; + size_t cmdlen; int argc; pid_t pager_pid; - if (pipe(fildes) == -1) { - fprintf(stderr, "%s: pipe: %s\n", - progname, strerror(errno)); - return(0); - } - - switch (pager_pid = fork()) { - case -1: - fprintf(stderr, "%s: fork: %s\n", - progname, strerror(errno)); - exit((int)MANDOCLEVEL_SYSERR); - case 0: - break; - default: - close(fildes[0]); - if (dup2(fildes[1], STDOUT_FILENO) == -1) { - fprintf(stderr, "%s: dup output: %s\n", - progname, strerror(errno)); - exit((int)MANDOCLEVEL_SYSERR); - } - close(fildes[1]); - return(pager_pid); - } - - /* The child process becomes the pager. */ - - close(fildes[1]); - if (dup2(fildes[0], STDIN_FILENO) == -1) { - fprintf(stderr, "%s: dup input: %s\n", - progname, strerror(errno)); - exit((int)MANDOCLEVEL_SYSERR); - } - close(fildes[0]); - pager = getenv("MANPAGER"); if (pager == NULL || *pager == '\0') pager = getenv("PAGER"); if (pager == NULL || *pager == '\0') - pager = "/usr/bin/more -s"; + pager = "more -s"; cp = mandoc_strdup(pager); /* @@ -998,7 +1039,7 @@ spawn_pager(void) */ argc = 0; - while (argc + 1 < MAX_PAGER_ARGS) { + while (argc + 4 < MAX_PAGER_ARGS) { argv[argc++] = cp; cp = strchr(cp, ' '); if (cp == NULL) @@ -1009,12 +1050,43 @@ spawn_pager(void) if (*cp == '\0') break; } + + /* For more(1) and less(1), use the tag file. */ + + if ((cmdlen = strlen(argv[0])) >= 4) { + cp = argv[0] + cmdlen - 4; + if (strcmp(cp, "less") == 0 || strcmp(cp, "more") == 0) { + argv[argc++] = mandoc_strdup("-T"); + argv[argc++] = tag_files->tfn; + } + } + argv[argc++] = tag_files->ofn; argv[argc] = NULL; - /* Hand over to the pager. */ + switch (pager_pid = fork()) { + case -1: + err((int)MANDOCLEVEL_SYSERR, "fork"); + case 0: + /* Set pgrp in both parent and child to avoid racing exec. */ + (void)setpgid(0, 0); + break; + default: + (void)setpgid(pager_pid, 0); + (void)tcsetpgrp(STDIN_FILENO, pager_pid); +#if HAVE_PLEDGE + if (pledge("stdio rpath tmppath tty proc", NULL) == -1) + err((int)MANDOCLEVEL_SYSERR, "pledge"); +#endif + tag_files->pager_pid = pager_pid; + return pager_pid; + } + + /* The child process becomes the pager. */ + if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) + err((int)MANDOCLEVEL_SYSERR, "pager stdout"); + close(tag_files->ofd); + close(tag_files->tfd); execvp(argv[0], argv); - fprintf(stderr, "%s: exec: %s\n", - progname, strerror(errno)); - exit((int)MANDOCLEVEL_SYSERR); + err((int)MANDOCLEVEL_SYSERR, "exec %s", argv[0]); } diff --git a/contrib/mdocml/main.h b/contrib/mdocml/main.h index 9b04a78..e9e7e86 100644 --- a/contrib/mdocml/main.h +++ b/contrib/mdocml/main.h @@ -1,15 +1,15 @@ -/* $Id: main.h,v 1.20 2014/12/31 16:52:40 schwarze Exp $ */ +/* $Id: main.h,v 1.24 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -18,11 +18,8 @@ #define UNCONST(a) ((void *)(uintptr_t)(const void *)(a)) -__BEGIN_DECLS - -struct mchars; -struct mdoc; -struct man; +struct roff_man; +struct manoutput; /* * Definitions for main.c-visible output device functions, e.g., -Thtml @@ -31,28 +28,26 @@ struct man; * terminal output routines with different character settings. */ -void *html_alloc(const struct mchars *, char *); -void html_mdoc(void *, const struct mdoc *); -void html_man(void *, const struct man *); +void *html_alloc(const struct manoutput *); +void html_mdoc(void *, const struct roff_man *); +void html_man(void *, const struct roff_man *); void html_free(void *); -void tree_mdoc(void *, const struct mdoc *); -void tree_man(void *, const struct man *); +void tree_mdoc(void *, const struct roff_man *); +void tree_man(void *, const struct roff_man *); -void man_mdoc(void *, const struct mdoc *); -void man_man(void *, const struct man *); +void man_mdoc(void *, const struct roff_man *); +void man_man(void *, const struct roff_man *); -void *locale_alloc(const struct mchars *, char *); -void *utf8_alloc(const struct mchars *, char *); -void *ascii_alloc(const struct mchars *, char *); +void *locale_alloc(const struct manoutput *); +void *utf8_alloc(const struct manoutput *); +void *ascii_alloc(const struct manoutput *); void ascii_free(void *); void ascii_sepline(void *); -void *pdf_alloc(const struct mchars *, char *); -void *ps_alloc(const struct mchars *, char *); +void *pdf_alloc(const struct manoutput *); +void *ps_alloc(const struct manoutput *); void pspdf_free(void *); -void terminal_mdoc(void *, const struct mdoc *); -void terminal_man(void *, const struct man *); - -__END_DECLS +void terminal_mdoc(void *, const struct roff_man *); +void terminal_man(void *, const struct roff_man *); diff --git a/contrib/mdocml/man.1 b/contrib/mdocml/man.1 index 8580296..f29360b 100644 --- a/contrib/mdocml/man.1 +++ b/contrib/mdocml/man.1 @@ -1,4 +1,4 @@ -.\" $Id: man.1,v 1.13 2015/02/16 16:23:54 schwarze Exp $ +.\" $Id: man.1,v 1.16 2015/09/21 09:59:02 schwarze Exp $ .\" .\" Copyright (c) 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,7 +31,7 @@ .\" .\" @(#)man.1 8.2 (Berkeley) 1/2/94 .\" -.Dd $Mdocdate: February 16 2015 $ +.Dd $Mdocdate: September 21 2015 $ .Dt MAN 1 .Os .Sh NAME @@ -173,12 +173,6 @@ must be a colon separated list of directories. This search path may also be set using the environment variable .Ev MANPATH . -The subdirectories to be searched, and their search order, -are specified by the -.Dq _subdir -line in the -.Nm -configuration file. .It Fl m Ar path Augment the list of standard directories which .Nm @@ -194,12 +188,6 @@ the directories specified using the option or the .Ev MANPATH environment variable. -The subdirectories to be searched, and their search order, -are specified by the -.Dq _subdir -line in the -.Nm -configuration file. .It Fl O Ar option Ns = Ns Ar value Comma-separated output options. For each output format, the available options are described in the @@ -360,6 +348,13 @@ Any non-empty value of the environment variable .Ev MANPAGER will be used instead of the standard pagination program, .Xr more 1 . +If +.Xr less 1 +is used, the interactive +.Ic :t +command can be used to go to the definitions of various terms, for +example command line options, command modifiers, internal commands, +and environment variables. .It Ev MANPATH The standard search path used by .Nm @@ -370,18 +365,13 @@ variable. The format of the path is a colon .Pq Ql \&: separated list of directories. -The subdirectories to be searched, as well as their search order, -are specified by the -.Dq _subdir -line in the -.Nm -configuration file. .It Ev PAGER Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Pa /usr/bin/more Fl s +.Xr more 1 +.Fl s will be used. .El .Sh FILES diff --git a/contrib/mdocml/man.c b/contrib/mdocml/man.c index 4e7a398..31c094e 100644 --- a/contrib/mdocml/man.c +++ b/contrib/mdocml/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.149 2015/01/30 21:28:46 schwarze Exp $ */ +/* $Id: man.c,v 1.166 2015/10/22 21:54:23 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -8,9 +8,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -27,11 +27,13 @@ #include <stdio.h> #include <string.h> -#include "man.h" -#include "mandoc.h" #include "mandoc_aux.h" -#include "libman.h" +#include "mandoc.h" +#include "roff.h" +#include "man.h" #include "libmandoc.h" +#include "roff_int.h" +#include "libman.h" const char *const __man_macronames[MAN_MAX] = { "br", "TH", "SH", "SS", @@ -48,306 +50,25 @@ const char *const __man_macronames[MAN_MAX] = { const char * const *man_macronames = __man_macronames; -static void man_alloc1(struct man *); -static void man_breakscope(struct man *, enum mant); -static void man_descope(struct man *, int, int); -static void man_free1(struct man *); -static struct man_node *man_node_alloc(struct man *, int, int, - enum man_type, enum mant); -static void man_node_append(struct man *, struct man_node *); -static void man_node_free(struct man_node *); -static void man_node_unlink(struct man *, - struct man_node *); -static int man_ptext(struct man *, int, char *, int); -static int man_pmacro(struct man *, int, char *, int); - - -const struct man_node * -man_node(const struct man *man) -{ - - return(man->first); -} - -const struct man_meta * -man_meta(const struct man *man) -{ - - return(&man->meta); -} - -void -man_reset(struct man *man) -{ - - man_free1(man); - man_alloc1(man); -} - -void -man_free(struct man *man) -{ - - man_free1(man); - free(man); -} - -struct man * -man_alloc(struct roff *roff, struct mparse *parse, - const char *defos, int quick) -{ - struct man *p; - - p = mandoc_calloc(1, sizeof(struct man)); - - man_hash_init(); - p->parse = parse; - p->defos = defos; - p->quick = quick; - p->roff = roff; - - man_alloc1(p); - return(p); -} - -void -man_endparse(struct man *man) -{ +static void man_descope(struct roff_man *, int, int); +static int man_ptext(struct roff_man *, int, char *, int); +static int man_pmacro(struct roff_man *, int, char *, int); - man_macroend(man); -} int -man_parseln(struct man *man, int ln, char *buf, int offs) +man_parseln(struct roff_man *man, int ln, char *buf, int offs) { - if (man->last->type != MAN_EQN || ln > man->last->line) + if (man->last->type != ROFFT_EQN || ln > man->last->line) man->flags |= MAN_NEWLINE; - return (roff_getcontrol(man->roff, buf, &offs) ? + return roff_getcontrol(man->roff, buf, &offs) ? man_pmacro(man, ln, buf, offs) : - man_ptext(man, ln, buf, offs)); -} - -static void -man_free1(struct man *man) -{ - - if (man->first) - man_node_delete(man, man->first); - free(man->meta.title); - free(man->meta.source); - free(man->meta.date); - free(man->meta.vol); - free(man->meta.msec); -} - -static void -man_alloc1(struct man *man) -{ - - 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; -} - - -static void -man_node_append(struct man *man, struct man_node *p) -{ - - assert(man->last); - assert(man->first); - assert(p->type != MAN_ROOT); - - switch (man->next) { - case MAN_NEXT_SIBLING: - man->last->next = p; - p->prev = man->last; - p->parent = man->last->parent; - break; - case MAN_NEXT_CHILD: - man->last->child = p; - p->parent = man->last; - break; - default: - abort(); - /* NOTREACHED */ - } - - assert(p->parent); - p->parent->nchild++; - - switch (p->type) { - case MAN_BLOCK: - if (p->tok == MAN_SH || p->tok == MAN_SS) - man->flags &= ~MAN_LITERAL; - break; - case MAN_HEAD: - assert(p->parent->type == MAN_BLOCK); - p->parent->head = p; - break; - case MAN_BODY: - assert(p->parent->type == MAN_BLOCK); - p->parent->body = p; - break; - default: - break; - } - - man->last = p; - - switch (p->type) { - case MAN_TBL: - /* FALLTHROUGH */ - case MAN_TEXT: - man_valid_post(man); - break; - default: - break; - } -} - -static struct man_node * -man_node_alloc(struct man *man, int line, int pos, - enum man_type type, enum mant tok) -{ - struct man_node *p; - - p = mandoc_calloc(1, sizeof(struct man_node)); - p->line = line; - p->pos = pos; - p->type = type; - p->tok = tok; - - if (man->flags & MAN_NEWLINE) - p->flags |= MAN_LINE; - man->flags &= ~MAN_NEWLINE; - return(p); -} - -void -man_elem_alloc(struct man *man, int line, int pos, enum mant tok) -{ - struct man_node *p; - - p = man_node_alloc(man, line, pos, MAN_ELEM, tok); - man_node_append(man, p); - man->next = MAN_NEXT_CHILD; -} - -void -man_head_alloc(struct man *man, int line, int pos, enum mant tok) -{ - struct man_node *p; - - p = man_node_alloc(man, line, pos, MAN_HEAD, tok); - man_node_append(man, p); - man->next = MAN_NEXT_CHILD; -} - -void -man_body_alloc(struct man *man, int line, int pos, enum mant tok) -{ - struct man_node *p; - - p = man_node_alloc(man, line, pos, MAN_BODY, tok); - man_node_append(man, p); - man->next = MAN_NEXT_CHILD; -} - -void -man_block_alloc(struct man *man, int line, int pos, enum mant tok) -{ - struct man_node *p; - - p = man_node_alloc(man, line, pos, MAN_BLOCK, tok); - man_node_append(man, p); - man->next = MAN_NEXT_CHILD; -} - -void -man_word_alloc(struct man *man, int line, int pos, const char *word) -{ - struct man_node *n; - - n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX); - n->string = roff_strdup(man->roff, word); - man_node_append(man, n); - man->next = MAN_NEXT_SIBLING; -} - -void -man_word_append(struct man *man, const char *word) -{ - struct man_node *n; - char *addstr, *newstr; - - n = man->last; - addstr = roff_strdup(man->roff, word); - mandoc_asprintf(&newstr, "%s %s", n->string, addstr); - free(addstr); - free(n->string); - n->string = newstr; - man->next = MAN_NEXT_SIBLING; -} - -/* - * Free all of the resources held by a node. This does NOT unlink a - * node from its context; for that, see man_node_unlink(). - */ -static void -man_node_free(struct man_node *p) -{ - - free(p->string); - free(p); -} - -void -man_node_delete(struct man *man, struct man_node *p) -{ - - while (p->child) - man_node_delete(man, p->child); - - man_node_unlink(man, p); - man_node_free(p); -} - -void -man_addeqn(struct man *man, const struct eqn *ep) -{ - struct man_node *n; - - n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX); - n->eqn = ep; - if (ep->ln > man->last->line) - n->flags |= MAN_LINE; - man_node_append(man, n); - man->next = MAN_NEXT_SIBLING; - man_descope(man, ep->ln, ep->pos); -} - -void -man_addspan(struct man *man, const struct tbl_span *sp) -{ - struct man_node *n; - - man_breakscope(man, MAN_MAX); - n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX); - n->span = sp; - man_node_append(man, n); - man->next = MAN_NEXT_SIBLING; - man_descope(man, sp->line, 0); + man_ptext(man, ln, buf, offs); } static void -man_descope(struct man *man, int line, int offs) +man_descope(struct roff_man *man, int line, int offs) { /* * Co-ordinate what happens with having a next-line scope open: @@ -363,20 +84,20 @@ man_descope(struct man *man, int line, int offs) return; man->flags &= ~MAN_BLINE; man_unscope(man, man->last->parent); - man_body_alloc(man, line, offs, man->last->tok); + roff_body_alloc(man, line, offs, man->last->tok); } static int -man_ptext(struct man *man, int line, char *buf, int offs) +man_ptext(struct roff_man *man, int line, char *buf, int offs) { int i; /* Literal free-form text whitespace is preserved. */ if (man->flags & MAN_LITERAL) { - man_word_alloc(man, line, offs, buf + offs); + roff_word_alloc(man, line, offs, buf + offs); man_descope(man, line, offs); - return(1); + return 1; } for (i = offs; buf[i] == ' '; i++) @@ -391,10 +112,10 @@ man_ptext(struct man *man, int line, char *buf, int offs) /* Allocate a blank entry. */ if (man->last->tok != MAN_SH && man->last->tok != MAN_SS) { - man_elem_alloc(man, line, offs, MAN_sp); - man->next = MAN_NEXT_SIBLING; + roff_elem_alloc(man, line, offs, MAN_sp); + man->next = ROFF_NEXT_SIBLING; } - return(1); + return 1; } /* @@ -418,7 +139,7 @@ man_ptext(struct man *man, int line, char *buf, int offs) buf[i] = '\0'; } - man_word_alloc(man, line, offs, buf + offs); + roff_word_alloc(man, line, offs, buf + offs); /* * End-of-sentence check. If the last character is an unescaped @@ -431,15 +152,15 @@ man_ptext(struct man *man, int line, char *buf, int offs) man->last->flags |= MAN_EOS; man_descope(man, line, offs); - return(1); + return 1; } static int -man_pmacro(struct man *man, int ln, char *buf, int offs) +man_pmacro(struct roff_man *man, int ln, char *buf, int offs) { - struct man_node *n; + struct roff_node *n; const char *cp; - enum mant tok; + int tok; int i, ppos; int bline; char mac[5]; @@ -457,12 +178,12 @@ man_pmacro(struct man *man, int ln, char *buf, int offs) mac[i] = '\0'; - tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX; + tok = (i > 0 && i < 4) ? man_hash_find(mac) : TOKEN_NONE; - if (tok == MAN_MAX) { + if (tok == TOKEN_NONE) { mandoc_msg(MANDOCERR_MACRO, man->parse, ln, ppos, buf + ppos - 1); - return(1); + return 1; } /* Skip a leading escape sequence or tab. */ @@ -511,9 +232,9 @@ man_pmacro(struct man *man, int ln, char *buf, int offs) if (man->quick && tok == MAN_SH) { n = man->last; - if (n->type == MAN_BODY && + if (n->type == ROFFT_BODY && strcmp(n->prev->child->string, "NAME")) - return(2); + return 2; } /* @@ -524,20 +245,20 @@ man_pmacro(struct man *man, int ln, char *buf, int offs) if ( ! bline || man->flags & MAN_ELINE || man_macros[tok].flags & MAN_NSCOPED) - return(1); + return 1; assert(man->flags & MAN_BLINE); man->flags &= ~MAN_BLINE; man_unscope(man, man->last->parent); - man_body_alloc(man, ln, ppos, man->last->tok); - return(1); + roff_body_alloc(man, ln, ppos, man->last->tok); + return 1; } void -man_breakscope(struct man *man, enum mant tok) +man_breakscope(struct roff_man *man, int tok) { - struct man_node *n; + struct roff_node *n; /* * An element next line scope is open, @@ -545,142 +266,104 @@ man_breakscope(struct man *man, enum mant tok) * Delete the element that is being broken. */ - if (man->flags & MAN_ELINE && (tok == MAN_MAX || + if (man->flags & MAN_ELINE && (tok == TOKEN_NONE || ! (man_macros[tok].flags & MAN_NSCOPED))) { n = man->last; - assert(n->type != MAN_TEXT); + assert(n->type != ROFFT_TEXT); if (man_macros[n->tok].flags & MAN_NSCOPED) n = n->parent; mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line, n->pos, "%s breaks %s", - tok == MAN_MAX ? "TS" : man_macronames[tok], + tok == TOKEN_NONE ? "TS" : man_macronames[tok], man_macronames[n->tok]); - man_node_delete(man, n); + roff_node_delete(man, n); man->flags &= ~MAN_ELINE; } /* + * Weird special case: + * Switching fill mode closes section headers. + */ + + if (man->flags & MAN_BLINE && + (tok == MAN_nf || tok == MAN_fi) && + (man->last->tok == MAN_SH || man->last->tok == MAN_SS)) { + n = man->last; + man_unscope(man, n); + roff_body_alloc(man, n->line, n->pos, n->tok); + man->flags &= ~MAN_BLINE; + } + + /* * A block header next line scope is open, * and the new macro is not allowed inside block headers. * Delete the block that is being broken. */ - if (man->flags & MAN_BLINE && (tok == MAN_MAX || + if (man->flags & MAN_BLINE && (tok == TOKEN_NONE || man_macros[tok].flags & MAN_BSCOPE)) { n = man->last; - if (n->type == MAN_TEXT) + if (n->type == ROFFT_TEXT) n = n->parent; if ( ! (man_macros[n->tok].flags & MAN_BSCOPE)) n = n->parent; - assert(n->type == MAN_HEAD); + assert(n->type == ROFFT_HEAD); n = n->parent; - assert(n->type == MAN_BLOCK); + assert(n->type == ROFFT_BLOCK); assert(man_macros[n->tok].flags & MAN_SCOPED); mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse, n->line, n->pos, "%s breaks %s", - tok == MAN_MAX ? "TS" : man_macronames[tok], + tok == TOKEN_NONE ? "TS" : man_macronames[tok], man_macronames[n->tok]); - man_node_delete(man, n); + roff_node_delete(man, n); man->flags &= ~MAN_BLINE; } } -/* - * 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 *man, struct man_node *n) -{ - - /* Adjust siblings. */ - - if (n->prev) - n->prev->next = n->next; - if (n->next) - n->next->prev = n->prev; - - /* Adjust parent. */ - - if (n->parent) { - n->parent->nchild--; - if (n->parent->child == n) - n->parent->child = n->prev ? n->prev : n->next; - } - - /* Adjust parse point, if applicable. */ - - if (man && man->last == n) { - /*XXX: this can occur when bailing from validation. */ - /*assert(NULL == n->next);*/ - if (n->prev) { - man->last = n->prev; - man->next = MAN_NEXT_SIBLING; - } else { - man->last = n->parent; - man->next = MAN_NEXT_CHILD; - } - } - - if (man && man->first == n) - man->first = NULL; -} - const struct mparse * -man_mparse(const struct man *man) +man_mparse(const struct roff_man *man) { assert(man && man->parse); - return(man->parse); + return man->parse; } void -man_deroff(char **dest, const struct man_node *n) +man_state(struct roff_man *man, struct roff_node *n) { - char *cp; - size_t sz; - - if (n->type != MAN_TEXT) { - for (n = n->child; n; n = n->next) - man_deroff(dest, n); - return; - } - /* Skip leading whitespace and escape sequences. */ - - cp = n->string; - while ('\0' != *cp) { - if ('\\' == *cp) { - cp++; - mandoc_escape((const char **)&cp, NULL, NULL); - } else if (isspace((unsigned char)*cp)) - cp++; - else - break; + switch(n->tok) { + case MAN_nf: + case MAN_EX: + if (man->flags & MAN_LITERAL && ! (n->flags & MAN_VALID)) + mandoc_msg(MANDOCERR_NF_SKIP, man->parse, + n->line, n->pos, "nf"); + man->flags |= MAN_LITERAL; + break; + case MAN_fi: + case MAN_EE: + if ( ! (man->flags & MAN_LITERAL) && + ! (n->flags & MAN_VALID)) + mandoc_msg(MANDOCERR_FI_SKIP, man->parse, + n->line, n->pos, "fi"); + man->flags &= ~MAN_LITERAL; + break; + default: + break; } + man->last->flags |= MAN_VALID; +} - /* Skip trailing whitespace. */ - - for (sz = strlen(cp); sz; sz--) - if (0 == isspace((unsigned char)cp[sz-1])) - break; - - /* Skip empty strings. */ - - if (0 == sz) - return; - - if (NULL == *dest) { - *dest = mandoc_strndup(cp, sz); - return; - } +void +man_validate(struct roff_man *man) +{ - mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp); - free(*dest); - *dest = cp; + man->last = man->first; + man_node_validate(man); + man->flags &= ~MAN_LITERAL; } diff --git a/contrib/mdocml/man.cgi.8 b/contrib/mdocml/man.cgi.8 index 4d3588b..2e54dbf 100644 --- a/contrib/mdocml/man.cgi.8 +++ b/contrib/mdocml/man.cgi.8 @@ -1,4 +1,4 @@ -.\" $Id: man.cgi.8,v 1.11 2014/09/14 19:44:28 schwarze Exp $ +.\" $Id: man.cgi.8,v 1.13 2015/11/05 20:55:41 schwarze Exp $ .\" .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 14 2014 $ +.Dd $Mdocdate: November 5 2015 $ .Dt MAN.CGI 8 .Os .Sh NAME @@ -161,6 +161,9 @@ database inside each manpath. Configure your web server to execute CGI programs located in .Pa /cgi-bin . When using +.Ox +.Xr httpd 8 +or .Xr nginx 8 , the .Xr slowcgi 8 @@ -187,14 +190,8 @@ and to be specified without a trailing slash. When not specified, the CSS files are assumed to be in the document root. This is used in generated HTML code. -.It Ev CUSTOMIZE_BEGIN -A HTML string to be inserted right after opening the -.Aq BODY -element. .It Ev CUSTOMIZE_TITLE -An ASCII string to be used for the HTML -.Aq TITLE -element. +An ASCII string to be used for the HTML <TITLE> element. .It Ev HTTP_HOST The FQDN of the (possibly virtual) host the HTTP server is running on. This is used for @@ -349,15 +346,10 @@ Can be overridden by The path to the server document root relative to the server root. This is part of the web server configuration and not specific to .Nm . -.It Pa /htdocs/man-cgi.css -A style sheet for general -.Nm -styling, referenced from each generated HTML page. -.It Pa /htdocs/man.css +.It Pa /htdocs/mandoc.css A style sheet for .Xr mandoc 1 -HTML styling, referenced from each generated HTML page after -.Pa man-cgi.css . +HTML styling, referenced from each generated HTML page. .It Pa /man Default .Nm @@ -376,6 +368,12 @@ or any character not contained in the .Sx Restricted character set , .Nm reports an internal server error and exits without doing anything. +.It Pa /man/header.html +An optional file containing static HTML code to be inserted right +after opening the <BODY> element. +.It Pa /man/footer.html +An optional file containing static HTML code to be inserted right +before closing the <BODY> element. .It Pa /man/OpenBSD-current/man1/mandoc.1 An example .Xr mdoc 7 diff --git a/contrib/mdocml/man.conf.5 b/contrib/mdocml/man.conf.5 new file mode 100644 index 0000000..9cfeca7 --- /dev/null +++ b/contrib/mdocml/man.conf.5 @@ -0,0 +1,131 @@ +.\" $Id: man.conf.5,v 1.3 2015/03/27 21:33:20 schwarze Exp $ +.\" +.\" Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 27 2015 $ +.Dt MAN.CONF 5 +.Os +.Sh NAME +.Nm man.conf +.Nd configuration file for man +.Sh DESCRIPTION +This is the configuration file +for the +.Xr man 1 , +.Xr apropos 1 , +and +.Xr makewhatis 8 +utilities. +Its presence, and all directives, are optional. +.Pp +This file is an ASCII text file. +Leading whitespace on lines, lines starting with +.Sq # , +and blank lines are ignored. +Words are separated by whitespace. +The first word on each line is the name of a configuration directive. +.Pp +The following directives are supported: +.Bl -tag -width Ds +.It Ic manpath Ar path +Override the default search +.Ar path +for +.Xr man 1 , +.Xr apropos 1 , +and +.Xr makewhatis 8 . +It can be used multiple times to specify multiple paths, +with the order determining the manual page search order. +.Pp +Each path is a tree containing subdirectories +whose names consist of the strings +.Sq man +and/or +.Sq cat +followed by the names of sections, usually single digits. +The former are supposed to contain unformatted manual pages in +.Xr mdoc 7 +and/or +.Xr man 7 +format; file names should end with the name of the section +preceded by a dot. +The latter should contain preformatted manual pages; +file names should end with +.Ql .0 . +.Pp +Creating a +.Xr mandoc.db 5 +database with +.Xr makewhatis 8 +in each directory configured with +.Ic manpath +is recommended and necessary for +.Xr apropos 1 +to work, but not strictly required for +.Xr man 1 . +.It Ic output Ar option Op Ar value +Configure the default value of an output option. +These directives are overridden by the +.Fl O +command line options of the same names. +For details, see the +.Xr mandoc 1 +manual. +.Pp +.Bl -column fragment integer "ascii, utf8" -compact +.It Ar option Ta Ar value Ta used by Fl T Ta purpose +.It Ta Ta Ta +.It Ic fragment Ta none Ta Cm html Ta print only body +.It Ic includes Ta string Ta Cm html Ta path to header files +.It Ic indent Ta integer Ta Cm ascii , utf8 Ta left margin +.It Ic man Ta string Ta Cm html Ta path for Xr links +.It Ic paper Ta string Ta Cm ps , pdf Ta paper size +.It Ic style Ta string Ta Cm html Ta CSS file +.It Ic width Ta integer Ta Cm ascii , utf8 Ta right margin +.El +.It Ic _whatdb Ar path Ns Cm /whatis.db +This directive provides the same functionality as +.Ic manpath , +but using a historic and misleading syntax. +It is kept for backward compatibility for now, +but will eventually be removed. +.El +.Sh FILES +.Pa /etc/man.conf +.Sh EXAMPLES +The following configuration file reproduces the defaults: +installing it is equivalent to not having a +.Nm +file at all. +.Bd -literal -offset indent +manpath /usr/share/man +manpath /usr/X11R6/man +manpath /usr/local/man +.Ed +.Sh SEE ALSO +.Xr apropos 1 , +.Xr man 1 , +.Xr makewhatis 8 +.Sh HISTORY +A relatively complicated +.Nm +file format first appeared in +.Bx 4.3 Reno . +For +.Ox 5.8 , +it was redesigned from scratch, aiming for simplicity. +.Sh AUTHORS +.An Ingo Schwarze Aq Mt schwarze@openbsd.org diff --git a/contrib/mdocml/man.h b/contrib/mdocml/man.h index 9e8eb03..8f63f3b 100644 --- a/contrib/mdocml/man.h +++ b/contrib/mdocml/man.h @@ -1,116 +1,66 @@ -/* $Id: man.h,v 1.69 2015/01/24 02:41:49 schwarze Exp $ */ +/* $Id: man.h,v 1.77 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -enum mant { - MAN_br = 0, - MAN_TH, - MAN_SH, - MAN_SS, - MAN_TP, - MAN_LP, - MAN_PP, - MAN_P, - MAN_IP, - MAN_HP, - MAN_SM, - MAN_SB, - MAN_BI, - MAN_IB, - MAN_BR, - MAN_RB, - MAN_R, - MAN_B, - MAN_I, - MAN_IR, - MAN_RI, - MAN_sp, - MAN_nf, - MAN_fi, - MAN_RE, - MAN_RS, - MAN_DT, - MAN_UC, - MAN_PD, - MAN_AT, - MAN_in, - MAN_ft, - MAN_OP, - MAN_EX, - MAN_EE, - MAN_UR, - MAN_UE, - MAN_ll, - MAN_MAX -}; +#define MAN_br 0 +#define MAN_TH 1 +#define MAN_SH 2 +#define MAN_SS 3 +#define MAN_TP 4 +#define MAN_LP 5 +#define MAN_PP 6 +#define MAN_P 7 +#define MAN_IP 8 +#define MAN_HP 9 +#define MAN_SM 10 +#define MAN_SB 11 +#define MAN_BI 12 +#define MAN_IB 13 +#define MAN_BR 14 +#define MAN_RB 15 +#define MAN_R 16 +#define MAN_B 17 +#define MAN_I 18 +#define MAN_IR 19 +#define MAN_RI 20 +#define MAN_sp 21 +#define MAN_nf 22 +#define MAN_fi 23 +#define MAN_RE 24 +#define MAN_RS 25 +#define MAN_DT 26 +#define MAN_UC 27 +#define MAN_PD 28 +#define MAN_AT 29 +#define MAN_in 30 +#define MAN_ft 31 +#define MAN_OP 32 +#define MAN_EX 33 +#define MAN_EE 34 +#define MAN_UR 35 +#define MAN_UE 36 +#define MAN_ll 37 +#define MAN_MAX 38 -enum man_type { - MAN_TEXT, - MAN_ELEM, - MAN_ROOT, - MAN_BLOCK, - MAN_HEAD, - MAN_BODY, - MAN_TBL, - MAN_EQN -}; - -struct man_meta { - char *msec; /* `TH' section (1, 3p, etc.) */ - char *date; /* `TH' normalised date */ - char *vol; /* `TH' volume */ - char *title; /* `TH' title (e.g., FOO) */ - char *source; /* `TH' source (e.g., GNU) */ - int hasbody; /* document is not empty */ -}; - -struct man_node { - struct man_node *parent; /* parent AST node */ - struct man_node *child; /* first child AST node */ - struct man_node *next; /* sibling AST node */ - struct man_node *prev; /* prior sibling AST node */ - int nchild; /* number children */ - int line; - int pos; - enum mant tok; /* tok or MAN__MAX if none */ - int flags; -#define MAN_VALID (1 << 0) /* has been validated */ -#define MAN_EOS (1 << 2) /* at sentence boundary */ -#define MAN_LINE (1 << 3) /* first macro/text on line */ - enum man_type type; /* AST node type */ - char *string; /* TEXT node argument */ - struct man_node *head; /* BLOCK node HEAD ptr */ - struct man_node *tail; /* BLOCK node TAIL ptr */ - struct man_node *body; /* BLOCK node BODY ptr */ - const struct tbl_span *span; /* TBL */ - const struct eqn *eqn; /* EQN */ - int aux; /* decoded node data, type-dependent */ -}; - -/* Names of macros. Index is enum mant. */ +/* Names of macros. */ extern const char *const *man_macronames; -__BEGIN_DECLS - -struct man; -const struct man_node *man_node(const struct man *); -const struct man_meta *man_meta(const struct man *); -const struct mparse *man_mparse(const struct man *); -void man_deroff(char **, const struct man_node *); +struct roff_man; -__END_DECLS +const struct mparse *man_mparse(const struct roff_man *); +void man_validate(struct roff_man *); diff --git a/contrib/mdocml/man_hash.c b/contrib/mdocml/man_hash.c index 1cbfb1b..8573994 100644 --- a/contrib/mdocml/man_hash.c +++ b/contrib/mdocml/man_hash.c @@ -1,6 +1,7 @@ -/* $Id: man_hash.c,v 1.29 2014/12/01 08:05:52 schwarze Exp $ */ +/* $Id: man_hash.c,v 1.34 2015/10/06 18:32:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +24,7 @@ #include <limits.h> #include <string.h> +#include "roff.h" #include "man.h" #include "libman.h" @@ -46,18 +48,15 @@ static unsigned char table[26 * HASH_DEPTH]; -/* - * XXX - this hash has global scope, so if intended for use as a library - * with multiple callers, it will need re-invocation protection. - */ void man_hash_init(void) { int i, j, x; - memset(table, UCHAR_MAX, sizeof(table)); + if (*table != '\0') + return; - assert(MAN_MAX < UCHAR_MAX); + memset(table, UCHAR_MAX, sizeof(table)); for (i = 0; i < (int)MAN_MAX; i++) { x = man_macronames[i][0]; @@ -76,27 +75,27 @@ man_hash_init(void) } } -enum mant +int man_hash_find(const char *tmp) { int x, y, i; - enum mant tok; + int tok; if ('\0' == (x = tmp[0])) - return(MAN_MAX); + return TOKEN_NONE; if ( ! (isalpha((unsigned char)x))) - return(MAN_MAX); + return TOKEN_NONE; HASH_ROW(x); for (i = 0; i < HASH_DEPTH; i++) { if (UCHAR_MAX == (y = table[x + i])) - return(MAN_MAX); + return TOKEN_NONE; - tok = (enum mant)y; + tok = y; if (0 == strcmp(tmp, man_macronames[tok])) - return(tok); + return tok; } - return(MAN_MAX); + return TOKEN_NONE; } diff --git a/contrib/mdocml/man_html.c b/contrib/mdocml/man_html.c index 1109415..d71eb38 100644 --- a/contrib/mdocml/man_html.c +++ b/contrib/mdocml/man_html.c @@ -1,4 +1,4 @@ -/* $Id: man_html.c,v 1.112 2015/03/03 21:11:34 schwarze Exp $ */ +/* $Id: man_html.c,v 1.120 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -26,6 +26,7 @@ #include <string.h> #include "mandoc_aux.h" +#include "roff.h" #include "man.h" #include "out.h" #include "html.h" @@ -36,8 +37,8 @@ #define INDENT 5 -#define MAN_ARGS const struct man_meta *man, \ - const struct man_node *n, \ +#define MAN_ARGS const struct roff_meta *man, \ + const struct roff_node *n, \ struct mhtml *mh, \ struct html *h @@ -52,12 +53,11 @@ struct htmlman { }; static void print_bvspace(struct html *, - const struct man_node *); -static void print_man(MAN_ARGS); + const struct roff_node *); static void print_man_head(MAN_ARGS); static void print_man_nodelist(MAN_ARGS); static void print_man_node(MAN_ARGS); -static int a2width(const struct man_node *, +static int a2width(const struct roff_node *, struct roffsu *); static int man_B_pre(MAN_ARGS); static int man_HP_pre(MAN_ARGS); @@ -129,14 +129,14 @@ static const struct htmlman mans[MAN_MAX] = { * first, print it. */ static void -print_bvspace(struct html *h, const struct man_node *n) +print_bvspace(struct html *h, const struct roff_node *n) { if (n->body && n->body->child) - if (MAN_TBL == n->body->child->type) + if (n->body->child->type == ROFFT_TBL) return; - if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) + if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS) if (NULL == n->prev) return; @@ -144,36 +144,31 @@ print_bvspace(struct html *h, const struct man_node *n) } void -html_man(void *arg, const struct man *man) +html_man(void *arg, const struct roff_man *man) { struct mhtml mh; - - memset(&mh, 0, sizeof(struct mhtml)); - print_man(man_meta(man), man_node(man), &mh, (struct html *)arg); - putchar('\n'); -} - -static void -print_man(MAN_ARGS) -{ - struct tag *t, *tt; struct htmlpair tag; + struct html *h; + struct tag *t, *tt; + memset(&mh, 0, sizeof(mh)); PAIR_CLASS_INIT(&tag, "mandoc"); + h = (struct html *)arg; if ( ! (HTML_FRAGMENT & h->oflags)) { print_gen_decls(h); t = print_otag(h, TAG_HTML, 0, NULL); tt = print_otag(h, TAG_HEAD, 0, NULL); - print_man_head(man, n, mh, h); + print_man_head(&man->meta, man->first, &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(man, n, mh, h); + print_man_nodelist(&man->meta, man->first, &mh, h); print_tagq(h, t); + putchar('\n'); } static void @@ -208,10 +203,10 @@ print_man_node(MAN_ARGS) t = h->tags.head; switch (n->type) { - case MAN_ROOT: + case ROFFT_ROOT: man_root_pre(man, n, mh, h); break; - case MAN_TEXT: + case ROFFT_TEXT: if ('\0' == *n->string) { print_paragraph(h); return; @@ -222,12 +217,12 @@ print_man_node(MAN_ARGS) print_otag(h, TAG_BR, 0, NULL); print_text(h, n->string); return; - case MAN_EQN: + case ROFFT_EQN: if (n->flags & MAN_LINE) putchar('\n'); print_eqn(h, n->eqn); break; - case MAN_TBL: + case ROFFT_TBL: /* * This will take care of initialising all of the table * state data for the first table, then tearing it down @@ -266,10 +261,10 @@ print_man_node(MAN_ARGS) print_stagq(h, t); switch (n->type) { - case MAN_ROOT: + case ROFFT_ROOT: man_root_post(man, n, mh, h); break; - case MAN_EQN: + case ROFFT_EQN: break; default: if (mans[n->tok].post) @@ -279,15 +274,15 @@ print_man_node(MAN_ARGS) } static int -a2width(const struct man_node *n, struct roffsu *su) +a2width(const struct roff_node *n, struct roffsu *su) { - if (MAN_TEXT != n->type) - return(0); + if (n->type != ROFFT_TEXT) + return 0; if (a2roffsu(n->string, su, SCALE_EN)) - return(1); + return 1; - return(0); + return 0; } static void @@ -347,8 +342,8 @@ man_root_post(MAN_ARGS) PAIR_CLASS_INIT(&tag, "foot-os"); print_otag(h, TAG_TD, 1, &tag); - if (man->source) - print_text(h, man->source); + if (man->os) + print_text(h, man->os); print_tagq(h, t); } @@ -376,7 +371,7 @@ man_br_pre(MAN_ARGS) /* So the div isn't empty: */ print_text(h, "\\~"); - return(0); + return 0; } static int @@ -384,22 +379,22 @@ man_SH_pre(MAN_ARGS) { struct htmlpair tag; - if (MAN_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { mh->fl &= ~MANH_LITERAL; PAIR_CLASS_INIT(&tag, "section"); print_otag(h, TAG_DIV, 1, &tag); - return(1); - } else if (MAN_BODY == n->type) - return(1); + return 1; + } else if (n->type == ROFFT_BODY) + return 1; print_otag(h, TAG_H1, 0, NULL); - return(1); + return 1; } static int man_alt_pre(MAN_ARGS) { - const struct man_node *nn; + const struct roff_node *nn; int i, savelit; enum htmltag fp; struct tag *t; @@ -432,7 +427,6 @@ man_alt_pre(MAN_ARGS) break; default: abort(); - /* NOTREACHED */ } if (i) @@ -450,7 +444,7 @@ man_alt_pre(MAN_ARGS) if (savelit) mh->fl |= MANH_LITERAL; - return(0); + return 0; } static int @@ -460,7 +454,7 @@ man_SM_pre(MAN_ARGS) print_otag(h, TAG_SMALL, 0, NULL); if (MAN_SB == n->tok) print_otag(h, TAG_B, 0, NULL); - return(1); + return 1; } static int @@ -468,41 +462,41 @@ man_SS_pre(MAN_ARGS) { struct htmlpair tag; - if (MAN_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { mh->fl &= ~MANH_LITERAL; PAIR_CLASS_INIT(&tag, "subsection"); print_otag(h, TAG_DIV, 1, &tag); - return(1); - } else if (MAN_BODY == n->type) - return(1); + return 1; + } else if (n->type == ROFFT_BODY) + return 1; print_otag(h, TAG_H2, 0, NULL); - return(1); + return 1; } static int man_PP_pre(MAN_ARGS) { - if (MAN_HEAD == n->type) - return(0); - else if (MAN_BLOCK == n->type) + if (n->type == ROFFT_HEAD) + return 0; + else if (n->type == ROFFT_BLOCK) print_bvspace(h, n); - return(1); + return 1; } static int man_IP_pre(MAN_ARGS) { - const struct man_node *nn; + const struct roff_node *nn; - if (MAN_BODY == n->type) { + if (n->type == ROFFT_BODY) { print_otag(h, TAG_DD, 0, NULL); - return(1); - } else if (MAN_HEAD != n->type) { + return 1; + } else if (n->type != ROFFT_HEAD) { print_otag(h, TAG_DL, 0, NULL); - return(1); + return 1; } /* FIXME: width specification. */ @@ -526,7 +520,7 @@ man_IP_pre(MAN_ARGS) } } - return(0); + return 0; } static int @@ -534,12 +528,12 @@ man_HP_pre(MAN_ARGS) { struct htmlpair tag[2]; struct roffsu su; - const struct man_node *np; + const struct roff_node *np; - if (MAN_HEAD == n->type) - return(0); - else if (MAN_BLOCK != n->type) - return(1); + if (n->type == ROFFT_HEAD) + return 0; + else if (n->type != ROFFT_BLOCK) + return 1; np = n->head->child; @@ -555,7 +549,7 @@ man_HP_pre(MAN_ARGS) PAIR_STYLE_INIT(&tag[0], h); PAIR_CLASS_INIT(&tag[1], "spacer"); print_otag(h, TAG_DIV, 2, tag); - return(1); + return 1; } static int @@ -584,7 +578,7 @@ man_OP_pre(MAN_ARGS) print_stagq(h, tt); h->flags |= HTML_NOSPACE; print_text(h, "]"); - return(0); + return 0; } static int @@ -592,7 +586,7 @@ man_B_pre(MAN_ARGS) { print_otag(h, TAG_B, 0, NULL); - return(1); + return 1; } static int @@ -600,7 +594,7 @@ man_I_pre(MAN_ARGS) { print_otag(h, TAG_I, 0, NULL); - return(1); + return 1; } static int @@ -613,7 +607,7 @@ man_literal_pre(MAN_ARGS) } else mh->fl |= MANH_LITERAL; - return(0); + return 0; } static int @@ -621,14 +615,14 @@ man_in_pre(MAN_ARGS) { print_otag(h, TAG_BR, 0, NULL); - return(0); + return 0; } static int man_ign_pre(MAN_ARGS) { - return(0); + return 0; } static int @@ -637,10 +631,10 @@ man_RS_pre(MAN_ARGS) struct htmlpair tag; struct roffsu su; - if (MAN_HEAD == n->type) - return(0); - else if (MAN_BODY == n->type) - return(1); + if (n->type == ROFFT_HEAD) + return 0; + else if (n->type == ROFFT_BODY) + return 1; SCALE_HS_INIT(&su, INDENT); if (n->head->child) @@ -650,7 +644,7 @@ man_RS_pre(MAN_ARGS) bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); - return(1); + return 1; } static int @@ -659,19 +653,19 @@ man_UR_pre(MAN_ARGS) struct htmlpair tag[2]; n = n->child; - assert(MAN_HEAD == n->type); - if (n->nchild) { - assert(MAN_TEXT == n->child->type); + assert(n->type == ROFFT_HEAD); + if (n->child != NULL) { + assert(n->child->type == ROFFT_TEXT); PAIR_CLASS_INIT(&tag[0], "link-ext"); PAIR_HREF_INIT(&tag[1], n->child->string); print_otag(h, TAG_A, 2, tag); } - assert(MAN_BODY == n->next->type); - if (n->next->nchild) + assert(n->next->type == ROFFT_BODY); + if (n->next->child != NULL) n = n->next; print_man_nodelist(man, n->child, mh, h); - return(0); + return 0; } diff --git a/contrib/mdocml/man_macro.c b/contrib/mdocml/man_macro.c index c86ab6f..d153357 100644 --- a/contrib/mdocml/man_macro.c +++ b/contrib/mdocml/man_macro.c @@ -1,4 +1,4 @@ -/* $Id: man_macro.c,v 1.98 2015/02/06 11:54:36 schwarze Exp $ */ +/* $Id: man_macro.c,v 1.114 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2012, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -8,9 +8,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -25,37 +25,27 @@ #include <stdlib.h> #include <string.h> -#include "man.h" #include "mandoc.h" +#include "roff.h" +#include "man.h" #include "libmandoc.h" +#include "roff_int.h" #include "libman.h" -enum rew { - REW_REWIND, - REW_NOHALT, - REW_HALT -}; - static void blk_close(MACRO_PROT_ARGS); static void blk_exp(MACRO_PROT_ARGS); static void blk_imp(MACRO_PROT_ARGS); static void in_line_eoln(MACRO_PROT_ARGS); -static int man_args(struct man *, int, +static int man_args(struct roff_man *, int, int *, char *, char **); - -static void rew_scope(enum man_type, - struct man *, enum mant); -static enum rew rew_dohalt(enum mant, enum man_type, - const struct man_node *); -static enum rew rew_block(enum mant, enum man_type, - const struct man_node *); +static void rew_scope(struct roff_man *, int); const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, MAN_NSCOPED }, /* br */ { in_line_eoln, MAN_BSCOPE }, /* TH */ { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SH */ { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SS */ - { blk_imp, MAN_BSCOPE | MAN_SCOPED | MAN_FSCOPED }, /* TP */ + { blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* TP */ { blk_imp, MAN_BSCOPE }, /* LP */ { blk_imp, MAN_BSCOPE }, /* PP */ { blk_imp, MAN_BSCOPE }, /* P */ @@ -73,20 +63,20 @@ const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, 0 }, /* IR */ { in_line_eoln, 0 }, /* RI */ { in_line_eoln, MAN_NSCOPED }, /* sp */ - { in_line_eoln, MAN_BSCOPE }, /* nf */ - { in_line_eoln, MAN_BSCOPE }, /* fi */ + { in_line_eoln, MAN_NSCOPED }, /* nf */ + { in_line_eoln, MAN_NSCOPED }, /* fi */ { blk_close, MAN_BSCOPE }, /* RE */ - { blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* RS */ + { blk_exp, MAN_BSCOPE }, /* RS */ { in_line_eoln, 0 }, /* DT */ { in_line_eoln, 0 }, /* UC */ - { in_line_eoln, 0 }, /* PD */ + { in_line_eoln, MAN_NSCOPED }, /* PD */ { in_line_eoln, 0 }, /* AT */ { 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 */ - { blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */ + { blk_exp, MAN_BSCOPE }, /* UR */ { blk_close, MAN_BSCOPE }, /* UE */ { in_line_eoln, 0 }, /* ll */ }; @@ -95,9 +85,9 @@ const struct man_macro * const man_macros = __man_macros; void -man_unscope(struct man *man, const struct man_node *to) +man_unscope(struct roff_man *man, const struct roff_node *to) { - struct man_node *n; + struct roff_node *n; to = to->parent; n = man->last; @@ -115,17 +105,17 @@ man_unscope(struct man *man, const struct man_node *to) if (man->flags & MAN_ELINE) man->flags &= ~MAN_ELINE; else { - assert(n->type == MAN_HEAD); + assert(n->type == ROFFT_HEAD); n = n->parent; man->flags &= ~MAN_BLINE; } man->last = n; n = n->parent; - man_node_delete(man, man->last); + roff_node_delete(man, man->last); continue; } - if (n->type == MAN_BLOCK && - man_macros[n->tok].flags & MAN_EXPLICIT) + if (n->type == ROFFT_BLOCK && + man_macros[n->tok].fp == blk_exp) mandoc_msg(MANDOCERR_BLK_NOEND, man->parse, n->line, n->pos, man_macronames[n->tok]); @@ -140,7 +130,7 @@ man_unscope(struct man *man, const struct man_node *to) man->last = n; n = n->parent; - man_valid_post(man); + man->last->flags |= MAN_VALID; } /* @@ -151,90 +141,7 @@ man_unscope(struct man *man, const struct man_node *to) */ man->next = (man->last == to) ? - MAN_NEXT_CHILD : MAN_NEXT_SIBLING; -} - -static enum rew -rew_block(enum mant ntok, enum man_type type, const struct man_node *n) -{ - - if (type == MAN_BLOCK && ntok == n->parent->tok && - n->parent->type == MAN_BODY) - return(REW_REWIND); - return(ntok == n->tok ? REW_HALT : REW_NOHALT); -} - -/* - * There are three scope levels: scoped to the root (all), scoped to the - * section (all less sections), and scoped to subsections (all less - * sections and subsections). - */ -static enum rew -rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n) -{ - enum rew c; - - /* We cannot progress beyond the root ever. */ - if (MAN_ROOT == n->type) - return(REW_HALT); - - assert(n->parent); - - /* Normal nodes shouldn't go to the level of the root. */ - if (MAN_ROOT == n->parent->type) - return(REW_REWIND); - - /* Already-validated nodes should be closed out. */ - if (MAN_VALID & n->flags) - return(REW_NOHALT); - - /* First: rewind to ourselves. */ - 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: - * section, sub-section, etc. - */ - - switch (tok) { - case MAN_SH: - break; - case MAN_SS: - /* Rewind to a section, if a block. */ - if (REW_NOHALT != (c = rew_block(MAN_SH, type, 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); - /* Rewind to a section, if a block. */ - if (REW_NOHALT != (c = rew_block(MAN_SH, type, n))) - return(c); - break; - default: - /* Rewind to an offsetter, if a block. */ - if (REW_NOHALT != (c = rew_block(MAN_RS, type, n))) - return(c); - /* Rewind to a subsection, if a block. */ - if (REW_NOHALT != (c = rew_block(MAN_SS, type, n))) - return(c); - /* Rewind to a section, if a block. */ - if (REW_NOHALT != (c = rew_block(MAN_SH, type, n))) - return(c); - break; - } - - return(REW_NOHALT); + ROFF_NEXT_CHILD : ROFF_NEXT_SIBLING; } /* @@ -243,30 +150,40 @@ 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 void -rew_scope(enum man_type type, struct man *man, enum mant tok) +rew_scope(struct roff_man *man, int tok) { - struct man_node *n; - enum rew c; + struct roff_node *n; - 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 - * rewinding (REW_NOHALT). - */ - c = rew_dohalt(tok, type, n); - if (REW_HALT == c) - return; - if (REW_REWIND == c) - break; - } + /* Preserve empty paragraphs before RS. */ - /* - * Rewind until the current point. Warn if we're a roff - * instruction that's mowing over explicit scopes. - */ + n = man->last; + if (tok == MAN_RS && n->child == NULL && + (n->tok == MAN_P || n->tok == MAN_PP || n->tok == MAN_LP)) + return; - man_unscope(man, n); + for (;;) { + if (n->type == ROFFT_ROOT) + return; + if (n->flags & MAN_VALID) { + n = n->parent; + continue; + } + if (n->type != ROFFT_BLOCK) { + if (n->parent->type == ROFFT_ROOT) { + man_unscope(man, n); + return; + } else { + n = n->parent; + continue; + } + } + if (tok != MAN_SH && (n->tok == MAN_SH || + (tok != MAN_SS && (n->tok == MAN_SS || + man_macros[n->tok].fp == blk_exp)))) + return; + man_unscope(man, n); + n = man->last; + } } @@ -276,8 +193,8 @@ rew_scope(enum man_type type, struct man *man, enum mant tok) void blk_close(MACRO_PROT_ARGS) { - enum mant ntok; - const struct man_node *nn; + int ntok; + const struct roff_node *nn; char *p; int nrew, target; @@ -288,7 +205,7 @@ blk_close(MACRO_PROT_ARGS) if ( ! man_args(man, line, pos, buf, &p)) break; for (nn = man->last->parent; nn; nn = nn->parent) - if (nn->tok == ntok && nn->type == MAN_BLOCK) + if (nn->tok == ntok && nn->type == ROFFT_BLOCK) nrew++; target = strtol(p, &p, 10); if (*p != '\0') @@ -308,17 +225,16 @@ blk_close(MACRO_PROT_ARGS) break; default: abort(); - /* NOTREACHED */ } for (nn = man->last->parent; nn; nn = nn->parent) - if (nn->tok == ntok && nn->type == MAN_BLOCK && ! --nrew) + if (nn->tok == ntok && nn->type == ROFFT_BLOCK && ! --nrew) break; if (nn == NULL) { mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse, line, ppos, man_macronames[tok]); - rew_scope(MAN_BLOCK, man, MAN_PP); + rew_scope(man, MAN_PP); } else { line = man->last->line; ppos = man->last->pos; @@ -337,18 +253,17 @@ blk_close(MACRO_PROT_ARGS) void blk_exp(MACRO_PROT_ARGS) { - struct man_node *head; + struct roff_node *head; char *p; int la; - rew_scope(MAN_BLOCK, man, tok); - man_block_alloc(man, line, ppos, tok); - man_head_alloc(man, line, ppos, tok); - head = man->last; + rew_scope(man, tok); + roff_block_alloc(man, line, ppos, tok); + head = roff_head_alloc(man, line, ppos, tok); la = *pos; if (man_args(man, line, pos, buf, &p)) - man_word_alloc(man, line, la, p); + roff_word_alloc(man, line, la, p); if (buf[*pos] != '\0') mandoc_vmsg(MANDOCERR_ARG_EXCESS, @@ -356,12 +271,12 @@ blk_exp(MACRO_PROT_ARGS) man_macronames[tok], buf + *pos); man_unscope(man, head); - man_body_alloc(man, line, ppos, tok); + roff_body_alloc(man, line, ppos, tok); } /* - * Parse an implicit-block macro. These contain a MAN_HEAD and a - * MAN_BODY contained within a MAN_BLOCK. Rules for closing out other + * Parse an implicit-block macro. These contain a ROFFT_HEAD and a + * ROFFT_BODY contained within a ROFFT_BLOCK. Rules for closing out other * scopes, such as `SH' closing out an `SS', are defined in the rew * routines. */ @@ -370,13 +285,13 @@ blk_imp(MACRO_PROT_ARGS) { int la; char *p; - struct man_node *n; + struct roff_node *n; - rew_scope(MAN_BODY, man, tok); - rew_scope(MAN_BLOCK, man, tok); - man_block_alloc(man, line, ppos, tok); - man_head_alloc(man, line, ppos, tok); - n = man->last; + rew_scope(man, tok); + n = roff_block_alloc(man, line, ppos, tok); + if (n->tok == MAN_SH || n->tok == MAN_SS) + man->flags &= ~MAN_LITERAL; + n = roff_head_alloc(man, line, ppos, tok); /* Add line arguments. */ @@ -384,23 +299,25 @@ blk_imp(MACRO_PROT_ARGS) la = *pos; if ( ! man_args(man, line, pos, buf, &p)) break; - man_word_alloc(man, line, la, p); + roff_word_alloc(man, line, la, p); } - /* Close out head and open body (unless MAN_SCOPE). */ + /* + * For macros having optional next-line scope, + * keep the head open if there were no arguments. + * For `TP', always keep the head open. + */ - if (man_macros[tok].flags & MAN_SCOPED) { - /* If we're forcing scope (`TP'), keep it open. */ - if (man_macros[tok].flags & MAN_FSCOPED) { - man->flags |= MAN_BLINE; - return; - } else if (n == man->last) { - man->flags |= MAN_BLINE; - return; - } + if (man_macros[tok].flags & MAN_SCOPED && + (tok == MAN_TP || n == man->last)) { + man->flags |= MAN_BLINE; + return; } - rew_scope(MAN_HEAD, man, tok); - man_body_alloc(man, line, ppos, tok); + + /* Close out the head and open the body. */ + + man_unscope(man, n); + roff_body_alloc(man, line, ppos, tok); } void @@ -408,9 +325,9 @@ in_line_eoln(MACRO_PROT_ARGS) { int la; char *p; - struct man_node *n; + struct roff_node *n; - man_elem_alloc(man, line, ppos, tok); + roff_elem_alloc(man, line, ppos, tok); n = man->last; for (;;) { @@ -432,10 +349,10 @@ in_line_eoln(MACRO_PROT_ARGS) if ( ! man_args(man, line, pos, buf, &p)) break; if (man_macros[tok].flags & MAN_JOIN && - man->last->type == MAN_TEXT) - man_word_append(man, p); + man->last->type == ROFFT_TEXT) + roff_word_append(man, p); else - man_word_alloc(man, line, la, p); + roff_word_alloc(man, line, la, p); } /* @@ -459,43 +376,28 @@ in_line_eoln(MACRO_PROT_ARGS) return; } - assert(man->last->type != MAN_ROOT); - man->next = MAN_NEXT_SIBLING; + assert(man->last->type != ROFFT_ROOT); + man->next = ROFF_NEXT_SIBLING; - /* - * Rewind our element scope. Note that when TH is pruned, we'll - * be back at the root, so make sure that we don't clobber as - * its sibling. - */ + /* Rewind our element scope. */ for ( ; man->last; man->last = man->last->parent) { + man_state(man, man->last); if (man->last == n) break; - if (man->last->type == MAN_ROOT) - break; - man_valid_post(man); } - - assert(man->last); - - /* - * Same here regarding whether we're back at the root. - */ - - if (man->last->type != MAN_ROOT) - man_valid_post(man); } - void -man_macroend(struct man *man) +man_endparse(struct roff_man *man) { man_unscope(man, man->first); + man->flags &= ~MAN_LITERAL; } static int -man_args(struct man *man, int line, int *pos, char *buf, char **v) +man_args(struct roff_man *man, int line, int *pos, char *buf, char **v) { char *start; @@ -504,8 +406,8 @@ man_args(struct man *man, int line, int *pos, char *buf, char **v) assert(' ' != *start); if ('\0' == *start) - return(0); + return 0; *v = mandoc_getarg(man->parse, v, line, pos); - return(1); + return 1; } diff --git a/contrib/mdocml/man_term.c b/contrib/mdocml/man_term.c index 8be7927..f45e24a 100644 --- a/contrib/mdocml/man_term.c +++ b/contrib/mdocml/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.169 2015/03/06 15:48:52 schwarze Exp $ */ +/* $Id: man_term.c,v 1.187 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -26,10 +26,11 @@ #include <stdlib.h> #include <string.h> -#include "mandoc.h" #include "mandoc_aux.h" -#include "out.h" +#include "mandoc.h" +#include "roff.h" #include "man.h" +#include "out.h" #include "term.h" #include "main.h" @@ -47,8 +48,8 @@ struct mtermp { #define DECL_ARGS struct termp *p, \ struct mtermp *mt, \ - struct man_node *n, \ - const struct man_meta *meta + struct roff_node *n, \ + const struct roff_meta *meta struct termact { int (*pre)(DECL_ARGS); @@ -59,10 +60,12 @@ struct termact { static void print_man_nodelist(DECL_ARGS); 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_man_head(struct termp *, + const struct roff_meta *); +static void print_man_foot(struct termp *, + const struct roff_meta *); static void print_bvspace(struct termp *, - const struct man_node *, int); + const struct roff_node *, int); static int pre_B(DECL_ARGS); static int pre_HP(DECL_ARGS); @@ -135,36 +138,32 @@ static const struct termact termacts[MAN_MAX] = { void -terminal_man(void *arg, const struct man *man) +terminal_man(void *arg, const struct roff_man *man) { struct termp *p; - const struct man_meta *meta; - struct man_node *n; + struct roff_node *n; struct mtermp mt; p = (struct termp *)arg; - p->overstep = 0; p->rmargin = p->maxrmargin = p->defrmargin; p->tabwidth = term_len(p, 5); - n = man_node(man)->child; - meta = man_meta(man); - 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; + n = man->first->child; if (p->synopsisonly) { while (n != NULL) { if (n->tok == MAN_SH && - n->child->child->type == MAN_TEXT && + n->child->child->type == ROFFT_TEXT && !strcmp(n->child->child->string, "SYNOPSIS")) { if (n->child->next->child != NULL) print_man_nodelist(p, &mt, - n->child->next->child, meta); + n->child->next->child, + &man->meta); term_newln(p); break; } @@ -173,10 +172,10 @@ terminal_man(void *arg, const struct man *man) } else { if (p->defindent == 0) p->defindent = 7; - term_begin(p, print_man_head, print_man_foot, meta); + term_begin(p, print_man_head, print_man_foot, &man->meta); p->flags |= TERMP_NOSPACE; if (n != NULL) - print_man_nodelist(p, &mt, n, meta); + print_man_nodelist(p, &mt, n, &man->meta); term_end(p); } } @@ -190,17 +189,17 @@ terminal_man(void *arg, const struct man *man) * first, print it. */ static void -print_bvspace(struct termp *p, const struct man_node *n, int pardist) +print_bvspace(struct termp *p, const struct roff_node *n, int pardist) { int i; term_newln(p); if (n->body && n->body->child) - if (MAN_TBL == n->body->child->type) + if (n->body->child->type == ROFFT_TBL) return; - if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) + if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS) if (NULL == n->prev) return; @@ -213,15 +212,15 @@ static int pre_ign(DECL_ARGS) { - return(0); + return 0; } static int pre_ll(DECL_ARGS) { - term_setwidth(p, n->nchild ? n->child->string : NULL); - return(0); + term_setwidth(p, n->child != NULL ? n->child->string : NULL); + return 0; } static int @@ -229,7 +228,7 @@ pre_I(DECL_ARGS) { term_fontrepl(p, TERMFONT_UNDER); - return(1); + return 1; } static int @@ -256,7 +255,7 @@ pre_literal(DECL_ARGS) p->flags |= TERMP_NOSPACE; } - return(0); + return 0; } static int @@ -267,19 +266,19 @@ pre_PD(DECL_ARGS) n = n->child; if (n == NULL) { mt->pardist = 1; - return(0); + return 0; } - assert(MAN_TEXT == n->type); + assert(n->type == ROFFT_TEXT); if (a2roffsu(n->string, &su, SCALE_VS)) mt->pardist = term_vspan(p, &su); - return(0); + return 0; } static int pre_alternate(DECL_ARGS) { enum termfont font[2]; - struct man_node *nn; + struct roff_node *nn; int savelit, i; switch (n->tok) { @@ -318,12 +317,15 @@ pre_alternate(DECL_ARGS) term_fontrepl(p, font[i]); if (savelit && NULL == nn->next) mt->fl |= MANT_LITERAL; - print_man_node(p, mt, nn, meta); + assert(nn->type == ROFFT_TEXT); + term_word(p, nn->string); + if (nn->flags & MAN_EOS) + p->flags |= TERMP_SENTENCE; if (nn->next) p->flags |= TERMP_NOSPACE; } - return(0); + return 0; } static int @@ -331,7 +333,7 @@ pre_B(DECL_ARGS) { term_fontrepl(p, TERMFONT_BOLD); - return(1); + return 1; } static int @@ -353,7 +355,7 @@ pre_OP(DECL_ARGS) term_fontrepl(p, TERMFONT_NONE); p->flags |= TERMP_NOSPACE; term_word(p, "]"); - return(0); + return 0; } static int @@ -363,20 +365,17 @@ pre_ft(DECL_ARGS) if (NULL == n->child) { term_fontlast(p); - return(0); + return 0; } cp = n->child->string; switch (*cp) { case '4': - /* FALLTHROUGH */ case '3': - /* FALLTHROUGH */ case 'B': term_fontrepl(p, TERMFONT_BOLD); break; case '2': - /* FALLTHROUGH */ case 'I': term_fontrepl(p, TERMFONT_UNDER); break; @@ -384,16 +383,14 @@ pre_ft(DECL_ARGS) term_fontlast(p); break; case '1': - /* FALLTHROUGH */ case 'C': - /* FALLTHROUGH */ case 'R': term_fontrepl(p, TERMFONT_NONE); break; default: break; } - return(0); + return 0; } static int @@ -408,7 +405,7 @@ pre_in(DECL_ARGS) if (NULL == n->child) { p->offset = mt->offset; - return(0); + return 0; } cp = n->child->string; @@ -422,9 +419,9 @@ pre_in(DECL_ARGS) cp--; if ( ! a2roffsu(++cp, &su, SCALE_EN)) - return(0); + return 0; - v = term_hspan(p, &su); + v = (term_hspan(p, &su) + 11) / 24; if (less < 0) p->offset -= p->offset > v ? v : p->offset; @@ -435,7 +432,7 @@ pre_in(DECL_ARGS) if (p->offset > SHRT_MAX) p->offset = term_len(p, p->defindent); - return(0); + return 0; } static int @@ -447,16 +444,11 @@ pre_sp(DECL_ARGS) if ((NULL == n->prev && n->parent)) { 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); + return 0; default: break; } @@ -480,24 +472,35 @@ pre_sp(DECL_ARGS) for (i = 0; i < len; i++) term_vspace(p); - return(0); + /* + * Handle an explicit break request in the same way + * as an overflowing line. + */ + + if (p->flags & TERMP_BRIND) { + p->offset = p->rmargin; + p->rmargin = p->maxrmargin; + p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); + } + + return 0; } static int pre_HP(DECL_ARGS) { struct roffsu su; - const struct man_node *nn; + const struct roff_node *nn; int len; switch (n->type) { - case MAN_BLOCK: + case ROFFT_BLOCK: print_bvspace(p, n, mt->pardist); - return(1); - case MAN_BODY: + return 1; + case ROFFT_BODY: break; default: - return(0); + return 0; } if ( ! (MANT_LITERAL & mt->fl)) { @@ -509,7 +512,7 @@ pre_HP(DECL_ARGS) if ((nn = n->parent->head->child) != NULL && a2roffsu(nn->string, &su, SCALE_EN)) { - len = term_hspan(p, &su); + len = term_hspan(p, &su) / 24; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; else if (len > SHRT_MAX) @@ -520,7 +523,7 @@ pre_HP(DECL_ARGS) p->offset = mt->offset; p->rmargin = mt->offset + len; - return(1); + return 1; } static void @@ -528,8 +531,19 @@ post_HP(DECL_ARGS) { switch (n->type) { - case MAN_BODY: + case ROFFT_BODY: term_newln(p); + + /* + * Compatibility with a groff bug. + * The .HP macro uses the undocumented .tag request + * which causes a line break and cancels no-space + * mode even if there isn't any output. + */ + + if (n->child == NULL) + term_vspace(p); + p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); p->trailspace = 0; p->offset = mt->offset; @@ -545,7 +559,7 @@ pre_PP(DECL_ARGS) { switch (n->type) { - case MAN_BLOCK: + case ROFFT_BLOCK: mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); print_bvspace(p, n, mt->pardist); break; @@ -554,36 +568,36 @@ pre_PP(DECL_ARGS) break; } - return(MAN_HEAD != n->type); + return n->type != ROFFT_HEAD; } static int pre_IP(DECL_ARGS) { struct roffsu su; - const struct man_node *nn; + const struct roff_node *nn; int len, savelit; switch (n->type) { - case MAN_BODY: + case ROFFT_BODY: p->flags |= TERMP_NOSPACE; break; - case MAN_HEAD: + case ROFFT_HEAD: p->flags |= TERMP_NOBREAK; p->trailspace = 1; break; - case MAN_BLOCK: + case ROFFT_BLOCK: print_bvspace(p, n, mt->pardist); /* FALLTHROUGH */ default: - return(1); + return 1; } /* Calculate the offset from the optional second argument. */ if ((nn = n->parent->head->child) != NULL && (nn = nn->next) != NULL && a2roffsu(nn->string, &su, SCALE_EN)) { - len = term_hspan(p, &su); + len = term_hspan(p, &su) / 24; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; else if (len > SHRT_MAX) @@ -593,7 +607,7 @@ pre_IP(DECL_ARGS) len = mt->lmargin[mt->lmargincur]; switch (n->type) { - case MAN_HEAD: + case ROFFT_HEAD: p->offset = mt->offset; p->rmargin = mt->offset + len; @@ -606,8 +620,8 @@ pre_IP(DECL_ARGS) if (savelit) mt->fl |= MANT_LITERAL; - return(0); - case MAN_BODY: + return 0; + case ROFFT_BODY: p->offset = mt->offset + len; p->rmargin = p->maxrmargin; break; @@ -615,7 +629,7 @@ pre_IP(DECL_ARGS) break; } - return(1); + return 1; } static void @@ -623,13 +637,13 @@ post_IP(DECL_ARGS) { switch (n->type) { - case MAN_HEAD: + case ROFFT_HEAD: term_flushln(p); p->flags &= ~TERMP_NOBREAK; p->trailspace = 0; p->rmargin = p->maxrmargin; break; - case MAN_BODY: + case ROFFT_BODY: term_newln(p); p->offset = mt->offset; break; @@ -642,22 +656,22 @@ static int pre_TP(DECL_ARGS) { struct roffsu su; - struct man_node *nn; + struct roff_node *nn; int len, savelit; switch (n->type) { - case MAN_HEAD: - p->flags |= TERMP_NOBREAK; + case ROFFT_HEAD: + p->flags |= TERMP_NOBREAK | TERMP_BRTRSP; p->trailspace = 1; break; - case MAN_BODY: + case ROFFT_BODY: p->flags |= TERMP_NOSPACE; break; - case MAN_BLOCK: + case ROFFT_BLOCK: print_bvspace(p, n, mt->pardist); /* FALLTHROUGH */ default: - return(1); + return 1; } /* Calculate offset. */ @@ -665,7 +679,7 @@ pre_TP(DECL_ARGS) if ((nn = n->parent->head->child) != NULL && nn->string != NULL && ! (MAN_LINE & nn->flags) && a2roffsu(nn->string, &su, SCALE_EN)) { - len = term_hspan(p, &su); + len = term_hspan(p, &su) / 24; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; else if (len > SHRT_MAX) @@ -675,7 +689,7 @@ pre_TP(DECL_ARGS) len = mt->lmargin[mt->lmargincur]; switch (n->type) { - case MAN_HEAD: + case ROFFT_HEAD: p->offset = mt->offset; p->rmargin = mt->offset + len; @@ -694,18 +708,18 @@ pre_TP(DECL_ARGS) if (savelit) mt->fl |= MANT_LITERAL; - return(0); - case MAN_BODY: + return 0; + case ROFFT_BODY: p->offset = mt->offset + len; p->rmargin = p->maxrmargin; p->trailspace = 0; - p->flags &= ~TERMP_NOBREAK; + p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP); break; default: break; } - return(1); + return 1; } static void @@ -713,10 +727,10 @@ post_TP(DECL_ARGS) { switch (n->type) { - case MAN_HEAD: + case ROFFT_HEAD: term_flushln(p); break; - case MAN_BODY: + case ROFFT_BODY: term_newln(p); p->offset = mt->offset; break; @@ -731,7 +745,7 @@ pre_SS(DECL_ARGS) int i; switch (n->type) { - case MAN_BLOCK: + case ROFFT_BLOCK: mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); @@ -743,25 +757,32 @@ pre_SS(DECL_ARGS) do { n = n->prev; - } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT); + } while (n != NULL && n->tok != TOKEN_NONE && + termacts[n->tok].flags & MAN_NOTEXT); if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) term_vspace(p); break; - case MAN_HEAD: + case ROFFT_HEAD: term_fontrepl(p, TERMFONT_BOLD); p->offset = term_len(p, 3); + p->rmargin = mt->offset; + p->trailspace = mt->offset; + p->flags |= TERMP_NOBREAK | TERMP_BRIND; break; - case MAN_BODY: + case ROFFT_BODY: p->offset = mt->offset; + p->rmargin = p->maxrmargin; + p->trailspace = 0; + p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); break; default: break; } - return(1); + return 1; } static void @@ -769,10 +790,10 @@ post_SS(DECL_ARGS) { switch (n->type) { - case MAN_HEAD: + case ROFFT_HEAD: term_newln(p); break; - case MAN_BODY: + case ROFFT_BODY: term_newln(p); break; default: @@ -786,7 +807,7 @@ pre_SH(DECL_ARGS) int i; switch (n->type) { - case MAN_BLOCK: + case ROFFT_BLOCK: mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); @@ -805,18 +826,24 @@ pre_SH(DECL_ARGS) for (i = 0; i < mt->pardist; i++) term_vspace(p); break; - case MAN_HEAD: + case ROFFT_HEAD: term_fontrepl(p, TERMFONT_BOLD); p->offset = 0; + p->rmargin = mt->offset; + p->trailspace = mt->offset; + p->flags |= TERMP_NOBREAK | TERMP_BRIND; break; - case MAN_BODY: + case ROFFT_BODY: p->offset = mt->offset; + p->rmargin = p->maxrmargin; + p->trailspace = 0; + p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); break; default: break; } - return(1); + return 1; } static void @@ -824,10 +851,10 @@ post_SH(DECL_ARGS) { switch (n->type) { - case MAN_HEAD: + case ROFFT_HEAD: term_newln(p); break; - case MAN_BODY: + case ROFFT_BODY: term_newln(p); break; default: @@ -841,19 +868,21 @@ pre_RS(DECL_ARGS) struct roffsu su; switch (n->type) { - case MAN_BLOCK: + case ROFFT_BLOCK: term_newln(p); - return(1); - case MAN_HEAD: - return(0); + return 1; + case ROFFT_HEAD: + return 0; default: break; } n = n->parent->head; n->aux = SHRT_MAX + 1; - if (n->child != NULL && a2roffsu(n->child->string, &su, SCALE_EN)) - n->aux = term_hspan(p, &su); + if (n->child == NULL) + n->aux = mt->lmargin[mt->lmargincur]; + else if (a2roffsu(n->child->string, &su, SCALE_EN)) + n->aux = term_hspan(p, &su) / 24; if (n->aux < 0 && (size_t)(-n->aux) > mt->offset) n->aux = -mt->offset; else if (n->aux > SHRT_MAX) @@ -866,8 +895,8 @@ pre_RS(DECL_ARGS) if (++mt->lmarginsz < MAXMARGINS) mt->lmargincur = mt->lmarginsz; - mt->lmargin[mt->lmargincur] = mt->lmargin[mt->lmargincur - 1]; - return(1); + mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); + return 1; } static void @@ -875,9 +904,9 @@ post_RS(DECL_ARGS) { switch (n->type) { - case MAN_BLOCK: + case ROFFT_BLOCK: return; - case MAN_HEAD: + case ROFFT_HEAD: return; default: term_newln(p); @@ -895,14 +924,14 @@ static int pre_UR(DECL_ARGS) { - return (MAN_HEAD != n->type); + return n->type != ROFFT_HEAD; } static void post_UR(DECL_ARGS) { - if (MAN_BLOCK != n->type) + if (n->type != ROFFT_BLOCK) return; term_word(p, "<"); @@ -922,7 +951,7 @@ print_man_node(DECL_ARGS) int c; switch (n->type) { - case MAN_TEXT: + case ROFFT_TEXT: /* * If we have a blank line, output a vertical space. * If we have a space as the first character, break @@ -937,14 +966,14 @@ print_man_node(DECL_ARGS) term_word(p, n->string); goto out; - case MAN_EQN: + case ROFFT_EQN: if ( ! (n->flags & MAN_LINE)) p->flags |= TERMP_NOSPACE; term_eqn(p, n->eqn); if (n->next != NULL && ! (n->next->flags & MAN_LINE)) p->flags |= TERMP_NOSPACE; return; - case MAN_TBL: + case ROFFT_TBL: if (p->tbl.cols == NULL) term_vspace(p); term_tbl(p, n->span); @@ -1010,13 +1039,11 @@ print_man_nodelist(DECL_ARGS) } static void -print_man_foot(struct termp *p, const void *arg) +print_man_foot(struct termp *p, const struct roff_meta *meta) { - const struct man_meta *meta; char *title; size_t datelen, titlen; - meta = (const struct man_meta *)arg; assert(meta->title); assert(meta->msec); assert(meta->date); @@ -1028,8 +1055,8 @@ print_man_foot(struct termp *p, const void *arg) /* * Temporary, undocumented option to imitate mdoc(7) output. - * In the bottom right corner, use the source instead of - * the title. + * In the bottom right corner, use the operating system + * instead of the title. */ if ( ! p->mdocstyle) { @@ -1039,14 +1066,14 @@ print_man_foot(struct termp *p, const void *arg) } mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec); - } else if (meta->source) { - title = mandoc_strdup(meta->source); + } else if (meta->os) { + title = mandoc_strdup(meta->os); } else { title = mandoc_strdup(""); } datelen = term_strlen(p, meta->date); - /* Bottom left corner: manual source. */ + /* Bottom left corner: operating system. */ p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->trailspace = 1; @@ -1054,8 +1081,8 @@ print_man_foot(struct termp *p, const void *arg) p->rmargin = p->maxrmargin > datelen ? (p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0; - if (meta->source) - term_word(p, meta->source); + if (meta->os) + term_word(p, meta->os); term_flushln(p); /* At the bottom in the middle: manual date. */ @@ -1082,14 +1109,12 @@ print_man_foot(struct termp *p, const void *arg) } static void -print_man_head(struct termp *p, const void *arg) +print_man_head(struct termp *p, const struct roff_meta *meta) { - const struct man_meta *meta; const char *volume; char *title; size_t vollen, titlen; - meta = (const struct man_meta *)arg; assert(meta->title); assert(meta->msec); diff --git a/contrib/mdocml/man_validate.c b/contrib/mdocml/man_validate.c index 93ee9b3..16d9963 100644 --- a/contrib/mdocml/man_validate.c +++ b/contrib/mdocml/man_validate.c @@ -1,15 +1,15 @@ /* $OpenBSD$ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2016 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -28,13 +28,15 @@ #include <string.h> #include <time.h> -#include "man.h" -#include "mandoc.h" #include "mandoc_aux.h" -#include "libman.h" +#include "mandoc.h" +#include "roff.h" +#include "man.h" #include "libmandoc.h" +#include "roff_int.h" +#include "libman.h" -#define CHKARGS struct man *man, struct man_node *n +#define CHKARGS struct roff_man *man, struct roff_node *n typedef void (*v_check)(CHKARGS); @@ -46,9 +48,7 @@ static void check_text(CHKARGS); static void post_AT(CHKARGS); static void post_IP(CHKARGS); static void post_vs(CHKARGS); -static void post_fi(CHKARGS); static void post_ft(CHKARGS); -static void post_nf(CHKARGS); static void post_OP(CHKARGS); static void post_TH(CHKARGS); static void post_UC(CHKARGS); @@ -77,8 +77,8 @@ static v_check man_valids[MAN_MAX] = { NULL, /* IR */ NULL, /* RI */ post_vs, /* sp */ - post_nf, /* nf */ - post_fi, /* fi */ + NULL, /* nf */ + NULL, /* fi */ NULL, /* RE */ check_part, /* RS */ NULL, /* DT */ @@ -88,8 +88,8 @@ static v_check man_valids[MAN_MAX] = { NULL, /* in */ post_ft, /* ft */ post_OP, /* OP */ - post_nf, /* EX */ - post_fi, /* EE */ + NULL, /* EX */ + NULL, /* EE */ post_UR, /* UR */ NULL, /* UE */ NULL, /* ll */ @@ -97,31 +97,39 @@ static v_check man_valids[MAN_MAX] = { void -man_valid_post(struct man *man) +man_node_validate(struct roff_man *man) { - struct man_node *n; + struct roff_node *n; v_check *cp; n = man->last; - if (n->flags & MAN_VALID) - return; - n->flags |= MAN_VALID; + man->last = man->last->child; + while (man->last != NULL) { + man_node_validate(man); + if (man->last == n) + man->last = man->last->child; + else + man->last = man->last->next; + } + man->last = n; + man->next = ROFF_NEXT_SIBLING; switch (n->type) { - case MAN_TEXT: + case ROFFT_TEXT: check_text(man, n); break; - case MAN_ROOT: + case ROFFT_ROOT: check_root(man, n); break; - case MAN_EQN: - /* FALLTHROUGH */ - case MAN_TBL: + case ROFFT_EQN: + case ROFFT_TBL: break; default: cp = man_valids + n->tok; if (*cp) (*cp)(man, n); + if (man->last == n) + man_state(man, n); break; } } @@ -172,10 +180,10 @@ static void post_OP(CHKARGS) { - if (n->nchild == 0) + if (n->child == NULL) mandoc_msg(MANDOCERR_OP_EMPTY, man->parse, n->line, n->pos, "OP"); - else if (n->nchild > 2) { + else if (n->child->next != NULL && n->child->next->next != NULL) { n = n->child->next->next; mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, n->line, n->pos, "OP ... %s", n->string); @@ -186,7 +194,7 @@ static void post_UR(CHKARGS) { - if (n->type == MAN_HEAD && n->child == NULL) + if (n->type == ROFFT_HEAD && n->child == NULL) mandoc_vmsg(MANDOCERR_UR_NOHEAD, man->parse, n->line, n->pos, "UR"); check_part(man, n); @@ -198,24 +206,18 @@ post_ft(CHKARGS) char *cp; int ok; - if (0 == n->nchild) + if (n->child == NULL) return; ok = 0; cp = n->child->string; switch (*cp) { case '1': - /* FALLTHROUGH */ case '2': - /* FALLTHROUGH */ case '3': - /* FALLTHROUGH */ case '4': - /* FALLTHROUGH */ case 'I': - /* FALLTHROUGH */ case 'P': - /* FALLTHROUGH */ case 'R': if ('\0' == cp[1]) ok = 1; @@ -243,7 +245,7 @@ static void check_part(CHKARGS) { - if (n->type == MAN_BODY && n->child == NULL) + if (n->type == ROFFT_BODY && n->child == NULL) mandoc_msg(MANDOCERR_BLK_EMPTY, man->parse, n->line, n->pos, man_macronames[n->tok]); } @@ -253,23 +255,23 @@ check_par(CHKARGS) { switch (n->type) { - case MAN_BLOCK: - if (0 == n->body->nchild) - man_node_delete(man, n); + case ROFFT_BLOCK: + if (n->body->child == NULL) + roff_node_delete(man, n); break; - case MAN_BODY: - if (0 == n->nchild) + case ROFFT_BODY: + if (n->child == NULL) mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos, "%s empty", man_macronames[n->tok]); break; - case MAN_HEAD: - if (n->nchild) + case ROFFT_HEAD: + if (n->child != NULL) mandoc_vmsg(MANDOCERR_ARG_SKIP, man->parse, n->line, n->pos, "%s %s%s", man_macronames[n->tok], n->child->string, - n->nchild > 1 ? " ..." : ""); + n->child->next != NULL ? " ..." : ""); break; default: break; @@ -281,12 +283,12 @@ post_IP(CHKARGS) { switch (n->type) { - case MAN_BLOCK: - if (0 == n->head->nchild && 0 == n->body->nchild) - man_node_delete(man, n); + case ROFFT_BLOCK: + if (n->head->child == NULL && n->body->child == NULL) + roff_node_delete(man, n); break; - case MAN_BODY: - if (0 == n->parent->head->nchild && 0 == n->nchild) + case ROFFT_BODY: + if (n->parent->head->child == NULL && n->child == NULL) mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos, "%s empty", man_macronames[n->tok]); @@ -299,21 +301,21 @@ post_IP(CHKARGS) static void post_TH(CHKARGS) { - struct man_node *nb; + struct roff_node *nb; const char *p; free(man->meta.title); free(man->meta.vol); - free(man->meta.source); + free(man->meta.os); free(man->meta.msec); free(man->meta.date); man->meta.title = man->meta.vol = man->meta.date = - man->meta.msec = man->meta.source = NULL; + man->meta.msec = man->meta.os = NULL; nb = n; - /* ->TITLE<- MSEC DATE SOURCE VOL */ + /* ->TITLE<- MSEC DATE OS VOL */ n = n->child; if (n && n->string) { @@ -335,7 +337,7 @@ post_TH(CHKARGS) nb->line, nb->pos, "TH"); } - /* TITLE ->MSEC<- DATE SOURCE VOL */ + /* TITLE ->MSEC<- DATE OS VOL */ if (n) n = n->next; @@ -347,7 +349,7 @@ post_TH(CHKARGS) nb->line, nb->pos, "TH %s", man->meta.title); } - /* TITLE MSEC ->DATE<- SOURCE VOL */ + /* TITLE MSEC ->DATE<- OS VOL */ if (n) n = n->next; @@ -363,14 +365,14 @@ post_TH(CHKARGS) n ? n->pos : nb->pos, "TH"); } - /* TITLE MSEC DATE ->SOURCE<- VOL */ + /* TITLE MSEC DATE ->OS<- VOL */ if (n && (n = n->next)) - man->meta.source = mandoc_strdup(n->string); + man->meta.os = mandoc_strdup(n->string); else if (man->defos != NULL) - man->meta.source = mandoc_strdup(man->defos); + man->meta.os = mandoc_strdup(man->defos); - /* TITLE MSEC DATE SOURCE ->VOL<- */ + /* TITLE MSEC DATE OS ->VOL<- */ /* If missing, use the default VOL name for MSEC. */ if (n && (n = n->next)) @@ -387,29 +389,7 @@ post_TH(CHKARGS) * Remove the `TH' node after we've processed it for our * meta-data. */ - man_node_delete(man, man->last); -} - -static void -post_nf(CHKARGS) -{ - - if (man->flags & MAN_LITERAL) - mandoc_msg(MANDOCERR_NF_SKIP, man->parse, - n->line, n->pos, "nf"); - - man->flags |= MAN_LITERAL; -} - -static void -post_fi(CHKARGS) -{ - - if ( ! (MAN_LITERAL & man->flags)) - mandoc_msg(MANDOCERR_FI_SKIP, man->parse, - n->line, n->pos, "fi"); - - man->flags &= ~MAN_LITERAL; + roff_node_delete(man, man->last); } static void @@ -427,7 +407,7 @@ post_UC(CHKARGS) n = n->child; - if (NULL == n || MAN_TEXT != n->type) + if (n == NULL || n->type != ROFFT_TEXT) p = bsd_versions[0]; else { s = n->string; @@ -445,8 +425,8 @@ post_UC(CHKARGS) p = bsd_versions[0]; } - free(man->meta.source); - man->meta.source = mandoc_strdup(p); + free(man->meta.os); + man->meta.os = mandoc_strdup(p); } static void @@ -459,12 +439,12 @@ post_AT(CHKARGS) "System V Release 2", }; + struct roff_node *nn; const char *p, *s; - struct man_node *nn; n = n->child; - if (NULL == n || MAN_TEXT != n->type) + if (n == NULL || n->type != ROFFT_TEXT) p = unix_versions[0]; else { s = n->string; @@ -474,7 +454,9 @@ post_AT(CHKARGS) p = unix_versions[1]; else if (0 == strcmp(s, "5")) { nn = n->next; - if (nn && MAN_TEXT == nn->type && nn->string[0]) + if (nn != NULL && + nn->type == ROFFT_TEXT && + nn->string[0] != '\0') p = unix_versions[3]; else p = unix_versions[2]; @@ -482,8 +464,8 @@ post_AT(CHKARGS) p = unix_versions[0]; } - free(man->meta.source); - man->meta.source = mandoc_strdup(p); + free(man->meta.os); + man->meta.os = mandoc_strdup(p); } static void @@ -495,18 +477,17 @@ post_vs(CHKARGS) switch (n->parent->tok) { case MAN_SH: - /* FALLTHROUGH */ case MAN_SS: mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos, "%s after %s", man_macronames[n->tok], man_macronames[n->parent->tok]); /* FALLTHROUGH */ - case MAN_MAX: + case TOKEN_NONE: /* * Don't warn about this because it occurs in pod2man * and would cause considerable (unfixable) warnage. */ - man_node_delete(man, n); + roff_node_delete(man, n); break; default: break; diff --git a/contrib/mdocml/manconf.h b/contrib/mdocml/manconf.h new file mode 100644 index 0000000..782269e --- /dev/null +++ b/contrib/mdocml/manconf.h @@ -0,0 +1,48 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* List of unique, absolute paths to manual trees. */ + +struct manpaths { + char **paths; + size_t sz; +}; + +/* Data from -O options and man.conf(5) output directives. */ + +struct manoutput { + char *includes; + char *man; + char *paper; + char *style; + size_t indent; + size_t width; + int fragment; + int mdoc; + int synopsisonly; +}; + +struct manconf { + struct manoutput output; + struct manpaths manpath; +}; + + +void manconf_parse(struct manconf *, const char *, char *, char *); +void manconf_output(struct manoutput *, const char *); +void manconf_free(struct manconf *); diff --git a/contrib/mdocml/mandoc.1 b/contrib/mdocml/mandoc.1 index e218ed7..f4707aa 100644 --- a/contrib/mdocml/mandoc.1 +++ b/contrib/mdocml/mandoc.1 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.1,v 1.155 2015/02/23 13:31:03 schwarze Exp $ +.\" $Id: mandoc.1,v 1.164 2015/11/05 17:47:51 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2012, 2014, 2015 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: February 23 2015 $ +.Dd $Mdocdate: November 5 2015 $ .Dt MANDOC 1 .Os .Sh NAME @@ -24,14 +24,12 @@ .Sh SYNOPSIS .Nm mandoc .Op Fl acfhkl -.Sm off -.Op Fl I Cm os Li = Ar name -.Sm on -.Op Fl K Ns Ar encoding +.Op Fl I Cm os Ns = Ns Ar name +.Op Fl K Ar encoding .Op Fl m Ns Ar format -.Op Fl O Ns Ar option -.Op Fl T Ns Ar output -.Op Fl W Ns Ar level +.Op Fl O Ar option +.Op Fl T Ar output +.Op Fl W Ar level .Op Ar .Sh DESCRIPTION The @@ -49,7 +47,7 @@ or text from stdin, implying .Fl m Ns Cm andoc , and produces -.Fl T Ns Cm locale +.Fl T Cm locale output. .Pp The options are as follows: @@ -77,9 +75,7 @@ This overrides any earlier and .Fl l options. -.Sm off -.It Fl I Cm os Li = Ar name -.Sm on +.It Fl I Cm os Ns = Ns Ar name Override the default operating system .Ar name for the @@ -93,7 +89,7 @@ macro. Display only the SYNOPSIS lines. Implies .Fl c . -.It Fl K Ns Ar encoding +.It Fl K Ar encoding Specify the input encoding. The supported .Ar encoding @@ -141,16 +137,16 @@ See for available formats. Defaults to .Fl m Ns Cm andoc . -.It Fl O Ns Ar option +.It Fl O Ar option Comma-separated output options. -.It Fl T Ns Ar output +.It Fl T Ar output Output format. See .Sx Output Formats for available formats. Defaults to -.Fl T Ns Cm locale . -.It Fl W Ns Ar level +.Fl T Cm locale . +.It Fl W Ar level Specify the minimum message .Ar level to be reported on the standard error output and to affect the exit status. @@ -174,7 +170,7 @@ and for details. .Pp The special option -.Fl W Ns Cm stop +.Fl W Cm stop tells .Nm to exit after parsing a file that causes warnings or errors of at least @@ -185,7 +181,7 @@ If both a and .Cm stop are requested, they can be joined with a comma, for example -.Fl W Ns Cm error , Ns Cm stop . +.Fl W Cm error , Ns Cm stop . .It Ar file Read input from zero or more files. If unspecified, reads from stdin. @@ -254,54 +250,56 @@ The utility accepts the following .Fl T arguments, which correspond to output modes: -.Bl -tag -width "-Tlocale" -.It Fl T Ns Cm ascii +.Bl -tag -width "-T locale" +.It Fl T Cm ascii Produce 7-bit ASCII output. See .Sx ASCII Output . -.It Fl T Ns Cm html +.It Fl T Cm html Produce HTML5, CSS1, and MathML output. See .Sx HTML Output . -.It Fl T Ns Cm lint +.It Fl T Cm lint Parse only: produce no output. Implies -.Fl W Ns Cm warning . -.It Fl T Ns Cm locale +.Fl W Cm warning . +.It Fl T Cm locale Encode output using the current locale. This is the default. See .Sx Locale Output . -.It Fl T Ns Cm man +.It Fl T Cm man Produce .Xr man 7 format output. See .Sx Man Output . -.It Fl T Ns Cm pdf +.It Fl T Cm pdf Produce PDF output. See .Sx PDF Output . -.It Fl T Ns Cm ps +.It Fl T Cm ps Produce PostScript output. See .Sx PostScript Output . -.It Fl T Ns Cm tree +.It Fl T Cm tree Produce an indented parse tree. -.It Fl T Ns Cm utf8 +See +.Sx Syntax tree output . +.It Fl T Cm utf8 Encode output in the UTF\-8 multi-byte format. See .Sx UTF\-8 Output . -.It Fl T Ns Cm xhtml +.It Fl T Cm xhtml This is a synonym for -.Fl T Ns Cm html . +.Fl T Cm html . .El .Pp If multiple input files are specified, these will be processed by the corresponding filter in-order. .Ss ASCII Output Output produced by -.Fl T Ns Cm ascii +.Fl T Cm ascii is rendered in standard 7-bit ASCII documented in .Xr ascii 7 . .Pp @@ -343,7 +341,7 @@ which will normalise to \(>=58. .El .Ss HTML Output Output produced by -.Fl T Ns Cm html +.Fl T Cm html conforms to HTML5 using optional self-closing tags. Default styles use only CSS1. Equations rendered from @@ -351,11 +349,11 @@ Equations rendered from blocks use MathML. .Pp The -.Pa example.style.css +.Pa mandoc.css file documents style-sheet classes available for customising output. If a style-sheet is not specified with -.Fl O Ns Ar style , -.Fl T Ns Cm html +.Fl O Cm style , +.Fl T Cm html defaults to simple output (via an embedded style-sheet) readable in any graphical or text-based web browser. @@ -411,13 +409,13 @@ relative URI. .El .Ss Locale Output Locale-depending output encoding is triggered with -.Fl T Ns Cm locale . +.Fl T Cm locale . This is the default. .Pp This option is not available on all systems: systems without locale support, or those whose internal representation is not natively UCS-4, will fall back to -.Fl T Ns Cm ascii . +.Fl T Cm ascii . See .Sx ASCII Output for font style specification and available command-line arguments. @@ -447,7 +445,7 @@ level controls which are displayed before copying the input to the output. .Ss PDF Output PDF-1.1 output may be generated by -.Fl T Ns Cm pdf . +.Fl T Cm pdf . See .Sx PostScript Output for @@ -457,7 +455,7 @@ arguments and defaults. PostScript .Qq Adobe-3.0 Level-2 pages may be generated by -.Fl T Ns Cm ps . +.Fl T Cm ps . Output pages default to letter sized and are rendered in the Times font family, 11-point. Margins are calculated as 1/9 the page length and width. @@ -489,11 +487,50 @@ is used. .El .Ss UTF\-8 Output Use -.Fl T Ns Cm utf8 +.Fl T Cm utf8 to force a UTF\-8 locale. See .Sx Locale Output for details and options. +.Ss Syntax tree output +Use +.Fl T Cm tree +to show a human readable representation of the syntax tree. +It is useful for debugging the source code of manual pages. +The exact format is subject to change, so don't write parsers for it. +Each output line shows one syntax tree node. +Child nodes are indented with respect to their parent node. +The columns are: +.Pp +.Bl -enum -compact +.It +For macro nodes, the macro name; for text and +.Xr tbl 7 +nodes, the content. +There is a special format for +.Xr eqn 7 +nodes. +.It +Node type (text, elem, block, head, body, body-end, tail, tbl, eqn). +.It +Flags: +.Bl -dash -compact +.It +An opening parenthesis if the node is an opening delimiter. +.It +An asterisk if the node starts a new input line. +.It +The input line number (starting at one). +.It +A colon. +.It +The input column number (starting at one). +.It +A closing parenthesis if the node is a closing delimiter. +.It +A full stop if the node ends a sentence. +.El +.El .Sh ENVIRONMENT .Bl -tag -width MANPAGER .It Ev MANPAGER @@ -506,7 +543,8 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Pa /usr/bin/more Fl s +.Xr more 1 +.Fl s will be used. .El .Sh EXIT STATUS @@ -525,21 +563,21 @@ they were lower than the requested .Ar level . .It 2 At least one warning occurred, but no error, and -.Fl W Ns Cm warning +.Fl W Cm warning was specified. .It 3 At least one parsing error occurred, but no unsupported feature was encountered, and -.Fl W Ns Cm error +.Fl W Cm error or -.Fl W Ns Cm warning +.Fl W Cm warning was specified. .It 4 At least one unsupported feature was encountered, and -.Fl W Ns Cm unsupp , -.Fl W Ns Cm error +.Fl W Cm unsupp , +.Fl W Cm error or -.Fl W Ns Cm warning +.Fl W Cm warning was specified. .It 5 Invalid command line arguments were specified. @@ -553,28 +591,28 @@ to exit at once, possibly in the middle of parsing or formatting a file. .El .Pp Note that selecting -.Fl T Ns Cm lint +.Fl T Cm lint output mode implies -.Fl W Ns Cm warning . +.Fl W Cm warning . .Sh EXAMPLES To page manuals to the terminal: .Pp -.Dl $ mandoc \-Wall,stop mandoc.1 2\*(Gt&1 | less +.Dl $ mandoc \-W all,stop mandoc.1 2\*(Gt&1 | less .Dl $ mandoc mandoc.1 mdoc.3 mdoc.7 | less .Pp To produce HTML manuals with -.Ar style.css +.Pa mandoc.css as the style-sheet: .Pp -.Dl $ mandoc \-Thtml -Ostyle=style.css mdoc.7 \*(Gt mdoc.7.html +.Dl $ mandoc \-T html -O style=mandoc.css mdoc.7 \*(Gt mdoc.7.html .Pp To check over a large set of manuals: .Pp -.Dl $ mandoc \-Tlint `find /usr/src -name \e*\e.[1-9]` +.Dl $ mandoc \-T lint \(gafind /usr/src -name \e*\e.[1-9]\(ga .Pp To produce a series of PostScript manuals for A4 paper: .Pp -.Dl $ mandoc \-Tps \-Opaper=a4 mdoc.7 man.7 \*(Gt manuals.ps +.Dl $ mandoc \-T ps \-O paper=a4 mdoc.7 man.7 \*(Gt manuals.ps .Pp Convert a modern .Xr mdoc 7 @@ -584,7 +622,7 @@ format, for use on systems lacking an .Xr mdoc 7 parser: .Pp -.Dl $ mandoc \-Tman foo.mdoc \*(Gt foo.man +.Dl $ mandoc \-T man foo.mdoc \*(Gt foo.man .Sh DIAGNOSTICS Messages displayed by .Nm @@ -651,7 +689,7 @@ levels except those about non-existent or unreadable input files are hidden unless their level, or a lower level, is requested using a .Fl W option or -.Fl T Ns Cm lint +.Fl T Cm lint output mode. .Ss Warnings related to the document prologue .Bl -ohang @@ -817,7 +855,7 @@ In the SEE ALSO section, an macro with a lower section number follows one with a higher number, or two .Ic \&Xr -macros refering to the same section are out of alphabetical order. +macros referring to the same section are out of alphabetical order. .It Sy "unusual Xr punctuation" .Pq mdoc In the SEE ALSO section, punctuation between two @@ -937,13 +975,6 @@ list block contains text or macros before the first .Ic \&It macro. The offending children are moved before the beginning of the list. -.It Sy ".Vt block has child macro" -.Pq mdoc -The -.Ic \&Vt -macro supports plain text arguments only. -Formatting may be ugly and semantic searching -for the affected content might not work. .It Sy "fill mode already enabled, skipping" .Pq man A @@ -1569,6 +1600,13 @@ By requesting the inclusion of a sensitive file, a malicious document might otherwise trick a privileged user into inadvertently displaying the file on the screen, revealing the file content to bystanders. The argument is ignored including the file name following it. +.It Sy "skipping display without arguments" +.Pq mdoc +A +.Ic \&Bd +block macro does not have any arguments. +The block is discarded, and the block content is displayed in +whatever mode was active before the block. .It Sy "missing list type, using -item" .Pq mdoc A @@ -1767,6 +1805,7 @@ as if they were a text line. .Xr roff 7 , .Xr tbl 7 .Sh AUTHORS +.An -nosplit The .Nm utility was written by @@ -1775,10 +1814,10 @@ and is maintained by .An Ingo Schwarze Aq Mt schwarze@openbsd.org . .Sh BUGS In -.Fl T Ns Cm html , +.Fl T Cm html , the maximum size of an element attribute is determined by .Dv BUFSIZ , which is usually 1024 bytes. Be aware of this when setting long link formats such as -.Fl O Ns Cm style Ns = Ns Ar really/long/link . +.Fl O Cm style Ns = Ns Ar really/long/link . diff --git a/contrib/mdocml/mandoc.3 b/contrib/mdocml/mandoc.3 index a41e25b..61012ed 100644 --- a/contrib/mdocml/mandoc.3 +++ b/contrib/mdocml/mandoc.3 @@ -1,7 +1,7 @@ -.\" $Id: mandoc.3,v 1.31 2015/01/15 04:26:40 schwarze Exp $ +.\" $Id: mandoc.3,v 1.36 2016/01/08 17:48:09 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2010, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010-2016 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 15 2015 $ +.Dd $Mdocdate: January 8 2016 $ .Dt MANDOC 3 .Os .Sh NAME @@ -37,7 +37,6 @@ .Nm mparse_result , .Nm mparse_strerror , .Nm mparse_strlevel -.Nm mparse_wait , .Nd mandoc macro compiler library .Sh SYNOPSIS .In sys/types.h @@ -51,7 +50,6 @@ .Fa "int options" .Fa "enum mandoclevel wlevel" .Fa "mandocmsg mmsg" -.Fa "const struct mchars *mchars" .Fa "char *defos" .Fc .Ft void @@ -75,10 +73,9 @@ .Fo mparse_keep .Fa "struct mparse *parse" .Fc -.Ft "enum mandoclevel" +.Ft int .Fo mparse_open .Fa "struct mparse *parse" -.Fa "int *fd" .Fa "const char *fname" .Fc .Ft "enum mandoclevel" @@ -106,10 +103,6 @@ .Fo mparse_strlevel .Fa "enum mandoclevel" .Fc -.Ft "enum mandoclevel" -.Fo mparse_wait -.Fa "struct mparse *parse" -.Fc .In sys/types.h .In mandoc.h .In mdoc.h @@ -183,6 +176,9 @@ or parse it with .Fn mparse_readfd ; .It +close it with +.Xr close 2 ; +.It retrieve the syntax tree with .Fn mparse_result ; .It @@ -215,12 +211,6 @@ An error or warning message during parsing. A classification of an .Vt "enum mandocerr" as regards system operation. -.It Vt "struct mchars" -An opaque pointer to a a character table. -Created with -.Xr mchars_alloc 3 -and freed with -.Xr mchars_free 3 . .It Vt "struct mparse" An opaque pointer to a running parse sequence. Created with @@ -345,9 +335,6 @@ A callback function to handle errors and warnings. See .Pa main.c for an example. -.It Ar mchars -An opaque pointer to a a character table obtained from -.Xr mchars_alloc 3 . .It Ar defos A default string for the .Xr mdoc 7 @@ -392,23 +379,15 @@ Declared in implemented in .Pa read.c . .It Fn mparse_open -If the +Open the file for reading. +If that fails and .Fa fname -ends in -.Pa .gz , -open with -.Xr gunzip 1 ; -otherwise, with -.Xr open 2 . -If -.Xr open 2 -fails, append -.Pa .gz -and try with -.Xr gunzip 1 . -Return a file descriptor open for reading in -.Fa fd , -or -1 on failure. +does not already end in +.Ql .gz , +try again after appending +.Ql .gz . +Save the information whether the file is zipped or not. +Return a file descriptor open for reading or -1 on failure. It can be passed to .Fn mparse_readfd or used directly. @@ -423,10 +402,9 @@ or .Fn mparse_open . Pass the associated filename in .Va fname . -Calls -.Fn mparse_wait -before returning. This function may be called multiple times with different parameters; however, +.Xr close 2 +and .Fn mparse_reset should be invoked between parses. Declared in @@ -460,28 +438,6 @@ Declared in .In mandoc.h , implemented in .Pa read.c . -.It Fn mparse_wait -Bury a -.Xr gunzip 1 -child process that was spawned with -.Fn mparse_open . -To be called after the parse sequence is complete. -Not needed after -.Fn mparse_readfd , -but does no harm in that case, either. -Returns -.Dv MANDOCLEVEL_OK -on success and -.Dv MANDOCLEVEL_SYSERR -on failure, that is, when -.Xr wait 2 -fails, or when -.Xr gunzip 1 -died from a signal or exited with non-zero status. -Declared in -.In mandoc.h , -implemented in -.Pa read.c . .El .Ss Variables .Bl -ohang @@ -601,7 +557,7 @@ and fields), its position in the tree (the .Va parent , .Va child , -.Va nchild , +.Va last , .Va next and .Va prev diff --git a/contrib/mdocml/mandoc.c b/contrib/mdocml/mandoc.c index 0619420..d265463 100644 --- a/contrib/mdocml/mandoc.c +++ b/contrib/mdocml/mandoc.c @@ -1,4 +1,4 @@ -/* $Id: mandoc.c,v 1.92 2015/02/20 23:55:10 schwarze Exp $ */ +/* $Id: mandoc.c,v 1.98 2015/11/12 22:44:27 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -32,8 +32,6 @@ #include "mandoc_aux.h" #include "libmandoc.h" -#define DATESIZE 32 - static int a2time(time_t *, const char *, const char *); static char *time2a(time_t); @@ -83,7 +81,7 @@ mandoc_escape(const char **end, const char **start, int *sz) break; case 'C': if ('\'' != **start) - return(ESCAPE_ERROR); + return ESCAPE_ERROR; *start = ++*end; gly = ESCAPE_SPECIAL; term = '\''; @@ -93,9 +91,10 @@ mandoc_escape(const char **end, const char **start, int *sz) * Escapes taking no arguments at all. */ case 'd': - /* FALLTHROUGH */ case 'u': - return(ESCAPE_IGNORE); + case ',': + case '/': + return ESCAPE_IGNORE; /* * The \z escape is supposed to output the following @@ -104,26 +103,19 @@ mandoc_escape(const char **end, const char **start, int *sz) * let us just skip the next character. */ case 'z': - return(ESCAPE_SKIPCHAR); + return ESCAPE_SKIPCHAR; /* * Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where * 'X' is the trigger. These have opaque sub-strings. */ case 'F': - /* FALLTHROUGH */ case 'g': - /* FALLTHROUGH */ case 'k': - /* FALLTHROUGH */ case 'M': - /* FALLTHROUGH */ case 'm': - /* FALLTHROUGH */ case 'n': - /* FALLTHROUGH */ case 'V': - /* FALLTHROUGH */ case 'Y': gly = ESCAPE_IGNORE; /* FALLTHROUGH */ @@ -151,21 +143,16 @@ mandoc_escape(const char **end, const char **start, int *sz) * The \B and \w escapes are handled in roff.c, roff_res(). */ case 'A': - /* FALLTHROUGH */ case 'b': - /* FALLTHROUGH */ case 'D': - /* FALLTHROUGH */ case 'R': - /* FALLTHROUGH */ case 'X': - /* FALLTHROUGH */ case 'Z': gly = ESCAPE_IGNORE; /* FALLTHROUGH */ case 'o': if (**start == '\0') - return(ESCAPE_ERROR); + return ESCAPE_ERROR; if (gly == ESCAPE_ERROR) gly = ESCAPE_OVERSTRIKE; term = **start; @@ -177,22 +164,16 @@ mandoc_escape(const char **end, const char **start, int *sz) * and 'N' resolves to a numerical expression. */ case 'h': - /* FALLTHROUGH */ case 'H': - /* FALLTHROUGH */ case 'L': - /* FALLTHROUGH */ case 'l': - /* FALLTHROUGH */ case 'S': - /* FALLTHROUGH */ case 'v': - /* FALLTHROUGH */ case 'x': if (strchr(" %&()*+-./0123456789:<=>", **start)) { if ('\0' != **start) ++*end; - return(ESCAPE_ERROR); + return ESCAPE_ERROR; } gly = ESCAPE_IGNORE; term = **start; @@ -205,11 +186,11 @@ mandoc_escape(const char **end, const char **start, int *sz) */ case 'N': if ('\0' == **start) - return(ESCAPE_ERROR); + return ESCAPE_ERROR; (*end)++; if (isdigit((unsigned char)**start)) { *sz = 1; - return(ESCAPE_IGNORE); + return ESCAPE_IGNORE; } (*start)++; while (isdigit((unsigned char)**end)) @@ -217,7 +198,7 @@ mandoc_escape(const char **end, const char **start, int *sz) *sz = *end - *start; if ('\0' != **end) (*end)++; - return(ESCAPE_NUMBERED); + return ESCAPE_NUMBERED; /* * Sizes get a special category of their own. @@ -243,9 +224,7 @@ mandoc_escape(const char **end, const char **start, int *sz) term = '\''; break; case '3': - /* FALLTHROUGH */ case '2': - /* FALLTHROUGH */ case '1': *sz = (*end)[-1] == 's' && isdigit((unsigned char)(*end)[1]) ? 2 : 1; @@ -279,12 +258,12 @@ mandoc_escape(const char **end, const char **start, int *sz) while (**end != term) { switch (**end) { case '\0': - return(ESCAPE_ERROR); + return ESCAPE_ERROR; case '\\': (*end)++; if (ESCAPE_ERROR == mandoc_escape(end, NULL, NULL)) - return(ESCAPE_ERROR); + return ESCAPE_ERROR; break; default: (*end)++; @@ -295,7 +274,7 @@ mandoc_escape(const char **end, const char **start, int *sz) } else { assert(*sz > 0); if ((size_t)*sz > strlen(*start)) - return(ESCAPE_ERROR); + return ESCAPE_ERROR; *end += *sz; } @@ -321,12 +300,10 @@ mandoc_escape(const char **end, const char **start, int *sz) switch (**start) { case '3': - /* FALLTHROUGH */ case 'B': gly = ESCAPE_FONTBOLD; break; case '2': - /* FALLTHROUGH */ case 'I': gly = ESCAPE_FONTITALIC; break; @@ -334,7 +311,6 @@ mandoc_escape(const char **end, const char **start, int *sz) gly = ESCAPE_FONTPREV; break; case '1': - /* FALLTHROUGH */ case 'R': gly = ESCAPE_FONTROMAN; break; @@ -355,6 +331,9 @@ mandoc_escape(const char **end, const char **start, int *sz) break; if (*sz == 6 && (*start)[1] == '0') break; + if (*sz == 5 && (*start)[1] == 'D' && + strchr("89ABCDEF", (*start)[2]) != NULL) + break; if ((int)strspn(*start + 1, "0123456789ABCDEFabcdef") + 1 == *sz) gly = ESCAPE_UNICODE; @@ -363,7 +342,7 @@ mandoc_escape(const char **end, const char **start, int *sz) break; } - return(gly); + return gly; } /* @@ -458,7 +437,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos) if ('\0' == *cp && (white || ' ' == cp[-1])) mandoc_msg(MANDOCERR_SPACE_EOL, parse, ln, *pos, NULL); - return(start); + return start; } static int @@ -475,10 +454,10 @@ a2time(time_t *t, const char *fmt, const char *p) #endif if (NULL != pp && '\0' == *pp) { *t = mktime(&tm); - return(1); + return 1; } - return(0); + return 0; } static char * @@ -491,7 +470,7 @@ time2a(time_t t) tm = localtime(&t); if (tm == NULL) - return(NULL); + return NULL; /* * Reserve space: @@ -499,45 +478,61 @@ time2a(time_t t) * up to 2 characters for the day + comma + blank * 4 characters for the year and a terminating '\0' */ + p = buf = mandoc_malloc(10 + 4 + 4 + 1); - if (0 == (ssz = strftime(p, 10 + 1, "%B ", tm))) + if ((ssz = strftime(p, 10 + 1, "%B ", tm)) == 0) goto fail; p += (int)ssz; - if (-1 == (isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday))) + /* + * The output format is just "%d" here, not "%2d" or "%02d". + * That's also the reason why we can't just format the + * date as a whole with "%B %e, %Y" or "%B %d, %Y". + * Besides, the present approach is less prone to buffer + * overflows, in case anybody should ever introduce the bug + * of looking at LC_TIME. + */ + + if ((isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)) == -1) goto fail; p += isz; - if (0 == strftime(p, 4 + 1, "%Y", tm)) + if (strftime(p, 4 + 1, "%Y", tm) == 0) goto fail; - return(buf); + return buf; fail: free(buf); - return(NULL); + return NULL; } char * mandoc_normdate(struct mparse *parse, char *in, int ln, int pos) { - char *out; time_t t; - if (NULL == in || '\0' == *in || - 0 == strcmp(in, "$" "Mdocdate$")) { + /* No date specified: use today's date. */ + + if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0) { mandoc_msg(MANDOCERR_DATE_MISSING, parse, ln, pos, NULL); - time(&t); + return time2a(time(NULL)); } - else if (a2time(&t, "%Y-%m-%d", in)) - t = 0; - else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) && - !a2time(&t, "%b %d, %Y", in)) { + + /* Valid mdoc(7) date format. */ + + if (a2time(&t, "$" "Mdocdate: %b %d %Y $", in) || + a2time(&t, "%b %d, %Y", in)) + return time2a(t); + + /* Do not warn about the legacy man(7) format. */ + + if ( ! a2time(&t, "%Y-%m-%d", in)) mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, in); - t = 0; - } - out = t ? time2a(t) : NULL; - return(out ? out : mandoc_strdup(in)); + + /* Use any non-mdoc(7) date verbatim. */ + + return mandoc_strdup(in); } int @@ -547,7 +542,7 @@ mandoc_eos(const char *p, size_t sz) int enclosed, found; if (0 == sz) - return(0); + return 0; /* * End-of-sentence recognition must include situations where @@ -559,28 +554,24 @@ mandoc_eos(const char *p, size_t sz) for (q = p + (int)sz - 1; q >= p; q--) { switch (*q) { case '\"': - /* FALLTHROUGH */ case '\'': - /* FALLTHROUGH */ case ']': - /* FALLTHROUGH */ case ')': if (0 == found) enclosed = 1; break; case '.': - /* FALLTHROUGH */ case '!': - /* FALLTHROUGH */ case '?': found = 1; break; default: - return(found && (!enclosed || isalnum((unsigned char)*q))); + return found && + (!enclosed || isalnum((unsigned char)*q)); } } - return(found && !enclosed); + return found && !enclosed; } /* @@ -595,7 +586,7 @@ mandoc_strntoi(const char *p, size_t sz, int base) long v; if (sz > 31) - return(-1); + return -1; memcpy(buf, p, sz); buf[(int)sz] = '\0'; @@ -604,12 +595,12 @@ mandoc_strntoi(const char *p, size_t sz, int base) v = strtol(buf, &ep, base); if (buf[0] == '\0' || *ep != '\0') - return(-1); + return -1; if (v > INT_MAX) v = INT_MAX; if (v < INT_MIN) v = INT_MIN; - return((int)v); + return (int)v; } diff --git a/contrib/mdocml/style.css b/contrib/mdocml/mandoc.css index 1328f4d..38c5c58 100644 --- a/contrib/mdocml/style.css +++ b/contrib/mdocml/mandoc.css @@ -1,4 +1,4 @@ -/* $Id: style.css,v 1.31 2015/02/10 08:05:30 schwarze Exp $ */ +/* $Id: mandoc.css,v 1.1 2015/11/05 17:47:51 schwarze Exp $ */ /* * This is an example style-sheet provided for mandoc(1) and the -Thtml @@ -11,6 +11,19 @@ html { max-width: 880px; margin-left: 1em; } body { font-size: smaller; font-family: Helvetica,Arial,sans-serif; } +body > div { padding-left: 2em; + padding-top: 1em; } +body > div.mandoc, +body > div#mancgi { padding-left: 0em; + padding-top: 0em; } +body > div.results { font-size: smaller; } +#mancgi fieldset { text-align: center; + border: thin solid silver; + border-radius: 1em; + font-size: small; } +#mancgi input[name=expr] { width: 25%; } +.results td.title { vertical-align: top; + padding-right: 1em; } h1 { margin-bottom: 1ex; font-size: 110%; margin-left: -4ex; } /* Section header (Sh, SH). */ h2 { margin-bottom: 1ex; font-size: 105%; margin-left: -2ex; } /* Sub-section header (Ss, SS). */ table { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */ diff --git a/contrib/mdocml/mandoc.h b/contrib/mdocml/mandoc.h index eb8a1aa..d63814c 100644 --- a/contrib/mdocml/mandoc.h +++ b/contrib/mdocml/mandoc.h @@ -1,15 +1,15 @@ -/* $Id: mandoc.h,v 1.201 2015/02/23 13:31:04 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.209 2016/01/08 02:53:13 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2016 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -86,7 +86,6 @@ enum mandocerr { MANDOCERR_BLK_NEST, /* blocks badly nested: macro ... */ MANDOCERR_BD_NEST, /* nested displays are not portable: macro ... */ MANDOCERR_BL_MOVE, /* moving content out of list: macro */ - MANDOCERR_VT_CHILD, /* .Vt block has child macro: macro */ MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */ MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */ MANDOCERR_BLK_LINE, /* line scope broken: macro breaks macro */ @@ -173,6 +172,7 @@ enum mandocerr { /* related to request and macro arguments */ MANDOCERR_NAMESC, /* escaped character not allowed in a name: name */ MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */ + MANDOCERR_BD_NOARG, /* skipping display without arguments: Bd */ MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */ MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */ MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */ @@ -408,37 +408,28 @@ enum mandoc_esc { typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel, const char *, int, int, const char *); -__BEGIN_DECLS struct mparse; -struct mchars; -struct mdoc; -struct man; +struct roff_man; enum mandoc_esc mandoc_escape(const char **, const char **, int *); -struct mchars *mchars_alloc(void); -void mchars_free(struct mchars *); +void mchars_alloc(void); +void mchars_free(void); int mchars_num2char(const char *, size_t); const char *mchars_uc2str(int); int mchars_num2uc(const char *, size_t); -int mchars_spec2cp(const struct mchars *, - const char *, size_t); -const char *mchars_spec2str(const struct mchars *, - const char *, size_t, size_t *); -struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg, - const struct mchars *, const char *); +int mchars_spec2cp(const char *, size_t); +const char *mchars_spec2str(const char *, size_t, size_t *); +struct mparse *mparse_alloc(int, enum mandoclevel, mandocmsg, const char *); void mparse_free(struct mparse *); void mparse_keep(struct mparse *); -enum mandoclevel mparse_open(struct mparse *, int *, const char *); +int mparse_open(struct mparse *, const char *); enum mandoclevel mparse_readfd(struct mparse *, int, const char *); enum mandoclevel mparse_readmem(struct mparse *, void *, size_t, const char *); void mparse_reset(struct mparse *); void mparse_result(struct mparse *, - struct mdoc **, struct man **, char **); + struct roff_man **, char **); const char *mparse_getkeep(const struct mparse *); const char *mparse_strerror(enum mandocerr); const char *mparse_strlevel(enum mandoclevel); -enum mandoclevel mparse_wait(struct mparse *); - -__END_DECLS diff --git a/contrib/mdocml/mandoc_aux.c b/contrib/mdocml/mandoc_aux.c index 2275bbc..cc74b7e 100644 --- a/contrib/mdocml/mandoc_aux.c +++ b/contrib/mdocml/mandoc_aux.c @@ -1,4 +1,4 @@ -/* $Id: mandoc_aux.c,v 1.4 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: mandoc_aux.c,v 1.9 2015/11/07 14:22:29 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -19,6 +19,9 @@ #include <sys/types.h> +#if HAVE_ERR +#include <err.h> +#endif #include <stdarg.h> #include <stdlib.h> #include <stdio.h> @@ -27,6 +30,7 @@ #include "mandoc.h" #include "mandoc_aux.h" + int mandoc_asprintf(char **dest, const char *fmt, ...) { @@ -37,11 +41,9 @@ mandoc_asprintf(char **dest, const char *fmt, ...) ret = vasprintf(dest, fmt, ap); va_end(ap); - if (-1 == ret) { - perror(NULL); - exit((int)MANDOCLEVEL_SYSERR); - } - return(ret); + if (ret == -1) + err((int)MANDOCLEVEL_SYSERR, NULL); + return ret; } void * @@ -50,11 +52,9 @@ mandoc_calloc(size_t num, size_t size) void *ptr; ptr = calloc(num, size); - if (NULL == ptr) { - perror(NULL); - exit((int)MANDOCLEVEL_SYSERR); - } - return(ptr); + if (ptr == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); + return ptr; } void * @@ -63,11 +63,9 @@ mandoc_malloc(size_t size) void *ptr; ptr = malloc(size); - if (NULL == ptr) { - perror(NULL); - exit((int)MANDOCLEVEL_SYSERR); - } - return(ptr); + if (ptr == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); + return ptr; } void * @@ -75,11 +73,9 @@ mandoc_realloc(void *ptr, size_t size) { ptr = realloc(ptr, size); - if (NULL == ptr) { - perror(NULL); - exit((int)MANDOCLEVEL_SYSERR); - } - return(ptr); + if (ptr == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); + return ptr; } void * @@ -87,11 +83,9 @@ mandoc_reallocarray(void *ptr, size_t num, size_t size) { ptr = reallocarray(ptr, num, size); - if (NULL == ptr) { - perror(NULL); - exit((int)MANDOCLEVEL_SYSERR); - } - return(ptr); + if (ptr == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); + return ptr; } char * @@ -100,11 +94,9 @@ mandoc_strdup(const char *ptr) char *p; p = strdup(ptr); - if (NULL == p) { - perror(NULL); - exit((int)MANDOCLEVEL_SYSERR); - } - return(p); + if (p == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); + return p; } char * @@ -115,5 +107,5 @@ mandoc_strndup(const char *ptr, size_t sz) p = mandoc_malloc(sz + 1); memcpy(p, ptr, sz); p[(int)sz] = '\0'; - return(p); + return p; } diff --git a/contrib/mdocml/mandoc_aux.h b/contrib/mdocml/mandoc_aux.h index e72fe4e..2ae3a0c 100644 --- a/contrib/mdocml/mandoc_aux.h +++ b/contrib/mdocml/mandoc_aux.h @@ -1,4 +1,4 @@ -/* $Id: mandoc_aux.h,v 1.3 2014/12/01 04:05:32 schwarze Exp $ */ +/* $Id: mandoc_aux.h,v 1.4 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -16,8 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -__BEGIN_DECLS - int mandoc_asprintf(char **, const char *, ...); void *mandoc_calloc(size_t, size_t); void *mandoc_malloc(size_t); @@ -25,5 +23,3 @@ void *mandoc_realloc(void *, size_t); void *mandoc_reallocarray(void *, size_t, size_t); char *mandoc_strdup(const char *); char *mandoc_strndup(const char *, size_t); - -__END_DECLS diff --git a/contrib/mdocml/mandoc_char.7 b/contrib/mdocml/mandoc_char.7 index 806b990..d272080 100644 --- a/contrib/mdocml/mandoc_char.7 +++ b/contrib/mdocml/mandoc_char.7 @@ -1,8 +1,8 @@ -.\" $Id: mandoc_char.7,v 1.59 2015/01/20 19:39:34 schwarze Exp $ +.\" $Id: mandoc_char.7,v 1.63 2015/09/02 15:38:35 schwarze Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org> .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2011, 2013, 2015 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 20 2015 $ +.Dd $Mdocdate: September 2 2015 $ .Dt MANDOC_CHAR 7 .Os .Sh NAME @@ -49,7 +49,7 @@ names; instead, provide ASCII transcriptions of the names. .Ss Dashes and Hyphens In typography there are different types of dashes of various width: the hyphen (-), -the minus sign (\-), +the minus sign (\(mi), the en-dash (\(en), and the em-dash (\(em). .Pp @@ -64,10 +64,10 @@ lorry-driver .Pp The mathematical minus sign is used for negative numbers or subtraction. It should be written as -.Sq \e- : +.Sq \e(mi : .Bd -unfilled -offset indent -a = 3 \e- 1; -b = \e-2; +a = 3 \e(mi 1; +b = \e(mi2; .Ed .Pp The en-dash is used to separate the two elements of a range, @@ -142,6 +142,28 @@ Note that on text lines, literal double-quote characters can be used verbatim. All other quote-like characters can be used verbatim as well, even on request and macro lines. +.Ss Accents +In output modes supporting such special output characters, for example +.Fl T Cm pdf , +some +.Xr roff 7 +formatters convert the following ASCII input characters to the +following Unicode special output characters: +.Bl -column x(ga U+2018 -offset indent +.It \(ga Ta U+2018 Ta left single quotation mark +.It \(aq Ta U+2019 Ta right single quotation mark +.It \(ti Ta U+02DC Ta small tilde +.El +.Pp +In prose, this automatic substitution is often desirable; +but when these characters have to be displayed as plain ASCII +characters, for example in source code samples, they require +escaping to render as follows: +.Bl -column x(ga U+2018 -offset indent +.It \e(ga Ta U+0060 Ta grave accent +.It \e(aq Ta U+0027 Ta apostrophe +.It \e(ti Ta U+007E Ta tilde +.El .Ss Periods The period .Pq Sq \&. @@ -196,7 +218,7 @@ Spacing: .Bl -column "Input" "Description" -offset indent -compact .It Em Input Ta Em Description .It Sq \e\ \& Ta unpaddable non-breaking space -.It \e~ Ta paddable non-breaking space +.It \e\(ti Ta paddable non-breaking space .It \e0 Ta unpaddable, breaking digit-width space .It \e| Ta one-sixth \e(em narrow space, zero width in nroff mode .It \e^ Ta one-twelfth \e(em half-narrow space, zero width in nroff @@ -371,9 +393,9 @@ Mathematical: .It \e(ne Ta \(ne Ta not equivalent .It \e(ap Ta \(ap Ta tilde operator .It \e(|= Ta \(|= Ta asymptotically equal -.It \e(=~ Ta \(=~ Ta approximately equal -.It \e(~~ Ta \(~~ Ta almost equal -.It \e(~= Ta \(~= Ta almost equal +.It \e(=\(ti Ta \(=~ Ta approximately equal +.It \e(\(ti\(ti Ta \(~~ Ta almost equal +.It \e(\(ti= Ta \(~= Ta almost equal .It \e(pt Ta \(pt Ta proportionate .It \e(es Ta \(es Ta empty set .It \e(mo Ta \(mo Ta element @@ -436,15 +458,15 @@ Accents: .It \e(a. Ta \(a. Ta dotted .It \e(a^ Ta \(a^ Ta circumflex .It \e(aa Ta \(aa Ta acute -.It \e' Ta \' Ta acute +.It \e\(aq Ta \' Ta acute .It \e(ga Ta \(ga Ta grave -.It \e` Ta \` Ta grave +.It \e\(ga Ta \` Ta grave .It \e(ab Ta \(ab Ta breve .It \e(ac Ta \(ac Ta cedilla .It \e(ad Ta \(ad Ta dieresis .It \e(ah Ta \(ah Ta caron .It \e(ao Ta \(ao Ta ring -.It \e(a~ Ta \(a~ Ta tilde +.It \e(a\(ti Ta \(a~ Ta tilde .It \e(ho Ta \(ho Ta ogonek .It \e(ha Ta \(ha Ta hat (text) .It \e(ti Ta \(ti Ta tilde (text) @@ -453,32 +475,32 @@ Accents: Accented letters: .Bl -column "Input" "Rendered" "Description" -offset indent -compact .It Em Input Ta Em Rendered Ta Em Description -.It \e('A Ta \('A Ta acute A -.It \e('E Ta \('E Ta acute E -.It \e('I Ta \('I Ta acute I -.It \e('O Ta \('O Ta acute O -.It \e('U Ta \('U Ta acute U -.It \e('a Ta \('a Ta acute a -.It \e('e Ta \('e Ta acute e -.It \e('i Ta \('i Ta acute i -.It \e('o Ta \('o Ta acute o -.It \e('u Ta \('u Ta acute u -.It \e(`A Ta \(`A Ta grave A -.It \e(`E Ta \(`E Ta grave E -.It \e(`I Ta \(`I Ta grave I -.It \e(`O Ta \(`O Ta grave O -.It \e(`U Ta \(`U Ta grave U -.It \e(`a Ta \(`a Ta grave a -.It \e(`e Ta \(`e Ta grave e -.It \e(`i Ta \(`i Ta grave i -.It \e(`o Ta \(`i Ta grave o -.It \e(`u Ta \(`u Ta grave u -.It \e(~A Ta \(~A Ta tilde A -.It \e(~N Ta \(~N Ta tilde N -.It \e(~O Ta \(~O Ta tilde O -.It \e(~a Ta \(~a Ta tilde a -.It \e(~n Ta \(~n Ta tilde n -.It \e(~o Ta \(~o Ta tilde o +.It \e(\(aqA Ta \('A Ta acute A +.It \e(\(aqE Ta \('E Ta acute E +.It \e(\(aqI Ta \('I Ta acute I +.It \e(\(aqO Ta \('O Ta acute O +.It \e(\(aqU Ta \('U Ta acute U +.It \e(\(aqa Ta \('a Ta acute a +.It \e(\(aqe Ta \('e Ta acute e +.It \e(\(aqi Ta \('i Ta acute i +.It \e(\(aqo Ta \('o Ta acute o +.It \e(\(aqu Ta \('u Ta acute u +.It \e(\(gaA Ta \(`A Ta grave A +.It \e(\(gaE Ta \(`E Ta grave E +.It \e(\(gaI Ta \(`I Ta grave I +.It \e(\(gaO Ta \(`O Ta grave O +.It \e(\(gaU Ta \(`U Ta grave U +.It \e(\(gaa Ta \(`a Ta grave a +.It \e(\(gae Ta \(`e Ta grave e +.It \e(\(gai Ta \(`i Ta grave i +.It \e(\(gao Ta \(`i Ta grave o +.It \e(\(gau Ta \(`u Ta grave u +.It \e(\(tiA Ta \(~A Ta tilde A +.It \e(\(tiN Ta \(~N Ta tilde N +.It \e(\(tiO Ta \(~O Ta tilde O +.It \e(\(tia Ta \(~a Ta tilde a +.It \e(\(tin Ta \(~n Ta tilde n +.It \e(\(tio Ta \(~o Ta tilde o .It \e(:A Ta \(:A Ta dieresis A .It \e(:E Ta \(:E Ta dieresis E .It \e(:I Ta \(:I Ta dieresis I @@ -657,7 +679,7 @@ manual. .Sh UNICODE CHARACTERS The escape sequences .Pp -.Dl \e[uXXXX] and \eC'uXXXX' +.Dl \e[uXXXX] and \eC\(aquXXXX\(aq .Pp are interpreted as Unicode codepoints. The codepoint must be in the range above U+0080 and less than U+10FFFF. @@ -669,10 +691,6 @@ must be given as uppercase characters, and points must be zero-padded to four characters; if greater than four characters, no zero padding is allowed. Unicode surrogates are not allowed. -.\" .Pp -.\" Unicode glyphs attenuate to the -.\" .Sq \&? -.\" character if invalid or not rendered by current output media. .Sh NUMBERED CHARACTERS For backward compatibility with existing manuals, .Xr mandoc 1 @@ -685,7 +703,7 @@ escape sequence, inserting the character from the current character set into the output. Of course, this is inherently non-portable and is already marked as deprecated in the Heirloom roff manual. -For example, do not use \eN'34', use \e(dq, or even the plain +For example, do not use \eN\(aq34\(aq, use \e(dq, or even the plain .Sq \(dq character where possible. .Sh COMPATIBILITY @@ -702,14 +720,14 @@ In .Fl T Ns Cm ascii , the \e(ss, \e(nm, \e(nb, \e(nc, \e(ib, \e(ip, \e(pp, \e[sum], \e[product], -\e[coproduct], \e(gr, \e(\-h, and \e(a. special characters render +\e[coproduct], \e(gr, \e(-h, and \e(a. special characters render differently between mandoc and groff. .It In .Fl T Ns Cm html and .Fl T Ns Cm xhtml , -the \e(~=, \e(nb, and \e(nc special characters render differently +the \e(\(ti=, \e(nb, and \e(nc special characters render differently between mandoc and groff. .It The diff --git a/contrib/mdocml/mandoc_headers.3 b/contrib/mdocml/mandoc_headers.3 index 79d90ff..6c30e16 100644 --- a/contrib/mdocml/mandoc_headers.3 +++ b/contrib/mdocml/mandoc_headers.3 @@ -54,7 +54,6 @@ require inclusion of the header where that type is defined. Each of the following headers can be included without including any other mandoc header. These headers should be included before any other mandoc headers. -Afterwards, any other mandoc headers can be included as needed. .Bl -tag -width Ds .It Qq Pa mandoc_aux.h Requires @@ -99,14 +98,10 @@ and the functions described in .Xr mandoc 3 . .Pp -Uses the opaque types +Uses the opaque type .Vt struct mparse from .Pa read.c -and -.Vt struct mchars -from -.Pa chars.c for function prototypes. Uses the types .Vt struct mdoc @@ -117,23 +112,45 @@ and from .Pa libman.h as opaque types for function prototypes. +.It Qq Pa roff.h +Provides +.Vt enum mdoc_endbody , +.Vt enum roff_sec , +.Vt enum roff_type , +.Vt struct roff_meta , +and +.Vt struct roff_node . +.Pp +Uses pointers to the types +.Vt struct mdoc_arg +and +.Vt union mdoc_data +from +.Qq Pa mdoc.h +as opaque struct members. +.El +.Pp +The following two require +.Qq Pa roff.h +but no other mandoc headers. +Afterwards, any other mandoc headers can be included as needed. +.Bl -tag -width Ds .It Qq Pa mdoc.h Requires .In sys/types.h for -.Vt size_t . +.Vt size_t +and +.Qq Pa roff.h +for +.Vt enum roff_type . .Pp Provides -.Vt enum mdoct , .Vt enum mdocargt , -.Vt enum mdoc_type , -.Vt enum mdoc_sec , -.Vt enum mdoc_endbody , .Vt enum mdoc_disp , .Vt enum mdoc_list , .Vt enum mdoc_auth , .Vt enum mdoc_font , -.Vt struct mdoc_meta , .Vt struct mdoc_argv , .Vt struct mdoc_arg , .Vt struct mdoc_bd , @@ -141,7 +158,6 @@ Provides .Vt struct mdoc_an , .Vt struct mdoc_bf , .Vt struct mdoc_rs , -.Vt struct mdoc_node , and the functions .Fn mdoc_* described in @@ -163,12 +179,12 @@ When this header is included, the same file should not include or .Pa libroff.h . .It Qq Pa man.h -Provides -.Vt enum mant , -.Vt enum man_type , -.Vt struct man_meta , -.Vt struct man_node , -and the functions +Requires +.Qq Pa roff.h +for +.Vt enum roff_type . +.Pp +Provides the functions .Fn man_* described in .Xr mandoc 3 . @@ -204,11 +220,16 @@ are included, the same file should not include any formatter headers. Requires .In sys/types.h for -.Vt size_t -and +.Vt size_t , .Qq Pa mandoc.h for -.Vt enum mandocerr . +.Vt enum mandocerr , +and +.Qq Pa roff.h +for +.Vt struct roff_meta +and +.Vt struct roff_node . .Pp Provides .Vt enum rofferr , @@ -243,8 +264,7 @@ as opaque types for function prototypes. Requires .Qq Pa mdoc.h for -.Vt enum mdoct , -.Vt enum mdoc_* , +.Vt enum mdoc_* and .Vt struct mdoc_* . .Pp @@ -274,11 +294,11 @@ or .Pa libroff.h . .It Qq Pa libman.h Requires -.Qq Pa man.h +.Qq Pa roff.h for -.Vt enum mant +.Vt struct roff_meta and -.Vt struct man_node. +.Vt struct roff_node . .Pp Provides .Vt enum man_next , @@ -366,8 +386,6 @@ from as an opaque type for function prototypes. .Pp When this header is included, the same file should not include -.Pa manpath.h -or .Pa mansearch.h . .It Qq Pa term.h Requires @@ -389,11 +407,7 @@ Provides .Vt struct termp , and many terminal formatting functions. .Pp -Uses the opaque types -.Vt struct mchars -from -.Pa chars.c -and +Uses the opaque type .Vt struct termp_ps from .Pa term_ps.c . @@ -403,11 +417,14 @@ and .Vt struct eqn from .Pa mandoc.h +and +.Vt struct roff_meta +from +.Qq Pa roff.h as opaque types for function prototypes. .Pp When this header is included, the same file should not include -.Pa html.h , -.Pa manpath.h +.Pa html.h or .Pa mansearch.h . .It Qq Pa html.h @@ -435,23 +452,13 @@ Provides .Vt struct html , and many HTML formatting functions. .Pp -Uses the opaque type -.Vt struct mchars -from -.Pa chars.c . -.Pp When this header is included, the same file should not include -.Pa term.h , -.Pa manpath.h +.Pa term.h or .Pa mansearch.h . .It Qq Pa main.h Provides the top level steering functions for all formatters. .Pp -Uses the opaque type -.Vt struct mchars -from -.Pa chars.c . Uses the types .Vt struct mdoc from @@ -461,25 +468,21 @@ and from .Pa libman.h as opaque types for function prototypes. -.It Qq Pa manpath.h +.It Qq Pa manconf.h Requires .In sys/types.h for .Vt size_t . .Pp Provides -.Vt struct manpaths +.Vt struct manconf , +.Vt struct manpaths , +.Vt struct manoutput , and the functions -.Fn manpath_manconf , -.Fn manpath_parse , +.Fn manconf_parse , +.Fn manconf_output , and -.Fn manpath_free . -.Pp -When this header is included, the same file should not include -.Pa out.h , -.Pa term.h , -or -.Pa html.h . +.Fn manconf_free . .It Qq Pa mansearch.h Requires .In sys/types.h @@ -503,7 +506,7 @@ and Uses .Vt struct manpaths from -.Pa manpath.h +.Pa manconf.h as an opaque type for function prototypes. .Pp When this header is included, the same file should not include diff --git a/contrib/mdocml/mandoc_ohash.c b/contrib/mdocml/mandoc_ohash.c new file mode 100644 index 0000000..0627b46 --- /dev/null +++ b/contrib/mdocml/mandoc_ohash.c @@ -0,0 +1,63 @@ +/* $Id: mandoc_ohash.c,v 1.2 2015/10/19 18:58:47 schwarze Exp $ */ +/* + * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <sys/types.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "mandoc_aux.h" +#include "mandoc_ohash.h" + +static void *hash_alloc(size_t, void *); +static void *hash_calloc(size_t, size_t, void *); +static void hash_free(void *, void *); + + +void +mandoc_ohash_init(struct ohash *h, unsigned int sz, ptrdiff_t ko) +{ + struct ohash_info info; + + info.alloc = hash_alloc; + info.calloc = hash_calloc; + info.free = hash_free; + info.data = NULL; + info.key_offset = ko; + + ohash_init(h, sz, &info); +} + +static void * +hash_alloc(size_t sz, void *arg) +{ + + return mandoc_malloc(sz); +} + +static void * +hash_calloc(size_t n, size_t sz, void *arg) +{ + + return mandoc_calloc(n, sz); +} + +static void +hash_free(void *p, void *arg) +{ + + free(p); +} diff --git a/contrib/mdocml/mandoc_ohash.h b/contrib/mdocml/mandoc_ohash.h new file mode 100644 index 0000000..571c4cd --- /dev/null +++ b/contrib/mdocml/mandoc_ohash.h @@ -0,0 +1,23 @@ +/* $Id: mandoc_ohash.h,v 1.2 2015/11/07 14:01:16 schwarze Exp $ */ +/* + * Copyright (c) 2015 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 HAVE_OHASH +#include <ohash.h> +#else +#include "compat_ohash.h" +#endif + +void mandoc_ohash_init(struct ohash *, unsigned int, ptrdiff_t); diff --git a/contrib/mdocml/mandocdb.c b/contrib/mdocml/mandocdb.c index fed11e9..08f89c1 100644 --- a/contrib/mdocml/mandocdb.c +++ b/contrib/mdocml/mandocdb.c @@ -1,15 +1,15 @@ -/* $Id: mandocdb.c,v 1.186 2015/03/13 00:19:41 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.215 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2016 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -23,6 +23,9 @@ #include <assert.h> #include <ctype.h> +#if HAVE_ERR +#include <err.h> +#endif #include <errno.h> #include <fcntl.h> #if HAVE_FTS @@ -39,18 +42,15 @@ #include <string.h> #include <unistd.h> -#if HAVE_OHASH -#include <ohash.h> -#else -#include "compat_ohash.h" -#endif #include <sqlite3.h> +#include "mandoc_aux.h" +#include "mandoc_ohash.h" +#include "mandoc.h" +#include "roff.h" #include "mdoc.h" #include "man.h" -#include "mandoc.h" -#include "mandoc_aux.h" -#include "manpath.h" +#include "manconf.h" #include "mansearch.h" extern int mansearch_keymax; @@ -129,8 +129,8 @@ enum stmt { STMT__MAX }; -typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); +typedef int (*mdoc_fp)(struct mpage *, const struct roff_meta *, + const struct roff_node *); struct mdoc_handler { mdoc_fp fp; /* optional handler */ @@ -144,9 +144,6 @@ static void dbadd_mlink_name(const struct mlink *mlink); static int dbopen(int); static void dbprune(void); static void filescan(const char *); -static void *hash_alloc(size_t, void *); -static void hash_free(void *, void *); -static void *hash_calloc(size_t, size_t, void *); static void mlink_add(struct mlink *, const struct stat *); static void mlink_check(struct mpage *, struct mlink *); static void mlink_free(struct mlink *); @@ -155,33 +152,33 @@ static void mpages_free(void); static void mpages_merge(struct mparse *); static void names_check(void); static void parse_cat(struct mpage *, int); -static void parse_man(struct mpage *, const struct man_meta *, - const struct man_node *); -static void parse_mdoc(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_body(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_head(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_Fd(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static void parse_mdoc_fname(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Fn(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_Fo(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_Nd(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_Nm(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_Sh(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); -static int parse_mdoc_Xr(struct mpage *, const struct mdoc_meta *, - const struct mdoc_node *); +static void parse_man(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static void parse_mdoc(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_head(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Fd(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static void parse_mdoc_fname(struct mpage *, const struct roff_node *); +static int parse_mdoc_Fn(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Fo(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Nd(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Nm(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Sh(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Va(struct mpage *, const struct roff_meta *, + const struct roff_node *); +static int parse_mdoc_Xr(struct mpage *, const struct roff_meta *, + const struct roff_node *); static void putkey(const struct mpage *, char *, uint64_t); static void putkeys(const struct mpage *, char *, size_t, uint64_t); static void putmdockey(const struct mpage *, - const struct mdoc_node *, uint64_t); + const struct roff_node *, uint64_t); static int render_string(char **, size_t *); static void say(const char *, const char *, ...); static int set_basedir(const char *, int); @@ -189,7 +186,6 @@ static int treescan(void); static size_t utf8(unsigned int, char [7]); static char tempfilename[32]; -static char *progname; static int nodb; /* no database changes */ static int mparse_options; /* abort the parse early */ static int use_all; /* use all found files */ @@ -199,7 +195,6 @@ static int write_utf8; /* write UTF-8 output; else ASCII */ static int exitcode; /* to be returned by main */ static enum op op; /* operational mode */ static char basedir[PATH_MAX]; /* current base directory */ -static struct mchars *mchars; /* table of named characters */ static struct ohash mpages; /* table of distinct manual pages */ static struct ohash mlinks; /* table of directory entries */ static struct ohash names; /* table of all names */ @@ -247,8 +242,8 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = { { NULL, TYPE_Pa }, /* Pa */ { NULL, 0 }, /* Rv */ { NULL, TYPE_St }, /* St */ - { NULL, TYPE_Va }, /* Va */ - { parse_mdoc_body, TYPE_Va }, /* Vt */ + { parse_mdoc_Va, TYPE_Va }, /* Va */ + { parse_mdoc_Va, TYPE_Vt }, /* Vt */ { parse_mdoc_Xr, 0 }, /* Xr */ { NULL, 0 }, /* %A */ { NULL, 0 }, /* %B */ @@ -338,29 +333,21 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = { int mandocdb(int argc, char *argv[]) { - int ch, i; - size_t j, sz; - const char *path_arg; - struct manpaths dirs; + struct manconf conf; struct mparse *mp; - struct ohash_info mpages_info, mlinks_info; - - memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *)); - memset(&dirs, 0, sizeof(struct manpaths)); - - mpages_info.alloc = mlinks_info.alloc = hash_alloc; - mpages_info.calloc = mlinks_info.calloc = hash_calloc; - mpages_info.free = mlinks_info.free = hash_free; - mpages_info.data = mlinks_info.data = NULL; + const char *path_arg, *progname; + size_t j, sz; + int ch, i; - mpages_info.key_offset = offsetof(struct mpage, inodev); - mlinks_info.key_offset = offsetof(struct mlink, file); +#if HAVE_PLEDGE + if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) { + warn("pledge"); + return (int)MANDOCLEVEL_SYSERR; + } +#endif - progname = strrchr(argv[0], '/'); - if (progname == NULL) - progname = argv[0]; - else - ++progname; + memset(&conf, 0, sizeof(conf)); + memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *)); /* * We accept a few different invocations. @@ -369,8 +356,7 @@ mandocdb(int argc, char *argv[]) */ #define CHECKOP(_op, _ch) do \ if (OP_DEFAULT != (_op)) { \ - fprintf(stderr, "%s: -%c: Conflicting option\n", \ - progname, (_ch)); \ + warnx("-%c: Conflicting option", (_ch)); \ goto usage; \ } while (/*CONSTCOND*/0) @@ -406,9 +392,8 @@ mandocdb(int argc, char *argv[]) break; case 'T': if (strcmp(optarg, "utf8")) { - fprintf(stderr, "%s: -T%s: " - "Unsupported output format\n", - progname, optarg); + warnx("-T%s: Unsupported output format", + optarg); goto usage; } write_utf8 = 1; @@ -434,18 +419,25 @@ mandocdb(int argc, char *argv[]) argc -= optind; argv += optind; +#if HAVE_PLEDGE + if (nodb) { + if (pledge("stdio rpath", NULL) == -1) { + warn("pledge"); + return (int)MANDOCLEVEL_SYSERR; + } + } +#endif + if (OP_CONFFILE == op && argc > 0) { - fprintf(stderr, "%s: -C: Too many arguments\n", - progname); + warnx("-C: Too many arguments"); goto usage; } exitcode = (int)MANDOCLEVEL_OK; - mchars = mchars_alloc(); - mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL, - mchars, NULL); - ohash_init(&mpages, 6, &mpages_info); - ohash_init(&mlinks, 6, &mlinks_info); + mchars_alloc(); + mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL, NULL); + mandoc_ohash_init(&mpages, 6, offsetof(struct mpage, inodev)); + mandoc_ohash_init(&mlinks, 6, offsetof(struct mlink, file)); if (OP_UPDATE == op || OP_DELETE == op || OP_TEST == op) { @@ -461,6 +453,15 @@ mandocdb(int argc, char *argv[]) * The existing database is usable. Process * all files specified on the command-line. */ +#if HAVE_PLEDGE + if (!nodb) { + if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1) { + warn("pledge"); + exitcode = (int)MANDOCLEVEL_SYSERR; + goto out; + } + } +#endif use_all = 1; for (i = 0; i < argc; i++) filescan(argv[i]); @@ -485,18 +486,18 @@ mandocdb(int argc, char *argv[]) /* * If we have arguments, use them as our manpaths. * If we don't, grok from manpath(1) or however else - * manpath_parse() wants to do it. + * manconf_parse() wants to do it. */ if (argc > 0) { - dirs.paths = mandoc_reallocarray(NULL, + conf.manpath.paths = mandoc_reallocarray(NULL, argc, sizeof(char *)); - dirs.sz = (size_t)argc; + conf.manpath.sz = (size_t)argc; for (i = 0; i < argc; i++) - dirs.paths[i] = mandoc_strdup(argv[i]); + conf.manpath.paths[i] = mandoc_strdup(argv[i]); } else - manpath_parse(&dirs, path_arg, NULL, NULL); + manconf_parse(&conf, path_arg, NULL, NULL); - if (0 == dirs.sz) { + if (conf.manpath.sz == 0) { exitcode = (int)MANDOCLEVEL_BADARG; say("", "Empty manpath"); } @@ -507,19 +508,21 @@ mandocdb(int argc, char *argv[]) * Ignore zero-length directories and strip trailing * slashes. */ - for (j = 0; j < dirs.sz; j++) { - sz = strlen(dirs.paths[j]); - if (sz && '/' == dirs.paths[j][sz - 1]) - dirs.paths[j][--sz] = '\0'; + for (j = 0; j < conf.manpath.sz; j++) { + sz = strlen(conf.manpath.paths[j]); + if (sz && conf.manpath.paths[j][sz - 1] == '/') + conf.manpath.paths[j][--sz] = '\0'; if (0 == sz) continue; if (j) { - ohash_init(&mpages, 6, &mpages_info); - ohash_init(&mlinks, 6, &mlinks_info); + mandoc_ohash_init(&mpages, 6, + offsetof(struct mpage, inodev)); + mandoc_ohash_init(&mlinks, 6, + offsetof(struct mlink, file)); } - if (0 == set_basedir(dirs.paths[j], argc > 0)) + if ( ! set_basedir(conf.manpath.paths[j], argc > 0)) continue; if (0 == treescan()) continue; @@ -532,7 +535,7 @@ mandocdb(int argc, char *argv[]) names_check(); dbclose(0); - if (j + 1 < dirs.sz) { + if (j + 1 < conf.manpath.sz) { mpages_free(); ohash_delete(&mpages); ohash_delete(&mlinks); @@ -540,23 +543,23 @@ mandocdb(int argc, char *argv[]) } } out: - manpath_free(&dirs); + manconf_free(&conf); mparse_free(mp); - mchars_free(mchars); + mchars_free(); mpages_free(); ohash_delete(&mpages); ohash_delete(&mlinks); - return(exitcode); + return exitcode; usage: + progname = getprogname(); fprintf(stderr, "usage: %s [-aDnpQ] [-C file] [-Tutf8]\n" " %s [-aDnpQ] [-Tutf8] dir ...\n" " %s [-DnpQ] [-Tutf8] -d dir [file ...]\n" " %s [-Dnp] -u dir [file ...]\n" " %s [-Q] -t file ...\n", - progname, progname, progname, - progname, progname); + progname, progname, progname, progname, progname); - return((int)MANDOCLEVEL_BADARG); + return (int)MANDOCLEVEL_BADARG; } /* @@ -590,16 +593,16 @@ treescan(void) f = fts_open((char * const *)argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL); - if (NULL == f) { + if (f == NULL) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "&fts_open"); - return(0); + return 0; } dsec = arch = NULL; dform = FORM_NONE; - while (NULL != (ff = fts_read(f))) { + while ((ff = fts_read(f)) != NULL) { path = ff->fts_path + 2; switch (ff->fts_info) { @@ -608,7 +611,7 @@ treescan(void) * then get handled just like regular files. */ case FTS_SL: - if (NULL == realpath(path, buf)) { + if (realpath(path, buf) == NULL) { if (warnings) say(path, "&realpath"); continue; @@ -623,7 +626,7 @@ treescan(void) continue; } /* Use logical inode to avoid mpages dupe. */ - if (-1 == stat(path, ff->fts_statp)) { + if (stat(path, ff->fts_statp) == -1) { if (warnings) say(path, "&stat"); continue; @@ -635,7 +638,7 @@ treescan(void) * stored directory data and handling the filename. */ case FTS_F: - if (0 == strcmp(path, MANDOC_DB)) + if ( ! strcmp(path, MANDOC_DB)) continue; if ( ! use_all && ff->fts_level < 2) { if (warnings) @@ -644,37 +647,37 @@ treescan(void) } gzip = 0; fsec = NULL; - while (NULL == fsec) { + while (fsec == NULL) { fsec = strrchr(ff->fts_name, '.'); - if (NULL == fsec || strcmp(fsec+1, "gz")) + if (fsec == NULL || strcmp(fsec+1, "gz")) break; gzip = 1; *fsec = '\0'; fsec = NULL; } - if (NULL == fsec) { + if (fsec == NULL) { if ( ! use_all) { if (warnings) say(path, "No filename suffix"); continue; } - } else if (0 == strcmp(++fsec, "html")) { + } else if ( ! strcmp(++fsec, "html")) { if (warnings) say(path, "Skip html"); continue; - } else if (0 == strcmp(fsec, "ps")) { + } else if ( ! strcmp(fsec, "ps")) { if (warnings) say(path, "Skip ps"); continue; - } else if (0 == strcmp(fsec, "pdf")) { + } else if ( ! strcmp(fsec, "pdf")) { if (warnings) say(path, "Skip pdf"); continue; } else if ( ! use_all && - ((FORM_SRC == dform && + ((dform == FORM_SRC && strncmp(fsec, dsec, strlen(dsec))) || - (FORM_CAT == dform && strcmp(fsec, "0")))) { + (dform == FORM_CAT && strcmp(fsec, "0")))) { if (warnings) say(path, "Wrong filename suffix"); continue; @@ -699,7 +702,6 @@ treescan(void) continue; case FTS_D: - /* FALLTHROUGH */ case FTS_DP: break; @@ -720,13 +722,16 @@ treescan(void) * If we're not in use_all, enforce it. */ cp = ff->fts_name; - if (FTS_DP == ff->fts_info) + if (ff->fts_info == FTS_DP) { + dform = FORM_NONE; + dsec = NULL; break; + } - if (0 == strncmp(cp, "man", 3)) { + if ( ! strncmp(cp, "man", 3)) { dform = FORM_SRC; dsec = cp + 3; - } else if (0 == strncmp(cp, "cat", 3)) { + } else if ( ! strncmp(cp, "cat", 3)) { dform = FORM_CAT; dsec = cp + 3; } else { @@ -734,7 +739,7 @@ treescan(void) dsec = NULL; } - if (NULL != dsec || use_all) + if (dsec != NULL || use_all) break; if (warnings) @@ -746,13 +751,13 @@ treescan(void) * Possibly our architecture. * If we're descending, keep tabs on it. */ - if (FTS_DP != ff->fts_info && NULL != dsec) + if (ff->fts_info != FTS_DP && dsec != NULL) arch = ff->fts_name; else arch = NULL; break; default: - if (FTS_DP == ff->fts_info || use_all) + if (ff->fts_info == FTS_DP || use_all) break; if (warnings) say(path, "Extraneous directory part"); @@ -762,7 +767,7 @@ treescan(void) } fts_close(f); - return(1); + return 1; } /* @@ -1103,22 +1108,14 @@ static void mpages_merge(struct mparse *mp) { char any[] = "any"; - struct ohash_info str_info; struct mpage *mpage, *mpage_dest; struct mlink *mlink, *mlink_dest; - struct mdoc *mdoc; - struct man *man; + struct roff_man *man; char *sodest; char *cp; int fd; unsigned int pslot; - str_info.alloc = hash_alloc; - str_info.calloc = hash_calloc; - str_info.free = hash_free; - str_info.data = NULL; - str_info.key_offset = offsetof(struct str, key); - if ( ! nodb) SQL_EXEC("BEGIN TRANSACTION"); @@ -1131,15 +1128,13 @@ mpages_merge(struct mparse *mp) } name_mask = NAME_MASK; - ohash_init(&names, 4, &str_info); - ohash_init(&strings, 6, &str_info); + mandoc_ohash_init(&names, 4, offsetof(struct str, key)); + mandoc_ohash_init(&strings, 6, offsetof(struct str, key)); mparse_reset(mp); - mdoc = NULL; man = NULL; sodest = NULL; - mparse_open(mp, &fd, mlink->file); - if (fd == -1) { + if ((fd = mparse_open(mp, mlink->file)) == -1) { say(mlink->file, "&open"); goto nextpage; } @@ -1150,7 +1145,8 @@ mpages_merge(struct mparse *mp) */ if (mlink->dform != FORM_CAT || mlink->fform != FORM_CAT) { mparse_readfd(mp, fd, mlink->file); - mparse_result(mp, &mdoc, &man, &sodest); + close(fd); + mparse_result(mp, &man, &sodest); } if (sodest != NULL) { @@ -1194,21 +1190,22 @@ mpages_merge(struct mparse *mp) mpage->mlinks = NULL; } goto nextpage; - } else if (mdoc != NULL) { + } else if (man != NULL && man->macroset == MACROSET_MDOC) { + mdoc_validate(man); mpage->form = FORM_SRC; - mpage->sec = mdoc_meta(mdoc)->msec; + mpage->sec = man->meta.msec; mpage->sec = mandoc_strdup( mpage->sec == NULL ? "" : mpage->sec); - mpage->arch = mdoc_meta(mdoc)->arch; + mpage->arch = man->meta.arch; mpage->arch = mandoc_strdup( mpage->arch == NULL ? "" : mpage->arch); - mpage->title = - mandoc_strdup(mdoc_meta(mdoc)->title); - } else if (man != NULL) { + mpage->title = mandoc_strdup(man->meta.title); + } else if (man != NULL && man->macroset == MACROSET_MAN) { + man_validate(man); mpage->form = FORM_SRC; - mpage->sec = mandoc_strdup(man_meta(man)->msec); + mpage->sec = mandoc_strdup(man->meta.msec); mpage->arch = mandoc_strdup(mlink->arch); - mpage->title = mandoc_strdup(man_meta(man)->title); + mpage->title = mandoc_strdup(man->meta.title); } else { mpage->form = FORM_CAT; mpage->sec = mandoc_strdup(mlink->dsec); @@ -1230,10 +1227,10 @@ mpages_merge(struct mparse *mp) } assert(mpage->desc == NULL); - if (mdoc != NULL) - parse_mdoc(mpage, mdoc_meta(mdoc), mdoc_node(mdoc)); + if (man != NULL && man->macroset == MACROSET_MDOC) + parse_mdoc(mpage, &man->meta, man->first); else if (man != NULL) - parse_man(mpage, man_meta(man), man_node(man)); + parse_man(mpage, &man->meta, man->first); else parse_cat(mpage, fd); if (mpage->desc == NULL) @@ -1248,10 +1245,6 @@ mpages_merge(struct mparse *mp) mlink = mpage->mlinks; nextpage: - if (mparse_wait(mp) != MANDOCLEVEL_OK) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say(mlink->file, "&wait gunzip"); - } ohash_delete(&strings); ohash_delete(&names); mpage = ohash_next(&mpages, &pslot); @@ -1266,7 +1259,6 @@ names_check(void) { sqlite3_stmt *stmt; const char *name, *sec, *arch, *key; - int irc; sqlite3_prepare_v2(db, "SELECT name, sec, arch, key FROM (" @@ -1282,10 +1274,10 @@ names_check(void) ") USING (pageid);", -1, &stmt, NULL); - if (SQLITE_OK != sqlite3_bind_int64(stmt, 1, NAME_TITLE)) + if (sqlite3_bind_int64(stmt, 1, NAME_TITLE) != SQLITE_OK) say("", "%s", sqlite3_errmsg(db)); - while (SQLITE_ROW == (irc = sqlite3_step(stmt))) { + while (sqlite3_step(stmt) == SQLITE_ROW) { name = (const char *)sqlite3_column_text(stmt, 0); sec = (const char *)sqlite3_column_text(stmt, 1); arch = (const char *)sqlite3_column_text(stmt, 2); @@ -1302,7 +1294,9 @@ parse_cat(struct mpage *mpage, int fd) { FILE *stream; char *line, *p, *title; - size_t len, plen, titlesz; + size_t linesz, plen, titlesz; + ssize_t len; + int offs; stream = (-1 == fd) ? fopen(mpage->mlinks->file, "r") : @@ -1315,10 +1309,13 @@ parse_cat(struct mpage *mpage, int fd) return; } + line = NULL; + linesz = 0; + /* Skip to first blank line. */ - while (NULL != (line = fgetln(stream, &len))) - if ('\n' == *line) + while (getline(&line, &linesz, stream) != -1) + if (*line == '\n') break; /* @@ -1326,8 +1323,8 @@ parse_cat(struct mpage *mpage, int fd) * is the first section header. Skip to it. */ - while (NULL != (line = fgetln(stream, &len))) - if ('\n' != *line && ' ' != *line) + while (getline(&line, &linesz, stream) != -1) + if (*line != '\n' && *line != ' ') break; /* @@ -1340,20 +1337,20 @@ parse_cat(struct mpage *mpage, int fd) titlesz = 0; title = NULL; - while (NULL != (line = fgetln(stream, &len))) { - if (' ' != *line || '\n' != line[len - 1]) + while ((len = getline(&line, &linesz, stream)) != -1) { + if (*line != ' ') break; - while (len > 0 && isspace((unsigned char)*line)) { - line++; - len--; - } - if (1 == len) + offs = 0; + while (isspace((unsigned char)line[offs])) + offs++; + if (line[offs] == '\0') continue; - title = mandoc_realloc(title, titlesz + len); - memcpy(title + titlesz, line, len); - titlesz += len; + title = mandoc_realloc(title, titlesz + len - offs); + memcpy(title + titlesz, line + offs, len - offs); + titlesz += len - offs; title[titlesz - 1] = ' '; } + free(line); /* * If no page content can be found, or the input line @@ -1371,8 +1368,7 @@ parse_cat(struct mpage *mpage, int fd) return; } - title = mandoc_realloc(title, titlesz + 1); - title[titlesz] = '\0'; + title[titlesz - 1] = '\0'; /* * Skip to the first dash. @@ -1430,27 +1426,27 @@ putkey(const struct mpage *mpage, char *value, uint64_t type) */ static void putmdockey(const struct mpage *mpage, - const struct mdoc_node *n, uint64_t m) + const struct roff_node *n, uint64_t m) { for ( ; NULL != n; n = n->next) { if (NULL != n->child) putmdockey(mpage, n->child, m); - if (MDOC_TEXT == n->type) + if (n->type == ROFFT_TEXT) putkey(mpage, n->string, m); } } static void -parse_man(struct mpage *mpage, const struct man_meta *meta, - const struct man_node *n) +parse_man(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { - const struct man_node *head, *body; + const struct roff_node *head, *body; char *start, *title; char byte; size_t sz; - if (NULL == n) + if (n == NULL) return; /* @@ -1460,15 +1456,14 @@ parse_man(struct mpage *mpage, const struct man_meta *meta, * the correct section or not. */ - if (MAN_BODY == n->type && MAN_SH == n->tok) { + if (n->type == ROFFT_BODY && n->tok == MAN_SH) { body = n; - assert(body->parent); - if (NULL != (head = body->parent->head) && - 1 == head->nchild && - NULL != (head = (head->child)) && - MAN_TEXT == head->type && - 0 == strcmp(head->string, "NAME") && - NULL != body->child) { + if ((head = body->parent->head) != NULL && + (head = head->child) != NULL && + head->next == NULL && + head->type == ROFFT_TEXT && + strcmp(head->string, "NAME") == 0 && + body->child != NULL) { /* * Suck the entire NAME section into memory. @@ -1478,7 +1473,7 @@ parse_man(struct mpage *mpage, const struct man_meta *meta, */ title = NULL; - man_deroff(&title, body); + deroff(&title, body); if (NULL == title) return; @@ -1568,22 +1563,18 @@ parse_man(struct mpage *mpage, const struct man_meta *meta, } static void -parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { assert(NULL != n); for (n = n->child; NULL != n; n = n->next) { switch (n->type) { - case MDOC_ELEM: - /* FALLTHROUGH */ - case MDOC_BLOCK: - /* FALLTHROUGH */ - case MDOC_HEAD: - /* FALLTHROUGH */ - case MDOC_BODY: - /* FALLTHROUGH */ - case MDOC_TAIL: + case ROFFT_ELEM: + case ROFFT_BLOCK: + case ROFFT_HEAD: + case ROFFT_BODY: + case ROFFT_TAIL: if (NULL != mdocs[n->tok].fp) if (0 == (*mdocs[n->tok].fp)(mpage, meta, n)) break; @@ -1592,7 +1583,7 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta, mdocs[n->tok].mask); break; default: - assert(MDOC_ROOT != n->type); + assert(n->type != ROFFT_ROOT); continue; } if (NULL != n->child) @@ -1601,16 +1592,16 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta, } static int -parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Fd(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { char *start, *end; size_t sz; if (SEC_SYNOPSIS != n->sec || NULL == (n = n->child) || - MDOC_TEXT != n->type) - return(0); + n->type != ROFFT_TEXT) + return 0; /* * Only consider those `Fd' macro fields that begin with an @@ -1618,10 +1609,10 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta, */ if (strcmp("#include", n->string)) - return(0); + return 0; - if (NULL == (n = n->next) || MDOC_TEXT != n->type) - return(0); + if ((n = n->next) == NULL || n->type != ROFFT_TEXT) + return 0; /* * Strip away the enclosing angle brackets and make sure we're @@ -1633,7 +1624,7 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta, start++; if (0 == (sz = strlen(start))) - return(0); + return 0; end = &start[(int)sz - 1]; if ('>' == *end || '"' == *end) @@ -1641,16 +1632,16 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta, if (end > start) putkeys(mpage, start, end - start + 1, TYPE_In); - return(0); + return 0; } static void -parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_fname(struct mpage *mpage, const struct roff_node *n) { char *cp; size_t sz; - if (n->type != MDOC_TEXT) + if (n->type != ROFFT_TEXT) return; /* Skip function pointer punctuation. */ @@ -1666,74 +1657,99 @@ parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n) } static int -parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Fn(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { if (n->child == NULL) - return(0); + return 0; parse_mdoc_fname(mpage, n->child); for (n = n->child->next; n != NULL; n = n->next) - if (n->type == MDOC_TEXT) + if (n->type == ROFFT_TEXT) putkey(mpage, n->string, TYPE_Fa); - return(0); + return 0; } static int -parse_mdoc_Fo(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Fo(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { - if (n->type != MDOC_HEAD) - return(1); + if (n->type != ROFFT_HEAD) + return 1; if (n->child != NULL) parse_mdoc_fname(mpage, n->child); - return(0); + return 0; } static int -parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Va(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) +{ + char *cp; + + if (n->type != ROFFT_ELEM && n->type != ROFFT_BODY) + return 0; + + if (n->child != NULL && + n->child->next == NULL && + n->child->type == ROFFT_TEXT) + return 1; + + cp = NULL; + deroff(&cp, n); + if (cp != NULL) { + putkey(mpage, cp, TYPE_Vt | (n->tok == MDOC_Va || + n->type == ROFFT_BODY ? TYPE_Va : 0)); + free(cp); + } + + return 0; +} + +static int +parse_mdoc_Xr(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { char *cp; if (NULL == (n = n->child)) - return(0); + return 0; if (NULL == n->next) { putkey(mpage, n->string, TYPE_Xr); - return(0); + return 0; } mandoc_asprintf(&cp, "%s(%s)", n->string, n->next->string); putkey(mpage, cp, TYPE_Xr); free(cp); - return(0); + return 0; } static int -parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Nd(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { - if (MDOC_BODY == n->type) - mdoc_deroff(&mpage->desc, n); - return(0); + if (n->type == ROFFT_BODY) + deroff(&mpage->desc, n); + return 0; } static int -parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Nm(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { if (SEC_NAME == n->sec) putmdockey(mpage, n->child, NAME_TITLE); - else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) { + else if (n->sec == SEC_SYNOPSIS && n->type == ROFFT_HEAD) { if (n->child == NULL) putkey(mpage, meta->name, NAME_SYN); else @@ -1742,34 +1758,26 @@ parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta, if ( ! (mpage->name_head_done || n->child == NULL || n->child->string == NULL || strcasecmp(n->child->string, meta->title))) { - putkey(mpage, n->child->string, NAME_HEAD); + putkey(mpage, n->child->string, ROFFT_HEAD); mpage->name_head_done = 1; } - return(0); -} - -static int -parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) -{ - - return(SEC_CUSTOM == n->sec && MDOC_HEAD == n->type); + return 0; } static int -parse_mdoc_head(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_Sh(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { - return(MDOC_HEAD == n->type); + return n->sec == SEC_CUSTOM && n->type == ROFFT_HEAD; } static int -parse_mdoc_body(struct mpage *mpage, const struct mdoc_meta *meta, - const struct mdoc_node *n) +parse_mdoc_head(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) { - return(MDOC_BODY == n->type); + return n->type == ROFFT_HEAD; } /* @@ -1874,10 +1882,10 @@ utf8(unsigned int cp, char out[7]) out[4] = (cp >> 6 & 63) | 128; out[5] = (cp & 63) | 128; } else - return(0); + return 0; out[rc] = '\0'; - return(rc); + return rc; } /* @@ -1935,7 +1943,6 @@ render_string(char **public, size_t *psz) case '\\': break; case '\t': - /* FALLTHROUGH */ case ASCII_NBRSP: dst[dsz++] = ' '; scp++; @@ -1966,7 +1973,7 @@ render_string(char **public, size_t *psz) */ if (write_utf8) { - unicode = mchars_spec2cp(mchars, seq, seqlen); + unicode = mchars_spec2cp(seq, seqlen); if (unicode <= 0) continue; addsz = utf8(unicode, utfbuf); @@ -1974,7 +1981,7 @@ render_string(char **public, size_t *psz) continue; addcp = utfbuf; } else { - addcp = mchars_spec2str(mchars, seq, seqlen, &addsz); + addcp = mchars_spec2str(seq, seqlen, &addsz); if (addcp == NULL) continue; if (*addcp == ASCII_NBRSP) { @@ -2001,9 +2008,9 @@ render_string(char **public, size_t *psz) --*psz; if (dst != NULL) { (*public)[*psz] = '\0'; - return(1); + return 1; } else - return(0); + return 0; } static void @@ -2214,7 +2221,7 @@ dbclose(int real) return; case 0: execlp("cmp", "cmp", "-s", - tempfilename, MANDOC_DB, NULL); + tempfilename, MANDOC_DB, (char *)NULL); say("", "&exec cmp"); exit(0); default: @@ -2239,7 +2246,7 @@ dbclose(int real) say("", "&fork rm"); return; case 0: - execlp("rm", "rm", "-rf", tempfilename, NULL); + execlp("rm", "rm", "-rf", tempfilename, (char *)NULL); say("", "&exec rm"); exit((int)MANDOCLEVEL_SYSERR); default: @@ -2270,7 +2277,7 @@ dbopen(int real) int rc, ofl; if (nodb) - return(1); + return 1; *tempfilename = '\0'; ofl = SQLITE_OPEN_READWRITE; @@ -2281,7 +2288,7 @@ dbopen(int real) exitcode = (int)MANDOCLEVEL_SYSERR; if (SQLITE_CANTOPEN != rc) say(MANDOC_DB, "%s", sqlite3_errstr(rc)); - return(0); + return 0; } goto prepare_statements; } @@ -2295,7 +2302,7 @@ dbopen(int real) if (MPARSE_QUICK & mparse_options) { exitcode = (int)MANDOCLEVEL_SYSERR; say(MANDOC_DB "~", "%s", sqlite3_errstr(rc)); - return(0); + return 0; } (void)strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX", @@ -2303,7 +2310,7 @@ dbopen(int real) if (NULL == mkdtemp(tempfilename)) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "&%s", tempfilename); - return(0); + return 0; } (void)strlcat(tempfilename, "/" MANDOC_DB, sizeof(tempfilename)); @@ -2311,7 +2318,7 @@ dbopen(int real) if (SQLITE_OK != rc) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "%s: %s", tempfilename, sqlite3_errstr(rc)); - return(0); + return 0; } create_tables: @@ -2350,7 +2357,7 @@ create_tables: exitcode = (int)MANDOCLEVEL_SYSERR; say(MANDOC_DB, "%s", sqlite3_errmsg(db)); sqlite3_close(db); - return(0); + return 0; } prepare_statements: @@ -2360,7 +2367,7 @@ prepare_statements: say(MANDOC_DB, "PRAGMA foreign_keys: %s", sqlite3_errmsg(db)); sqlite3_close(db); - return(0); + return 0; } sql = "DELETE FROM mpages WHERE pageid IN " @@ -2394,32 +2401,11 @@ prepare_statements: say(MANDOC_DB, "PRAGMA synchronous: %s", sqlite3_errmsg(db)); sqlite3_close(db); - return(0); + return 0; } #endif - return(1); -} - -static void * -hash_calloc(size_t n, size_t sz, void *arg) -{ - - return(mandoc_calloc(n, sz)); -} - -static void * -hash_alloc(size_t sz, void *arg) -{ - - return(mandoc_malloc(sz)); -} - -static void -hash_free(void *p, void *arg) -{ - - free(p); + return 1; } static int @@ -2461,12 +2447,12 @@ set_basedir(const char *targetdir, int report_baddir) if (2 == getcwd_status) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "getcwd: %s", startdir); - return(0); + return 0; } if (-1 == chdir(startdir)) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "&chdir %s", startdir); - return(0); + return 0; } } @@ -2480,13 +2466,13 @@ set_basedir(const char *targetdir, int report_baddir) exitcode = (int)MANDOCLEVEL_BADARG; say("", "&%s: realpath", targetdir); } - return(0); + return 0; } else if (-1 == chdir(basedir)) { if (report_baddir || errno != ENOENT) { exitcode = (int)MANDOCLEVEL_BADARG; say("", "&chdir"); } - return(0); + return 0; } chdir_status = 1; cp = strchr(basedir, '\0'); @@ -2494,12 +2480,12 @@ set_basedir(const char *targetdir, int report_baddir) if (cp - basedir >= PATH_MAX - 1) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "Filename too long"); - return(0); + return 0; } *cp++ = '/'; *cp = '\0'; } - return(1); + return 1; } static void diff --git a/contrib/mdocml/manpage.c b/contrib/mdocml/manpage.c index 999f3d3..45b6e76 100644 --- a/contrib/mdocml/manpage.c +++ b/contrib/mdocml/manpage.c @@ -1,4 +1,4 @@ -/* $Id: manpage.c,v 1.10 2015/02/10 08:05:30 schwarze Exp $ */ +/* $Id: manpage.c,v 1.13 2015/11/07 17:58:55 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org> @@ -28,7 +28,7 @@ #include <string.h> #include <unistd.h> -#include "manpath.h" +#include "manconf.h" #include "mansearch.h" static void show(const char *, const char *); @@ -37,13 +37,14 @@ int main(int argc, char *argv[]) { int ch, term; - size_t i, sz, len; + size_t i, sz, linesz; + ssize_t len; struct mansearch search; struct manpage *res; - char *conf_file, *defpaths, *auxpaths, *cp; + char *conf_file, *defpaths, *auxpaths, *line; char buf[PATH_MAX]; const char *cmd; - struct manpaths paths; + struct manconf conf; char *progname; extern char *optarg; extern int optind; @@ -57,7 +58,7 @@ main(int argc, char *argv[]) ++progname; auxpaths = defpaths = conf_file = NULL; - memset(&paths, 0, sizeof(struct manpaths)); + memset(&conf, 0, sizeof(conf)); memset(&search, 0, sizeof(struct mansearch)); while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:"))) @@ -90,21 +91,21 @@ main(int argc, char *argv[]) search.outkey = "Nd"; search.argmode = ARG_EXPR; - manpath_parse(&paths, conf_file, defpaths, auxpaths); - ch = mansearch(&search, &paths, argc, argv, &res, &sz); - manpath_free(&paths); + manconf_parse(&conf, conf_file, defpaths, auxpaths); + ch = mansearch(&search, &conf.manpath, argc, argv, &res, &sz); + manconf_free(&conf); if (0 == ch) goto usage; if (0 == sz) { free(res); - return(EXIT_FAILURE); + return EXIT_FAILURE; } else if (1 == sz && term) { i = 1; goto show; } else if (NULL == res) - return(EXIT_FAILURE); + return EXIT_FAILURE; for (i = 0; i < sz; i++) { printf("%6zu %s: %s\n", @@ -117,25 +118,29 @@ main(int argc, char *argv[]) for (i = 0; i < sz; i++) free(res[i].file); free(res); - return(EXIT_SUCCESS); + return EXIT_SUCCESS; } i = 1; printf("Enter a choice [1]: "); fflush(stdout); - if (NULL != (cp = fgetln(stdin, &len))) - if ('\n' == cp[--len] && len > 0) { - cp[len] = '\0'; - if ((i = atoi(cp)) < 1 || i > sz) + line = NULL; + linesz = 0; + if ((len = getline(&line, &linesz, stdin)) != -1) { + if ('\n' == line[--len] && len > 0) { + line[len] = '\0'; + if ((i = atoi(line)) < 1 || i > sz) i = 0; } + } + free(line); if (0 == i) { for (i = 0; i < sz; i++) free(res[i].file); free(res); - return(EXIT_SUCCESS); + return EXIT_SUCCESS; } show: cmd = res[i - 1].form ? "mandoc" : "cat"; @@ -154,7 +159,7 @@ usage: "[-s section] " "expr ...\n", progname); - return(EXIT_FAILURE); + return EXIT_FAILURE; } static void diff --git a/contrib/mdocml/manpath.c b/contrib/mdocml/manpath.c index e85175e..0627f13 100644 --- a/contrib/mdocml/manpath.c +++ b/contrib/mdocml/manpath.c @@ -1,15 +1,15 @@ -/* $Id: manpath.c,v 1.19 2014/11/27 00:30:40 schwarze Exp $ */ +/* $Id: manpath.c,v 1.29 2015/11/07 17:58:55 schwarze Exp $ */ /* - * Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -20,24 +20,27 @@ #include <sys/types.h> #include <sys/stat.h> -#include <assert.h> #include <ctype.h> +#if HAVE_ERR +#include <err.h> +#endif #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "mandoc_aux.h" -#include "manpath.h" - -#define MAN_CONF_FILE "/etc/man.conf" -#define MAN_CONF_KEY "_whatdb" +#include "manconf.h" +#if !HAVE_MANPATH +static void manconf_file(struct manconf *, const char *); +#endif static void manpath_add(struct manpaths *, const char *, int); static void manpath_parseline(struct manpaths *, char *, int); + void -manpath_parse(struct manpaths *dirs, const char *file, +manconf_parse(struct manconf *conf, const char *file, char *defp, char *auxp) { #if HAVE_MANPATH @@ -80,7 +83,7 @@ manpath_parse(struct manpaths *dirs, const char *file, if ( ! ferror(stream) && feof(stream) && bsz && '\n' == buf[bsz - 1]) { buf[bsz - 1] = '\0'; - manpath_parseline(dirs, buf, 1); + manpath_parseline(&conf->manpath, buf, 1); } free(buf); @@ -89,11 +92,11 @@ manpath_parse(struct manpaths *dirs, const char *file, char *insert; /* Always prepend -m. */ - manpath_parseline(dirs, auxp, 1); + manpath_parseline(&conf->manpath, auxp, 1); /* If -M is given, it overrides everything else. */ if (NULL != defp) { - manpath_parseline(dirs, defp, 1); + manpath_parseline(&conf->manpath, defp, 1); return; } @@ -104,21 +107,21 @@ manpath_parse(struct manpaths *dirs, const char *file, /* No MANPATH; use man.conf(5) only. */ if (NULL == defp || '\0' == defp[0]) { - manpath_manconf(dirs, file); + manconf_file(conf, file); return; } /* Prepend man.conf(5) to MANPATH. */ if (':' == defp[0]) { - manpath_manconf(dirs, file); - manpath_parseline(dirs, defp, 0); + manconf_file(conf, file); + manpath_parseline(&conf->manpath, defp, 0); return; } /* Append man.conf(5) to MANPATH. */ if (':' == defp[strlen(defp) - 1]) { - manpath_parseline(dirs, defp, 0); - manpath_manconf(dirs, file); + manpath_parseline(&conf->manpath, defp, 0); + manconf_file(conf, file); return; } @@ -126,14 +129,14 @@ manpath_parse(struct manpaths *dirs, const char *file, insert = strstr(defp, "::"); if (NULL != insert) { *insert++ = '\0'; - manpath_parseline(dirs, defp, 0); - manpath_manconf(dirs, file); - manpath_parseline(dirs, insert + 1, 0); + manpath_parseline(&conf->manpath, defp, 0); + manconf_file(conf, file); + manpath_parseline(&conf->manpath, insert + 1, 0); return; } /* MANPATH overrides man.conf(5) completely. */ - manpath_parseline(dirs, defp, 0); + manpath_parseline(&conf->manpath, defp, 0); #endif } @@ -165,10 +168,8 @@ manpath_add(struct manpaths *dirs, const char *dir, int complain) size_t i; if (NULL == (cp = realpath(dir, buf))) { - if (complain) { - fputs("manpath: ", stderr); - perror(dir); - } + if (complain) + warn("manpath: %s", dir); return; } @@ -177,10 +178,8 @@ manpath_add(struct manpaths *dirs, const char *dir, int complain) return; if (stat(cp, &sb) == -1) { - if (complain) { - fputs("manpath: ", stderr); - perror(dir); - } + if (complain) + warn("manpath: %s", dir); return; } @@ -191,47 +190,147 @@ manpath_add(struct manpaths *dirs, const char *dir, int complain) } void -manpath_free(struct manpaths *p) +manconf_free(struct manconf *conf) { size_t i; - for (i = 0; i < p->sz; i++) - free(p->paths[i]); + for (i = 0; i < conf->manpath.sz; i++) + free(conf->manpath.paths[i]); - free(p->paths); + free(conf->manpath.paths); + free(conf->output.includes); + free(conf->output.man); + free(conf->output.paper); + free(conf->output.style); } -void -manpath_manconf(struct manpaths *dirs, const char *file) +#if !HAVE_MANPATH +static void +manconf_file(struct manconf *conf, const char *file) { + const char *const toks[] = { "manpath", "output", "_whatdb" }; + char manpath_default[] = MANPATH_DEFAULT; + FILE *stream; - char *p, *q; - size_t len, keysz; + char *line, *cp, *ep; + size_t linesz, tok, toklen; + ssize_t linelen; - keysz = strlen(MAN_CONF_KEY); - assert(keysz > 0); + if ((stream = fopen(file, "r")) == NULL) + goto out; - if (NULL == (stream = fopen(file, "r"))) - return; + line = NULL; + linesz = 0; - while (NULL != (p = fgetln(stream, &len))) { - if (0 == len || '\n' != p[--len]) + while ((linelen = getline(&line, &linesz, stream)) != -1) { + cp = line; + ep = cp + linelen; + if (ep[-1] != '\n') break; - p[len] = '\0'; - while (isspace((unsigned char)*p)) - p++; - if (strncmp(MAN_CONF_KEY, p, keysz)) - continue; - p += keysz; - while (isspace((unsigned char)*p)) - p++; - if ('\0' == *p) + *--ep = '\0'; + while (isspace((unsigned char)*cp)) + cp++; + if (*cp == '#') continue; - if (NULL == (q = strrchr(p, '/'))) - continue; - *q = '\0'; - manpath_add(dirs, p, 0); - } + for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) { + toklen = strlen(toks[tok]); + if (cp + toklen < ep && + isspace((unsigned char)cp[toklen]) && + strncmp(cp, toks[tok], toklen) == 0) { + cp += toklen; + while (isspace((unsigned char)*cp)) + cp++; + break; + } + } + + switch (tok) { + case 2: /* _whatdb */ + while (ep > cp && ep[-1] != '/') + ep--; + if (ep == cp) + continue; + *ep = '\0'; + /* FALLTHROUGH */ + case 0: /* manpath */ + manpath_add(&conf->manpath, cp, 0); + *manpath_default = '\0'; + break; + case 1: /* output */ + manconf_output(&conf->output, cp); + break; + default: + break; + } + } + free(line); fclose(stream); + +out: + if (*manpath_default != '\0') + manpath_parseline(&conf->manpath, manpath_default, 0); +} +#endif + +void +manconf_output(struct manoutput *conf, const char *cp) +{ + const char *const toks[] = { + "includes", "man", "paper", "style", + "indent", "width", "fragment", "mdoc" + }; + + size_t len, tok; + + for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) { + len = strlen(toks[tok]); + if ( ! strncmp(cp, toks[tok], len) && + strchr(" = ", cp[len]) != NULL) { + cp += len; + if (*cp == '=') + cp++; + while (isspace((unsigned char)*cp)) + cp++; + break; + } + } + + if (tok < 6 && *cp == '\0') + return; + + switch (tok) { + case 0: + if (conf->includes == NULL) + conf->includes = mandoc_strdup(cp); + break; + case 1: + if (conf->man == NULL) + conf->man = mandoc_strdup(cp); + break; + case 2: + if (conf->paper == NULL) + conf->paper = mandoc_strdup(cp); + break; + case 3: + if (conf->style == NULL) + conf->style = mandoc_strdup(cp); + break; + case 4: + if (conf->indent == 0) + conf->indent = strtonum(cp, 0, 1000, NULL); + break; + case 5: + if (conf->width == 0) + conf->width = strtonum(cp, 58, 1000, NULL); + break; + case 6: + conf->fragment = 1; + break; + case 7: + conf->mdoc = 1; + break; + default: + break; + } } diff --git a/contrib/mdocml/mansearch.3 b/contrib/mdocml/mansearch.3 index f41e361..051f9aa 100644 --- a/contrib/mdocml/mansearch.3 +++ b/contrib/mdocml/mansearch.3 @@ -1,4 +1,4 @@ -.\" $Id: mansearch.3,v 1.3 2014/12/12 21:44:33 schwarze Exp $ +.\" $Id: mansearch.3,v 1.4 2015/03/27 17:37:25 schwarze Exp $ .\" .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 12 2014 $ +.Dd $Mdocdate: March 27 2015 $ .Dt MANSEARCH 3 .Os .Sh NAME @@ -23,7 +23,7 @@ .Nd search manual page databases .Sh SYNOPSIS .In stdint.h -.In manpath.h +.In manconf.h .In mansearch.h .Ft int .Fo mansearch_setup @@ -53,7 +53,7 @@ Search options, defined in .In mansearch.h . .It Fa "const struct manpaths *paths" Directories to be searched, defined in -.In manpath.h . +.In manconf.h . .It Fa "int argc" , "char *argv[]" Search criteria, usually taken from the command line. .El diff --git a/contrib/mdocml/mansearch.c b/contrib/mdocml/mansearch.c index 05e2a0a..843326b 100644 --- a/contrib/mdocml/mansearch.c +++ b/contrib/mdocml/mansearch.c @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.55 2015/03/11 13:11:22 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.64 2016/01/08 15:02:54 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -21,6 +21,9 @@ #include <sys/types.h> #include <assert.h> +#if HAVE_ERR +#include <err.h> +#endif #include <errno.h> #include <fcntl.h> #include <getopt.h> @@ -34,11 +37,6 @@ #include <string.h> #include <unistd.h> -#if HAVE_OHASH -#include <ohash.h> -#else -#include "compat_ohash.h" -#endif #include <sqlite3.h> #ifndef SQLITE_DETERMINISTIC #define SQLITE_DETERMINISTIC 0 @@ -46,7 +44,8 @@ #include "mandoc.h" #include "mandoc_aux.h" -#include "manpath.h" +#include "mandoc_ohash.h" +#include "manconf.h" #include "mansearch.h" extern int mansearch_keymax; @@ -55,17 +54,17 @@ extern const char *const mansearch_keynames[]; #define SQL_BIND_TEXT(_db, _s, _i, _v) \ do { if (SQLITE_OK != sqlite3_bind_text \ ((_s), (_i)++, (_v), -1, SQLITE_STATIC)) \ - fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \ + errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \ } while (0) #define SQL_BIND_INT64(_db, _s, _i, _v) \ do { if (SQLITE_OK != sqlite3_bind_int64 \ ((_s), (_i)++, (_v))) \ - fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \ + errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \ } while (0) #define SQL_BIND_BLOB(_db, _s, _i, _v) \ do { if (SQLITE_OK != sqlite3_bind_blob \ ((_s), (_i)++, (&_v), sizeof(_v), SQLITE_STATIC)) \ - fprintf(stderr, "%s\n", sqlite3_errmsg((_db))); \ + errx((int)MANDOCLEVEL_SYSERR, "%s", sqlite3_errmsg((_db))); \ } while (0) struct expr { @@ -92,9 +91,6 @@ static void buildnames(const struct mansearch *, const char *, int form); static char *buildoutput(sqlite3 *, sqlite3_stmt *, uint64_t, uint64_t); -static void *hash_alloc(size_t, void *); -static void hash_free(void *, void *); -static void *hash_calloc(size_t, size_t, void *); static struct expr *exprcomp(const struct mansearch *, int, char *[]); static void exprfree(struct expr *); @@ -120,8 +116,8 @@ mansearch_setup(int start) if (start) { if (NULL != pagecache) { - fprintf(stderr, "pagecache already enabled\n"); - return((int)MANDOCLEVEL_BADARG); + warnx("pagecache already enabled"); + return (int)MANDOCLEVEL_BADARG; } pagecache = mmap(NULL, PC_PAGESIZE * PC_NUMPAGES, @@ -129,32 +125,32 @@ mansearch_setup(int start) MAP_SHARED | MAP_ANON, -1, 0); if (MAP_FAILED == pagecache) { - perror("mmap"); + warn("mmap"); pagecache = NULL; - return((int)MANDOCLEVEL_SYSERR); + return (int)MANDOCLEVEL_SYSERR; } c = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pagecache, PC_PAGESIZE, PC_NUMPAGES); if (SQLITE_OK == c) - return((int)MANDOCLEVEL_OK); + return (int)MANDOCLEVEL_OK; - fprintf(stderr, "pagecache: %s\n", sqlite3_errstr(c)); + warnx("pagecache: %s", sqlite3_errstr(c)); } else if (NULL == pagecache) { - fprintf(stderr, "pagecache missing\n"); - return((int)MANDOCLEVEL_BADARG); + warnx("pagecache missing"); + return (int)MANDOCLEVEL_BADARG; } if (-1 == munmap(pagecache, PC_PAGESIZE * PC_NUMPAGES)) { - perror("munmap"); + warn("munmap"); pagecache = NULL; - return((int)MANDOCLEVEL_SYSERR); + return (int)MANDOCLEVEL_SYSERR; } pagecache = NULL; - return((int)MANDOCLEVEL_OK); + return (int)MANDOCLEVEL_OK; } int @@ -163,7 +159,6 @@ mansearch(const struct mansearch *search, int argc, char *argv[], struct manpage **res, size_t *sz) { - int fd, rc, c, indexbit; int64_t pageid; uint64_t outbit, iterbit; char buf[PATH_MAX]; @@ -173,27 +168,18 @@ mansearch(const struct mansearch *search, sqlite3 *db; sqlite3_stmt *s, *s2; struct match *mp; - struct ohash_info info; struct ohash htab; unsigned int idx; size_t i, j, cur, maxres; + int c, chdir_status, getcwd_status, indexbit; - info.calloc = hash_calloc; - info.alloc = hash_alloc; - info.free = hash_free; - info.key_offset = offsetof(struct match, pageid); + if (argc == 0 || (e = exprcomp(search, argc, argv)) == NULL) { + *sz = 0; + return 0; + } - *sz = cur = maxres = 0; - sql = NULL; + cur = maxres = 0; *res = NULL; - fd = -1; - e = NULL; - rc = 0; - - if (0 == argc) - goto out; - if (NULL == (e = exprcomp(search, argc, argv))) - goto out; if (NULL != search->outkey) { outbit = TYPE_Nd; @@ -210,19 +196,18 @@ mansearch(const struct mansearch *search, outbit = 0; /* - * Save a descriptor to the current working directory. - * Since pathnames in the "paths" variable might be relative, - * and we'll be chdir()ing into them, we need to keep a handle - * on our current directory from which to start the chdir(). + * Remember the original working directory, if possible. + * This will be needed if the second or a later directory + * is given as a relative path. + * Do not error out if the current directory is not + * searchable: Maybe it won't be needed after all. */ - if (NULL == getcwd(buf, PATH_MAX)) { - perror("getcwd"); - goto out; - } else if (-1 == (fd = open(buf, O_RDONLY, 0))) { - perror(buf); - goto out; - } + if (getcwd(buf, PATH_MAX) == NULL) { + getcwd_status = 0; + (void)strlcpy(buf, strerror(errno), sizeof(buf)); + } else + getcwd_status = 1; sql = sql_statement(e); @@ -234,22 +219,28 @@ mansearch(const struct mansearch *search, * scan it for our match expression. */ + chdir_status = 0; for (i = 0; i < paths->sz; i++) { - if (-1 == fchdir(fd)) { - perror(buf); - free(*res); - break; - } else if (-1 == chdir(paths->paths[i])) { - perror(paths->paths[i]); + if (chdir_status && paths->paths[i][0] != '/') { + if ( ! getcwd_status) { + warnx("%s: getcwd: %s", paths->paths[i], buf); + continue; + } else if (chdir(buf) == -1) { + warn("%s", buf); + continue; + } + } + if (chdir(paths->paths[i]) == -1) { + warn("%s", paths->paths[i]); continue; } + chdir_status = 1; c = sqlite3_open_v2(MANDOC_DB, &db, SQLITE_OPEN_READONLY, NULL); if (SQLITE_OK != c) { - fprintf(stderr, "%s/%s: %s\n", - paths->paths[i], MANDOC_DB, strerror(errno)); + warn("%s/%s", paths->paths[i], MANDOC_DB); sqlite3_close(db); continue; } @@ -271,7 +262,8 @@ mansearch(const struct mansearch *search, j = 1; c = sqlite3_prepare_v2(db, sql, -1, &s, NULL); if (SQLITE_OK != c) - fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + errx((int)MANDOCLEVEL_SYSERR, + "%s", sqlite3_errmsg(db)); for (ep = e; NULL != ep; ep = ep->next) { if (NULL == ep->substr) { @@ -282,8 +274,7 @@ mansearch(const struct mansearch *search, SQL_BIND_INT64(db, s, j, ep->bits); } - memset(&htab, 0, sizeof(struct ohash)); - ohash_init(&htab, 4, &info); + mandoc_ohash_init(&htab, 4, offsetof(struct match, pageid)); /* * Hash each entry on its [unique] document identifier. @@ -313,7 +304,7 @@ mansearch(const struct mansearch *search, } if (SQLITE_DONE != c) - fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + warnx("%s", sqlite3_errmsg(db)); sqlite3_finalize(s); @@ -322,14 +313,16 @@ mansearch(const struct mansearch *search, "WHERE pageid=? ORDER BY sec, arch, name", -1, &s, NULL); if (SQLITE_OK != c) - fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + errx((int)MANDOCLEVEL_SYSERR, + "%s", sqlite3_errmsg(db)); c = sqlite3_prepare_v2(db, "SELECT bits, key, pageid FROM keys " "WHERE pageid=? AND bits & ?", -1, &s2, NULL); if (SQLITE_OK != c) - fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + errx((int)MANDOCLEVEL_SYSERR, + "%s", sqlite3_errmsg(db)); for (mp = ohash_first(&htab, &idx); NULL != mp; @@ -370,17 +363,12 @@ mansearch(const struct mansearch *search, break; } qsort(*res, cur, sizeof(struct manpage), manpage_compare); - rc = 1; -out: - if (-1 != fd) { - if (-1 == fchdir(fd)) - perror(buf); - close(fd); - } + if (chdir_status && getcwd_status && chdir(buf) == -1) + warn("%s", buf); exprfree(e); free(sql); *sz = cur; - return(rc); + return 1; } void @@ -404,9 +392,9 @@ manpage_compare(const void *vp1, const void *vp2) mp1 = vp1; mp2 = vp2; - return( (diff = mp2->bits - mp1->bits) ? diff : - (diff = mp1->sec - mp2->sec) ? diff : - strcasecmp(mp1->names, mp2->names)); + return (diff = mp2->bits - mp1->bits) ? diff : + (diff = mp1->sec - mp2->sec) ? diff : + strcasecmp(mp1->names, mp2->names); } static void @@ -515,7 +503,7 @@ buildnames(const struct mansearch *search, struct manpage *mpage, globfree(&globinfo); } if (c != SQLITE_DONE) - fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + warnx("%s", sqlite3_errmsg(db)); sqlite3_reset(s); /* If none of the files is usable, use the first name. */ @@ -565,9 +553,9 @@ buildoutput(sqlite3 *db, sqlite3_stmt *s, uint64_t pageid, uint64_t outbit) output = newoutput; } if (SQLITE_DONE != c) - fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + warnx("%s", sqlite3_errmsg(db)); sqlite3_reset(s); - return(output); + return output; } /* @@ -662,7 +650,7 @@ sql_statement(const struct expr *e) needop = 1; } - return(sql); + return sql; } /* @@ -745,12 +733,12 @@ exprcomp(const struct mansearch *search, int argc, char *argv[]) toopen = logic = igncase = 0; } if ( ! (toopen || logic || igncase || toclose)) - return(first); + return first; fail: if (NULL != first) exprfree(first); - return(NULL); + return NULL; } static struct expr * @@ -763,7 +751,7 @@ exprterm(const struct mansearch *search, char *buf, int cs) int i, irc; if ('\0' == *buf) - return(NULL); + return NULL; e = mandoc_calloc(1, sizeof(struct expr)); @@ -771,7 +759,7 @@ exprterm(const struct mansearch *search, char *buf, int cs) e->bits = TYPE_Nm; e->substr = buf; e->equal = 1; - return(e); + return e; } /* @@ -783,7 +771,14 @@ exprterm(const struct mansearch *search, char *buf, int cs) if (search->argmode == ARG_WORD) { e->bits = TYPE_Nm; e->substr = NULL; +#if HAVE_REWB_BSD mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf); +#elif HAVE_REWB_SYSV + mandoc_asprintf(&val, "\\<%s\\>", buf); +#else + mandoc_asprintf(&val, + "(^|[^a-zA-Z01-9_])%s([^a-zA-Z01-9_]|$)", buf); +#endif cs = 0; } else if ((val = strpbrk(buf, "=~")) == NULL) { e->bits = TYPE_Nm | TYPE_Nd; @@ -807,14 +802,14 @@ exprterm(const struct mansearch *search, char *buf, int cs) free(val); if (irc) { regerror(irc, &e->regexp, errbuf, sizeof(errbuf)); - fprintf(stderr, "regcomp: %s\n", errbuf); + warnx("regcomp: %s", errbuf); free(e); - return(NULL); + return NULL; } } if (e->bits) - return(e); + return e; /* * Parse out all possible fields. @@ -836,13 +831,13 @@ exprterm(const struct mansearch *search, char *buf, int cs) if (i == mansearch_keymax) { if (strcasecmp(key, "any")) { free(e); - return(NULL); + return NULL; } e->bits |= ~0ULL; } } - return(e); + return e; } static void @@ -856,24 +851,3 @@ exprfree(struct expr *p) p = pp; } } - -static void * -hash_calloc(size_t nmemb, size_t sz, void *arg) -{ - - return(mandoc_calloc(nmemb, sz)); -} - -static void * -hash_alloc(size_t sz, void *arg) -{ - - return(mandoc_malloc(sz)); -} - -static void -hash_free(void *p, void *arg) -{ - - free(p); -} diff --git a/contrib/mdocml/mansearch.h b/contrib/mdocml/mansearch.h index 14ec8ce..7f68ff6 100644 --- a/contrib/mdocml/mansearch.h +++ b/contrib/mdocml/mansearch.h @@ -1,4 +1,4 @@ -/* $Id: mansearch.h,v 1.23 2014/12/01 08:05:52 schwarze Exp $ */ +/* $Id: mansearch.h,v 1.24 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -95,7 +95,6 @@ struct mansearch { int firstmatch; /* first matching database only */ }; -__BEGIN_DECLS struct manpaths; @@ -107,5 +106,3 @@ int mansearch(const struct mansearch *cfg, /* options */ struct manpage **res, /* results */ size_t *ressz); /* results returned */ void mansearch_free(struct manpage *, size_t); - -__END_DECLS diff --git a/contrib/mdocml/mchars_alloc.3 b/contrib/mdocml/mchars_alloc.3 index eba81b5..2d42a43 100644 --- a/contrib/mdocml/mchars_alloc.3 +++ b/contrib/mdocml/mchars_alloc.3 @@ -1,4 +1,4 @@ -.\" $Id: mchars_alloc.3,v 1.2 2014/10/26 18:07:28 schwarze Exp $ +.\" $Id: mchars_alloc.3,v 1.3 2015/10/13 22:59:54 schwarze Exp $ .\" .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 26 2014 $ +.Dd $Mdocdate: October 13 2015 $ .Dt MCHARS_ALLOC 3 .Os .Sh NAME @@ -25,17 +25,13 @@ .Nm mchars_spec2cp , .Nm mchars_spec2str .Nd character table for mandoc -.Sh LIBRARY -.Lb libmandoc .Sh SYNOPSIS .In sys/types.h .In mandoc.h -.Ft "struct mchars *" -.Fn mchars_alloc "void" .Ft void -.Fo mchars_free -.Fa "struct mchars *table" -.Fc +.Fn mchars_alloc void +.Ft void +.Fn mchars_free void .Ft char .Fo mchars_num2char .Fa "const char *decimal" @@ -48,13 +44,11 @@ .Fc .Ft int .Fo mchars_spec2cp -.Fa "const struct mchars *table" .Fa "const char *name" .Fa "size_t sz" .Fc .Ft "const char *" .Fo mchars_spec2str -.Fa "const struct mchars *table" .Fa "const char *name" .Fa "size_t sz" .Fa "size_t *rsz" @@ -135,9 +129,9 @@ escape sequences. .Pp The function .Fn mchars_alloc -allocates an opaque -.Vt "struct mchars *" -table object for subsequent use by the following two lookup functions. +initializes a static +.Vt "struct ohash" +object for subsequent use by the following two lookup functions. When no longer needed, this object can be destroyed with .Fn mchars_free . .Pp @@ -149,9 +143,7 @@ special character .Fa name consisting of .Fa sz -characters in the -.Fa table -and returns the corresponding Unicode codepoint. +characters and returns the corresponding Unicode codepoint. If the .Ar name is not recognized, \-1 is returned. @@ -175,9 +167,7 @@ special character .Fa name consisting of .Fa sz -characters in the -.Fa table -and returns an ASCII string representation. +characters and returns an ASCII string representation. The length of the representation is returned in .Fa rsz . In many cases, the meaning of such ASCII representations @@ -215,6 +205,7 @@ These funtions are implemented in the file .Sh SEE ALSO .Xr mandoc 1 , .Xr mandoc_escape 3 , +.Xr ohash_init 3 , .Xr mandoc_char 7 , .Xr roff 7 .Sh HISTORY diff --git a/contrib/mdocml/mdoc.7 b/contrib/mdocml/mdoc.7 index d4c8ccd..198a46a 100644 --- a/contrib/mdocml/mdoc.7 +++ b/contrib/mdocml/mdoc.7 @@ -1,4 +1,4 @@ -.\" $Id: mdoc.7,v 1.252 2015/02/23 13:31:04 schwarze Exp $ +.\" $Id: mdoc.7,v 1.257 2015/11/05 12:06:45 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2010, 2011, 2013 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: February 23 2015 $ +.Dd $Mdocdate: November 5 2015 $ .Dt MDOC 7 .Os .Sh NAME @@ -304,6 +304,11 @@ Print verbose information. \&.El .Ed .Pp +List the options in alphabetical order, +uppercase before lowercase for each letter and +with no regard to whether an option takes an argument. +Put digits in ascending order before all letter options. +.Pp Manuals not documenting a command won't include the above fragment. .Pp Since the @@ -1622,7 +1627,7 @@ See also A function name. Its syntax is as follows: .Bd -ragged -offset indent -.Pf \. Ns Sx \&Fn +.Pf . Sx \&Fn .Op Ar functype .Ar funcname .Op Oo Ar argtype Oc Ar argname @@ -2093,7 +2098,7 @@ It is suggested to leave it unspecified, in which case .Xr mandoc 1 uses its .Fl Ios -argument, or, if that isn't specified either, +argument or, if that isn't specified either, .Fa sysname and .Fa release @@ -2155,19 +2160,23 @@ See also Close parenthesised context opened by .Sx \&Po . .Ss \&Pf -Removes the space between its argument -.Pq Dq prefix -and the following macro. +Removes the space between its argument and the following macro. Its syntax is as follows: .Pp .D1 .Pf Ar prefix macro arguments ... .Pp This is equivalent to: .Pp -.D1 .No Ar prefix No \&Ns Ar macro arguments ... +.D1 .No \e& Ns Ar prefix No \&Ns Ar macro arguments ... +.Pp +The +.Ar prefix +argument is not parsed for macro names or delimiters, +but used verbatim as if it were escaped. .Pp Examples: .Dl ".Pf $ Ar variable_name" +.Dl ".Pf . Ar macro_name" .Dl ".Pf 0x Ar hex_digits" .Pp See also @@ -2267,7 +2276,7 @@ Examples: \&.%A J. D. Ullman \&.%B Introduction to Automata Theory, Languages, and Computation \&.%I Addison-Wesley -\&.%C Reading, Massachusettes +\&.%C Reading, Massachusetts \&.%D 1979 \&.Re .Ed diff --git a/contrib/mdocml/mdoc.c b/contrib/mdocml/mdoc.c index 027ecbe..724d45c 100644 --- a/contrib/mdocml/mdoc.c +++ b/contrib/mdocml/mdoc.c @@ -1,4 +1,4 @@ -/* $Id: mdoc.c,v 1.238 2015/02/12 13:00:52 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.256 2015/10/30 19:04:16 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -27,13 +27,16 @@ #include <string.h> #include <time.h> -#include "mdoc.h" -#include "mandoc.h" #include "mandoc_aux.h" -#include "libmdoc.h" +#include "mandoc.h" +#include "roff.h" +#include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" +#include "libmdoc.h" const char *const __mdoc_macronames[MDOC_MAX + 1] = { + "text", "Ap", "Dd", "Dt", "Os", "Sh", "Ss", "Pp", "D1", "Dl", "Bd", "Ed", "Bl", @@ -64,8 +67,8 @@ const char *const __mdoc_macronames[MDOC_MAX + 1] = { "Lk", "Mt", "Brq", "Bro", "Brc", "%C", "Es", "En", "Dx", "%Q", "br", "sp", - "%U", "Ta", "ll", "text", - }; + "%U", "Ta", "ll", +}; const char *const __mdoc_argnames[MDOC_ARG_MAX] = { "split", "nosplit", "ragged", @@ -79,157 +82,22 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = { "symbolic", "nested", "centered" }; -const char * const *mdoc_macronames = __mdoc_macronames; +const char * const *mdoc_macronames = __mdoc_macronames + 1; const char * const *mdoc_argnames = __mdoc_argnames; -static void mdoc_node_free(struct mdoc_node *); -static void mdoc_node_unlink(struct mdoc *, - struct mdoc_node *); -static void mdoc_free1(struct mdoc *); -static void mdoc_alloc1(struct mdoc *); -static struct mdoc_node *node_alloc(struct mdoc *, int, int, - enum mdoct, enum mdoc_type); -static void node_append(struct mdoc *, struct mdoc_node *); -static int mdoc_ptext(struct mdoc *, int, char *, int); -static int mdoc_pmacro(struct mdoc *, int, char *, int); - - -const struct mdoc_node * -mdoc_node(const struct mdoc *mdoc) -{ - - return(mdoc->first); -} - -const struct mdoc_meta * -mdoc_meta(const struct mdoc *mdoc) -{ - - return(&mdoc->meta); -} - -/* - * Frees volatile resources (parse tree, meta-data, fields). - */ -static void -mdoc_free1(struct mdoc *mdoc) -{ - - if (mdoc->first) - mdoc_node_delete(mdoc, mdoc->first); - free(mdoc->meta.msec); - free(mdoc->meta.vol); - free(mdoc->meta.arch); - free(mdoc->meta.date); - free(mdoc->meta.title); - free(mdoc->meta.os); - free(mdoc->meta.name); -} - -/* - * Allocate all volatile resources (parse tree, meta-data, fields). - */ -static void -mdoc_alloc1(struct mdoc *mdoc) -{ - - memset(&mdoc->meta, 0, sizeof(struct mdoc_meta)); - mdoc->flags = 0; - mdoc->lastnamed = mdoc->lastsec = SEC_NONE; - mdoc->last = mandoc_calloc(1, sizeof(struct mdoc_node)); - mdoc->first = mdoc->last; - mdoc->last->type = MDOC_ROOT; - mdoc->last->tok = MDOC_MAX; - mdoc->next = MDOC_NEXT_CHILD; -} - -/* - * Free up volatile resources (see mdoc_free1()) then re-initialises the - * data with mdoc_alloc1(). After invocation, parse data has been reset - * and the parser is ready for re-invocation on a new tree; however, - * cross-parse non-volatile data is kept intact. - */ -void -mdoc_reset(struct mdoc *mdoc) -{ - - mdoc_free1(mdoc); - mdoc_alloc1(mdoc); -} - -/* - * Completely free up all volatile and non-volatile parse resources. - * After invocation, the pointer is no longer usable. - */ -void -mdoc_free(struct mdoc *mdoc) -{ - - mdoc_free1(mdoc); - free(mdoc); -} - -/* - * Allocate volatile and non-volatile parse resources. - */ -struct mdoc * -mdoc_alloc(struct roff *roff, struct mparse *parse, - const char *defos, int quick) -{ - struct mdoc *p; - - p = mandoc_calloc(1, sizeof(struct mdoc)); - - p->parse = parse; - p->defos = defos; - p->quick = quick; - p->roff = roff; - - mdoc_hash_init(); - mdoc_alloc1(p); - return(p); -} - -void -mdoc_endparse(struct mdoc *mdoc) -{ - - mdoc_macroend(mdoc); -} - -void -mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep) -{ - struct mdoc_node *n; - - n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN); - n->eqn = ep; - if (ep->ln > mdoc->last->line) - n->flags |= MDOC_LINE; - node_append(mdoc, n); - mdoc->next = MDOC_NEXT_SIBLING; -} +static int mdoc_ptext(struct roff_man *, int, char *, int); +static int mdoc_pmacro(struct roff_man *, int, char *, int); -void -mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp) -{ - struct mdoc_node *n; - - n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL); - n->span = sp; - node_append(mdoc, n); - mdoc->next = MDOC_NEXT_SIBLING; -} /* * Main parse routine. Parses a single line -- really just hands off to * the macro (mdoc_pmacro()) or text parser (mdoc_ptext()). */ int -mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs) +mdoc_parseln(struct roff_man *mdoc, int ln, char *buf, int offs) { - if (mdoc->last->type != MDOC_EQN || ln > mdoc->last->line) + if (mdoc->last->type != ROFFT_EQN || ln > mdoc->last->line) mdoc->flags |= MDOC_NEWLINE; /* @@ -243,231 +111,80 @@ mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs) else mdoc->flags &= ~MDOC_SYNOPSIS; - return(roff_getcontrol(mdoc->roff, buf, &offs) ? + return roff_getcontrol(mdoc->roff, buf, &offs) ? mdoc_pmacro(mdoc, ln, buf, offs) : - mdoc_ptext(mdoc, ln, buf, offs)); + mdoc_ptext(mdoc, ln, buf, offs); } void mdoc_macro(MACRO_PROT_ARGS) { - assert(tok < MDOC_MAX); - - if (mdoc->flags & MDOC_PBODY) { - if (tok == MDOC_Dt) { - mandoc_vmsg(MANDOCERR_DT_LATE, - mdoc->parse, line, ppos, - "Dt %s", buf + *pos); - return; - } - } else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) { - if (mdoc->meta.title == NULL) { - mandoc_vmsg(MANDOCERR_DT_NOTITLE, - mdoc->parse, line, ppos, "%s %s", - mdoc_macronames[tok], buf + *pos); - mdoc->meta.title = mandoc_strdup("UNTITLED"); - } - if (NULL == mdoc->meta.vol) - mdoc->meta.vol = mandoc_strdup("LOCAL"); - mdoc->flags |= MDOC_PBODY; - } - (*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf); -} - - -static void -node_append(struct mdoc *mdoc, struct mdoc_node *p) -{ - - assert(mdoc->last); - assert(mdoc->first); - assert(MDOC_ROOT != p->type); - - switch (mdoc->next) { - case MDOC_NEXT_SIBLING: - mdoc->last->next = p; - p->prev = mdoc->last; - p->parent = mdoc->last->parent; - break; - case MDOC_NEXT_CHILD: - mdoc->last->child = p; - p->parent = mdoc->last; - break; - default: - abort(); - /* NOTREACHED */ - } - - p->parent->nchild++; - - /* - * Copy over the normalised-data pointer of our parent. Not - * everybody has one, but copying a null pointer is fine. - */ - - switch (p->type) { - case MDOC_BODY: - if (ENDBODY_NOT != p->end) - break; - /* FALLTHROUGH */ - case MDOC_TAIL: - /* FALLTHROUGH */ - case MDOC_HEAD: - p->norm = p->parent->norm; - break; - default: - break; - } - - mdoc_valid_pre(mdoc, p); + assert(tok > TOKEN_NONE && tok < MDOC_MAX); - switch (p->type) { - case MDOC_HEAD: - assert(MDOC_BLOCK == p->parent->type); - p->parent->head = p; - break; - case MDOC_TAIL: - assert(MDOC_BLOCK == p->parent->type); - p->parent->tail = p; - break; - case MDOC_BODY: - if (p->end) - break; - assert(MDOC_BLOCK == p->parent->type); - p->parent->body = p; - break; - default: - break; - } - - mdoc->last = p; - - switch (p->type) { - case MDOC_TBL: - /* FALLTHROUGH */ - case MDOC_TEXT: - mdoc_valid_post(mdoc); - break; - default: - break; - } -} - -static struct mdoc_node * -node_alloc(struct mdoc *mdoc, int line, int pos, - enum mdoct tok, enum mdoc_type type) -{ - struct mdoc_node *p; - - p = mandoc_calloc(1, sizeof(struct mdoc_node)); - p->sec = mdoc->lastsec; - p->line = line; - p->pos = pos; - p->tok = tok; - p->type = type; - - /* Flag analysis. */ - - if (MDOC_SYNOPSIS & mdoc->flags) - p->flags |= MDOC_SYNPRETTY; - else - p->flags &= ~MDOC_SYNPRETTY; - if (MDOC_NEWLINE & mdoc->flags) - p->flags |= MDOC_LINE; - mdoc->flags &= ~MDOC_NEWLINE; - - return(p); + (*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf); } void -mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok) +mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, int tok) { - struct mdoc_node *p; + struct roff_node *p; - p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL); - node_append(mdoc, p); - mdoc->next = MDOC_NEXT_CHILD; + p = roff_node_alloc(mdoc, line, pos, ROFFT_TAIL, tok); + roff_node_append(mdoc, p); + mdoc->next = ROFF_NEXT_CHILD; } -struct mdoc_node * -mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok) +struct roff_node * +mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok, + struct roff_node *body, enum mdoc_endbody end) { - struct mdoc_node *p; - - assert(mdoc->first); - assert(mdoc->last); - p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD); - node_append(mdoc, p); - mdoc->next = MDOC_NEXT_CHILD; - return(p); -} - -struct mdoc_node * -mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok) -{ - struct mdoc_node *p; - - p = node_alloc(mdoc, line, pos, tok, MDOC_BODY); - node_append(mdoc, p); - mdoc->next = MDOC_NEXT_CHILD; - return(p); -} - -struct mdoc_node * -mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok, - struct mdoc_node *body, enum mdoc_endbody end) -{ - struct mdoc_node *p; + struct roff_node *p; body->flags |= MDOC_ENDED; body->parent->flags |= MDOC_ENDED; - p = node_alloc(mdoc, line, pos, tok, MDOC_BODY); + p = roff_node_alloc(mdoc, line, pos, ROFFT_BODY, tok); p->body = body; p->norm = body->norm; p->end = end; - node_append(mdoc, p); - mdoc->next = MDOC_NEXT_SIBLING; - return(p); + roff_node_append(mdoc, p); + mdoc->next = ROFF_NEXT_SIBLING; + return p; } -struct mdoc_node * -mdoc_block_alloc(struct mdoc *mdoc, int line, int pos, - enum mdoct tok, struct mdoc_arg *args) +struct roff_node * +mdoc_block_alloc(struct roff_man *mdoc, int line, int pos, + int tok, struct mdoc_arg *args) { - struct mdoc_node *p; + struct roff_node *p; - p = node_alloc(mdoc, line, pos, tok, MDOC_BLOCK); + p = roff_node_alloc(mdoc, line, pos, ROFFT_BLOCK, tok); p->args = args; if (p->args) (args->refcnt)++; switch (tok) { case MDOC_Bd: - /* FALLTHROUGH */ case MDOC_Bf: - /* FALLTHROUGH */ case MDOC_Bl: - /* FALLTHROUGH */ case MDOC_En: - /* FALLTHROUGH */ case MDOC_Rs: p->norm = mandoc_calloc(1, sizeof(union mdoc_data)); break; default: break; } - node_append(mdoc, p); - mdoc->next = MDOC_NEXT_CHILD; - return(p); + roff_node_append(mdoc, p); + mdoc->next = ROFF_NEXT_CHILD; + return p; } void -mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos, - enum mdoct tok, struct mdoc_arg *args) +mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos, + int tok, struct mdoc_arg *args) { - struct mdoc_node *p; + struct roff_node *p; - p = node_alloc(mdoc, line, pos, tok, MDOC_ELEM); + p = roff_node_alloc(mdoc, line, pos, ROFFT_ELEM, tok); p->args = args; if (p->args) (args->refcnt)++; @@ -479,106 +196,17 @@ mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos, default: break; } - node_append(mdoc, p); - mdoc->next = MDOC_NEXT_CHILD; -} - -void -mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p) -{ - struct mdoc_node *n; - - n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT); - n->string = roff_strdup(mdoc->roff, p); - node_append(mdoc, n); - mdoc->next = MDOC_NEXT_SIBLING; + roff_node_append(mdoc, p); + mdoc->next = ROFF_NEXT_CHILD; } void -mdoc_word_append(struct mdoc *mdoc, const char *p) +mdoc_node_relink(struct roff_man *mdoc, struct roff_node *p) { - struct mdoc_node *n; - char *addstr, *newstr; - n = mdoc->last; - addstr = roff_strdup(mdoc->roff, p); - mandoc_asprintf(&newstr, "%s %s", n->string, addstr); - free(addstr); - free(n->string); - n->string = newstr; - mdoc->next = MDOC_NEXT_SIBLING; -} - -static void -mdoc_node_free(struct mdoc_node *p) -{ - - if (MDOC_BLOCK == p->type || MDOC_ELEM == p->type) - free(p->norm); - if (p->string) - free(p->string); - if (p->args) - mdoc_argv_free(p->args); - free(p); -} - -static void -mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n) -{ - - /* Adjust siblings. */ - - if (n->prev) - n->prev->next = n->next; - if (n->next) - n->next->prev = n->prev; - - /* Adjust parent. */ - - if (n->parent) { - n->parent->nchild--; - if (n->parent->child == n) - n->parent->child = n->prev ? n->prev : n->next; - if (n->parent->last == n) - n->parent->last = n->prev ? n->prev : NULL; - } - - /* Adjust parse point, if applicable. */ - - if (mdoc && mdoc->last == n) { - if (n->prev) { - mdoc->last = n->prev; - mdoc->next = MDOC_NEXT_SIBLING; - } else { - mdoc->last = n->parent; - mdoc->next = MDOC_NEXT_CHILD; - } - } - - if (mdoc && mdoc->first == n) - mdoc->first = NULL; -} - -void -mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p) -{ - - while (p->child) { - assert(p->nchild); - mdoc_node_delete(mdoc, p->child); - } - assert(0 == p->nchild); - - mdoc_node_unlink(mdoc, p); - mdoc_node_free(p); -} - -void -mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p) -{ - - mdoc_node_unlink(mdoc, p); - node_append(mdoc, p); + roff_node_unlink(mdoc, p); + p->prev = p->next = NULL; + roff_node_append(mdoc, p); } /* @@ -586,37 +214,37 @@ mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p) * control character. */ static int -mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs) +mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs) { + struct roff_node *n; char *c, *ws, *end; - struct mdoc_node *n; assert(mdoc->last); n = mdoc->last; /* * Divert directly to list processing if we're encountering a - * columnar MDOC_BLOCK with or without a prior MDOC_BLOCK entry - * (a MDOC_BODY means it's already open, in which case we should + * columnar ROFFT_BLOCK with or without a prior ROFFT_BLOCK entry + * (a ROFFT_BODY means it's already open, in which case we should * process within its context in the normal way). */ - if (n->tok == MDOC_Bl && n->type == MDOC_BODY && + if (n->tok == MDOC_Bl && n->type == ROFFT_BODY && n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) { /* `Bl' is open without any children. */ mdoc->flags |= MDOC_FREECOL; mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf); - return(1); + return 1; } - if (MDOC_It == n->tok && MDOC_BLOCK == n->type && + if (n->tok == MDOC_It && n->type == ROFFT_BLOCK && NULL != n->parent && MDOC_Bl == n->parent->tok && LIST_column == n->parent->norm->Bl.type) { /* `Bl' has block-level `It' children. */ mdoc->flags |= MDOC_FREECOL; mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf); - return(1); + return 1; } /* @@ -673,16 +301,16 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs) * blank lines aren't allowed, but enough manuals assume this * behaviour that we want to work around it. */ - mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL); - mdoc->next = MDOC_NEXT_SIBLING; - mdoc_valid_post(mdoc); - return(1); + roff_elem_alloc(mdoc, line, offs, MDOC_sp); + mdoc->last->flags |= MDOC_VALID | MDOC_ENDED; + mdoc->next = ROFF_NEXT_SIBLING; + return 1; } - mdoc_word_alloc(mdoc, line, offs, buf+offs); + roff_word_alloc(mdoc, line, offs, buf+offs); if (mdoc->flags & MDOC_LITERAL) - return(1); + return 1; /* * End-of-sentence check. If the last character is an unescaped @@ -694,7 +322,7 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs) if (mandoc_eos(buf+offs, (size_t)(end-buf-offs))) mdoc->last->flags |= MDOC_EOS; - return(1); + return 1; } /* @@ -702,11 +330,11 @@ mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs) * character. */ static int -mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) +mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs) { - struct mdoc_node *n; + struct roff_node *n; const char *cp; - enum mdoct tok; + int tok; int i, sv; char mac[5]; @@ -723,12 +351,12 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) mac[i] = '\0'; - tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : MDOC_MAX; + tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : TOKEN_NONE; - if (tok == MDOC_MAX) { + if (tok == TOKEN_NONE) { mandoc_msg(MANDOCERR_MACRO, mdoc->parse, ln, sv, buf + sv - 1); - return(1); + return 1; } /* Skip a leading escape sequence or tab. */ @@ -767,7 +395,7 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) { mdoc_macro(mdoc, tok, ln, sv, &offs, buf); - return(1); + return 1; } n = mdoc->last; @@ -778,11 +406,11 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) * context around the parsed macro. */ - if (n->tok == MDOC_Bl && n->type == MDOC_BODY && + if (n->tok == MDOC_Bl && n->type == ROFFT_BODY && n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) { mdoc->flags |= MDOC_FREECOL; mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf); - return(1); + return 1; } /* @@ -791,13 +419,13 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) * then open an `It' block context around the parsed macro. */ - if (MDOC_It == n->tok && MDOC_BLOCK == n->type && + if (n->tok == MDOC_It && n->type == ROFFT_BLOCK && NULL != n->parent && MDOC_Bl == n->parent->tok && LIST_column == n->parent->norm->Bl.type) { mdoc->flags |= MDOC_FREECOL; mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf); - return(1); + return 1; } /* Normal processing of a macro. */ @@ -808,9 +436,9 @@ mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs) if (mdoc->quick && MDOC_Sh == tok && SEC_NAME != mdoc->last->sec) - return(2); + return 2; - return(1); + return 1; } enum mdelim @@ -818,82 +446,44 @@ mdoc_isdelim(const char *p) { if ('\0' == p[0]) - return(DELIM_NONE); + return DELIM_NONE; if ('\0' == p[1]) switch (p[0]) { case '(': - /* FALLTHROUGH */ case '[': - return(DELIM_OPEN); + return DELIM_OPEN; case '|': - return(DELIM_MIDDLE); + return DELIM_MIDDLE; case '.': - /* FALLTHROUGH */ case ',': - /* FALLTHROUGH */ case ';': - /* FALLTHROUGH */ case ':': - /* FALLTHROUGH */ case '?': - /* FALLTHROUGH */ case '!': - /* FALLTHROUGH */ case ')': - /* FALLTHROUGH */ case ']': - return(DELIM_CLOSE); + return DELIM_CLOSE; default: - return(DELIM_NONE); + return DELIM_NONE; } if ('\\' != p[0]) - return(DELIM_NONE); + return DELIM_NONE; if (0 == strcmp(p + 1, ".")) - return(DELIM_CLOSE); + return DELIM_CLOSE; if (0 == strcmp(p + 1, "fR|\\fP")) - return(DELIM_MIDDLE); + return DELIM_MIDDLE; - return(DELIM_NONE); + return DELIM_NONE; } void -mdoc_deroff(char **dest, const struct mdoc_node *n) +mdoc_validate(struct roff_man *mdoc) { - char *cp; - size_t sz; - - if (MDOC_TEXT != n->type) { - for (n = n->child; n; n = n->next) - mdoc_deroff(dest, n); - return; - } - - /* Skip leading whitespace. */ - - for (cp = n->string; '\0' != *cp; cp++) - if (0 == isspace((unsigned char)*cp)) - break; - - /* Skip trailing whitespace. */ - - for (sz = strlen(cp); sz; sz--) - if (0 == isspace((unsigned char)cp[sz-1])) - break; - - /* Skip empty strings. */ - - if (0 == sz) - return; - - if (NULL == *dest) { - *dest = mandoc_strndup(cp, sz); - return; - } - mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp); - free(*dest); - *dest = cp; + mdoc->last = mdoc->first; + mdoc_node_validate(mdoc); + mdoc_state_reset(mdoc); } diff --git a/contrib/mdocml/mdoc.h b/contrib/mdocml/mdoc.h index e45786d..ebe4391 100644 --- a/contrib/mdocml/mdoc.h +++ b/contrib/mdocml/mdoc.h @@ -1,4 +1,4 @@ -/* $Id: mdoc.h,v 1.136 2015/02/12 12:24:33 schwarze Exp $ */ +/* $Id: mdoc.h,v 1.144 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,141 +7,139 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -enum mdoct { - MDOC_Ap = 0, - MDOC_Dd, - MDOC_Dt, - MDOC_Os, - MDOC_Sh, - MDOC_Ss, - MDOC_Pp, - MDOC_D1, - MDOC_Dl, - MDOC_Bd, - MDOC_Ed, - MDOC_Bl, - MDOC_El, - MDOC_It, - MDOC_Ad, - MDOC_An, - MDOC_Ar, - MDOC_Cd, - MDOC_Cm, - MDOC_Dv, - MDOC_Er, - MDOC_Ev, - MDOC_Ex, - MDOC_Fa, - MDOC_Fd, - MDOC_Fl, - MDOC_Fn, - MDOC_Ft, - MDOC_Ic, - MDOC_In, - MDOC_Li, - MDOC_Nd, - MDOC_Nm, - MDOC_Op, - MDOC_Ot, - MDOC_Pa, - MDOC_Rv, - MDOC_St, - MDOC_Va, - MDOC_Vt, - MDOC_Xr, - MDOC__A, - MDOC__B, - MDOC__D, - MDOC__I, - MDOC__J, - MDOC__N, - MDOC__O, - MDOC__P, - MDOC__R, - MDOC__T, - MDOC__V, - MDOC_Ac, - MDOC_Ao, - MDOC_Aq, - MDOC_At, - MDOC_Bc, - MDOC_Bf, - MDOC_Bo, - MDOC_Bq, - MDOC_Bsx, - MDOC_Bx, - MDOC_Db, - MDOC_Dc, - MDOC_Do, - MDOC_Dq, - MDOC_Ec, - MDOC_Ef, - MDOC_Em, - MDOC_Eo, - MDOC_Fx, - MDOC_Ms, - MDOC_No, - MDOC_Ns, - MDOC_Nx, - MDOC_Ox, - MDOC_Pc, - MDOC_Pf, - MDOC_Po, - MDOC_Pq, - MDOC_Qc, - MDOC_Ql, - MDOC_Qo, - MDOC_Qq, - MDOC_Re, - MDOC_Rs, - MDOC_Sc, - MDOC_So, - MDOC_Sq, - MDOC_Sm, - MDOC_Sx, - MDOC_Sy, - MDOC_Tn, - MDOC_Ux, - MDOC_Xc, - MDOC_Xo, - MDOC_Fo, - MDOC_Fc, - MDOC_Oo, - MDOC_Oc, - MDOC_Bk, - MDOC_Ek, - MDOC_Bt, - MDOC_Hf, - MDOC_Fr, - MDOC_Ud, - MDOC_Lb, - MDOC_Lp, - MDOC_Lk, - MDOC_Mt, - MDOC_Brq, - MDOC_Bro, - MDOC_Brc, - MDOC__C, - MDOC_Es, - MDOC_En, - MDOC_Dx, - MDOC__Q, - MDOC_br, - MDOC_sp, - MDOC__U, - MDOC_Ta, - MDOC_ll, - MDOC_MAX -}; +#define MDOC_Ap 0 +#define MDOC_Dd 1 +#define MDOC_Dt 2 +#define MDOC_Os 3 +#define MDOC_Sh 4 +#define MDOC_Ss 5 +#define MDOC_Pp 6 +#define MDOC_D1 7 +#define MDOC_Dl 8 +#define MDOC_Bd 9 +#define MDOC_Ed 10 +#define MDOC_Bl 11 +#define MDOC_El 12 +#define MDOC_It 13 +#define MDOC_Ad 14 +#define MDOC_An 15 +#define MDOC_Ar 16 +#define MDOC_Cd 17 +#define MDOC_Cm 18 +#define MDOC_Dv 19 +#define MDOC_Er 20 +#define MDOC_Ev 21 +#define MDOC_Ex 22 +#define MDOC_Fa 23 +#define MDOC_Fd 24 +#define MDOC_Fl 25 +#define MDOC_Fn 26 +#define MDOC_Ft 27 +#define MDOC_Ic 28 +#define MDOC_In 29 +#define MDOC_Li 30 +#define MDOC_Nd 31 +#define MDOC_Nm 32 +#define MDOC_Op 33 +#define MDOC_Ot 34 +#define MDOC_Pa 35 +#define MDOC_Rv 36 +#define MDOC_St 37 +#define MDOC_Va 38 +#define MDOC_Vt 39 +#define MDOC_Xr 40 +#define MDOC__A 41 +#define MDOC__B 42 +#define MDOC__D 43 +#define MDOC__I 44 +#define MDOC__J 45 +#define MDOC__N 46 +#define MDOC__O 47 +#define MDOC__P 48 +#define MDOC__R 49 +#define MDOC__T 50 +#define MDOC__V 51 +#define MDOC_Ac 52 +#define MDOC_Ao 53 +#define MDOC_Aq 54 +#define MDOC_At 55 +#define MDOC_Bc 56 +#define MDOC_Bf 57 +#define MDOC_Bo 58 +#define MDOC_Bq 59 +#define MDOC_Bsx 60 +#define MDOC_Bx 61 +#define MDOC_Db 62 +#define MDOC_Dc 63 +#define MDOC_Do 64 +#define MDOC_Dq 65 +#define MDOC_Ec 66 +#define MDOC_Ef 67 +#define MDOC_Em 68 +#define MDOC_Eo 69 +#define MDOC_Fx 70 +#define MDOC_Ms 71 +#define MDOC_No 72 +#define MDOC_Ns 73 +#define MDOC_Nx 74 +#define MDOC_Ox 75 +#define MDOC_Pc 76 +#define MDOC_Pf 77 +#define MDOC_Po 78 +#define MDOC_Pq 79 +#define MDOC_Qc 80 +#define MDOC_Ql 81 +#define MDOC_Qo 82 +#define MDOC_Qq 83 +#define MDOC_Re 84 +#define MDOC_Rs 85 +#define MDOC_Sc 86 +#define MDOC_So 87 +#define MDOC_Sq 88 +#define MDOC_Sm 89 +#define MDOC_Sx 90 +#define MDOC_Sy 91 +#define MDOC_Tn 92 +#define MDOC_Ux 93 +#define MDOC_Xc 94 +#define MDOC_Xo 95 +#define MDOC_Fo 96 +#define MDOC_Fc 97 +#define MDOC_Oo 98 +#define MDOC_Oc 99 +#define MDOC_Bk 100 +#define MDOC_Ek 101 +#define MDOC_Bt 102 +#define MDOC_Hf 103 +#define MDOC_Fr 104 +#define MDOC_Ud 105 +#define MDOC_Lb 106 +#define MDOC_Lp 107 +#define MDOC_Lk 108 +#define MDOC_Mt 109 +#define MDOC_Brq 110 +#define MDOC_Bro 111 +#define MDOC_Brc 112 +#define MDOC__C 113 +#define MDOC_Es 114 +#define MDOC_En 115 +#define MDOC_Dx 116 +#define MDOC__Q 117 +#define MDOC_br 118 +#define MDOC_sp 119 +#define MDOC__U 120 +#define MDOC_Ta 121 +#define MDOC_ll 122 +#define MDOC_MAX 123 enum mdocargt { MDOC_Split, /* -split */ @@ -174,61 +172,6 @@ enum mdocargt { MDOC_ARG_MAX }; -enum mdoc_type { - MDOC_TEXT, - MDOC_ELEM, - MDOC_HEAD, - MDOC_TAIL, - MDOC_BODY, - MDOC_BLOCK, - MDOC_TBL, - MDOC_EQN, - MDOC_ROOT -}; - -/* - * Section (named/unnamed) of `Sh'. Note that these appear in the - * conventional order imposed by mdoc.7. In the case of SEC_NONE, no - * section has been invoked (this shouldn't happen). SEC_CUSTOM refers - * to other sections. - */ -enum mdoc_sec { - SEC_NONE = 0, - SEC_NAME, /* NAME */ - SEC_LIBRARY, /* LIBRARY */ - SEC_SYNOPSIS, /* SYNOPSIS */ - SEC_DESCRIPTION, /* DESCRIPTION */ - SEC_CONTEXT, /* CONTEXT */ - SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */ - SEC_RETURN_VALUES, /* RETURN VALUES */ - SEC_ENVIRONMENT, /* ENVIRONMENT */ - SEC_FILES, /* FILES */ - SEC_EXIT_STATUS, /* EXIT STATUS */ - SEC_EXAMPLES, /* EXAMPLES */ - SEC_DIAGNOSTICS, /* DIAGNOSTICS */ - SEC_COMPATIBILITY, /* COMPATIBILITY */ - SEC_ERRORS, /* ERRORS */ - SEC_SEE_ALSO, /* SEE ALSO */ - SEC_STANDARDS, /* STANDARDS */ - SEC_HISTORY, /* HISTORY */ - SEC_AUTHORS, /* AUTHORS */ - SEC_CAVEATS, /* CAVEATS */ - SEC_BUGS, /* BUGS */ - SEC_SECURITY, /* SECURITY */ - SEC_CUSTOM, - SEC__MAX -}; - -struct mdoc_meta { - char *msec; /* `Dt' section (1, 3p, etc.) */ - char *vol; /* `Dt' volume (implied) */ - char *arch; /* `Dt' arch (i386, etc.) */ - char *date; /* `Dd' normalised date */ - char *title; /* `Dt' title (FOO, etc.) */ - char *os; /* `Os' system (OpenBSD, etc.) */ - char *name; /* leading `Nm' name */ -}; - /* * An argument to a macro (multiple values = `-column xxx yyy'). */ @@ -251,16 +194,6 @@ struct mdoc_arg { unsigned int refcnt; }; -/* - * Indicates that a BODY's formatting has ended, but the scope is still - * open. Used for syntax-broken blocks. - */ -enum mdoc_endbody { - ENDBODY_NOT = 0, - ENDBODY_SPACE, /* is broken: append a space */ - ENDBODY_NOSPACE /* is broken: don't append a space */ -}; - enum mdoc_list { LIST__NONE = 0, LIST_bullet, /* -bullet */ @@ -337,59 +270,15 @@ union mdoc_data { struct mdoc_bd Bd; struct mdoc_bf Bf; struct mdoc_bl Bl; - struct mdoc_node *Es; + struct roff_node *Es; struct mdoc_rs Rs; }; -/* - * Single node in tree-linked AST. - */ -struct mdoc_node { - struct mdoc_node *parent; /* parent AST node */ - struct mdoc_node *child; /* first child AST node */ - struct mdoc_node *last; /* last child AST node */ - struct mdoc_node *next; /* sibling AST node */ - struct mdoc_node *prev; /* prior sibling AST node */ - int nchild; /* number children */ - int line; /* parse line */ - int pos; /* parse column */ - enum mdoct tok; /* tok or MDOC__MAX if none */ - int flags; -#define MDOC_VALID (1 << 0) /* has been validated */ -#define MDOC_ENDED (1 << 1) /* gone past body end mark */ -#define MDOC_EOS (1 << 2) /* at sentence boundary */ -#define MDOC_LINE (1 << 3) /* first macro/text on line */ -#define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting */ -#define MDOC_BROKEN (1 << 5) /* must validate parent when ending */ -#define MDOC_DELIMO (1 << 6) -#define MDOC_DELIMC (1 << 7) - enum mdoc_type type; /* AST node type */ - enum mdoc_sec sec; /* current named section */ - union mdoc_data *norm; /* normalised args */ - int prev_font; /* before entering this node */ - /* FIXME: these can be union'd to shave a few bytes. */ - struct mdoc_arg *args; /* BLOCK/ELEM */ - struct mdoc_node *head; /* BLOCK */ - struct mdoc_node *body; /* BLOCK/ENDBODY */ - struct mdoc_node *tail; /* BLOCK */ - char *string; /* TEXT */ - const struct tbl_span *span; /* TBL */ - const struct eqn *eqn; /* EQN */ - enum mdoc_endbody end; /* BODY */ -}; - -/* Names of macros. Index is enum mdoct. */ +/* Names of macros. */ extern const char *const *mdoc_macronames; /* Names of macro args. Index is enum mdocargt. */ extern const char *const *mdoc_argnames; -__BEGIN_DECLS - -struct mdoc; - -const struct mdoc_node *mdoc_node(const struct mdoc *); -const struct mdoc_meta *mdoc_meta(const struct mdoc *); -void mdoc_deroff(char **, const struct mdoc_node *); -__END_DECLS +void mdoc_validate(struct roff_man *); diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mdocml/mdoc_argv.c index a53389b..8675bdb 100644 --- a/contrib/mdocml/mdoc_argv.c +++ b/contrib/mdocml/mdoc_argv.c @@ -1,15 +1,15 @@ -/* $Id: mdoc_argv.c,v 1.100 2015/02/04 18:59:45 schwarze Exp $ */ +/* $Id: mdoc_argv.c,v 1.107 2015/10/17 00:21:07 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2012, 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -24,11 +24,12 @@ #include <stdio.h> #include <string.h> -#include "mdoc.h" -#include "mandoc.h" #include "mandoc_aux.h" -#include "libmdoc.h" +#include "mandoc.h" +#include "roff.h" +#include "mdoc.h" #include "libmandoc.h" +#include "libmdoc.h" #define MULTI_STEP 5 /* pre-allocate argument values */ #define DELIMSZ 6 /* max possible size of a delimiter */ @@ -51,12 +52,12 @@ struct mdocarg { }; static void argn_free(struct mdoc_arg *, int); -static enum margserr args(struct mdoc *, int, int *, +static enum margserr args(struct roff_man *, int, int *, char *, enum argsflag, char **); static int args_checkpunct(const char *, int); -static void argv_multi(struct mdoc *, int, +static void argv_multi(struct roff_man *, int, struct mdoc_argv *, int *, char *); -static void argv_single(struct mdoc *, int, +static void argv_single(struct roff_man *, int, struct mdoc_argv *, int *, char *); static const enum argvflag argvflags[MDOC_ARG_MAX] = { @@ -275,7 +276,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = { * Some flags take no argument, some one, some multiple. */ void -mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok, +mdoc_argv(struct roff_man *mdoc, int line, int tok, struct mdoc_arg **reta, int *pos, char *buf) { struct mdoc_argv tmpv; @@ -412,18 +413,18 @@ argn_free(struct mdoc_arg *p, int iarg) } enum margserr -mdoc_args(struct mdoc *mdoc, int line, int *pos, - char *buf, enum mdoct tok, char **v) +mdoc_args(struct roff_man *mdoc, int line, int *pos, + char *buf, int tok, char **v) { - struct mdoc_node *n; + struct roff_node *n; char *v_local; enum argsflag fl; if (v == NULL) v = &v_local; - fl = tok == MDOC_MAX ? ARGSFL_NONE : mdocargs[tok].flags; + fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok].flags; if (tok != MDOC_It) - return(args(mdoc, line, pos, buf, fl, v)); + return args(mdoc, line, pos, buf, fl, v); /* * We know that we're in an `It', so it's reasonable to expect @@ -439,105 +440,82 @@ mdoc_args(struct mdoc *mdoc, int line, int *pos, break; } - return(args(mdoc, line, pos, buf, fl, v)); + return args(mdoc, line, pos, buf, fl, v); } static enum margserr -args(struct mdoc *mdoc, int line, int *pos, +args(struct roff_man *mdoc, int line, int *pos, char *buf, enum argsflag fl, char **v) { - char *p, *pp; + char *p; int pairs; - enum margserr rc; - if ('\0' == buf[*pos]) { - if (MDOC_PPHRASE & mdoc->flags) - return(ARGS_EOLN); - /* - * If we're not in a partial phrase and the flag for - * being a phrase literal is still set, the punctuation - * is unterminated. - */ - if (MDOC_PHRASELIT & mdoc->flags) + if (buf[*pos] == '\0') { + if (mdoc->flags & MDOC_PHRASELIT && + ! (mdoc->flags & MDOC_PHRASE)) { mandoc_msg(MANDOCERR_ARG_QUOTE, mdoc->parse, line, *pos, NULL); - - mdoc->flags &= ~MDOC_PHRASELIT; - return(ARGS_EOLN); + mdoc->flags &= ~MDOC_PHRASELIT; + } + return ARGS_EOLN; } - *v = &buf[*pos]; + *v = buf + *pos; - if (ARGSFL_DELIM == fl) - if (args_checkpunct(buf, *pos)) - return(ARGS_PUNCT); + if (fl == ARGSFL_DELIM && args_checkpunct(buf, *pos)) + return ARGS_PUNCT; /* - * First handle TABSEP items, restricted to `Bl -column'. This - * ignores conventional token parsing and instead uses tabs or - * `Ta' macros to separate phrases. Phrases are parsed again - * for arguments at a later phase. + * Tabs in `It' lines in `Bl -column' can't be escaped. + * Phrases are reparsed for `Ta' and other macros later. */ - if (ARGSFL_TABSEP == fl) { - /* Scan ahead to tab (can't be escaped). */ - p = strchr(*v, '\t'); - pp = NULL; - - /* Scan ahead to unescaped `Ta'. */ - if ( ! (MDOC_PHRASELIT & mdoc->flags)) - for (pp = *v; ; pp++) { - if (NULL == (pp = strstr(pp, "Ta"))) - break; - if (pp > *v && ' ' != *(pp - 1)) - continue; - if (' ' == *(pp + 2) || '\0' == *(pp + 2)) - break; - } - - /* By default, assume a phrase. */ - rc = ARGS_PHRASE; - - /* - * Adjust new-buffer position to be beyond delimiter - * mark (e.g., Ta -> end + 2). - */ - if (p && pp) { - *pos += pp < p ? 2 : 1; - rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE; - p = pp < p ? pp : p; - } else if (p && ! pp) { - rc = ARGS_PPHRASE; - *pos += 1; - } else if (pp && ! p) { - p = pp; - *pos += 2; + if (fl == ARGSFL_TABSEP) { + if ((p = strchr(*v, '\t')) != NULL) { + + /* + * Words right before and right after + * tab characters are not parsed, + * unless there is a blank in between. + */ + + if (p[-1] != ' ') + mdoc->flags |= MDOC_PHRASEQL; + if (p[1] != ' ') + mdoc->flags |= MDOC_PHRASEQN; + + /* + * One or more blanks after a tab cause + * one leading blank in the next column. + * So skip all but one of them. + */ + + *pos += (int)(p - *v) + 1; + while (buf[*pos] == ' ' && buf[*pos + 1] == ' ') + (*pos)++; + + /* + * A tab at the end of an input line + * switches to the next column. + */ + + if (buf[*pos] == '\0' || buf[*pos + 1] == '\0') + mdoc->flags |= MDOC_PHRASEQN; } else { - rc = ARGS_PEND; - p = strchr(*v, 0); + p = strchr(*v, '\0'); + if (p[-1] == ' ') + mandoc_msg(MANDOCERR_SPACE_EOL, + mdoc->parse, line, *pos, NULL); + *pos += (int)(p - *v); } - /* Whitespace check for eoln case... */ - if ('\0' == *p && ' ' == *(p - 1)) - mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse, - line, *pos, NULL); - - *pos += (int)(p - *v); - - /* Strip delimiter's preceding whitespace. */ - pp = p - 1; - while (pp > *v && ' ' == *pp) { - if (pp > *v && '\\' == *(pp - 1)) - break; - pp--; - } - *(pp + 1) = 0; + /* Skip any trailing blank characters. */ + while (p > *v && p[-1] == ' ' && + (p - 1 == *v || p[-2] != '\\')) + p--; + *p = '\0'; - /* Strip delimiter's proceeding whitespace. */ - for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++) - /* Skip ahead. */ ; - - return(rc); + return ARGS_PHRASE; } /* @@ -548,11 +526,11 @@ args(struct mdoc *mdoc, int line, int *pos, * Whitespace is NOT involved in literal termination. */ - if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) { - if ( ! (MDOC_PHRASELIT & mdoc->flags)) + if (mdoc->flags & MDOC_PHRASELIT || buf[*pos] == '\"') { + if ( ! (mdoc->flags & MDOC_PHRASELIT)) *v = &buf[++(*pos)]; - if (MDOC_PPHRASE & mdoc->flags) + if (mdoc->flags & MDOC_PHRASE) mdoc->flags |= MDOC_PHRASELIT; pairs = 0; @@ -572,19 +550,18 @@ args(struct mdoc *mdoc, int line, int *pos, if (pairs) buf[*pos - pairs] = '\0'; - if ('\0' == buf[*pos]) { - if (MDOC_PPHRASE & mdoc->flags) - return(ARGS_QWORD); - mandoc_msg(MANDOCERR_ARG_QUOTE, - mdoc->parse, line, *pos, NULL); - return(ARGS_QWORD); + if (buf[*pos] == '\0') { + if ( ! (mdoc->flags & MDOC_PHRASE)) + mandoc_msg(MANDOCERR_ARG_QUOTE, + mdoc->parse, line, *pos, NULL); + return ARGS_QWORD; } mdoc->flags &= ~MDOC_PHRASELIT; buf[(*pos)++] = '\0'; if ('\0' == buf[*pos]) - return(ARGS_QWORD); + return ARGS_QWORD; while (' ' == buf[*pos]) (*pos)++; @@ -593,13 +570,22 @@ args(struct mdoc *mdoc, int line, int *pos, mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse, line, *pos, NULL); - return(ARGS_QWORD); + return ARGS_QWORD; } p = &buf[*pos]; *v = mandoc_getarg(mdoc->parse, &p, line, pos); - return(ARGS_WORD); + /* + * After parsing the last word in this phrase, + * tell lookup() whether or not to interpret it. + */ + + if (*p == '\0' && mdoc->flags & MDOC_PHRASEQL) { + mdoc->flags &= ~MDOC_PHRASEQL; + mdoc->flags |= MDOC_PHRASEQF; + } + return ARGS_WORD; } /* @@ -621,11 +607,11 @@ args_checkpunct(const char *buf, int i) dbuf[j] = buf[i]; if (DELIMSZ == j) - return(0); + return 0; dbuf[j] = '\0'; if (DELIM_CLOSE != mdoc_isdelim(dbuf)) - return(0); + return 0; while (' ' == buf[i]) i++; @@ -638,22 +624,22 @@ args_checkpunct(const char *buf, int i) dbuf[j++] = buf[i++]; if (DELIMSZ == j) - return(0); + return 0; dbuf[j] = '\0'; d = mdoc_isdelim(dbuf); if (DELIM_NONE == d || DELIM_OPEN == d) - return(0); + return 0; while (' ' == buf[i]) i++; } - return('\0' == buf[i]); + return '\0' == buf[i]; } static void -argv_multi(struct mdoc *mdoc, int line, +argv_multi(struct roff_man *mdoc, int line, struct mdoc_argv *v, int *pos, char *buf) { enum margserr ac; @@ -675,7 +661,7 @@ argv_multi(struct mdoc *mdoc, int line, } static void -argv_single(struct mdoc *mdoc, int line, +argv_single(struct roff_man *mdoc, int line, struct mdoc_argv *v, int *pos, char *buf) { enum margserr ac; diff --git a/contrib/mdocml/mdoc_hash.c b/contrib/mdocml/mdoc_hash.c index 5e34fe8..476116d 100644 --- a/contrib/mdocml/mdoc_hash.c +++ b/contrib/mdocml/mdoc_hash.c @@ -1,6 +1,7 @@ -/* $Id: mdoc_hash.c,v 1.21 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -25,22 +26,22 @@ #include <stdio.h> #include <string.h> +#include "roff.h" #include "mdoc.h" #include "libmdoc.h" static unsigned char table[27 * 12]; -/* - * XXX - this hash has global scope, so if intended for use as a library - * with multiple callers, it will need re-invocation protection. - */ void mdoc_hash_init(void) { int i, j, major; const char *p; + if (*table != '\0') + return; + memset(table, UCHAR_MAX, sizeof(table)); for (i = 0; i < (int)MDOC_MAX; i++) { @@ -61,32 +62,32 @@ mdoc_hash_init(void) } } -enum mdoct +int mdoc_hash_find(const char *p) { int major, i, j; if (0 == p[0]) - return(MDOC_MAX); + return TOKEN_NONE; if ( ! isalpha((unsigned char)p[0]) && '%' != p[0]) - return(MDOC_MAX); + return TOKEN_NONE; if (isalpha((unsigned char)p[1])) major = 12 * (tolower((unsigned char)p[1]) - 97); else if ('1' == p[1]) major = 12 * 26; else - return(MDOC_MAX); + return TOKEN_NONE; if (p[2] && p[3]) - return(MDOC_MAX); + return TOKEN_NONE; for (j = 0; j < 12; j++) { if (UCHAR_MAX == (i = table[major + j])) break; if (0 == strcmp(p, mdoc_macronames[i])) - return((enum mdoct)i); + return i; } - return(MDOC_MAX); + return TOKEN_NONE; } diff --git a/contrib/mdocml/mdoc_html.c b/contrib/mdocml/mdoc_html.c index fba7fb6..8e21bc7 100644 --- a/contrib/mdocml/mdoc_html.c +++ b/contrib/mdocml/mdoc_html.c @@ -1,15 +1,15 @@ -/* $Id: mdoc_html.c,v 1.226 2015/03/03 21:11:34 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.240 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015, 2016 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -27,6 +27,7 @@ #include <unistd.h> #include "mandoc_aux.h" +#include "roff.h" #include "mdoc.h" #include "out.h" #include "html.h" @@ -34,8 +35,8 @@ #define INDENT 5 -#define MDOC_ARGS const struct mdoc_meta *meta, \ - struct mdoc_node *n, \ +#define MDOC_ARGS const struct roff_meta *meta, \ + struct roff_node *n, \ struct html *h #ifndef MIN @@ -47,12 +48,11 @@ struct htmlmdoc { void (*post)(MDOC_ARGS); }; -static void print_mdoc(MDOC_ARGS); static void print_mdoc_head(MDOC_ARGS); static void print_mdoc_node(MDOC_ARGS); static void print_mdoc_nodelist(MDOC_ARGS); static void synopsis_pre(struct html *, - const struct mdoc_node *); + const struct roff_node *); static void a2width(const char *, struct roffsu *); @@ -263,15 +263,6 @@ static const char * const lists[LIST_MAX] = { }; -void -html_mdoc(void *arg, const struct mdoc *mdoc) -{ - - print_mdoc(mdoc_meta(mdoc), mdoc_node(mdoc)->child, - (struct html *)arg); - putchar('\n'); -} - /* * Calculate the scaling unit passed in a `-width' argument. This uses * either a native scaling unit (e.g., 1i, 2m) or the string length of @@ -292,7 +283,7 @@ a2width(const char *p, struct roffsu *su) * See the same function in mdoc_term.c for documentation. */ static void -synopsis_pre(struct html *h, const struct mdoc_node *n) +synopsis_pre(struct html *h, const struct roff_node *n) { if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) @@ -308,13 +299,9 @@ synopsis_pre(struct html *h, const struct mdoc_node *n) switch (n->prev->tok) { case MDOC_Fd: - /* FALLTHROUGH */ case MDOC_Fn: - /* FALLTHROUGH */ case MDOC_Fo: - /* FALLTHROUGH */ case MDOC_In: - /* FALLTHROUGH */ case MDOC_Vt: print_paragraph(h); break; @@ -330,27 +317,32 @@ synopsis_pre(struct html *h, const struct mdoc_node *n) } } -static void -print_mdoc(MDOC_ARGS) +void +html_mdoc(void *arg, const struct roff_man *mdoc) { - struct tag *t, *tt; struct htmlpair tag; + struct html *h; + struct tag *t, *tt; PAIR_CLASS_INIT(&tag, "mandoc"); + h = (struct html *)arg; if ( ! (HTML_FRAGMENT & h->oflags)) { print_gen_decls(h); t = print_otag(h, TAG_HTML, 0, NULL); tt = print_otag(h, TAG_HEAD, 0, NULL); - print_mdoc_head(meta, n, h); + print_mdoc_head(&mdoc->meta, mdoc->first->child, h); print_tagq(h, tt); print_otag(h, TAG_BODY, 0, NULL); print_otag(h, TAG_DIV, 1, &tag); } else t = print_otag(h, TAG_DIV, 1, &tag); - print_mdoc_nodelist(meta, n, h); + mdoc_root_pre(&mdoc->meta, mdoc->first->child, h); + print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h); + mdoc_root_post(&mdoc->meta, mdoc->first->child, h); print_tagq(h, t); + putchar('\n'); } static void @@ -390,10 +382,7 @@ print_mdoc_node(MDOC_ARGS) n->flags &= ~MDOC_ENDED; switch (n->type) { - case MDOC_ROOT: - child = mdoc_root_pre(meta, n, h); - break; - case MDOC_TEXT: + case ROFFT_TEXT: /* No tables in this mode... */ assert(NULL == h->tblt); @@ -410,12 +399,12 @@ print_mdoc_node(MDOC_ARGS) if (MDOC_DELIMO & n->flags) h->flags |= HTML_NOSPACE; return; - case MDOC_EQN: + case ROFFT_EQN: if (n->flags & MDOC_LINE) putchar('\n'); print_eqn(h, n->eqn); break; - case MDOC_TBL: + case ROFFT_TBL: /* * This will take care of initialising all of the table * state data for the first table, then tearing it down @@ -450,10 +439,7 @@ print_mdoc_node(MDOC_ARGS) print_stagq(h, t); switch (n->type) { - case MDOC_ROOT: - mdoc_root_post(meta, n, h); - break; - case MDOC_EQN: + case ROFFT_EQN: break; default: if ( ! mdocs[n->tok].post || n->flags & MDOC_ENDED) @@ -534,7 +520,7 @@ mdoc_root_pre(MDOC_ARGS) free(title); free(volume); - return(1); + return 1; } static int @@ -543,22 +529,21 @@ mdoc_sh_pre(MDOC_ARGS) struct htmlpair tag; switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: PAIR_CLASS_INIT(&tag, "section"); print_otag(h, TAG_DIV, 1, &tag); - return(1); - case MDOC_BODY: + return 1; + case ROFFT_BODY: if (n->sec == SEC_AUTHORS) h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT); - return(1); + return 1; default: break; } bufinit(h); - bufcat(h, "x"); - for (n = n->child; n && MDOC_TEXT == n->type; ) { + for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) { bufcat_id(h, n->string); if (NULL != (n = n->next)) bufcat_id(h, " "); @@ -570,7 +555,7 @@ mdoc_sh_pre(MDOC_ARGS) } else print_otag(h, TAG_H1, 0, NULL); - return(1); + return 1; } static int @@ -578,17 +563,16 @@ mdoc_ss_pre(MDOC_ARGS) { struct htmlpair tag; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { PAIR_CLASS_INIT(&tag, "subsection"); print_otag(h, TAG_DIV, 1, &tag); - return(1); - } else if (MDOC_BODY == n->type) - return(1); + return 1; + } else if (n->type == ROFFT_BODY) + return 1; bufinit(h); - bufcat(h, "x"); - for (n = n->child; n && MDOC_TEXT == n->type; ) { + for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) { bufcat_id(h, n->string); if (NULL != (n = n->next)) bufcat_id(h, " "); @@ -600,7 +584,7 @@ mdoc_ss_pre(MDOC_ARGS) } else print_otag(h, TAG_H2, 0, NULL); - return(1); + return 1; } static int @@ -614,17 +598,17 @@ mdoc_fl_pre(MDOC_ARGS) /* `Cm' has no leading hyphen. */ if (MDOC_Cm == n->tok) - return(1); + return 1; print_text(h, "\\-"); - if ( ! (n->nchild == 0 && + if (!(n->child == NULL && (n->next == NULL || - n->next->type == MDOC_TEXT || + n->next->type == ROFFT_TEXT || n->next->flags & MDOC_LINE))) h->flags |= HTML_NOSPACE; - return(1); + return 1; } static int @@ -632,15 +616,15 @@ mdoc_nd_pre(MDOC_ARGS) { struct htmlpair tag; - if (MDOC_BODY != n->type) - return(1); + if (n->type != ROFFT_BODY) + return 1; /* XXX: this tag in theory can contain block elements. */ print_text(h, "\\(em"); PAIR_CLASS_INIT(&tag, "desc"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -651,21 +635,18 @@ mdoc_nm_pre(MDOC_ARGS) int len; switch (n->type) { - case MDOC_ELEM: - synopsis_pre(h, n); + case ROFFT_HEAD: + print_otag(h, TAG_TD, 0, NULL); + /* FALLTHROUGH */ + case ROFFT_ELEM: PAIR_CLASS_INIT(&tag, "name"); print_otag(h, TAG_B, 1, &tag); - if (NULL == n->child && meta->name) - print_text(h, meta->name); - return(1); - case MDOC_HEAD: - print_otag(h, TAG_TD, 0, NULL); - if (NULL == n->child && meta->name) + if (n->child == NULL && meta->name != NULL) print_text(h, meta->name); - return(1); - case MDOC_BODY: + return 1; + case ROFFT_BODY: print_otag(h, TAG_TD, 0, NULL); - return(1); + return 1; default: break; } @@ -674,11 +655,11 @@ mdoc_nm_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "synopsis"); print_otag(h, TAG_TABLE, 1, &tag); - for (len = 0, n = n->child; n; n = n->next) - if (MDOC_TEXT == n->type) + for (len = 0, n = n->head->child; n; n = n->next) + if (n->type == ROFFT_TEXT) len += html_strlen(n->string); - if (0 == len && meta->name) + if (len == 0 && meta->name != NULL) len = html_strlen(meta->name); SCALE_HS_INIT(&su, len); @@ -689,7 +670,7 @@ mdoc_nm_pre(MDOC_ARGS) print_otag(h, TAG_COL, 0, NULL); print_otag(h, TAG_TBODY, 0, NULL); print_otag(h, TAG_TR, 0, NULL); - return(1); + return 1; } static int @@ -698,7 +679,7 @@ mdoc_xr_pre(MDOC_ARGS) struct htmlpair tag[2]; if (NULL == n->child) - return(0); + return 0; PAIR_CLASS_INIT(&tag[0], "link-man"); @@ -715,7 +696,7 @@ mdoc_xr_pre(MDOC_ARGS) print_text(h, n->string); if (NULL == (n = n->next)) - return(0); + return 0; h->flags |= HTML_NOSPACE; print_text(h, "("); @@ -723,7 +704,7 @@ mdoc_xr_pre(MDOC_ARGS) print_text(h, n->string); h->flags |= HTML_NOSPACE; print_text(h, ")"); - return(0); + return 0; } static int @@ -732,7 +713,7 @@ mdoc_ns_pre(MDOC_ARGS) if ( ! (MDOC_LINE & n->flags)) h->flags |= HTML_NOSPACE; - return(1); + return 1; } static int @@ -742,7 +723,7 @@ mdoc_ar_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "arg"); print_otag(h, TAG_I, 1, &tag); - return(1); + return 1; } static int @@ -772,7 +753,7 @@ mdoc_xx_pre(MDOC_ARGS) pp = "UNIX"; break; default: - return(1); + return 1; } PAIR_CLASS_INIT(&tag, "unix"); @@ -785,7 +766,7 @@ mdoc_xx_pre(MDOC_ARGS) print_text(h, n->child->string); h->flags = flags; } - return(0); + return 0; } static int @@ -802,7 +783,7 @@ mdoc_bx_pre(MDOC_ARGS) print_text(h, "BSD"); } else { print_text(h, "BSD"); - return(0); + return 0; } if (NULL != (n = n->next)) { @@ -812,7 +793,7 @@ mdoc_bx_pre(MDOC_ARGS) print_text(h, n->string); } - return(0); + return 0; } static int @@ -821,7 +802,7 @@ mdoc_it_pre(MDOC_ARGS) struct roffsu su; enum mdoc_list type; struct htmlpair tag[2]; - const struct mdoc_node *bl; + const struct roff_node *bl; bl = n->parent; while (bl && MDOC_Bl != bl->tok) @@ -836,26 +817,18 @@ mdoc_it_pre(MDOC_ARGS) bufinit(h); - if (MDOC_HEAD == n->type) { + if (n->type == ROFFT_HEAD) { switch (type) { case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_item: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_enum: - return(0); + return 0; case LIST_diag: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_tag: SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); bufcat_su(h, "margin-top", &su); @@ -871,16 +844,12 @@ mdoc_it_pre(MDOC_ARGS) default: break; } - } else if (MDOC_BODY == n->type) { + } else if (n->type == ROFFT_BODY) { switch (type) { case LIST_bullet: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_enum: - /* FALLTHROUGH */ case LIST_item: SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); bufcat_su(h, "margin-top", &su); @@ -888,13 +857,9 @@ mdoc_it_pre(MDOC_ARGS) print_otag(h, TAG_LI, 2, tag); break; case LIST_diag: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_tag: if (NULL == bl->norm->Bl.width) { print_otag(h, TAG_DD, 1, tag); @@ -924,7 +889,7 @@ mdoc_it_pre(MDOC_ARGS) } } - return(1); + return 1; } static int @@ -935,15 +900,15 @@ mdoc_bl_pre(MDOC_ARGS) struct roffsu su; char buf[BUFSIZ]; - if (MDOC_BODY == n->type) { + if (n->type == ROFFT_BODY) { if (LIST_column == n->norm->Bl.type) print_otag(h, TAG_TBODY, 0, NULL); - return(1); + return 1; } - if (MDOC_HEAD == n->type) { + if (n->type == ROFFT_HEAD) { if (LIST_column != n->norm->Bl.type) - return(0); + return 0; /* * For each column, print out the <COL> tag with our @@ -963,7 +928,7 @@ mdoc_bl_pre(MDOC_ARGS) print_otag(h, TAG_COL, 1, tag); } - return(0); + return 0; } SCALE_VS_INIT(&su, 0); @@ -986,11 +951,8 @@ mdoc_bl_pre(MDOC_ARGS) switch (n->norm->Bl.type) { case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_item: print_otag(h, TAG_UL, 2, tag); break; @@ -998,13 +960,9 @@ mdoc_bl_pre(MDOC_ARGS) print_otag(h, TAG_OL, 2, tag); break; case LIST_diag: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_tag: print_otag(h, TAG_DL, 2, tag); break; @@ -1013,18 +971,17 @@ mdoc_bl_pre(MDOC_ARGS) break; default: abort(); - /* NOTREACHED */ } - return(1); + return 1; } static int mdoc_ex_pre(MDOC_ARGS) { - struct tag *t; - struct htmlpair tag; - int nchild; + struct htmlpair tag; + struct tag *t; + struct roff_node *nch; if (n->prev) print_otag(h, TAG_BR, 0, NULL); @@ -1033,30 +990,32 @@ mdoc_ex_pre(MDOC_ARGS) print_text(h, "The"); - nchild = n->nchild; - for (n = n->child; n; n = n->next) { - assert(MDOC_TEXT == n->type); + for (nch = n->child; nch != NULL; nch = nch->next) { + assert(nch->type == ROFFT_TEXT); t = print_otag(h, TAG_B, 1, &tag); - print_text(h, n->string); + print_text(h, nch->string); print_tagq(h, t); - if (nchild > 2 && n->next) { + if (nch->next == NULL) + continue; + + if (nch->prev != NULL || nch->next->next != NULL) { h->flags |= HTML_NOSPACE; print_text(h, ","); } - if (n->next && NULL == n->next->next) + if (nch->next->next == NULL) print_text(h, "and"); } - if (nchild > 1) + if (n->child != NULL && n->child->next != NULL) print_text(h, "utilities exit\\~0"); else print_text(h, "utility exits\\~0"); print_text(h, "on success, and\\~>0 if an error occurs."); - return(0); + return 0; } static int @@ -1066,7 +1025,7 @@ mdoc_em_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "emph"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1075,8 +1034,8 @@ mdoc_d1_pre(MDOC_ARGS) struct htmlpair tag[2]; struct roffsu su; - if (MDOC_BLOCK != n->type) - return(1); + if (n->type != ROFFT_BLOCK) + return 1; SCALE_VS_INIT(&su, 0); bufinit(h); @@ -1095,7 +1054,7 @@ mdoc_d1_pre(MDOC_ARGS) print_otag(h, TAG_CODE, 1, tag); } - return(1); + return 1; } static int @@ -1104,7 +1063,7 @@ mdoc_sx_pre(MDOC_ARGS) struct htmlpair tag[2]; bufinit(h); - bufcat(h, "#x"); + bufcat(h, "#"); for (n = n->child; n; ) { bufcat_id(h, n->string); @@ -1117,7 +1076,7 @@ mdoc_sx_pre(MDOC_ARGS) print_otag(h, TAG_I, 1, tag); print_otag(h, TAG_A, 2, tag); - return(1); + return 1; } static int @@ -1125,16 +1084,16 @@ mdoc_bd_pre(MDOC_ARGS) { struct htmlpair tag[2]; int comp, sv; - struct mdoc_node *nn; + struct roff_node *nn; struct roffsu su; - if (MDOC_HEAD == n->type) - return(0); + if (n->type == ROFFT_HEAD) + return 0; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { comp = n->norm->Bd.comp; for (nn = n; nn && ! comp; nn = nn->parent) { - if (MDOC_BLOCK != nn->type) + if (nn->type != ROFFT_BLOCK) continue; if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok) comp = 1; @@ -1143,7 +1102,7 @@ mdoc_bd_pre(MDOC_ARGS) } if ( ! comp) print_paragraph(h); - return(1); + return 1; } /* Handle the -offset argument. */ @@ -1166,7 +1125,7 @@ mdoc_bd_pre(MDOC_ARGS) DISP_literal != n->norm->Bd.type) { PAIR_CLASS_INIT(&tag[1], "display"); print_otag(h, TAG_DIV, 2, tag); - return(1); + return 1; } PAIR_CLASS_INIT(&tag[1], "lit display"); @@ -1187,19 +1146,12 @@ mdoc_bd_pre(MDOC_ARGS) */ switch (nn->tok) { case MDOC_Sm: - /* FALLTHROUGH */ case MDOC_br: - /* FALLTHROUGH */ case MDOC_sp: - /* FALLTHROUGH */ case MDOC_Bl: - /* FALLTHROUGH */ case MDOC_D1: - /* FALLTHROUGH */ case MDOC_Dl: - /* FALLTHROUGH */ case MDOC_Lp: - /* FALLTHROUGH */ case MDOC_Pp: continue; default: @@ -1217,7 +1169,7 @@ mdoc_bd_pre(MDOC_ARGS) if (0 == sv) h->flags &= ~HTML_LITERAL; - return(0); + return 0; } static int @@ -1227,7 +1179,7 @@ mdoc_pa_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "file"); print_otag(h, TAG_I, 1, &tag); - return(1); + return 1; } static int @@ -1237,7 +1189,7 @@ mdoc_ad_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "addr"); print_otag(h, TAG_I, 1, &tag); - return(1); + return 1; } static int @@ -1248,12 +1200,12 @@ mdoc_an_pre(MDOC_ARGS) if (n->norm->An.auth == AUTH_split) { h->flags &= ~HTML_NOSPLIT; h->flags |= HTML_SPLIT; - return(0); + return 0; } if (n->norm->An.auth == AUTH_nosplit) { h->flags &= ~HTML_SPLIT; h->flags |= HTML_NOSPLIT; - return(0); + return 0; } if (h->flags & HTML_SPLIT) @@ -1264,7 +1216,7 @@ mdoc_an_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "author"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1275,7 +1227,7 @@ mdoc_cd_pre(MDOC_ARGS) synopsis_pre(h, n); PAIR_CLASS_INIT(&tag, "config"); print_otag(h, TAG_B, 1, &tag); - return(1); + return 1; } static int @@ -1285,7 +1237,7 @@ mdoc_dv_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "define"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1295,7 +1247,7 @@ mdoc_ev_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "env"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1305,20 +1257,20 @@ mdoc_er_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "errno"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int mdoc_fa_pre(MDOC_ARGS) { - const struct mdoc_node *nn; + const struct roff_node *nn; struct htmlpair tag; struct tag *t; PAIR_CLASS_INIT(&tag, "farg"); if (n->parent->tok != MDOC_Fo) { print_otag(h, TAG_I, 1, &tag); - return(1); + return 1; } for (nn = n->child; nn; nn = nn->next) { @@ -1336,7 +1288,7 @@ mdoc_fa_pre(MDOC_ARGS) print_text(h, ","); } - return(0); + return 0; } static int @@ -1351,14 +1303,14 @@ mdoc_fd_pre(MDOC_ARGS) synopsis_pre(h, n); if (NULL == (n = n->child)) - return(0); + return 0; - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); if (strcmp(n->string, "#include")) { PAIR_CLASS_INIT(&tag[0], "macro"); print_otag(h, TAG_B, 1, tag); - return(1); + return 1; } PAIR_CLASS_INIT(&tag[0], "includes"); @@ -1366,7 +1318,7 @@ mdoc_fd_pre(MDOC_ARGS) print_text(h, n->string); if (NULL != (n = n->next)) { - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); /* * XXX This is broken and not easy to fix. @@ -1400,11 +1352,11 @@ mdoc_fd_pre(MDOC_ARGS) } for ( ; n; n = n->next) { - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); print_text(h, n->string); } - return(0); + return 0; } static int @@ -1412,17 +1364,17 @@ mdoc_vt_pre(MDOC_ARGS) { struct htmlpair tag; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { synopsis_pre(h, n); - return(1); - } else if (MDOC_ELEM == n->type) { + return 1; + } else if (n->type == ROFFT_ELEM) { synopsis_pre(h, n); - } else if (MDOC_HEAD == n->type) - return(0); + } else if (n->type == ROFFT_HEAD) + return 0; PAIR_CLASS_INIT(&tag, "type"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1433,7 +1385,7 @@ mdoc_ft_pre(MDOC_ARGS) synopsis_pre(h, n); PAIR_CLASS_INIT(&tag, "ftype"); print_otag(h, TAG_I, 1, &tag); - return(1); + return 1; } static int @@ -1523,7 +1475,7 @@ mdoc_fn_pre(MDOC_ARGS) print_text(h, ";"); } - return(0); + return 0; } static int @@ -1540,14 +1492,14 @@ mdoc_sm_pre(MDOC_ARGS) if ( ! (HTML_NONOSPACE & h->flags)) h->flags &= ~HTML_NOSPACE; - return(0); + return 0; } static int mdoc_skip_pre(MDOC_ARGS) { - return(0); + return 0; } static int @@ -1555,7 +1507,7 @@ mdoc_pp_pre(MDOC_ARGS) { print_paragraph(h); - return(0); + return 0; } static int @@ -1584,7 +1536,7 @@ mdoc_sp_pre(MDOC_ARGS) /* So the div isn't empty: */ print_text(h, "\\~"); - return(0); + return 0; } @@ -1594,9 +1546,9 @@ mdoc_lk_pre(MDOC_ARGS) struct htmlpair tag[2]; if (NULL == (n = n->child)) - return(0); + return 0; - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); PAIR_CLASS_INIT(&tag[0], "link-ext"); PAIR_HREF_INIT(&tag[1], n->string); @@ -1609,7 +1561,7 @@ mdoc_lk_pre(MDOC_ARGS) for (n = n->next; n; n = n->next) print_text(h, n->string); - return(0); + return 0; } static int @@ -1621,7 +1573,7 @@ mdoc_mt_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag[0], "link-mail"); for (n = n->child; n; n = n->next) { - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); bufinit(h); bufcat(h, "mailto:"); @@ -1633,7 +1585,7 @@ mdoc_mt_pre(MDOC_ARGS) print_tagq(h, t); } - return(0); + return 0; } static int @@ -1642,33 +1594,32 @@ mdoc_fo_pre(MDOC_ARGS) struct htmlpair tag; struct tag *t; - if (MDOC_BODY == n->type) { + if (n->type == ROFFT_BODY) { h->flags |= HTML_NOSPACE; print_text(h, "("); h->flags |= HTML_NOSPACE; - return(1); - } else if (MDOC_BLOCK == n->type) { + return 1; + } else if (n->type == ROFFT_BLOCK) { synopsis_pre(h, n); - return(1); + return 1; } - /* XXX: we drop non-initial arguments as per groff. */ + if (n->child == NULL) + return 0; - assert(n->child); assert(n->child->string); - PAIR_CLASS_INIT(&tag, "fname"); t = print_otag(h, TAG_B, 1, &tag); print_text(h, n->child->string); print_tagq(h, t); - return(0); + return 0; } static void mdoc_fo_post(MDOC_ARGS) { - if (MDOC_BODY != n->type) + if (n->type != ROFFT_BODY) return; h->flags |= HTML_NOSPACE; print_text(h, ")"); @@ -1702,7 +1653,7 @@ mdoc_in_pre(MDOC_ARGS) h->flags |= HTML_NOSPACE; if (NULL != (n = n->child)) { - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); PAIR_CLASS_INIT(&tag[0], "link-includes"); @@ -1724,11 +1675,11 @@ mdoc_in_pre(MDOC_ARGS) print_text(h, ">"); for ( ; n; n = n->next) { - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); print_text(h, n->string); } - return(0); + return 0; } static int @@ -1738,7 +1689,7 @@ mdoc_ic_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "cmd"); print_otag(h, TAG_B, 1, &tag); - return(1); + return 1; } static int @@ -1746,37 +1697,36 @@ mdoc_rv_pre(MDOC_ARGS) { struct htmlpair tag; struct tag *t; - int nchild; + struct roff_node *nch; if (n->prev) print_otag(h, TAG_BR, 0, NULL); PAIR_CLASS_INIT(&tag, "fname"); - nchild = n->nchild; - if (nchild > 0) { + if (n->child != NULL) { print_text(h, "The"); - for (n = n->child; n; n = n->next) { + for (nch = n->child; nch != NULL; nch = nch->next) { t = print_otag(h, TAG_B, 1, &tag); - print_text(h, n->string); + print_text(h, nch->string); print_tagq(h, t); h->flags |= HTML_NOSPACE; print_text(h, "()"); - if (n->next == NULL) + if (nch->next == NULL) continue; - if (nchild > 2) { + if (nch->prev != NULL || nch->next->next != NULL) { h->flags |= HTML_NOSPACE; print_text(h, ","); } - if (n->next->next == NULL) + if (nch->next->next == NULL) print_text(h, "and"); } - if (nchild > 1) + if (n->child != NULL && n->child->next != NULL) print_text(h, "functions return"); else print_text(h, "function returns"); @@ -1794,7 +1744,7 @@ mdoc_rv_pre(MDOC_ARGS) print_text(h, "errno"); print_tagq(h, t); print_text(h, "is set to indicate the error."); - return(0); + return 0; } static int @@ -1804,7 +1754,7 @@ mdoc_va_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "var"); print_otag(h, TAG_B, 1, &tag); - return(1); + return 1; } static int @@ -1814,7 +1764,7 @@ mdoc_ap_pre(MDOC_ARGS) h->flags |= HTML_NOSPACE; print_text(h, "\\(aq"); h->flags |= HTML_NOSPACE; - return(1); + return 1; } static int @@ -1823,10 +1773,10 @@ mdoc_bf_pre(MDOC_ARGS) struct htmlpair tag[2]; struct roffsu su; - if (MDOC_HEAD == n->type) - return(0); - else if (MDOC_BODY != n->type) - return(1); + if (n->type == ROFFT_HEAD) + return 0; + else if (n->type != ROFFT_BODY) + return 1; if (FONT_Em == n->norm->Bf.font) PAIR_CLASS_INIT(&tag[0], "emph"); @@ -1848,7 +1798,7 @@ mdoc_bf_pre(MDOC_ARGS) bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag[1], h); print_otag(h, TAG_DIV, 2, tag); - return(1); + return 1; } static int @@ -1858,7 +1808,7 @@ mdoc_ms_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "symb"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1866,7 +1816,7 @@ mdoc_igndelim_pre(MDOC_ARGS) { h->flags |= HTML_IGNDELIM; - return(1); + return 1; } static void @@ -1882,15 +1832,15 @@ mdoc_rs_pre(MDOC_ARGS) { struct htmlpair tag; - if (MDOC_BLOCK != n->type) - return(1); + if (n->type != ROFFT_BLOCK) + return 1; if (n->prev && SEC_SEE_ALSO == n->sec) print_paragraph(h); PAIR_CLASS_INIT(&tag, "ref"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1900,7 +1850,7 @@ mdoc_no_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "none"); print_otag(h, TAG_CODE, 1, &tag); - return(1); + return 1; } static int @@ -1910,7 +1860,7 @@ mdoc_li_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "lit"); print_otag(h, TAG_CODE, 1, &tag); - return(1); + return 1; } static int @@ -1920,7 +1870,7 @@ mdoc_sy_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "symb"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -1928,7 +1878,7 @@ mdoc_bt_pre(MDOC_ARGS) { print_text(h, "is currently in beta test."); - return(0); + return 0; } static int @@ -1936,7 +1886,7 @@ mdoc_ud_pre(MDOC_ARGS) { print_text(h, "currently under development."); - return(0); + return 0; } static int @@ -1949,7 +1899,7 @@ mdoc_lb_pre(MDOC_ARGS) PAIR_CLASS_INIT(&tag, "lib"); print_otag(h, TAG_SPAN, 1, &tag); - return(1); + return 1; } static int @@ -2011,18 +1961,17 @@ mdoc__x_pre(MDOC_ARGS) break; default: abort(); - /* NOTREACHED */ } if (MDOC__U != n->tok) { print_otag(h, t, 1, tag); - return(1); + return 1; } PAIR_HREF_INIT(&tag[1], n->child->string); print_otag(h, TAG_A, 2, tag); - return(1); + return 1; } static void @@ -2048,27 +1997,26 @@ mdoc_bk_pre(MDOC_ARGS) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: break; - case MDOC_HEAD: - return(0); - case MDOC_BODY: - if (n->parent->args || 0 == n->prev->nchild) + case ROFFT_HEAD: + return 0; + case ROFFT_BODY: + if (n->parent->args != NULL || n->prev->child == NULL) h->flags |= HTML_PREKEEP; break; default: abort(); - /* NOTREACHED */ } - return(1); + return 1; } static void mdoc_bk_post(MDOC_ARGS) { - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) h->flags &= ~(HTML_KEEP | HTML_PREKEEP); } @@ -2077,28 +2025,24 @@ mdoc_quote_pre(MDOC_ARGS) { struct htmlpair tag; - if (MDOC_BODY != n->type) - return(1); + if (n->type != ROFFT_BODY) + return 1; switch (n->tok) { case MDOC_Ao: - /* FALLTHROUGH */ case MDOC_Aq: - print_text(h, n->nchild == 1 && + print_text(h, n->child != NULL && n->child->next == NULL && n->child->tok == MDOC_Mt ? "<" : "\\(la"); break; case MDOC_Bro: - /* FALLTHROUGH */ case MDOC_Brq: print_text(h, "\\(lC"); break; case MDOC_Bo: - /* FALLTHROUGH */ case MDOC_Bq: print_text(h, "\\(lB"); break; case MDOC_Oo: - /* FALLTHROUGH */ case MDOC_Op: print_text(h, "\\(lB"); h->flags |= HTML_NOSPACE; @@ -2108,20 +2052,16 @@ mdoc_quote_pre(MDOC_ARGS) case MDOC_En: if (NULL == n->norm->Es || NULL == n->norm->Es->child) - return(1); + return 1; print_text(h, n->norm->Es->child->string); break; case MDOC_Do: - /* FALLTHROUGH */ case MDOC_Dq: - /* FALLTHROUGH */ case MDOC_Qo: - /* FALLTHROUGH */ case MDOC_Qq: print_text(h, "\\(lq"); break; case MDOC_Po: - /* FALLTHROUGH */ case MDOC_Pq: print_text(h, "("); break; @@ -2132,46 +2072,39 @@ mdoc_quote_pre(MDOC_ARGS) print_otag(h, TAG_CODE, 1, &tag); break; case MDOC_So: - /* FALLTHROUGH */ case MDOC_Sq: print_text(h, "\\(oq"); break; default: abort(); - /* NOTREACHED */ } h->flags |= HTML_NOSPACE; - return(1); + return 1; } static void mdoc_quote_post(MDOC_ARGS) { - if (n->type != MDOC_BODY && n->type != MDOC_ELEM) + if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM) return; h->flags |= HTML_NOSPACE; switch (n->tok) { case MDOC_Ao: - /* FALLTHROUGH */ case MDOC_Aq: - print_text(h, n->nchild == 1 && + print_text(h, n->child != NULL && n->child->next == NULL && n->child->tok == MDOC_Mt ? ">" : "\\(ra"); break; case MDOC_Bro: - /* FALLTHROUGH */ case MDOC_Brq: print_text(h, "\\(rC"); break; case MDOC_Oo: - /* FALLTHROUGH */ case MDOC_Op: - /* FALLTHROUGH */ case MDOC_Bo: - /* FALLTHROUGH */ case MDOC_Bq: print_text(h, "\\(rB"); break; @@ -2184,29 +2117,22 @@ mdoc_quote_post(MDOC_ARGS) print_text(h, n->norm->Es->child->next->string); break; case MDOC_Qo: - /* FALLTHROUGH */ case MDOC_Qq: - /* FALLTHROUGH */ case MDOC_Do: - /* FALLTHROUGH */ case MDOC_Dq: print_text(h, "\\(rq"); break; case MDOC_Po: - /* FALLTHROUGH */ case MDOC_Pq: print_text(h, ")"); break; case MDOC_Ql: - /* FALLTHROUGH */ case MDOC_So: - /* FALLTHROUGH */ case MDOC_Sq: print_text(h, "\\(cq"); break; default: abort(); - /* NOTREACHED */ } } @@ -2214,8 +2140,8 @@ static int mdoc_eo_pre(MDOC_ARGS) { - if (n->type != MDOC_BODY) - return(1); + if (n->type != ROFFT_BODY) + return 1; if (n->end == ENDBODY_NOT && n->parent->head->child == NULL && @@ -2226,7 +2152,7 @@ mdoc_eo_pre(MDOC_ARGS) n->parent->head->child != NULL && (n->child != NULL || (n->parent->tail != NULL && n->parent->tail->child != NULL))) h->flags |= HTML_NOSPACE; - return(1); + return 1; } static void @@ -2234,7 +2160,7 @@ mdoc_eo_post(MDOC_ARGS) { int body, tail; - if (n->type != MDOC_BODY) + if (n->type != ROFFT_BODY) return; if (n->end != ENDBODY_NOT) { diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mdocml/mdoc_macro.c index efb48d0..ca95958 100644 --- a/contrib/mdocml/mdoc_macro.c +++ b/contrib/mdocml/mdoc_macro.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.183 2015/02/12 12:24:33 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.206 2015/10/20 02:01:32 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -26,10 +26,12 @@ #include <string.h> #include <time.h> -#include "mdoc.h" #include "mandoc.h" -#include "libmdoc.h" +#include "roff.h" +#include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" +#include "libmdoc.h" static void blk_full(MACRO_PROT_ARGS); static void blk_exp_close(MACRO_PROT_ARGS); @@ -41,18 +43,19 @@ static void in_line_argn(MACRO_PROT_ARGS); static void in_line(MACRO_PROT_ARGS); static void phrase_ta(MACRO_PROT_ARGS); -static void dword(struct mdoc *, int, int, const char *, - enum mdelim, int); -static void append_delims(struct mdoc *, int, int *, char *); -static enum mdoct lookup(struct mdoc *, enum mdoct, - int, int, const char *); +static void append_delims(struct roff_man *, int, int *, char *); +static void dword(struct roff_man *, int, int, const char *, + enum mdelim, int); +static int find_pending(struct roff_man *, int, int, int, + struct roff_node *); +static int lookup(struct roff_man *, int, int, int, const char *); static int macro_or_word(MACRO_PROT_ARGS, int); -static int parse_rest(struct mdoc *, enum mdoct, - int, int *, char *); -static enum mdoct rew_alt(enum mdoct); -static void rew_elem(struct mdoc *, enum mdoct); -static void rew_last(struct mdoc *, const struct mdoc_node *); -static void rew_pending(struct mdoc *, const struct mdoc_node *); +static int parse_rest(struct roff_man *, int, int, int *, char *); +static int rew_alt(int); +static void rew_elem(struct roff_man *, int); +static void rew_last(struct roff_man *, const struct roff_node *); +static void rew_pending(struct roff_man *, + const struct roff_node *); const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ap */ @@ -207,9 +210,9 @@ const struct mdoc_macro * const mdoc_macros = __mdoc_macros; * are errors. */ void -mdoc_macroend(struct mdoc *mdoc) +mdoc_endparse(struct roff_man *mdoc) { - struct mdoc_node *n; + struct roff_node *n; /* Scan for open explicit scopes. */ @@ -217,7 +220,7 @@ mdoc_macroend(struct mdoc *mdoc) mdoc->last->parent : mdoc->last; for ( ; n; n = n->parent) - if (n->type == MDOC_BLOCK && + if (n->type == ROFFT_BLOCK && mdoc_macros[n->tok].flags & MDOC_EXPLICIT) mandoc_msg(MANDOCERR_BLK_NOEND, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); @@ -225,86 +228,87 @@ mdoc_macroend(struct mdoc *mdoc) /* Rewind to the first. */ rew_last(mdoc, mdoc->first); + mdoc_state_reset(mdoc); } /* * Look up the macro at *p called by "from", - * or as a line macro if from == MDOC_MAX. + * or as a line macro if from == TOKEN_NONE. */ -static enum mdoct -lookup(struct mdoc *mdoc, enum mdoct from, int line, int ppos, const char *p) +static int +lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p) { - enum mdoct res; + int res; - if (from == MDOC_MAX || mdoc_macros[from].flags & MDOC_PARSED) { + if (mdoc->flags & MDOC_PHRASEQF) { + mdoc->flags &= ~MDOC_PHRASEQF; + return TOKEN_NONE; + } + if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) { res = mdoc_hash_find(p); - if (res != MDOC_MAX) { + if (res != TOKEN_NONE) { if (mdoc_macros[res].flags & MDOC_CALLABLE) - return(res); + return res; if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll) mandoc_msg(MANDOCERR_MACRO_CALL, mdoc->parse, line, ppos, p); } } - return(MDOC_MAX); + return TOKEN_NONE; } /* * Rewind up to and including a specific node. */ static void -rew_last(struct mdoc *mdoc, const struct mdoc_node *to) +rew_last(struct roff_man *mdoc, const struct roff_node *to) { - struct mdoc_node *n, *np; - assert(to); - mdoc->next = MDOC_NEXT_SIBLING; + if (to->flags & MDOC_VALID) + return; + while (mdoc->last != to) { - /* - * Save the parent here, because we may delete the - * mdoc->last node in the post-validation phase and reset - * it to mdoc->last->parent, causing a step in the closing - * out to be lost. - */ - np = mdoc->last->parent; - mdoc_valid_post(mdoc); - n = mdoc->last; - mdoc->last = np; - assert(mdoc->last); - mdoc->last->last = n; + mdoc_state(mdoc, mdoc->last); + mdoc->last->flags |= MDOC_VALID | MDOC_ENDED; + mdoc->last = mdoc->last->parent; } - mdoc_valid_post(mdoc); + mdoc_state(mdoc, mdoc->last); + mdoc->last->flags |= MDOC_VALID | MDOC_ENDED; + mdoc->next = ROFF_NEXT_SIBLING; } /* * Rewind up to a specific block, including all blocks that broke it. */ static void -rew_pending(struct mdoc *mdoc, const struct mdoc_node *n) +rew_pending(struct roff_man *mdoc, const struct roff_node *n) { for (;;) { rew_last(mdoc, n); - switch (n->type) { - case MDOC_HEAD: - mdoc_body_alloc(mdoc, n->line, n->pos, n->tok); - return; - case MDOC_BLOCK: - break; - default: - return; - } - - if ( ! (n->flags & MDOC_BROKEN)) - return; + if (mdoc->last == n) { + switch (n->type) { + case ROFFT_HEAD: + roff_body_alloc(mdoc, n->line, n->pos, + n->tok); + return; + case ROFFT_BLOCK: + break; + default: + return; + } + if ( ! (n->flags & MDOC_BROKEN)) + return; + } else + n = mdoc->last; for (;;) { if ((n = n->parent) == NULL) return; - if (n->type == MDOC_BLOCK || - n->type == MDOC_HEAD) { + if (n->type == ROFFT_BLOCK || + n->type == ROFFT_HEAD) { if (n->flags & MDOC_ENDED) break; else @@ -318,67 +322,104 @@ rew_pending(struct mdoc *mdoc, const struct mdoc_node *n) * For a block closing macro, return the corresponding opening one. * Otherwise, return the macro itself. */ -static enum mdoct -rew_alt(enum mdoct tok) +static int +rew_alt(int tok) { switch (tok) { case MDOC_Ac: - return(MDOC_Ao); + return MDOC_Ao; case MDOC_Bc: - return(MDOC_Bo); + return MDOC_Bo; case MDOC_Brc: - return(MDOC_Bro); + return MDOC_Bro; case MDOC_Dc: - return(MDOC_Do); + return MDOC_Do; case MDOC_Ec: - return(MDOC_Eo); + return MDOC_Eo; case MDOC_Ed: - return(MDOC_Bd); + return MDOC_Bd; case MDOC_Ef: - return(MDOC_Bf); + return MDOC_Bf; case MDOC_Ek: - return(MDOC_Bk); + return MDOC_Bk; case MDOC_El: - return(MDOC_Bl); + return MDOC_Bl; case MDOC_Fc: - return(MDOC_Fo); + return MDOC_Fo; case MDOC_Oc: - return(MDOC_Oo); + return MDOC_Oo; case MDOC_Pc: - return(MDOC_Po); + return MDOC_Po; case MDOC_Qc: - return(MDOC_Qo); + return MDOC_Qo; case MDOC_Re: - return(MDOC_Rs); + return MDOC_Rs; case MDOC_Sc: - return(MDOC_So); + return MDOC_So; case MDOC_Xc: - return(MDOC_Xo); + return MDOC_Xo; default: - return(tok); + return tok; } - /* NOTREACHED */ } static void -rew_elem(struct mdoc *mdoc, enum mdoct tok) +rew_elem(struct roff_man *mdoc, int tok) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; - if (MDOC_ELEM != n->type) + if (n->type != ROFFT_ELEM) n = n->parent; - assert(MDOC_ELEM == n->type); + assert(n->type == ROFFT_ELEM); assert(tok == n->tok); rew_last(mdoc, n); } /* + * If there is an open sub-block of the target requiring + * explicit close-out, postpone closing out the target until + * the rew_pending() call closing out the sub-block. + */ +static int +find_pending(struct roff_man *mdoc, int tok, int line, int ppos, + struct roff_node *target) +{ + struct roff_node *n; + int irc; + + irc = 0; + for (n = mdoc->last; n != NULL && n != target; n = n->parent) { + if (n->flags & MDOC_ENDED) { + if ( ! (n->flags & MDOC_VALID)) + n->flags |= MDOC_BROKEN; + continue; + } + if (n->type == ROFFT_BLOCK && + mdoc_macros[n->tok].flags & MDOC_EXPLICIT) { + irc = 1; + n->flags = MDOC_BROKEN; + if (target->type == ROFFT_HEAD) + target->flags = MDOC_ENDED; + else if ( ! (target->flags & MDOC_ENDED)) { + mandoc_vmsg(MANDOCERR_BLK_NEST, + mdoc->parse, line, ppos, + "%s breaks %s", mdoc_macronames[tok], + mdoc_macronames[n->tok]); + mdoc_endbody_alloc(mdoc, line, ppos, + tok, target, ENDBODY_NOSPACE); + } + } + } + return irc; +} + +/* * Allocate a word and check whether it's punctuation or not. * Punctuation consists of those tokens found in mdoc_isdelim(). */ static void -dword(struct mdoc *mdoc, int line, int col, const char *p, +dword(struct roff_man *mdoc, int line, int col, const char *p, enum mdelim d, int may_append) { @@ -387,13 +428,13 @@ dword(struct mdoc *mdoc, int line, int col, const char *p, if (may_append && ! (mdoc->flags & (MDOC_SYNOPSIS | MDOC_KEEP | MDOC_SMOFF)) && - d == DELIM_NONE && mdoc->last->type == MDOC_TEXT && + d == DELIM_NONE && mdoc->last->type == ROFFT_TEXT && mdoc_isdelim(mdoc->last->string) == DELIM_NONE) { - mdoc_word_append(mdoc, p); + roff_word_append(mdoc, p); return; } - mdoc_word_alloc(mdoc, line, col, p); + roff_word_alloc(mdoc, line, col, p); /* * If the word consists of a bare delimiter, @@ -412,7 +453,7 @@ dword(struct mdoc *mdoc, int line, int col, const char *p, } static void -append_delims(struct mdoc *mdoc, int line, int *pos, char *buf) +append_delims(struct roff_man *mdoc, int line, int *pos, char *buf) { char *p; int la; @@ -422,7 +463,8 @@ append_delims(struct mdoc *mdoc, int line, int *pos, char *buf) for (;;) { la = *pos; - if (mdoc_args(mdoc, line, pos, buf, MDOC_MAX, &p) == ARGS_EOLN) + if (mdoc_args(mdoc, line, pos, buf, TOKEN_NONE, &p) == + ARGS_EOLN) break; dword(mdoc, line, la, p, DELIM_MAX, 1); @@ -452,26 +494,26 @@ static int macro_or_word(MACRO_PROT_ARGS, int parsed) { char *p; - enum mdoct ntok; + int ntok; p = buf + ppos; - ntok = MDOC_MAX; + ntok = TOKEN_NONE; if (*p == '"') p++; else if (parsed && ! (mdoc->flags & MDOC_PHRASELIT)) ntok = lookup(mdoc, tok, line, ppos, p); - if (ntok == MDOC_MAX) { - dword(mdoc, line, ppos, p, DELIM_MAX, tok == MDOC_MAX || + if (ntok == TOKEN_NONE) { + dword(mdoc, line, ppos, p, DELIM_MAX, tok == TOKEN_NONE || mdoc_macros[tok].flags & MDOC_JOIN); - return(0); + return 0; } else { if (mdoc_macros[tok].fp == in_line_eoln) rew_elem(mdoc, tok); mdoc_macro(mdoc, ntok, line, ppos, pos, buf); - if (tok == MDOC_MAX) + if (tok == TOKEN_NONE) append_delims(mdoc, line, pos, buf); - return(1); + return 1; } } @@ -481,15 +523,16 @@ macro_or_word(MACRO_PROT_ARGS, int parsed) static void blk_exp_close(MACRO_PROT_ARGS) { - struct mdoc_node *body; /* Our own body. */ - struct mdoc_node *endbody; /* Our own end marker. */ - struct mdoc_node *itblk; /* An It block starting later. */ - struct mdoc_node *later; /* A sub-block starting later. */ - struct mdoc_node *n; /* Search back to our block. */ - - int j, lastarg, maxargs, nl; + struct roff_node *body; /* Our own body. */ + struct roff_node *endbody; /* Our own end marker. */ + struct roff_node *itblk; /* An It block starting later. */ + struct roff_node *later; /* A sub-block starting later. */ + struct roff_node *n; /* Search back to our block. */ + struct roff_node *target; /* For find_pending(). */ + + int j, lastarg, maxargs, nl, pending; enum margserr ac; - enum mdoct atok, ntok; + int atok, ntok; char *p; nl = MDOC_NEWLINE & mdoc->flags; @@ -522,13 +565,13 @@ blk_exp_close(MACRO_PROT_ARGS) /* Remember the start of our own body. */ - if (n->type == MDOC_BODY && atok == n->tok) { + if (n->type == ROFFT_BODY && atok == n->tok) { if (n->end == ENDBODY_NOT) body = n; continue; } - if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm) + if (n->type != ROFFT_BLOCK || n->tok == MDOC_Nm) continue; if (n->tok == MDOC_It) { @@ -575,7 +618,7 @@ blk_exp_close(MACRO_PROT_ARGS) */ if (maxargs) - mdoc->next = MDOC_NEXT_CHILD; + mdoc->next = ROFF_NEXT_CHILD; break; } @@ -596,12 +639,14 @@ blk_exp_close(MACRO_PROT_ARGS) if (body == NULL) { mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse, line, ppos, mdoc_macronames[tok]); + if (later != NULL) + later->flags &= ~MDOC_BROKEN; if (maxargs && endbody == NULL) { /* * Stray .Ec without previous .Eo: * Break the output line, keep the arguments. */ - mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL); + roff_elem_alloc(mdoc, line, ppos, MDOC_br); rew_elem(mdoc, MDOC_br); } } else if (endbody == NULL) { @@ -623,38 +668,47 @@ blk_exp_close(MACRO_PROT_ARGS) if (endbody != NULL) n = endbody; + + ntok = TOKEN_NONE; for (j = 0; ; j++) { lastarg = *pos; - if (j == maxargs && n != NULL) { - rew_pending(mdoc, n); - n = NULL; - } + if (j == maxargs && n != NULL) + rew_last(mdoc, n); ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ac == ARGS_PUNCT || ac == ARGS_EOLN) break; - ntok = ac == ARGS_QWORD ? MDOC_MAX : + ntok = ac == ARGS_QWORD ? TOKEN_NONE : lookup(mdoc, tok, line, lastarg, p); - if (ntok == MDOC_MAX) { + if (ntok == TOKEN_NONE) { dword(mdoc, line, lastarg, p, DELIM_MAX, MDOC_JOIN & mdoc_macros[tok].flags); continue; } - if (n != NULL) { - rew_pending(mdoc, n); - n = NULL; - } + if (n != NULL) + rew_last(mdoc, n); mdoc->flags &= ~MDOC_NEWLINE; mdoc_macro(mdoc, ntok, line, lastarg, pos, buf); break; } - if (n != NULL) - rew_pending(mdoc, n); + if (n != NULL) { + if (ntok != TOKEN_NONE && n->flags & MDOC_BROKEN) { + target = n; + do + target = target->parent; + while ( ! (target->flags & MDOC_ENDED)); + pending = find_pending(mdoc, ntok, line, ppos, + target); + } else + pending = 0; + if ( ! pending) + rew_pending(mdoc, n); + } if (nl) append_delims(mdoc, line, pos, buf); } @@ -663,7 +717,7 @@ static void in_line(MACRO_PROT_ARGS) { int la, scope, cnt, firstarg, mayopen, nc, nl; - enum mdoct ntok; + int ntok; enum margserr ac; enum mdelim d; struct mdoc_arg *arg; @@ -678,15 +732,10 @@ in_line(MACRO_PROT_ARGS) switch (tok) { case MDOC_An: - /* FALLTHROUGH */ case MDOC_Ar: - /* FALLTHROUGH */ case MDOC_Fl: - /* FALLTHROUGH */ case MDOC_Mt: - /* FALLTHROUGH */ case MDOC_Nm: - /* FALLTHROUGH */ case MDOC_Pa: nc = 1; break; @@ -730,7 +779,7 @@ in_line(MACRO_PROT_ARGS) } ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ? - MDOC_MAX : lookup(mdoc, tok, line, la, p); + TOKEN_NONE : lookup(mdoc, tok, line, la, p); /* * In this case, we've located a submacro and must @@ -739,7 +788,7 @@ in_line(MACRO_PROT_ARGS) * or raise a warning. */ - if (ntok != MDOC_MAX) { + if (ntok != TOKEN_NONE) { if (scope) rew_elem(mdoc, tok); if (nc && ! cnt) { @@ -847,10 +896,10 @@ blk_full(MACRO_PROT_ARGS) { int la, nl, parsed; struct mdoc_arg *arg; - struct mdoc_node *blk; /* Our own or a broken block. */ - struct mdoc_node *head; /* Our own head. */ - struct mdoc_node *body; /* Our own body. */ - struct mdoc_node *n; + struct roff_node *blk; /* Our own or a broken block. */ + struct roff_node *head; /* Our own head. */ + struct roff_node *body; /* Our own body. */ + struct roff_node *n; enum margserr ac, lac; char *p; @@ -873,7 +922,7 @@ blk_full(MACRO_PROT_ARGS) n->flags |= MDOC_BROKEN; continue; } - if (n->type != MDOC_BLOCK) + if (n->type != ROFFT_BLOCK) continue; if (tok == MDOC_It && n->tok == MDOC_Bl) { @@ -890,7 +939,6 @@ blk_full(MACRO_PROT_ARGS) if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) { switch (tok) { case MDOC_Sh: - /* FALLTHROUGH */ case MDOC_Ss: mandoc_vmsg(MANDOCERR_BLK_BROKEN, mdoc->parse, line, ppos, @@ -938,7 +986,7 @@ blk_full(MACRO_PROT_ARGS) if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) { mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse, line, ppos, "It %s", buf + *pos); - mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL); + roff_elem_alloc(mdoc, line, ppos, MDOC_br); rew_elem(mdoc, MDOC_br); return; } @@ -972,34 +1020,47 @@ blk_full(MACRO_PROT_ARGS) */ if (tok == MDOC_Nd) { - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); rew_last(mdoc, head); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); } if (tok == MDOC_Bk) mdoc->flags |= MDOC_KEEP; - ac = ARGS_PEND; + ac = ARGS_EOLN; for (;;) { + + /* + * If we are right after a tab character, + * do not parse the first word for macros. + */ + + if (mdoc->flags & MDOC_PHRASEQN) { + mdoc->flags &= ~MDOC_PHRASEQN; + mdoc->flags |= MDOC_PHRASEQF; + } + la = *pos; lac = ac; ac = mdoc_args(mdoc, line, pos, buf, tok, &p); if (ac == ARGS_EOLN) { - if (lac != ARGS_PPHRASE && lac != ARGS_PHRASE) + if (lac != ARGS_PHRASE || + ! (mdoc->flags & MDOC_PHRASEQF)) break; + /* - * This is necessary: if the last token on a - * line is a `Ta' or tab, then we'll get - * ARGS_EOLN, so we must be smart enough to - * reopen our scope if the last parse was a - * phrase or partial phrase. + * This line ends in a tab; start the next + * column now, with a leading blank. */ + if (body != NULL) rew_last(mdoc, body); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); + roff_word_alloc(mdoc, line, ppos, "\\&"); break; } + if (tok == MDOC_Bd || tok == MDOC_Bk) { mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, line, la, "%s ... %s", @@ -1016,13 +1077,11 @@ blk_full(MACRO_PROT_ARGS) /* * Emit leading punctuation (i.e., punctuation before - * the MDOC_HEAD) for non-phrase types. + * the ROFFT_HEAD) for non-phrase types. */ if (head == NULL && - ac != ARGS_PEND && ac != ARGS_PHRASE && - ac != ARGS_PPHRASE && ac != ARGS_QWORD && mdoc_isdelim(p) == DELIM_OPEN) { dword(mdoc, line, la, p, DELIM_OPEN, 0); @@ -1032,11 +1091,9 @@ blk_full(MACRO_PROT_ARGS) /* Open a head if one hasn't been opened. */ if (head == NULL) - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); - if (ac == ARGS_PHRASE || - ac == ARGS_PEND || - ac == ARGS_PPHRASE) { + if (ac == ARGS_PHRASE) { /* * If we haven't opened a body yet, rewind the @@ -1044,20 +1101,18 @@ blk_full(MACRO_PROT_ARGS) */ rew_last(mdoc, body == NULL ? head : body); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); - /* - * Process phrases: set whether we're in a - * partial-phrase (this effects line handling) - * then call down into the phrase parser. - */ + /* Process to the tab or to the end of the line. */ - if (ac == ARGS_PPHRASE) - mdoc->flags |= MDOC_PPHRASE; - if (ac == ARGS_PEND && lac == ARGS_PPHRASE) - mdoc->flags |= MDOC_PPHRASE; - parse_rest(mdoc, MDOC_MAX, line, &la, buf); - mdoc->flags &= ~MDOC_PPHRASE; + mdoc->flags |= MDOC_PHRASE; + parse_rest(mdoc, TOKEN_NONE, line, &la, buf); + mdoc->flags &= ~MDOC_PHRASE; + + /* There may have been `Ta' macros. */ + + while (body->next != NULL) + body = body->next; continue; } @@ -1068,37 +1123,18 @@ blk_full(MACRO_PROT_ARGS) if (blk->flags & MDOC_VALID) return; if (head == NULL) - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); if (nl && tok != MDOC_Bd && tok != MDOC_Bl && tok != MDOC_Rs) append_delims(mdoc, line, pos, buf); if (body != NULL) goto out; - - /* - * If there is an open (i.e., unvalidated) sub-block requiring - * explicit close-out, postpone switching the current block from - * head to body until the rew_pending() call closing out that - * sub-block. - */ - for (n = mdoc->last; n && n != head; n = n->parent) { - if (n->flags & MDOC_ENDED) { - if ( ! (n->flags & MDOC_VALID)) - n->flags |= MDOC_BROKEN; - continue; - } - if (n->type == MDOC_BLOCK && - mdoc_macros[n->tok].flags & MDOC_EXPLICIT) { - n->flags = MDOC_BROKEN; - head->flags = MDOC_ENDED; - } - } - if (head->flags & MDOC_ENDED) + if (find_pending(mdoc, tok, line, ppos, head)) return; /* Close out scopes to remain in a consistent state. */ rew_last(mdoc, head); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); out: if (mdoc->flags & MDOC_FREECOL) { rew_last(mdoc, body); @@ -1113,9 +1149,9 @@ blk_part_imp(MACRO_PROT_ARGS) int la, nl; enum margserr ac; char *p; - struct mdoc_node *blk; /* saved block context */ - struct mdoc_node *body; /* saved body context */ - struct mdoc_node *n; + struct roff_node *blk; /* saved block context */ + struct roff_node *body; /* saved body context */ + struct roff_node *n; nl = MDOC_NEWLINE & mdoc->flags; @@ -1129,7 +1165,7 @@ blk_part_imp(MACRO_PROT_ARGS) */ blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL); - rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok)); + rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok)); /* * Open the body scope "on-demand", that is, after we've @@ -1150,42 +1186,15 @@ blk_part_imp(MACRO_PROT_ARGS) } if (body == NULL) - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); if (macro_or_word(mdoc, tok, line, la, pos, buf, 1)) break; } if (body == NULL) - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); - /* - * If there is an open sub-block requiring explicit close-out, - * postpone closing out the current block until the - * rew_pending() call closing out the sub-block. - */ - - for (n = mdoc->last; n && n != body && n != blk->parent; - n = n->parent) { - if (n->flags & MDOC_ENDED) { - if ( ! (n->flags & MDOC_VALID)) - n->flags |= MDOC_BROKEN; - continue; - } - if (n->type == MDOC_BLOCK && - mdoc_macros[n->tok].flags & MDOC_EXPLICIT) { - n->flags |= MDOC_BROKEN; - if ( ! (body->flags & MDOC_ENDED)) { - mandoc_vmsg(MANDOCERR_BLK_NEST, - mdoc->parse, line, ppos, - "%s breaks %s", mdoc_macronames[tok], - mdoc_macronames[n->tok]); - mdoc_endbody_alloc(mdoc, line, ppos, - tok, body, ENDBODY_NOSPACE); - } - } - } - assert(n == body); - if (body->flags & MDOC_ENDED) + if (find_pending(mdoc, tok, line, ppos, body)) return; rew_last(mdoc, body); @@ -1206,7 +1215,7 @@ blk_part_exp(MACRO_PROT_ARGS) { int la, nl; enum margserr ac; - struct mdoc_node *head; /* keep track of head */ + struct roff_node *head; /* keep track of head */ char *p; nl = MDOC_NEWLINE & mdoc->flags; @@ -1217,7 +1226,7 @@ blk_part_exp(MACRO_PROT_ARGS) * case of `Eo'); and a body that may be empty. */ - mdoc_block_alloc(mdoc, line, ppos, tok, NULL); + roff_block_alloc(mdoc, line, ppos, tok); head = NULL; for (;;) { la = *pos; @@ -1234,11 +1243,11 @@ blk_part_exp(MACRO_PROT_ARGS) } if (head == NULL) { - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); if (tok == MDOC_Eo) /* Not parsed. */ dword(mdoc, line, la, p, DELIM_MAX, 0); rew_last(mdoc, head); - mdoc_body_alloc(mdoc, line, ppos, tok); + roff_body_alloc(mdoc, line, ppos, tok); if (tok == MDOC_Eo) continue; } @@ -1250,8 +1259,8 @@ blk_part_exp(MACRO_PROT_ARGS) /* Clean-up to leave in a consistent state. */ if (head == NULL) { - rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok)); - mdoc_body_alloc(mdoc, line, ppos, tok); + rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok)); + roff_body_alloc(mdoc, line, ppos, tok); } if (nl) append_delims(mdoc, line, pos, buf); @@ -1263,7 +1272,7 @@ in_line_argn(MACRO_PROT_ARGS) struct mdoc_arg *arg; char *p; enum margserr ac; - enum mdoct ntok; + int ntok; int state; /* arg#; -1: not yet open; -2: closed */ int la, maxargs, nl; @@ -1279,16 +1288,12 @@ in_line_argn(MACRO_PROT_ARGS) switch (tok) { case MDOC_Ap: - /* FALLTHROUGH */ case MDOC_Ns: - /* FALLTHROUGH */ case MDOC_Ux: maxargs = 0; break; case MDOC_Bx: - /* FALLTHROUGH */ case MDOC_Es: - /* FALLTHROUGH */ case MDOC_Xr: maxargs = 2; break; @@ -1332,9 +1337,9 @@ in_line_argn(MACRO_PROT_ARGS) } ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && state == 0)) ? - MDOC_MAX : lookup(mdoc, tok, line, la, p); + TOKEN_NONE : lookup(mdoc, tok, line, la, p); - if (ntok != MDOC_MAX) { + if (ntok != TOKEN_NONE) { if (state >= 0) { rew_elem(mdoc, tok); state = -2; @@ -1377,16 +1382,16 @@ in_line_argn(MACRO_PROT_ARGS) static void in_line_eoln(MACRO_PROT_ARGS) { - struct mdoc_node *n; + struct roff_node *n; struct mdoc_arg *arg; if ((tok == MDOC_Pp || tok == MDOC_Lp) && ! (mdoc->flags & MDOC_SYNOPSIS)) { n = mdoc->last; - if (mdoc->next == MDOC_NEXT_SIBLING) + if (mdoc->next == ROFF_NEXT_SIBLING) n = n->parent; if (n->tok == MDOC_Nm) - rew_last(mdoc, mdoc->last->parent); + rew_last(mdoc, n->parent); } if (buf[*pos] == '\0' && @@ -1409,16 +1414,16 @@ in_line_eoln(MACRO_PROT_ARGS) * or until the next macro, call that macro, and return 1. */ static int -parse_rest(struct mdoc *mdoc, enum mdoct tok, int line, int *pos, char *buf) +parse_rest(struct roff_man *mdoc, int tok, int line, int *pos, char *buf) { int la; for (;;) { la = *pos; if (mdoc_args(mdoc, line, pos, buf, tok, NULL) == ARGS_EOLN) - return(0); + return 0; if (macro_or_word(mdoc, tok, line, la, pos, buf, 1)) - return(1); + return 1; } } @@ -1444,7 +1449,7 @@ ctx_synopsis(MACRO_PROT_ARGS) static void phrase_ta(MACRO_PROT_ARGS) { - struct mdoc_node *body, *n; + struct roff_node *body, *n; /* Make sure we are in a column list or ignore this macro. */ @@ -1452,7 +1457,7 @@ phrase_ta(MACRO_PROT_ARGS) for (n = mdoc->last; n != NULL; n = n->parent) { if (n->flags & MDOC_ENDED) continue; - if (n->tok == MDOC_It && n->type == MDOC_BODY) + if (n->tok == MDOC_It && n->type == ROFFT_BODY) body = n; if (n->tok == MDOC_Bl) break; @@ -1467,6 +1472,6 @@ phrase_ta(MACRO_PROT_ARGS) /* Advance to the next column. */ rew_last(mdoc, body); - mdoc_body_alloc(mdoc, line, ppos, MDOC_It); - parse_rest(mdoc, MDOC_MAX, line, pos, buf); + roff_body_alloc(mdoc, line, ppos, MDOC_It); + parse_rest(mdoc, TOKEN_NONE, line, pos, buf); } diff --git a/contrib/mdocml/mdoc_man.c b/contrib/mdocml/mdoc_man.c index 9c086a5..ab24531 100644 --- a/contrib/mdocml/mdoc_man.c +++ b/contrib/mdocml/mdoc_man.c @@ -1,6 +1,6 @@ -/* $Id: mdoc_man.c,v 1.88 2015/02/17 20:37:17 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.96 2016/01/08 17:48:09 schwarze Exp $ */ /* - * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2016 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 @@ -22,14 +22,15 @@ #include <stdio.h> #include <string.h> -#include "mandoc.h" #include "mandoc_aux.h" -#include "out.h" -#include "man.h" +#include "mandoc.h" +#include "roff.h" #include "mdoc.h" +#include "man.h" +#include "out.h" #include "main.h" -#define DECL_ARGS const struct mdoc_meta *meta, struct mdoc_node *n +#define DECL_ARGS const struct roff_meta *meta, struct roff_node *n struct manact { int (*cond)(DECL_ARGS); /* DON'T run actions */ @@ -107,7 +108,7 @@ static int pre_sm(DECL_ARGS); static int pre_sp(DECL_ARGS); static int pre_sect(DECL_ARGS); static int pre_sy(DECL_ARGS); -static void pre_syn(const struct mdoc_node *); +static void pre_syn(const struct roff_node *); static int pre_vt(DECL_ARGS); static int pre_ux(DECL_ARGS); static int pre_xr(DECL_ARGS); @@ -116,7 +117,7 @@ static void print_line(const char *, int); static void print_block(const char *, int); static void print_offs(const char *, int); static void print_width(const struct mdoc_bl *, - const struct mdoc_node *); + const struct roff_node *); static void print_count(int *); static void print_node(DECL_ARGS); @@ -467,7 +468,7 @@ print_offs(const char *v, int keywords) * Set up the indentation for a list item; used from pre_it(). */ static void -print_width(const struct mdoc_bl *bl, const struct mdoc_node *child) +print_width(const struct mdoc_bl *bl, const struct roff_node *child) { char buf[24]; struct roffsu su; @@ -492,7 +493,7 @@ print_width(const struct mdoc_bl *bl, const struct mdoc_node *child) /* XXX Rough estimation, might have multiple parts. */ if (bl->type == LIST_enum) chsz = (bl->count > 8) + 1; - else if (child != NULL && child->type == MDOC_TEXT) + else if (child != NULL && child->type == ROFFT_TEXT) chsz = strlen(child->string); else chsz = 0; @@ -531,7 +532,7 @@ print_count(int *count) } void -man_man(void *arg, const struct man *man) +man_man(void *arg, const struct roff_man *man) { /* @@ -544,18 +545,14 @@ man_man(void *arg, const struct man *man) } void -man_mdoc(void *arg, const struct mdoc *mdoc) +man_mdoc(void *arg, const struct roff_man *mdoc) { - const struct mdoc_meta *meta; - struct mdoc_node *n; - - meta = mdoc_meta(mdoc); - n = mdoc_node(mdoc)->child; + struct roff_node *n; printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n", - meta->title, - (meta->msec == NULL ? "" : meta->msec), - meta->date, meta->os, meta->vol); + mdoc->meta.title, + (mdoc->meta.msec == NULL ? "" : mdoc->meta.msec), + mdoc->meta.date, mdoc->meta.os, mdoc->meta.vol); /* Disable hyphenation and if nroff, disable justification. */ printf(".nh\n.if n .ad l"); @@ -566,10 +563,8 @@ man_mdoc(void *arg, const struct mdoc *mdoc) fontqueue.head = fontqueue.tail = mandoc_malloc(8); *fontqueue.tail = 'R'; } - while (n != NULL) { - print_node(meta, n); - n = n->next; - } + for (n = mdoc->first->child; n != NULL; n = n->next) + print_node(&mdoc->meta, n); putchar('\n'); } @@ -577,7 +572,7 @@ static void print_node(DECL_ARGS) { const struct manact *act; - struct mdoc_node *sub; + struct roff_node *sub; int cond, do_sub; /* @@ -592,7 +587,7 @@ print_node(DECL_ARGS) do_sub = 1; n->flags &= ~MDOC_ENDED; - if (MDOC_TEXT == n->type) { + if (n->type == ROFFT_TEXT) { /* * Make sure that we don't happen to start with a * control character at the start of a line. @@ -615,7 +610,8 @@ print_node(DECL_ARGS) */ act = manacts + n->tok; cond = act->cond == NULL || (*act->cond)(meta, n); - if (cond && act->pre && (n->end == ENDBODY_NOT || n->nchild)) + if (cond && act->pre != NULL && + (n->end == ENDBODY_NOT || n->child != NULL)) do_sub = (*act->pre)(meta, n); } @@ -648,14 +644,14 @@ static int cond_head(DECL_ARGS) { - return(MDOC_HEAD == n->type); + return n->type == ROFFT_HEAD; } static int cond_body(DECL_ARGS) { - return(MDOC_BODY == n->type); + return n->type == ROFFT_BODY; } static int @@ -665,10 +661,10 @@ pre_enc(DECL_ARGS) prefix = manacts[n->tok].prefix; if (NULL == prefix) - return(1); + return 1; print_word(prefix); outflags &= ~MMAN_spc; - return(1); + return 1; } static void @@ -686,37 +682,36 @@ post_enc(DECL_ARGS) static int pre_ex(DECL_ARGS) { - int nchild; + struct roff_node *nch; outflags |= MMAN_br | MMAN_nl; print_word("The"); - nchild = n->nchild; - for (n = n->child; n; n = n->next) { + for (nch = n->child; nch != NULL; nch = nch->next) { font_push('B'); - print_word(n->string); + print_word(nch->string); font_pop(); - if (n->next == NULL) + if (nch->next == NULL) continue; - if (nchild > 2) { + if (nch->prev != NULL || nch->next->next != NULL) { outflags &= ~MMAN_spc; print_word(","); } - if (n->next->next == NULL) + if (nch->next->next == NULL) print_word("and"); } - if (nchild > 1) + if (n->child != NULL && n->child->next != NULL) print_word("utilities exit\\~0"); else print_word("utility exits\\~0"); print_word("on success, and\\~>0 if an error occurs."); outflags |= MMAN_nl; - return(0); + return 0; } static void @@ -754,7 +749,7 @@ pre__t(DECL_ARGS) outflags &= ~MMAN_spc; } else font_push('I'); - return(1); + return 1; } static void @@ -778,14 +773,14 @@ static int pre_sect(DECL_ARGS) { - if (MDOC_HEAD == n->type) { + if (n->type == ROFFT_HEAD) { outflags |= MMAN_sp; print_block(manacts[n->tok].prefix, 0); print_word(""); putchar('\"'); outflags &= ~MMAN_spc; } - return(1); + return 1; } /* @@ -795,7 +790,7 @@ static void post_sect(DECL_ARGS) { - if (MDOC_HEAD != n->type) + if (n->type != ROFFT_HEAD) return; outflags &= ~MMAN_spc; print_word(""); @@ -807,7 +802,7 @@ post_sect(DECL_ARGS) /* See mdoc_term.c, synopsis_pre() for comments. */ static void -pre_syn(const struct mdoc_node *n) +pre_syn(const struct roff_node *n) { if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) @@ -823,13 +818,9 @@ pre_syn(const struct mdoc_node *n) switch (n->prev->tok) { case MDOC_Fd: - /* FALLTHROUGH */ case MDOC_Fn: - /* FALLTHROUGH */ case MDOC_Fo: - /* FALLTHROUGH */ case MDOC_In: - /* FALLTHROUGH */ case MDOC_Vt: outflags |= MMAN_sp; break; @@ -853,18 +844,18 @@ pre_an(DECL_ARGS) case AUTH_split: outflags &= ~MMAN_An_nosplit; outflags |= MMAN_An_split; - return(0); + return 0; case AUTH_nosplit: outflags &= ~MMAN_An_split; outflags |= MMAN_An_nosplit; - return(0); + return 0; default: if (MMAN_An_split & outflags) outflags |= MMAN_br; else if (SEC_AUTHORS == n->sec && ! (MMAN_An_nosplit & outflags)) outflags |= MMAN_An_split; - return(1); + return 1; } } @@ -875,17 +866,17 @@ pre_ap(DECL_ARGS) outflags &= ~MMAN_spc; print_word("'"); outflags &= ~MMAN_spc; - return(0); + return 0; } static int pre_aq(DECL_ARGS) { - print_word(n->nchild == 1 && + print_word(n->child != NULL && n->child->next == NULL && n->child->tok == MDOC_Mt ? "<" : "\\(la"); outflags &= ~MMAN_spc; - return(1); + return 1; } static void @@ -893,7 +884,7 @@ post_aq(DECL_ARGS) { outflags &= ~(MMAN_spc | MMAN_nl); - print_word(n->nchild == 1 && + print_word(n->child != NULL && n->child->next == NULL && n->child->tok == MDOC_Mt ? ">" : "\\(ra"); } @@ -909,7 +900,7 @@ pre_bd(DECL_ARGS) if (0 == n->norm->Bd.comp && NULL != n->parent->prev) outflags |= MMAN_sp; print_offs(n->norm->Bd.offs, 1); - return(1); + return 1; } static void @@ -932,12 +923,12 @@ pre_bf(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: - return(1); - case MDOC_BODY: + case ROFFT_BLOCK: + return 1; + case ROFFT_BODY: break; default: - return(0); + return 0; } switch (n->norm->Bf.font) { case FONT_Em: @@ -950,14 +941,14 @@ pre_bf(DECL_ARGS) font_push('R'); break; } - return(1); + return 1; } static void post_bf(DECL_ARGS) { - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) font_pop(); } @@ -966,13 +957,13 @@ pre_bk(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: - return(1); - case MDOC_BODY: + case ROFFT_BLOCK: + return 1; + case ROFFT_BODY: outflags |= MMAN_Bk; - return(1); + return 1; default: - return(0); + return 0; } } @@ -980,7 +971,7 @@ static void post_bk(DECL_ARGS) { - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) outflags &= ~MMAN_Bk; } @@ -1002,21 +993,21 @@ pre_bl(DECL_ARGS) switch (n->norm->Bl.type) { case LIST_enum: n->norm->Bl.count = 0; - return(1); + return 1; case LIST_column: break; default: - return(1); + return 1; } - if (n->nchild) { + if (n->child != NULL) { print_line(".TS", MMAN_nl); for (icol = 0; icol < n->norm->Bl.ncols; icol++) print_word("l"); print_word("."); } outflags |= MMAN_nl; - return(1); + return 1; } static void @@ -1025,7 +1016,7 @@ post_bl(DECL_ARGS) switch (n->norm->Bl.type) { case LIST_column: - if (n->nchild) + if (n->child != NULL) print_line(".TE", 0); break; case LIST_enum: @@ -1056,7 +1047,7 @@ pre_br(DECL_ARGS) { outflags |= MMAN_br; - return(0); + return 0; } static int @@ -1071,12 +1062,12 @@ pre_bx(DECL_ARGS) } print_word("BSD"); if (NULL == n) - return(0); + return 0; outflags &= ~MMAN_spc; print_word("-"); outflags &= ~MMAN_spc; print_word(n->string); - return(0); + return 0; } static int @@ -1084,7 +1075,7 @@ pre_dl(DECL_ARGS) { print_offs("6n", 0); - return(1); + return 1; } static void @@ -1103,7 +1094,7 @@ pre_em(DECL_ARGS) { font_push('I'); - return(1); + return 1; } static int @@ -1112,11 +1103,11 @@ pre_en(DECL_ARGS) if (NULL == n->norm->Es || NULL == n->norm->Es->child) - return(1); + return 1; print_word(n->norm->Es->child->string); outflags &= ~MMAN_spc; - return(1); + return 1; } static void @@ -1146,7 +1137,7 @@ pre_eo(DECL_ARGS) n->parent->head->child != NULL && (n->child != NULL || (n->parent->tail != NULL && n->parent->tail->child != NULL))) outflags &= ~(MMAN_spc | MMAN_nl); - return(1); + return 1; } static void @@ -1189,7 +1180,7 @@ pre_fa(DECL_ARGS) if (NULL != (n = n->next)) print_word(","); } - return(0); + return 0; } static void @@ -1206,7 +1197,7 @@ pre_fd(DECL_ARGS) pre_syn(n); font_push('B'); - return(1); + return 1; } static void @@ -1223,9 +1214,9 @@ pre_fl(DECL_ARGS) font_push('B'); print_word("\\-"); - if (n->nchild) + if (n->child != NULL) outflags &= ~MMAN_spc; - return(1); + return 1; } static void @@ -1233,9 +1224,9 @@ post_fl(DECL_ARGS) { font_pop(); - if ( ! (n->nchild || + if (!(n->child != NULL || n->next == NULL || - n->next->type == MDOC_TEXT || + n->next->type == ROFFT_TEXT || n->next->flags & MDOC_LINE)) outflags &= ~MMAN_spc; } @@ -1248,7 +1239,7 @@ pre_fn(DECL_ARGS) n = n->child; if (NULL == n) - return(0); + return 0; if (MDOC_SYNPRETTY & n->flags) print_block(".HP 4n", MMAN_nl); @@ -1263,7 +1254,7 @@ pre_fn(DECL_ARGS) n = n->next; if (NULL != n) pre_fa(meta, n); - return(0); + return 0; } static void @@ -1282,17 +1273,17 @@ pre_fo(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: pre_syn(n); break; - case MDOC_HEAD: + case ROFFT_HEAD: if (n->child == NULL) - return(0); + return 0; if (MDOC_SYNPRETTY & n->flags) print_block(".HP 4n", MMAN_nl); font_push('B'); break; - case MDOC_BODY: + case ROFFT_BODY: outflags &= ~(MMAN_spc | MMAN_nl); print_word("("); outflags &= ~MMAN_spc; @@ -1300,7 +1291,7 @@ pre_fo(DECL_ARGS) default: break; } - return(1); + return 1; } static void @@ -1308,11 +1299,11 @@ post_fo(DECL_ARGS) { switch (n->type) { - case MDOC_HEAD: + case ROFFT_HEAD: if (n->child != NULL) font_pop(); break; - case MDOC_BODY: + case ROFFT_BODY: post_fn(meta, n); break; default: @@ -1326,7 +1317,7 @@ pre_ft(DECL_ARGS) pre_syn(n); font_push('I'); - return(1); + return 1; } static int @@ -1343,7 +1334,7 @@ pre_in(DECL_ARGS) outflags &= ~MMAN_spc; font_push('I'); } - return(1); + return 1; } static void @@ -1365,10 +1356,10 @@ post_in(DECL_ARGS) static int pre_it(DECL_ARGS) { - const struct mdoc_node *bln; + const struct roff_node *bln; switch (n->type) { - case MDOC_HEAD: + case ROFFT_HEAD: outflags |= MMAN_PP | MMAN_nl; bln = n->parent->parent; if (0 == bln->norm->Bl.comp || @@ -1378,22 +1369,18 @@ pre_it(DECL_ARGS) outflags &= ~MMAN_br; switch (bln->norm->Bl.type) { case LIST_item: - return(0); + return 0; case LIST_inset: - /* FALLTHROUGH */ case LIST_diag: - /* FALLTHROUGH */ case LIST_ohang: if (bln->norm->Bl.type == LIST_diag) print_line(".B \"", 0); else print_line(".R \"", 0); outflags &= ~MMAN_spc; - return(1); + return 1; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: print_width(&bln->norm->Bl, NULL); TPremain = 0; @@ -1405,31 +1392,31 @@ pre_it(DECL_ARGS) print_word("-"); font_pop(); outflags |= MMAN_nl; - return(0); + return 0; case LIST_enum: print_width(&bln->norm->Bl, NULL); TPremain = 0; outflags |= MMAN_nl; print_count(&bln->norm->Bl.count); outflags |= MMAN_nl; - return(0); + return 0; case LIST_hang: print_width(&bln->norm->Bl, n->child); TPremain = 0; outflags |= MMAN_nl; - return(1); + return 1; case LIST_tag: print_width(&bln->norm->Bl, n->child); putchar('\n'); outflags &= ~MMAN_spc; - return(1); + return 1; default: - return(1); + return 1; } default: break; } - return(1); + return 1; } /* @@ -1462,12 +1449,12 @@ mid_it(void) static void post_it(DECL_ARGS) { - const struct mdoc_node *bln; + const struct roff_node *bln; bln = n->parent->parent; switch (n->type) { - case MDOC_HEAD: + case ROFFT_HEAD: switch (bln->norm->Bl.type) { case LIST_diag: outflags &= ~MMAN_spc; @@ -1480,18 +1467,13 @@ post_it(DECL_ARGS) break; } break; - case MDOC_BODY: + case ROFFT_BODY: switch (bln->norm->Bl.type) { case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_enum: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_tag: assert(Bl_stack_len); Bl_stack[--Bl_stack_len] = 0; @@ -1532,10 +1514,10 @@ post_lb(DECL_ARGS) static int pre_lk(DECL_ARGS) { - const struct mdoc_node *link, *descr; + const struct roff_node *link, *descr; if (NULL == (link = n->child)) - return(0); + return 0; if (NULL != (descr = link->next)) { font_push('I'); @@ -1550,7 +1532,7 @@ pre_lk(DECL_ARGS) font_push('B'); print_word(link->string); font_pop(); - return(0); + return 0; } static int @@ -1558,7 +1540,7 @@ pre_ll(DECL_ARGS) { print_line(".ll", 0); - return(1); + return 1; } static int @@ -1566,7 +1548,7 @@ pre_li(DECL_ARGS) { font_push('R'); - return(1); + return 1; } static int @@ -1574,16 +1556,16 @@ pre_nm(DECL_ARGS) { char *name; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { outflags |= MMAN_Bk; pre_syn(n); } - if (MDOC_ELEM != n->type && MDOC_HEAD != n->type) - return(1); + if (n->type != ROFFT_ELEM && n->type != ROFFT_HEAD) + return 1; name = n->child ? n->child->string : meta->name; if (NULL == name) - return(0); - if (MDOC_HEAD == n->type) { + return 0; + if (n->type == ROFFT_HEAD) { if (NULL == n->parent->prev) outflags |= MMAN_sp; print_block(".HP", 0); @@ -1593,7 +1575,7 @@ pre_nm(DECL_ARGS) font_push('B'); if (NULL == n->child) print_word(meta->name); - return(1); + return 1; } static void @@ -1601,12 +1583,11 @@ post_nm(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: outflags &= ~MMAN_Bk; break; - case MDOC_HEAD: - /* FALLTHROUGH */ - case MDOC_ELEM: + case ROFFT_HEAD: + case ROFFT_ELEM: if (n->child != NULL || meta->name != NULL) font_pop(); break; @@ -1620,7 +1601,7 @@ pre_no(DECL_ARGS) { outflags |= MMAN_spc_force; - return(1); + return 1; } static int @@ -1628,7 +1609,7 @@ pre_ns(DECL_ARGS) { outflags &= ~MMAN_spc; - return(0); + return 0; } static void @@ -1647,7 +1628,7 @@ pre_pp(DECL_ARGS) outflags |= MMAN_PP; outflags |= MMAN_sp | MMAN_nl; outflags &= ~MMAN_br; - return(0); + return 0; } static int @@ -1658,40 +1639,39 @@ pre_rs(DECL_ARGS) outflags |= MMAN_PP | MMAN_sp | MMAN_nl; outflags &= ~MMAN_br; } - return(1); + return 1; } static int pre_rv(DECL_ARGS) { - int nchild; + struct roff_node *nch; outflags |= MMAN_br | MMAN_nl; - nchild = n->nchild; - if (nchild > 0) { + if (n->child != NULL) { print_word("The"); - for (n = n->child; n; n = n->next) { + for (nch = n->child; nch != NULL; nch = nch->next) { font_push('B'); - print_word(n->string); + print_word(nch->string); font_pop(); outflags &= ~MMAN_spc; print_word("()"); - if (n->next == NULL) + if (nch->next == NULL) continue; - if (nchild > 2) { + if (nch->prev != NULL || nch->next->next != NULL) { outflags &= ~MMAN_spc; print_word(","); } - if (n->next->next == NULL) + if (nch->next->next == NULL) print_word("and"); } - if (nchild > 1) + if (n->child != NULL && n->child->next != NULL) print_word("functions return"); else print_word("function returns"); @@ -1710,14 +1690,14 @@ pre_rv(DECL_ARGS) print_word("is set to indicate the error."); outflags |= MMAN_nl; - return(0); + return 0; } static int pre_skip(DECL_ARGS) { - return(0); + return 0; } static int @@ -1734,7 +1714,7 @@ pre_sm(DECL_ARGS) if (MMAN_Sm & outflags) outflags |= MMAN_spc; - return(0); + return 0; } static int @@ -1746,7 +1726,7 @@ pre_sp(DECL_ARGS) print_line(".PP", 0); } else print_line(".sp", 0); - return(1); + return 1; } static void @@ -1761,7 +1741,7 @@ pre_sy(DECL_ARGS) { font_push('B'); - return(1); + return 1; } static int @@ -1770,24 +1750,24 @@ pre_vt(DECL_ARGS) if (MDOC_SYNPRETTY & n->flags) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: pre_syn(n); - return(1); - case MDOC_BODY: + return 1; + case ROFFT_BODY: break; default: - return(0); + return 0; } } font_push('I'); - return(1); + return 1; } static void post_vt(DECL_ARGS) { - if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type) + if (n->flags & MDOC_SYNPRETTY && n->type != ROFFT_BODY) return; font_pop(); } @@ -1798,16 +1778,16 @@ pre_xr(DECL_ARGS) n = n->child; if (NULL == n) - return(0); + return 0; print_node(meta, n); n = n->next; if (NULL == n) - return(0); + return 0; outflags &= ~MMAN_spc; print_word("("); print_node(meta, n); print_word(")"); - return(0); + return 0; } static int @@ -1816,9 +1796,9 @@ pre_ux(DECL_ARGS) print_word(manacts[n->tok].prefix); if (NULL == n->child) - return(0); + return 0; outflags &= ~MMAN_spc; print_word("\\ "); outflags &= ~MMAN_spc; - return(1); + return 1; } diff --git a/contrib/mdocml/mdoc_state.c b/contrib/mdocml/mdoc_state.c new file mode 100644 index 0000000..cbd7376 --- /dev/null +++ b/contrib/mdocml/mdoc_state.c @@ -0,0 +1,292 @@ +/* $Id: mdoc_state.c,v 1.3 2015/10/30 18:53:54 schwarze Exp $ */ +/* + * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <sys/types.h> + +#include <stdlib.h> +#include <string.h> + +#include "mandoc.h" +#include "roff.h" +#include "mdoc.h" +#include "libmandoc.h" +#include "libmdoc.h" + +#define STATE_ARGS struct roff_man *mdoc, struct roff_node *n + +typedef void (*state_handler)(STATE_ARGS); + +static void state_bd(STATE_ARGS); +static void state_bl(STATE_ARGS); +static void state_dl(STATE_ARGS); +static void state_sh(STATE_ARGS); +static void state_sm(STATE_ARGS); + +static const state_handler state_handlers[MDOC_MAX] = { + NULL, /* Ap */ + NULL, /* Dd */ + NULL, /* Dt */ + NULL, /* Os */ + state_sh, /* Sh */ + NULL, /* Ss */ + NULL, /* Pp */ + NULL, /* D1 */ + state_dl, /* Dl */ + state_bd, /* Bd */ + NULL, /* Ed */ + state_bl, /* Bl */ + NULL, /* El */ + NULL, /* It */ + NULL, /* Ad */ + NULL, /* An */ + NULL, /* Ar */ + NULL, /* Cd */ + NULL, /* Cm */ + NULL, /* Dv */ + NULL, /* Er */ + NULL, /* Ev */ + NULL, /* Ex */ + NULL, /* Fa */ + NULL, /* Fd */ + NULL, /* Fl */ + NULL, /* Fn */ + NULL, /* Ft */ + NULL, /* Ic */ + NULL, /* In */ + NULL, /* Li */ + NULL, /* Nd */ + NULL, /* Nm */ + NULL, /* Op */ + NULL, /* Ot */ + NULL, /* Pa */ + NULL, /* Rv */ + NULL, /* St */ + NULL, /* Va */ + NULL, /* Vt */ + NULL, /* Xr */ + NULL, /* %A */ + NULL, /* %B */ + NULL, /* %D */ + NULL, /* %I */ + NULL, /* %J */ + NULL, /* %N */ + NULL, /* %O */ + NULL, /* %P */ + NULL, /* %R */ + NULL, /* %T */ + NULL, /* %V */ + NULL, /* Ac */ + NULL, /* Ao */ + NULL, /* Aq */ + NULL, /* At */ + NULL, /* Bc */ + NULL, /* Bf */ + NULL, /* Bo */ + NULL, /* Bq */ + NULL, /* Bsx */ + NULL, /* Bx */ + NULL, /* Db */ + NULL, /* Dc */ + NULL, /* Do */ + NULL, /* Dq */ + NULL, /* Ec */ + NULL, /* Ef */ + NULL, /* Em */ + NULL, /* Eo */ + NULL, /* Fx */ + NULL, /* Ms */ + NULL, /* No */ + NULL, /* Ns */ + NULL, /* Nx */ + NULL, /* Ox */ + NULL, /* Pc */ + NULL, /* Pf */ + NULL, /* Po */ + NULL, /* Pq */ + NULL, /* Qc */ + NULL, /* Ql */ + NULL, /* Qo */ + NULL, /* Qq */ + NULL, /* Re */ + NULL, /* Rs */ + NULL, /* Sc */ + NULL, /* So */ + NULL, /* Sq */ + state_sm, /* Sm */ + NULL, /* Sx */ + NULL, /* Sy */ + NULL, /* Tn */ + NULL, /* Ux */ + NULL, /* Xc */ + NULL, /* Xo */ + NULL, /* Fo */ + NULL, /* Fc */ + NULL, /* Oo */ + NULL, /* Oc */ + NULL, /* Bk */ + NULL, /* Ek */ + NULL, /* Bt */ + NULL, /* Hf */ + NULL, /* Fr */ + NULL, /* Ud */ + NULL, /* Lb */ + NULL, /* Lp */ + NULL, /* Lk */ + NULL, /* Mt */ + NULL, /* Brq */ + NULL, /* Bro */ + NULL, /* Brc */ + NULL, /* %C */ + NULL, /* Es */ + NULL, /* En */ + NULL, /* Dx */ + NULL, /* %Q */ + NULL, /* br */ + NULL, /* sp */ + NULL, /* %U */ + NULL, /* Ta */ + NULL, /* ll */ +}; + + +void +mdoc_state(struct roff_man *mdoc, struct roff_node *n) +{ + state_handler handler; + + if (n->tok == TOKEN_NONE) + return; + + if ( ! (mdoc_macros[n->tok].flags & MDOC_PROLOGUE)) + mdoc->flags |= MDOC_PBODY; + + handler = state_handlers[n->tok]; + if (*handler) + (*handler)(mdoc, n); +} + +void +mdoc_state_reset(struct roff_man *mdoc) +{ + + roff_setreg(mdoc->roff, "nS", 0, '='); + mdoc->flags = 0; +} + +static void +state_bd(STATE_ARGS) +{ + enum mdocargt arg; + + if (n->type != ROFFT_HEAD && + (n->type != ROFFT_BODY || n->end != ENDBODY_NOT)) + return; + + if (n->parent->args == NULL) + return; + + arg = n->parent->args->argv[0].arg; + if (arg != MDOC_Literal && arg != MDOC_Unfilled) + return; + + state_dl(mdoc, n); +} + +static void +state_bl(STATE_ARGS) +{ + + if (n->type != ROFFT_HEAD || n->parent->args == NULL) + return; + + switch(n->parent->args->argv[0].arg) { + case MDOC_Diag: + n->norm->Bl.type = LIST_diag; + break; + case MDOC_Column: + n->norm->Bl.type = LIST_column; + break; + default: + break; + } +} + +static void +state_dl(STATE_ARGS) +{ + + switch (n->type) { + case ROFFT_HEAD: + mdoc->flags |= MDOC_LITERAL; + break; + case ROFFT_BODY: + mdoc->flags &= ~MDOC_LITERAL; + break; + default: + break; + } +} + +static void +state_sh(STATE_ARGS) +{ + struct roff_node *nch; + char *secname; + + if (n->type != ROFFT_HEAD) + return; + + if ( ! (n->flags & MDOC_VALID)) { + secname = NULL; + deroff(&secname, n); + + /* + * Set the section attribute for the BLOCK, HEAD, + * and HEAD children; the latter can only be TEXT + * nodes, so no recursion is needed. For other + * nodes, including the .Sh BODY, this is done + * when allocating the node data structures, but + * for .Sh BLOCK and HEAD, the section is still + * unknown at that time. + */ + + n->sec = n->parent->sec = secname == NULL ? + SEC_CUSTOM : mdoc_a2sec(secname); + for (nch = n->child; nch != NULL; nch = nch->next) + nch->sec = n->sec; + free(secname); + } + + if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) { + roff_setreg(mdoc->roff, "nS", 1, '='); + mdoc->flags |= MDOC_SYNOPSIS; + } else { + roff_setreg(mdoc->roff, "nS", 0, '='); + mdoc->flags &= ~MDOC_SYNOPSIS; + } +} + +static void +state_sm(STATE_ARGS) +{ + + if (n->child == NULL) + mdoc->flags ^= MDOC_SMOFF; + else if ( ! strcmp(n->child->string, "on")) + mdoc->flags &= ~MDOC_SMOFF; + else if ( ! strcmp(n->child->string, "off")) + mdoc->flags |= MDOC_SMOFF; +} diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mdocml/mdoc_term.c index 20c47d6..e846436 100644 --- a/contrib/mdocml/mdoc_term.c +++ b/contrib/mdocml/mdoc_term.c @@ -1,16 +1,16 @@ -/* $Id: mdoc_term.c,v 1.313 2015/03/06 15:48:52 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.331 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> * * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -28,11 +28,13 @@ #include <stdlib.h> #include <string.h> -#include "mandoc.h" #include "mandoc_aux.h" +#include "mandoc.h" +#include "roff.h" +#include "mdoc.h" #include "out.h" #include "term.h" -#include "mdoc.h" +#include "tag.h" #include "main.h" struct termpair { @@ -42,8 +44,8 @@ struct termpair { #define DECL_ARGS struct termp *p, \ struct termpair *pair, \ - const struct mdoc_meta *meta, \ - struct mdoc_node *n + const struct roff_meta *meta, \ + struct roff_node *n struct termact { int (*pre)(DECL_ARGS); @@ -53,14 +55,14 @@ struct termact { static int a2width(const struct termp *, const char *); static void print_bvspace(struct termp *, - const struct mdoc_node *, - const struct mdoc_node *); + const struct roff_node *, + const struct roff_node *); static void print_mdoc_node(DECL_ARGS); static void print_mdoc_nodelist(DECL_ARGS); -static void print_mdoc_head(struct termp *, const void *); -static void print_mdoc_foot(struct termp *, const void *); +static void print_mdoc_head(struct termp *, const struct roff_meta *); +static void print_mdoc_foot(struct termp *, const struct roff_meta *); static void synopsis_pre(struct termp *, - const struct mdoc_node *); + const struct roff_node *); static void termp____post(DECL_ARGS); static void termp__t_post(DECL_ARGS); @@ -93,6 +95,7 @@ static int termp_bx_pre(DECL_ARGS); static int termp_cd_pre(DECL_ARGS); static int termp_d1_pre(DECL_ARGS); static int termp_eo_pre(DECL_ARGS); +static int termp_er_pre(DECL_ARGS); static int termp_ex_pre(DECL_ARGS); static int termp_fa_pre(DECL_ARGS); static int termp_fd_pre(DECL_ARGS); @@ -116,6 +119,7 @@ static int termp_skip_pre(DECL_ARGS); static int termp_sm_pre(DECL_ARGS); static int termp_sp_pre(DECL_ARGS); static int termp_ss_pre(DECL_ARGS); +static int termp_tag_pre(DECL_ARGS); static int termp_under_pre(DECL_ARGS); static int termp_ud_pre(DECL_ARGS); static int termp_vt_pre(DECL_ARGS); @@ -142,9 +146,9 @@ static const struct termact termacts[MDOC_MAX] = { { termp_under_pre, NULL }, /* Ar */ { termp_cd_pre, NULL }, /* Cd */ { termp_bold_pre, NULL }, /* Cm */ - { NULL, NULL }, /* Dv */ - { NULL, NULL }, /* Er */ - { NULL, NULL }, /* Ev */ + { termp_li_pre, NULL }, /* Dv */ + { termp_er_pre, NULL }, /* Er */ + { termp_tag_pre, NULL }, /* Ev */ { termp_ex_pre, NULL }, /* Ex */ { termp_fa_pre, NULL }, /* Fa */ { termp_fd_pre, termp_fd_post }, /* Fd */ @@ -248,29 +252,27 @@ static const struct termact termacts[MDOC_MAX] = { { termp_ll_pre, NULL }, /* ll */ }; +static int fn_prio; void -terminal_mdoc(void *arg, const struct mdoc *mdoc) +terminal_mdoc(void *arg, const struct roff_man *mdoc) { - const struct mdoc_meta *meta; - struct mdoc_node *n; + struct roff_node *n; struct termp *p; p = (struct termp *)arg; - p->overstep = 0; p->rmargin = p->maxrmargin = p->defrmargin; p->tabwidth = term_len(p, 5); - n = mdoc_node(mdoc)->child; - meta = mdoc_meta(mdoc); - + n = mdoc->first->child; if (p->synopsisonly) { while (n != NULL) { if (n->tok == MDOC_Sh && n->sec == SEC_SYNOPSIS) { if (n->child->next->child != NULL) print_mdoc_nodelist(p, NULL, - meta, n->child->next->child); + &mdoc->meta, + n->child->next->child); term_newln(p); break; } @@ -279,11 +281,12 @@ terminal_mdoc(void *arg, const struct mdoc *mdoc) } else { if (p->defindent == 0) p->defindent = 5; - term_begin(p, print_mdoc_head, print_mdoc_foot, meta); + term_begin(p, print_mdoc_head, print_mdoc_foot, + &mdoc->meta); if (n != NULL) { if (n->tok != MDOC_Sh) term_vspace(p); - print_mdoc_nodelist(p, NULL, meta, n); + print_mdoc_nodelist(p, NULL, &mdoc->meta, n); } term_end(p); } @@ -331,7 +334,7 @@ print_mdoc_node(DECL_ARGS) */ switch (n->type) { - case MDOC_TEXT: + case ROFFT_TEXT: if (' ' == *n->string && MDOC_LINE & n->flags) term_newln(p); if (MDOC_DELIMC & n->flags) @@ -340,21 +343,21 @@ print_mdoc_node(DECL_ARGS) if (MDOC_DELIMO & n->flags) p->flags |= TERMP_NOSPACE; break; - case MDOC_EQN: + case ROFFT_EQN: if ( ! (n->flags & MDOC_LINE)) p->flags |= TERMP_NOSPACE; term_eqn(p, n->eqn); if (n->next != NULL && ! (n->next->flags & MDOC_LINE)) p->flags |= TERMP_NOSPACE; break; - case MDOC_TBL: + case ROFFT_TBL: if (p->tbl.cols == NULL) term_newln(p); term_tbl(p, n->span); break; default: if (termacts[n->tok].pre && - (n->end == ENDBODY_NOT || n->nchild)) + (n->end == ENDBODY_NOT || n->child != NULL)) chld = (*termacts[n->tok].pre) (p, &npair, meta, n); break; @@ -367,11 +370,11 @@ print_mdoc_node(DECL_ARGS) (ENDBODY_NOT == n->end ? n : n->body)->prev_font); switch (n->type) { - case MDOC_TEXT: + case ROFFT_TEXT: break; - case MDOC_TBL: + case ROFFT_TBL: break; - case MDOC_EQN: + case ROFFT_EQN: break; default: if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) @@ -406,13 +409,10 @@ print_mdoc_node(DECL_ARGS) } static void -print_mdoc_foot(struct termp *p, const void *arg) +print_mdoc_foot(struct termp *p, const struct roff_meta *meta) { - const struct mdoc_meta *meta; size_t sz; - meta = (const struct mdoc_meta *)arg; - term_fontrepl(p, TERMFONT_NONE); /* @@ -458,14 +458,11 @@ print_mdoc_foot(struct termp *p, const void *arg) } static void -print_mdoc_head(struct termp *p, const void *arg) +print_mdoc_head(struct termp *p, const struct roff_meta *meta) { - const struct mdoc_meta *meta; char *volume, *title; size_t vollen, titlen; - meta = (const struct mdoc_meta *)arg; - /* * The header is strange. It has three components, which are * really two with the first duplicated. It goes like this: @@ -538,7 +535,7 @@ a2width(const struct termp *p, const char *v) SCALE_HS_INIT(&su, term_strlen(p, v)); su.scale /= term_strlen(p, "0"); } - return(term_hspan(p, &su)); + return term_hspan(p, &su) / 24; } /* @@ -548,10 +545,10 @@ a2width(const struct termp *p, const char *v) */ static void print_bvspace(struct termp *p, - const struct mdoc_node *bl, - const struct mdoc_node *n) + const struct roff_node *bl, + const struct roff_node *n) { - const struct mdoc_node *nn; + const struct roff_node *nn; assert(n); @@ -568,9 +565,9 @@ print_bvspace(struct termp *p, while (nn->prev == NULL) { do { nn = nn->parent; - if (nn->type == MDOC_ROOT) + if (nn->type == ROFFT_ROOT) return; - } while (nn->type != MDOC_BLOCK); + } while (nn->type != ROFFT_BLOCK); if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss) return; if (nn->tok == MDOC_It && @@ -601,22 +598,22 @@ static int termp_ll_pre(DECL_ARGS) { - term_setwidth(p, n->nchild ? n->child->string : NULL); - return(0); + term_setwidth(p, n->child != NULL ? n->child->string : NULL); + return 0; } static int termp_it_pre(DECL_ARGS) { char buf[24]; - const struct mdoc_node *bl, *nn; + const struct roff_node *bl, *nn; size_t ncols, dcol; int i, offset, width; enum mdoc_list type; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { print_bvspace(p, n->parent->parent, n); - return(1); + return 1; } bl = n->parent->parent->parent; @@ -628,11 +625,8 @@ termp_it_pre(DECL_ARGS) switch (type) { case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_enum: width = term_len(p, 2); break; @@ -640,7 +634,6 @@ termp_it_pre(DECL_ARGS) width = term_len(p, 8); break; case LIST_column: - /* FALLTHROUGH */ case LIST_tag: width = term_len(p, 10); break; @@ -666,7 +659,7 @@ termp_it_pre(DECL_ARGS) switch (type) { case LIST_column: - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) break; /* @@ -683,8 +676,8 @@ termp_it_pre(DECL_ARGS) ncols == 5 ? term_len(p, 3) : term_len(p, 1); /* - * Calculate the offset by applying all prior MDOC_BODY, - * so we stop at the MDOC_HEAD (NULL == nn->prev). + * Calculate the offset by applying all prior ROFFT_BODY, + * so we stop at the ROFFT_HEAD (nn->prev == NULL). */ for (i = 0, nn = n->prev; @@ -734,11 +727,11 @@ termp_it_pre(DECL_ARGS) switch (type) { case LIST_diag: - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) term_word(p, "\\ \\ "); break; case LIST_inset: - if (MDOC_BODY == n->type && n->parent->head->nchild) + if (n->type == ROFFT_BODY && n->parent->head->child != NULL) term_word(p, "\\ "); break; default: @@ -749,7 +742,7 @@ termp_it_pre(DECL_ARGS) switch (type) { case LIST_diag: - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) term_fontpush(p, TERMFONT_BOLD); break; default: @@ -765,25 +758,22 @@ termp_it_pre(DECL_ARGS) switch (type) { case LIST_enum: + case LIST_bullet: + case LIST_dash: + case LIST_hyphen: /* * Weird special case. * Some very narrow lists actually hang. */ - /* FALLTHROUGH */ - case LIST_bullet: - /* FALLTHROUGH */ - case LIST_dash: - /* FALLTHROUGH */ - case LIST_hyphen: if (width <= (int)term_len(p, 2)) p->flags |= TERMP_HANG; - if (MDOC_HEAD != n->type) + if (n->type != ROFFT_HEAD) break; p->flags |= TERMP_NOBREAK; p->trailspace = 1; break; case LIST_hang: - if (MDOC_HEAD != n->type) + if (n->type != ROFFT_HEAD) break; /* @@ -802,17 +792,17 @@ termp_it_pre(DECL_ARGS) p->trailspace = 1; break; case LIST_tag: - if (MDOC_HEAD != n->type) + if (n->type != ROFFT_HEAD) break; - p->flags |= TERMP_NOBREAK | TERMP_BRIND; + p->flags |= TERMP_NOBREAK | TERMP_BRTRSP | TERMP_BRIND; p->trailspace = 2; if (NULL == n->next || NULL == n->next->child) p->flags |= TERMP_DANGLE; break; case LIST_column: - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) break; if (NULL == n->next) { @@ -825,7 +815,7 @@ termp_it_pre(DECL_ARGS) break; case LIST_diag: - if (MDOC_HEAD != n->type) + if (n->type != ROFFT_HEAD) break; p->flags |= TERMP_NOBREAK | TERMP_BRIND; p->trailspace = 1; @@ -849,7 +839,7 @@ termp_it_pre(DECL_ARGS) * don't want to recalculate rmargin and offsets when * using `Bd' or `Bl' within `-hang' overstep lists. */ - if (MDOC_HEAD == n->type && + if (n->type == ROFFT_HEAD && NULL != n->next && NULL != n->next->child && (MDOC_Bl == n->next->child->tok || @@ -857,15 +847,11 @@ termp_it_pre(DECL_ARGS) break; /* FALLTHROUGH */ case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_enum: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_tag: - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) p->rmargin = p->offset + width; else p->offset += width; @@ -877,7 +863,7 @@ termp_it_pre(DECL_ARGS) * XXX - this behaviour is not documented: the * right-most column is filled to the right margin. */ - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) break; if (NULL == n->next && p->rmargin < p->maxrmargin) p->rmargin = p->maxrmargin; @@ -891,7 +877,7 @@ termp_it_pre(DECL_ARGS) * HEAD character (temporarily bold, in some cases). */ - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) switch (type) { case LIST_bullet: term_fontpush(p, TERMFONT_BOLD); @@ -899,10 +885,9 @@ termp_it_pre(DECL_ARGS) term_fontpop(p); break; case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: term_fontpush(p, TERMFONT_BOLD); - term_word(p, "\\(hy"); + term_word(p, "-"); term_fontpop(p); break; case LIST_enum: @@ -921,26 +906,22 @@ termp_it_pre(DECL_ARGS) switch (type) { case LIST_bullet: - /* FALLTHROUGH */ case LIST_item: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: - /* FALLTHROUGH */ case LIST_enum: - if (MDOC_HEAD == n->type) - return(0); + if (n->type == ROFFT_HEAD) + return 0; break; case LIST_column: - if (MDOC_HEAD == n->type) - return(0); + if (n->type == ROFFT_HEAD) + return 0; break; default: break; } - return(1); + return 1; } static void @@ -948,22 +929,20 @@ termp_it_post(DECL_ARGS) { enum mdoc_list type; - if (MDOC_BLOCK == n->type) + if (n->type == ROFFT_BLOCK) return; type = n->parent->parent->parent->norm->Bl.type; switch (type) { case LIST_item: - /* FALLTHROUGH */ case LIST_diag: - /* FALLTHROUGH */ case LIST_inset: - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) term_newln(p); break; case LIST_column: - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) term_flushln(p); break; default: @@ -977,7 +956,7 @@ termp_it_post(DECL_ARGS) * has munged them in the meanwhile. */ - p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | + p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP | TERMP_BRIND | TERMP_DANGLE | TERMP_HANG); p->trailspace = 0; } @@ -987,14 +966,14 @@ termp_nm_pre(DECL_ARGS) { const char *cp; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { p->flags |= TERMP_PREKEEP; - return(1); + return 1; } - if (MDOC_BODY == n->type) { + if (n->type == ROFFT_BODY) { if (NULL == n->child) - return(0); + return 0; p->flags |= TERMP_NOSPACE; cp = NULL; if (n->prev->child != NULL) @@ -1005,23 +984,23 @@ termp_nm_pre(DECL_ARGS) p->offset += term_len(p, 6); else p->offset += term_len(p, 1) + term_strlen(p, cp); - return(1); + return 1; } if (NULL == n->child && NULL == meta->name) - return(0); + return 0; - if (MDOC_HEAD == n->type) + if (n->type == ROFFT_HEAD) synopsis_pre(p, n->parent); - if (MDOC_HEAD == n->type && + if (n->type == ROFFT_HEAD && NULL != n->next && NULL != n->next->child) { p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND; p->trailspace = 1; p->rmargin = p->offset + term_len(p, 1); if (NULL == n->child) { p->rmargin += term_strlen(p, meta->name); - } else if (MDOC_TEXT == n->child->type) { + } else if (n->child->type == ROFFT_TEXT) { p->rmargin += term_strlen(p, n->child->string); if (n->child->next) p->flags |= TERMP_HANG; @@ -1034,21 +1013,21 @@ termp_nm_pre(DECL_ARGS) term_fontpush(p, TERMFONT_BOLD); if (NULL == n->child) term_word(p, meta->name); - return(1); + return 1; } static void termp_nm_post(DECL_ARGS) { - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); - } else if (MDOC_HEAD == n->type && + } else if (n->type == ROFFT_HEAD && NULL != n->next && NULL != n->next->child) { term_flushln(p); p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG); p->trailspace = 0; - } else if (MDOC_BODY == n->type && n->child) + } else if (n->type == ROFFT_BODY && n->child != NULL) term_flushln(p); } @@ -1056,16 +1035,17 @@ static int termp_fl_pre(DECL_ARGS) { + termp_tag_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_BOLD); term_word(p, "\\-"); - if ( ! (n->nchild == 0 && + if (!(n->child == NULL && (n->next == NULL || - n->next->type == MDOC_TEXT || + n->next->type == ROFFT_TEXT || n->next->flags & MDOC_LINE))) p->flags |= TERMP_NOSPACE; - return(1); + return 1; } static int @@ -1076,7 +1056,7 @@ termp__a_pre(DECL_ARGS) if (NULL == n->next || MDOC__A != n->next->tok) term_word(p, "and"); - return(1); + return 1; } static int @@ -1086,12 +1066,12 @@ termp_an_pre(DECL_ARGS) if (n->norm->An.auth == AUTH_split) { p->flags &= ~TERMP_NOSPLIT; p->flags |= TERMP_SPLIT; - return(0); + return 0; } if (n->norm->An.auth == AUTH_nosplit) { p->flags &= ~TERMP_SPLIT; p->flags |= TERMP_NOSPLIT; - return(0); + return 0; } if (p->flags & TERMP_SPLIT) @@ -1100,7 +1080,7 @@ termp_an_pre(DECL_ARGS) if (n->sec == SEC_AUTHORS && ! (p->flags & TERMP_NOSPLIT)) p->flags |= TERMP_SPLIT; - return(1); + return 1; } static int @@ -1109,7 +1089,7 @@ termp_ns_pre(DECL_ARGS) if ( ! (MDOC_LINE & n->flags)) p->flags |= TERMP_NOSPACE; - return(1); + return 1; } static int @@ -1117,43 +1097,42 @@ termp_rs_pre(DECL_ARGS) { if (SEC_SEE_ALSO != n->sec) - return(1); - if (MDOC_BLOCK == n->type && n->prev) + return 1; + if (n->type == ROFFT_BLOCK && n->prev != NULL) term_vspace(p); - return(1); + return 1; } static int termp_rv_pre(DECL_ARGS) { - int nchild; + struct roff_node *nch; term_newln(p); - nchild = n->nchild; - if (nchild > 0) { + if (n->child != NULL) { term_word(p, "The"); - for (n = n->child; n; n = n->next) { + for (nch = n->child; nch != NULL; nch = nch->next) { term_fontpush(p, TERMFONT_BOLD); - term_word(p, n->string); + term_word(p, nch->string); term_fontpop(p); p->flags |= TERMP_NOSPACE; term_word(p, "()"); - if (n->next == NULL) + if (nch->next == NULL) continue; - if (nchild > 2) { + if (nch->prev != NULL || nch->next->next != NULL) { p->flags |= TERMP_NOSPACE; term_word(p, ","); } - if (n->next->next == NULL) + if (nch->next->next == NULL) term_word(p, "and"); } - if (nchild > 1) + if (n->child != NULL && n->child->next != NULL) term_word(p, "functions return"); else term_word(p, "function returns"); @@ -1173,33 +1152,35 @@ termp_rv_pre(DECL_ARGS) term_word(p, "is set to indicate the error."); p->flags |= TERMP_SENTENCE; - return(0); + return 0; } static int termp_ex_pre(DECL_ARGS) { - int nchild; + struct roff_node *nch; term_newln(p); term_word(p, "The"); - nchild = n->nchild; - for (n = n->child; n; n = n->next) { + for (nch = n->child; nch != NULL; nch = nch->next) { term_fontpush(p, TERMFONT_BOLD); - term_word(p, n->string); + term_word(p, nch->string); term_fontpop(p); - if (nchild > 2 && n->next) { + if (nch->next == NULL) + continue; + + if (nch->prev != NULL || nch->next->next != NULL) { p->flags |= TERMP_NOSPACE; term_word(p, ","); } - if (n->next && NULL == n->next->next) + if (nch->next->next == NULL) term_word(p, "and"); } - if (nchild > 1) + if (n->child != NULL && n->child->next != NULL) term_word(p, "utilities exit\\~0"); else term_word(p, "utility exits\\~0"); @@ -1207,30 +1188,30 @@ termp_ex_pre(DECL_ARGS) term_word(p, "on success, and\\~>0 if an error occurs."); p->flags |= TERMP_SENTENCE; - return(0); + return 0; } static int termp_nd_pre(DECL_ARGS) { - if (n->type == MDOC_BODY) + if (n->type == ROFFT_BODY) term_word(p, "\\(en"); - return(1); + return 1; } static int termp_bl_pre(DECL_ARGS) { - return(MDOC_HEAD != n->type); + return n->type != ROFFT_HEAD; } static void termp_bl_post(DECL_ARGS) { - if (MDOC_BLOCK == n->type) + if (n->type == ROFFT_BLOCK) term_newln(p); } @@ -1239,25 +1220,25 @@ termp_xr_pre(DECL_ARGS) { if (NULL == (n = n->child)) - return(0); + return 0; - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); term_word(p, n->string); if (NULL == (n = n->next)) - return(0); + return 0; p->flags |= TERMP_NOSPACE; term_word(p, "("); p->flags |= TERMP_NOSPACE; - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); term_word(p, n->string); p->flags |= TERMP_NOSPACE; term_word(p, ")"); - return(0); + return 0; } /* @@ -1266,7 +1247,7 @@ termp_xr_pre(DECL_ARGS) * macro combos). */ static void -synopsis_pre(struct termp *p, const struct mdoc_node *n) +synopsis_pre(struct termp *p, const struct roff_node *n) { /* * Obviously, if we're not in a SYNOPSIS or no prior macros @@ -1295,13 +1276,9 @@ synopsis_pre(struct termp *p, const struct mdoc_node *n) */ switch (n->prev->tok) { case MDOC_Fd: - /* FALLTHROUGH */ case MDOC_Fn: - /* FALLTHROUGH */ case MDOC_Fo: - /* FALLTHROUGH */ case MDOC_In: - /* FALLTHROUGH */ case MDOC_Vt: term_vspace(p); break; @@ -1321,24 +1298,25 @@ static int termp_vt_pre(DECL_ARGS) { - if (MDOC_ELEM == n->type) { + if (n->type == ROFFT_ELEM) { synopsis_pre(p, n); - return(termp_under_pre(p, pair, meta, n)); - } else if (MDOC_BLOCK == n->type) { + return termp_under_pre(p, pair, meta, n); + } else if (n->type == ROFFT_BLOCK) { synopsis_pre(p, n); - return(1); - } else if (MDOC_HEAD == n->type) - return(0); + return 1; + } else if (n->type == ROFFT_HEAD) + return 0; - return(termp_under_pre(p, pair, meta, n)); + return termp_under_pre(p, pair, meta, n); } static int termp_bold_pre(DECL_ARGS) { + termp_tag_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_BOLD); - return(1); + return 1; } static int @@ -1346,7 +1324,7 @@ termp_fd_pre(DECL_ARGS) { synopsis_pre(p, n); - return(termp_bold_pre(p, pair, meta, n)); + return termp_bold_pre(p, pair, meta, n); } static void @@ -1361,29 +1339,37 @@ termp_sh_pre(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: /* * Vertical space before sections, except * when the previous section was empty. */ if (n->prev == NULL || - MDOC_Sh != n->prev->tok || + n->prev->tok != MDOC_Sh || (n->prev->body != NULL && n->prev->body->child != NULL)) term_vspace(p); break; - case MDOC_HEAD: + case ROFFT_HEAD: term_fontpush(p, TERMFONT_BOLD); break; - case MDOC_BODY: + case ROFFT_BODY: p->offset = term_len(p, p->defindent); - if (SEC_AUTHORS == n->sec) + switch (n->sec) { + case SEC_DESCRIPTION: + fn_prio = 0; + break; + case SEC_AUTHORS: p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT); + break; + default: + break; + } break; default: break; } - return(1); + return 1; } static void @@ -1391,10 +1377,10 @@ termp_sh_post(DECL_ARGS) { switch (n->type) { - case MDOC_HEAD: + case ROFFT_HEAD: term_newln(p); break; - case MDOC_BODY: + case ROFFT_BODY: term_newln(p); p->offset = 0; break; @@ -1409,7 +1395,7 @@ termp_bt_pre(DECL_ARGS) term_word(p, "is currently in beta test."); p->flags |= TERMP_SENTENCE; - return(0); + return 0; } static void @@ -1426,18 +1412,18 @@ termp_ud_pre(DECL_ARGS) term_word(p, "currently under development."); p->flags |= TERMP_SENTENCE; - return(0); + return 0; } static int termp_d1_pre(DECL_ARGS) { - if (MDOC_BLOCK != n->type) - return(1); + if (n->type != ROFFT_BLOCK) + return 1; term_newln(p); p->offset += term_len(p, p->defindent + 1); - return(1); + return 1; } static int @@ -1447,7 +1433,7 @@ termp_ft_pre(DECL_ARGS) /* NB: MDOC_LINE does not effect this! */ synopsis_pre(p, n); term_fontpush(p, TERMFONT_UNDER); - return(1); + return 1; } static int @@ -1461,7 +1447,7 @@ termp_fn_pre(DECL_ARGS) synopsis_pre(p, n); if (NULL == (n = n->child)) - return(0); + return 0; if (pretty) { rmargin = p->rmargin; @@ -1469,11 +1455,14 @@ termp_fn_pre(DECL_ARGS) p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG; } - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); term_fontpush(p, TERMFONT_BOLD); term_word(p, n->string); term_fontpop(p); + if (n->sec == SEC_DESCRIPTION) + tag_put(n->string, ++fn_prio, p->line); + if (pretty) { term_flushln(p); p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG); @@ -1486,7 +1475,7 @@ termp_fn_pre(DECL_ARGS) p->flags |= TERMP_NOSPACE; for (n = n->next; n; n = n->next) { - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); term_fontpush(p, TERMFONT_UNDER); if (pretty) p->flags |= TERMP_NBRWORD; @@ -1508,17 +1497,17 @@ termp_fn_pre(DECL_ARGS) term_flushln(p); } - return(0); + return 0; } static int termp_fa_pre(DECL_ARGS) { - const struct mdoc_node *nn; + const struct roff_node *nn; if (n->parent->tok != MDOC_Fo) { term_fontpush(p, TERMFONT_UNDER); - return(1); + return 1; } for (nn = n->child; nn; nn = nn->next) { @@ -1533,21 +1522,21 @@ termp_fa_pre(DECL_ARGS) } } - return(0); + return 0; } static int termp_bd_pre(DECL_ARGS) { size_t tabwidth, lm, len, rm, rmax; - struct mdoc_node *nn; + struct roff_node *nn; int offset; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { print_bvspace(p, n, n); - return(1); - } else if (MDOC_HEAD == n->type) - return(0); + return 1; + } else if (n->type == ROFFT_HEAD) + return 0; /* Handle the -offset argument. */ @@ -1577,7 +1566,7 @@ termp_bd_pre(DECL_ARGS) if (DISP_literal != n->norm->Bd.type && DISP_unfilled != n->norm->Bd.type && DISP_centered != n->norm->Bd.type) - return(1); + return 1; tabwidth = p->tabwidth; if (DISP_literal == n->norm->Bd.type) @@ -1590,7 +1579,7 @@ termp_bd_pre(DECL_ARGS) for (nn = n->child; nn; nn = nn->next) { if (DISP_centered == n->norm->Bd.type) { - if (MDOC_TEXT == nn->type) { + if (nn->type == ROFFT_TEXT) { len = term_strlen(p, nn->string); p->offset = len >= rm ? 0 : lm + len >= rm ? rm - len : @@ -1607,19 +1596,12 @@ termp_bd_pre(DECL_ARGS) */ switch (nn->tok) { case MDOC_Sm: - /* FALLTHROUGH */ case MDOC_br: - /* FALLTHROUGH */ case MDOC_sp: - /* FALLTHROUGH */ case MDOC_Bl: - /* FALLTHROUGH */ case MDOC_D1: - /* FALLTHROUGH */ case MDOC_Dl: - /* FALLTHROUGH */ case MDOC_Lp: - /* FALLTHROUGH */ case MDOC_Pp: continue; default: @@ -1635,7 +1617,7 @@ termp_bd_pre(DECL_ARGS) p->tabwidth = tabwidth; p->rmargin = rm; p->maxrmargin = rmax; - return(0); + return 0; } static void @@ -1643,7 +1625,7 @@ termp_bd_post(DECL_ARGS) { size_t rm, rmax; - if (MDOC_BODY != n->type) + if (n->type != ROFFT_BODY) return; rm = p->rmargin; @@ -1670,7 +1652,7 @@ termp_bx_pre(DECL_ARGS) term_word(p, "BSD"); } else { term_word(p, "BSD"); - return(0); + return 0; } if (NULL != (n = n->next)) { @@ -1680,7 +1662,7 @@ termp_bx_pre(DECL_ARGS) term_word(p, n->string); } - return(0); + return 0; } static int @@ -1711,7 +1693,6 @@ termp_xx_pre(DECL_ARGS) break; default: abort(); - /* NOTREACHED */ } term_word(p, pp); @@ -1721,7 +1702,7 @@ termp_xx_pre(DECL_ARGS) term_word(p, n->child->string); p->flags = flags; } - return(0); + return 0; } static void @@ -1737,30 +1718,30 @@ termp_ss_pre(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: term_newln(p); if (n->prev) term_vspace(p); break; - case MDOC_HEAD: + case ROFFT_HEAD: term_fontpush(p, TERMFONT_BOLD); p->offset = term_len(p, (p->defindent+1)/2); break; - case MDOC_BODY: + case ROFFT_BODY: p->offset = term_len(p, p->defindent); break; default: break; } - return(1); + return 1; } static void termp_ss_post(DECL_ARGS) { - if (n->type == MDOC_HEAD || n->type == MDOC_BODY) + if (n->type == ROFFT_HEAD || n->type == ROFFT_BODY) term_newln(p); } @@ -1770,7 +1751,7 @@ termp_cd_pre(DECL_ARGS) synopsis_pre(p, n); term_fontpush(p, TERMFONT_BOLD); - return(1); + return 1; } static int @@ -1789,7 +1770,7 @@ termp_in_pre(DECL_ARGS) } p->flags |= TERMP_NOSPACE; - return(1); + return 1; } static void @@ -1826,6 +1807,7 @@ termp_sp_pre(DECL_ARGS) break; default: len = 1; + fn_prio = 0; break; } @@ -1837,115 +1819,97 @@ termp_sp_pre(DECL_ARGS) for (i = 0; i < len; i++) term_vspace(p); - return(0); + return 0; } static int termp_skip_pre(DECL_ARGS) { - return(0); + return 0; } static int termp_quote_pre(DECL_ARGS) { - if (MDOC_BODY != n->type && MDOC_ELEM != n->type) - return(1); + if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM) + return 1; switch (n->tok) { case MDOC_Ao: - /* FALLTHROUGH */ case MDOC_Aq: - term_word(p, n->nchild == 1 && + term_word(p, n->child != NULL && n->child->next == NULL && n->child->tok == MDOC_Mt ? "<" : "\\(la"); break; case MDOC_Bro: - /* FALLTHROUGH */ case MDOC_Brq: term_word(p, "{"); break; case MDOC_Oo: - /* FALLTHROUGH */ case MDOC_Op: - /* FALLTHROUGH */ case MDOC_Bo: - /* FALLTHROUGH */ case MDOC_Bq: term_word(p, "["); break; case MDOC_Do: - /* FALLTHROUGH */ case MDOC_Dq: term_word(p, "\\(Lq"); break; case MDOC_En: if (NULL == n->norm->Es || NULL == n->norm->Es->child) - return(1); + return 1; term_word(p, n->norm->Es->child->string); break; case MDOC_Po: - /* FALLTHROUGH */ case MDOC_Pq: term_word(p, "("); break; case MDOC__T: - /* FALLTHROUGH */ case MDOC_Qo: - /* FALLTHROUGH */ case MDOC_Qq: term_word(p, "\""); break; case MDOC_Ql: - /* FALLTHROUGH */ case MDOC_So: - /* FALLTHROUGH */ case MDOC_Sq: term_word(p, "\\(oq"); break; default: abort(); - /* NOTREACHED */ } p->flags |= TERMP_NOSPACE; - return(1); + return 1; } static void termp_quote_post(DECL_ARGS) { - if (n->type != MDOC_BODY && n->type != MDOC_ELEM) + if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM) return; p->flags |= TERMP_NOSPACE; switch (n->tok) { case MDOC_Ao: - /* FALLTHROUGH */ case MDOC_Aq: - term_word(p, n->nchild == 1 && + term_word(p, n->child != NULL && n->child->next == NULL && n->child->tok == MDOC_Mt ? ">" : "\\(ra"); break; case MDOC_Bro: - /* FALLTHROUGH */ case MDOC_Brq: term_word(p, "}"); break; case MDOC_Oo: - /* FALLTHROUGH */ case MDOC_Op: - /* FALLTHROUGH */ case MDOC_Bo: - /* FALLTHROUGH */ case MDOC_Bq: term_word(p, "]"); break; case MDOC_Do: - /* FALLTHROUGH */ case MDOC_Dq: term_word(p, "\\(Rq"); break; @@ -1958,27 +1922,21 @@ termp_quote_post(DECL_ARGS) term_word(p, n->norm->Es->child->next->string); break; case MDOC_Po: - /* FALLTHROUGH */ case MDOC_Pq: term_word(p, ")"); break; case MDOC__T: - /* FALLTHROUGH */ case MDOC_Qo: - /* FALLTHROUGH */ case MDOC_Qq: term_word(p, "\""); break; case MDOC_Ql: - /* FALLTHROUGH */ case MDOC_So: - /* FALLTHROUGH */ case MDOC_Sq: term_word(p, "\\(cq"); break; default: abort(); - /* NOTREACHED */ } } @@ -1986,8 +1944,8 @@ static int termp_eo_pre(DECL_ARGS) { - if (n->type != MDOC_BODY) - return(1); + if (n->type != ROFFT_BODY) + return 1; if (n->end == ENDBODY_NOT && n->parent->head->child == NULL && @@ -1999,7 +1957,7 @@ termp_eo_pre(DECL_ARGS) (n->parent->tail != NULL && n->parent->tail->child != NULL))) p->flags |= TERMP_NOSPACE; - return(1); + return 1; } static void @@ -2007,7 +1965,7 @@ termp_eo_post(DECL_ARGS) { int body, tail; - if (n->type != MDOC_BODY) + if (n->type != ROFFT_BODY) return; if (n->end != ENDBODY_NOT) { @@ -2034,10 +1992,10 @@ termp_fo_pre(DECL_ARGS) pretty = MDOC_SYNPRETTY & n->flags; - if (MDOC_BLOCK == n->type) { + if (n->type == ROFFT_BLOCK) { synopsis_pre(p, n); - return(1); - } else if (MDOC_BODY == n->type) { + return 1; + } else if (n->type == ROFFT_BODY) { if (pretty) { rmargin = p->rmargin; p->rmargin = p->offset + term_len(p, 4); @@ -2054,25 +2012,25 @@ termp_fo_pre(DECL_ARGS) p->offset = p->rmargin; p->rmargin = rmargin; } - return(1); + return 1; } if (NULL == n->child) - return(0); + return 0; /* XXX: we drop non-initial arguments as per groff. */ assert(n->child->string); term_fontpush(p, TERMFONT_BOLD); term_word(p, n->child->string); - return(0); + return 0; } static void termp_fo_post(DECL_ARGS) { - if (MDOC_BODY != n->type) + if (n->type != ROFFT_BODY) return; p->flags |= TERMP_NOSPACE; @@ -2089,10 +2047,10 @@ static int termp_bf_pre(DECL_ARGS) { - if (MDOC_HEAD == n->type) - return(0); - else if (MDOC_BODY != n->type) - return(1); + if (n->type == ROFFT_HEAD) + return 0; + else if (n->type != ROFFT_BODY) + return 1; if (FONT_Em == n->norm->Bf.font) term_fontpush(p, TERMFONT_UNDER); @@ -2101,7 +2059,7 @@ termp_bf_pre(DECL_ARGS) else term_fontpush(p, TERMFONT_NONE); - return(1); + return 1; } static int @@ -2118,7 +2076,7 @@ termp_sm_pre(DECL_ARGS) if (p->col && ! (TERMP_NONOSPACE & p->flags)) p->flags &= ~TERMP_NOSPACE; - return(0); + return 0; } static int @@ -2128,7 +2086,7 @@ termp_ap_pre(DECL_ARGS) p->flags |= TERMP_NOSPACE; term_word(p, "'"); p->flags |= TERMP_NOSPACE; - return(1); + return 1; } static void @@ -2163,16 +2121,16 @@ termp_li_pre(DECL_ARGS) { term_fontpush(p, TERMFONT_NONE); - return(1); + return 1; } static int termp_lk_pre(DECL_ARGS) { - const struct mdoc_node *link, *descr; + const struct roff_node *link, *descr; if (NULL == (link = n->child)) - return(0); + return 0; if (NULL != (descr = link->next)) { term_fontpush(p, TERMFONT_UNDER); @@ -2189,7 +2147,7 @@ termp_lk_pre(DECL_ARGS) term_word(p, link->string); term_fontpop(p); - return(0); + return 0; } static int @@ -2197,27 +2155,26 @@ termp_bk_pre(DECL_ARGS) { switch (n->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: break; - case MDOC_HEAD: - return(0); - case MDOC_BODY: - if (n->parent->args || 0 == n->prev->nchild) + case ROFFT_HEAD: + return 0; + case ROFFT_BODY: + if (n->parent->args != NULL || n->prev->child == NULL) p->flags |= TERMP_PREKEEP; break; default: abort(); - /* NOTREACHED */ } - return(1); + return 1; } static void termp_bk_post(DECL_ARGS) { - if (MDOC_BODY == n->type) + if (n->type == ROFFT_BODY) p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); } @@ -2246,10 +2203,10 @@ termp__t_pre(DECL_ARGS) */ if (n->parent && MDOC_Rs == n->parent->tok && n->parent->norm->Rs.quote_T) - return(termp_quote_pre(p, pair, meta, n)); + return termp_quote_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_UNDER); - return(1); + return 1; } static int @@ -2257,5 +2214,32 @@ termp_under_pre(DECL_ARGS) { term_fontpush(p, TERMFONT_UNDER); - return(1); + return 1; +} + +static int +termp_er_pre(DECL_ARGS) +{ + + if (n->sec == SEC_ERRORS && + (n->parent->tok == MDOC_It || + (n->parent->tok == MDOC_Bq && + n->parent->parent->parent->tok == MDOC_It))) + tag_put(n->child->string, 1, p->line); + return 1; +} + +static int +termp_tag_pre(DECL_ARGS) +{ + + if (n->child != NULL && + n->child->type == ROFFT_TEXT && + n->prev == NULL && + (n->parent->tok == MDOC_It || + (n->parent->tok == MDOC_Xo && + n->parent->parent->prev == NULL && + n->parent->parent->parent->tok == MDOC_It))) + tag_put(n->child->string, 1, p->line); + return 1; } diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mdocml/mdoc_validate.c index eb531e8..e369349 100644 --- a/contrib/mdocml/mdoc_validate.c +++ b/contrib/mdocml/mdoc_validate.c @@ -1,16 +1,16 @@ -/* $Id: mdoc_validate.c,v 1.283 2015/02/23 13:55:55 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.301 2016/01/08 17:48:09 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -31,16 +31,17 @@ #include <string.h> #include <time.h> -#include "mdoc.h" -#include "mandoc.h" #include "mandoc_aux.h" -#include "libmdoc.h" +#include "mandoc.h" +#include "roff.h" +#include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" +#include "libmdoc.h" /* FIXME: .Bl -diag can't have non-text children in HEAD. */ -#define PRE_ARGS struct mdoc *mdoc, struct mdoc_node *n -#define POST_ARGS struct mdoc *mdoc +#define POST_ARGS struct roff_man *mdoc enum check_ineq { CHECK_LT, @@ -48,34 +49,30 @@ enum check_ineq { CHECK_EQ }; -typedef void (*v_pre)(PRE_ARGS); typedef void (*v_post)(POST_ARGS); -struct valids { - v_pre pre; - v_post post; -}; - -static void check_text(struct mdoc *, int, int, char *); -static void check_argv(struct mdoc *, - struct mdoc_node *, struct mdoc_argv *); -static void check_args(struct mdoc *, struct mdoc_node *); -static int child_an(const struct mdoc_node *); -static enum mdoc_sec a2sec(const char *); -static size_t macro2len(enum mdoct); +static void check_text(struct roff_man *, int, int, char *); +static void check_argv(struct roff_man *, + struct roff_node *, struct mdoc_argv *); +static void check_args(struct roff_man *, struct roff_node *); +static int child_an(const struct roff_node *); +static size_t macro2len(int); static void rewrite_macro2len(char **); static void post_an(POST_ARGS); +static void post_an_norm(POST_ARGS); static void post_at(POST_ARGS); +static void post_bd(POST_ARGS); static void post_bf(POST_ARGS); static void post_bk(POST_ARGS); static void post_bl(POST_ARGS); static void post_bl_block(POST_ARGS); static void post_bl_block_tag(POST_ARGS); static void post_bl_head(POST_ARGS); +static void post_bl_norm(POST_ARGS); static void post_bx(POST_ARGS); -static void post_d1(POST_ARGS); static void post_defaults(POST_ARGS); +static void post_display(POST_ARGS); static void post_dd(POST_ARGS); static void post_dt(POST_ARGS); static void post_en(POST_ARGS); @@ -90,12 +87,13 @@ static void post_hyph(POST_ARGS); static void post_ignpar(POST_ARGS); static void post_it(POST_ARGS); static void post_lb(POST_ARGS); -static void post_literal(POST_ARGS); static void post_nd(POST_ARGS); static void post_nm(POST_ARGS); static void post_ns(POST_ARGS); +static void post_obsolete(POST_ARGS); static void post_os(POST_ARGS); static void post_par(POST_ARGS); +static void post_prevpar(POST_ARGS); static void post_root(POST_ARGS); static void post_rs(POST_ARGS); static void post_sh(POST_ARGS); @@ -105,149 +103,137 @@ static void post_sh_see_also(POST_ARGS); static void post_sh_authors(POST_ARGS); static void post_sm(POST_ARGS); static void post_st(POST_ARGS); -static void post_vt(POST_ARGS); - -static void pre_an(PRE_ARGS); -static void pre_bd(PRE_ARGS); -static void pre_bl(PRE_ARGS); -static void pre_dd(PRE_ARGS); -static void pre_display(PRE_ARGS); -static void pre_dt(PRE_ARGS); -static void pre_literal(PRE_ARGS); -static void pre_obsolete(PRE_ARGS); -static void pre_os(PRE_ARGS); -static void pre_par(PRE_ARGS); -static void pre_std(PRE_ARGS); - -static const struct valids mdoc_valids[MDOC_MAX] = { - { NULL, NULL }, /* Ap */ - { pre_dd, post_dd }, /* Dd */ - { pre_dt, post_dt }, /* Dt */ - { pre_os, post_os }, /* Os */ - { NULL, post_sh }, /* Sh */ - { NULL, post_ignpar }, /* Ss */ - { pre_par, post_par }, /* Pp */ - { pre_display, post_d1 }, /* D1 */ - { pre_literal, post_literal }, /* Dl */ - { pre_bd, post_literal }, /* Bd */ - { NULL, NULL }, /* Ed */ - { pre_bl, post_bl }, /* Bl */ - { NULL, NULL }, /* El */ - { pre_par, post_it }, /* It */ - { NULL, NULL }, /* Ad */ - { pre_an, post_an }, /* An */ - { NULL, post_defaults }, /* Ar */ - { NULL, NULL }, /* Cd */ - { NULL, NULL }, /* Cm */ - { NULL, NULL }, /* Dv */ - { NULL, NULL }, /* Er */ - { NULL, NULL }, /* Ev */ - { pre_std, post_ex }, /* Ex */ - { NULL, post_fa }, /* Fa */ - { NULL, NULL }, /* Fd */ - { NULL, NULL }, /* Fl */ - { NULL, post_fn }, /* Fn */ - { NULL, NULL }, /* Ft */ - { NULL, NULL }, /* Ic */ - { NULL, NULL }, /* In */ - { NULL, post_defaults }, /* Li */ - { NULL, post_nd }, /* Nd */ - { NULL, post_nm }, /* Nm */ - { NULL, NULL }, /* Op */ - { pre_obsolete, NULL }, /* Ot */ - { NULL, post_defaults }, /* Pa */ - { pre_std, NULL }, /* Rv */ - { NULL, post_st }, /* St */ - { NULL, NULL }, /* Va */ - { NULL, post_vt }, /* Vt */ - { NULL, NULL }, /* Xr */ - { NULL, NULL }, /* %A */ - { NULL, post_hyph }, /* %B */ /* FIXME: can be used outside Rs/Re. */ - { NULL, NULL }, /* %D */ - { NULL, NULL }, /* %I */ - { NULL, NULL }, /* %J */ - { NULL, post_hyph }, /* %N */ - { NULL, post_hyph }, /* %O */ - { NULL, NULL }, /* %P */ - { NULL, post_hyph }, /* %R */ - { NULL, post_hyph }, /* %T */ /* FIXME: can be used outside Rs/Re. */ - { NULL, NULL }, /* %V */ - { NULL, NULL }, /* Ac */ - { NULL, NULL }, /* Ao */ - { NULL, NULL }, /* Aq */ - { NULL, post_at }, /* At */ - { NULL, NULL }, /* Bc */ - { NULL, post_bf }, /* Bf */ - { NULL, NULL }, /* Bo */ - { NULL, NULL }, /* Bq */ - { NULL, NULL }, /* Bsx */ - { NULL, post_bx }, /* Bx */ - { pre_obsolete, NULL }, /* Db */ - { NULL, NULL }, /* Dc */ - { NULL, NULL }, /* Do */ - { NULL, NULL }, /* Dq */ - { NULL, NULL }, /* Ec */ - { NULL, NULL }, /* Ef */ - { NULL, NULL }, /* Em */ - { NULL, NULL }, /* Eo */ - { NULL, NULL }, /* Fx */ - { NULL, NULL }, /* Ms */ - { NULL, NULL }, /* No */ - { NULL, post_ns }, /* Ns */ - { NULL, NULL }, /* Nx */ - { NULL, NULL }, /* Ox */ - { NULL, NULL }, /* Pc */ - { NULL, NULL }, /* Pf */ - { NULL, NULL }, /* Po */ - { NULL, NULL }, /* Pq */ - { NULL, NULL }, /* Qc */ - { NULL, NULL }, /* Ql */ - { NULL, NULL }, /* Qo */ - { NULL, NULL }, /* Qq */ - { NULL, NULL }, /* Re */ - { NULL, post_rs }, /* Rs */ - { NULL, NULL }, /* Sc */ - { NULL, NULL }, /* So */ - { NULL, NULL }, /* Sq */ - { NULL, post_sm }, /* Sm */ - { NULL, post_hyph }, /* Sx */ - { NULL, NULL }, /* Sy */ - { NULL, NULL }, /* Tn */ - { NULL, NULL }, /* Ux */ - { NULL, NULL }, /* Xc */ - { NULL, NULL }, /* Xo */ - { NULL, post_fo }, /* Fo */ - { NULL, NULL }, /* Fc */ - { NULL, NULL }, /* Oo */ - { NULL, NULL }, /* Oc */ - { NULL, post_bk }, /* Bk */ - { NULL, NULL }, /* Ek */ - { NULL, post_eoln }, /* Bt */ - { NULL, NULL }, /* Hf */ - { pre_obsolete, NULL }, /* Fr */ - { NULL, post_eoln }, /* Ud */ - { NULL, post_lb }, /* Lb */ - { pre_par, post_par }, /* Lp */ - { NULL, NULL }, /* Lk */ - { NULL, post_defaults }, /* Mt */ - { NULL, NULL }, /* Brq */ - { NULL, NULL }, /* Bro */ - { NULL, NULL }, /* Brc */ - { NULL, NULL }, /* %C */ - { pre_obsolete, post_es }, /* Es */ - { pre_obsolete, post_en }, /* En */ - { NULL, NULL }, /* Dx */ - { NULL, NULL }, /* %Q */ - { NULL, post_par }, /* br */ - { NULL, post_par }, /* sp */ - { NULL, NULL }, /* %U */ - { NULL, NULL }, /* Ta */ - { NULL, NULL }, /* ll */ +static void post_std(POST_ARGS); + +static v_post mdoc_valids[MDOC_MAX] = { + NULL, /* Ap */ + post_dd, /* Dd */ + post_dt, /* Dt */ + post_os, /* Os */ + post_sh, /* Sh */ + post_ignpar, /* Ss */ + post_par, /* Pp */ + post_display, /* D1 */ + post_display, /* Dl */ + post_display, /* Bd */ + NULL, /* Ed */ + post_bl, /* Bl */ + NULL, /* El */ + post_it, /* It */ + NULL, /* Ad */ + post_an, /* An */ + post_defaults, /* Ar */ + NULL, /* Cd */ + NULL, /* Cm */ + NULL, /* Dv */ + NULL, /* Er */ + NULL, /* Ev */ + post_ex, /* Ex */ + post_fa, /* Fa */ + NULL, /* Fd */ + NULL, /* Fl */ + post_fn, /* Fn */ + NULL, /* Ft */ + NULL, /* Ic */ + NULL, /* In */ + post_defaults, /* Li */ + post_nd, /* Nd */ + post_nm, /* Nm */ + NULL, /* Op */ + post_obsolete, /* Ot */ + post_defaults, /* Pa */ + post_std, /* Rv */ + post_st, /* St */ + NULL, /* Va */ + NULL, /* Vt */ + NULL, /* Xr */ + NULL, /* %A */ + post_hyph, /* %B */ /* FIXME: can be used outside Rs/Re. */ + NULL, /* %D */ + NULL, /* %I */ + NULL, /* %J */ + post_hyph, /* %N */ + post_hyph, /* %O */ + NULL, /* %P */ + post_hyph, /* %R */ + post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ + NULL, /* %V */ + NULL, /* Ac */ + NULL, /* Ao */ + NULL, /* Aq */ + post_at, /* At */ + NULL, /* Bc */ + post_bf, /* Bf */ + NULL, /* Bo */ + NULL, /* Bq */ + NULL, /* Bsx */ + post_bx, /* Bx */ + post_obsolete, /* Db */ + NULL, /* Dc */ + NULL, /* Do */ + NULL, /* Dq */ + NULL, /* Ec */ + NULL, /* Ef */ + NULL, /* Em */ + NULL, /* Eo */ + NULL, /* Fx */ + NULL, /* Ms */ + NULL, /* No */ + post_ns, /* Ns */ + NULL, /* Nx */ + NULL, /* Ox */ + NULL, /* Pc */ + NULL, /* Pf */ + NULL, /* Po */ + NULL, /* Pq */ + NULL, /* Qc */ + NULL, /* Ql */ + NULL, /* Qo */ + NULL, /* Qq */ + NULL, /* Re */ + post_rs, /* Rs */ + NULL, /* Sc */ + NULL, /* So */ + NULL, /* Sq */ + post_sm, /* Sm */ + post_hyph, /* Sx */ + NULL, /* Sy */ + NULL, /* Tn */ + NULL, /* Ux */ + NULL, /* Xc */ + NULL, /* Xo */ + post_fo, /* Fo */ + NULL, /* Fc */ + NULL, /* Oo */ + NULL, /* Oc */ + post_bk, /* Bk */ + NULL, /* Ek */ + post_eoln, /* Bt */ + NULL, /* Hf */ + post_obsolete, /* Fr */ + post_eoln, /* Ud */ + post_lb, /* Lb */ + post_par, /* Lp */ + NULL, /* Lk */ + post_defaults, /* Mt */ + NULL, /* Brq */ + NULL, /* Bro */ + NULL, /* Brc */ + NULL, /* %C */ + post_es, /* Es */ + post_en, /* En */ + NULL, /* Dx */ + NULL, /* %Q */ + post_par, /* br */ + post_par, /* sp */ + NULL, /* %U */ + NULL, /* Ta */ + NULL, /* ll */ }; #define RSORD_MAX 14 /* Number of `Rs' blocks. */ -static const enum mdoct rsord[RSORD_MAX] = { +static const int rsord[RSORD_MAX] = { MDOC__A, MDOC__T, MDOC__B, @@ -292,53 +278,36 @@ static const char * const secnames[SEC__MAX] = { void -mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) +mdoc_node_validate(struct roff_man *mdoc) { - v_pre p; + struct roff_node *n; + v_post *p; + n = mdoc->last; + mdoc->last = mdoc->last->child; + while (mdoc->last != NULL) { + mdoc_node_validate(mdoc); + if (mdoc->last == n) + mdoc->last = mdoc->last->child; + else + mdoc->last = mdoc->last->next; + } + + mdoc->last = n; + mdoc->next = ROFF_NEXT_SIBLING; switch (n->type) { - case MDOC_TEXT: + case ROFFT_TEXT: if (n->sec != SEC_SYNOPSIS || n->parent->tok != MDOC_Fd) check_text(mdoc, n->line, n->pos, n->string); - /* FALLTHROUGH */ - case MDOC_TBL: - /* FALLTHROUGH */ - case MDOC_EQN: - /* FALLTHROUGH */ - case MDOC_ROOT: - return; - default: break; - } - - check_args(mdoc, n); - p = mdoc_valids[n->tok].pre; - if (*p) - (*p)(mdoc, n); -} - -void -mdoc_valid_post(struct mdoc *mdoc) -{ - struct mdoc_node *n; - v_post p; - - n = mdoc->last; - if (n->flags & MDOC_VALID) - return; - n->flags |= MDOC_VALID | MDOC_ENDED; - - switch (n->type) { - case MDOC_TEXT: - /* FALLTHROUGH */ - case MDOC_EQN: - /* FALLTHROUGH */ - case MDOC_TBL: + case ROFFT_EQN: + case ROFFT_TBL: break; - case MDOC_ROOT: + case ROFFT_ROOT: post_root(mdoc); break; default: + check_args(mdoc, mdoc->last); /* * Closing delimiters are not special at the @@ -353,15 +322,17 @@ mdoc_valid_post(struct mdoc *mdoc) /* Call the macro's postprocessor. */ - p = mdoc_valids[n->tok].post; + p = mdoc_valids + n->tok; if (*p) (*p)(mdoc); + if (mdoc->last == n) + mdoc_state(mdoc, n); break; } } static void -check_args(struct mdoc *mdoc, struct mdoc_node *n) +check_args(struct roff_man *mdoc, struct roff_node *n) { int i; @@ -374,7 +345,7 @@ check_args(struct mdoc *mdoc, struct mdoc_node *n) } static void -check_argv(struct mdoc *mdoc, struct mdoc_node *n, struct mdoc_argv *v) +check_argv(struct roff_man *mdoc, struct roff_node *n, struct mdoc_argv *v) { int i; @@ -383,7 +354,7 @@ check_argv(struct mdoc *mdoc, struct mdoc_node *n, struct mdoc_argv *v) } static void -check_text(struct mdoc *mdoc, int ln, int pos, char *p) +check_text(struct roff_man *mdoc, int ln, int pos, char *p) { char *cp; @@ -396,34 +367,16 @@ check_text(struct mdoc *mdoc, int ln, int pos, char *p) } static void -pre_display(PRE_ARGS) -{ - struct mdoc_node *node; - - if (MDOC_BLOCK != n->type) - return; - - for (node = mdoc->last->parent; node; node = node->parent) - if (MDOC_BLOCK == node->type) - if (MDOC_Bd == node->tok) - break; - - if (node) - mandoc_vmsg(MANDOCERR_BD_NEST, - mdoc->parse, n->line, n->pos, - "%s in Bd", mdoc_macronames[n->tok]); -} - -static void -pre_bl(PRE_ARGS) +post_bl_norm(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv, *wa; int i; enum mdocargt mdoclt; enum mdoc_list lt; - if (n->type != MDOC_BLOCK) - return; + n = mdoc->last->parent; + n->norm->Bl.type = LIST__NONE; /* * First figure out which kind of list to use: bind ourselves to @@ -565,13 +518,9 @@ pre_bl(PRE_ARGS) n->line, n->pos, "Bl -tag"); break; case LIST_column: - /* FALLTHROUGH */ case LIST_diag: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_item: if (n->norm->Bl.width) mandoc_vmsg(MANDOCERR_BL_SKIPW, mdoc->parse, @@ -579,9 +528,7 @@ pre_bl(PRE_ARGS) mdoc_argnames[mdoclt]); break; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_hyphen: if (NULL == n->norm->Bl.width) n->norm->Bl.width = "2n"; @@ -593,21 +540,17 @@ pre_bl(PRE_ARGS) default: break; } - pre_par(mdoc, n); } static void -pre_bd(PRE_ARGS) +post_bd(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv; int i; enum mdoc_disp dt; - pre_literal(mdoc, n); - - if (n->type != MDOC_BLOCK) - return; - + n = mdoc->last; for (i = 0; n->args && i < (int)n->args->argc; i++) { argv = n->args->argv + i; dt = DISP__NONE; @@ -656,7 +599,6 @@ pre_bd(PRE_ARGS) break; default: abort(); - /* NOTREACHED */ } if (DISP__NONE == dt) continue; @@ -674,15 +616,16 @@ pre_bd(PRE_ARGS) n->line, n->pos, "Bd"); n->norm->Bd.type = DISP_ragged; } - pre_par(mdoc, n); } static void -pre_an(PRE_ARGS) +post_an_norm(POST_ARGS) { + struct roff_node *n; struct mdoc_argv *argv; size_t i; + n = mdoc->last; if (n->args == NULL) return; @@ -703,11 +646,13 @@ pre_an(PRE_ARGS) } static void -pre_std(PRE_ARGS) +post_std(POST_ARGS) { + struct roff_node *n; - if (n->args && 1 == n->args->argc) - if (MDOC_Std == n->args->argv[0].arg) + n = mdoc->last; + if (n->args && n->args->argc == 1) + if (n->args->argv[0].arg == MDOC_Std) return; mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse, @@ -715,61 +660,20 @@ pre_std(PRE_ARGS) } static void -pre_obsolete(PRE_ARGS) +post_obsolete(POST_ARGS) { + struct roff_node *n; - if (MDOC_ELEM == n->type || MDOC_BLOCK == n->type) + n = mdoc->last; + if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK) mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse, n->line, n->pos, mdoc_macronames[n->tok]); } static void -pre_dt(PRE_ARGS) -{ - - if (mdoc->meta.title != NULL) - mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, - n->line, n->pos, "Dt"); - else if (mdoc->meta.os != NULL) - mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, - n->line, n->pos, "Dt after Os"); -} - -static void -pre_os(PRE_ARGS) -{ - - if (mdoc->meta.os != NULL) - mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, - n->line, n->pos, "Os"); - else if (mdoc->flags & MDOC_PBODY) - mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, - n->line, n->pos, "Os"); -} - -static void -pre_dd(PRE_ARGS) -{ - - if (mdoc->meta.date != NULL) - mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, - n->line, n->pos, "Dd"); - else if (mdoc->flags & MDOC_PBODY) - mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, - n->line, n->pos, "Dd"); - else if (mdoc->meta.title != NULL) - mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, - n->line, n->pos, "Dd after Dt"); - else if (mdoc->meta.os != NULL) - mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, - n->line, n->pos, "Dd after Os"); -} - -static void post_bf(POST_ARGS) { - struct mdoc_node *np, *nch; - enum mdocargt arg; + struct roff_node *np, *nch; /* * Unlike other data pointers, these are "housed" by the HEAD @@ -777,49 +681,53 @@ post_bf(POST_ARGS) */ np = mdoc->last; - if (MDOC_HEAD != np->type) + if (np->type != ROFFT_HEAD) return; - assert(MDOC_BLOCK == np->parent->type); - assert(MDOC_Bf == np->parent->tok); + assert(np->parent->type == ROFFT_BLOCK); + assert(np->parent->tok == MDOC_Bf); /* Check the number of arguments. */ nch = np->child; - if (NULL == np->parent->args) { - if (NULL == nch) { + if (np->parent->args == NULL) { + if (nch == NULL) { mandoc_msg(MANDOCERR_BF_NOFONT, mdoc->parse, np->line, np->pos, "Bf"); return; } nch = nch->next; } - if (NULL != nch) + if (nch != NULL) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nch->line, nch->pos, "Bf ... %s", nch->string); /* Extract argument into data. */ - if (np->parent->args) { - arg = np->parent->args->argv[0].arg; - if (MDOC_Emphasis == arg) + if (np->parent->args != NULL) { + switch (np->parent->args->argv[0].arg) { + case MDOC_Emphasis: np->norm->Bf.font = FONT_Em; - else if (MDOC_Literal == arg) + break; + case MDOC_Literal: np->norm->Bf.font = FONT_Li; - else if (MDOC_Symbolic == arg) + break; + case MDOC_Symbolic: np->norm->Bf.font = FONT_Sy; - else + break; + default: abort(); + } return; } /* Extract parameter into data. */ - if (0 == strcmp(np->child->string, "Em")) + if ( ! strcmp(np->child->string, "Em")) np->norm->Bf.font = FONT_Em; - else if (0 == strcmp(np->child->string, "Li")) + else if ( ! strcmp(np->child->string, "Li")) np->norm->Bf.font = FONT_Li; - else if (0 == strcmp(np->child->string, "Sy")) + else if ( ! strcmp(np->child->string, "Sy")) np->norm->Bf.font = FONT_Sy; else mandoc_vmsg(MANDOCERR_BF_BADFONT, mdoc->parse, @@ -830,12 +738,12 @@ post_bf(POST_ARGS) static void post_lb(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; const char *stdlibname; char *libname; n = mdoc->last->child; - assert(MDOC_TEXT == n->type); + assert(n->type == ROFFT_TEXT); if (NULL == (stdlibname = mdoc_a2lib(n->string))) mandoc_asprintf(&libname, @@ -850,10 +758,10 @@ post_lb(POST_ARGS) static void post_eoln(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; n = mdoc->last; - if (n->child) + if (n->child != NULL) mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, n->line, n->pos, "%s %s", mdoc_macronames[n->tok], @@ -863,7 +771,7 @@ post_eoln(POST_ARGS) static void post_fname(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; const char *cp; size_t pos; @@ -886,11 +794,11 @@ post_fn(POST_ARGS) static void post_fo(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; n = mdoc->last; - if (n->type != MDOC_HEAD) + if (n->type != ROFFT_HEAD) return; if (n->child == NULL) { @@ -903,7 +811,7 @@ post_fo(POST_ARGS) n->child->next->line, n->child->next->pos, "Fo ... %s", n->child->next->string); while (n->child != n->last) - mdoc_node_delete(mdoc, n->last); + roff_node_delete(mdoc, n->last); } post_fname(mdoc); @@ -912,7 +820,7 @@ post_fo(POST_ARGS) static void post_fa(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; const char *cp; for (n = mdoc->last->child; n != NULL; n = n->next) { @@ -931,31 +839,9 @@ post_fa(POST_ARGS) } static void -post_vt(POST_ARGS) -{ - const struct mdoc_node *n; - - /* - * The Vt macro comes in both ELEM and BLOCK form, both of which - * have different syntaxes (yet more context-sensitive - * behaviour). ELEM types must have a child, which is already - * guaranteed by the in_line parsing routine; BLOCK types, - * specifically the BODY, should only have TEXT children. - */ - - if (MDOC_BODY != mdoc->last->type) - return; - - for (n = mdoc->last->child; n; n = n->next) - if (MDOC_TEXT != n->type) - mandoc_msg(MANDOCERR_VT_CHILD, mdoc->parse, - n->line, n->pos, mdoc_macronames[n->tok]); -} - -static void post_nm(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; @@ -964,12 +850,12 @@ post_nm(POST_ARGS) n->last->tok == MDOC_Lp)) mdoc_node_relink(mdoc, n->last); - if (NULL != mdoc->meta.name) + if (mdoc->meta.name != NULL) return; - mdoc_deroff(&mdoc->meta.name, n); + deroff(&mdoc->meta.name, n); - if (NULL == mdoc->meta.name) + if (mdoc->meta.name == NULL) mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse, n->line, n->pos, "Nm"); } @@ -977,11 +863,11 @@ post_nm(POST_ARGS) static void post_nd(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; - if (n->type != MDOC_BODY) + if (n->type != ROFFT_BODY) return; if (n->child == NULL) @@ -992,48 +878,54 @@ post_nd(POST_ARGS) } static void -post_d1(POST_ARGS) +post_display(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n, *np; n = mdoc->last; - - if (n->type != MDOC_BODY) - return; - - if (n->child == NULL) - mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, - n->line, n->pos, "D1"); - - post_hyph(mdoc); -} - -static void -post_literal(POST_ARGS) -{ - struct mdoc_node *n; - - n = mdoc->last; - - if (n->type != MDOC_BODY) - return; - - if (n->child == NULL) - mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, - n->line, n->pos, mdoc_macronames[n->tok]); - - if (n->tok == MDOC_Bd && - n->norm->Bd.type != DISP_literal && - n->norm->Bd.type != DISP_unfilled) - return; - - mdoc->flags &= ~MDOC_LITERAL; + switch (n->type) { + case ROFFT_BODY: + if (n->end != ENDBODY_NOT) + break; + if (n->child == NULL) + mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, + n->line, n->pos, mdoc_macronames[n->tok]); + else if (n->tok == MDOC_D1) + post_hyph(mdoc); + break; + case ROFFT_BLOCK: + if (n->tok == MDOC_Bd) { + if (n->args == NULL) { + mandoc_msg(MANDOCERR_BD_NOARG, + mdoc->parse, n->line, n->pos, "Bd"); + mdoc->next = ROFF_NEXT_SIBLING; + while (n->body->child != NULL) + mdoc_node_relink(mdoc, + n->body->child); + roff_node_delete(mdoc, n); + break; + } + post_bd(mdoc); + post_prevpar(mdoc); + } + for (np = n->parent; np != NULL; np = np->parent) { + if (np->type == ROFFT_BLOCK && np->tok == MDOC_Bd) { + mandoc_vmsg(MANDOCERR_BD_NEST, + mdoc->parse, n->line, n->pos, + "%s in Bd", mdoc_macronames[n->tok]); + break; + } + } + break; + default: + break; + } } static void post_defaults(POST_ARGS) { - struct mdoc_node *nn; + struct roff_node *nn; /* * The `Ar' defaults to "file ..." if no value is provided as an @@ -1041,25 +933,24 @@ post_defaults(POST_ARGS) * gets an empty string. */ - if (mdoc->last->child) + if (mdoc->last->child != NULL) return; nn = mdoc->last; - mdoc->next = MDOC_NEXT_CHILD; switch (nn->tok) { case MDOC_Ar: - mdoc_word_alloc(mdoc, nn->line, nn->pos, "file"); - mdoc_word_alloc(mdoc, nn->line, nn->pos, "..."); + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, nn->line, nn->pos, "file"); + roff_word_alloc(mdoc, nn->line, nn->pos, "..."); break; case MDOC_Pa: - /* FALLTHROUGH */ case MDOC_Mt: - mdoc_word_alloc(mdoc, nn->line, nn->pos, "~"); + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, nn->line, nn->pos, "~"); break; default: abort(); - /* NOTREACHED */ } mdoc->last = nn; } @@ -1067,14 +958,14 @@ post_defaults(POST_ARGS) static void post_at(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; const char *std_att; char *att; n = mdoc->last; if (n->child == NULL) { - mdoc->next = MDOC_NEXT_CHILD; - mdoc_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"); + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, n->line, n->pos, "AT&T UNIX"); mdoc->last = n; return; } @@ -1086,8 +977,8 @@ post_at(POST_ARGS) */ n = n->child; - assert(MDOC_TEXT == n->type); - if (NULL == (std_att = mdoc_a2att(n->string))) { + assert(n->type == ROFFT_TEXT); + if ((std_att = mdoc_a2att(n->string)) == NULL) { mandoc_vmsg(MANDOCERR_AT_BAD, mdoc->parse, n->line, n->pos, "At %s", n->string); mandoc_asprintf(&att, "AT&T UNIX %s", n->string); @@ -1101,7 +992,9 @@ post_at(POST_ARGS) static void post_an(POST_ARGS) { - struct mdoc_node *np, *nch; + struct roff_node *np, *nch; + + post_an_norm(mdoc); np = mdoc->last; nch = np->child; @@ -1118,7 +1011,8 @@ static void post_en(POST_ARGS) { - if (MDOC_BLOCK == mdoc->last->type) + post_obsolete(mdoc); + if (mdoc->last->type == ROFFT_BLOCK) mdoc->last->norm->Es = mdoc->last_es; } @@ -1126,18 +1020,21 @@ static void post_es(POST_ARGS) { + post_obsolete(mdoc); mdoc->last_es = mdoc->last; } static void post_it(POST_ARGS) { + struct roff_node *nbl, *nit, *nch; int i, cols; enum mdoc_list lt; - struct mdoc_node *nbl, *nit, *nch; + + post_prevpar(mdoc); nit = mdoc->last; - if (nit->type != MDOC_BLOCK) + if (nit->type != ROFFT_BLOCK) return; nbl = nit->parent->parent; @@ -1145,13 +1042,9 @@ post_it(POST_ARGS) switch (lt) { case LIST_tag: - /* FALLTHROUGH */ case LIST_hang: - /* FALLTHROUGH */ case LIST_ohang: - /* FALLTHROUGH */ case LIST_inset: - /* FALLTHROUGH */ case LIST_diag: if (nit->head->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOHEAD, @@ -1160,11 +1053,8 @@ post_it(POST_ARGS) mdoc_argnames[nbl->args->argv[0].arg]); break; case LIST_bullet: - /* FALLTHROUGH */ case LIST_dash: - /* FALLTHROUGH */ case LIST_enum: - /* FALLTHROUGH */ case LIST_hyphen: if (nit->body == NULL || nit->body->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOBODY, @@ -1183,8 +1073,9 @@ post_it(POST_ARGS) assert(nit->head->child == NULL); - for (i = 0, nch = nit->child; nch; nch = nch->next) - if (nch->type == MDOC_BODY) + i = 0; + for (nch = nit->child; nch != NULL; nch = nch->next) + if (nch->type == ROFFT_BODY) i++; if (i < cols || i > cols + 1) @@ -1200,7 +1091,9 @@ post_it(POST_ARGS) static void post_bl_block(POST_ARGS) { - struct mdoc_node *n, *ni, *nc; + struct roff_node *n, *ni, *nc; + + post_prevpar(mdoc); /* * These are fairly complicated, so we've broken them into two @@ -1212,40 +1105,38 @@ post_bl_block(POST_ARGS) n = mdoc->last; - if (LIST_tag == n->norm->Bl.type && - NULL == n->norm->Bl.width) { + if (n->norm->Bl.type == LIST_tag && + n->norm->Bl.width == NULL) { post_bl_block_tag(mdoc); - assert(n->norm->Bl.width); + assert(n->norm->Bl.width != NULL); } - for (ni = n->body->child; ni; ni = ni->next) { - if (NULL == ni->body) + for (ni = n->body->child; ni != NULL; ni = ni->next) { + if (ni->body == NULL) continue; nc = ni->body->last; - while (NULL != nc) { + while (nc != NULL) { switch (nc->tok) { case MDOC_Pp: - /* FALLTHROUGH */ case MDOC_Lp: - /* FALLTHROUGH */ case MDOC_br: break; default: nc = NULL; continue; } - if (NULL == ni->next) { + if (ni->next == NULL) { mandoc_msg(MANDOCERR_PAR_MOVE, mdoc->parse, nc->line, nc->pos, mdoc_macronames[nc->tok]); mdoc_node_relink(mdoc, nc); - } else if (0 == n->norm->Bl.comp && - LIST_column != n->norm->Bl.type) { + } else if (n->norm->Bl.comp == 0 && + n->norm->Bl.type != LIST_column) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, nc->line, nc->pos, "%s before It", mdoc_macronames[nc->tok]); - mdoc_node_delete(mdoc, nc); + roff_node_delete(mdoc, nc); } else break; nc = ni->body->last; @@ -1261,13 +1152,13 @@ void rewrite_macro2len(char **arg) { size_t width; - enum mdoct tok; + int tok; if (*arg == NULL) return; else if ( ! strcmp(*arg, "Ds")) width = 6; - else if ((tok = mdoc_hash_find(*arg)) == MDOC_MAX) + else if ((tok = mdoc_hash_find(*arg)) == TOKEN_NONE) return; else width = macro2len(tok); @@ -1279,7 +1170,7 @@ rewrite_macro2len(char **arg) static void post_bl_block_tag(POST_ARGS) { - struct mdoc_node *n, *nn; + struct roff_node *n, *nn; size_t sz, ssz; int i; char buf[24]; @@ -1294,17 +1185,17 @@ post_bl_block_tag(POST_ARGS) sz = 10; n = mdoc->last; - for (nn = n->body->child; nn; nn = nn->next) { - if (MDOC_It != nn->tok) + for (nn = n->body->child; nn != NULL; nn = nn->next) { + if (nn->tok != MDOC_It) continue; - assert(MDOC_BLOCK == nn->type); + assert(nn->type == ROFFT_BLOCK); nn = nn->head->child; if (nn == NULL) break; - if (MDOC_TEXT == nn->type) { + if (nn->type == ROFFT_TEXT) { sz = strlen(nn->string) + 1; break; } @@ -1324,7 +1215,7 @@ post_bl_block_tag(POST_ARGS) * We're guaranteed that a MDOC_Width doesn't already exist. */ - assert(n->args); + assert(n->args != NULL); i = (int)(n->args->argc)++; n->args->argv = mandoc_reallocarray(n->args->argv, @@ -1344,19 +1235,20 @@ post_bl_block_tag(POST_ARGS) static void post_bl_head(POST_ARGS) { - struct mdoc_node *nbl, *nh, *nch, *nnext; + struct roff_node *nbl, *nh, *nch, *nnext; struct mdoc_argv *argv; int i, j; - nh = mdoc->last; + post_bl_norm(mdoc); + nh = mdoc->last; if (nh->norm->Bl.type != LIST_column) { if ((nch = nh->child) == NULL) return; mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nch->line, nch->pos, "Bl ... %s", nch->string); while (nch != NULL) { - mdoc_node_delete(mdoc, nch); + roff_node_delete(mdoc, nch); nch = nh->child; } return; @@ -1386,7 +1278,8 @@ post_bl_head(POST_ARGS) argv = nbl->args->argv + j; i = argv->sz; - argv->sz += nh->nchild; + for (nch = nh->child; nch != NULL; nch = nch->next) + argv->sz++; argv->value = mandoc_reallocarray(argv->value, argv->sz, sizeof(char *)); @@ -1397,32 +1290,33 @@ post_bl_head(POST_ARGS) argv->value[i++] = nch->string; nch->string = NULL; nnext = nch->next; - mdoc_node_delete(NULL, nch); + roff_node_delete(NULL, nch); } - nh->nchild = 0; nh->child = NULL; } static void post_bl(POST_ARGS) { - struct mdoc_node *nparent, *nprev; /* of the Bl block */ - struct mdoc_node *nblock, *nbody; /* of the Bl */ - struct mdoc_node *nchild, *nnext; /* of the Bl body */ + struct roff_node *nparent, *nprev; /* of the Bl block */ + struct roff_node *nblock, *nbody; /* of the Bl */ + struct roff_node *nchild, *nnext; /* of the Bl body */ nbody = mdoc->last; switch (nbody->type) { - case MDOC_BLOCK: + case ROFFT_BLOCK: post_bl_block(mdoc); return; - case MDOC_HEAD: + case ROFFT_HEAD: post_bl_head(mdoc); return; - case MDOC_BODY: + case ROFFT_BODY: break; default: return; } + if (nbody->end != ENDBODY_NOT) + return; nchild = nbody->child; if (nchild == NULL) { @@ -1457,15 +1351,12 @@ post_bl(POST_ARGS) * Unlink this child. */ - assert(NULL == nchild->prev); - if (0 == --nbody->nchild) { - nbody->child = NULL; + assert(nchild->prev == NULL); + nbody->child = nnext; + if (nnext == NULL) nbody->last = NULL; - assert(NULL == nnext); - } else { - nbody->child = nnext; + else nnext->prev = NULL; - } /* * Relink this child. @@ -1476,8 +1367,7 @@ post_bl(POST_ARGS) nchild->next = nblock; nblock->prev = nchild; - nparent->nchild++; - if (NULL == nprev) + if (nprev == NULL) nparent->child = nchild; else nprev->next = nchild; @@ -1489,21 +1379,21 @@ post_bl(POST_ARGS) static void post_bk(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; - if (n->type == MDOC_BLOCK && n->body->child == NULL) { + if (n->type == ROFFT_BLOCK && n->body->child == NULL) { mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, n->line, n->pos, "Bk"); - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } } static void -post_sm(struct mdoc *mdoc) +post_sm(POST_ARGS) { - struct mdoc_node *nch; + struct roff_node *nch; nch = mdoc->last->child; @@ -1512,7 +1402,7 @@ post_sm(struct mdoc *mdoc) return; } - assert(nch->type == MDOC_TEXT); + assert(nch->type == ROFFT_TEXT); if ( ! strcmp(nch->string, "on")) { mdoc->flags &= ~MDOC_SMOFF; @@ -1533,7 +1423,7 @@ post_sm(struct mdoc *mdoc) static void post_root(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; /* Add missing prologue data. */ @@ -1560,7 +1450,8 @@ post_root(POST_ARGS) /* Check that we begin with a proper `Sh'. */ n = mdoc->first->child; - while (n != NULL && mdoc_macros[n->tok].flags & MDOC_PROLOGUE) + while (n != NULL && n->tok != TOKEN_NONE && + mdoc_macros[n->tok].flags & MDOC_PROLOGUE) n = n->next; if (n == NULL) @@ -1573,18 +1464,18 @@ post_root(POST_ARGS) static void post_st(POST_ARGS) { - struct mdoc_node *n, *nch; + struct roff_node *n, *nch; const char *p; n = mdoc->last; nch = n->child; - assert(MDOC_TEXT == nch->type); + assert(nch->type == ROFFT_TEXT); - if (NULL == (p = mdoc_a2st(nch->string))) { + if ((p = mdoc_a2st(nch->string)) == NULL) { mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, nch->line, nch->pos, "St %s", nch->string); - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } else { free(nch->string); nch->string = mandoc_strdup(p); @@ -1594,12 +1485,12 @@ post_st(POST_ARGS) static void post_rs(POST_ARGS) { - struct mdoc_node *np, *nch, *next, *prev; + struct roff_node *np, *nch, *next, *prev; int i, j; np = mdoc->last; - if (np->type != MDOC_BODY) + if (np->type != ROFFT_BODY) return; if (np->child == NULL) { @@ -1631,7 +1522,7 @@ post_rs(POST_ARGS) /* * Remove this child from the chain. This somewhat - * repeats mdoc_node_unlink(), but since we're + * repeats roff_node_unlink(), but since we're * just re-ordering, there's no need for the * full unlink process. */ @@ -1688,11 +1579,11 @@ post_rs(POST_ARGS) static void post_hyph(POST_ARGS) { - struct mdoc_node *nch; + struct roff_node *nch; char *cp; for (nch = mdoc->last->child; nch != NULL; nch = nch->next) { - if (nch->type != MDOC_TEXT) + if (nch->type != ROFFT_TEXT) continue; cp = nch->string; if (*cp == '\0') @@ -1709,7 +1600,7 @@ static void post_ns(POST_ARGS) { - if (MDOC_LINE & mdoc->last->flags) + if (mdoc->last->flags & MDOC_LINE) mandoc_msg(MANDOCERR_NS_SKIP, mdoc->parse, mdoc->last->line, mdoc->last->pos, NULL); } @@ -1721,10 +1612,10 @@ post_sh(POST_ARGS) post_ignpar(mdoc); switch (mdoc->last->type) { - case MDOC_HEAD: + case ROFFT_HEAD: post_sh_head(mdoc); break; - case MDOC_BODY: + case ROFFT_BODY: switch (mdoc->lastsec) { case SEC_NAME: post_sh_name(mdoc); @@ -1747,7 +1638,7 @@ post_sh(POST_ARGS) static void post_sh_name(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; int hasnm, hasnd; hasnm = hasnd = 0; @@ -1763,7 +1654,7 @@ post_sh_name(POST_ARGS) mandoc_msg(MANDOCERR_NAMESEC_ND, mdoc->parse, n->line, n->pos, NULL); break; - case MDOC_MAX: + case TOKEN_NONE: if (hasnm) break; /* FALLTHROUGH */ @@ -1785,7 +1676,7 @@ post_sh_name(POST_ARGS) static void post_sh_see_also(POST_ARGS) { - const struct mdoc_node *n; + const struct roff_node *n; const char *name, *sec; const char *lastname, *lastsec, *lastpunct; int cmp; @@ -1793,7 +1684,9 @@ post_sh_see_also(POST_ARGS) n = mdoc->last->child; lastname = lastsec = lastpunct = NULL; while (n != NULL) { - if (n->tok != MDOC_Xr || n->nchild < 2) + if (n->tok != MDOC_Xr || + n->child == NULL || + n->child->next == NULL) break; /* Process one .Xr node. */ @@ -1830,7 +1723,7 @@ post_sh_see_also(POST_ARGS) lastpunct = "none"; continue; } - if (n->type != MDOC_TEXT) + if (n->type != ROFFT_TEXT) break; for (name = n->string; *name != '\0'; name++) if (isalpha((const unsigned char)*name)) @@ -1845,13 +1738,13 @@ post_sh_see_also(POST_ARGS) } static int -child_an(const struct mdoc_node *n) +child_an(const struct roff_node *n) { for (n = n->child; n != NULL; n = n->next) - if ((n->tok == MDOC_An && n->nchild) || child_an(n)) - return(1); - return(0); + if ((n->tok == MDOC_An && n->child != NULL) || child_an(n)) + return 1; + return 0; } static void @@ -1866,10 +1759,8 @@ post_sh_authors(POST_ARGS) static void post_sh_head(POST_ARGS) { - struct mdoc_node *n; const char *goodsec; - char *secname; - enum mdoc_sec sec; + enum roff_sec sec; /* * Process a new section. Sections are either "named" or @@ -1878,21 +1769,18 @@ post_sh_head(POST_ARGS) * manual sections. */ - secname = NULL; - sec = SEC_CUSTOM; - mdoc_deroff(&secname, mdoc->last); - sec = NULL == secname ? SEC_CUSTOM : a2sec(secname); + sec = mdoc->last->sec; /* The NAME should be first. */ if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); /* The SYNOPSIS gets special attention in other areas. */ - if (SEC_SYNOPSIS == sec) { + if (sec == SEC_SYNOPSIS) { roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; } else { @@ -1904,26 +1792,10 @@ post_sh_head(POST_ARGS) mdoc->lastsec = sec; - /* - * Set the section attribute for the current HEAD, for its - * parent BLOCK, and for the HEAD children; the latter can - * only be TEXT nodes, so no recursion is needed. - * For other blocks and elements, including .Sh BODY, this is - * done when allocating the node data structures, but for .Sh - * BLOCK and HEAD, the section is still unknown at that time. - */ - - mdoc->last->parent->sec = sec; - mdoc->last->sec = sec; - for (n = mdoc->last->child; n; n = n->next) - n->sec = sec; - /* We don't care about custom sections after this. */ - if (SEC_CUSTOM == sec) { - free(secname); + if (sec == SEC_CUSTOM) return; - } /* * Check whether our non-custom section is being repeated or is @@ -1933,12 +1805,12 @@ post_sh_head(POST_ARGS) if (sec == mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); if (sec < mdoc->lastnamed) mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s", secname); + "Sh %s", secnames[sec]); /* Mark the last named section. */ @@ -1946,10 +1818,8 @@ post_sh_head(POST_ARGS) /* Check particular section/manual conventions. */ - if (mdoc->meta.msec == NULL) { - free(secname); + if (mdoc->meta.msec == NULL) return; - } goodsec = NULL; switch (sec) { @@ -1959,7 +1829,6 @@ post_sh_head(POST_ARGS) goodsec = "2, 3, 4, 9"; /* FALLTHROUGH */ case SEC_RETURN_VALUES: - /* FALLTHROUGH */ case SEC_LIBRARY: if (*mdoc->meta.msec == '2') break; @@ -1975,55 +1844,56 @@ post_sh_head(POST_ARGS) goodsec = "9"; mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse, mdoc->last->line, mdoc->last->pos, - "Sh %s for %s only", secname, goodsec); + "Sh %s for %s only", secnames[sec], goodsec); break; default: break; } - free(secname); } static void post_ignpar(POST_ARGS) { - struct mdoc_node *np; + struct roff_node *np; switch (mdoc->last->type) { - case MDOC_HEAD: + case ROFFT_HEAD: post_hyph(mdoc); return; - case MDOC_BODY: + case ROFFT_BODY: break; default: return; } - if (NULL != (np = mdoc->last->child)) - if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { + if ((np = mdoc->last->child) != NULL) + if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, np->line, np->pos, "%s after %s", mdoc_macronames[np->tok], mdoc_macronames[mdoc->last->tok]); - mdoc_node_delete(mdoc, np); + roff_node_delete(mdoc, np); } - if (NULL != (np = mdoc->last->last)) - if (MDOC_Pp == np->tok || MDOC_Lp == np->tok) { + if ((np = mdoc->last->last) != NULL) + if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) { mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, np->line, np->pos, "%s at the end of %s", mdoc_macronames[np->tok], mdoc_macronames[mdoc->last->tok]); - mdoc_node_delete(mdoc, np); + roff_node_delete(mdoc, np); } } static void -pre_par(PRE_ARGS) +post_prevpar(POST_ARGS) { + struct roff_node *n; - if (NULL == mdoc->last) + n = mdoc->last; + if (NULL == n->prev) return; - if (MDOC_ELEM != n->type && MDOC_BLOCK != n->type) + if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) return; /* @@ -2031,33 +1901,35 @@ pre_par(PRE_ARGS) * block: `Lp', `Pp', or non-compact `Bd' or `Bl'. */ - if (MDOC_Pp != mdoc->last->tok && - MDOC_Lp != mdoc->last->tok && - MDOC_br != mdoc->last->tok) + if (n->prev->tok != MDOC_Pp && + n->prev->tok != MDOC_Lp && + n->prev->tok != MDOC_br) return; - if (MDOC_Bl == n->tok && n->norm->Bl.comp) + if (n->tok == MDOC_Bl && n->norm->Bl.comp) return; - if (MDOC_Bd == n->tok && n->norm->Bd.comp) + if (n->tok == MDOC_Bd && n->norm->Bd.comp) return; - if (MDOC_It == n->tok && n->parent->norm->Bl.comp) + if (n->tok == MDOC_It && n->parent->norm->Bl.comp) return; mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, - mdoc->last->line, mdoc->last->pos, - "%s before %s", mdoc_macronames[mdoc->last->tok], + n->prev->line, n->prev->pos, + "%s before %s", mdoc_macronames[n->prev->tok], mdoc_macronames[n->tok]); - mdoc_node_delete(mdoc, mdoc->last); + roff_node_delete(mdoc, n->prev); } static void post_par(POST_ARGS) { - struct mdoc_node *np; + struct roff_node *np; np = mdoc->last; + if (np->tok != MDOC_br && np->tok != MDOC_sp) + post_prevpar(mdoc); if (np->tok == MDOC_sp) { - if (np->nchild > 1) + if (np->child != NULL && np->child->next != NULL) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, np->child->next->line, np->child->next->pos, "sp ... %s", np->child->next->string); @@ -2066,70 +1938,51 @@ post_par(POST_ARGS) mdoc->parse, np->line, np->pos, "%s %s", mdoc_macronames[np->tok], np->child->string); - if (NULL == (np = mdoc->last->prev)) { + if ((np = mdoc->last->prev) == NULL) { np = mdoc->last->parent; - if (MDOC_Sh != np->tok && MDOC_Ss != np->tok) + if (np->tok != MDOC_Sh && np->tok != MDOC_Ss) return; - } else if (MDOC_Pp != np->tok && MDOC_Lp != np->tok && - (MDOC_br != mdoc->last->tok || - (MDOC_sp != np->tok && MDOC_br != np->tok))) + } else if (np->tok != MDOC_Pp && np->tok != MDOC_Lp && + (mdoc->last->tok != MDOC_br || + (np->tok != MDOC_sp && np->tok != MDOC_br))) return; mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse, mdoc->last->line, mdoc->last->pos, "%s after %s", mdoc_macronames[mdoc->last->tok], mdoc_macronames[np->tok]); - mdoc_node_delete(mdoc, mdoc->last); -} - -static void -pre_literal(PRE_ARGS) -{ - - pre_display(mdoc, n); - - if (MDOC_BODY != n->type) - return; - - /* - * The `Dl' (note "el" not "one") and `Bd -literal' and `Bd - * -unfilled' macros set MDOC_LITERAL on entrance to the body. - */ - - switch (n->tok) { - case MDOC_Dl: - mdoc->flags |= MDOC_LITERAL; - break; - case MDOC_Bd: - if (DISP_literal == n->norm->Bd.type) - mdoc->flags |= MDOC_LITERAL; - if (DISP_unfilled == n->norm->Bd.type) - mdoc->flags |= MDOC_LITERAL; - break; - default: - abort(); - /* NOTREACHED */ - } + roff_node_delete(mdoc, mdoc->last); } static void post_dd(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; char *datestr; - if (mdoc->meta.date) + n = mdoc->last; + if (mdoc->meta.date != NULL) { + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Dd"); free(mdoc->meta.date); + } else if (mdoc->flags & MDOC_PBODY) + mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, + n->line, n->pos, "Dd"); + else if (mdoc->meta.title != NULL) + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dd after Dt"); + else if (mdoc->meta.os != NULL) + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dd after Os"); - n = mdoc->last; - if (NULL == n->child || '\0' == n->child->string[0]) { + if (n->child == NULL || n->child->string[0] == '\0') { mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); goto out; } datestr = NULL; - mdoc_deroff(&datestr, n); + deroff(&datestr, n); if (mdoc->quick) mdoc->meta.date = datestr; else { @@ -2138,17 +1991,29 @@ post_dd(POST_ARGS) free(datestr); } out: - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } static void post_dt(POST_ARGS) { - struct mdoc_node *nn, *n; + struct roff_node *nn, *n; const char *cp; char *p; n = mdoc->last; + if (mdoc->flags & MDOC_PBODY) { + mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse, + n->line, n->pos, "Dt"); + goto out; + } + + if (mdoc->meta.title != NULL) + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Dt"); + else if (mdoc->meta.os != NULL) + mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse, + n->line, n->pos, "Dt after Os"); free(mdoc->meta.title); free(mdoc->meta.msec); @@ -2223,13 +2088,13 @@ post_dt(POST_ARGS) nn->line, nn->pos, "Dt ... %s", nn->string); out: - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } static void post_bx(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; /* * Make `Bx's second argument always start with an uppercase @@ -2237,8 +2102,7 @@ post_bx(POST_ARGS) * uppercase blindly. */ - n = mdoc->last->child; - if (n && NULL != (n = n->next)) + if ((n = mdoc->last->child) != NULL && (n = n->next) != NULL) *n->string = (char)toupper((unsigned char)*n->string); } @@ -2249,9 +2113,15 @@ post_os(POST_ARGS) struct utsname utsname; static char *defbuf; #endif - struct mdoc_node *n; + struct roff_node *n; n = mdoc->last; + if (mdoc->meta.os != NULL) + mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse, + n->line, n->pos, "Os"); + else if (mdoc->flags & MDOC_PBODY) + mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse, + n->line, n->pos, "Os"); /* * Set the operating system by way of the `Os' macro. @@ -2264,7 +2134,7 @@ post_os(POST_ARGS) free(mdoc->meta.os); mdoc->meta.os = NULL; - mdoc_deroff(&mdoc->meta.os, n); + deroff(&mdoc->meta.os, n); if (mdoc->meta.os) goto out; @@ -2276,8 +2146,8 @@ post_os(POST_ARGS) #ifdef OSNAME mdoc->meta.os = mandoc_strdup(OSNAME); #else /*!OSNAME */ - if (NULL == defbuf) { - if (-1 == uname(&utsname)) { + if (defbuf == NULL) { + if (uname(&utsname) == -1) { mandoc_msg(MANDOCERR_OS_UNAME, mdoc->parse, n->line, n->pos, "Os"); defbuf = mandoc_strdup("UNKNOWN"); @@ -2289,7 +2159,7 @@ post_os(POST_ARGS) #endif /*!OSNAME*/ out: - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } /* @@ -2299,11 +2169,12 @@ out: static void post_ex(POST_ARGS) { - struct mdoc_node *n; + struct roff_node *n; - n = mdoc->last; + post_std(mdoc); - if (n->child) + n = mdoc->last; + if (n->child != NULL) return; if (mdoc->meta.name == NULL) { @@ -2312,112 +2183,112 @@ post_ex(POST_ARGS) return; } - mdoc->next = MDOC_NEXT_CHILD; - mdoc_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); + mdoc->next = ROFF_NEXT_CHILD; + roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name); mdoc->last = n; } -static enum mdoc_sec -a2sec(const char *p) +enum roff_sec +mdoc_a2sec(const char *p) { int i; for (i = 0; i < (int)SEC__MAX; i++) if (secnames[i] && 0 == strcmp(p, secnames[i])) - return((enum mdoc_sec)i); + return (enum roff_sec)i; - return(SEC_CUSTOM); + return SEC_CUSTOM; } static size_t -macro2len(enum mdoct macro) +macro2len(int macro) { switch (macro) { case MDOC_Ad: - return(12); + return 12; case MDOC_Ao: - return(12); + return 12; case MDOC_An: - return(12); + return 12; case MDOC_Aq: - return(12); + return 12; case MDOC_Ar: - return(12); + return 12; case MDOC_Bo: - return(12); + return 12; case MDOC_Bq: - return(12); + return 12; case MDOC_Cd: - return(12); + return 12; case MDOC_Cm: - return(10); + return 10; case MDOC_Do: - return(10); + return 10; case MDOC_Dq: - return(12); + return 12; case MDOC_Dv: - return(12); + return 12; case MDOC_Eo: - return(12); + return 12; case MDOC_Em: - return(10); + return 10; case MDOC_Er: - return(17); + return 17; case MDOC_Ev: - return(15); + return 15; case MDOC_Fa: - return(12); + return 12; case MDOC_Fl: - return(10); + return 10; case MDOC_Fo: - return(16); + return 16; case MDOC_Fn: - return(16); + return 16; case MDOC_Ic: - return(10); + return 10; case MDOC_Li: - return(16); + return 16; case MDOC_Ms: - return(6); + return 6; case MDOC_Nm: - return(10); + return 10; case MDOC_No: - return(12); + return 12; case MDOC_Oo: - return(10); + return 10; case MDOC_Op: - return(14); + return 14; case MDOC_Pa: - return(32); + return 32; case MDOC_Pf: - return(12); + return 12; case MDOC_Po: - return(12); + return 12; case MDOC_Pq: - return(12); + return 12; case MDOC_Ql: - return(16); + return 16; case MDOC_Qo: - return(12); + return 12; case MDOC_So: - return(12); + return 12; case MDOC_Sq: - return(12); + return 12; case MDOC_Sy: - return(6); + return 6; case MDOC_Sx: - return(16); + return 16; case MDOC_Tn: - return(10); + return 10; case MDOC_Va: - return(12); + return 12; case MDOC_Vt: - return(12); + return 12; case MDOC_Xr: - return(10); + return 10; default: break; }; - return(0); + return 0; } diff --git a/contrib/mdocml/msec.c b/contrib/mdocml/msec.c index d49d297..9d41511 100644 --- a/contrib/mdocml/msec.c +++ b/contrib/mdocml/msec.c @@ -1,4 +1,4 @@ -/* $Id: msec.c,v 1.14 2014/12/21 14:14:35 schwarze Exp $ */ +/* $Id: msec.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -32,5 +32,5 @@ mandoc_a2msec(const char *p) #include "msec.in" - return(NULL); + return NULL; } diff --git a/contrib/mdocml/out.c b/contrib/mdocml/out.c index 53b93fb..aff3558 100644 --- a/contrib/mdocml/out.c +++ b/contrib/mdocml/out.c @@ -1,4 +1,4 @@ -/* $Id: out.c,v 1.59 2015/01/30 04:11:50 schwarze Exp $ */ +/* $Id: out.c,v 1.62 2015/10/12 00:08:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -51,7 +51,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def) dst->unit = def == SCALE_MAX ? SCALE_BU : def; dst->scale = strtod(src, &endptr); if (endptr == src) - return(0); + return 0; switch (*endptr++) { case 'c': @@ -89,12 +89,12 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def) /* FALLTHROUGH */ default: if (SCALE_MAX == def) - return(0); + return 0; dst->unit = def; break; } - return(*endptr == '\0' ? 2 : 1); + return *endptr == '\0' ? 2 : 1; } /* @@ -240,18 +240,14 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col, switch (dp->layout->pos) { case TBL_CELL_HORIZ: - /* FALLTHROUGH */ case TBL_CELL_DHORIZ: sz = (*tbl->len)(1, tbl->arg); if (col->width < sz) col->width = sz; break; case TBL_CELL_LONG: - /* FALLTHROUGH */ case TBL_CELL_CENTRE: - /* FALLTHROUGH */ case TBL_CELL_LEFT: - /* FALLTHROUGH */ case TBL_CELL_RIGHT: tblcalc_literal(tbl, col, dp); break; @@ -262,7 +258,6 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col, break; default: abort(); - /* NOTREACHED */ } } diff --git a/contrib/mdocml/out.h b/contrib/mdocml/out.h index cc218f4..2c1cf3f 100644 --- a/contrib/mdocml/out.h +++ b/contrib/mdocml/out.h @@ -1,4 +1,4 @@ -/* $Id: out.h,v 1.26 2014/12/01 08:05:52 schwarze Exp $ */ +/* $Id: out.h,v 1.27 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -60,12 +60,9 @@ struct rofftbl { (p)->scale = (v); } \ while (/* CONSTCOND */ 0) -__BEGIN_DECLS struct tbl_span; int a2roffsu(const char *, struct roffsu *, enum roffscale); void tblcalc(struct rofftbl *tbl, const struct tbl_span *, size_t); - -__END_DECLS diff --git a/contrib/mdocml/preconv.c b/contrib/mdocml/preconv.c index 87e65ea..1fc137a 100644 --- a/contrib/mdocml/preconv.c +++ b/contrib/mdocml/preconv.c @@ -1,4 +1,4 @@ -/* $Id: preconv.c,v 1.14 2015/03/06 09:24:59 kristaps Exp $ */ +/* $Id: preconv.c,v 1.15 2015/10/06 18:32:19 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -92,17 +92,17 @@ preconv_encode(struct buf *ib, size_t *ii, struct buf *ob, size_t *oi, *oi += snprintf(ob->buf + *oi, 11, "\\[u%.4X]", accum); *ii = (char *)cu - ib->buf; *filenc &= ~MPARSE_LATIN1; - return(1); + return 1; latin: if ( ! (*filenc & MPARSE_LATIN1)) - return(0); + return 0; *oi += snprintf(ob->buf + *oi, 11, "\\[u%.4X]", (unsigned char)ib->buf[(*ii)++]); *filenc &= ~MPARSE_UTF8; - return(1); + return 1; } int @@ -123,7 +123,7 @@ preconv_cue(const struct buf *b, size_t offset) if ((sz = (size_t)(eoln - ln)) < 10 || memcmp(ln, ".\\\" -*-", 7) || memcmp(eoln - 3, "-*-", 3)) - return(MPARSE_UTF8 | MPARSE_LATIN1); + return MPARSE_UTF8 | MPARSE_LATIN1; /* Move after the header and adjust for the trailer. */ @@ -162,15 +162,15 @@ preconv_cue(const struct buf *b, size_t offset) sz--; } if (0 == sz) - return(0); + return 0; /* Check us against known encodings. */ if (phsz > 4 && !strncasecmp(ln, "utf-8", 5)) - return(MPARSE_UTF8); + return MPARSE_UTF8; if (phsz > 10 && !strncasecmp(ln, "iso-latin-1", 11)) - return(MPARSE_LATIN1); - return(0); + return MPARSE_LATIN1; + return 0; } - return(MPARSE_UTF8 | MPARSE_LATIN1); + return MPARSE_UTF8 | MPARSE_LATIN1; } diff --git a/contrib/mdocml/read.c b/contrib/mdocml/read.c index a34c9ff..0ef3cdf 100644 --- a/contrib/mdocml/read.c +++ b/contrib/mdocml/read.c @@ -1,16 +1,16 @@ -/* $Id: read.c,v 1.131 2015/03/11 13:05:20 schwarze Exp $ */ +/* $Id: read.c,v 1.148 2016/01/08 02:53:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -23,12 +23,13 @@ #include <sys/mman.h> #include <sys/stat.h> #endif -#include <sys/wait.h> #include <assert.h> #include <ctype.h> -#include <errno.h> +#if HAVE_ERR #include <err.h> +#endif +#include <errno.h> #include <fcntl.h> #include <stdarg.h> #include <stdint.h> @@ -38,21 +39,19 @@ #include <unistd.h> #include <zlib.h> -#include "mandoc.h" #include "mandoc_aux.h" -#include "libmandoc.h" +#include "mandoc.h" +#include "roff.h" #include "mdoc.h" #include "man.h" +#include "libmandoc.h" +#include "roff_int.h" #define REPARSE_LIMIT 1000 struct mparse { - struct man *pman; /* persistent man parser */ - struct mdoc *pmdoc; /* persistent mdoc parser */ - struct man *man; /* man parser */ - struct mdoc *mdoc; /* mdoc parser */ + struct roff_man *man; /* man parser */ struct roff *roff; /* roff parser (!NULL) */ - const struct mchars *mchars; /* character table */ char *sodest; /* filename pointed to by .so */ const char *file; /* filename of current input file */ struct buf *primary; /* buffer currently being parsed */ @@ -62,10 +61,10 @@ struct mparse { enum mandoclevel file_status; /* status of current parse */ enum mandoclevel wlevel; /* ignore messages below this */ int options; /* parser options */ + int gzip; /* current input file is gzipped */ int filenc; /* encoding of the current file */ int reparse_count; /* finite interp. stack */ int line; /* line number in the file */ - pid_t child; /* the gunzip(1) process */ }; static void choose_parser(struct mparse *); @@ -132,7 +131,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "blocks badly nested", "nested displays are not portable", "moving content out of list", - ".Vt block has child macro", "fill mode already enabled, skipping", "fill mode already disabled, skipping", "line scope broken", @@ -219,6 +217,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { /* related to request and macro arguments */ "escaped character not allowed in a name", "NOT IMPLEMENTED: Bd -file", + "skipping display without arguments", "missing list type, using -item", "missing manual name, using \"\"", "uname(3) system call failed, using UNKNOWN", @@ -292,24 +291,22 @@ choose_parser(struct mparse *curp) } } - if (format == MPARSE_MDOC) { - if (NULL == curp->pmdoc) - curp->pmdoc = mdoc_alloc( - curp->roff, curp, curp->defos, - MPARSE_QUICK & curp->options ? 1 : 0); - assert(curp->pmdoc); - curp->mdoc = curp->pmdoc; - return; + if (curp->man == NULL) { + curp->man = roff_man_alloc(curp->roff, curp, curp->defos, + curp->options & MPARSE_QUICK ? 1 : 0); + curp->man->macroset = MACROSET_MAN; + curp->man->first->tok = TOKEN_NONE; } - /* Fall back to man(7) as a last resort. */ - - if (NULL == curp->pman) - curp->pman = man_alloc( - curp->roff, curp, curp->defos, - MPARSE_QUICK & curp->options ? 1 : 0); - assert(curp->pman); - curp->man = curp->pman; + if (format == MPARSE_MDOC) { + mdoc_hash_init(); + curp->man->macroset = MACROSET_MDOC; + curp->man->first->tok = TOKEN_NONE; + } else { + man_hash_init(); + curp->man->macroset = MACROSET_MAN; + curp->man->first->tok = TOKEN_NONE; + } } /* @@ -331,7 +328,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start) int of; int lnn; /* line number in the real file */ int fd; - pid_t save_child; unsigned char c; memset(&ln, 0, sizeof(ln)); @@ -543,10 +539,9 @@ rerun: if (curp->secondary) curp->secondary->sz -= pos + 1; save_file = curp->file; - save_child = curp->child; - if (mparse_open(curp, &fd, ln.buf + of) == - MANDOCLEVEL_OK) { + if ((fd = mparse_open(curp, ln.buf + of)) != -1) { mparse_readfd(curp, fd, ln.buf + of); + close(fd); curp->file = save_file; } else { curp->file = save_file; @@ -561,7 +556,6 @@ rerun: of = 0; mparse_buf_r(curp, ln, of, 0); } - curp->child = save_child; pos = 0; continue; default: @@ -575,7 +569,8 @@ rerun: * parsers with each one. */ - if ( ! (curp->man || curp->mdoc)) + if (curp->man == NULL || + curp->man->macroset == MACROSET_NONE) choose_parser(curp); /* @@ -587,19 +582,13 @@ rerun: * Do the same for ROFF_EQN. */ - if (rr == ROFF_TBL) { + if (rr == ROFF_TBL) while ((span = roff_span(curp->roff)) != NULL) - if (curp->man == NULL) - mdoc_addspan(curp->mdoc, span); - else - man_addspan(curp->man, span); - } else if (rr == ROFF_EQN) { - if (curp->man == NULL) - mdoc_addeqn(curp->mdoc, roff_eqn(curp->roff)); - else - man_addeqn(curp->man, roff_eqn(curp->roff)); - } else if ((curp->man == NULL ? - mdoc_parseln(curp->mdoc, curp->line, ln.buf, of) : + roff_addtbl(curp->man, span); + else if (rr == ROFF_EQN) + roff_addeqn(curp->man, roff_eqn(curp->roff)); + else if ((curp->man->macroset == MACROSET_MDOC ? + mdoc_parseln(curp->man, curp->line, ln.buf, of) : man_parseln(curp->man, curp->line, ln.buf, of)) == 2) break; @@ -620,15 +609,15 @@ static int read_whole_file(struct mparse *curp, const char *file, int fd, struct buf *fb, int *with_mmap) { + gzFile gz; size_t off; ssize_t ssz; #if HAVE_MMAP struct stat st; - if (-1 == fstat(fd, &st)) { - perror(file); - exit((int)MANDOCLEVEL_SYSERR); - } + + if (fstat(fd, &st) == -1) + err((int)MANDOCLEVEL_SYSERR, "%s", file); /* * If we're a regular file, try just reading in the whole entry @@ -637,19 +626,25 @@ read_whole_file(struct mparse *curp, const char *file, int fd, * concerned that this is going to tank any machines. */ - if (S_ISREG(st.st_mode)) { + if (curp->gzip == 0 && S_ISREG(st.st_mode)) { if (st.st_size > 0x7fffffff) { mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL); - return(0); + return 0; } *with_mmap = 1; fb->sz = (size_t)st.st_size; fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); if (fb->buf != MAP_FAILED) - return(1); + return 1; } #endif + if (curp->gzip) { + if ((gz = gzdopen(fd, "rb")) == NULL) + err((int)MANDOCLEVEL_SYSERR, "%s", file); + } else + gz = NULL; + /* * If this isn't a regular file (like, say, stdin), then we must * go the old way and just read things in bit by bit. @@ -668,43 +663,35 @@ read_whole_file(struct mparse *curp, const char *file, int fd, } resize_buf(fb, 65536); } - ssz = read(fd, fb->buf + (int)off, fb->sz - off); + ssz = curp->gzip ? + gzread(gz, fb->buf + (int)off, fb->sz - off) : + read(fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; - return(1); - } - if (ssz == -1) { - perror(file); - exit((int)MANDOCLEVEL_SYSERR); + return 1; } + if (ssz == -1) + err((int)MANDOCLEVEL_SYSERR, "%s", file); off += (size_t)ssz; } free(fb->buf); fb->buf = NULL; - return(0); + return 0; } static void mparse_end(struct mparse *curp) { - if (curp->mdoc == NULL && - curp->man == NULL && - curp->sodest == NULL) { - if (curp->options & MPARSE_MDOC) - curp->mdoc = curp->pmdoc; - else { - if (curp->pman == NULL) - curp->pman = man_alloc( - curp->roff, curp, curp->defos, - curp->options & MPARSE_QUICK ? 1 : 0); - curp->man = curp->pman; - } - } - if (curp->mdoc) - mdoc_endparse(curp->mdoc); - if (curp->man) + if (curp->man == NULL && curp->sodest == NULL) + curp->man = roff_man_alloc(curp->roff, curp, curp->defos, + curp->options & MPARSE_QUICK ? 1 : 0); + if (curp->man->macroset == MACROSET_NONE) + curp->man->macroset = MACROSET_MAN; + if (curp->man->macroset == MACROSET_MDOC) + mdoc_endparse(curp->man); + else man_endparse(curp->man); roff_endparse(curp->roff); } @@ -759,7 +746,7 @@ mparse_readmem(struct mparse *curp, void *buf, size_t len, blk.sz = len; mparse_parse_buffer(curp, blk, file); - return(curp->file_status); + return curp->file_status; } /* @@ -786,126 +773,48 @@ mparse_readfd(struct mparse *curp, int fd, const char *file) #endif free(blk.buf); } - - if (fd != STDIN_FILENO && close(fd) == -1) - perror(file); - - mparse_wait(curp); - return(curp->file_status); + return curp->file_status; } -/* - * hack to avoid depending on gnuzip(1) waiting for upstream proper - * support - */ -static int -gunzip(const char *file) -{ - gzFile gz; - char buf[8192]; - int r; - - gz = gzopen(file, "r"); - if (gz == NULL) - err(EXIT_FAILURE, "cannot open %s", file); - - while ((r = gzread(gz, buf, sizeof(buf))) > 0) - fwrite(buf, 1, r, stdout); - - gzclose(gz); - return (EXIT_SUCCESS); -} -enum mandoclevel -mparse_open(struct mparse *curp, int *fd, const char *file) +int +mparse_open(struct mparse *curp, const char *file) { - int pfd[2]; - int save_errno; char *cp; + int fd; curp->file = file; + cp = strrchr(file, '.'); + curp->gzip = (cp != NULL && ! strcmp(cp + 1, "gz")); - /* Unless zipped, try to just open the file. */ + /* First try to use the filename as it is. */ - if ((cp = strrchr(file, '.')) == NULL || - strcmp(cp + 1, "gz")) { - curp->child = 0; - if ((*fd = open(file, O_RDONLY)) != -1) - return(MANDOCLEVEL_OK); + if ((fd = open(file, O_RDONLY)) != -1) + return fd; - /* Open failed; try to append ".gz". */ + /* + * If that doesn't work and the filename doesn't + * already end in .gz, try appending .gz. + */ + if ( ! curp->gzip) { mandoc_asprintf(&cp, "%s.gz", file); - file = cp; - } else - cp = NULL; - - /* Before forking, make sure the file can be read. */ - - save_errno = errno; - if (access(file, R_OK) == -1) { - if (cp != NULL) - errno = save_errno; + fd = open(file, O_RDONLY); free(cp); - *fd = -1; - curp->child = 0; - mandoc_msg(MANDOCERR_FILE, curp, 0, 0, strerror(errno)); - return(MANDOCLEVEL_ERROR); - } - - /* Run gunzip(1). */ - - if (pipe(pfd) == -1) { - perror("pipe"); - exit((int)MANDOCLEVEL_SYSERR); - } - - switch (curp->child = fork()) { - case -1: - perror("fork"); - exit((int)MANDOCLEVEL_SYSERR); - case 0: - close(pfd[0]); - if (dup2(pfd[1], STDOUT_FILENO) == -1) { - perror("dup"); - exit((int)MANDOCLEVEL_SYSERR); + if (fd != -1) { + curp->gzip = 1; + return fd; } - exit(gunzip(file)); - default: - close(pfd[1]); - *fd = pfd[0]; - return(MANDOCLEVEL_OK); } -} -enum mandoclevel -mparse_wait(struct mparse *curp) -{ - int status; - - if (curp->child == 0) - return(MANDOCLEVEL_OK); + /* Neither worked, give up. */ - if (waitpid(curp->child, &status, 0) == -1) { - perror("wait"); - exit((int)MANDOCLEVEL_SYSERR); - } - curp->child = 0; - if (WIFSIGNALED(status)) { - mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, - "gunzip died from signal %d", WTERMSIG(status)); - return(MANDOCLEVEL_ERROR); - } - if (WEXITSTATUS(status)) { - mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, - "gunzip failed with code %d", WEXITSTATUS(status)); - return(MANDOCLEVEL_ERROR); - } - return(MANDOCLEVEL_OK); + mandoc_msg(MANDOCERR_FILE, curp, 0, 0, strerror(errno)); + return -1; } struct mparse * mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg, - const struct mchars *mchars, const char *defos) + const char *defos) { struct mparse *curp; @@ -916,18 +825,18 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg, curp->mmsg = mmsg; curp->defos = defos; - curp->mchars = mchars; - curp->roff = roff_alloc(curp, curp->mchars, options); - if (curp->options & MPARSE_MDOC) - curp->pmdoc = mdoc_alloc( - curp->roff, curp, curp->defos, - curp->options & MPARSE_QUICK ? 1 : 0); - if (curp->options & MPARSE_MAN) - curp->pman = man_alloc( - curp->roff, curp, curp->defos, - curp->options & MPARSE_QUICK ? 1 : 0); - - return(curp); + curp->roff = roff_alloc(curp, options); + curp->man = roff_man_alloc( curp->roff, curp, curp->defos, + curp->options & MPARSE_QUICK ? 1 : 0); + if (curp->options & MPARSE_MDOC) { + mdoc_hash_init(); + curp->man->macroset = MACROSET_MDOC; + } else if (curp->options & MPARSE_MAN) { + man_hash_init(); + curp->man->macroset = MACROSET_MAN; + } + curp->man->first->tok = TOKEN_NONE; + return curp; } void @@ -936,16 +845,12 @@ mparse_reset(struct mparse *curp) roff_reset(curp->roff); - if (curp->mdoc) - mdoc_reset(curp->mdoc); - if (curp->man) - man_reset(curp->man); + if (curp->man != NULL) + roff_man_reset(curp->man); if (curp->secondary) curp->secondary->sz = 0; curp->file_status = MANDOCLEVEL_OK; - curp->mdoc = NULL; - curp->man = NULL; free(curp->sodest); curp->sodest = NULL; @@ -955,10 +860,7 @@ void mparse_free(struct mparse *curp) { - if (curp->pmdoc) - mdoc_free(curp->pmdoc); - if (curp->pman) - man_free(curp->pman); + roff_man_free(curp->man); if (curp->roff) roff_free(curp->roff); if (curp->secondary) @@ -970,17 +872,14 @@ mparse_free(struct mparse *curp) } void -mparse_result(struct mparse *curp, - struct mdoc **mdoc, struct man **man, char **sodest) +mparse_result(struct mparse *curp, struct roff_man **man, + char **sodest) { if (sodest && NULL != (*sodest = curp->sodest)) { - *mdoc = NULL; *man = NULL; return; } - if (mdoc) - *mdoc = curp->mdoc; if (man) *man = curp->man; } @@ -1023,13 +922,13 @@ const char * mparse_strerror(enum mandocerr er) { - return(mandocerrs[er]); + return mandocerrs[er]; } const char * mparse_strlevel(enum mandoclevel lvl) { - return(mandoclevels[lvl]); + return mandoclevels[lvl]; } void @@ -1045,5 +944,5 @@ mparse_getkeep(const struct mparse *p) { assert(p->secondary); - return(p->secondary->sz ? p->secondary->buf : NULL); + return p->secondary->sz ? p->secondary->buf : NULL; } diff --git a/contrib/mdocml/roff.7 b/contrib/mdocml/roff.7 index dc39b69..114f63e 100644 --- a/contrib/mdocml/roff.7 +++ b/contrib/mdocml/roff.7 @@ -1,7 +1,7 @@ -.\" $Id: roff.7,v 1.70 2015/02/17 17:16:52 schwarze Exp $ +.\" $Id: roff.7,v 1.75 2015/09/24 18:41:22 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010, 2011, 2013-2015 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 17 2015 $ +.Dd $Mdocdate: September 24 2015 $ .Dt ROFF 7 .Os .Sh NAME @@ -665,6 +665,8 @@ produces .D1 \efI\e^XtFree\e^\efP. .Pp in the input stream, and thus in the output: \fI\^XtFree\^\fP. +Each occurrence of \e\e$* is replaced with all the arguments, +joined together with single blank characters. .Pp Since macros and user-defined strings share a common string table, defining a macro @@ -1057,8 +1059,6 @@ If the first character of COND is .Pq string defined , .Sq e .Pq even page , -.Sq r -.Pq register accessed , .Sq t .Pq troff mode , or @@ -1066,6 +1066,11 @@ or .Pq vroff mode , COND evaluates to false. .It +If the first character of COND is +.Sq r , +it evaluates to true if the rest of COND is the name of an existing +number register; otherwise, it evaluates to false. +.It If COND starts with a parenthesis or with an optionally signed integer number, it is evaluated according to the rules of .Sx Numerical expressions @@ -1337,7 +1342,7 @@ Currently unsupported. Temporarily turn off line numbering. Currently unsupported. .Ss \&nop -Exexute the rest of the input line as a request or macro line. +Execute the rest of the input line as a request or macro line. Currently unsupported. .Ss \&nr Define or change a register. @@ -1579,7 +1584,7 @@ Set tab stops. Takes an arbitrary number of arguments. Currently unsupported. .Ss \&tc -Change tab repetion character. +Change tab repetition character. Currently unsupported. .Ss \&TE End a table context. @@ -1679,7 +1684,7 @@ Notify on change of string or macro. This is a Heirloom extension and currently ignored. .Ss \&watchlength On change, report the contents of macros and strings -up to the sepcified length. +up to the specified length. This is a Heirloom extension and currently ignored. .Ss \&watchn Notify on change of register. @@ -1774,7 +1779,7 @@ minimum (not available in C) maximum (not available in C) .El .Pp -There is no concept of precendence; evaluation proceeds from left to right, +There is no concept of precedence; evaluation proceeds from left to right, except when subexpressions are enclosed in parantheses. Inside parentheses, whitespace is ignored. .Sh ESCAPE SEQUENCE REFERENCE @@ -1834,9 +1839,15 @@ For short names, there are variants .No \e* Ns Ar c and .No \e*( Ns Ar cc . +.Ss \e, +Left italic correction (groff extension); ignored by +.Xr mandoc 1 . .Ss \e- Special character .Dq mathematical minus sign . +.Ss \e/ +Right italic correction (groff extension); ignored by +.Xr mandoc 1 . .Ss \e[ Ns Ar name ] .Sx Special Characters with names of arbitrary length, see @@ -2028,10 +2039,7 @@ Print with zero width and height; ignored by .Xr mandoc 1 . .Ss \ez -Output the next character without advancing the cursor position; -approximated in -.Xr mandoc 1 -by simply skipping the next character. +Output the next character without advancing the cursor position. .Sh COMPATIBILITY The .Xr mandoc 1 diff --git a/contrib/mdocml/roff.c b/contrib/mdocml/roff.c index 3c92013..13b9439 100644 --- a/contrib/mdocml/roff.c +++ b/contrib/mdocml/roff.c @@ -1,6 +1,6 @@ -/* $Id: roff.c,v 1.263 2015/02/21 14:46:58 schwarze Exp $ */ +/* $Id: roff.c,v 1.284 2016/01/08 17:48:10 schwarze Exp $ */ /* - * Copyright (c) 2010, 2011, 2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -28,15 +28,16 @@ #include "mandoc.h" #include "mandoc_aux.h" +#include "roff.h" #include "libmandoc.h" +#include "roff_int.h" #include "libroff.h" -/* Maximum number of nested if-else conditionals. */ -#define RSTACK_MAX 128 - /* Maximum number of string expansions per line, to break infinite loops. */ #define EXPAND_LIMIT 1000 +/* --- data types --------------------------------------------------------- */ + enum rofft { ROFF_ab, ROFF_ad, @@ -312,7 +313,6 @@ struct roffreg { struct roff { struct mparse *parse; /* parse point */ - const struct mchars *mchars; /* character table */ struct roffnode *last; /* leaf of stack */ int *rstack; /* stack of inverted `ie' values */ struct roffreg *regtab; /* number registers */ @@ -331,6 +331,7 @@ struct roff { int rstacksz; /* current size limit of rstack */ int rstackpos; /* position in rstack */ int format; /* current file in mdoc or man format */ + int argc; /* number of args of the last macro */ char control; /* control character */ }; @@ -373,6 +374,8 @@ struct predef { #define PREDEF(__name, __str) \ { (__name), (__str) }, +/* --- function prototypes ------------------------------------------------ */ + static enum rofft roffhash_find(const char *, size_t); static void roffhash_init(void); static void roffnode_cleanscope(struct roff *); @@ -391,8 +394,7 @@ static enum rofferr roff_cond_text(ROFF_ARGS); static enum rofferr roff_cond_sub(ROFF_ARGS); static enum rofferr roff_ds(ROFF_ARGS); static enum rofferr roff_eqndelim(struct roff *, struct buf *, int); -static int roff_evalcond(struct roff *r, int, - const char *, int *); +static int roff_evalcond(struct roff *r, int, char *, int *); static int roff_evalnum(struct roff *, int, const char *, int *, int *, int); static int roff_evalpar(struct roff *, int, @@ -406,12 +408,17 @@ static int roff_getnum(const char *, int *, int *, int); static int roff_getop(const char *, int *, char *); static int roff_getregn(const struct roff *, const char *, size_t); -static int roff_getregro(const char *name); +static int roff_getregro(const struct roff *, + const char *name); static const char *roff_getstrn(const struct roff *, const char *, size_t); +static int roff_hasregn(const struct roff *, + const char *, size_t); static enum rofferr roff_insec(ROFF_ARGS); static enum rofferr roff_it(ROFF_ARGS); static enum rofferr roff_line_ignore(ROFF_ARGS); +static void roff_man_alloc1(struct roff_man *); +static void roff_man_free1(struct roff_man *); static enum rofferr roff_nr(ROFF_ARGS); static enum rofft roff_parse(struct roff *, char *, int *, int, int); @@ -435,6 +442,8 @@ static enum rofferr roff_T_(ROFF_ARGS); static enum rofferr roff_unsupp(ROFF_ARGS); static enum rofferr roff_userdef(ROFF_ARGS); +/* --- constant data ------------------------------------------------------ */ + /* See roffhash_find() */ #define ASCII_HI 126 @@ -731,6 +740,8 @@ static int roffit_lines; /* number of lines to delay */ static char *roffit_macro; /* nil-terminated macro line */ +/* --- request table ------------------------------------------------------ */ + static void roffhash_init(void) { @@ -770,19 +781,21 @@ roffhash_find(const char *p, size_t s) */ if (p[0] < ASCII_LO || p[0] > ASCII_HI) - return(ROFF_MAX); + return ROFF_MAX; buc = ROFF_HASH(p); if (NULL == (n = hash[buc])) - return(ROFF_MAX); + return ROFF_MAX; for ( ; n; n = n->next) if (0 == strncmp(n->name, p, s) && '\0' == n->name[(int)s]) - return((enum rofft)(n - roffs)); + return (enum rofft)(n - roffs); - return(ROFF_MAX); + return ROFF_MAX; } +/* --- stack of request blocks -------------------------------------------- */ + /* * Pop the current node off of the stack of roff instructions currently * pending. @@ -823,6 +836,8 @@ roffnode_push(struct roff *r, enum rofft tok, const char *name, r->last = p; } +/* --- roff parser state data management ---------------------------------- */ + static void roff_free1(struct roff *r) { @@ -882,22 +897,370 @@ roff_free(struct roff *r) } struct roff * -roff_alloc(struct mparse *parse, const struct mchars *mchars, int options) +roff_alloc(struct mparse *parse, int options) { struct roff *r; r = mandoc_calloc(1, sizeof(struct roff)); r->parse = parse; - r->mchars = mchars; r->options = options; r->format = options & (MPARSE_MDOC | MPARSE_MAN); r->rstackpos = -1; roffhash_init(); - return(r); + return r; +} + +/* --- syntax tree state data management ---------------------------------- */ + +static void +roff_man_free1(struct roff_man *man) +{ + + if (man->first != NULL) + roff_node_delete(man, man->first); + free(man->meta.msec); + free(man->meta.vol); + free(man->meta.os); + free(man->meta.arch); + free(man->meta.title); + free(man->meta.name); + free(man->meta.date); +} + +static void +roff_man_alloc1(struct roff_man *man) +{ + + memset(&man->meta, 0, sizeof(man->meta)); + man->first = mandoc_calloc(1, sizeof(*man->first)); + man->first->type = ROFFT_ROOT; + man->last = man->first; + man->last_es = NULL; + man->flags = 0; + man->macroset = MACROSET_NONE; + man->lastsec = man->lastnamed = SEC_NONE; + man->next = ROFF_NEXT_CHILD; +} + +void +roff_man_reset(struct roff_man *man) +{ + + roff_man_free1(man); + roff_man_alloc1(man); +} + +void +roff_man_free(struct roff_man *man) +{ + + roff_man_free1(man); + free(man); +} + +struct roff_man * +roff_man_alloc(struct roff *roff, struct mparse *parse, + const char *defos, int quick) +{ + struct roff_man *man; + + man = mandoc_calloc(1, sizeof(*man)); + man->parse = parse; + man->roff = roff; + man->defos = defos; + man->quick = quick; + roff_man_alloc1(man); + return man; +} + +/* --- syntax tree handling ----------------------------------------------- */ + +struct roff_node * +roff_node_alloc(struct roff_man *man, int line, int pos, + enum roff_type type, int tok) +{ + struct roff_node *n; + + n = mandoc_calloc(1, sizeof(*n)); + n->line = line; + n->pos = pos; + n->tok = tok; + n->type = type; + n->sec = man->lastsec; + + if (man->flags & MDOC_SYNOPSIS) + n->flags |= MDOC_SYNPRETTY; + else + n->flags &= ~MDOC_SYNPRETTY; + if (man->flags & MDOC_NEWLINE) + n->flags |= MDOC_LINE; + man->flags &= ~MDOC_NEWLINE; + + return n; +} + +void +roff_node_append(struct roff_man *man, struct roff_node *n) +{ + + switch (man->next) { + case ROFF_NEXT_SIBLING: + if (man->last->next != NULL) { + n->next = man->last->next; + man->last->next->prev = n; + } else + man->last->parent->last = n; + man->last->next = n; + n->prev = man->last; + n->parent = man->last->parent; + break; + case ROFF_NEXT_CHILD: + man->last->child = n; + n->parent = man->last; + n->parent->last = n; + break; + default: + abort(); + } + man->last = n; + + switch (n->type) { + case ROFFT_HEAD: + n->parent->head = n; + break; + case ROFFT_BODY: + if (n->end != ENDBODY_NOT) + return; + n->parent->body = n; + break; + case ROFFT_TAIL: + n->parent->tail = n; + break; + default: + return; + } + + /* + * Copy over the normalised-data pointer of our parent. Not + * everybody has one, but copying a null pointer is fine. + */ + + n->norm = n->parent->norm; + assert(n->parent->type == ROFFT_BLOCK); +} + +void +roff_word_alloc(struct roff_man *man, int line, int pos, const char *word) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_TEXT, TOKEN_NONE); + n->string = roff_strdup(man->roff, word); + roff_node_append(man, n); + if (man->macroset == MACROSET_MDOC) + n->flags |= MDOC_VALID | MDOC_ENDED; + else + n->flags |= MAN_VALID; + man->next = ROFF_NEXT_SIBLING; +} + +void +roff_word_append(struct roff_man *man, const char *word) +{ + struct roff_node *n; + char *addstr, *newstr; + + n = man->last; + addstr = roff_strdup(man->roff, word); + mandoc_asprintf(&newstr, "%s %s", n->string, addstr); + free(addstr); + free(n->string); + n->string = newstr; + man->next = ROFF_NEXT_SIBLING; +} + +void +roff_elem_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_ELEM, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; +} + +struct roff_node * +roff_block_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_BLOCK, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; + return n; +} + +struct roff_node * +roff_head_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_HEAD, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; + return n; +} + +struct roff_node * +roff_body_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_BODY, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; + return n; +} + +void +roff_addeqn(struct roff_man *man, const struct eqn *eqn) +{ + struct roff_node *n; + + n = roff_node_alloc(man, eqn->ln, eqn->pos, ROFFT_EQN, TOKEN_NONE); + n->eqn = eqn; + if (eqn->ln > man->last->line) + n->flags |= MDOC_LINE; + roff_node_append(man, n); + man->next = ROFF_NEXT_SIBLING; +} + +void +roff_addtbl(struct roff_man *man, const struct tbl_span *tbl) +{ + struct roff_node *n; + + if (man->macroset == MACROSET_MAN) + man_breakscope(man, TOKEN_NONE); + n = roff_node_alloc(man, tbl->line, 0, ROFFT_TBL, TOKEN_NONE); + n->span = tbl; + roff_node_append(man, n); + if (man->macroset == MACROSET_MDOC) + n->flags |= MDOC_VALID | MDOC_ENDED; + else + n->flags |= MAN_VALID; + man->next = ROFF_NEXT_SIBLING; +} + +void +roff_node_unlink(struct roff_man *man, struct roff_node *n) +{ + + /* Adjust siblings. */ + + if (n->prev) + n->prev->next = n->next; + if (n->next) + n->next->prev = n->prev; + + /* Adjust parent. */ + + if (n->parent != NULL) { + if (n->parent->child == n) + n->parent->child = n->next; + if (n->parent->last == n) + n->parent->last = n->prev; + } + + /* Adjust parse point. */ + + if (man == NULL) + return; + if (man->last == n) { + if (n->prev == NULL) { + man->last = n->parent; + man->next = ROFF_NEXT_CHILD; + } else { + man->last = n->prev; + man->next = ROFF_NEXT_SIBLING; + } + } + if (man->first == n) + man->first = NULL; +} + +void +roff_node_free(struct roff_node *n) +{ + + if (n->args != NULL) + mdoc_argv_free(n->args); + if (n->type == ROFFT_BLOCK || n->type == ROFFT_ELEM) + free(n->norm); + free(n->string); + free(n); +} + +void +roff_node_delete(struct roff_man *man, struct roff_node *n) +{ + + while (n->child != NULL) + roff_node_delete(man, n->child); + roff_node_unlink(man, n); + roff_node_free(n); } +void +deroff(char **dest, const struct roff_node *n) +{ + char *cp; + size_t sz; + + if (n->type != ROFFT_TEXT) { + for (n = n->child; n != NULL; n = n->next) + deroff(dest, n); + return; + } + + /* Skip leading whitespace and escape sequences. */ + + cp = n->string; + while (*cp != '\0') { + if ('\\' == *cp) { + cp++; + mandoc_escape((const char **)&cp, NULL, NULL); + } else if (isspace((unsigned char)*cp)) + cp++; + else + break; + } + + /* Skip trailing whitespace. */ + + for (sz = strlen(cp); sz; sz--) + if ( ! isspace((unsigned char)cp[sz-1])) + break; + + /* Skip empty strings. */ + + if (sz == 0) + return; + + if (*dest == NULL) { + *dest = mandoc_strndup(cp, sz); + return; + } + + mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp); + free(*dest); + *dest = cp; +} + +/* --- main functions of the roff parser ---------------------------------- */ + /* * In the current line, expand escape sequences that tend to get * used in numerical expressions and conditional requests. @@ -952,7 +1315,6 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) res = NULL; break; case 'B': - /* FALLTHROUGH */ case 'w': term = cp[1]; /* FALLTHROUGH */ @@ -963,7 +1325,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) esc = mandoc_escape(&cp, &stnam, &inaml); if (esc == ESCAPE_ERROR || (esc == ESCAPE_SPECIAL && - mchars_spec2cp(r->mchars, stnam, inaml) < 0)) + mchars_spec2cp(stnam, inaml) < 0)) mandoc_vmsg(MANDOCERR_ESC_BAD, r->parse, ln, (int)(stesc - buf->buf), "%.*s", (int)(cp - stesc), stesc); @@ -973,7 +1335,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) if (EXPAND_LIMIT < ++expand_count) { mandoc_msg(MANDOCERR_ROFFLOOP, r->parse, ln, (int)(stesc - buf->buf), NULL); - return(ROFF_IGN); + return ROFF_IGN; } /* @@ -1027,11 +1389,8 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) } switch (mandoc_escape(&cp, NULL, NULL)) { case ESCAPE_SPECIAL: - /* FALLTHROUGH */ case ESCAPE_UNICODE: - /* FALLTHROUGH */ case ESCAPE_NUMBERED: - /* FALLTHROUGH */ case ESCAPE_OVERSTRIKE: naml++; break; @@ -1080,7 +1439,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) } else if (buf->sz + strlen(res) > SHRT_MAX) { mandoc_msg(MANDOCERR_ROFFLOOP, r->parse, ln, (int)(stesc - buf->buf), NULL); - return(ROFF_IGN); + return ROFF_IGN; } /* Replace the escape sequence by the string. */ @@ -1096,13 +1455,11 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) free(buf->buf); buf->buf = nbuf; } - return(ROFF_CONT); + return ROFF_CONT; } /* - * Process text streams: - * Convert all breakable hyphens into ASCII_HYPH. - * Decrement and spring input line trap. + * Process text streams. */ static enum rofferr roff_parsetext(struct buf *buf, int pos, int *offs) @@ -1113,6 +1470,22 @@ roff_parsetext(struct buf *buf, int pos, int *offs) int isz; enum mandoc_esc esc; + /* Spring the input line trap. */ + + if (roffit_lines == 1) { + isz = mandoc_asprintf(&p, "%s\n.%s", buf->buf, roffit_macro); + free(buf->buf); + buf->buf = p; + buf->sz = isz + 1; + *offs = 0; + free(roffit_macro); + roffit_lines = 0; + return ROFF_REPARSE; + } else if (roffit_lines > 1) + --roffit_lines; + + /* Convert all breakable hyphens into ASCII_HYPH. */ + start = p = buf->buf + pos; while (*p != '\0') { @@ -1128,6 +1501,8 @@ roff_parsetext(struct buf *buf, int pos, int *offs) esc = mandoc_escape((const char **)&p, NULL, NULL); if (esc == ESCAPE_ERROR) break; + while (*p == '-') + p++; continue; } else if (p == start) { p++; @@ -1139,20 +1514,7 @@ roff_parsetext(struct buf *buf, int pos, int *offs) *p = ASCII_HYPH; p++; } - - /* Spring the input line trap. */ - if (roffit_lines == 1) { - isz = mandoc_asprintf(&p, "%s\n.%s", buf->buf, roffit_macro); - free(buf->buf); - buf->buf = p; - buf->sz = isz + 1; - *offs = 0; - free(roffit_macro); - roffit_lines = 0; - return(ROFF_REPARSE); - } else if (roffit_lines > 1) - --roffit_lines; - return(ROFF_CONT); + return ROFF_CONT; } enum rofferr @@ -1174,7 +1536,7 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs) (r->eqn == NULL || r->eqn_inline)) { e = roff_eqndelim(r, buf, pos); if (e == ROFF_REPARSE) - return(e); + return e; assert(e == ROFF_CONT); } @@ -1182,7 +1544,7 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs) e = roff_res(r, buf, ln, pos); if (e == ROFF_IGN) - return(e); + return e; assert(e == ROFF_CONT); ctl = roff_getcontrol(r, buf->buf, &pos); @@ -1201,23 +1563,23 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs) e = (*roffs[t].text)(r, t, buf, ln, pos, pos, offs); assert(e == ROFF_IGN || e == ROFF_CONT); if (e != ROFF_CONT) - return(e); + return e; } if (r->eqn != NULL) - return(eqn_read(&r->eqn, ln, buf->buf, ppos, offs)); + return eqn_read(&r->eqn, ln, buf->buf, ppos, offs); if (r->tbl != NULL && ( ! ctl || buf->buf[pos] == '\0')) - return(tbl_read(r->tbl, ln, buf->buf, ppos)); + return tbl_read(r->tbl, ln, buf->buf, ppos); if ( ! ctl) - return(roff_parsetext(buf, pos, offs)); + return roff_parsetext(buf, pos, offs); /* Skip empty request lines. */ if (buf->buf[pos] == '"') { mandoc_msg(MANDOCERR_COMMENT_BAD, r->parse, ln, pos, NULL); - return(ROFF_IGN); + return ROFF_IGN; } else if (buf->buf[pos] == '\0') - return(ROFF_IGN); + return ROFF_IGN; /* * If a scope is open, go to the child handler for that macro, @@ -1228,7 +1590,7 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs) if (r->last) { t = r->last->tok; assert(roffs[t].sub); - return((*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs)); + return (*roffs[t].sub)(r, t, buf, ln, ppos, pos, offs); } /* No scope is open. This is a new request or macro. */ @@ -1242,12 +1604,12 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs) mandoc_msg(MANDOCERR_TBLMACRO, r->parse, ln, pos, buf->buf + spos); if (t == ROFF_TS) - return(ROFF_IGN); + return ROFF_IGN; while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ') pos++; while (buf->buf[pos] != '\0' && buf->buf[pos] == ' ') pos++; - return(tbl_read(r->tbl, ln, buf->buf, pos)); + return tbl_read(r->tbl, ln, buf->buf, pos); } /* @@ -1256,12 +1618,12 @@ roff_parseln(struct roff *r, int ln, struct buf *buf, int *offs) */ if (t == ROFF_MAX) - return(ROFF_CONT); + return ROFF_CONT; /* Execute a roff request or a user defined macro. */ assert(roffs[t].proc); - return((*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs)); + return (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs); } void @@ -1301,7 +1663,7 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) cp = buf + *pos; if ('\0' == *cp || '"' == *cp || '\t' == *cp || ' ' == *cp) - return(ROFF_MAX); + return ROFF_MAX; mac = cp; maclen = roff_getname(r, &cp, ln, ppos); @@ -1312,9 +1674,11 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) if (ROFF_MAX != t) *pos = cp - buf; - return(t); + return t; } +/* --- handling of request blocks ----------------------------------------- */ + static enum rofferr roff_cblock(ROFF_ARGS) { @@ -1327,26 +1691,22 @@ roff_cblock(ROFF_ARGS) if (r->last == NULL) { mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, ".."); - return(ROFF_IGN); + return ROFF_IGN; } switch (r->last->tok) { case ROFF_am: /* ROFF_am1 is remapped to ROFF_am in roff_block(). */ - /* FALLTHROUGH */ case ROFF_ami: - /* FALLTHROUGH */ case ROFF_de: /* ROFF_de1 is remapped to ROFF_de in roff_block(). */ - /* FALLTHROUGH */ case ROFF_dei: - /* FALLTHROUGH */ case ROFF_ig: break; default: mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, ".."); - return(ROFF_IGN); + return ROFF_IGN; } if (buf->buf[pos] != '\0') @@ -1355,7 +1715,7 @@ roff_cblock(ROFF_ARGS) roffnode_pop(r); roffnode_cleanscope(r); - return(ROFF_IGN); + return ROFF_IGN; } @@ -1382,9 +1742,7 @@ roff_ccond(struct roff *r, int ln, int ppos) switch (r->last->tok) { case ROFF_el: - /* FALLTHROUGH */ case ROFF_ie: - /* FALLTHROUGH */ case ROFF_if: break; default: @@ -1450,7 +1808,7 @@ roff_block(ROFF_ARGS) if (namesz == 0 && tok != ROFF_ig) { mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse, ln, ppos, roffs[tok].name); - return(ROFF_IGN); + return ROFF_IGN; } roffnode_push(r, tok, name, ln, ppos); @@ -1465,7 +1823,7 @@ roff_block(ROFF_ARGS) roff_setstrn(&r->strtab, name, namesz, "", 0, 0); if (*cp == '\0') - return(ROFF_IGN); + return ROFF_IGN; /* Get the custom end marker. */ @@ -1492,7 +1850,7 @@ roff_block(ROFF_ARGS) mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse, ln, pos, ".%s ... %s", roffs[tok].name, cp); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -1528,8 +1886,8 @@ roff_block_sub(ROFF_ARGS) pos = i; if (roff_parse(r, buf->buf, &pos, ln, ppos) != ROFF_MAX) - return(ROFF_RERUN); - return(ROFF_IGN); + return ROFF_RERUN; + return ROFF_IGN; } } @@ -1543,11 +1901,11 @@ roff_block_sub(ROFF_ARGS) if (t != ROFF_cblock) { if (tok != ROFF_ig) roff_setstr(r, r->last->name, buf->buf + ppos, 2); - return(ROFF_IGN); + return ROFF_IGN; } assert(roffs[t].proc); - return((*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs)); + return (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs); } static enum rofferr @@ -1557,7 +1915,7 @@ roff_block_text(ROFF_ARGS) if (tok != ROFF_ig) roff_setstr(r, r->last->name, buf->buf + pos, 2); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -1579,7 +1937,7 @@ roff_cond_sub(ROFF_ARGS) if ((t != ROFF_MAX) && (rr || roffs[t].flags & ROFFMAC_STRUCT)) { assert(roffs[t].proc); - return((*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs)); + return (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs); } /* @@ -1601,7 +1959,7 @@ roff_cond_sub(ROFF_ARGS) if (*ep != '\0') ++ep; } - return(rr ? ROFF_CONT : ROFF_IGN); + return rr ? ROFF_CONT : ROFF_IGN; } static enum rofferr @@ -1622,9 +1980,11 @@ roff_cond_text(ROFF_ARGS) if (*ep != '\0') ++ep; } - return(rr ? ROFF_CONT : ROFF_IGN); + return rr ? ROFF_CONT : ROFF_IGN; } +/* --- handling of numeric and conditional expressions -------------------- */ + /* * Parse a single signed integer number. Stop at the first non-digit. * If there is at least one digit, return success and advance the @@ -1669,12 +2029,10 @@ roff_getnum(const char *v, int *pos, int *res, int flags) scaled = *res * 240 / 2.54; break; case 'v': - /* FALLTROUGH */ case 'P': scaled = *res * 40; break; case 'm': - /* FALLTROUGH */ case 'n': scaled = *res * 24; break; @@ -1696,7 +2054,7 @@ roff_getnum(const char *v, int *pos, int *res, int flags) *res = scaled; *pos = p + 1; - return(1); + return 1; } /* @@ -1739,7 +2097,7 @@ out: else if (*s3 != '\0') s3++; *pos = s3 - v; - return(match); + return match; } /* @@ -1747,8 +2105,10 @@ out: * or string condition. */ static int -roff_evalcond(struct roff *r, int ln, const char *v, int *pos) +roff_evalcond(struct roff *r, int ln, char *v, int *pos) { + char *cp, *name; + size_t sz; int number, savepos, wanttrue; if ('!' == v[*pos]) { @@ -1759,43 +2119,41 @@ roff_evalcond(struct roff *r, int ln, const char *v, int *pos) switch (v[*pos]) { case '\0': - return(0); + return 0; case 'n': - /* FALLTHROUGH */ case 'o': (*pos)++; - return(wanttrue); + return wanttrue; case 'c': - /* FALLTHROUGH */ case 'd': - /* FALLTHROUGH */ case 'e': - /* FALLTHROUGH */ - case 'r': - /* FALLTHROUGH */ case 't': - /* FALLTHROUGH */ case 'v': (*pos)++; - return(!wanttrue); + return !wanttrue; + case 'r': + cp = name = v + ++*pos; + sz = roff_getname(r, &cp, ln, *pos); + *pos = cp - v; + return (sz && roff_hasregn(r, name, sz)) == wanttrue; default: break; } savepos = *pos; if (roff_evalnum(r, ln, v, pos, &number, ROFFNUM_SCALE)) - return((number > 0) == wanttrue); + return (number > 0) == wanttrue; else if (*pos == savepos) - return(roff_evalstrcond(v, pos) == wanttrue); + return roff_evalstrcond(v, pos) == wanttrue; else - return (0); + return 0; } static enum rofferr roff_line_ignore(ROFF_ARGS) { - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -1804,7 +2162,7 @@ roff_insec(ROFF_ARGS) mandoc_msg(MANDOCERR_REQ_INSEC, r->parse, ln, ppos, roffs[tok].name); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -1813,7 +2171,7 @@ roff_unsupp(ROFF_ARGS) mandoc_msg(MANDOCERR_REQ_UNSUPP, r->parse, ln, ppos, roffs[tok].name); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -1872,6 +2230,8 @@ roff_cond(ROFF_ARGS) if (buf->buf[pos] == '\\' && buf->buf[pos + 1] == '{') { r->last->endspan = -1; pos += 2; + while (buf->buf[pos] == ' ') + pos++; goto out; } @@ -1889,7 +2249,7 @@ roff_cond(ROFF_ARGS) out: *offs = pos; - return(ROFF_RERUN); + return ROFF_RERUN; } static enum rofferr @@ -1914,11 +2274,11 @@ roff_ds(ROFF_ARGS) name = string = buf->buf + pos; if (*name == '\0') - return(ROFF_IGN); + return ROFF_IGN; namesz = roff_getname(r, &string, ln, pos); if (name[namesz] == '\\') - return(ROFF_IGN); + return ROFF_IGN; /* Read past the initial double-quote, if any. */ if (*string == '"') @@ -1927,7 +2287,7 @@ roff_ds(ROFF_ARGS) /* The rest is the value. */ roff_setstrn(&r->strtab, name, namesz, string, strlen(string), ROFF_as == tok); - return(ROFF_IGN); + return ROFF_IGN; } /* @@ -1943,17 +2303,11 @@ roff_getop(const char *v, int *pos, char *res) switch (*res) { case '+': - /* FALLTHROUGH */ case '-': - /* FALLTHROUGH */ case '*': - /* FALLTHROUGH */ case '/': - /* FALLTHROUGH */ case '%': - /* FALLTHROUGH */ case '&': - /* FALLTHROUGH */ case ':': break; case '<': @@ -1993,11 +2347,11 @@ roff_getop(const char *v, int *pos, char *res) (*pos)++; break; default: - return(0); + return 0; } (*pos)++; - return(*res); + return *res; } /* @@ -2010,11 +2364,11 @@ roff_evalpar(struct roff *r, int ln, { if ('(' != v[*pos]) - return(roff_getnum(v, pos, res, flags)); + return roff_getnum(v, pos, res, flags); (*pos)++; if ( ! roff_evalnum(r, ln, v, pos, res, flags | ROFFNUM_WHITE)) - return(0); + return 0; /* * Omission of the closing parenthesis @@ -2025,9 +2379,9 @@ roff_evalpar(struct roff *r, int ln, if (')' == v[*pos]) (*pos)++; else if (NULL == res) - return(0); + return 0; - return(1); + return 1; } /* @@ -2051,7 +2405,7 @@ roff_evalnum(struct roff *r, int ln, const char *v, (*pos)++; if ( ! roff_evalpar(r, ln, v, pos, res, flags)) - return(0); + return 0; while (1) { if (flags & ROFFNUM_WHITE) @@ -2066,7 +2420,7 @@ roff_evalnum(struct roff *r, int ln, const char *v, (*pos)++; if ( ! roff_evalpar(r, ln, v, pos, &operand2, flags)) - return(0); + return 0; if (flags & ROFFNUM_WHITE) while (isspace((unsigned char)v[*pos])) @@ -2139,9 +2493,11 @@ roff_evalnum(struct roff *r, int ln, const char *v, abort(); } } - return(1); + return 1; } +/* --- register management ------------------------------------------------ */ + void roff_setreg(struct roff *r, const char *name, int val, char sign) { @@ -2178,24 +2534,26 @@ roff_setreg(struct roff *r, const char *name, int val, char sign) * were to turn up, another special value would have to be chosen. */ static int -roff_getregro(const char *name) +roff_getregro(const struct roff *r, const char *name) { switch (*name) { + case '$': /* Number of arguments of the last macro evaluated. */ + return r->argc; case 'A': /* ASCII approximation mode is always off. */ - return(0); + return 0; case 'g': /* Groff compatibility mode is always on. */ - return(1); + return 1; case 'H': /* Fixed horizontal resolution. */ - return (24); + return 24; case 'j': /* Always adjust left margin only. */ - return(0); + return 0; case 'T': /* Some output device is always defined. */ - return(1); + return 1; case 'V': /* Fixed vertical resolution. */ - return (40); + return 40; default: - return (-1); + return -1; } } @@ -2206,16 +2564,16 @@ roff_getreg(const struct roff *r, const char *name) int val; if ('.' == name[0] && '\0' != name[1] && '\0' == name[2]) { - val = roff_getregro(name + 1); + val = roff_getregro(r, name + 1); if (-1 != val) - return (val); + return val; } for (reg = r->regtab; reg; reg = reg->next) if (0 == strcmp(name, reg->key.p)) - return(reg->val); + return reg->val; - return(0); + return 0; } static int @@ -2225,17 +2583,37 @@ roff_getregn(const struct roff *r, const char *name, size_t len) int val; if ('.' == name[0] && 2 == len) { - val = roff_getregro(name + 1); + val = roff_getregro(r, name + 1); + if (-1 != val) + return val; + } + + for (reg = r->regtab; reg; reg = reg->next) + if (len == reg->key.sz && + 0 == strncmp(name, reg->key.p, len)) + return reg->val; + + return 0; +} + +static int +roff_hasregn(const struct roff *r, const char *name, size_t len) +{ + struct roffreg *reg; + int val; + + if ('.' == name[0] && 2 == len) { + val = roff_getregro(r, name + 1); if (-1 != val) - return (val); + return 1; } for (reg = r->regtab; reg; reg = reg->next) if (len == reg->key.sz && 0 == strncmp(name, reg->key.p, len)) - return(reg->val); + return 1; - return(0); + return 0; } static void @@ -2261,11 +2639,11 @@ roff_nr(ROFF_ARGS) key = val = buf->buf + pos; if (*key == '\0') - return(ROFF_IGN); + return ROFF_IGN; keysz = roff_getname(r, &val, ln, pos); if (key[keysz] == '\\') - return(ROFF_IGN); + return ROFF_IGN; key[keysz] = '\0'; sign = *val; @@ -2275,7 +2653,7 @@ roff_nr(ROFF_ARGS) if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE)) roff_setreg(r, key, iv, sign); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2287,7 +2665,7 @@ roff_rr(ROFF_ARGS) name = cp = buf->buf + pos; if (*name == '\0') - return(ROFF_IGN); + return ROFF_IGN; namesz = roff_getname(r, &cp, ln, pos); name[namesz] = '\0'; @@ -2303,9 +2681,11 @@ roff_rr(ROFF_ARGS) free(reg->key.p); free(reg); } - return(ROFF_IGN); + return ROFF_IGN; } +/* --- handler functions for roff requests -------------------------------- */ + static enum rofferr roff_rm(ROFF_ARGS) { @@ -2321,7 +2701,7 @@ roff_rm(ROFF_ARGS) if (name[namesz] == '\\') break; } - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2334,7 +2714,7 @@ roff_it(ROFF_ARGS) if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) { mandoc_msg(MANDOCERR_IT_NONUM, r->parse, ln, ppos, buf->buf + 1); - return(ROFF_IGN); + return ROFF_IGN; } while (isspace((unsigned char)buf->buf[pos])) @@ -2350,7 +2730,7 @@ roff_it(ROFF_ARGS) roffit_macro = mandoc_strdup(iv != 1 || strcmp(buf->buf + pos, "an-trap") ? buf->buf + pos : "br"); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2365,7 +2745,7 @@ roff_Dd(ROFF_ARGS) if (r->format == 0) r->format = MPARSE_MDOC; - return(ROFF_CONT); + return ROFF_CONT; } static enum rofferr @@ -2380,7 +2760,7 @@ roff_TH(ROFF_ARGS) if (r->format == 0) r->format = MPARSE_MAN; - return(ROFF_CONT); + return ROFF_CONT; } static enum rofferr @@ -2394,9 +2774,9 @@ roff_TE(ROFF_ARGS) free(buf->buf); buf->buf = mandoc_strdup(".sp"); buf->sz = 4; - return(ROFF_REPARSE); + return ROFF_REPARSE; } - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2409,7 +2789,7 @@ roff_T_(ROFF_ARGS) else tbl_restart(ppos, ln, r->tbl); - return(ROFF_IGN); + return ROFF_IGN; } /* @@ -2432,7 +2812,7 @@ roff_eqndelim(struct roff *r, struct buf *buf, int pos) cp2 = strchr(cp1, r->eqn == NULL ? r->last_eqn->odelim : r->last_eqn->cdelim); if (cp2 == NULL) - return(ROFF_CONT); + return ROFF_CONT; *cp2++ = '\0'; bef_pr = bef_nl = aft_nl = aft_pr = ""; @@ -2475,7 +2855,7 @@ roff_eqndelim(struct roff *r, struct buf *buf, int pos) /* Toggle the in-line state of the eqn subsystem. */ r->eqn_inline = r->eqn == NULL; - return(ROFF_REPARSE); + return ROFF_REPARSE; } static enum rofferr @@ -2500,7 +2880,7 @@ roff_EQ(ROFF_ARGS) mandoc_vmsg(MANDOCERR_ARG_SKIP, r->parse, ln, pos, ".EQ %s", buf->buf + pos); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2508,7 +2888,7 @@ roff_EN(ROFF_ARGS) { mandoc_msg(MANDOCERR_BLK_NOTOPEN, r->parse, ln, ppos, "EN"); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2530,7 +2910,7 @@ roff_TS(ROFF_ARGS) r->first_tbl = r->last_tbl = tbl; r->tbl = r->last_tbl = tbl; - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2538,7 +2918,7 @@ roff_brp(ROFF_ARGS) { buf->buf[pos - 1] = '\0'; - return(ROFF_CONT); + return ROFF_CONT; } static enum rofferr @@ -2555,7 +2935,7 @@ roff_cc(ROFF_ARGS) mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse, ln, p - buf->buf, "cc ... %s", p); - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2569,7 +2949,7 @@ roff_tr(ROFF_ARGS) if (*p == '\0') { mandoc_msg(MANDOCERR_REQ_EMPTY, r->parse, ln, ppos, "tr"); - return(ROFF_IGN); + return ROFF_IGN; } while (*p != '\0') { @@ -2581,7 +2961,7 @@ roff_tr(ROFF_ARGS) if (esc == ESCAPE_ERROR) { mandoc_msg(MANDOCERR_ESC_BAD, r->parse, ln, (int)(p - buf->buf), first); - return(ROFF_IGN); + return ROFF_IGN; } fsz = (size_t)(p - first); } @@ -2592,7 +2972,7 @@ roff_tr(ROFF_ARGS) if (esc == ESCAPE_ERROR) { mandoc_msg(MANDOCERR_ESC_BAD, r->parse, ln, (int)(p - buf->buf), second); - return(ROFF_IGN); + return ROFF_IGN; } ssz = (size_t)(p - second); } else if (*second == '\0') { @@ -2617,7 +2997,7 @@ roff_tr(ROFF_ARGS) r->xtab[(int)*first].sz = ssz; } - return(ROFF_IGN); + return ROFF_IGN; } static enum rofferr @@ -2643,19 +3023,21 @@ roff_so(ROFF_ARGS) free(buf->buf); buf->buf = cp; *offs = 0; - return(ROFF_REPARSE); + return ROFF_REPARSE; } *offs = pos; - return(ROFF_SO); + return ROFF_SO; } +/* --- user defined strings and macros ------------------------------------ */ + static enum rofferr roff_userdef(ROFF_ARGS) { const char *arg[9], *ap; char *cp, *n1, *n2; - int i; + int i, ib, ie; size_t asz, rsz; /* @@ -2663,10 +3045,16 @@ roff_userdef(ROFF_ARGS) * and NUL-terminate them. */ + r->argc = 0; cp = buf->buf + pos; - for (i = 0; i < 9; i++) - arg[i] = *cp == '\0' ? "" : - mandoc_getarg(r->parse, &cp, ln, &pos); + for (i = 0; i < 9; i++) { + if (*cp == '\0') + arg[i] = ""; + else { + arg[i] = mandoc_getarg(r->parse, &cp, ln, &pos); + r->argc = i + 1; + } + } /* * Expand macro arguments. @@ -2683,9 +3071,14 @@ roff_userdef(ROFF_ARGS) continue; if (*cp++ != '$') continue; - i = *cp - '1'; - if (0 > i || 8 < i) - continue; + if (*cp == '*') { /* \\$* inserts all arguments */ + ib = 0; + ie = r->argc - 1; + } else { /* \\$1 .. \\$9 insert one argument */ + ib = ie = *cp - '1'; + if (ib < 0 || ib > 8) + continue; + } cp -= 2; /* @@ -2693,11 +3086,13 @@ roff_userdef(ROFF_ARGS) * taking escaping of quotes into account. */ - asz = 0; - for (ap = arg[i]; *ap != '\0'; ap++) { - asz++; - if (*ap == '"') - asz += 3; + asz = ie > ib ? ie - ib : 0; /* for blanks */ + for (i = ib; i <= ie; i++) { + for (ap = arg[i]; *ap != '\0'; ap++) { + asz++; + if (*ap == '"') + asz += 3; + } } if (asz != 3) { @@ -2738,12 +3133,16 @@ roff_userdef(ROFF_ARGS) /* Copy the expanded argument, escaping quotes. */ n2 = cp; - for (ap = arg[i]; *ap != '\0'; ap++) { - if (*ap == '"') { - memcpy(n2, "\\(dq", 4); - n2 += 4; - } else - *n2++ = *ap; + for (i = ib; i <= ie; i++) { + for (ap = arg[i]; *ap != '\0'; ap++) { + if (*ap == '"') { + memcpy(n2, "\\(dq", 4); + n2 += 4; + } else + *n2++ = *ap; + } + if (i < ie) + *n2++ = ' '; } } @@ -2756,8 +3155,8 @@ roff_userdef(ROFF_ARGS) buf->buf = n1; *offs = 0; - return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ? - ROFF_REPARSE : ROFF_APPEND); + return buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ? + ROFF_REPARSE : ROFF_APPEND; } static size_t @@ -2768,7 +3167,7 @@ roff_getname(struct roff *r, char **cpp, int ln, int pos) name = *cpp; if ('\0' == *name) - return(0); + return 0; /* Read until end of name and terminate it with NUL. */ for (cp = name; 1; cp++) { @@ -2795,7 +3194,7 @@ roff_getname(struct roff *r, char **cpp, int ln, int pos) cp++; *cpp = cp; - return(namesz); + return namesz; } /* @@ -2895,14 +3294,14 @@ roff_getstrn(const struct roff *r, const char *name, size_t len) for (n = r->strtab; n; n = n->next) if (0 == strncmp(name, n->key.p, len) && '\0' == n->key.p[(int)len]) - return(n->val.p); + return n->val.p; for (i = 0; i < PREDEFS_MAX; i++) if (0 == strncmp(name, predefs[i].name, len) && '\0' == predefs[i].name[(int)len]) - return(predefs[i].str); + return predefs[i].str; - return(NULL); + return NULL; } static void @@ -2918,18 +3317,20 @@ roff_freestr(struct roffkv *r) } } +/* --- accessors and utility functions ------------------------------------ */ + const struct tbl_span * roff_span(const struct roff *r) { - return(r->tbl ? tbl_span(r->tbl) : NULL); + return r->tbl ? tbl_span(r->tbl) : NULL; } const struct eqn * roff_eqn(const struct roff *r) { - return(r->last_eqn ? &r->last_eqn->eqn : NULL); + return r->last_eqn ? &r->last_eqn->eqn : NULL; } /* @@ -2947,9 +3348,9 @@ roff_strdup(const struct roff *r, const char *p) enum mandoc_esc esc; if (NULL == r->xmbtab && NULL == r->xtab) - return(mandoc_strdup(p)); + return mandoc_strdup(p); else if ('\0' == *p) - return(mandoc_strdup("")); + return mandoc_strdup(""); /* * Step through each character looking for term matches @@ -3021,14 +3422,14 @@ roff_strdup(const struct roff *r, const char *p) } res[(int)ssz] = '\0'; - return(res); + return res; } int roff_getformat(const struct roff *r) { - return(r->format); + return r->format; } /* @@ -3051,17 +3452,17 @@ roff_getcontrol(const struct roff *r, const char *cp, int *ppos) if (0 != r->control && cp[pos] == r->control) pos++; else if (0 != r->control) - return(0); + return 0; else if ('\\' == cp[pos] && '.' == cp[pos + 1]) pos += 2; else if ('.' == cp[pos] || '\'' == cp[pos]) pos++; else - return(0); + return 0; while (' ' == cp[pos] || '\t' == cp[pos]) pos++; *ppos = pos; - return(1); + return 1; } diff --git a/contrib/mdocml/roff.h b/contrib/mdocml/roff.h new file mode 100644 index 0000000..19ec50f --- /dev/null +++ b/contrib/mdocml/roff.h @@ -0,0 +1,164 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct mdoc_arg; +union mdoc_data; + +enum roff_macroset { + MACROSET_NONE = 0, + MACROSET_MDOC, + MACROSET_MAN +}; + +enum roff_sec { + SEC_NONE = 0, + SEC_NAME, + SEC_LIBRARY, + SEC_SYNOPSIS, + SEC_DESCRIPTION, + SEC_CONTEXT, + SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */ + SEC_RETURN_VALUES, + SEC_ENVIRONMENT, + SEC_FILES, + SEC_EXIT_STATUS, + SEC_EXAMPLES, + SEC_DIAGNOSTICS, + SEC_COMPATIBILITY, + SEC_ERRORS, + SEC_SEE_ALSO, + SEC_STANDARDS, + SEC_HISTORY, + SEC_AUTHORS, + SEC_CAVEATS, + SEC_BUGS, + SEC_SECURITY, + SEC_CUSTOM, + SEC__MAX +}; + +enum roff_type { + ROFFT_ROOT, + ROFFT_BLOCK, + ROFFT_HEAD, + ROFFT_BODY, + ROFFT_TAIL, + ROFFT_ELEM, + ROFFT_TEXT, + ROFFT_TBL, + ROFFT_EQN +}; + +enum roff_next { + ROFF_NEXT_SIBLING = 0, + ROFF_NEXT_CHILD +}; + +/* + * Indicates that a BODY's formatting has ended, but + * the scope is still open. Used for badly nested blocks. + */ +enum mdoc_endbody { + ENDBODY_NOT = 0, + ENDBODY_SPACE, /* Is broken: append a space. */ + ENDBODY_NOSPACE /* Is broken: don't append a space. */ +}; + +struct roff_node { + struct roff_node *parent; /* Parent AST node. */ + struct roff_node *child; /* First child AST node. */ + struct roff_node *last; /* Last child AST node. */ + struct roff_node *next; /* Sibling AST node. */ + struct roff_node *prev; /* Prior sibling AST node. */ + struct roff_node *head; /* BLOCK */ + struct roff_node *body; /* BLOCK/ENDBODY */ + struct roff_node *tail; /* BLOCK */ + struct mdoc_arg *args; /* BLOCK/ELEM */ + union mdoc_data *norm; /* Normalized arguments. */ + char *string; /* TEXT */ + const struct tbl_span *span; /* TBL */ + const struct eqn *eqn; /* EQN */ + int line; /* Input file line number. */ + int pos; /* Input file column number. */ + int tok; /* Request or macro ID. */ +#define TOKEN_NONE (-1) /* No request or macro. */ + int flags; +#define MDOC_VALID (1 << 0) /* Has been validated. */ +#define MDOC_ENDED (1 << 1) /* Gone past body end mark. */ +#define MDOC_EOS (1 << 2) /* At sentence boundary. */ +#define MDOC_LINE (1 << 3) /* First macro/text on line. */ +#define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting. */ +#define MDOC_BROKEN (1 << 5) /* Must validate parent when ending. */ +#define MDOC_DELIMO (1 << 6) +#define MDOC_DELIMC (1 << 7) +#define MAN_VALID MDOC_VALID +#define MAN_EOS MDOC_EOS +#define MAN_LINE MDOC_LINE + int prev_font; /* Before entering this node. */ + int aux; /* Decoded node data, type-dependent. */ + enum roff_type type; /* AST node type. */ + enum roff_sec sec; /* Current named section. */ + enum mdoc_endbody end; /* BODY */ +}; + +struct roff_meta { + char *msec; /* Manual section, usually a digit. */ + char *vol; /* Manual volume title. */ + char *os; /* Operating system. */ + char *arch; /* Machine architecture. */ + char *title; /* Manual title, usually CAPS. */ + char *name; /* Leading manual name. */ + char *date; /* Normalized date. */ + int hasbody; /* Document is not empty. */ +}; + +struct roff_man { + struct roff_meta meta; /* Document meta-data. */ + struct mparse *parse; /* Parse pointer. */ + struct roff *roff; /* Roff parser state data. */ + const char *defos; /* Default operating system. */ + struct roff_node *first; /* The first node parsed. */ + struct roff_node *last; /* The last node parsed. */ + struct roff_node *last_es; /* The most recent Es node. */ + int quick; /* Abort parse early. */ + int flags; /* Parse flags. */ +#define MDOC_LITERAL (1 << 1) /* In a literal scope. */ +#define MDOC_PBODY (1 << 2) /* In the document body. */ +#define MDOC_NEWLINE (1 << 3) /* First macro/text in a line. */ +#define MDOC_PHRASE (1 << 4) /* In a Bl -column phrase. */ +#define MDOC_PHRASELIT (1 << 5) /* Literal within a phrase. */ +#define MDOC_FREECOL (1 << 6) /* `It' invocation should close. */ +#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting. */ +#define MDOC_KEEP (1 << 8) /* In a word keep. */ +#define MDOC_SMOFF (1 << 9) /* Spacing is off. */ +#define MDOC_NODELIMC (1 << 10) /* Disable closing delimiter handling. */ +#define MAN_ELINE (1 << 11) /* Next-line element scope. */ +#define MAN_BLINE (1 << 12) /* Next-line block scope. */ +#define MDOC_PHRASEQF (1 << 13) /* Quote first word encountered. */ +#define MDOC_PHRASEQL (1 << 14) /* Quote last word of this phrase. */ +#define MDOC_PHRASEQN (1 << 15) /* Quote first word of the next phrase. */ +#define MAN_LITERAL MDOC_LITERAL +#define MAN_NEWLINE MDOC_NEWLINE + enum roff_macroset macroset; /* Kind of high-level macros used. */ + enum roff_sec lastsec; /* Last section seen. */ + enum roff_sec lastnamed; /* Last standard section seen. */ + enum roff_next next; /* Where to put the next node. */ +}; + + +void deroff(char **, const struct roff_node *); diff --git a/contrib/mdocml/roff_int.h b/contrib/mdocml/roff_int.h new file mode 100644 index 0000000..5567b75 --- /dev/null +++ b/contrib/mdocml/roff_int.h @@ -0,0 +1,41 @@ +/* $Id: roff_int.h,v 1.7 2015/11/07 14:01:16 schwarze Exp $ */ +/* + * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct roff_node *roff_node_alloc(struct roff_man *, int, int, + enum roff_type, int); +void roff_node_append(struct roff_man *, struct roff_node *); +void roff_word_alloc(struct roff_man *, int, int, const char *); +void roff_word_append(struct roff_man *, const char *); +void roff_elem_alloc(struct roff_man *, int, int, int); +struct roff_node *roff_block_alloc(struct roff_man *, int, int, int); +struct roff_node *roff_head_alloc(struct roff_man *, int, int, int); +struct roff_node *roff_body_alloc(struct roff_man *, int, int, int); +void roff_addeqn(struct roff_man *, const struct eqn *); +void roff_addtbl(struct roff_man *, const struct tbl_span *); +void roff_node_unlink(struct roff_man *, struct roff_node *); +void roff_node_free(struct roff_node *); +void roff_node_delete(struct roff_man *, struct roff_node *); + +/* + * Functions called from roff.c need to be declared here, + * not in libmdoc.h or libman.h, even if they are specific + * to either the mdoc(7) or the man(7) parser. + */ + +void man_breakscope(struct roff_man *, int); +void mdoc_argv_free(struct mdoc_arg *); diff --git a/contrib/mdocml/soelim.1 b/contrib/mdocml/soelim.1 new file mode 100644 index 0000000..20f15ec --- /dev/null +++ b/contrib/mdocml/soelim.1 @@ -0,0 +1,86 @@ +.\" $Id: soelim.1,v 1.3 2015/05/20 22:59:12 schwarze Exp $ +.\" +.\" Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd $Mdocdate: May 20 2015 $ +.Dt SOELIM 1 +.Os +.Sh NAME +.Nm soelim +.Nd interpret .so requests in manpages +.Sh SYNOPSIS +.Nm +.Op Fl Crtv +.Op Fl I Ar dir +.Op Ar files ... +.Sh DESCRIPTION +.Nm +reads +.Ar files +lines by lines. +.Pp +If a line starts by: +.Dq .so anotherfile +it replace the line by processing +.Dq anotherfile . +Otherwise the line is printed to stdout. +.Bl -tag -width "-I dir" +.It Fl C +Recognise +.Em .so +when not followed by a space character. +.It Fl r +Compatibility with GNU groff's +.Xr soelim 1 +(does nothing). +.It Fl t +Compatibility with GNU groff's +.Xr soelim 1 +(does nothing). +.It Fl v +Compatibility with GNU groff's +.Xr soelim 1 +(does nothing). +.It Fl I Ar dir +This option specify directories where +.Nm +searches for files (both those on the command line and those named in +.Dq .so +directive.) +This options may be specified multiple times. The directories will be searched +in the order specified. +.El +.Pp +The files are always searched first in the current directory. +.Pp +A file specified with an absolute path will be opened directly without +performing a search. +.Sh SEE ALSO +.Xr mandoc 1 +.Sh AUTHORS +This version of the +.Nm +utility was written by +.An Baptiste Daroussin Aq Mt bapt@freebsd.org . diff --git a/contrib/mdocml/soelim.c b/contrib/mdocml/soelim.c new file mode 100644 index 0000000..3ef3082 --- /dev/null +++ b/contrib/mdocml/soelim.c @@ -0,0 +1,182 @@ +/* $Id: soelim.c,v 1.5 2015/11/07 14:22:29 schwarze Exp $ */ +/* + * Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" + +#include <sys/types.h> + +#include <ctype.h> +#if HAVE_ERR +#include <err.h> +#endif +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if HAVE_STRINGLIST +#include <stringlist.h> +#else +#include "compat_stringlist.h" +#endif +#include <unistd.h> + +#define C_OPTION 0x1 + +static StringList *includes; + +static void +usage(void) +{ + + fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n"); + + exit(EXIT_FAILURE); +} + +static FILE * +soelim_fopen(const char *name) +{ + FILE *f; + char path[PATH_MAX]; + size_t i; + + if (strcmp(name, "-") == 0) + return (stdin); + + if ((f = fopen(name, "r")) != NULL) + return (f); + + if (*name == '/') { + warn("can't open '%s'", name); + return (NULL); + } + + for (i = 0; i < includes->sl_cur; i++) { + snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i], + name); + if ((f = fopen(path, "r")) != NULL) + return (f); + } + + warn("can't open '%s'", name); + + return (f); +} + +static int +soelim_file(FILE *f, int flag) +{ + char *line = NULL; + char *walk, *cp; + size_t linecap = 0; + ssize_t linelen; + + if (f == NULL) + return (1); + + while ((linelen = getline(&line, &linecap, f)) > 0) { + if (strncmp(line, ".so", 3) != 0) { + printf("%s", line); + continue; + } + + walk = line + 3; + if (!isspace(*walk) && ((flag & C_OPTION) == 0)) { + printf("%s", line); + continue; + } + + while (isspace(*walk)) + walk++; + + cp = walk; + while (*cp != '\0' && !isspace(*cp)) + cp++; + *cp = 0; + if (cp < line + linelen) + cp++; + + if (*walk == '\0') { + printf("%s", line); + continue; + } + if (soelim_file(soelim_fopen(walk), flag) == 1) { + free(line); + return (1); + } + if (*cp != '\0') + printf("%s", cp); + } + + free(line); + fclose(f); + + return (0); +} + +int +main(int argc, char **argv) +{ + int ch, i; + int ret = 0; + int flags = 0; + + includes = sl_init(); + if (includes == NULL) + err(EXIT_FAILURE, "sl_init()"); + + while ((ch = getopt(argc, argv, "CrtvI:")) != -1) { + switch (ch) { + case 'C': + flags |= C_OPTION; + break; + case 'r': + case 'v': + case 't': + /* stub compatibility with groff's soelim */ + break; + case 'I': + sl_add(includes, optarg); + break; + default: + sl_free(includes, 0); + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) + ret = soelim_file(stdin, flags); + + for (i = 0; i < argc; i++) + ret = soelim_file(soelim_fopen(argv[i]), flags); + + sl_free(includes, 0); + + return (ret); +} diff --git a/contrib/mdocml/st.c b/contrib/mdocml/st.c index 172403a..02868f0 100644 --- a/contrib/mdocml/st.c +++ b/contrib/mdocml/st.c @@ -1,4 +1,4 @@ -/* $Id: st.c,v 1.11 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: st.c,v 1.13 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -20,6 +20,7 @@ #include <string.h> +#include "roff.h" #include "mdoc.h" #include "libmdoc.h" @@ -32,5 +33,5 @@ mdoc_a2st(const char *p) #include "st.in" - return(NULL); + return NULL; } diff --git a/contrib/mdocml/tag.c b/contrib/mdocml/tag.c new file mode 100644 index 0000000..57925ce --- /dev/null +++ b/contrib/mdocml/tag.c @@ -0,0 +1,192 @@ +/* $Id: tag.c,v 1.11 2015/11/20 21:59:54 schwarze Exp $ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "config.h" + +#include <sys/types.h> + +#include <signal.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "mandoc_aux.h" +#include "mandoc_ohash.h" +#include "tag.h" + +struct tag_entry { + size_t line; + int prio; + char s[]; +}; + +static void tag_signal(int); + +static struct ohash tag_data; +static struct tag_files tag_files; + + +/* + * Prepare for using a pager. + * Not all pagers are capable of using a tag file, + * but for simplicity, create it anyway. + */ +struct tag_files * +tag_init(void) +{ + struct sigaction sa; + int ofd; + + ofd = -1; + tag_files.tfd = -1; + tag_files.tcpgid = -1; + + /* Save the original standard output for use by the pager. */ + + if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) + goto fail; + + /* Create both temporary output files. */ + + (void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX", + sizeof(tag_files.ofn)); + (void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX", + sizeof(tag_files.tfn)); + memset(&sa, 0, sizeof(sa)); + sigfillset(&sa.sa_mask); + sa.sa_handler = tag_signal; + sigaction(SIGHUP, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + if ((ofd = mkstemp(tag_files.ofn)) == -1) + goto fail; + if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1) + goto fail; + if (dup2(ofd, STDOUT_FILENO) == -1) + goto fail; + close(ofd); + + /* + * Set up the ohash table to collect output line numbers + * where various marked-up terms are documented. + */ + + mandoc_ohash_init(&tag_data, 4, offsetof(struct tag_entry, s)); + return &tag_files; + +fail: + tag_unlink(); + if (ofd != -1) + close(ofd); + if (tag_files.ofd != -1) + close(tag_files.ofd); + if (tag_files.tfd != -1) + close(tag_files.tfd); + *tag_files.ofn = '\0'; + *tag_files.tfn = '\0'; + tag_files.ofd = -1; + tag_files.tfd = -1; + return NULL; +} + +/* + * Set the line number where a term is defined, + * unless it is already defined at a higher priority. + */ +void +tag_put(const char *s, int prio, size_t line) +{ + struct tag_entry *entry; + size_t len; + unsigned int slot; + + if (tag_files.tfd <= 0 || strchr(s, ' ') != NULL) + return; + slot = ohash_qlookup(&tag_data, s); + entry = ohash_find(&tag_data, slot); + if (entry == NULL) { + len = strlen(s) + 1; + entry = mandoc_malloc(sizeof(*entry) + len); + memcpy(entry->s, s, len); + ohash_insert(&tag_data, slot, entry); + } else if (entry->prio <= prio) + return; + entry->line = line; + entry->prio = prio; +} + +/* + * Write out the tags file using the previously collected + * information and clear the ohash table while going along. + */ +void +tag_write(void) +{ + FILE *stream; + struct tag_entry *entry; + unsigned int slot; + + if (tag_files.tfd <= 0) + return; + stream = fdopen(tag_files.tfd, "w"); + entry = ohash_first(&tag_data, &slot); + while (entry != NULL) { + if (stream != NULL) + fprintf(stream, "%s %s %zu\n", + entry->s, tag_files.ofn, entry->line); + free(entry); + entry = ohash_next(&tag_data, &slot); + } + ohash_delete(&tag_data); + if (stream != NULL) + fclose(stream); +} + +void +tag_unlink(void) +{ + pid_t tc_pgid; + + if (tag_files.tcpgid != -1) { + tc_pgid = tcgetpgrp(STDIN_FILENO); + if (tc_pgid == tag_files.pager_pid || + tc_pgid == getpgid(0) || + getpgid(tc_pgid) == -1) + (void)tcsetpgrp(STDIN_FILENO, tag_files.tcpgid); + } + if (*tag_files.ofn != '\0') + unlink(tag_files.ofn); + if (*tag_files.tfn != '\0') + unlink(tag_files.tfn); +} + +static void +tag_signal(int signum) +{ + struct sigaction sa; + + tag_unlink(); + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + sigaction(signum, &sa, NULL); + kill(getpid(), signum); + /* NOTREACHED */ + _exit(1); +} diff --git a/contrib/mdocml/tag.h b/contrib/mdocml/tag.h new file mode 100644 index 0000000..ab1388d --- /dev/null +++ b/contrib/mdocml/tag.h @@ -0,0 +1,31 @@ +/* $Id: tag.h,v 1.7 2015/11/20 21:59:54 schwarze Exp $ */ +/* + * Copyright (c) 2015 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. + */ + +struct tag_files { + char ofn[20]; + char tfn[20]; + int ofd; + int tfd; + pid_t tcpgid; + pid_t pager_pid; +}; + + +struct tag_files *tag_init(void); +void tag_put(const char *, int, size_t); +void tag_write(void); +void tag_unlink(void); diff --git a/contrib/mdocml/tbl.c b/contrib/mdocml/tbl.c index 00ee466..ed6fbd8 100644 --- a/contrib/mdocml/tbl.c +++ b/contrib/mdocml/tbl.c @@ -1,4 +1,4 @@ -/* $Id: tbl.c,v 1.39 2015/01/30 17:32:16 schwarze Exp $ */ +/* $Id: tbl.c,v 1.40 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -66,7 +66,7 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos) if (*cp == ';') { tbl_option(tbl, ln, p, &pos); if (p[pos] == '\0') - return(ROFF_IGN); + return ROFF_IGN; } } @@ -75,15 +75,15 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos) switch (tbl->part) { case TBL_PART_LAYOUT: tbl_layout(tbl, ln, p, pos); - return(ROFF_IGN); + return ROFF_IGN; case TBL_PART_CDATA: - return(tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN); + return tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN; default: break; } tbl_data(tbl, ln, p, pos); - return(ROFF_TBL); + return ROFF_TBL; } struct tbl_node * @@ -98,7 +98,7 @@ tbl_alloc(int pos, int line, struct mparse *parse) tbl->part = TBL_PART_OPTS; tbl->opts.tab = '\t'; tbl->opts.decimal = '.'; - return(tbl); + return tbl; } void @@ -155,7 +155,7 @@ tbl_span(struct tbl_node *tbl) : tbl->first_span; if (span) tbl->current_span = span; - return(span); + return span; } int @@ -177,7 +177,7 @@ tbl_end(struct tbl_node **tblp) if (sp == NULL) { mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->parse, tbl->line, tbl->pos, NULL); - return(0); + return 0; } - return(1); + return 1; } diff --git a/contrib/mdocml/tbl_data.c b/contrib/mdocml/tbl_data.c index e2be64e..40b756a0 100644 --- a/contrib/mdocml/tbl_data.c +++ b/contrib/mdocml/tbl_data.c @@ -1,4 +1,4 @@ -/* $Id: tbl_data.c,v 1.39 2015/01/30 17:32:16 schwarze Exp $ */ +/* $Id: tbl_data.c,v 1.41 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -132,11 +132,12 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos) if (p[pos] == tbl->opts.tab) { tbl->part = TBL_PART_DATA; pos++; - getdata(tbl, tbl->last_span, ln, p, &pos); - return(1); + while (p[pos] != '\0') + getdata(tbl, tbl->last_span, ln, p, &pos); + return 1; } else if (p[pos] == '\0') { tbl->part = TBL_PART_DATA; - return(1); + return 1; } /* Fallthrough: T} is part of a word. */ @@ -156,7 +157,7 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos) mandoc_msg(MANDOCERR_TBLDATA_SPAN, tbl->parse, ln, pos, dat->string); - return(0); + return 0; } static struct tbl_span * @@ -177,7 +178,7 @@ newspan(struct tbl_node *tbl, int line, struct tbl_row *rp) dp->prev->next = dp; tbl->last_span = dp; - return(dp); + return dp; } void diff --git a/contrib/mdocml/tbl_html.c b/contrib/mdocml/tbl_html.c index e794038..51c4328 100644 --- a/contrib/mdocml/tbl_html.c +++ b/contrib/mdocml/tbl_html.c @@ -1,6 +1,7 @@ -/* $Id: tbl_html.c,v 1.16 2015/01/30 17:32:16 schwarze Exp $ */ +/* $Id: tbl_html.c,v 1.18 2015/10/12 00:08:16 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> + * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -36,14 +37,14 @@ static size_t html_tbl_len(size_t sz, void *arg) { - return(sz); + return sz; } static size_t html_tbl_strlen(const char *p, void *arg) { - return(strlen(p)); + return strlen(p); } static void @@ -107,7 +108,6 @@ print_tbl(struct html *h, const struct tbl_span *sp) switch (sp->pos) { case TBL_SPAN_HORIZ: - /* FALLTHROUGH */ case TBL_SPAN_DHORIZ: PAIR_INIT(&tag, ATTR_COLSPAN, "0"); print_otag(h, TAG_TD, 1, &tag); diff --git a/contrib/mdocml/tbl_layout.c b/contrib/mdocml/tbl_layout.c index ed9acc9..c0eafbd 100644 --- a/contrib/mdocml/tbl_layout.c +++ b/contrib/mdocml/tbl_layout.c @@ -1,4 +1,4 @@ -/* $Id: tbl_layout.c,v 1.38 2015/02/10 11:03:13 schwarze Exp $ */ +/* $Id: tbl_layout.c,v 1.41 2015/10/12 00:08:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -115,7 +115,6 @@ mod: ln, *pos, "m"); goto mod; case 'p': - /* FALLTHROUGH */ case 'v': if (p[*pos] == '-' || p[*pos] == '+') (*pos)++; @@ -168,17 +167,14 @@ mod: switch (p[(*pos)++]) { case '3': - /* FALLTHROUGH */ case 'B': cp->flags |= TBL_CELL_BOLD; goto mod; case '2': - /* FALLTHROUGH */ case 'I': cp->flags |= TBL_CELL_ITALIC; goto mod; case '1': - /* FALLTHROUGH */ case 'R': goto mod; default: @@ -308,6 +304,7 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos) rp->next->first == NULL) { free(rp->next); rp->next = NULL; + tbl->last_row = rp; } } return; @@ -354,5 +351,5 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos) if (tbl->opts.cols <= p->col) tbl->opts.cols = p->col + 1; - return(p); + return p; } diff --git a/contrib/mdocml/tbl_opts.c b/contrib/mdocml/tbl_opts.c index c012a3c..f2f5942 100644 --- a/contrib/mdocml/tbl_opts.c +++ b/contrib/mdocml/tbl_opts.c @@ -1,4 +1,4 @@ -/* $Id: tbl_opts.c,v 1.20 2015/01/28 17:32:07 schwarze Exp $ */ +/* $Id: tbl_opts.c,v 1.21 2015/09/26 00:54:04 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -99,7 +99,6 @@ arg(struct tbl_node *tbl, int ln, const char *p, int *pos, int key) break; default: abort(); - /* NOTREACHED */ } if (len == 0) diff --git a/contrib/mdocml/tbl_term.c b/contrib/mdocml/tbl_term.c index 1276776..eceaa4b 100644 --- a/contrib/mdocml/tbl_term.c +++ b/contrib/mdocml/tbl_term.c @@ -1,4 +1,4 @@ -/* $Id: tbl_term.c,v 1.40 2015/03/06 15:48:53 schwarze Exp $ */ +/* $Id: tbl_term.c,v 1.43 2015/10/12 00:08:16 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011, 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -47,14 +47,14 @@ static size_t term_tbl_strlen(const char *p, void *arg) { - return(term_strlen((const struct termp *)arg, p)); + return term_strlen((const struct termp *)arg, p); } static size_t term_tbl_len(size_t sz, void *arg) { - return(term_len((const struct termp *)arg, sz)); + return term_len((const struct termp *)arg, sz); } void @@ -266,12 +266,10 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts, tbl_char(tp, ASCII_NBRSP, col->width); return; case TBL_DATA_HORIZ: - /* FALLTHROUGH */ case TBL_DATA_NHORIZ: tbl_char(tp, '-', col->width); return; case TBL_DATA_NDHORIZ: - /* FALLTHROUGH */ case TBL_DATA_DHORIZ: tbl_char(tp, '=', col->width); return; @@ -287,11 +285,8 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts, tbl_char(tp, '=', col->width); break; case TBL_CELL_LONG: - /* FALLTHROUGH */ case TBL_CELL_CENTRE: - /* FALLTHROUGH */ case TBL_CELL_LEFT: - /* FALLTHROUGH */ case TBL_CELL_RIGHT: tbl_literal(tp, dp, col); break; @@ -303,7 +298,6 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts, break; default: abort(); - /* NOTREACHED */ } } diff --git a/contrib/mdocml/term.c b/contrib/mdocml/term.c index ee2af9e..e917101 100644 --- a/contrib/mdocml/term.c +++ b/contrib/mdocml/term.c @@ -1,4 +1,4 @@ -/* $Id: term.c,v 1.245 2015/03/06 13:02:43 schwarze Exp $ */ +/* $Id: term.c,v 1.256 2016/01/07 21:03:54 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -49,7 +49,7 @@ term_free(struct termp *p) void term_begin(struct termp *p, term_margin head, - term_margin foot, const void *arg) + term_margin foot, const struct roff_meta *arg) { p->headf = head; @@ -78,6 +78,8 @@ term_end(struct termp *p) * the next column. However, if less than p->trailspace blanks, * which can be 0, 1, or 2, remain to the right margin, the line * will be broken. + * - TERMP_BRTRSP: Consider trailing whitespace significant + * when deciding whether the chunk fits or not. * - TERMP_BRIND: If the chunk does not fit and the output line has * to be broken, start the next line at the right margin instead * of at the offset. Used together with TERMP_NOBREAK for the tags @@ -265,6 +267,7 @@ term_flushln(struct termp *p) p->col = 0; p->overstep = 0; + p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE); if ( ! (TERMP_NOBREAK & p->flags)) { p->viscol = 0; @@ -290,6 +293,10 @@ term_flushln(struct termp *p) } else if (TERMP_DANGLE & p->flags) return; + /* Trailing whitespace is significant in some columns. */ + if (vis && vbl && (TERMP_BRTRSP & p->flags)) + vis += vbl; + /* If the column was overrun, break the line. */ if (maxvis < vis + p->trailspace * (*p->width)(p, ' ')) { (*p->endline)(p); @@ -358,7 +365,7 @@ term_fontpush(struct termp *p, enum termfont f) if (++p->fonti == p->fontsz) { p->fontsz += 8; p->fontq = mandoc_reallocarray(p->fontq, - p->fontsz, sizeof(enum termfont *)); + p->fontsz, sizeof(*p->fontq)); } p->fontq[p->fonti] = f; } @@ -417,11 +424,6 @@ term_word(struct termp *p, const char *word) while ('\0' != *word) { if ('\\' != *word) { - if (TERMP_SKIPCHAR & p->flags) { - p->flags &= ~TERMP_SKIPCHAR; - word++; - continue; - } if (TERMP_NBRWORD & p->flags) { if (' ' == *word) { encode(p, nbrsp, 1); @@ -452,12 +454,11 @@ term_word(struct termp *p, const char *word) break; case ESCAPE_SPECIAL: if (p->enc == TERMENC_ASCII) { - cp = mchars_spec2str(p->symtab, - seq, sz, &ssz); + cp = mchars_spec2str(seq, sz, &ssz); if (cp != NULL) encode(p, cp, ssz); } else { - uc = mchars_spec2cp(p->symtab, seq, sz); + uc = mchars_spec2cp(seq, sz); if (uc > 0) encode1(p, uc); } @@ -472,7 +473,6 @@ term_word(struct termp *p, const char *word) term_fontrepl(p, TERMFONT_BI); continue; case ESCAPE_FONT: - /* FALLTHROUGH */ case ESCAPE_FONTROMAN: term_fontrepl(p, TERMFONT_NONE); continue; @@ -480,13 +480,13 @@ term_word(struct termp *p, const char *word) term_fontlast(p); continue; case ESCAPE_NOSPACE: - if (TERMP_SKIPCHAR & p->flags) - p->flags &= ~TERMP_SKIPCHAR; - else if ('\0' == *word) + if (p->flags & TERMP_BACKAFTER) + p->flags &= ~TERMP_BACKAFTER; + else if (*word == '\0') p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE); continue; case ESCAPE_SKIPCHAR: - p->flags |= TERMP_SKIPCHAR; + p->flags |= TERMP_BACKAFTER; continue; case ESCAPE_OVERSTRIKE: cp = seq + sz; @@ -496,9 +496,17 @@ term_word(struct termp *p, const char *word) continue; } encode1(p, *seq++); - if (seq < cp) - encode(p, "\b", 1); + if (seq < cp) { + if (p->flags & TERMP_BACKBEFORE) + p->flags |= TERMP_BACKAFTER; + else + p->flags |= TERMP_BACKBEFORE; + } } + /* Trim trailing backspace/blank pair. */ + if (p->col > 2 && p->buf[p->col - 1] == ' ') + p->col -= 2; + continue; default: continue; } @@ -553,16 +561,19 @@ encode1(struct termp *p, int c) { enum termfont f; - if (TERMP_SKIPCHAR & p->flags) { - p->flags &= ~TERMP_SKIPCHAR; - return; - } - - if (p->col + 6 >= p->maxcols) - adjbuf(p, p->col + 6); + if (p->col + 7 >= p->maxcols) + adjbuf(p, p->col + 7); - f = p->fontq[p->fonti]; + f = (c == ASCII_HYPH || c > 127 || isgraph(c)) ? + p->fontq[p->fonti] : TERMFONT_NONE; + if (p->flags & TERMP_BACKBEFORE) { + if (p->buf[p->col - 1] == ' ') + p->col--; + else + p->buf[p->col++] = 8; + p->flags &= ~TERMP_BACKBEFORE; + } if (TERMFONT_UNDER == f || TERMFONT_BI == f) { p->buf[p->col++] = '_'; p->buf[p->col++] = 8; @@ -575,6 +586,10 @@ encode1(struct termp *p, int c) p->buf[p->col++] = 8; } p->buf[p->col++] = c; + if (p->flags & TERMP_BACKAFTER) { + p->flags |= TERMP_BACKBEFORE; + p->flags &= ~TERMP_BACKAFTER; + } } static void @@ -582,29 +597,8 @@ encode(struct termp *p, const char *word, size_t sz) { size_t i; - if (TERMP_SKIPCHAR & p->flags) { - p->flags &= ~TERMP_SKIPCHAR; - return; - } - - /* - * Encode and buffer a string of characters. If the current - * font mode is unset, buffer directly, else encode then buffer - * character by character. - */ - - if (p->fontq[p->fonti] == TERMFONT_NONE) { - if (p->col + sz >= p->maxcols) - adjbuf(p, p->col + sz); - for (i = 0; i < sz; i++) - p->buf[p->col++] = word[i]; - return; - } - - /* Pre-buffer, assuming worst-case. */ - - if (p->col + 1 + (sz * 5) >= p->maxcols) - adjbuf(p, p->col + 1 + (sz * 5)); + if (p->col + 2 + (sz * 5) >= p->maxcols) + adjbuf(p, p->col + 2 + (sz * 5)); for (i = 0; i < sz; i++) { if (ASCII_HYPH == word[i] || @@ -619,8 +613,7 @@ void term_setwidth(struct termp *p, const char *wstr) { struct roffsu su; - size_t width; - int iop; + int iop, width; iop = 0; width = 0; @@ -649,7 +642,7 @@ size_t term_len(const struct termp *p, size_t sz) { - return((*p->width)(p, ' ') * sz); + return (*p->width)(p, ' ') * sz; } static size_t @@ -658,9 +651,9 @@ cond_width(const struct termp *p, int c, int *skip) if (*skip) { (*skip) = 0; - return(0); + return 0; } else - return((*p->width)(p, c)); + return (*p->width)(p, c); } size_t @@ -706,13 +699,11 @@ term_strlen(const struct termp *p, const char *cp) break; case ESCAPE_SPECIAL: if (p->enc == TERMENC_ASCII) { - rhs = mchars_spec2str(p->symtab, - seq, ssz, &rsz); + rhs = mchars_spec2str(seq, ssz, &rsz); if (rhs != NULL) break; } else { - uc = mchars_spec2cp(p->symtab, - seq, ssz); + uc = mchars_spec2cp(seq, ssz); if (uc > 0) sz += cond_width(p, uc, &skip); } @@ -776,15 +767,13 @@ term_strlen(const struct termp *p, const char *cp) case ASCII_HYPH: sz += cond_width(p, '-', &skip); cp++; - /* FALLTHROUGH */ - case ASCII_BREAK: break; default: break; } } - return(sz); + return sz; } int @@ -816,7 +805,6 @@ term_vspan(const struct termp *p, const struct roffsu *su) r = su->scale / 12.0; break; case SCALE_EN: - /* FALLTHROUGH */ case SCALE_EM: r = su->scale * 0.6; break; @@ -825,17 +813,17 @@ term_vspan(const struct termp *p, const struct roffsu *su) break; default: abort(); - /* NOTREACHED */ } ri = r > 0.0 ? r + 0.4995 : r - 0.4995; - return(ri < 66 ? ri : 1); + return ri < 66 ? ri : 1; } +/* + * Convert a scaling width to basic units, rounding down. + */ int term_hspan(const struct termp *p, const struct roffsu *su) { - double v; - v = (*p->hspan)(p, su); - return(v > 0.0 ? v + 0.0005 : v - 0.0005); + return (*p->hspan)(p, su); } diff --git a/contrib/mdocml/term.h b/contrib/mdocml/term.h index b65524b..fabc117 100644 --- a/contrib/mdocml/term.h +++ b/contrib/mdocml/term.h @@ -1,15 +1,15 @@ -/* $Id: term.h,v 1.111 2015/01/31 00:12:41 schwarze Exp $ */ +/* $Id: term.h,v 1.118 2015/11/07 14:01:16 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -38,9 +38,10 @@ enum termfont { #define TERM_MAXMARGIN 100000 /* FIXME */ +struct roff_meta; struct termp; -typedef void (*term_margin)(struct termp *, const void *); +typedef void (*term_margin)(struct termp *, const struct roff_meta *); struct termp_tbl { int width; /* width in fixed chars */ @@ -52,6 +53,7 @@ struct termp { struct rofftbl tbl; /* table configuration */ int synopsisonly; /* print the synopsis only */ int mdocstyle; /* imitate mdoc(7) output */ + size_t line; /* Current output line number. */ size_t defindent; /* Default indent for text. */ size_t defrmargin; /* Right margin of the device. */ size_t lastrmargin; /* Right margin before the last ll. */ @@ -66,23 +68,24 @@ struct termp { int overstep; /* See termp_flushln(). */ int skipvsp; /* Vertical space to skip. */ int flags; -#define TERMP_SENTENCE (1 << 1) /* Space before a sentence. */ -#define TERMP_NOSPACE (1 << 2) /* No space before words. */ -#define TERMP_NONOSPACE (1 << 3) /* No space (no autounset). */ -#define TERMP_NBRWORD (1 << 4) /* Make next word nonbreaking. */ -#define TERMP_KEEP (1 << 5) /* Keep words together. */ -#define TERMP_PREKEEP (1 << 6) /* ...starting with the next one. */ -#define TERMP_SKIPCHAR (1 << 7) /* Skip the next character. */ +#define TERMP_SENTENCE (1 << 0) /* Space before a sentence. */ +#define TERMP_NOSPACE (1 << 1) /* No space before words. */ +#define TERMP_NONOSPACE (1 << 2) /* No space (no autounset). */ +#define TERMP_NBRWORD (1 << 3) /* Make next word nonbreaking. */ +#define TERMP_KEEP (1 << 4) /* Keep words together. */ +#define TERMP_PREKEEP (1 << 5) /* ...starting with the next one. */ +#define TERMP_BACKAFTER (1 << 6) /* Back up after next character. */ +#define TERMP_BACKBEFORE (1 << 7) /* Back up before next character. */ #define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */ -#define TERMP_BRIND (1 << 9) /* See term_flushln(). */ -#define TERMP_DANGLE (1 << 10) /* See term_flushln(). */ -#define TERMP_HANG (1 << 11) /* See term_flushln(). */ -#define TERMP_NOSPLIT (1 << 12) /* Do not break line before .An. */ -#define TERMP_SPLIT (1 << 13) /* Break line before .An. */ -#define TERMP_NONEWLINE (1 << 14) /* No line break in nofill mode. */ +#define TERMP_BRTRSP (1 << 9) /* See term_flushln(). */ +#define TERMP_BRIND (1 << 10) /* See term_flushln(). */ +#define TERMP_DANGLE (1 << 11) /* See term_flushln(). */ +#define TERMP_HANG (1 << 12) /* See term_flushln(). */ +#define TERMP_NOSPLIT (1 << 13) /* Do not break line before .An. */ +#define TERMP_SPLIT (1 << 14) /* Break line before .An. */ +#define TERMP_NONEWLINE (1 << 15) /* No line break in nofill mode. */ int *buf; /* Output buffer. */ enum termenc enc; /* Type of encoding. */ - const struct mchars *symtab; /* Character table. */ enum termfont fontl; /* Last font set. */ enum termfont *fontq; /* Symmetric fonts. */ int fontsz; /* Allocated size of font stack */ @@ -94,15 +97,14 @@ struct termp { void (*end)(struct termp *); void (*endline)(struct termp *); void (*advance)(struct termp *, size_t); - void (*setwidth)(struct termp *, int, size_t); + void (*setwidth)(struct termp *, int, int); size_t (*width)(const struct termp *, int); - double (*hspan)(const struct termp *, + int (*hspan)(const struct termp *, const struct roffsu *); const void *argf; /* arg for headf/footf */ struct termp_ps *ps; }; -__BEGIN_DECLS struct tbl_span; struct eqn; @@ -117,7 +119,7 @@ void term_vspace(struct termp *); void term_word(struct termp *, const char *); void term_flushln(struct termp *); void term_begin(struct termp *, term_margin, - term_margin, const void *); + term_margin, const struct roff_meta *); void term_end(struct termp *); void term_setwidth(struct termp *, const char *); @@ -131,5 +133,3 @@ void term_fontpop(struct termp *); void term_fontpopq(struct termp *, int); void term_fontrepl(struct termp *, enum termfont); void term_fontlast(struct termp *); - -__END_DECLS diff --git a/contrib/mdocml/term_ascii.c b/contrib/mdocml/term_ascii.c index 4ce4b68..7215a59 100644 --- a/contrib/mdocml/term_ascii.c +++ b/contrib/mdocml/term_ascii.c @@ -1,15 +1,15 @@ -/* $Id: term_ascii.c,v 1.43 2015/02/16 14:11:41 schwarze Exp $ */ +/* $Id: term_ascii.c,v 1.52 2015/11/12 21:50:03 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -35,11 +35,11 @@ #include "mandoc_aux.h" #include "out.h" #include "term.h" +#include "manconf.h" #include "main.h" -static struct termp *ascii_init(enum termenc, - const struct mchars *, char *); -static double ascii_hspan(const struct termp *, +static struct termp *ascii_init(enum termenc, const struct manoutput *); +static int ascii_hspan(const struct termp *, const struct roffsu *); static size_t ascii_width(const struct termp *, int); static void ascii_advance(struct termp *, size_t); @@ -47,7 +47,7 @@ static void ascii_begin(struct termp *); static void ascii_end(struct termp *); static void ascii_endline(struct termp *); static void ascii_letter(struct termp *, int); -static void ascii_setwidth(struct termp *, int, size_t); +static void ascii_setwidth(struct termp *, int, int); #if HAVE_WCHAR static void locale_advance(struct termp *, size_t); @@ -58,17 +58,16 @@ static size_t locale_width(const struct termp *, int); static struct termp * -ascii_init(enum termenc enc, const struct mchars *mchars, char *outopts) +ascii_init(enum termenc enc, const struct manoutput *outopts) { - const char *toks[5]; +#if HAVE_WCHAR char *v; +#endif struct termp *p; - const char *errstr; - int num; p = mandoc_calloc(1, sizeof(struct termp)); - p->symtab = mchars; + p->line = 1; p->tabwidth = 5; p->defrmargin = p->lastrmargin = 78; p->fontq = mandoc_reallocarray(NULL, @@ -89,8 +88,16 @@ ascii_init(enum termenc enc, const struct mchars *mchars, char *outopts) #if HAVE_WCHAR if (TERMENC_ASCII != enc) { + + /* + * Do not change any of this to LC_ALL. It might break + * the formatting by subtly changing the behaviour of + * various functions, for example strftime(3). As a + * worst case, it might even cause buffer overflows. + */ + v = TERMENC_LOCALE == enc ? - setlocale(LC_ALL, "") : + setlocale(LC_CTYPE, "") : setlocale(LC_CTYPE, "en_US.UTF-8"); if (NULL != v && MB_CUR_MAX > 1) { p->enc = enc; @@ -102,77 +109,52 @@ ascii_init(enum termenc enc, const struct mchars *mchars, char *outopts) } #endif - toks[0] = "indent"; - toks[1] = "width"; - toks[2] = "mdoc"; - toks[3] = "synopsis"; - toks[4] = NULL; - - while (outopts && *outopts) - switch (getsubopt(&outopts, UNCONST(toks), &v)) { - case 0: - num = strtonum(v, 0, 1000, &errstr); - if (!errstr) - p->defindent = num; - break; - case 1: - num = strtonum(v, 0, 1000, &errstr); - if (!errstr) - p->defrmargin = num; - break; - case 2: - /* - * Temporary, undocumented mode - * to imitate mdoc(7) output style. - */ - p->mdocstyle = 1; - p->defindent = 5; - break; - case 3: - p->synopsisonly = 1; - break; - default: - break; - } - - /* Enforce a lower boundary. */ - if (p->defrmargin < 58) - p->defrmargin = 58; - - return(p); + if (outopts->mdoc) { + p->mdocstyle = 1; + p->defindent = 5; + } + if (outopts->indent) + p->defindent = outopts->indent; + if (outopts->width) + p->defrmargin = outopts->width; + if (outopts->synopsisonly) + p->synopsisonly = 1; + + return p; } void * -ascii_alloc(const struct mchars *mchars, char *outopts) +ascii_alloc(const struct manoutput *outopts) { - return(ascii_init(TERMENC_ASCII, mchars, outopts)); + return ascii_init(TERMENC_ASCII, outopts); } void * -utf8_alloc(const struct mchars *mchars, char *outopts) +utf8_alloc(const struct manoutput *outopts) { - return(ascii_init(TERMENC_UTF8, mchars, outopts)); + return ascii_init(TERMENC_UTF8, outopts); } void * -locale_alloc(const struct mchars *mchars, char *outopts) +locale_alloc(const struct manoutput *outopts) { - return(ascii_init(TERMENC_LOCALE, mchars, outopts)); + return ascii_init(TERMENC_LOCALE, outopts); } static void -ascii_setwidth(struct termp *p, int iop, size_t width) +ascii_setwidth(struct termp *p, int iop, int width) { + width /= 24; p->rmargin = p->defrmargin; if (iop > 0) p->defrmargin += width; else if (iop == 0) - p->defrmargin = width ? width : p->lastrmargin; - else if (p->defrmargin > width) + p->defrmargin = width ? (size_t)width : p->lastrmargin; + else if (p->defrmargin > (size_t)width) p->defrmargin -= width; else p->defrmargin = 0; @@ -187,6 +169,7 @@ ascii_sepline(void *arg) size_t i; p = (struct termp *)arg; + p->line += 3; putchar('\n'); for (i = 0; i < p->defrmargin; i++) putchar('-'); @@ -198,7 +181,7 @@ static size_t ascii_width(const struct termp *p, int c) { - return(1); + return 1; } void @@ -233,6 +216,7 @@ static void ascii_endline(struct termp *p) { + p->line++; putchar('\n'); } @@ -245,52 +229,42 @@ ascii_advance(struct termp *p, size_t len) putchar(' '); } -static double +static int ascii_hspan(const struct termp *p, const struct roffsu *su) { double r; - /* - * Approximate based on character width. - * None of these will be actually correct given that an inch on - * the screen depends on character size, terminal, etc., etc. - */ switch (su->unit) { case SCALE_BU: - r = su->scale * 10.0 / 240.0; + r = su->scale; break; case SCALE_CM: - r = su->scale * 10.0 / 2.54; + r = su->scale * 240.0 / 2.54; break; case SCALE_FS: - r = su->scale * 2730.666; + r = su->scale * 65536.0; break; case SCALE_IN: - r = su->scale * 10.0; + r = su->scale * 240.0; break; case SCALE_MM: - r = su->scale / 100.0; + r = su->scale * 0.24; break; + case SCALE_VS: case SCALE_PC: - r = su->scale * 10.0 / 6.0; + r = su->scale * 40.0; break; case SCALE_PT: - r = su->scale * 10.0 / 72.0; - break; - case SCALE_VS: - r = su->scale * 2.0 - 1.0; + r = su->scale * 10.0 / 3.0; break; case SCALE_EN: - /* FALLTHROUGH */ case SCALE_EM: - r = su->scale; + r = su->scale * 24.0; break; default: abort(); - /* NOTREACHED */ } - - return(r); + return r > 0.0 ? r + 0.01 : r - 0.01; } const char * @@ -365,8 +339,8 @@ ascii_uc2str(int uc) assert(uc >= 0); if ((size_t)uc < sizeof(tab)/sizeof(tab[0])) - return(tab[uc]); - return(mchars_uc2str(uc)); + return tab[uc]; + return mchars_uc2str(uc); } #if HAVE_WCHAR @@ -380,7 +354,7 @@ locale_width(const struct termp *p, int c) rc = wcwidth(c); if (rc < 0) rc = 0; - return(rc); + return rc; } static void @@ -396,6 +370,7 @@ static void locale_endline(struct termp *p) { + p->line++; putwchar(L'\n'); } diff --git a/contrib/mdocml/term_ps.c b/contrib/mdocml/term_ps.c index 12ca7d6..6105d55 100644 --- a/contrib/mdocml/term_ps.c +++ b/contrib/mdocml/term_ps.c @@ -1,4 +1,4 @@ -/* $Id: term_ps.c,v 1.72 2015/01/21 19:40:54 schwarze Exp $ */ +/* $Id: term_ps.c,v 1.80 2015/12/23 20:50:13 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -20,6 +20,9 @@ #include <sys/types.h> #include <assert.h> +#if HAVE_ERR +#include <err.h> +#endif #include <stdarg.h> #include <stdint.h> #include <stdio.h> @@ -30,6 +33,7 @@ #include "mandoc_aux.h" #include "out.h" #include "term.h" +#include "manconf.h" #include "main.h" /* These work the buffer used by the header and footer. */ @@ -86,7 +90,7 @@ struct termp_ps { size_t pdfobjsz; /* size of pdfobjs */ }; -static double ps_hspan(const struct termp *, +static int ps_hspan(const struct termp *, const struct roffsu *); static size_t ps_width(const struct termp *, int); static void ps_advance(struct termp *, size_t); @@ -105,8 +109,8 @@ __attribute__((__format__ (__printf__, 2, 3))) static void ps_printf(struct termp *, const char *, ...); static void ps_putchar(struct termp *, char); static void ps_setfont(struct termp *, enum termfont); -static void ps_setwidth(struct termp *, int, size_t); -static struct termp *pspdf_alloc(const struct mchars *, char *); +static void ps_setwidth(struct termp *, int, int); +static struct termp *pspdf_alloc(const struct manoutput *); static void pdf_obj(struct termp *, size_t); /* @@ -507,39 +511,36 @@ static const struct font fonts[TERMFONT__MAX] = { }; void * -pdf_alloc(const struct mchars *mchars, char *outopts) +pdf_alloc(const struct manoutput *outopts) { struct termp *p; - if (NULL != (p = pspdf_alloc(mchars, outopts))) + if (NULL != (p = pspdf_alloc(outopts))) p->type = TERMTYPE_PDF; - return(p); + return p; } void * -ps_alloc(const struct mchars *mchars, char *outopts) +ps_alloc(const struct manoutput *outopts) { struct termp *p; - if (NULL != (p = pspdf_alloc(mchars, outopts))) + if (NULL != (p = pspdf_alloc(outopts))) p->type = TERMTYPE_PS; - return(p); + return p; } static struct termp * -pspdf_alloc(const struct mchars *mchars, char *outopts) +pspdf_alloc(const struct manoutput *outopts) { struct termp *p; unsigned int pagex, pagey; size_t marginx, marginy, lineheight; - const char *toks[2]; const char *pp; - char *v; p = mandoc_calloc(1, sizeof(struct termp)); - p->symtab = mchars; p->enc = TERMENC_ASCII; p->fontq = mandoc_reallocarray(NULL, (p->fontsz = 8), sizeof(enum termfont)); @@ -555,20 +556,6 @@ pspdf_alloc(const struct mchars *mchars, char *outopts) p->setwidth = ps_setwidth; p->width = ps_width; - toks[0] = "paper"; - toks[1] = NULL; - - pp = NULL; - - while (outopts && *outopts) - switch (getsubopt(&outopts, UNCONST(toks), &v)) { - case 0: - pp = v; - break; - default: - break; - } - /* Default to US letter (millimetres). */ pagex = 216; @@ -581,6 +568,7 @@ pspdf_alloc(const struct mchars *mchars, char *outopts) * only happens once, I'm not terribly concerned. */ + pp = outopts->paper; if (pp && strcasecmp(pp, "letter")) { if (0 == strcasecmp(pp, "a3")) { pagex = 297; @@ -595,7 +583,7 @@ pspdf_alloc(const struct mchars *mchars, char *outopts) pagex = 216; pagey = 356; } else if (2 != sscanf(pp, "%ux%u", &pagex, &pagey)) - fprintf(stderr, "%s: Unknown paper\n", pp); + warnx("%s: Unknown paper", pp); } /* @@ -629,11 +617,11 @@ pspdf_alloc(const struct mchars *mchars, char *outopts) p->ps->lineheight = lineheight; p->defrmargin = pagex - (marginx * 2); - return(p); + return p; } static void -ps_setwidth(struct termp *p, int iop, size_t width) +ps_setwidth(struct termp *p, int iop, int width) { size_t lastwidth; @@ -641,8 +629,8 @@ ps_setwidth(struct termp *p, int iop, size_t width) if (iop > 0) p->ps->width += width; else if (iop == 0) - p->ps->width = width ? width : p->ps->lastwidth; - else if (p->ps->width > width) + p->ps->width = width ? (size_t)width : p->ps->lastwidth; + else if (p->ps->width > (size_t)width) p->ps->width -= width; else p->ps->width = 0; @@ -656,10 +644,8 @@ pspdf_free(void *arg) p = (struct termp *)arg; - if (p->ps->psmarg) - free(p->ps->psmarg); - if (p->ps->pdfobjs) - free(p->ps->pdfobjs); + free(p->ps->psmarg); + free(p->ps->pdfobjs); free(p->ps); term_free(p); @@ -998,9 +984,7 @@ ps_pletter(struct termp *p, int c) switch (c) { case '(': - /* FALLTHROUGH */ case ')': - /* FALLTHROUGH */ case '\\': ps_putchar(p, '\\'); break; @@ -1283,10 +1267,10 @@ ps_width(const struct termp *p, int c) else c -= 32; - return((size_t)fonts[(int)TERMFONT_NONE].gly[c].wx); + return (size_t)fonts[(int)TERMFONT_NONE].gly[c].wx; } -static double +static int ps_hspan(const struct termp *p, const struct roffsu *su) { double r; @@ -1338,7 +1322,7 @@ ps_hspan(const struct termp *p, const struct roffsu *su) break; } - return(r); + return r * 24.0; } static void diff --git a/contrib/mdocml/test-dirent-namlen.c b/contrib/mdocml/test-dirent-namlen.c index 4a00789..032e75e 100644 --- a/contrib/mdocml/test-dirent-namlen.c +++ b/contrib/mdocml/test-dirent-namlen.c @@ -6,5 +6,5 @@ main(void) { struct dirent entry; - return (sizeof(entry.d_namlen) == 0); + return sizeof(entry.d_namlen) == 0; } diff --git a/contrib/mdocml/test-err.c b/contrib/mdocml/test-err.c new file mode 100644 index 0000000..d17e0f0 --- /dev/null +++ b/contrib/mdocml/test-err.c @@ -0,0 +1,28 @@ +/* $Id: test-err.c,v 1.1 2015/10/11 21:12:55 schwarze Exp $ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <err.h> + +int +main(void) +{ + warnx("%d. warnx", 1); + warn("%d. warn", 2); + err(0, "%d. err", 3); + /* NOTREACHED */ + return 1; +} diff --git a/contrib/mdocml/test-fts.c b/contrib/mdocml/test-fts.c index 1a1bfc7..dbee529 100644 --- a/contrib/mdocml/test-fts.c +++ b/contrib/mdocml/test-fts.c @@ -18,25 +18,25 @@ main(void) if (ftsp == NULL) { perror("fts_open"); - return(1); + return 1; } entry = fts_read(ftsp); if (entry == NULL) { perror("fts_read"); - return(1); + return 1; } if (fts_set(ftsp, entry, FTS_SKIP) != 0) { perror("fts_set"); - return(1); + return 1; } if (fts_close(ftsp) != 0) { perror("fts_close"); - return(1); + return 1; } - return(0); + return 0; } diff --git a/contrib/mdocml/test-getline.c b/contrib/mdocml/test-getline.c new file mode 100644 index 0000000..d05df21 --- /dev/null +++ b/contrib/mdocml/test-getline.c @@ -0,0 +1,13 @@ +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> + +int +main(void) +{ + char *line = NULL; + size_t linesz = 0; + + fclose(stdin); + return getline(&line, &linesz, stdin) != -1; +} diff --git a/contrib/mdocml/test-getsubopt.c b/contrib/mdocml/test-getsubopt.c index b083569..afcc559 100644 --- a/contrib/mdocml/test-getsubopt.c +++ b/contrib/mdocml/test-getsubopt.c @@ -1,4 +1,4 @@ -/* $Id: test-getsubopt.c,v 1.3 2014/08/17 20:53:50 schwarze Exp $ */ +/* $Id: test-getsubopt.c,v 1.4 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -29,6 +29,6 @@ main(void) char token0[] = "k"; char *const tokens[] = { token0, NULL }; char *value = NULL; - return( ! (0 == getsubopt(&options, tokens, &value) - && value == buf+2 && options == buf+3)); + return ! (getsubopt(&options, tokens, &value) == 0 + && value == buf+2 && options == buf+3); } diff --git a/contrib/mdocml/test-isblank.c b/contrib/mdocml/test-isblank.c new file mode 100644 index 0000000..eb2cfdf --- /dev/null +++ b/contrib/mdocml/test-isblank.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int +main(void) +{ + return !isblank(' ') || !isblank('\t') || isblank('_'); +} diff --git a/contrib/mdocml/test-mkdtemp.c b/contrib/mdocml/test-mkdtemp.c new file mode 100644 index 0000000..a0cb30e --- /dev/null +++ b/contrib/mdocml/test-mkdtemp.c @@ -0,0 +1,12 @@ +#include <stdlib.h> +#include <unistd.h> + +int +main(void) +{ + char dirname[] = "/tmp/temp.XXXXXX"; + + if (mkdtemp(dirname) != dirname) + return 1; + return rmdir(dirname) == -1; +} diff --git a/contrib/mdocml/test-mmap.c b/contrib/mdocml/test-mmap.c index c322a34..3a6232d 100644 --- a/contrib/mdocml/test-mmap.c +++ b/contrib/mdocml/test-mmap.c @@ -5,5 +5,5 @@ int main(void) { - return(MAP_FAILED != mmap(NULL, 1, PROT_READ, MAP_SHARED, -1, 0)); + return mmap(NULL, 1, PROT_READ, MAP_SHARED, -1, 0) != MAP_FAILED; } diff --git a/contrib/mdocml/test-ohash.c b/contrib/mdocml/test-ohash.c index 522ad70..138d520 100644 --- a/contrib/mdocml/test-ohash.c +++ b/contrib/mdocml/test-ohash.c @@ -3,8 +3,8 @@ #include <stdlib.h> #include <ohash.h> -void *xmalloc(size_t sz, void *arg) { return(calloc(1,sz)); } -void *xcalloc(size_t nmemb, size_t sz, void *arg) { return(calloc(nmemb,sz)); } +void *xmalloc(size_t sz, void *arg) { return calloc(1,sz); } +void *xcalloc(size_t nmemb, size_t sz, void *arg) { return calloc(nmemb,sz); } void xfree(void *p, void *arg) { free(p); } int diff --git a/contrib/mdocml/test-pledge.c b/contrib/mdocml/test-pledge.c new file mode 100644 index 0000000..ab2dfb4 --- /dev/null +++ b/contrib/mdocml/test-pledge.c @@ -0,0 +1,7 @@ +#include <unistd.h> + +int +main(void) +{ + return !!pledge("stdio", NULL); +} diff --git a/contrib/mdocml/test-progname.c b/contrib/mdocml/test-progname.c new file mode 100644 index 0000000..0418b3c --- /dev/null +++ b/contrib/mdocml/test-progname.c @@ -0,0 +1,10 @@ +#include <stdlib.h> + +int +main(void) +{ + const char * progname; + + progname = getprogname(); + return progname == NULL; +} diff --git a/contrib/mdocml/test-reallocarray.c b/contrib/mdocml/test-reallocarray.c index 9a514e8..f99e685 100644 --- a/contrib/mdocml/test-reallocarray.c +++ b/contrib/mdocml/test-reallocarray.c @@ -3,5 +3,5 @@ int main(void) { - return( ! reallocarray(NULL, 2, 2)); + return !reallocarray(NULL, 2, 2); } diff --git a/contrib/mdocml/test-rewb-bsd.c b/contrib/mdocml/test-rewb-bsd.c new file mode 100644 index 0000000..88d3d35 --- /dev/null +++ b/contrib/mdocml/test-rewb-bsd.c @@ -0,0 +1,26 @@ +#include <sys/types.h> +#include <regex.h> + +int +main(void) +{ + regex_t re; + + if (regcomp(&re, "[[:<:]]word[[:>:]]", REG_EXTENDED | REG_NOSUB)) + return 1; + if (regexec(&re, "the word is here", 0, NULL, 0)) + return 2; + if (regexec(&re, "same word", 0, NULL, 0)) + return 3; + if (regexec(&re, "word again", 0, NULL, 0)) + return 4; + if (regexec(&re, "word", 0, NULL, 0)) + return 5; + if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH) + return 6; + if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH) + return 7; + if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH) + return 8; + return 0; +} diff --git a/contrib/mdocml/test-rewb-sysv.c b/contrib/mdocml/test-rewb-sysv.c new file mode 100644 index 0000000..cb35c54 --- /dev/null +++ b/contrib/mdocml/test-rewb-sysv.c @@ -0,0 +1,26 @@ +#include <sys/types.h> +#include <regex.h> + +int +main(void) +{ + regex_t re; + + if (regcomp(&re, "\\<word\\>", REG_EXTENDED | REG_NOSUB)) + return 1; + if (regexec(&re, "the word is here", 0, NULL, 0)) + return 2; + if (regexec(&re, "same word", 0, NULL, 0)) + return 3; + if (regexec(&re, "word again", 0, NULL, 0)) + return 4; + if (regexec(&re, "word", 0, NULL, 0)) + return 5; + if (regexec(&re, "wordy", 0, NULL, 0) != REG_NOMATCH) + return 6; + if (regexec(&re, "sword", 0, NULL, 0) != REG_NOMATCH) + return 7; + if (regexec(&re, "reworded", 0, NULL, 0) != REG_NOMATCH) + return 8; + return 0; +} diff --git a/contrib/mdocml/test-sqlite3.c b/contrib/mdocml/test-sqlite3.c index 29feab6..11f17ad 100644 --- a/contrib/mdocml/test-sqlite3.c +++ b/contrib/mdocml/test-sqlite3.c @@ -1,4 +1,4 @@ -/* $Id: test-sqlite3.c,v 1.1 2014/08/16 19:00:01 schwarze Exp $ */ +/* $Id: test-sqlite3.c,v 1.2 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> * @@ -29,19 +29,19 @@ main(void) NULL) != SQLITE_OK) { perror("test.db"); fprintf(stderr, "sqlite3_open_v2: %s", sqlite3_errmsg(db)); - return(1); + return 1; } unlink("test.db"); if (sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL) != SQLITE_OK) { fprintf(stderr, "sqlite3_exec: %s", sqlite3_errmsg(db)); - return(1); + return 1; } if (sqlite3_close(db) != SQLITE_OK) { fprintf(stderr, "sqlite3_close: %s", sqlite3_errmsg(db)); - return(1); + return 1; } - return(0); + return 0; } diff --git a/contrib/mdocml/test-sqlite3_errstr.c b/contrib/mdocml/test-sqlite3_errstr.c index 041bf62..4d3c7c5 100644 --- a/contrib/mdocml/test-sqlite3_errstr.c +++ b/contrib/mdocml/test-sqlite3_errstr.c @@ -4,5 +4,5 @@ int main(void) { - return(strcmp(sqlite3_errstr(SQLITE_OK), "not an error")); + return strcmp(sqlite3_errstr(SQLITE_OK), "not an error"); } diff --git a/contrib/mdocml/test-strcasestr.c b/contrib/mdocml/test-strcasestr.c index 479ba91..c3a87de 100644 --- a/contrib/mdocml/test-strcasestr.c +++ b/contrib/mdocml/test-strcasestr.c @@ -9,5 +9,5 @@ main(void) { const char *big = "BigString"; char *cp = strcasestr(big, "Gst"); - return(big + 2 != cp); + return cp != big + 2; } diff --git a/contrib/mdocml/test-stringlist.c b/contrib/mdocml/test-stringlist.c new file mode 100644 index 0000000..7555d20 --- /dev/null +++ b/contrib/mdocml/test-stringlist.c @@ -0,0 +1,37 @@ +/* $Id: test-stringlist.c,v 1.2 2015/10/06 18:32:20 schwarze Exp $ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stringlist.h> + +int +main(void) +{ + StringList *sl; + char teststr[] = "test"; + + if ((sl = sl_init()) == NULL) + return 1; + if (sl_add(sl, teststr)) + return 2; + if (sl->sl_cur != 1) + return 3; + if (sl->sl_str[0] != teststr) + return 4; + + sl_free(sl, 0); + return 0; +} diff --git a/contrib/mdocml/test-strlcat.c b/contrib/mdocml/test-strlcat.c index b74ce6f..48ab38a 100644 --- a/contrib/mdocml/test-strlcat.c +++ b/contrib/mdocml/test-strlcat.c @@ -4,6 +4,6 @@ int main(void) { char buf[3] = "a"; - return( ! (2 == strlcat(buf, "b", sizeof(buf)) && - 'a' == buf[0] && 'b' == buf[1] && '\0' == buf[2])); + return ! (strlcat(buf, "b", sizeof(buf)) == 2 && + buf[0] == 'a' && buf[1] == 'b' && buf[2] == '\0'); } diff --git a/contrib/mdocml/test-strlcpy.c b/contrib/mdocml/test-strlcpy.c index 05fa509..12e1db3 100644 --- a/contrib/mdocml/test-strlcpy.c +++ b/contrib/mdocml/test-strlcpy.c @@ -4,6 +4,6 @@ int main(void) { char buf[2] = ""; - return( ! (1 == strlcpy(buf, "a", sizeof(buf)) && - 'a' == buf[0] && '\0' == buf[1])); + return ! (strlcpy(buf, "a", sizeof(buf)) == 1 && + buf[0] == 'a' && buf[1] == '\0'); } diff --git a/contrib/mdocml/test-strptime.c b/contrib/mdocml/test-strptime.c index bedc775..d8799e9 100644 --- a/contrib/mdocml/test-strptime.c +++ b/contrib/mdocml/test-strptime.c @@ -9,6 +9,6 @@ main(void) { struct tm tm; const char input[] = "2014-01-04"; - return( ! (input+10 == strptime(input, "%Y-%m-%d", &tm) && - 114 == tm.tm_year && 0 == tm.tm_mon && 4 == tm.tm_mday)); + return ! (strptime(input, "%Y-%m-%d", &tm) == input + 10 && + tm.tm_year == 114 && tm.tm_mon == 0 && tm.tm_mday == 4); } diff --git a/contrib/mdocml/test-strsep.c b/contrib/mdocml/test-strsep.c index 4c57c13..18bbb10 100644 --- a/contrib/mdocml/test-strsep.c +++ b/contrib/mdocml/test-strsep.c @@ -6,5 +6,5 @@ main(void) char buf[6] = "aybxc"; char *workp = buf; char *retp = strsep(&workp, "xy"); - return( ! (retp == buf && '\0' == buf[1] && buf + 2 == workp)); + return ! (retp == buf && buf[1] == '\0' && workp == buf + 2); } diff --git a/contrib/mdocml/test-strtonum.c b/contrib/mdocml/test-strtonum.c index ce70dd6..4b6cd3f 100644 --- a/contrib/mdocml/test-strtonum.c +++ b/contrib/mdocml/test-strtonum.c @@ -1,4 +1,4 @@ -/* $Id: test-strtonum.c,v 1.1 2015/02/16 14:56:22 schwarze Exp $ */ +/* $Id: test-strtonum.c,v 1.2 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> * @@ -23,20 +23,20 @@ main(void) const char *errstr; if (strtonum("1", 0, 2, &errstr) != 1) - return(1); + return 1; if (errstr != NULL) - return(2); + return 2; if (strtonum("1x", 0, 2, &errstr) != 0) - return(3); + return 3; if (errstr == NULL) - return(4); + return 4; if (strtonum("2", 0, 1, &errstr) != 0) - return(5); + return 5; if (errstr == NULL) - return(6); + return 6; if (strtonum("0", 1, 2, &errstr) != 0) - return(7); + return 7; if (errstr == NULL) - return(8); - return(0); + return 8; + return 0; } diff --git a/contrib/mdocml/test-vasprintf.c b/contrib/mdocml/test-vasprintf.c new file mode 100644 index 0000000..bdb4408 --- /dev/null +++ b/contrib/mdocml/test-vasprintf.c @@ -0,0 +1,49 @@ +/* $Id: test-vasprintf.c,v 1.3 2015/10/06 18:32:20 schwarze Exp $ */ +/* + * Copyright (c) 2015 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 defined(__linux__) || defined(__MINT__) +#define _GNU_SOURCE /* vasprintf() */ +#endif + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +int +testfunc(char **ret, const char *format, ...) +{ + va_list ap; + int irc; + + va_start(ap, format); + irc = vasprintf(ret, format, ap); + va_end(ap); + + return irc; +} + +int +main(void) +{ + char *ret; + + if (testfunc(&ret, "%s.", "Text") != 5) + return 1; + if (strcmp(ret, "Text.")) + return 2; + return 0; +} diff --git a/contrib/mdocml/test-wchar.c b/contrib/mdocml/test-wchar.c index 2cbb49d..a096705 100644 --- a/contrib/mdocml/test-wchar.c +++ b/contrib/mdocml/test-wchar.c @@ -1,4 +1,4 @@ -/* $Id: test-wchar.c,v 1.2 2014/08/28 10:38:06 schwarze Exp $ */ +/* $Id: test-wchar.c,v 1.3 2015/10/06 18:32:20 schwarze Exp $ */ /* * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> * @@ -32,32 +32,32 @@ main(void) if (setlocale(LC_ALL, "") == NULL) { fputs("setlocale(LC_ALL, \"\") failed\n", stderr); - return(1); + return 1; } if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) { fputs("setlocale(LC_CTYPE, \"en_US.UTF-8\") failed\n", stderr); - return(1); + return 1; } if (sizeof(wchar_t) < 4) { fprintf(stderr, "wchar_t is only %zu bytes\n", sizeof(wchar_t)); - return(1); + return 1; } if ((width = wcwidth(L' ')) != 1) { fprintf(stderr, "wcwidth(L' ') returned %d\n", width); - return(1); + return 1; } dup2(STDERR_FILENO, STDOUT_FILENO); wc = L'*'; if (putwchar(wc) != (wint_t)wc) { fputs("bad putwchar return value\n", stderr); - return(1); + return 1; } - return(0); + return 0; } diff --git a/contrib/mdocml/tree.c b/contrib/mdocml/tree.c index a5a7f2c..52ca754 100644 --- a/contrib/mdocml/tree.c +++ b/contrib/mdocml/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.62 2015/02/05 00:14:13 schwarze Exp $ */ +/* $Id: tree.c,v 1.69 2015/10/12 00:08:16 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> @@ -7,9 +7,9 @@ * 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 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF @@ -26,32 +26,33 @@ #include <time.h> #include "mandoc.h" +#include "roff.h" #include "mdoc.h" #include "man.h" #include "main.h" static void print_box(const struct eqn_box *, int); -static void print_man(const struct man_node *, int); -static void print_mdoc(const struct mdoc_node *, int); +static void print_man(const struct roff_node *, int); +static void print_mdoc(const struct roff_node *, int); static void print_span(const struct tbl_span *, int); void -tree_mdoc(void *arg, const struct mdoc *mdoc) +tree_mdoc(void *arg, const struct roff_man *mdoc) { - print_mdoc(mdoc_node(mdoc)->child, 0); + print_mdoc(mdoc->first->child, 0); } void -tree_man(void *arg, const struct man *man) +tree_man(void *arg, const struct roff_man *man) { - print_man(man_node(man)->child, 0); + print_man(man->first->child, 0); } static void -print_mdoc(const struct mdoc_node *n, int indent) +print_mdoc(const struct roff_node *n, int indent) { const char *p, *t; int i, j; @@ -66,78 +67,76 @@ print_mdoc(const struct mdoc_node *n, int indent) t = p = NULL; switch (n->type) { - case MDOC_ROOT: + case ROFFT_ROOT: t = "root"; break; - case MDOC_BLOCK: + case ROFFT_BLOCK: t = "block"; break; - case MDOC_HEAD: - t = "block-head"; + case ROFFT_HEAD: + t = "head"; break; - case MDOC_BODY: + case ROFFT_BODY: if (n->end) t = "body-end"; else - t = "block-body"; + t = "body"; break; - case MDOC_TAIL: - t = "block-tail"; + case ROFFT_TAIL: + t = "tail"; break; - case MDOC_ELEM: + case ROFFT_ELEM: t = "elem"; break; - case MDOC_TEXT: + case ROFFT_TEXT: t = "text"; break; - case MDOC_TBL: + case ROFFT_TBL: break; - case MDOC_EQN: + case ROFFT_EQN: t = "eqn"; break; default: abort(); - /* NOTREACHED */ } switch (n->type) { - case MDOC_TEXT: + case ROFFT_TEXT: p = n->string; break; - case MDOC_BODY: + case ROFFT_BODY: p = mdoc_macronames[n->tok]; break; - case MDOC_HEAD: + case ROFFT_HEAD: p = mdoc_macronames[n->tok]; break; - case MDOC_TAIL: + case ROFFT_TAIL: p = mdoc_macronames[n->tok]; break; - case MDOC_ELEM: + case ROFFT_ELEM: p = mdoc_macronames[n->tok]; if (n->args) { argv = n->args->argv; argc = n->args->argc; } break; - case MDOC_BLOCK: + case ROFFT_BLOCK: p = mdoc_macronames[n->tok]; if (n->args) { argv = n->args->argv; argc = n->args->argc; } break; - case MDOC_TBL: + case ROFFT_TBL: break; - case MDOC_EQN: + case ROFFT_EQN: p = "EQ"; break; - case MDOC_ROOT: + case ROFFT_ROOT: p = "root"; break; default: abort(); - /* NOTREACHED */ } if (n->span) { @@ -160,22 +159,29 @@ print_mdoc(const struct mdoc_node *n, int indent) } putchar(' '); + if (MDOC_DELIMO & n->flags) + putchar('('); if (MDOC_LINE & n->flags) putchar('*'); - printf("%d:%d\n", n->line, n->pos + 1); + printf("%d:%d", n->line, n->pos + 1); + if (MDOC_DELIMC & n->flags) + putchar(')'); + if (MDOC_EOS & n->flags) + putchar('.'); + putchar('\n'); } if (n->eqn) print_box(n->eqn->root->first, indent + 4); if (n->child) print_mdoc(n->child, indent + - (n->type == MDOC_BLOCK ? 2 : 4)); + (n->type == ROFFT_BLOCK ? 2 : 4)); if (n->next) print_mdoc(n->next, indent); } static void -print_man(const struct man_node *n, int indent) +print_man(const struct roff_node *n, int indent) { const char *p, *t; int i; @@ -186,58 +192,53 @@ print_man(const struct man_node *n, int indent) t = p = NULL; switch (n->type) { - case MAN_ROOT: + case ROFFT_ROOT: t = "root"; break; - case MAN_ELEM: + case ROFFT_ELEM: t = "elem"; break; - case MAN_TEXT: + case ROFFT_TEXT: t = "text"; break; - case MAN_BLOCK: + case ROFFT_BLOCK: t = "block"; break; - case MAN_HEAD: - t = "block-head"; + case ROFFT_HEAD: + t = "head"; break; - case MAN_BODY: - t = "block-body"; + case ROFFT_BODY: + t = "body"; break; - case MAN_TBL: + case ROFFT_TBL: break; - case MAN_EQN: + case ROFFT_EQN: t = "eqn"; break; default: abort(); - /* NOTREACHED */ } switch (n->type) { - case MAN_TEXT: + case ROFFT_TEXT: p = n->string; break; - case MAN_ELEM: - /* FALLTHROUGH */ - case MAN_BLOCK: - /* FALLTHROUGH */ - case MAN_HEAD: - /* FALLTHROUGH */ - case MAN_BODY: + case ROFFT_ELEM: + case ROFFT_BLOCK: + case ROFFT_HEAD: + case ROFFT_BODY: p = man_macronames[n->tok]; break; - case MAN_ROOT: + case ROFFT_ROOT: p = "root"; break; - case MAN_TBL: + case ROFFT_TBL: break; - case MAN_EQN: + case ROFFT_EQN: p = "EQ"; break; default: abort(); - /* NOTREACHED */ } if (n->span) { @@ -249,14 +250,17 @@ print_man(const struct man_node *n, int indent) printf("%s (%s) ", p, t); if (MAN_LINE & n->flags) putchar('*'); - printf("%d:%d\n", n->line, n->pos + 1); + printf("%d:%d", n->line, n->pos + 1); + if (MAN_EOS & n->flags) + putchar('.'); + putchar('\n'); } if (n->eqn) print_box(n->eqn->root->first, indent + 4); if (n->child) print_man(n->child, indent + - (n->type == MAN_BLOCK ? 2 : 4)); + (n->type == ROFFT_BLOCK ? 2 : 4)); if (n->next) print_man(n->next, indent); } @@ -350,12 +354,10 @@ print_span(const struct tbl_span *sp, int indent) for (dp = sp->first; dp; dp = dp->next) { switch (dp->pos) { case TBL_DATA_HORIZ: - /* FALLTHROUGH */ case TBL_DATA_NHORIZ: putchar('-'); continue; case TBL_DATA_DHORIZ: - /* FALLTHROUGH */ case TBL_DATA_NDHORIZ: putchar('='); continue; |