aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2018-09-20 07:33:14 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2018-09-20 07:33:14 +0000
commit1f1d4007ae66645e397e325b72643166dc3c1efe (patch)
treee354209a74fdddab23006c2633687156dee4829e
parentabba600e6fdb031951c32298f8be9e45fb339099 (diff)
downloadsrc-1f1d4007ae66645e397e325b72643166dc3c1efe.tar.gz
src-1f1d4007ae66645e397e325b72643166dc3c1efe.zip
import mandoc 1.14.1vendor/mandoc/1.14.4
Notes
Notes: svn path=/vendor/mandoc/dist/; revision=338819 svn path=/vendor/mandoc/1.14.4/; revision=338821; tag=vendor/mandoc/1.14.4
-rw-r--r--INSTALL20
-rw-r--r--LICENSE6
-rw-r--r--Makefile18
-rw-r--r--Makefile.depend3
-rw-r--r--NEWS79
-rw-r--r--TODO109
-rw-r--r--apropos.127
-rw-r--r--cgi.c16
-rw-r--r--chars.c170
-rw-r--r--compat_strndup.c50
-rwxr-xr-xconfigure117
-rw-r--r--configure.local.example44
-rw-r--r--eqn.76
-rw-r--r--eqn_term.c28
-rw-r--r--gmdiff19
-rw-r--r--html.c331
-rw-r--r--html.h11
-rw-r--r--lib.in24
-rw-r--r--libmandoc.h4
-rw-r--r--main.c98
-rw-r--r--man.150
-rw-r--r--man.721
-rw-r--r--man.cgi.813
-rw-r--r--man.conf.512
-rw-r--r--man_html.c94
-rw-r--r--man_term.c25
-rw-r--r--man_validate.c6
-rw-r--r--mandoc.1238
-rw-r--r--mandoc.c7
-rw-r--r--mandoc.css256
-rw-r--r--mandoc.h8
-rw-r--r--mandoc_aux.c8
-rw-r--r--mandoc_char.7136
-rw-r--r--mandoc_html.3100
-rw-r--r--mandocdb.c158
-rw-r--r--mansearch.c12
-rw-r--r--mdoc.766
-rw-r--r--mdoc.c6
-rw-r--r--mdoc_html.c248
-rw-r--r--mdoc_man.c29
-rw-r--r--mdoc_markdown.c4
-rw-r--r--mdoc_state.c25
-rw-r--r--mdoc_term.c29
-rw-r--r--mdoc_validate.c108
-rw-r--r--out.h7
-rw-r--r--read.c45
-rw-r--r--roff.726
-rw-r--r--roff.c246
-rw-r--r--roff.h3
-rw-r--r--roff_html.c16
-rw-r--r--st.in88
-rw-r--r--tag.c5
-rw-r--r--tbl.78
-rw-r--r--tbl_html.c11
-rw-r--r--term_ascii.c34
-rw-r--r--term_ps.c120
-rw-r--r--test-noop.c5
-rw-r--r--test-strndup.c10
-rw-r--r--tree.c12
59 files changed, 2009 insertions, 1466 deletions
diff --git a/INSTALL b/INSTALL
index d80e8e319251..558574b903de 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-$Id: INSTALL,v 1.20 2017/07/28 14:57:56 schwarze Exp $
+$Id: INSTALL,v 1.22 2018/07/31 15:34:00 schwarze Exp $
About the portable mandoc distribution
--------------------------------------
@@ -18,7 +18,7 @@ tech@ mailing list, too.
Enjoy using the mandoc toolset!
-Ingo Schwarze, Karlsruhe, July 2017
+Ingo Schwarze, Karlsruhe, August 2018
Installation
@@ -54,8 +54,6 @@ 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.
5. Run "make".
Any POSIX-compatible make, in particular both BSD make and GNU make,
@@ -83,12 +81,14 @@ apropos(1) will not find the new pages.
10. To set up a man.cgi(8) server, read its manual page.
-Note that some man(7) pages may contain low-level roff(7) markup
-that mandoc does not yet understand. On some BSD systems using
-mandoc, third-party software is vetted on whether it may be formatted
-with mandoc. If not, groff(1) is pulled in as a dependency and
-used to install a pre-formatted "catpage" instead of directly as
-manual page source.
+Note that a very small number of man(7) pages contain low-level
+roff(7) markup that mandoc does not yet understand. On some BSD
+systems using mandoc, third-party software is vetted on whether it
+may be formatted with mandoc. If not, groff(1) is pulled in as a
+dependency and used to install pre-formatted "catpages" instead of
+manual page sources. This mechanism is used much less frequently
+than in the past. On OpenBSD, only 25 out of about 10000 ports
+still require formatting with groff(1).
Understanding mandoc dependencies
diff --git a/LICENSE b/LICENSE
index aca7ee7a6c7e..ec7fc029d82c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,17 +1,17 @@
-$Id: LICENSE,v 1.17 2017/06/23 15:58:14 schwarze Exp $
+$Id: LICENSE,v 1.19 2018/07/31 10:18:15 schwarze Exp $
With the exceptions noted below, all code and documentation
contained in the mandoc toolkit is protected by the Copyright
of the following developers:
Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
-Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
+Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
+Copyright (c) 1999, 2004, 2017 Marc Espie <espie@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) 2016 Ed Maste <emaste@freebsd.org>
Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.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, 2017 Otto Moerbeek <otto@drijf.net>
Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
diff --git a/Makefile b/Makefile
index 9855c9f8f1e8..09738579f0d2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile,v 1.516 2017/07/20 16:24:53 schwarze Exp $
+# $Id: Makefile,v 1.519 2018/07/31 15:34:00 schwarze Exp $
#
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
-# Copyright (c) 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
+# Copyright (c) 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-VERSION = 1.14.3
+VERSION = 1.14.4
# === LIST OF FILES ====================================================
@@ -30,6 +30,7 @@ TESTSRCS = test-be32toh.c \
test-isblank.c \
test-mkdtemp.c \
test-nanosleep.c \
+ test-noop.c \
test-ntohl.c \
test-O_DIRECTORY.c \
test-ohash.c \
@@ -46,6 +47,7 @@ TESTSRCS = test-be32toh.c \
test-stringlist.c \
test-strlcat.c \
test-strlcpy.c \
+ test-strndup.c \
test-strptime.c \
test-strsep.c \
test-strtonum.c \
@@ -70,6 +72,7 @@ SRCS = att.c \
compat_stringlist.c \
compat_strlcat.c \
compat_strlcpy.c \
+ compat_strndup.c \
compat_strsep.c \
compat_strtonum.c \
compat_vasprintf.c \
@@ -249,6 +252,7 @@ COMPAT_OBJS = compat_err.o \
compat_strcasestr.o \
compat_strlcat.o \
compat_strlcpy.o \
+ compat_strndup.o \
compat_strsep.o \
compat_strtonum.o \
compat_vasprintf.o
@@ -544,12 +548,12 @@ regress-distcheck:
! -path regress/regress.pl \
! -path regress/regress.pl.1
-dist: mandoc.sha256
+dist: mandoc-$(VERSION).sha256
-mandoc.sha256: mandoc.tar.gz
- sha256 mandoc.tar.gz > $@
+mandoc-$(VERSION).sha256: mandoc-$(VERSION).tar.gz
+ sha256 mandoc-$(VERSION).tar.gz > $@
-mandoc.tar.gz: $(DISTFILES)
+mandoc-$(VERSION).tar.gz: $(DISTFILES)
ls regress/*/*/*.mandoc_* && exit 1 || true
mkdir -p .dist/mandoc-$(VERSION)/
$(INSTALL) -m 0644 $(DISTFILES) .dist/mandoc-$(VERSION)
diff --git a/Makefile.depend b/Makefile.depend
index 4f5dc808823e..da366a1cd596 100644
--- a/Makefile.depend
+++ b/Makefile.depend
@@ -16,6 +16,7 @@ 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_strndup.o: compat_strndup.c config.h
compat_strsep.o: compat_strsep.c config.h
compat_strtonum.o: compat_strtonum.c config.h
compat_vasprintf.o: compat_vasprintf.c config.h
@@ -29,7 +30,7 @@ demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h
eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h libroff.h
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
-html.o: html.c config.h mandoc_aux.h mandoc.h roff.h out.h html.h manconf.h main.h
+html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h
lib.o: lib.c config.h mandoc.h roff.h mdoc.h libmdoc.h lib.in
main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
diff --git a/NEWS b/NEWS
index 3d35e2b7bdc5..3bb5b4728b99 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,84 @@
-$Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $
+$Id: NEWS,v 1.32 2018/08/08 14:47:38 schwarze Exp $
This file lists the most important changes in the mandoc.bsd.lv distribution.
+Changes in version 1.14.4, released on August 8, 2018
+
+ --- MAJOR NEW FEATURES ---
+ * In ASCII output, render mathematical symbols and greek letters
+ as transliterations conveying the characters' meanings rather
+ than trying to imitate their shape. Consequently, such characters
+ can now be used in portable manual pages. All the same, please
+ limit their use to contexts where they really matter, for example
+ when showing complicated mathematical formulae.
+ * First steps towards better support for small screens in HTML
+ output (responsive design): avoid most style= attributes, in
+ particular all hard-coded indentations and column widths, and
+ provide a better mandoc.css style sheet with a @media query,
+ using em units throughout, and avoiding redundancy in selectors.
+ * Better HTML output with some more fitting HTML elements, eliminating
+ needless class= attributes, and avoiding various HTML syntax errors
+ (element nesting, URL-fragment syntax, duplicate id= attributes).
+ --- MINOR NEW FEATURES ---
+ * When a man(1) argument contains a slash, imply -l like in man-db.
+ * Use TIOCGWINSZ to reduce the default -Owidth and -Oindent during
+ interactive use on terminals narrower than 79 columns.
+ * Generated PostScript files are now more than 50% smaller.
+ * Terminal rendering of eqn(7) is improved in several respects.
+ * Simplified and nicer output from the mdoc(7) .Lk macro, formatting
+ all links in-line, even long ones.
+ * roff(7) \n+ and \n- numerical register auto-increment and -decrement
+ * roff(7) .nr optional third argument (auto-increment step size)
+ * Autodetect in ./configure whether the compiler can use -W and -static,
+ allowing to build on Solaris 10 and 11 without any configure.local.
+ --- RELIABILITY BUGFIXES ---
+ * Only activate UTF-8 output when the user really selected UTF-8,
+ not some other multibyte character encoding.
+ * Prevent excessive .ll arguments from generating infinite output.
+ * Fix out of bounds accesses to parse buffers that could happen when
+ using renamed or user defined macros after roff(7) conditionals.
+ * Avoid an assertion failure in certain .Bl -column lists.
+ * Avoid a NULL pointer access on deroff() failure after '.SS ""'.
+ * Fix a segfault that could be triggered by two invalid .Dt macros.
+ * Fix two syntax errors in generated PDF files.
+ * Properly state the page size in generated PostScript files.
+ * Close a memory leak caused by missing gzclose(3).
+ * Fix misformatting of man(7) documents lacking .SH macros
+ in PostScript and PDF output.
+ * And many minor bugfixes.
+ --- THANKS TO ---
+ * Marc Espie (OpenBSD) for implementing the size reduction of
+ PostScript files, one additional patch for code simplification,
+ and two bug reports.
+ * Theo Buehler (OpenBSD) for a bugfix patch,
+ and Theo de Raadt (OpenBSD) for checking it.
+ * John Gardner for more than a dozen suggestions regarding HTML output.
+ * Mike Williams for teaching me how to use %%DocumentMedia and
+ setpagedevice in PostScript files.
+ * Werner Lemberg (groff) for feedback on mdoc(7) language changes.
+ * Colin Watson (man-db) for feedback on man-db semantics.
+ * Jason McIntyre (OpenBSD) for lots of feedback and suggestions
+ on diagnostic messages and on the documentation.
+ * Thomas Klausner (NetBSD) for suggesting two new style messages
+ and one new feature, for two bug reports, and for release testing.
+ * Leah Neukirchen (Void Linux) for suggesting a new style message,
+ five bug reports, and release testing.
+ * Anthony Bentley (OpenBSD) for reporting multiple bugs and missing
+ features.
+ * Paul Irofti (OpenBSD) and Nate Bargmann for suggesting new features.
+ * Michael Stapelberg (Debian) for bug reports and release testing.
+ * Christian Weisgerber, Jonathan Gray, Stuart Henderson,
+ Ted Unangst (OpenBSD), Takeshi Nakayama (NetBSD),
+ Anton Lazarov, Jakub Klinkovsky, Jan Stary, Jesper Wallin,
+ Will Backmam, and Wolfgang Mueller for bug reports.
+ * Sevan Janiyan (NetBSD) for additions to lib.in.
+ * George Brown for suggesting code simplifications.
+ * David Coppa, Igor Sobrado (OpenBSD), and Alexander Kuleshov
+ for documentation improvements.
+ * Laura Morales and Raf Czlonka for questions resulting in better
+ documentation.
+ * Yuri Pankov (illumos) for release testing.
+
Changes in version 1.14.3, released on August 5, 2017
--- BUG FIXES ---
diff --git a/TODO b/TODO
index 70371a0e9e5c..6df63ea3c79b 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
-* $Id: TODO,v 1.246 2017/07/24 11:15:12 schwarze Exp $
+* $Id: TODO,v 1.258 2018/08/06 14:16:30 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -38,6 +38,18 @@ are mere guesses, and some may be wrong.
--- missing roff features ----------------------------------------------
+- .nop prints its arguments as text,
+ see groff(7) for an example
+
+- .ft CB selects constant-width bold font
+ see groff_out(7) for examples
+
+- \*(.T prints the device being used,
+ see groff_char(7) for an example
+
+- \[charNN], \[charNNN] prints a single-byte codepoint
+ see groff_char(7) for examples
+
- .ad (adjust margins)
.ad l -- adjust left margin only (flush left)
.ad r -- adjust right margin only (flush right)
@@ -52,10 +64,6 @@ are mere guesses, and some may be wrong.
found by naddy@ in xloadimage(1)
loc ** exist *** algo * size * imp *
-- .nr third argument (auto-increment step size, requires \n+)
- found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
- 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
@@ -65,10 +73,6 @@ are mere guesses, and some may be wrong.
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
loc * exist ** algo ** size ** imp **
-- \n+ and \n- numerical register increment and decrement
- found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
- loc * exist * algo * size * imp **
-
- \w'' improve width measurements
would not be very useful without an expression parser, see below
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
@@ -87,9 +91,11 @@ are mere guesses, and some may be wrong.
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 *
+- check for missing roff escape sequences, implement those that are
+ trivial even if not usually appearing in manual pages, gracefully
+ ignore the non-trivial ones, document what they are supposed to do
+ and what mandoc does instead
+ loc * exist ** algo * size * imp *
--- missing mdoc features ----------------------------------------------
@@ -146,10 +152,6 @@ are mere guesses, and some may be wrong.
is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab."
but should give "ab ."
-- check whether it is correct that `D1' uses INDENT+1;
- does it need its own constant?
- loc * exist ** algo ** size * imp **
-
- prohibit `Nm' from having non-text HEAD children
(e.g., NetBSD mDNSShared/dns-sd.1)
(mdoc_html.c and mdoc_term.c `Nm' handlers can be slightly simplified)
@@ -170,6 +172,25 @@ are mere guesses, and some may be wrong.
uqs@ Thu, 2 Jun 2011 11:33:35 +0200
loc * exist ** algo *** size * imp **
+--- missing man features -----------------------------------------------
+
+- .SY and .YS,
+ used by many groff manual pages
+
+- preserve punctuation following .ME,
+ see ditroff(7) for an example
+
+- .TQ tagged paragraph continuation,
+ see groff_diff(7) for examples
+
+- groff_www(7) .MTO and .URL
+ These macros were used by the GNU grep(1) man page.
+ The groff_www(7) manual page itself uses them, too.
+ We should probably *not* add them to mandoc.
+ Just mentioning this here to keep track of the abuse.
+ Laura Morales <lauretas at mail dot com> 20 Apr 2018 07:33:02 +0200
+ loc ** exist * algo * size ** imp *
+
--- missing tbl features -----------------------------------------------
- the "s" layout column specifier is used for placement of data
@@ -177,6 +198,13 @@ are mere guesses, and some may be wrong.
synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400
loc * exist ** algo *** size * imp **
+- vertical centering in cells vertically spanned with ^
+ pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
+ loc * exist *** algo *** size ** imp *
+
+- support .ds requests inside tbl(7) code,
+ see tbl(1) for an example
+
- support mdoc(7) and man(7) macros inside tbl(7) code;
probably requires the parser reorg and letting tbl(7)
use roff_node such that macro sets can mix;
@@ -195,6 +223,18 @@ are mere guesses, and some may be wrong.
suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600
loc * exist ** algo * size * imp **
+- implement horizontal and vertical alignment in HTML output
+ pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
+ loc * exist * algo * size * imp ***
+
+- implement cell spanning in HTML output
+ pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
+ loc * exist * algo ** size ** imp **
+
+- implement table borders in HTML output
+ pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200
+ loc * exist * algo ** size ** imp **
+
--- missing eqn features -----------------------------------------------
- In a matrix, break the output line after each matrix line.
@@ -219,12 +259,15 @@ are mere guesses, and some may be wrong.
surrounded by blanks, not when it is part of an unquoted word.
Also, check whether there are more such cases (e.g., +?).
reported by bentley@ 20 Jun 2017 02:04:29 -0600
+ loc * exist ** algo ** size * imp *
- Primes, opprime, and '
bentley@ Thu, 13 Jul 2017 23:14:20 -0600
--- missing misc features ----------------------------------------------
+- man -ks 1,8 route; kn@ Jul 13, 2018 orally
+
- italic correction (\/) in PostScript mode
Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46
loc ** exist ** algo * size * imp *
@@ -298,6 +341,9 @@ are mere guesses, and some may be wrong.
* formatting issues: ugly output
************************************************************************
+- .UR can nest inside .TP,
+ see roff(7) for examples
+
- revisit empty in-line macros
look at the difference between "Em x Em ." and "Sq x Em ."
Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100
@@ -375,6 +421,17 @@ are mere guesses, and some may be wrong.
--- HTML issues --------------------------------------------------------
+- wrap Sh and Ss content into <div>
+ Laura Morales <lauretas at mail dot com> 21 Apr 2018 18:10:48 +0200
+ (Evaluate whether this is really useful and has no adverse
+ side effects before implementing; if it is possible,
+ it does seem cleaner.)
+ loc ** exist ** algo * size * imp ***
+
+- format ".IP *" etc. as <ul> rather than <dl>
+ https://github.com/Debian/debiman/issues/67
+ loc ** exist ** algo ** size * imp ***
+
- .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal
space, see for example random(3). Introduced in
http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92
@@ -471,6 +528,10 @@ are mere guesses, and some may be wrong.
* warning issues
************************************************************************
+- warn about duplicate .Sh/.Ss heads
+ gre(4): Rename duplicate sections 20 Apr 2018 15:27:33 +0200
+ loc * exist * algo * size * imp **
+
- style message about macros inside .Bd -literal and .Dl, in particular
font changing macros like .Cm, .Ar, .Fa (from the mdoclint TODO)
@@ -509,6 +570,10 @@ are mere guesses, and some may be wrong.
but just the overall format
loc ** exist ** algo *** size ** imp **
+- makewhatis -p complains about language subdirectories:
+ /usr/local/man//ru: Unknown directory part
+
+
************************************************************************
* documentation issues
************************************************************************
@@ -562,7 +627,7 @@ are mere guesses, and some may be wrong.
- Enable HTTP compression by detecting gzip encoding and filtering
output through libz.
- - Sandbox (see OpenSSH).
+ - Privilege separation (see OpenSSH).
- Enable caching support via HTTP 304 and If-Modified-Since.
- Have Mac OSX systems automatically disable -static compilation of the
CGI: -static isn't supported.
@@ -571,6 +636,16 @@ are mere guesses, and some may be wrong.
* to improve in the groff_mdoc(7) macros
************************************************************************
+- .Cd # arch1, arch2 in section 4 pages:
+ find better way to indicate multiple architectures, maybe:
+ allow .Dt vgafb 4 "macppc sparc64"
+ already shown as "Device Drivers Manual (macppc sparc64)"
+ for apropos, make that "vgafb(4) - macppc # sparc64" instead of "- all"
+ groff can be made to show multiple arches, too, but it is
+ tedious to do the string parsing in roff code...
+ jmc@ 23 Apr 2018 07:24:52 +0100 [man for vgafb(4)...]
+ loc ** exist ** algo * size * imp ***
+
- use uname(1) to set doc-default-operating-system at install time
tobimensch Mon, 1 Dec 2014 00:25:07 +0100
diff --git a/apropos.1 b/apropos.1
index 16cefbda375a..c0895a87e4c3 100644
--- a/apropos.1
+++ b/apropos.1
@@ -1,4 +1,4 @@
-.\" $Id: apropos.1,v 1.46 2017/07/04 23:40:01 schwarze Exp $
+.\" $Id: apropos.1,v 1.47 2018/02/23 18:54:02 schwarze Exp $
.\"
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 4 2017 $
+.Dd $Mdocdate: February 23 2018 $
.Dt APROPOS 1
.Os
.Sh NAME
@@ -328,6 +328,29 @@ Text production:
.It Li \&Ox Ta Ox No version reference
.It Li \&Dx Ta Dx No version reference
.El
+.Pp
+In general, macro keys are supposed to yield complete results without
+expecting the user to consider actual macro usage.
+For example, results include:
+.Pp
+.Bl -tag -width 3n -offset 3n -compact
+.It Li \&Fa
+function arguments appearing on
+.Ic \&Fn
+lines
+.It Li \&Fn
+fuction names marked up with
+.Ic \&Fo
+macros
+.It Li \&In
+include file names marked up with
+.Ic \&Fd
+macros
+.It Li \&Vt
+types appearing as function return types and
+.It \&
+types appearing in function arguments in the SYNOPSIS
+.El
.Sh ENVIRONMENT
.Bl -tag -width MANPAGER
.It Ev MANPAGER
diff --git a/cgi.c b/cgi.c
index 746c481ac524..8098352d6140 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/* $Id: cgi.c,v 1.156 2017/06/24 14:38:32 schwarze Exp $ */
+/* $Id: cgi.c,v 1.158 2018/05/29 20:32:45 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@usta.de>
@@ -356,6 +356,8 @@ resp_begin_html(int code, const char *msg, const char *file)
"<html>\n"
"<head>\n"
" <meta charset=\"UTF-8\"/>\n"
+ " <meta name=\"viewport\""
+ " content=\"width=device-width, initial-scale=1.0\">\n"
" <link rel=\"stylesheet\" href=\"%s/mandoc.css\""
" type=\"text/css\" media=\"all\">\n"
" <title>",
@@ -398,7 +400,7 @@ resp_searchform(const struct req *req, enum focus focus)
/* Write query input box. */
- printf(" <input type=\"text\" name=\"query\" value=\"");
+ printf(" <input type=\"search\" name=\"query\" value=\"");
if (req->q.query != NULL)
html_print(req->q.query);
printf( "\" size=\"40\"");
@@ -434,7 +436,7 @@ resp_searchform(const struct req *req, enum focus focus)
printf(" selected=\"selected\"");
puts(">All Architectures</option>");
for (i = 0; i < arch_MAX; i++) {
- printf(" <option value=\"%s\"", arch_names[i]);
+ printf(" <option");
if (NULL != req->q.arch &&
0 == strcmp(arch_names[i], req->q.arch))
printf(" selected=\"selected\"");
@@ -447,12 +449,10 @@ resp_searchform(const struct req *req, enum focus focus)
if (req->psz > 1) {
puts(" <select name=\"manpath\">");
for (i = 0; i < (int)req->psz; i++) {
- printf(" <option ");
+ printf(" <option");
if (strcmp(req->q.manpath, req->p[i]) == 0)
- printf("selected=\"selected\" ");
- printf("value=\"");
- html_print(req->p[i]);
- printf("\">");
+ printf(" selected=\"selected\"");
+ printf(">");
html_print(req->p[i]);
puts("</option>");
}
diff --git a/chars.c b/chars.c
index 039e6dc0909c..fb9ded8baef6 100644
--- a/chars.c
+++ b/chars.c
@@ -1,4 +1,4 @@
-/* $Id: chars.c,v 1.71 2017/06/14 20:57:07 schwarze Exp $ */
+/* $Id: chars.c,v 1.73 2017/08/23 13:01:29 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -70,17 +70,17 @@ static struct ln lines[] = {
/* Text markers. */
{ "ci", "O", 0x25cb },
{ "bu", "+\bo", 0x2022 },
- { "dd", "|\b=", 0x2021 },
- { "dg", "|\b-", 0x2020 },
+ { "dd", "<**>", 0x2021 },
+ { "dg", "<*>", 0x2020 },
{ "lz", "<>", 0x25ca },
{ "sq", "[]", 0x25a1 },
- { "ps", "<par>", 0x00b6 },
- { "sc", "<sec>", 0x00a7 },
+ { "ps", "<paragraph>", 0x00b6 },
+ { "sc", "<section>", 0x00a7 },
{ "lh", "<=", 0x261c },
{ "rh", "=>", 0x261e },
{ "at", "@", 0x0040 },
{ "sh", "#", 0x0023 },
- { "CR", "_|", 0x21b5 },
+ { "CR", "<cr>", 0x21b5 },
{ "OK", "\\/", 0x2713 },
{ "CL", "<club>", 0x2663 },
{ "SP", "<spade>", 0x2660 },
@@ -173,11 +173,11 @@ static struct ln lines[] = {
{ "OR", "v", 0x2228 },
{ "no", "~", 0x00ac },
{ "tno", "~", 0x00ac },
- { "te", "3", 0x2203 },
- { "fa", "-\bV", 0x2200 },
- { "st", "-)", 0x220b },
- { "tf", ".:.", 0x2234 },
- { "3d", ".:.", 0x2234 },
+ { "te", "<there\037exists>", 0x2203 },
+ { "fa", "<for\037all>", 0x2200 },
+ { "st", "<such\037that>", 0x220b },
+ { "tf", "<therefore>", 0x2234 },
+ { "3d", "<therefore>", 0x2234 },
{ "or", "|", 0x007c },
/* Mathematicals. */
@@ -193,8 +193,8 @@ static struct ln lines[] = {
{ "tmu", "x", 0x00d7 },
{ "c*", "O\bx", 0x2297 },
{ "c+", "O\b+", 0x2295 },
- { "di", "-:-", 0x00f7 },
- { "tdi", "-:-", 0x00f7 },
+ { "di", "/", 0x00f7 },
+ { "tdi", "/", 0x00f7 },
{ "f/", "/", 0x2044 },
{ "**", "*", 0x2217 },
{ "<=", "<=", 0x2264 },
@@ -210,38 +210,38 @@ static struct ln lines[] = {
{ "=~", "=~", 0x2245 },
{ "~~", "~~", 0x2248 },
{ "~=", "~=", 0x2248 },
- { "pt", "oc", 0x221d },
+ { "pt", "<proportional\037to>", 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 },
+ { "mo", "<element\037of>", 0x2208 },
+ { "nm", "<not\037element\037of>", 0x2209 },
+ { "sb", "<proper\037subset>", 0x2282 },
+ { "nb", "<not\037subset>", 0x2284 },
+ { "sp", "<proper\037superset>", 0x2283 },
+ { "nc", "<not\037superset>", 0x2285 },
+ { "ib", "<subset\037or\037equal>", 0x2286 },
+ { "ip", "<superset\037or\037equal>", 0x2287 },
+ { "ca", "<intersection>", 0x2229 },
+ { "cu", "<union>", 0x222a },
+ { "/_", "<angle>", 0x2220 },
+ { "pp", "<perpendicular>", 0x22a5 },
+ { "is", "<integral>", 0x222b },
+ { "integral", "<integral>", 0x222b },
+ { "sum", "<sum>", 0x2211 },
+ { "product", "<product>", 0x220f },
+ { "coproduct", "<coproduct>", 0x2210 },
+ { "gr", "<nabla>", 0x2207 },
+ { "sr", "<sqrt>", 0x221a },
+ { "sqrt", "<sqrt>", 0x221a },
{ "lc", "|~", 0x2308 },
{ "rc", "~|", 0x2309 },
{ "lf", "|_", 0x230a },
{ "rf", "_|", 0x230b },
- { "if", "oo", 0x221e },
- { "Ah", "N", 0x2135 },
- { "Im", "I", 0x2111 },
- { "Re", "R", 0x211c },
+ { "if", "<infinity>", 0x221e },
+ { "Ah", "<Aleph>", 0x2135 },
+ { "Im", "<Im>", 0x2111 },
+ { "Re", "<Re>", 0x211c },
{ "wp", "P", 0x2118 },
- { "pd", "a", 0x2202 },
+ { "pd", "<del>", 0x2202 },
{ "-h", "/h", 0x210f },
{ "hbar", "/h", 0x210f },
{ "12", "1/2", 0x00bd },
@@ -251,9 +251,9 @@ static struct ln lines[] = {
{ "38", "3/8", 0x215C },
{ "58", "5/8", 0x215D },
{ "78", "7/8", 0x215E },
- { "S1", "1", 0x00B9 },
- { "S2", "2", 0x00B2 },
- { "S3", "3", 0x00B3 },
+ { "S1", "^1", 0x00B9 },
+ { "S2", "^2", 0x00B2 },
+ { "S3", "^3", 0x00B3 },
/* Ligatures. */
{ "ff", "ff", 0xfb00 },
@@ -346,8 +346,8 @@ static struct ln lines[] = {
{ "oa", "o\ba", 0x00e5 },
/* Special letters. */
- { "-D", "-\bD", 0x00d0 },
- { "Sd", "d", 0x00f0 },
+ { "-D", "Dh", 0x00d0 },
+ { "Sd", "dh", 0x00f0 },
{ "TP", "Th", 0x00de },
{ "Tp", "th", 0x00fe },
{ ".i", "i", 0x0131 },
@@ -364,68 +364,68 @@ static struct ln lines[] = {
{ "Fn", ",\bf", 0x0192 },
/* Units. */
- { "de", "<deg>", 0x00b0 },
- { "%0", "%o", 0x2030 },
+ { "de", "<degree>", 0x00b0 },
+ { "%0", "<permille>", 0x2030 },
{ "fm", "\'", 0x2032 },
{ "sd", "''", 0x2033 },
- { "mc", ",\bu", 0x00b5 },
+ { "mc", "<micro>", 0x00b5 },
{ "Of", "_\ba", 0x00aa },
{ "Om", "_\bo", 0x00ba },
/* Greek characters. */
{ "*A", "A", 0x0391 },
{ "*B", "B", 0x0392 },
- { "*G", "G", 0x0393 },
- { "*D", "_\b/_\b\\", 0x0394 },
+ { "*G", "<Gamma>", 0x0393 },
+ { "*D", "<Delta>", 0x0394 },
{ "*E", "E", 0x0395 },
{ "*Z", "Z", 0x0396 },
{ "*Y", "H", 0x0397 },
- { "*H", "-\bO", 0x0398 },
+ { "*H", "<Theta>", 0x0398 },
{ "*I", "I", 0x0399 },
{ "*K", "K", 0x039a },
- { "*L", "/\\", 0x039b },
+ { "*L", "<Lambda>", 0x039b },
{ "*M", "M", 0x039c },
{ "*N", "N", 0x039d },
- { "*C", "_\bH", 0x039e },
+ { "*C", "<Xi>", 0x039e },
{ "*O", "O", 0x039f },
- { "*P", "TT", 0x03a0 },
+ { "*P", "<Pi>", 0x03a0 },
{ "*R", "P", 0x03a1 },
- { "*S", "S", 0x03a3 },
+ { "*S", "<Sigma>", 0x03a3 },
{ "*T", "T", 0x03a4 },
{ "*U", "Y", 0x03a5 },
- { "*F", "I\bO", 0x03a6 },
+ { "*F", "<Phi>", 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 },
+ { "*Q", "<Psi>", 0x03a8 },
+ { "*W", "<Omega>", 0x03a9 },
+ { "*a", "<alpha>", 0x03b1 },
+ { "*b", "<beta>", 0x03b2 },
+ { "*g", "<gamma>", 0x03b3 },
+ { "*d", "<delta>", 0x03b4 },
+ { "*e", "<epsilon>", 0x03b5 },
+ { "*z", "<zeta>", 0x03b6 },
+ { "*y", "<eta>", 0x03b7 },
+ { "*h", "<theta>", 0x03b8 },
+ { "*i", "<iota>", 0x03b9 },
+ { "*k", "<kappa>", 0x03ba },
+ { "*l", "<lambda>", 0x03bb },
+ { "*m", "<mu>", 0x03bc },
+ { "*n", "<nu>", 0x03bd },
+ { "*c", "<xi>", 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 },
+ { "*p", "<pi>", 0x03c0 },
+ { "*r", "<rho>", 0x03c1 },
+ { "*s", "<sigma>", 0x03c3 },
+ { "*t", "<tau>", 0x03c4 },
+ { "*u", "<upsilon>", 0x03c5 },
+ { "*f", "<phi>", 0x03d5 },
+ { "*x", "<chi>", 0x03c7 },
+ { "*q", "<psi>", 0x03c8 },
+ { "*w", "<omega>", 0x03c9 },
+ { "+h", "<theta>", 0x03d1 },
+ { "+f", "<phi>", 0x03c6 },
+ { "+p", "<pi>", 0x03d6 },
+ { "+e", "<epsilon>", 0x03f5 },
+ { "ts", "<sigma>", 0x03c2 },
};
static struct ohash mchars;
diff --git a/compat_strndup.c b/compat_strndup.c
new file mode 100644
index 000000000000..5e127364f5c8
--- /dev/null
+++ b/compat_strndup.c
@@ -0,0 +1,50 @@
+#include "config.h"
+
+#if HAVE_STRNDUP
+
+int dummy;
+
+#else
+
+/* $Id: compat_strndup.c,v 1.1 2018/02/27 11:16:23 schwarze Exp $ */
+/* OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp */
+/*
+ * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+char *
+strndup(const char *str, size_t maxlen)
+{
+ char *copy;
+ size_t len;
+
+ for (len = 0; len < maxlen && str[len] != '\0'; len++)
+ continue;
+
+ copy = malloc(len + 1);
+ if (copy != NULL) {
+ (void)memcpy(copy, str, len);
+ copy[len] = '\0';
+ }
+
+ return copy;
+}
+
+#endif
diff --git a/configure b/configure
index f9416ce7399d..1ccc37dc0cdc 100755
--- a/configure
+++ b/configure
@@ -1,8 +1,8 @@
#!/bin/sh
#
-# $Id: configure,v 1.64 2017/07/01 09:47:30 schwarze Exp $
+# $Id: configure,v 1.66 2018/07/31 15:34:00 schwarze Exp $
#
-# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
+# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -27,7 +27,7 @@ set -e
# 3: config.log
exec 3> config.log
-echo "config.log: writing..."
+echo "file config.log: writing..."
# --- default settings -------------------------------------------------
# Initialize all variables here,
@@ -41,14 +41,13 @@ OSNAME=
UTF8_LOCALE=
CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | env -i make -sf -`
-CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings"
-CFLAGS="${CFLAGS} -Wno-unused-parameter"
+CFLAGS=
LDADD=
LDFLAGS=
LD_NANOSLEEP=
LD_OHASH=
LD_RECVMSG=
-STATIC="-static"
+STATIC=
BUILD_CGI=0
BUILD_CATMAN=0
@@ -83,6 +82,7 @@ HAVE_STRCASESTR=
HAVE_STRINGLIST=
HAVE_STRLCAT=
HAVE_STRLCPY=
+HAVE_STRNDUP=
HAVE_STRPTIME=
HAVE_STRSEP=
HAVE_STRTONUM=
@@ -126,27 +126,25 @@ LN="ln -f"
# --- manual settings from configure.local -----------------------------
if [ -r ./configure.local ]; then
- echo "configure.local: reading..." 1>&2
- echo "configure.local: reading..." 1>&3
+ echo "file configure.local: reading..." 1>&2
+ echo "file configure.local: reading..." 1>&3
cat ./configure.local 1>&3
. ./configure.local
else
- echo "configure.local: no (fully automatic configuration)" 1>&2
- echo "configure.local: no (fully automatic configuration)" 1>&3
+ echo "file configure.local: no (fully automatic configuration)" 1>&2
+ echo "file configure.local: no (fully automatic configuration)" 1>&3
fi
echo 1>&3
-# --- tests for config.h ----------------------------------------------
-
-COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
+# --- tests functions --------------------------------------------------
# Check whether this HAVE_ setting is manually overridden.
# If yes, use the override, if no, do not decide anything yet.
-# Arguments: lower-case test name, manual value
+# Arguments: test file name, test var name, manual value
ismanual() {
[ -z "${3}" ] && return 1
- echo "${1}: manual (HAVE_${2}=${3})" 1>&2
- echo "${1}: manual (HAVE_${2}=${3})" 1>&3
+ echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&2
+ echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&3
echo 1>&3
return 0
}
@@ -154,31 +152,33 @@ ismanual() {
# Run a single autoconfiguration test.
# In case of success, enable the feature.
# In case of failure, do not decide anything yet.
-# Arguments: lower-case test name, upper-case test name, additional CFLAGS
+# Arguments: test file name, test var name, additional CFLAGS
singletest() {
cat 1>&3 << __HEREDOC__
-${1}${3}: testing...
+testing ${1}${3} ...
${COMP} -o test-${1} test-${1}.c ${3}
__HEREDOC__
if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} 1>&3 2>&3
then
- echo "${1}${3}: ${CC} succeeded" 1>&3
+ echo "partial result of ${1}${3}: ${CC} succeeded" 1>&3
else
- echo "${1}${3}: ${CC} failed with $?" 1>&3
+ echo "result of ${1}${3}: ${CC} failed with exit status $?" 1>&3
+ echo "result of compiling ${1}${3}: no" 1>&3
echo 1>&3
return 1
fi
if ./test-${1} 1>&3 2>&3; then
- echo "${1}${3}: yes" 1>&2
- echo "${1}${3}: yes" 1>&3
+ echo "tested ${1}${3}: yes" 1>&2
+ echo "result of running ${1}${3}: yes" 1>&3
echo 1>&3
eval HAVE_${2}=1
rm "test-${1}"
return 0
else
- echo "${1}${3}: execution failed with $?" 1>&3
+ echo "result of ${1}${3}: execution failed with exit status $?" 1>&3
+ echo "result of running ${1}${3}: no" 1>&3
echo 1>&3
rm "test-${1}"
return 1
@@ -187,12 +187,12 @@ __HEREDOC__
# Run a complete autoconfiguration test, including the check for
# a manual override and disabling the feature on failure.
-# Arguments: lower case name, upper case name, additional CFLAGS
+# Arguments: test file name, test var name, additional CFLAGS
runtest() {
eval _manual=\${HAVE_${2}}
ismanual "${1}" "${2}" "${_manual}" && return 0
singletest "${1}" "${2}" "${3}" && return 0
- echo "${1}${3}: no" 1>&2
+ echo "tested ${1}${3}: no" 1>&2
eval HAVE_${2}=0
return 1
}
@@ -201,18 +201,54 @@ runtest() {
get_locale() {
[ -n "${HAVE_WCHAR}" ] && [ "${HAVE_WCHAR}" -eq 0 ] && return 0
ismanual UTF8_LOCALE UTF8_LOCALE "$UTF8_LOCALE" && return 0
- echo "UTF8_LOCALE: testing..." 1>&3
+ echo "testing UTF8_LOCALE ..." 1>&3
UTF8_LOCALE=`locale -a | grep -i '^en_US\.UTF-*8$' | head -n 1`
if [ -z "${UTF8_LOCALE}" ]; then
UTF8_LOCALE=`locale -a | grep -i '\.UTF-*8' | head -n 1`
[ -n "${UTF8_LOCALE}" ] || return 1
fi
- echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&2
- echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&3
+ echo "selected UTF8_LOCALE=${UTF8_LOCALE}" 1>&2
+ echo "selected UTF8_LOCALE=${UTF8_LOCALE}" 1>&3
echo 1>&3
return 0;
}
+# --- compiler options -------------------------------------------------
+
+if [ -n "${CFLAGS}" ]; then
+ COMP="${CC} ${CFLAGS}"
+ echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&2
+ echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&3
+ echo 1>&3
+else
+ CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes"
+ CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter"
+ COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
+ echo -n "tested ${CC} -W: " 1>&2
+ echo -n "testing ${CC} -W: " 1>&3
+ runtest noop WFLAG || true
+ if [ "${HAVE_WFLAG}" -eq 0 ]; then
+ CFLAGS="-g"
+ COMP="${CC} ${CFLAGS}"
+ fi
+ echo "selected CFLAGS=\"${CFLAGS}\"" 1>&2
+ echo "selected CFLAGS=\"${CFLAGS}\"" 1>&3
+ echo 1>&3
+fi
+
+if [ -n "${STATIC}" ]; then
+ echo "selected STATIC=\"${STATIC}\" (manual)" 1>&2
+ echo "selected STATIC=\"${STATIC}\" (manual)" 1>&3
+ echo 1>&3
+else
+ runtest noop STATIC -static || true
+ [ ${HAVE_STATIC} -eq 0 ] || STATIC="-static"
+ echo "selected STATIC=\"${STATIC}\"" 1>&2
+ echo "selected STATIC=\"${STATIC}\"" 1>&3
+ echo 1>&3
+fi
+
+# --- tests for config.h ----------------------------------------------
# --- library functions ---
runtest dirent-namlen DIRENT_NAMLEN || true
@@ -238,6 +274,7 @@ runtest strcasestr STRCASESTR || true
runtest stringlist STRINGLIST || true
runtest strlcat STRLCAT || true
runtest strlcpy STRLCPY || true
+runtest strndup STRNDUP || true
runtest strptime STRPTIME || true
runtest strsep STRSEP || true
runtest strtonum STRTONUM || true
@@ -264,8 +301,9 @@ if get_locale; then
runtest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true
else
HAVE_WCHAR=0
- echo "wchar: no (no UTF8_LOCALE)" 1>&2
- echo "wchar: no (no UTF8_LOCALE)" 1>&3
+ echo "tested wchar: no (no UTF8_LOCALE)" 1>&2
+ echo "tested wchar: no (no UTF8_LOCALE)" 1>&3
+ echo 1>&3
fi
# --- nanosleep ---
@@ -328,8 +366,8 @@ fi
# --- LDADD ---
LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_RECVMSG} ${LD_OHASH} -lz"
-echo "LDADD=\"${LDADD}\"" 1>&2
-echo "LDADD=\"${LDADD}\"" 1>&3
+echo "selected LDADD=\"${LDADD}\"" 1>&2
+echo "selected LDADD=\"${LDADD}\"" 1>&3
echo 1>&3
# --- write config.h ---
@@ -353,7 +391,8 @@ __HEREDOC__
[ ${HAVE_GETLINE} -eq 0 -o \
${HAVE_REALLOCARRAY} -eq 0 -o ${HAVE_RECALLOCARRAY} -eq 0 -o \
- ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \
+ ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 -o \
+ ${HAVE_STRNDUP} -eq 0 ] \
&& echo "#include <sys/types.h>"
[ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>"
[ ${HAVE_GETLINE} -eq 0 ] && echo "#include <stdio.h>"
@@ -396,6 +435,7 @@ cat << __HEREDOC__
#define HAVE_STRINGLIST ${HAVE_STRINGLIST}
#define HAVE_STRLCAT ${HAVE_STRLCAT}
#define HAVE_STRLCPY ${HAVE_STRLCPY}
+#define HAVE_STRNDUP ${HAVE_STRNDUP}
#define HAVE_STRPTIME ${HAVE_STRPTIME}
#define HAVE_STRSEP ${HAVE_STRSEP}
#define HAVE_STRTONUM ${HAVE_STRTONUM}
@@ -452,6 +492,9 @@ fi
[ ${HAVE_STRLCPY} -eq 0 ] && \
echo "extern size_t strlcpy(char *, const char *, size_t);"
+[ ${HAVE_STRNDUP} -eq 0 ] && \
+ echo "extern char *strndup(const char *, size_t);"
+
[ ${HAVE_STRSEP} -eq 0 ] && \
echo "extern char *strsep(char **, const char *);"
@@ -461,8 +504,8 @@ fi
[ ${HAVE_VASPRINTF} -eq 0 ] && \
echo "extern int vasprintf(char **, const char *, va_list);"
-echo "config.h: written" 1>&2
-echo "config.h: written" 1>&3
+echo "file config.h: written" 1>&2
+echo "file config.h: written" 1>&3
# --- tests for Makefile.local -----------------------------------------
@@ -531,7 +574,7 @@ INSTALL_DATA = ${INSTALL_DATA}
LN = ${LN}
__HEREDOC__
-echo "Makefile.local: written" 1>&2
-echo "Makefile.local: written" 1>&3
+echo "file Makefile.local: written" 1>&2
+echo "file Makefile.local: written" 1>&3
exit 0
diff --git a/configure.local.example b/configure.local.example
index 4a583ad0bab2..82fc2a2c28e5 100644
--- a/configure.local.example
+++ b/configure.local.example
@@ -1,6 +1,6 @@
-# $Id: configure.local.example,v 1.33 2017/07/20 16:24:53 schwarze Exp $
+# $Id: configure.local.example,v 1.34 2018/07/31 15:34:00 schwarze Exp $
#
-# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
+# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -77,7 +77,7 @@ MANPATH_BASE="/usr/share/man:/usr/X11R6/man"
# If you do not want uname(3) to be called but instead want a fixed
# string to be used, use the following line:
-OSNAME="OpenBSD 6.0"
+OSNAME="OpenBSD 6.3"
# The following installation directories are used.
# It is possible to set only one or a few of these variables,
@@ -100,6 +100,7 @@ BIN_FROM_SBIN="../bin"
# 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.
@@ -148,13 +149,6 @@ LN="ln -sf" # default is "ln -f"
LD_OHASH="-lutil"
-# When library autodetection decides to use -L/usr/local/lib,
-# -I/usr/local/include is automatically added to CFLAGS.
-# If you manually set LD_OHASH to something including -L/usr/local/lib,
-# chances are you will also need the following line:
-
-CFLAGS="${CFLAGS} -I/usr/local/include"
-
# Some platforms may need an additional linker flag for nanosleep(2).
# If none is needed or it is -lrt, it is autodetected.
# Otherwise, set the following variable.
@@ -222,16 +216,22 @@ BUILD_CGI=1
# The remaining settings in this section are only relevant if BUILD_CGI
# is enabled. Otherwise, they have no effect either way.
-# By default, man.cgi(8) is linked statically.
-# Some systems do not support static linking, for example Mac OS X.
-# In that case, use the following line:
+# By default, man.cgi(8) is linked statically if the compiler supports
+# the -static option. If automatic detection fails, you can force
+# static linking of man.cgi(8).
-STATIC=
+STATIC="-static"
-# Some systems, for example Linux, require -pthread for static linking:
+# Some systems may require -pthread for static linking:
STATIC="-static -pthread"
+# If static linking works in general but not with additional libraries
+# like -lrt or -lz, you can force dynamic linking. This may for
+# example be required on SunOS 5.9.
+
+STATIC=" "
+
# Some directories.
# This works just like PREFIX, see above.
@@ -263,15 +263,19 @@ BINM_CATMAN=mcatman # default is "catman"
CC=cc
-# IBM AIX may need:
+# Because the system compiler may not provide <stdint.h>,
+# SunOS 5.9 may need:
-CC=xlc
+CC=gcc
-# The default compiler flags are:
+# IBM AIX may need:
-CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings"
+CC=xlc
-# IBM AIX xlc does not support -W; in that case, please use:
+# Normally, leave CFLAGS unset. In that case, -g will automatically
+# be used, and various -W options will be added if the compiler
+# supports them. If you define CFLAGS manually, it will be used
+# unchanged, and nothing will be added.
CFLAGS="-g"
diff --git a/eqn.7 b/eqn.7
index 33d509bd13e3..244903c56fe9 100644
--- a/eqn.7
+++ b/eqn.7
@@ -1,4 +1,4 @@
-.\" $Id: eqn.7,v 1.36 2017/07/20 11:07:27 schwarze Exp $
+.\" $Id: eqn.7,v 1.37 2017/09/04 10:35:27 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: July 20 2017 $
+.Dd $Mdocdate: September 4 2017 $
.Dt EQN 7
.Os
.Sh NAME
@@ -83,7 +83,7 @@ box : text
| \(dqsqrt\(dq box
| box pos box
| box mark
- | \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq ]*
+ | \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq]* \(dq}\(dq
| pile \(dq{\(dq list \(dq}\(dq
| font box
| \(dqsize\(dq text box
diff --git a/eqn_term.c b/eqn_term.c
index 08f4a993eca4..669c3c56cff7 100644
--- a/eqn_term.c
+++ b/eqn_term.c
@@ -1,4 +1,4 @@
-/* $Id: eqn_term.c,v 1.13 2017/07/08 14:51:04 schwarze Exp $ */
+/* $Id: eqn_term.c,v 1.17 2017/08/23 21:56:20 schwarze Exp $ */
/*
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <assert.h>
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -51,6 +52,7 @@ static void
eqn_box(struct termp *p, const struct eqn_box *bp)
{
const struct eqn_box *child;
+ const char *cp;
int delim;
/* Delimiters around this box? */
@@ -67,7 +69,16 @@ eqn_box(struct termp *p, const struct eqn_box *bp)
((bp->parent->type == EQN_LIST && bp->expectargs == 1) ||
(bp->parent->type == EQN_SUBEXPR &&
bp->pos != EQNPOS_SQRT)))))) {
- if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL)
+ if ((bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) ||
+ (bp->type == EQN_LIST &&
+ bp->first != NULL &&
+ bp->first->type != EQN_PILE &&
+ bp->first->type != EQN_MATRIX &&
+ bp->prev != NULL &&
+ (bp->prev->type == EQN_LIST ||
+ (bp->prev->type == EQN_TEXT &&
+ (*bp->prev->text == '\\' ||
+ isalpha((unsigned char)*bp->prev->text))))))
p->flags |= TERMP_NOSPACE;
term_word(p, bp->left != NULL ? bp->left : "(");
p->flags |= TERMP_NOSPACE;
@@ -80,8 +91,17 @@ eqn_box(struct termp *p, const struct eqn_box *bp)
if (bp->font != EQNFONT_NONE)
term_fontpush(p, fontmap[(int)bp->font]);
- if (bp->text != NULL)
+ if (bp->text != NULL) {
+ if (strchr("!\"'),.:;?]}", *bp->text) != NULL)
+ p->flags |= TERMP_NOSPACE;
term_word(p, bp->text);
+ if ((cp = strchr(bp->text, '\0')) > bp->text &&
+ (strchr("\"'([{", cp[-1]) != NULL ||
+ (bp->prev == NULL && (cp[-1] == '-' ||
+ (cp >= bp->text + 5 &&
+ strcmp(cp - 5, "\\[mi]") == 0)))))
+ p->flags |= TERMP_NOSPACE;
+ }
/* Special box types. */
@@ -98,9 +118,9 @@ eqn_box(struct termp *p, const struct eqn_box *bp)
term_word(p, bp->pos == EQNPOS_OVER ? "/" :
(bp->pos == EQNPOS_SUP ||
bp->pos == EQNPOS_TO) ? "^" : "_");
- p->flags |= TERMP_NOSPACE;
child = child->next;
if (child != NULL) {
+ p->flags |= TERMP_NOSPACE;
eqn_box(p, child);
if (bp->pos == EQNPOS_FROMTO ||
bp->pos == EQNPOS_SUBSUP) {
diff --git a/gmdiff b/gmdiff
index d5b1f2a76f01..65cf353daa0c 100644
--- a/gmdiff
+++ b/gmdiff
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+# Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,7 @@ if [ `id -u` -eq 0 ]; then
fi
if [ $# -eq 0 ]; then
- echo "usage: $0 [-h] manual_source_file ..."
+ echo "usage: $0 [-h|-u] manual_source_file ..."
exit 1
fi
@@ -28,22 +28,25 @@ if [ "X$1" = "X-h" ]; then
export PATH="/usr/local/heirloom-doctools/bin:$PATH"
EQN="neqn"
ROFF="nroff"
- MOPT="-Omdoc $MOPT"
+ MOPT="-Ios=BSD -Tascii $MOPT"
+ COLPIPE="col -b"
elif [ "X$1" = "X-u" ]; then
shift
ROFF="groff -ket -ww -Tutf8 -P -c"
- MOPT="-Werror -Tutf8 $MOPT"
+ MOPT="-Ios=OpenBSD -Wall -Tutf8 $MOPT"
+ COLPIPE="cat"
else
- ROFF="groff -et -ww -Tascii -P -c"
- MOPT="-Werror -Tascii $MOPT"
+ ROFF="groff -et -ww -mtty-char -Tascii -P -c"
+ MOPT="-Ios=OpenBSD -Wall -Tascii $MOPT"
+ COLPIPE="cat"
fi
while [ -n "$1" ]; do
file=$1
shift
echo " ========== $file ========== "
- $ROFF -mandoc $file 2> /tmp/roff.err > /tmp/roff.out
- ${MANDOC:=mandoc} -Ios=OpenBSD $MOPT $file \
+ $ROFF -mandoc $file | $COLPIPE 2> /tmp/roff.err > /tmp/roff.out
+ ${MANDOC:=mandoc} $MOPT $file | $COLPIPE \
2> /tmp/mandoc.err > /tmp/mandoc.out
for i in roff mandoc; do
[ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err
diff --git a/html.c b/html.c
index fc55e881b784..70935dcd57e4 100644
--- a/html.c
+++ b/html.c
@@ -1,7 +1,7 @@
-/* $Id: html.c,v 1.219 2017/07/15 17:57:51 schwarze Exp $ */
+/* $Id: html.c,v 1.238 2018/06/25 16:54:59 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -22,6 +22,7 @@
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -29,6 +30,7 @@
#include <unistd.h>
#include "mandoc_aux.h"
+#include "mandoc_ohash.h"
#include "mandoc.h"
#include "roff.h"
#include "out.h"
@@ -59,6 +61,7 @@ static const struct htmldata htmltags[TAG_MAX] = {
{"meta", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
{"title", HTML_NLAROUND},
{"div", HTML_NLAROUND},
+ {"div", 0},
{"h1", HTML_NLAROUND},
{"h2", HTML_NLAROUND},
{"span", 0},
@@ -66,8 +69,6 @@ static const struct htmldata htmltags[TAG_MAX] = {
{"br", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
{"a", 0},
{"table", HTML_NLALL | HTML_INDENT},
- {"colgroup", HTML_NLALL | HTML_INDENT},
- {"col", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},
{"tr", HTML_NLALL | HTML_INDENT},
{"td", HTML_NLAROUND},
{"li", HTML_NLAROUND | HTML_INDENT},
@@ -103,20 +104,9 @@ static const struct htmldata htmltags[TAG_MAX] = {
{"mover", 0},
};
-static const char *const roffscales[SCALE_MAX] = {
- "cm", /* SCALE_CM */
- "in", /* SCALE_IN */
- "pc", /* SCALE_PC */
- "pt", /* SCALE_PT */
- "em", /* SCALE_EM */
- "em", /* SCALE_MM */
- "ex", /* SCALE_EN */
- "ex", /* SCALE_BU */
- "em", /* SCALE_VS */
- "ex", /* SCALE_FS */
-};
+/* Avoid duplicate HTML id= attributes. */
+static struct ohash id_unique;
-static void a2width(const char *, struct roffsu *);
static void print_byte(struct html *, char);
static void print_endword(struct html *);
static void print_indent(struct html *);
@@ -143,6 +133,8 @@ html_alloc(const struct manoutput *outopts)
if (outopts->fragment)
h->oflags |= HTML_FRAGMENT;
+ mandoc_ohash_init(&id_unique, 4, 0);
+
return h;
}
@@ -151,15 +143,22 @@ html_free(void *p)
{
struct tag *tag;
struct html *h;
+ char *cp;
+ unsigned int slot;
h = (struct html *)p;
-
while ((tag = h->tag) != NULL) {
h->tag = tag->next;
free(tag);
}
-
free(h);
+
+ cp = ohash_first(&id_unique, &slot);
+ while (cp != NULL) {
+ free(cp);
+ cp = ohash_next(&id_unique, &slot);
+ }
+ ohash_delete(&id_unique);
}
void
@@ -168,9 +167,14 @@ print_gen_head(struct html *h)
struct tag *t;
print_otag(h, TAG_META, "?", "charset", "utf-8");
+ if (h->style != NULL) {
+ print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet",
+ h->style, "type", "text/css", "media", "all");
+ return;
+ }
/*
- * Print a default style-sheet.
+ * Print a minimal embedded style sheet.
*/
t = print_otag(h, TAG_STYLE, "");
@@ -181,11 +185,23 @@ print_gen_head(struct html *h)
print_text(h, "td.head-vol { text-align: center; }");
print_endline(h);
print_text(h, "div.Pp { margin: 1ex 0ex; }");
+ print_endline(h);
+ print_text(h, "div.Nd, div.Bf, div.Op { display: inline; }");
+ print_endline(h);
+ print_text(h, "span.Pa, span.Ad { font-style: italic; }");
+ print_endline(h);
+ print_text(h, "span.Ms { font-weight: bold; }");
+ print_endline(h);
+ print_text(h, "dl.Bl-diag ");
+ print_byte(h, '>');
+ print_text(h, " dt { font-weight: bold; }");
+ print_endline(h);
+ print_text(h, "code.Nm, code.Fl, code.Cm, code.Ic, "
+ "code.In, code.Fd, code.Fn,");
+ print_endline(h);
+ print_text(h, "code.Cd { font-weight: bold; "
+ "font-family: inherit; }");
print_tagq(h, t);
-
- if (h->style)
- print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet",
- h->style, "type", "text/css", "media", "all");
}
static void
@@ -239,10 +255,12 @@ print_metaf(struct html *h, enum mandoc_esc deco)
}
char *
-html_make_id(const struct roff_node *n)
+html_make_id(const struct roff_node *n, int unique)
{
const struct roff_node *nch;
- char *buf, *cp;
+ char *buf, *bufs, *cp;
+ unsigned int slot;
+ int suffix;
for (nch = n->child; nch != NULL; nch = nch->next)
if (nch->type != ROFFT_TEXT)
@@ -250,65 +268,46 @@ html_make_id(const struct roff_node *n)
buf = NULL;
deroff(&buf, n);
+ if (buf == NULL)
+ return NULL;
- /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
+ /*
+ * In ID attributes, only use ASCII characters that are
+ * permitted in URL-fragment strings according to the
+ * explicit list at:
+ * https://url.spec.whatwg.org/#url-fragment-string
+ */
for (cp = buf; *cp != '\0'; cp++)
- if (*cp == ' ')
+ if (isalnum((unsigned char)*cp) == 0 &&
+ strchr("!$&'()*+,-./:;=?@_~", *cp) == NULL)
*cp = '_';
- return buf;
-}
-
-int
-html_strlen(const char *cp)
-{
- size_t rsz;
- int skip, sz;
-
- /*
- * Account for escaped sequences within string length
- * calculations. This follows the logic in term_strlen() as we
- * must calculate the width of produced strings.
- * Assume that characters are always width of "1". This is
- * hacky, but it gets the job done for approximation of widths.
- */
-
- sz = 0;
- skip = 0;
- while (1) {
- rsz = strcspn(cp, "\\");
- if (rsz) {
- cp += rsz;
- if (skip) {
- skip = 0;
- rsz--;
+ if (unique == 0)
+ return buf;
+
+ /* Avoid duplicate HTML id= attributes. */
+
+ bufs = NULL;
+ suffix = 1;
+ slot = ohash_qlookup(&id_unique, buf);
+ cp = ohash_find(&id_unique, slot);
+ if (cp != NULL) {
+ while (cp != NULL) {
+ free(bufs);
+ if (++suffix > 127) {
+ free(buf);
+ return NULL;
}
- sz += rsz;
- }
- if ('\0' == *cp)
- break;
- cp++;
- switch (mandoc_escape(&cp, NULL, NULL)) {
- case ESCAPE_ERROR:
- return sz;
- case ESCAPE_UNICODE:
- case ESCAPE_NUMBERED:
- case ESCAPE_SPECIAL:
- case ESCAPE_OVERSTRIKE:
- if (skip)
- skip = 0;
- else
- sz++;
- break;
- case ESCAPE_SKIPCHAR:
- skip = 1;
- break;
- default:
- break;
+ mandoc_asprintf(&bufs, "%s_%d", buf, suffix);
+ slot = ohash_qlookup(&id_unique, bufs);
+ cp = ohash_find(&id_unique, slot);
}
+ free(buf);
+ buf = bufs;
}
- return sz;
+ ohash_insert(&id_unique, slot, buf);
+ return buf;
}
static int
@@ -490,13 +489,10 @@ struct tag *
print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
{
va_list ap;
- struct roffsu mysu, *su;
- char numbuf[16];
struct tag *t;
const char *attr;
char *arg1, *arg2;
- double v;
- int i, have_style, tflags;
+ int tflags;
tflags = htmltags[tag].flags;
@@ -536,17 +532,12 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
va_start(ap, fmt);
- have_style = 0;
while (*fmt != '\0') {
- if (*fmt == 's') {
- have_style = 1;
- fmt++;
- break;
- }
- /* Parse a non-style attribute and its arguments. */
+ /* Parse attributes and arguments. */
arg1 = va_arg(ap, char *);
+ arg2 = NULL;
switch (*fmt++) {
case 'c':
attr = "class";
@@ -557,6 +548,10 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
case 'i':
attr = "id";
break;
+ case 's':
+ attr = "style";
+ arg2 = va_arg(ap, char *);
+ break;
case '?':
attr = arg1;
arg1 = va_arg(ap, char *);
@@ -564,13 +559,12 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
default:
abort();
}
- arg2 = NULL;
if (*fmt == 'M')
arg2 = va_arg(ap, char *);
if (arg1 == NULL)
continue;
- /* Print the non-style attributes. */
+ /* Print the attributes. */
print_byte(h, ' ');
print_word(h, attr);
@@ -597,114 +591,19 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
fmt++;
break;
default:
- print_encode(h, arg1, NULL, 1);
- break;
- }
- print_byte(h, '"');
- }
-
- /* Print out styles. */
-
- while (*fmt != '\0') {
- arg1 = NULL;
- su = NULL;
-
- /* First letter: input argument type. */
-
- switch (*fmt++) {
- case 'h':
- i = va_arg(ap, int);
- su = &mysu;
- SCALE_HS_INIT(su, i);
- break;
- case 's':
- arg1 = va_arg(ap, char *);
- break;
- case 'u':
- su = va_arg(ap, struct roffsu *);
- break;
- case 'w':
- if ((arg2 = va_arg(ap, char *)) != NULL) {
- su = &mysu;
- a2width(arg2, su);
- }
- if (*fmt == '*') {
- if (su != NULL && su->unit == SCALE_EN &&
- su->scale > 5.9 && su->scale < 6.1)
- su = NULL;
- fmt++;
- }
- if (*fmt == '+') {
- if (su != NULL) {
- /* Make even bold text fit. */
- su->scale *= 1.2;
- /* Add padding. */
- su->scale += 3.0;
- }
- fmt++;
- }
- if (*fmt == '-') {
- if (su != NULL)
- su->scale *= -1.0;
- fmt++;
+ if (arg2 == NULL)
+ print_encode(h, arg1, NULL, 1);
+ else {
+ print_word(h, arg1);
+ print_byte(h, ':');
+ print_byte(h, ' ');
+ print_word(h, arg2);
+ print_byte(h, ';');
}
break;
- default:
- abort();
}
-
- /* Second letter: style name. */
-
- switch (*fmt++) {
- case 'h':
- attr = "height";
- break;
- case 'i':
- attr = "text-indent";
- break;
- case 'l':
- attr = "margin-left";
- break;
- case 'w':
- attr = "width";
- break;
- case 'W':
- attr = "min-width";
- break;
- case '?':
- attr = arg1;
- arg1 = va_arg(ap, char *);
- break;
- default:
- abort();
- }
- if (su == NULL && arg1 == NULL)
- continue;
-
- if (have_style == 1)
- print_word(h, " style=\"");
- else
- print_byte(h, ' ');
- print_word(h, attr);
- print_byte(h, ':');
- print_byte(h, ' ');
- if (su != NULL) {
- v = su->scale;
- if (su->unit == SCALE_MM && (v /= 100.0) == 0.0)
- v = 1.0;
- else if (su->unit == SCALE_BU)
- v /= 24.0;
- (void)snprintf(numbuf, sizeof(numbuf), "%.2f", v);
- print_word(h, numbuf);
- print_word(h, roffscales[su->unit]);
- } else
- print_word(h, arg1);
- print_byte(h, ';');
- have_style = 2;
- }
- if (have_style == 2)
print_byte(h, '"');
-
+ }
va_end(ap);
/* Accommodate for "well-formed" singleton escaping. */
@@ -769,6 +668,32 @@ print_gen_decls(struct html *h)
}
void
+print_gen_comment(struct html *h, struct roff_node *n)
+{
+ int wantblank;
+
+ print_word(h, "<!-- This is an automatically generated file."
+ " Do not edit.");
+ h->indent = 1;
+ wantblank = 0;
+ while (n != NULL && n->type == ROFFT_COMMENT) {
+ if (strstr(n->string, "-->") == NULL &&
+ (wantblank || *n->string != '\0')) {
+ print_endline(h);
+ print_indent(h);
+ print_word(h, n->string);
+ wantblank = *n->string != '\0';
+ }
+ n = n->next;
+ }
+ if (wantblank)
+ print_endline(h);
+ print_word(h, " -->");
+ print_endline(h);
+ h->indent = 0;
+}
+
+void
print_text(struct html *h, const char *word)
{
if (h->col && (h->flags & HTML_NOSPACE) == 0) {
@@ -959,21 +884,3 @@ print_word(struct html *h, const char *cp)
while (*cp != '\0')
print_byte(h, *cp++);
}
-
-/*
- * 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
- * the value.
- */
-static void
-a2width(const char *p, struct roffsu *su)
-{
- const char *end;
-
- end = a2roffsu(p, su, SCALE_MAX);
- if (end == NULL || *end != '\0') {
- su->unit = SCALE_EN;
- su->scale = html_strlen(p);
- } else if (su->scale < 0.0)
- su->scale = 0.0;
-}
diff --git a/html.h b/html.h
index c727eacf5d09..6d44a47383a7 100644
--- a/html.h
+++ b/html.h
@@ -1,7 +1,7 @@
-/* $Id: html.h,v 1.87 2017/07/08 14:51:04 schwarze Exp $ */
+/* $Id: html.h,v 1.92 2018/06/25 16:54:59 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -23,6 +23,7 @@ enum htmltag {
TAG_META,
TAG_TITLE,
TAG_DIV,
+ TAG_IDIV,
TAG_H1,
TAG_H2,
TAG_SPAN,
@@ -30,8 +31,6 @@ enum htmltag {
TAG_BR,
TAG_A,
TAG_TABLE,
- TAG_COLGROUP,
- TAG_COL,
TAG_TR,
TAG_TD,
TAG_LI,
@@ -119,6 +118,7 @@ struct eqn_box;
void roff_html_pre(struct html *, const struct roff_node *);
+void print_gen_comment(struct html *, struct roff_node *);
void print_gen_decls(struct html *);
void print_gen_head(struct html *);
struct tag *print_otag(struct html *, enum htmltag, const char *, ...);
@@ -131,5 +131,4 @@ void print_eqn(struct html *, const struct eqn_box *);
void print_paragraph(struct html *);
void print_endline(struct html *);
-char *html_make_id(const struct roff_node *);
-int html_strlen(const char *);
+char *html_make_id(const struct roff_node *, int);
diff --git a/lib.in b/lib.in
index 8b03df2ed3ec..2e217ee77da4 100644
--- a/lib.in
+++ b/lib.in
@@ -1,4 +1,4 @@
-/* $Id: lib.in,v 1.19 2016/11/23 20:22:13 schwarze Exp $ */
+/* $Id: lib.in,v 1.20 2017/08/20 02:30:27 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.org>
@@ -24,26 +24,31 @@
* Be sure to escape strings.
*/
+LINE("lib80211", "802.11 Wireless Network Management Library (lib80211, \\-l80211)")
LINE("libalias", "Packet Aliasing Library (libalias, \\-lalias)")
LINE("libarchive", "Streaming Archive Library (libarchive, \\-larchive)")
LINE("libarm", "ARM Architecture Library (libarm, \\-larm)")
LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)")
LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)")
LINE("libbsdxml", "eXpat XML parser library (libbsdxml, \\-lbsdxml)")
-LINE("libbsm", "Basic Security Module User Library (libbsm, \\-lbsm)")
-LINE("libc", "Standard C Library (libc, \\-lc)")
+LINE("libbsm", "Basic Security Module Library (libbsm, \\-lbsm)")
+LINE("libc", "Standard C\\~Library (libc, \\-lc)")
LINE("libc_r", "Reentrant C\\~Library (libc_r, \\-lc_r)")
LINE("libcalendar", "Calendar Arithmetic Library (libcalendar, \\-lcalendar)")
LINE("libcam", "Common Access Method User Library (libcam, \\-lcam)")
+LINE("libcasper", "Casper Library (libcasper, \\-lcasper)")
LINE("libcdk", "Curses Development Kit Library (libcdk, \\-lcdk)")
LINE("libcipher", "FreeSec Crypt Library (libcipher, \\-lcipher)")
LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)")
LINE("libcrypt", "Crypt Library (libcrypt, \\-lcrypt)")
LINE("libcurses", "Curses Library (libcurses, \\-lcurses)")
+LINE("libcuse", "Userland Character Device Library (libcuse, \\-lcuse)")
LINE("libdevattr", "Device attribute and event library (libdevattr, \\-ldevattr)")
+LINE("libdevctl", "Device Control Library (libdevctl, \\-ldevctl)")
LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)")
LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)")
LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)")
+LINE("libdl", "Dynamic Linker Services Filter (libdl, \\-ldl)")
LINE("libdm", "Device Mapper Library (libdm, \\-ldm)")
LINE("libdwarf", "DWARF Access Library (libdwarf, \\-ldwarf)")
LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)")
@@ -56,12 +61,11 @@ LINE("libfsid", "Filesystem Identification Library (libfsid, \\-lfsid)")
LINE("libftpio", "FTP Connection Management Library (libftpio, \\-lftpio)")
LINE("libform", "Curses Form Library (libform, \\-lform)")
LINE("libgeom", "Userland API Library for Kernel GEOM subsystem (libgeom, \\-lgeom)")
-LINE("libgpib", "General-Purpose Instrument Bus (GPIB) library (libgpib, \\-lgpib)")
+LINE("libgpio", "General-Purpose Input Output (GPIO) library (libgpio, \\-lgpio)")
LINE("libhammer", "HAMMER Filesystem Userland Library (libhammer, \\-lhammer)")
LINE("libi386", "i386 Architecture Library (libi386, \\-li386)")
LINE("libintl", "Internationalized Message Handling Library (libintl, \\-lintl)")
LINE("libipsec", "IPsec Policy Control Library (libipsec, \\-lipsec)")
-LINE("libipx", "IPX Address Conversion Support Library (libipx, \\-lipx)")
LINE("libiscsi", "iSCSI protocol library (libiscsi, \\-liscsi)")
LINE("libisns", "Internet Storage Name Service Library (libisns, \\-lisns)")
LINE("libjail", "Jail Library (libjail, \\-ljail)")
@@ -81,17 +85,19 @@ LINE("libnetgraph", "Netgraph User Library (libnetgraph, \\-lnetgraph)")
LINE("libnetpgp", "Netpgp Signing, Verification, Encryption and Decryption (libnetpgp, \\-lnetpgp)")
LINE("libnetpgpverify", "Netpgp Verification (libnetpgpverify, \\-lnetpgpverify)")
LINE("libnpf", "NPF Packet Filter Library (libnpf, \\-lnpf)")
+LINE("libnv", "Name/value pairs library (libnv, \\-lnv)")
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
LINE("libpanel", "Z-order for curses windows (libpanel, \\-lpanel)")
-LINE("libpcap", "Capture Library (libpcap, \\-lpcap)")
+LINE("libpcap", "Packet capture Library (libpcap, \\-lpcap)")
LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
LINE("libposix1e", "POSIX.1e Security API Library (libposix1e, \\-lposix1e)")
LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
-LINE("libproc", "Process Manipulation Library (libproc, \\-lproc)")
+LINE("libproc", "Processor Monitoring and Analysis Library (libproc, \\-lproc)")
+LINE("libprocstat", "Process and Files Information Retrieval (libprocstat, \\-lprocstat)")
LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
LINE("libpthread_dbg", "POSIX Debug Threads Library (libpthread_dbg, \\-lpthread_dbg)")
@@ -106,10 +112,13 @@ LINE("librt", "POSIX Real\\-time Library (librt, \\-lrt)")
LINE("librtld_db", "Debugging interface to the runtime linker Library (librtld_db, \\-lrtld_db)")
LINE("librumpclient", "Clientside Stubs for rump Kernel Remote Protocols (librumpclient, \\-lrumpclient)")
LINE("libsaslc", "Simple Authentication and Security Layer client library (libsaslc, \\-lsaslc)")
+LINE("libsbuf", "Safe String Composition Library (libsbuf, \\-lsbuf)")
LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)")
LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
LINE("libstand", "Standalone Applications Library (libstand, \\-lstand)")
+LINE("libstdthreads", "C11 Threads Library (libstdthreads, \\-lstdthreads)")
LINE("libSystem", "System Library (libSystem, \\-lSystem)")
+LINE("libsysdecode", "System Argument Decoding Library (libsysdecode, \\-lsysdecode)")
LINE("libtacplus", "TACACS+ Client Library (libtacplus, \\-ltacplus)")
LINE("libtcplay", "TrueCrypt-compatible API library (libtcplay, \\-ltcplay)")
LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
@@ -122,4 +131,5 @@ LINE("libusbhid", "USB Human Interface Devices Library (libusbhid, \\-lusbhid)")
LINE("libutil", "System Utilities Library (libutil, \\-lutil)")
LINE("libvgl", "Video Graphics Library (libvgl, \\-lvgl)")
LINE("libx86_64", "x86_64 Architecture Library (libx86_64, \\-lx86_64)")
+LINE("libxo", "Text, XML, JSON, and HTML Output Emission Library (libxo, \\-lxo)")
LINE("libz", "Compression Library (libz, \\-lz)")
diff --git a/libmandoc.h b/libmandoc.h
index 2cf076286177..9cc8cce4ecca 100644
--- a/libmandoc.h
+++ b/libmandoc.h
@@ -1,4 +1,4 @@
-/* $Id: libmandoc.h,v 1.70 2017/07/08 17:52:49 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.71 2018/04/09 22:27:04 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -66,7 +66,7 @@ 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);
-int roff_getreg(const struct roff *, const char *);
+int roff_getreg(struct roff *, const char *);
char *roff_strdup(const struct roff *, const char *);
int roff_getcontrol(const struct roff *,
const char *, int *);
diff --git a/main.c b/main.c
index 7f1411a6fbcc..600bc9bb4bef 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,7 @@
-/* $Id: main.c,v 1.301 2017/07/26 10:21:55 schwarze Exp $ */
+/* $Id: main.c,v 1.306 2018/05/14 14:10:23 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -19,7 +19,9 @@
#include "config.h"
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/param.h> /* MACHINE */
+#include <sys/termios.h>
#include <sys/wait.h>
#include <assert.h>
@@ -120,6 +122,7 @@ main(int argc, char *argv[])
struct manconf conf;
struct mansearch search;
struct curparse curp;
+ struct winsize ws;
struct tag_files *tag_files;
struct manpage *res, *resp;
const char *progname, *sec, *thisarg;
@@ -129,7 +132,7 @@ main(int argc, char *argv[])
size_t i, sz;
int prio, best_prio;
enum outmode outmode;
- int fd;
+ int fd, startdir;
int show_usage;
int options;
int use_pager;
@@ -316,6 +319,16 @@ main(int argc, char *argv[])
!isatty(STDOUT_FILENO))
use_pager = 0;
+ if (use_pager &&
+ (conf.output.width == 0 || conf.output.indent == 0) &&
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 &&
+ ws.ws_col > 1) {
+ if (conf.output.width == 0 && ws.ws_col < 79)
+ conf.output.width = ws.ws_col - 1;
+ if (conf.output.indent == 0 && ws.ws_col < 66)
+ conf.output.indent = 3;
+ }
+
#if HAVE_PLEDGE
if (!use_pager)
if (pledge("stdio rpath", NULL) == -1)
@@ -374,15 +387,34 @@ main(int argc, char *argv[])
argc, argv, &res, &sz))
usage(search.argmode);
- if (sz == 0) {
- if (search.argmode == ARG_NAME)
- fs_search(&search, &conf.manpath,
- argc, argv, &res, &sz);
- else
- warnx("nothing appropriate");
+ if (sz == 0 && search.argmode == ARG_NAME)
+ fs_search(&search, &conf.manpath,
+ argc, argv, &res, &sz);
+
+ if (search.argmode == ARG_NAME) {
+ for (c = 0; c < argc; c++) {
+ if (strchr(argv[c], '/') == NULL)
+ continue;
+ if (access(argv[c], R_OK) == -1) {
+ warn("%s", argv[c]);
+ continue;
+ }
+ res = mandoc_reallocarray(res,
+ sz + 1, sizeof(*res));
+ res[sz].file = mandoc_strdup(argv[c]);
+ res[sz].names = NULL;
+ res[sz].output = NULL;
+ res[sz].ipath = SIZE_MAX;
+ res[sz].bits = 0;
+ res[sz].sec = 10;
+ res[sz].form = FORM_SRC;
+ sz++;
+ }
}
if (sz == 0) {
+ if (search.argmode != ARG_NAME)
+ warnx("nothing appropriate");
rc = MANDOCLEVEL_BADARG;
goto out;
}
@@ -466,7 +498,29 @@ main(int argc, char *argv[])
parse(&curp, STDIN_FILENO, "<stdin>");
}
+ /*
+ * Remember the original working directory, if possible.
+ * This will be needed if some names on the command line
+ * are page names and some are relative file names.
+ * Do not error out if the current directory is not
+ * readable: Maybe it won't be needed after all.
+ */
+ startdir = open(".", O_RDONLY | O_DIRECTORY);
+
while (argc > 0) {
+
+ /*
+ * Changing directories is not needed in ARG_FILE mode.
+ * Do it on a best-effort basis. Even in case of
+ * failure, some functionality may still work.
+ */
+ if (resp != NULL) {
+ if (resp->ipath != SIZE_MAX)
+ (void)chdir(conf.manpath.paths[resp->ipath]);
+ else if (startdir != -1)
+ (void)fchdir(startdir);
+ }
+
fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv);
if (fd != -1) {
if (use_pager) {
@@ -476,14 +530,23 @@ main(int argc, char *argv[])
if (resp == NULL)
parse(&curp, fd, *argv);
- else if (resp->form == FORM_SRC) {
- /* For .so only; ignore failure. */
- (void)chdir(conf.manpath.paths[resp->ipath]);
+ else if (resp->form == FORM_SRC)
parse(&curp, fd, resp->file);
- } else
+ else
passthrough(resp->file, fd,
conf.output.synopsisonly);
+ if (ferror(stdout)) {
+ if (tag_files != NULL) {
+ warn("%s", tag_files->ofn);
+ tag_unlink();
+ tag_files = NULL;
+ } else
+ warn("stdout");
+ rc = MANDOCLEVEL_SYSERR;
+ break;
+ }
+
if (argc > 1 && curp.outtype <= OUTT_UTF8) {
if (curp.outdata == NULL)
outdata_alloc(&curp);
@@ -502,6 +565,10 @@ main(int argc, char *argv[])
if (--argc)
mparse_reset(curp.mp);
}
+ if (startdir != -1) {
+ (void)fchdir(startdir);
+ close(startdir);
+ }
if (curp.outdata != NULL) {
switch (curp.outtype) {
@@ -722,7 +789,8 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
cfg->firstmatch)
return 1;
}
- if (res != NULL && *ressz == lastsz)
+ if (res != NULL && *ressz == lastsz &&
+ strchr(*argv, '/') == NULL)
warnx("No entry for %s in the manual.", *argv);
lastsz = *ressz;
argv++;
@@ -1173,7 +1241,7 @@ spawn_pager(struct tag_files *tag_files)
if (dup2(tag_files->ofd, STDOUT_FILENO) == -1)
err((int)MANDOCLEVEL_SYSERR, "pager stdout");
close(tag_files->ofd);
- close(tag_files->tfd);
+ assert(tag_files->tfd == -1);
/* Do not start the pager before controlling the terminal. */
diff --git a/man.1 b/man.1
index 075497acab9d..cf03693ee981 100644
--- a/man.1
+++ b/man.1
@@ -1,4 +1,4 @@
-.\" $Id: man.1,v 1.29 2017/05/17 23:23:00 schwarze Exp $
+.\" $Id: man.1,v 1.33 2018/04/19 23:41:16 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: May 17 2017 $
+.Dd $Mdocdate: April 19 2018 $
.Dt MAN 1
.Os
.Sh NAME
@@ -78,6 +78,18 @@ Copy the manual page to the standard output instead of using
.Xr more 1
to paginate it.
This is done by default if the standard output is not a terminal device.
+.Pp
+When using
+.Fl c ,
+most terminal devices are unable to show the markup.
+To print the output of
+.Nm
+to the terminal with markup but without using a pager, pipe it to
+.Xr ul 1 .
+To remove the markup, pipe the output to
+.Xr col 1
+.Fl b
+instead.
.It Fl f
A synonym for
.Xr whatis 1 .
@@ -102,8 +114,7 @@ manual.
By default, it displays the header lines of all matching pages.
.It Fl l
A synonym for
-.Xr mandoc 1
-.Fl a .
+.Xr mandoc 1 .
The
.Ar name
arguments are interpreted as filenames.
@@ -115,6 +126,8 @@ No search is done and
and
.Fl w
are ignored.
+This option implies
+.Fl a .
.It Fl M Ar path
Override the list of standard directories which
.Nm
@@ -285,11 +298,6 @@ If neither PAGER nor MANPAGER is defined,
.Xr more 1
.Fl s
is used.
-Only used if
-.Fl a
-or
-.Fl l
-is specified.
.El
.Sh FILES
.Bl -tag -width /etc/man.conf -compact
@@ -301,20 +309,24 @@ default man configuration file
See
.Xr mandoc 1
for details.
+.Sh EXAMPLES
+Format a page for pasting extracts into an email message \(em
+avoid printing any UTF-8 characters, reduce the width to ease
+quoting in replies, and remove markup:
+.Pp
+.Dl $ man -T ascii -O width=65 pledge | col -b
+.Pp
+Read a typeset page in a PDF viewer:
+.Pp
+.Dl $ MANPAGER=mupdf man -T pdf lpd
.Sh SEE ALSO
.Xr apropos 1 ,
-.Xr intro 1 ,
+.Xr col 1 ,
+.Xr mandoc 1 ,
+.Xr ul 1 ,
.Xr whereis 1 ,
-.Xr intro 2 ,
-.Xr intro 3 ,
-.Xr intro 4 ,
-.Xr intro 5 ,
.Xr man.conf 5 ,
-.Xr intro 6 ,
-.Xr intro 7 ,
-.Xr mdoc 7 ,
-.Xr intro 8 ,
-.Xr intro 9
+.Xr mdoc 7
.Sh STANDARDS
The
.Nm
diff --git a/man.7 b/man.7
index 570e7ac3bdcd..d418b9ee76ca 100644
--- a/man.7
+++ b/man.7
@@ -1,4 +1,4 @@
-.\" $Id: man.7,v 1.136 2017/06/25 11:42:02 schwarze Exp $
+.\" $Id: man.7,v 1.137 2018/04/05 22:12:33 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -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: June 25 2017 $
+.Dd $Mdocdate: April 5 2018 $
.Dt MAN 7
.Os
.Sh NAME
@@ -273,7 +273,6 @@ in the alphabetical reference below.
.Bl -column "PP, LP, P" description
.It Sx B Ta boldface font
.It Sx I Ta italic font
-.It Sx R Ta roman (default) font
.It Sx SB Ta small boldface font
.It Sx SM Ta small roman font
.It Sx BI Ta alternate between boldface and italic fonts
@@ -297,9 +296,7 @@ The optional arguments specify which release it is from.
Text is rendered in bold face.
.Pp
See also
-.Sx \&I
-and
-.Sx \&R .
+.Sx \&I .
.Ss \&BI
Text is rendered alternately in bold face and italic.
Thus,
@@ -393,9 +390,7 @@ and
Text is rendered in italics.
.Pp
See also
-.Sx \&B
-and
-.Sx \&R .
+.Sx \&B .
.Ss \&IB
Text is rendered alternately in italics and bold face.
Whitespace between arguments is omitted in output.
@@ -546,13 +541,6 @@ See also
.Sx \&P ,
and
.Sx \&TP .
-.Ss \&R
-Text is rendered in roman (the default font).
-.Pp
-See also
-.Sx \&I
-and
-.Sx \&B .
.Ss \&RB
Text is rendered alternately in roman (the default font) and bold face.
Whitespace between arguments is omitted in output.
@@ -790,7 +778,6 @@ The syntax is as follows:
.It Sx \&IR Ta n Ta current Ta \&
.It Sx \&OP Ta 0, 1 Ta current Ta compat
.It Sx \&PD Ta 1 Ta current Ta \&
-.It Sx \&R Ta n Ta next-line Ta \&
.It Sx \&RB Ta n Ta current Ta \&
.It Sx \&RI Ta n Ta current Ta \&
.It Sx \&SB Ta n Ta next-line Ta \&
diff --git a/man.cgi.8 b/man.cgi.8
index eba3cec45a8a..b8cd623c598d 100644
--- a/man.cgi.8
+++ b/man.cgi.8
@@ -1,4 +1,4 @@
-.\" $Id: man.cgi.8,v 1.22 2017/03/18 16:48:24 schwarze Exp $
+.\" $Id: man.cgi.8,v 1.23 2018/05/20 21:48:44 schwarze Exp $
.\"
.\" Copyright (c) 2014, 2015, 2016 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: March 18 2017 $
+.Dd $Mdocdate: May 20 2018 $
.Dt MAN.CGI 8
.Os
.Sh NAME
@@ -104,6 +104,9 @@ Lists are returned when searches match more than one manual page.
The first column shows the names and section numbers of manuals
as clickable links.
The second column shows the one-line descriptions of the manuals.
+For
+.Xr man 1
+style searches, the content of the first manual page follows the list.
.It A manual page.
This output format is used when a search matches exactly one
manual page, or when a link on a list page or an
@@ -111,7 +114,7 @@ manual page, or when a link on a list page or an
link on another manual page is followed.
.It A no-result page.
This is shown when a search request returns no results -
-eiher because it violates the query syntax, or because
+either because it violates the query syntax, or because
the search does not match any manual pages.
.It \&An error page.
This cannot happen by merely clicking the
@@ -234,6 +237,8 @@ They consist of:
.It
The
.Cm http://
+or
+.Cm https://
protocol specifier.
.It
The host name.
@@ -394,7 +399,7 @@ The
CGI program is call-compatible with queries from the traditional
.Pa man.cgi
script by Wolfram Schneider.
-However, the output may not be quite the same.
+However, the output looks quite different.
.Sh SEE ALSO
.Xr apropos 1 ,
.Xr mandoc.db 5 ,
diff --git a/man.conf.5 b/man.conf.5
index 425895c1dc8a..be0998087d17 100644
--- a/man.conf.5
+++ b/man.conf.5
@@ -1,4 +1,4 @@
-.\" $Id: man.conf.5,v 1.4 2016/12/28 22:52:17 schwarze Exp $
+.\" $Id: man.conf.5,v 1.5 2017/08/22 18:17:52 schwarze Exp $
.\"
.\" Copyright (c) 2015 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 28 2016 $
+.Dd $Mdocdate: August 22 2017 $
.Dt MAN.CONF 5
.Os
.Sh NAME
@@ -74,8 +74,12 @@ 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 .
+to work, and also for
+.Xr man 1
+on operating systems like
+.Ox
+that install each manual page with only one file name in the file system,
+even if it documents multiple utilities or functions.
.It Ic output Ar option Op Ar value
Configure the default value of an output option.
These directives are overridden by the
diff --git a/man_html.c b/man_html.c
index a304b3e4d240..ae5dac1ad938 100644
--- a/man_html.c
+++ b/man_html.c
@@ -1,7 +1,7 @@
-/* $Id: man_html.c,v 1.145 2017/06/25 11:42:02 schwarze Exp $ */
+/* $Id: man_html.c,v 1.153 2018/07/27 17:49:31 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -35,8 +35,6 @@
/* FIXME: have PD set the default vspace width. */
-#define INDENT 5
-
#define MAN_ARGS const struct roff_meta *man, \
const struct roff_node *n, \
struct html *h
@@ -48,12 +46,11 @@ struct htmlman {
static void print_bvspace(struct html *,
const struct roff_node *);
-static void print_man_head(MAN_ARGS);
+static void print_man_head(const struct roff_meta *,
+ struct html *);
static void print_man_nodelist(MAN_ARGS);
static void print_man_node(MAN_ARGS);
static int fillmode(struct html *, int);
-static int a2width(const struct roff_node *,
- struct roffsu *);
static int man_B_pre(MAN_ARGS);
static int man_HP_pre(MAN_ARGS);
static int man_IP_pre(MAN_ARGS);
@@ -68,8 +65,10 @@ static int man_UR_pre(MAN_ARGS);
static int man_alt_pre(MAN_ARGS);
static int man_ign_pre(MAN_ARGS);
static int man_in_pre(MAN_ARGS);
-static void man_root_post(MAN_ARGS);
-static void man_root_pre(MAN_ARGS);
+static void man_root_post(const struct roff_meta *,
+ struct html *);
+static void man_root_pre(const struct roff_meta *,
+ struct html *);
static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
{ NULL, NULL }, /* TH */
@@ -138,30 +137,34 @@ print_bvspace(struct html *h, const struct roff_node *n)
void
html_man(void *arg, const struct roff_man *man)
{
- struct html *h;
- struct tag *t;
+ struct html *h;
+ struct roff_node *n;
+ struct tag *t;
h = (struct html *)arg;
+ n = man->first->child;
if ((h->oflags & HTML_FRAGMENT) == 0) {
print_gen_decls(h);
print_otag(h, TAG_HTML, "");
+ if (n->type == ROFFT_COMMENT)
+ print_gen_comment(h, n);
t = print_otag(h, TAG_HEAD, "");
- print_man_head(&man->meta, man->first, h);
+ print_man_head(&man->meta, h);
print_tagq(h, t);
print_otag(h, TAG_BODY, "");
}
- man_root_pre(&man->meta, man->first, h);
+ man_root_pre(&man->meta, h);
t = print_otag(h, TAG_DIV, "c", "manual-text");
- print_man_nodelist(&man->meta, man->first->child, h);
+ print_man_nodelist(&man->meta, n, h);
print_tagq(h, t);
- man_root_post(&man->meta, man->first, h);
+ man_root_post(&man->meta, h);
print_tagq(h, NULL);
}
static void
-print_man_head(MAN_ARGS)
+print_man_head(const struct roff_meta *man, struct html *h)
{
char *cp;
@@ -262,6 +265,8 @@ print_man_node(MAN_ARGS)
break;
print_paragraph(h);
return;
+ case ROFFT_COMMENT:
+ return;
default:
break;
}
@@ -359,16 +364,8 @@ fillmode(struct html *h, int want)
return had;
}
-static int
-a2width(const struct roff_node *n, struct roffsu *su)
-{
- if (n->type != ROFFT_TEXT)
- return 0;
- return a2roffsu(n->string, su, SCALE_EN) != NULL;
-}
-
static void
-man_root_pre(MAN_ARGS)
+man_root_pre(const struct roff_meta *man, struct html *h)
{
struct tag *t, *tt;
char *title;
@@ -396,7 +393,7 @@ man_root_pre(MAN_ARGS)
}
static void
-man_root_post(MAN_ARGS)
+man_root_post(const struct roff_meta *man, struct html *h)
{
struct tag *t, *tt;
@@ -419,11 +416,10 @@ man_SH_pre(MAN_ARGS)
char *id;
if (n->type == ROFFT_HEAD) {
- id = html_make_id(n);
+ id = html_make_id(n, 1);
print_otag(h, TAG_H1, "cTi", "Sh", id);
if (id != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
}
return 1;
}
@@ -489,11 +485,10 @@ man_SS_pre(MAN_ARGS)
char *id;
if (n->type == ROFFT_HEAD) {
- id = html_make_id(n);
+ id = html_make_id(n, 1);
print_otag(h, TAG_H2, "cTi", "Ss", id);
if (id != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
}
return 1;
}
@@ -516,7 +511,7 @@ man_IP_pre(MAN_ARGS)
const struct roff_node *nn;
if (n->type == ROFFT_BODY) {
- print_otag(h, TAG_DD, "c", "It-tag");
+ print_otag(h, TAG_DD, "");
return 1;
} else if (n->type != ROFFT_HEAD) {
print_otag(h, TAG_DL, "c", "Bl-tag");
@@ -525,7 +520,7 @@ man_IP_pre(MAN_ARGS)
/* FIXME: width specification. */
- print_otag(h, TAG_DT, "c", "It-tag");
+ print_otag(h, TAG_DT, "");
/* For IP, only print the first header element. */
@@ -550,24 +545,13 @@ man_IP_pre(MAN_ARGS)
static int
man_HP_pre(MAN_ARGS)
{
- struct roffsu sum, sui;
- const struct roff_node *np;
-
if (n->type == ROFFT_HEAD)
return 0;
- else if (n->type != ROFFT_BLOCK)
- return 1;
- np = n->head->child;
-
- if (np == NULL || !a2width(np, &sum))
- SCALE_HS_INIT(&sum, INDENT);
-
- sui.unit = sum.unit;
- sui.scale = -sum.scale;
-
- print_bvspace(h, n);
- print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui);
+ if (n->type == ROFFT_BLOCK) {
+ print_bvspace(h, n);
+ print_otag(h, TAG_DIV, "c", "HP");
+ }
return 1;
}
@@ -629,18 +613,10 @@ man_ign_pre(MAN_ARGS)
static int
man_RS_pre(MAN_ARGS)
{
- struct roffsu su;
-
if (n->type == ROFFT_HEAD)
return 0;
- else if (n->type == ROFFT_BODY)
- return 1;
-
- SCALE_HS_INIT(&su, INDENT);
- if (n->head->child)
- a2width(n->head->child, &su);
-
- print_otag(h, TAG_DIV, "sul", &su);
+ if (n->type == ROFFT_BLOCK)
+ print_otag(h, TAG_DIV, "c", "Bd-indent");
return 1;
}
diff --git a/man_term.c b/man_term.c
index 8946a05067a7..b5723ccf8383 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,7 +1,7 @@
-/* $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */
+/* $Id: man_term.c,v 1.211 2018/06/10 15:12:35 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -675,7 +675,8 @@ pre_SS(DECL_ARGS)
n = n->prev;
} while (n != NULL && n->tok >= MAN_TH &&
termacts[n->tok].flags & MAN_NOTEXT);
- if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
+ if (n == NULL || n->type == ROFFT_COMMENT ||
+ (n->tok == MAN_SS && n->body->child == NULL))
break;
for (i = 0; i < mt->pardist; i++)
@@ -737,7 +738,8 @@ pre_SH(DECL_ARGS)
n = n->prev;
} while (n != NULL && n->tok >= MAN_TH &&
termacts[n->tok].flags & MAN_NOTEXT);
- if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))
+ if (n == NULL || n->type == ROFFT_COMMENT ||
+ (n->tok == MAN_SH && n->body->child == NULL))
break;
for (i = 0; i < mt->pardist; i++)
@@ -885,7 +887,8 @@ print_man_node(DECL_ARGS)
term_word(p, n->string);
goto out;
-
+ case ROFFT_COMMENT:
+ return;
case ROFFT_EQN:
if ( ! (n->flags & NODE_LINE))
p->flags |= TERMP_NOSPACE;
@@ -1029,6 +1032,18 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
term_word(p, title);
term_flushln(p);
+
+ /*
+ * Reset the terminal state for more output after the footer:
+ * Some output modes, in particular PostScript and PDF, print
+ * the header and the footer into a buffer such that it can be
+ * reused for multiple output pages, then go on to format the
+ * main text.
+ */
+
+ p->tcol->offset = 0;
+ p->flags = 0;
+
free(title);
}
diff --git a/man_validate.c b/man_validate.c
index b3356ccb3d3f..d6c51af5255c 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -120,6 +120,7 @@ man_node_validate(struct roff_man *man)
case ROFFT_ROOT:
check_root(man, n);
break;
+ case ROFFT_COMMENT:
case ROFFT_EQN:
case ROFFT_TBL:
break;
@@ -149,10 +150,9 @@ man_node_validate(struct roff_man *man)
static void
check_root(CHKARGS)
{
-
assert((man->flags & (MAN_BLINE | MAN_ELINE)) == 0);
- if (NULL == man->first->child)
+ if (n->last == NULL || n->last->type == ROFFT_COMMENT)
mandoc_msg(MANDOCERR_DOC_EMPTY, man->parse,
n->line, n->pos, NULL);
else
diff --git a/mandoc.1 b/mandoc.1
index 1db4d3251f45..76b3cda5a704 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,7 +1,7 @@
-.\" $Id: mandoc.1,v 1.217 2017/07/20 15:26:41 schwarze Exp $
+.\" $Id: mandoc.1,v 1.226 2018/07/28 18:34:15 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 20 2017 $
+.Dd $Mdocdate: July 28 2018 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -34,9 +34,7 @@
.Sh DESCRIPTION
The
.Nm
-utility formats
-.Ux
-manual pages for display.
+utility formats manual pages for display.
.Pp
By default,
.Nm
@@ -118,7 +116,7 @@ With
all input files are interpreted as
.Xr man 7 .
By default, the input language is automatically detected for each file:
-if the the first macro is
+if the first macro is
.Ic \&Dd
or
.Ic \&Dt ,
@@ -132,13 +130,32 @@ With other arguments,
is silently ignored.
.It Fl O Ar options
Comma-separated output options.
+See the descriptions of the individual output formats for supported
+.Ar options .
.It Fl T Ar output
-Output format.
-See
-.Sx Output Formats
-for available formats.
-Defaults to
-.Fl T Cm locale .
+Select the output format.
+Supported values for the
+.Ar output
+argument are
+.Cm ascii ,
+.Cm html ,
+the default of
+.Cm locale ,
+.Cm man ,
+.Cm markdown ,
+.Cm pdf ,
+.Cm ps ,
+.Cm tree ,
+and
+.Cm utf8 .
+.Pp
+The special
+.Fl T Cm lint
+mode only parses the input and produces no output.
+It implies
+.Fl W Cm all
+and redirects parser messages, which usually appear on standard
+error output, to standard output.
.It Fl W Ar level
Specify the minimum message
.Ar level
@@ -196,11 +213,11 @@ and
are requested, they can be joined with a comma, for example
.Fl W Cm error , Ns Cm stop .
.It Ar file
-Read input from zero or more files.
-If unspecified, reads from stdin.
-If multiple files are specified,
+Read from the given input file.
+If multiple files are specified, they are processed in the given order.
+If unspecified,
.Nm
-will halt with the first failed parse.
+reads from standard input.
.El
.Pp
The options
@@ -220,69 +237,14 @@ manual.
The options
.Fl fkl
are mutually exclusive and override each other.
-.Ss Output Formats
-The
-.Nm
-utility accepts the following
-.Fl T
-arguments, which correspond to output modes:
-.Bl -tag -width "-T markdown"
-.It Fl T Cm ascii
-Produce 7-bit ASCII output.
-See
-.Sx ASCII Output .
-.It Fl T Cm html
-Produce HTML5, CSS1, and MathML output.
-See
-.Sx HTML Output .
-.It Fl T Cm lint
-Parse only: produce no output.
-Implies
-.Fl W Cm all
-and redirects parser messages, which usually appear
-on standard error output, to standard output.
-.It Fl T Cm locale
-Encode output using the current locale.
-This is the default.
-See
-.Sx Locale Output .
-.It Fl T Cm man
-Produce
-.Xr man 7
-format output.
-See
-.Sx Man Output .
-.It Fl T Cm markdown
-Produce output in
-.Sy markdown
-format.
-See
-.Sx Markdown Output .
-.It Fl T Cm pdf
-Produce PDF output.
-See
-.Sx PDF Output .
-.It Fl T Cm ps
-Produce PostScript output.
-See
-.Sx PostScript Output .
-.It Fl T Cm tree
-Produce an indented parse tree.
-See
-.Sx Syntax tree output .
-.It Fl T Cm utf8
-Encode output in the UTF\-8 multi-byte format.
-See
-.Sx UTF\-8 Output .
-.El
-.Pp
-If multiple input files are specified, these will be processed by the
-corresponding filter in-order.
.Ss ASCII Output
-Output produced by
+Use
.Fl T Cm ascii
-is rendered in standard 7-bit ASCII documented in
-.Xr ascii 7 .
+to force text output in 7-bit ASCII character encoding documented in the
+.Xr ascii 7
+manual page, ignoring the
+.Xr locale 1
+set in the environment.
.Pp
Font styles are applied by using back-spaced encoding such that an
underlined character
@@ -299,9 +261,6 @@ The special characters documented in
.Xr mandoc_char 7
are rendered best-effort in an ASCII equivalent.
.Pp
-Output width is limited to 78 visible columns unless literal input lines
-exceed this limit.
-.Pp
The following
.Fl O
arguments are accepted:
@@ -315,9 +274,30 @@ and seven for
.Xr man 7 .
Increasing this is not recommended; it may result in degraded formatting,
for example overfull lines or ugly line breaks.
+When output is to a pager on a terminal that is less than 66 columns
+wide, the default is reduced to three columns.
+.It Cm mdoc
+Format
+.Xr man 7
+input files in
+.Xr mdoc 7
+output style.
+Specifically, this suppresses the two additional blank lines near the
+top and the bottom of each page, and it implies
+.Fl O Cm indent Ns =5 .
+One useful application is for checking that
+.Fl T Cm man
+output formats in the same way as the
+.Xr mdoc 7
+source it was generated from.
.It Cm width Ns = Ns Ar width
The output width is set to
-.Ar width .
+.Ar width
+instead of the default of 78.
+When output is to a pager on a terminal that is less than 79 columns
+wide, the default is reduced to one less than the terminal width.
+In any case, lines that are output in literal mode are never wrapped
+and may exceed the output width.
.El
.Ss HTML Output
Output produced by
@@ -338,7 +318,8 @@ defaults to simple output (via an embedded style-sheet)
readable in any graphical or text-based web
browser.
.Pp
-Special characters are rendered in decimal-encoded UTF\-8.
+Non-ASCII characters are rendered
+as hexadecimal Unicode character references.
.Pp
The following
.Fl O
@@ -388,19 +369,28 @@ This must be a valid absolute or
relative URI.
.El
.Ss Locale Output
-Locale-depending output encoding is triggered with
+By default,
+.Nm
+automatically selects UTF-8 or ASCII output according to the current
+.Xr locale 1 .
+If any of the environment variables
+.Ev LC_ALL ,
+.Ev LC_CTYPE ,
+or
+.Ev LANG
+are set and the first one that is set
+selects the UTF-8 character encoding, it produces
+.Sx UTF-8 Output ;
+otherwise, it falls back to
+.Sx ASCII Output .
+This output mode can also be selected explicitly with
.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 Cm ascii .
-See
-.Sx ASCII Output
-for font style specification and available command-line arguments.
.Ss Man Output
-Translate input format into
+Use
+.Fl T Cm man
+to translate
+.Xr mdoc 7
+input into
.Xr man 7
output format.
This is useful for distributing manual sources to legacy systems
@@ -408,11 +398,7 @@ lacking
.Xr mdoc 7
formatters.
.Pp
-If
-.Xr mdoc 7
-is passed as input, it is translated into
-.Xr man 7 .
-If the input format is
+If the input format of a file is
.Xr man 7 ,
the input is copied to the output, expanding any
.Xr roff 7
@@ -424,11 +410,11 @@ level controls which
.Sx DIAGNOSTICS
are displayed before copying the input to the output.
.Ss Markdown Output
-Translate
+Use
+.Fl T Cm markdown
+to translate
.Xr mdoc 7
-input to the
-.Sy markdown
-format conforming to
+input to the markdown format conforming to
.Lk http://daringfireball.net/projects/markdown/syntax.text\
"John Gruber's 2004 specification" .
The output also almost conforms to the
@@ -499,13 +485,24 @@ If an unknown value is encountered,
.Ar letter
is used.
.El
-.Ss UTF\-8 Output
+.Ss UTF-8 Output
Use
.Fl T Cm utf8
-to force a UTF\-8 locale.
+to force text output in UTF-8 multi-byte character encoding,
+ignoring the
+.Xr locale 1
+settings in the environment.
See
-.Sx Locale Output
-for details and options.
+.Sx ASCII Output
+regarding font styles and
+.Fl O
+arguments.
+.Pp
+On operating systems lacking locale or wide character support, and
+on those where the internal character representation is not UCS-4,
+.Nm
+always falls back to
+.Sx ASCII Output .
.Ss Syntax tree output
Use
.Fl T Cm tree
@@ -574,6 +571,13 @@ Meta data is not available in this case.
.El
.Sh ENVIRONMENT
.Bl -tag -width MANPAGER
+.It Ev LC_CTYPE
+The character encoding
+.Xr locale 1 .
+When
+.Sx Locale Output
+is selected, it decides whether to use ASCII or UTF-8 output format.
+It never affects the interpretation of input files.
.It Ev MANPAGER
Any non-empty value of the environment variable
.Ev MANPAGER
@@ -741,7 +745,7 @@ Please use your good judgement to decide whether any particular
.Cm style
suggestion really justifies a change to the input file.
.It Cm base
-A convertion used in the base system of a specific operating system
+A convention used in the base system of a specific operating system
is not adhered to.
These are not markup mistakes, and neither the quality of formatting
nor portability are in danger.
@@ -849,6 +853,16 @@ Consider using the conventional
date format
.Dq "Month dd, yyyy"
instead.
+.It Sy "normalizing date format to" : No ...
+.Pq mdoc , man
+The
+.Ic \&Dd
+or
+.Ic \&TH
+macro provides an abbreviated month name or a day number with a
+leading zero.
+In the formatted output, the month name is written out in full
+and the leading zero is omitted.
.It Sy "lower case character in document title"
.Pq mdoc , man
The title is still used as given in the
@@ -861,7 +875,7 @@ A single manual page contains two copies of the RCS identifier for
the same operating system.
Consider deleting the later instance and moving the first one up
to the top of the page.
-.It Sy "typo in section name"
+.It Sy "possible typo in section name"
.Pq mdoc
Fuzzy string matching revealed that the argument of an
.Ic \&Sh
@@ -938,6 +952,12 @@ An
request occurs even though the document already switched to no-fill mode
and did not switch back to fill mode yet.
It has no effect.
+.It Sy "verbatim \(dq--\(dq, maybe consider using \e(em"
+.Pq mdoc
+Even though the ASCII output device renders an em-dash as
+.Qq \-\- ,
+that is not a good way to write it in an input file
+because it renders poorly on all other output devices.
.It Sy "function name without markup"
.Pq mdoc
A word followed by an empty pair of parentheses occurs on a text line.
diff --git a/mandoc.c b/mandoc.c
index 3e16d2c64fbc..1279b52ed50f 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,7 +1,7 @@
-/* $Id: mandoc.c,v 1.103 2017/07/03 13:40:19 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.104 2018/07/28 18:34:15 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -541,6 +541,9 @@ mandoc_normdate(struct roff_man *man, char *in, int ln, int pos)
if (t > time(NULL) + 86400)
mandoc_msg(MANDOCERR_DATE_FUTURE, man->parse,
ln, pos, cp);
+ else if (*in != '$' && strcmp(in, cp) != 0)
+ mandoc_msg(MANDOCERR_DATE_NORM, man->parse,
+ ln, pos, cp);
return cp;
}
diff --git a/mandoc.css b/mandoc.css
index 2a57a18f9d69..c93bc22a2d14 100644
--- a/mandoc.css
+++ b/mandoc.css
@@ -1,11 +1,11 @@
-/* $Id: mandoc.css,v 1.22 2017/07/16 18:45:00 schwarze Exp $ */
+/* $Id: mandoc.css,v 1.36 2018/07/23 22:51:26 schwarze Exp $ */
/*
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
*/
/* Global defaults. */
-html { max-width: 100ex; }
+html { max-width: 65em; }
body { font-family: Helvetica,Arial,sans-serif; }
table { margin-top: 0em;
margin-bottom: 0em; }
@@ -14,7 +14,7 @@ ul, ol, dl { margin-top: 0em;
margin-bottom: 0em; }
li, dt { margin-top: 1em; }
-a.selflink { border-bottom: thin dotted;
+.permalink { border-bottom: thin dotted;
color: inherit;
font: inherit;
text-decoration: inherit; }
@@ -41,7 +41,6 @@ table.head { width: 100%;
td.head-vol { text-align: center; }
td.head-rtitle {
text-align: right; }
-span.Nd { }
table.foot { width: 100%;
border-top: 1px dotted #808080;
@@ -51,147 +50,182 @@ td.foot-os { text-align: right; }
/* Sections and paragraphs. */
-div.manual-text {
- margin-left: 5ex; }
-h1.Sh { margin-top: 2ex;
- margin-bottom: 1ex;
- margin-left: -4ex;
+.manual-text {
+ margin-left: 3.8em; }
+.Nd { display: inline; }
+.Sh { margin-top: 1.2em;
+ margin-bottom: 0.6em;
+ margin-left: -3.2em;
font-size: 110%; }
-h2.Ss { margin-top: 2ex;
- margin-bottom: 1ex;
- margin-left: -2ex;
+.Ss { margin-top: 1.2em;
+ margin-bottom: 0.6em;
+ margin-left: -1.2em;
font-size: 105%; }
-div.Pp { margin: 1ex 0ex; }
-a.Sx { }
-a.Xr { }
+.Pp { margin: 0.6em 0em; }
+.Sx { }
+.Xr { }
/* Displays and lists. */
-div.Bd { }
-div.D1 { margin-left: 5ex; }
+.Bd { }
+.Bd-indent { margin-left: 3.8em; }
-ul.Bl-bullet { list-style-type: disc;
+.Bl-bullet { list-style-type: disc;
padding-left: 1em; }
-li.It-bullet { }
-ul.Bl-dash { list-style-type: none;
+.Bl-bullet > li { }
+.Bl-dash { list-style-type: none;
padding-left: 0em; }
-li.It-dash:before {
+.Bl-dash > li:before {
content: "\2014 "; }
-ul.Bl-item { list-style-type: none;
+.Bl-item { list-style-type: none;
padding-left: 0em; }
-li.It-item { }
-ul.Bl-compact > li {
- margin-top: 0ex; }
-
-ol.Bl-enum { padding-left: 2em; }
-li.It-enum { }
-ol.Bl-compact > li {
- margin-top: 0ex; }
-
-dl.Bl-diag { }
-dt.It-diag { }
-dd.It-diag { margin-left: 0ex; }
-b.It-diag { font-style: normal; }
-dl.Bl-hang { }
-dt.It-hang { }
-dd.It-hang { margin-left: 10.2ex; }
-dl.Bl-inset { }
-dt.It-inset { }
-dd.It-inset { margin-left: 0ex; }
-dl.Bl-ohang { }
-dt.It-ohang { }
-dd.It-ohang { margin-left: 0ex; }
-dl.Bl-tag { margin-left: 10.2ex; }
-dt.It-tag { float: left;
- margin-top: 0ex;
- margin-left: -10.2ex;
- padding-right: 2ex;
+.Bl-item > li { }
+.Bl-compact > li {
+ margin-top: 0em; }
+
+.Bl-enum { padding-left: 2em; }
+.Bl-enum > li { }
+.Bl-compact > li {
+ margin-top: 0em; }
+
+.Bl-diag { }
+.Bl-diag > dt {
+ font-style: normal;
+ font-weight: bold; }
+.Bl-diag > dd {
+ margin-left: 0em; }
+.Bl-hang { }
+.Bl-hang > dt { }
+.Bl-hang > dd {
+ margin-left: 5.5em; }
+.Bl-inset { }
+.Bl-inset > dt { }
+.Bl-inset > dd {
+ margin-left: 0em; }
+.Bl-ohang { }
+.Bl-ohang > dt { }
+.Bl-ohang > dd {
+ margin-left: 0em; }
+.Bl-tag { margin-left: 5.5em; }
+.Bl-tag > dt {
+ float: left;
+ margin-top: 0em;
+ margin-left: -5.5em;
+ padding-right: 1.2em;
vertical-align: top; }
-dd.It-tag { clear: right;
+.Bl-tag > dd {
+ clear: right;
width: 100%;
- margin-top: 0ex;
- margin-left: 0ex;
+ margin-top: 0em;
+ margin-left: 0em;
vertical-align: top;
overflow: auto; }
-dl.Bl-compact > dt {
- margin-top: 0ex; }
+.Bl-compact > dt {
+ margin-top: 0em; }
-table.Bl-column { }
-tr.It-column { }
-td.It-column { margin-top: 1em; }
-table.Bl-compact > tbody > tr > td {
- margin-top: 0ex; }
+.Bl-column { }
+.Bl-column > tbody > tr { }
+.Bl-column > tbody > tr > td {
+ margin-top: 1em; }
+.Bl-compact > tbody > tr > td {
+ margin-top: 0em; }
-cite.Rs { font-style: normal;
+.Rs { font-style: normal;
+ font-weight: normal; }
+.RsA { }
+.RsB { font-style: italic;
+ font-weight: normal; }
+.RsC { }
+.RsD { }
+.RsI { font-style: italic;
font-weight: normal; }
-span.RsA { }
-i.RsB { font-weight: normal; }
-span.RsC { }
-span.RsD { }
-i.RsI { font-weight: normal; }
-i.RsJ { font-weight: normal; }
-span.RsN { }
-span.RsO { }
-span.RsP { }
-span.RsQ { }
-span.RsR { }
-span.RsT { text-decoration: underline; }
-a.RsU { }
-span.RsV { }
-
-span.eqn { }
-table.tbl { }
+.RsJ { font-style: italic;
+ font-weight: normal; }
+.RsN { }
+.RsO { }
+.RsP { }
+.RsQ { }
+.RsR { }
+.RsT { text-decoration: underline; }
+.RsU { }
+.RsV { }
+
+.eqn { }
+.tbl { }
+
+.HP { margin-left: 3.8em;
+ text-indent: -3.8em; }
/* Semantic markup for command line utilities. */
table.Nm { }
-b.Nm { font-style: normal; }
-b.Fl { font-style: normal; }
-b.Cm { font-style: normal; }
-var.Ar { font-style: italic;
+code.Nm { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Fl { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Cm { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Ar { font-style: italic;
font-weight: normal; }
-span.Op { }
-b.Ic { font-style: normal; }
-code.Ev { font-style: normal;
+.Op { display: inline; }
+.Ic { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Ev { font-style: normal;
font-weight: normal;
font-family: monospace; }
-i.Pa { font-weight: normal; }
+.Pa { font-style: italic;
+ font-weight: normal; }
/* Semantic markup for function libraries. */
-span.Lb { }
-b.In { font-style: normal; }
+.Lb { }
+code.In { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
a.In { }
-b.Fd { font-style: normal; }
-var.Ft { font-style: italic;
+.Fd { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Ft { font-style: italic;
font-weight: normal; }
-b.Fn { font-style: normal; }
-var.Fa { font-style: italic;
+.Fn { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Fa { font-style: italic;
font-weight: normal; }
-var.Vt { font-style: italic;
+.Vt { font-style: italic;
font-weight: normal; }
-var.Va { font-style: italic;
+.Va { font-style: italic;
font-weight: normal; }
-code.Dv { font-style: normal;
+.Dv { font-style: normal;
font-weight: normal;
font-family: monospace; }
-code.Er { font-style: normal;
+.Er { font-style: normal;
font-weight: normal;
font-family: monospace; }
/* Various semantic markup. */
-span.An { }
-a.Lk { }
-a.Mt { }
-b.Cd { font-style: normal; }
-i.Ad { font-weight: normal; }
-b.Ms { font-style: normal; }
-span.St { }
-a.Ux { }
+.An { }
+.Lk { }
+.Mt { }
+.Cd { font-style: normal;
+ font-weight: bold;
+ font-family: inherit; }
+.Ad { font-style: italic;
+ font-weight: normal; }
+.Ms { font-style: normal;
+ font-weight: bold; }
+.St { }
+.Ux { }
/* Physical markup. */
+.Bf { display: inline; }
.No { font-style: normal;
font-weight: normal; }
.Em { font-style: italic;
@@ -201,3 +235,19 @@ a.Ux { }
.Li { font-style: normal;
font-weight: normal;
font-family: monospace; }
+
+/* Overrides to avoid excessive margins on small devices. */
+
+@media (max-width: 37.5em) {
+.manual-text {
+ margin-left: 0.5em; }
+.Sh, .Ss { margin-left: 0em; }
+.Bd-indent { margin-left: 2em; }
+.Bl-hang > dd {
+ margin-left: 2em; }
+.Bl-tag { margin-left: 2em; }
+.Bl-tag > dt {
+ margin-left: -2em; }
+.HP { margin-left: 2em;
+ text-indent: -2em; }
+}
diff --git a/mandoc.h b/mandoc.h
index b234cb5ee136..dbc266cc3b06 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,7 +1,7 @@
-/* $Id: mandoc.h,v 1.245 2017/07/08 14:51:04 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.248 2018/07/28 18:34:15 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -56,9 +56,10 @@ enum mandocerr {
MANDOCERR_STYLE, /* ===== start of style suggestions ===== */
MANDOCERR_DATE_LEGACY, /* legacy man(7) date format: Dd ... */
+ MANDOCERR_DATE_NORM, /* normalizing date format to: ... */
MANDOCERR_TITLE_CASE, /* lower case character in document title */
MANDOCERR_RCS_REP, /* duplicate RCS id: ... */
- MANDOCERR_SEC_TYPO, /* typo in section name: Sh ... */
+ MANDOCERR_SEC_TYPO, /* possible typo in section name: Sh ... */
MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */
MANDOCERR_MACRO_USELESS, /* useless macro: macro */
MANDOCERR_BX, /* consider using OS macro: macro */
@@ -68,6 +69,7 @@ enum mandocerr {
MANDOCERR_DELIM_NB, /* no blank before trailing delimiter: macro ... */
MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */
MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */
+ MANDOCERR_DASHDASH, /* verbatim "--", maybe consider using \(em */
MANDOCERR_FUNC, /* function name without markup: name() */
MANDOCERR_SPACE_EOL, /* whitespace at end of input line */
MANDOCERR_COMMENT_BAD, /* bad comment style */
diff --git a/mandoc_aux.c b/mandoc_aux.c
index db593e444c48..5d595ce0c292 100644
--- a/mandoc_aux.c
+++ b/mandoc_aux.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc_aux.c,v 1.10 2017/06/12 19:05:47 schwarze Exp $ */
+/* $Id: mandoc_aux.c,v 1.11 2018/02/07 20:04:57 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -111,8 +111,8 @@ mandoc_strndup(const char *ptr, size_t sz)
{
char *p;
- p = mandoc_malloc(sz + 1);
- memcpy(p, ptr, sz);
- p[(int)sz] = '\0';
+ p = strndup(ptr, sz);
+ if (p == NULL)
+ err((int)MANDOCLEVEL_SYSERR, NULL);
return p;
}
diff --git a/mandoc_char.7 b/mandoc_char.7
index a372b3e91dfc..f63cdaea8fcc 100644
--- a/mandoc_char.7
+++ b/mandoc_char.7
@@ -1,4 +1,4 @@
-.\" $Id: mandoc_char.7,v 1.67 2017/06/14 20:57:07 schwarze Exp $
+.\" $Id: mandoc_char.7,v 1.72 2018/08/08 14:30:48 schwarze Exp $
.\"
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -16,7 +16,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 14 2017 $
+.Dd $Mdocdate: August 8 2018 $
.Dt MANDOC_CHAR 7
.Os
.Sh NAME
@@ -35,23 +35,37 @@ documents.
.Pp
The rendering depends on the
.Xr mandoc 1
-output mode; in ASCII output, most characters are completely
-unintelligible.
-For that reason, using any of the special characters documented here,
-except those discussed in the
+output mode; it can be inspected by calling
+.Xr man 1
+on the
+.Nm
+manual page with different
+.Fl T
+arguments.
+In ASCII output, the rendering of some characters may be hard
+to interpret for the reader.
+Many are rendered as descriptive strings like
+.Qq <integral> ,
+.Qq <degree> ,
+or
+.Qq <Gamma> ,
+which may look ugly, and many are replaced by similar ASCII characters.
+In particular, accented characters are usually shown without the accent.
+For that reason, try to avoid using any of the special characters
+documented here except those discussed in the
.Sx DESCRIPTION ,
-is strongly discouraged; they are supported merely for backwards
-compatibility with existing documents.
+unless they are essential for explaining the subject matter at hand,
+for example when documenting complicated mathematical functions.
.Pp
In particular, in English manual pages, do not use special-character
escape sequences to represent national language characters in author
names; instead, provide ASCII transcriptions of the names.
.Ss Dashes and Hyphens
In typography there are different types of dashes of various width:
-the hyphen (-),
-the minus sign (\(mi),
+the hyphen (\(hy),
the en-dash (\(en),
-and the em-dash (\(em).
+the em-dash (\(em),
+and the mathematical minus sign (\(mi).
.Pp
Hyphens are used for adjectives;
to separate the two parts of a compound word;
@@ -62,6 +76,42 @@ blue-eyed
lorry-driver
.Ed
.Pp
+The en-dash is used to separate the two elements of a range,
+or can be used the same way as an em-dash.
+It should be written as
+.Sq \e(en :
+.Bd -unfilled -offset indent
+pp. 95\e(en97.
+Go away \e(en or else!
+.Ed
+.Pp
+The em-dash can be used to show an interruption
+or can be used the same way as colons, semi-colons, or parentheses.
+It should be written as
+.Sq \e(em :
+.Bd -unfilled -offset indent
+Three things \e(em apples, oranges, and bananas.
+This is not that \e(em rather, this is that.
+.Ed
+.Pp
+In
+.Xr roff 7
+documents, the minus sign is normally written as
+.Sq \e- .
+In manual pages, some style guides recommend to also use
+.Sq \e-
+if an ASCII 0x2d
+.Dq hyphen-minus
+output glyph that can be copied and pasted is desired in output modes
+supporting it, for example in
+.Fl T Cm utf8
+and
+.Fl T Cm html .
+But currently, no practically relevant manual page formatter actually
+requires that subtlety, so in manual pages just write plain
+.Sq -
+to represent hyphen, minus, and hyphen-minus.
+.Pp
If a word on a text input line contains a hyphen, a formatter may decide
to insert an output line break after the hyphen if that helps filling
the current output line, but the whole word would overflow the line.
@@ -85,37 +135,6 @@ Such automatic hyphenation is not supported by
.Xr mandoc 1 ,
which only breaks the line at whitespace, and inside words only
after existing hyphens.
-.Pp
-The mathematical minus sign is used for negative numbers or subtraction.
-It should be written as
-.Sq \e(mi :
-.Bd -unfilled -offset indent
-a = 3 \e(mi 1;
-b = \e(mi2;
-.Ed
-.Pp
-The en-dash is used to separate the two elements of a range,
-or can be used the same way as an em-dash.
-It should be written as
-.Sq \e(en :
-.Bd -unfilled -offset indent
-pp. 95\e(en97.
-Go away \e(en or else!
-.Ed
-.Pp
-The em-dash can be used to show an interruption
-or can be used the same way as colons, semi-colons, or parentheses.
-It should be written as
-.Sq \e(em :
-.Bd -unfilled -offset indent
-Three things \e(em apples, oranges, and bananas.
-This is not that \e(em rather, this is that.
-.Ed
-.Pp
-Note:
-hyphens, minus signs, and en-dashes look identical under normal ASCII output.
-Other formats, such as PostScript, render them correctly,
-with differing widths.
.Ss Spaces
To separate words in normal text, for indenting and alignment
in literal context, and when none of the following special cases apply,
@@ -319,8 +338,8 @@ Quotes:
.It \e(rq Ta \(rq Ta right double-quote
.It \e(oq Ta \(oq Ta left single-quote
.It \e(cq Ta \(cq Ta right single-quote
-.It \e(aq Ta \(aq Ta apostrophe quote (text)
-.It \e(dq Ta \(dq Ta double quote (text)
+.It \e(aq Ta \(aq Ta apostrophe quote (ASCII character)
+.It \e(dq Ta \(dq Ta double quote (ASCII character)
.It \e(Fo Ta \(Fo Ta left guillemet
.It \e(Fc Ta \(Fc Ta right guillemet
.It \e(fo Ta \(fo Ta left single guillemet
@@ -336,7 +355,7 @@ Brackets:
.It \e(rC Ta \(rC Ta right brace
.It \e(la Ta \(la Ta left angle
.It \e(ra Ta \(ra Ta right angle
-.It \e(bv Ta \(bv Ta brace extension
+.It \e(bv Ta \(bv Ta brace extension (special font)
.It \e[braceex] Ta \[braceex] Ta brace extension
.It \e[bracketlefttp] Ta \[bracketlefttp] Ta top-left hooked bracket
.It \e[bracketleftbt] Ta \[bracketleftbt] Ta bottom-left hooked bracket
@@ -389,8 +408,8 @@ Logical:
.It Em Input Ta Em Rendered Ta Em Description
.It \e(AN Ta \(AN Ta logical and
.It \e(OR Ta \(OR Ta logical or
-.It \e(no Ta \(no Ta logical not
-.It \e[tno] Ta \[tno] Ta logical not (text)
+.It \e[tno] Ta \[tno] Ta logical not (text font)
+.It \e(no Ta \(no Ta logical not (special font)
.It \e(te Ta \(te Ta existential quantifier
.It \e(fa Ta \(fa Ta universal quantifier
.It \e(st Ta \(st Ta such that
@@ -402,19 +421,20 @@ Logical:
Mathematical:
.Bl -column "xxcoproductxx" "Rendered" "Description" -offset indent -compact
.It Em Input Ta Em Rendered Ta Em Description
-.It \e(pl Ta \(pl Ta plus
-.It \e(mi Ta \(mi Ta minus
-.It \e- Ta \- Ta minus (text)
+.It \e- Ta \- Ta minus (text font)
+.It \e(mi Ta \(mi Ta minus (special font)
+.It + Ta + Ta plus (text font)
+.It \e(pl Ta \(pl Ta plus (special font)
.It \e(-+ Ta \(-+ Ta minus-plus
-.It \e(+- Ta \(+- Ta plus-minus
-.It \e[t+-] Ta \[t+-] Ta plus-minus (text)
+.It \e[t+-] Ta \[t+-] Ta plus-minus (text font)
+.It \e(+- Ta \(+- Ta plus-minus (special font)
.It \e(pc Ta \(pc Ta center-dot
-.It \e(mu Ta \(mu Ta multiply
-.It \e[tmu] Ta \[tmu] Ta multiply (text)
+.It \e[tmu] Ta \[tmu] Ta multiply (text font)
+.It \e(mu Ta \(mu Ta multiply (special font)
.It \e(c* Ta \(c* Ta circle-multiply
.It \e(c+ Ta \(c+ Ta circle-plus
-.It \e(di Ta \(di Ta divide
-.It \e[tdi] Ta \[tdi] Ta divide (text)
+.It \e[tdi] Ta \[tdi] Ta divide (text font)
+.It \e(di Ta \(di Ta divide (special font)
.It \e(f/ Ta \(f/ Ta fraction
.It \e(** Ta \(** Ta asterisk
.It \e(<= Ta \(<= Ta less-than-equal
@@ -511,8 +531,8 @@ Accents:
.It \e(ao Ta \(ao Ta ring
.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)
+.It \e(ha Ta \(ha Ta hat (ASCII character)
+.It \e(ti Ta \(ti Ta tilde (ASCII character)
.El
.Pp
Accented letters:
diff --git a/mandoc_html.3 b/mandoc_html.3
index ba25e0ad6a7d..5bd9446da824 100644
--- a/mandoc_html.3
+++ b/mandoc_html.3
@@ -1,6 +1,6 @@
-.\" $Id: mandoc_html.3,v 1.10 2017/07/15 17:57:51 schwarze Exp $
+.\" $Id: mandoc_html.3,v 1.17 2018/06/25 16:54:59 schwarze Exp $
.\"
-.\" Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -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: July 15 2017 $
+.Dd $Mdocdate: June 25 2018 $
.Dt MANDOC_HTML 3
.Os
.Sh NAME
@@ -25,6 +25,8 @@
.Ft void
.Fn print_gen_decls "struct html *h"
.Ft void
+.Fn print_gen_comment "struct html *h" "struct roff_node *n"
+.Ft void
.Fn print_gen_head "struct html *h"
.Ft struct tag *
.Fo print_otag
@@ -109,6 +111,18 @@ and
declarations required for the current document type.
.Pp
The function
+.Fn print_gen_comment
+prints the leading comments, usually containing a Copyright notice
+and license, as an HTML comment.
+It is intended to be called right after opening the
+.Aq Ic HTML
+element.
+Pass the first
+.Dv ROFFT_COMMENT
+node in
+.Fa n .
+.Pp
+The function
.Fn print_gen_head
prints the opening
.Aq Ic META
@@ -198,84 +212,10 @@ Print a
.Cm style
attribute.
If present, it must be the last format letter.
-In contrast to the other format letters, this one does not yet
-print the value and does not take an argument.
-Instead, the rest of the format string consists of pairs of
-argument type letters and style name letters.
-.El
-.Pp
-Argument type letters each require one argument as follows:
-.Bl -tag -width 1n -offset indent
-.It Cm h
-Requires one
-.Vt int
-argument, interpreted as a horizontal length in units of
-.Dv SCALE_EN .
-.It Cm s
-Requires one
-.Vt char *
-argument, used as a style value.
-.It Cm u
-Requires one
-.Vt struct roffsu *
-argument, used as a length.
-.It Cm w
-Requires one
-.Vt char *
-argument, interpreted as an
-.Xr mdoc 7 Ns -style
-width specifier.
-If the argument is
-.Dv NULL ,
-nothing is printed for this pair.
-.Pp
-The
-.Cm w
-argument type letter can optionally be followed by one, two, or three
-modifier letters.
-The modifier
-.Cm *
-suppresses printing of the pair if the argument matches 6n.
-The modifier
-.Cm +
-increases the width by 20% to make even bold text fit
-and adds three units for padding between columns.
-The modifier
-.Cm \-
-makes the width negative by multiplying it with \-1.
-.El
-.Pp
-Style name letters decide what to do with the preceding argument:
-.Bl -tag -width 1n -offset indent
-.It Cm h
-Set
-.Cm height
-to the given length.
-.It Cm i
-Set
-.Cm text-indent
-to the given length.
-.It Cm l
-Set
-.Cm margin-left
-to the given length.
-.It Cm w
-Set
-.Cm width
-to the given length.
-.It Cm W
-Set
-.Cm min-width
-to the given length.
-.It Cm \&?
-The special pair
-.Cm s?
-requires two
-.Vt char *
+It requires two
+.Va char *
arguments.
-The first is the style name, the second its value.
-The style name must not be
-.Dv NULL .
+The first is the name of the style property, the second its value.
.El
.Pp
.Fn print_otag
diff --git a/mandocdb.c b/mandocdb.c
index 26117cf82781..86dbce2d9fe6 100644
--- a/mandocdb.c
+++ b/mandocdb.c
@@ -1,4 +1,4 @@
-/* $Id: mandocdb.c,v 1.253 2017/07/28 14:48:25 schwarze Exp $ */
+/* $Id: mandocdb.c,v 1.258 2018/02/23 18:25:57 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -19,8 +19,8 @@
#include "config.h"
#include <sys/types.h>
+#include <sys/mman.h>
#include <sys/stat.h>
-#include <sys/wait.h>
#include <assert.h>
#include <ctype.h>
@@ -139,6 +139,8 @@ 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_Fa(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 *);
@@ -207,11 +209,11 @@ static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = {
{ NULL, TYPE_Er, 0 }, /* Er */
{ NULL, TYPE_Ev, 0 }, /* Ev */
{ NULL, 0, 0 }, /* Ex */
- { NULL, TYPE_Fa, 0 }, /* Fa */
+ { parse_mdoc_Fa, 0, 0 }, /* Fa */
{ parse_mdoc_Fd, 0, 0 }, /* Fd */
{ NULL, TYPE_Fl, 0 }, /* Fl */
{ parse_mdoc_Fn, 0, 0 }, /* Fn */
- { NULL, TYPE_Ft, 0 }, /* Ft */
+ { NULL, TYPE_Ft | TYPE_Vt, 0 }, /* Ft */
{ NULL, TYPE_Ic, 0 }, /* Ic */
{ NULL, TYPE_In, 0 }, /* In */
{ NULL, TYPE_Li, 0 }, /* Li */
@@ -319,7 +321,7 @@ mandocdb(int argc, char *argv[])
int ch, i;
#if HAVE_PLEDGE
- if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) {
+ if (pledge("stdio rpath wpath cpath", NULL) == -1) {
warn("pledge");
return (int)MANDOCLEVEL_SYSERR;
}
@@ -440,15 +442,6 @@ 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]);
@@ -1382,7 +1375,12 @@ parse_cat(struct mpage *mpage, int fd)
plen -= 2;
}
- mpage->desc = mandoc_strdup(p);
+ /*
+ * Cut off excessive one-line descriptions.
+ * Bad pages are not worth better heuristics.
+ */
+
+ mpage->desc = mandoc_strndup(p, 150);
fclose(stream);
free(title);
}
@@ -1526,7 +1524,12 @@ parse_man(struct mpage *mpage, const struct roff_meta *meta,
while (' ' == *start)
start++;
- mpage->desc = mandoc_strdup(start);
+ /*
+ * Cut off excessive one-line descriptions.
+ * Bad pages are not worth better heuristics.
+ */
+
+ mpage->desc = mandoc_strndup(start, 150);
free(title);
return;
}
@@ -1572,6 +1575,20 @@ parse_mdoc(struct mpage *mpage, const struct roff_meta *meta,
}
static int
+parse_mdoc_Fa(struct mpage *mpage, const struct roff_meta *meta,
+ const struct roff_node *n)
+{
+ uint64_t mask;
+
+ mask = TYPE_Fa;
+ if (n->sec == SEC_SYNOPSIS)
+ mask |= TYPE_Vt;
+
+ putmdockey(mpage, n->child, mask, 0);
+ return 0;
+}
+
+static int
parse_mdoc_Fd(struct mpage *mpage, const struct roff_meta *meta,
const struct roff_node *n)
{
@@ -1640,15 +1657,20 @@ static int
parse_mdoc_Fn(struct mpage *mpage, const struct roff_meta *meta,
const struct roff_node *n)
{
+ uint64_t mask;
if (n->child == NULL)
return 0;
parse_mdoc_fname(mpage, n->child);
- for (n = n->child->next; n != NULL; n = n->next)
- if (n->type == ROFFT_TEXT)
- putkey(mpage, n->string, TYPE_Fa);
+ n = n->child->next;
+ if (n != NULL && n->type == ROFFT_TEXT) {
+ mask = TYPE_Fa;
+ if (n->sec == SEC_SYNOPSIS)
+ mask |= TYPE_Vt;
+ putmdockey(mpage, n, mask, 0);
+ }
return 0;
}
@@ -2119,9 +2141,10 @@ dbprune(struct dba *dba)
static void
dbwrite(struct dba *dba)
{
- char tfn[32];
- int status;
- pid_t child;
+ struct stat sb1, sb2;
+ char tfn[33], *cp1, *cp2;
+ off_t i;
+ int fd1, fd2;
/*
* Do not write empty databases, and delete existing ones
@@ -2160,59 +2183,62 @@ dbwrite(struct dba *dba)
say("", "&%s", tfn);
return;
}
-
+ cp1 = cp2 = MAP_FAILED;
+ fd1 = fd2 = -1;
(void)strlcat(tfn, "/" MANDOC_DB, sizeof(tfn));
if (dba_write(tfn, dba) == -1) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
say(tfn, "&dba_write");
- goto out;
+ goto err;
}
-
- switch (child = fork()) {
- case -1:
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say("", "&fork cmp");
- return;
- case 0:
- execlp("cmp", "cmp", "-s", tfn, MANDOC_DB, (char *)NULL);
- say("", "&exec cmp");
- exit(0);
- default:
- break;
+ if ((fd1 = open(MANDOC_DB, O_RDONLY, 0)) == -1) {
+ say(MANDOC_DB, "&open");
+ goto err;
}
- if (waitpid(child, &status, 0) == -1) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say("", "&wait cmp");
- } else if (WIFSIGNALED(status)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say("", "cmp died from signal %d", WTERMSIG(status));
- } else if (WEXITSTATUS(status)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(MANDOC_DB,
- "Data changed, but cannot replace database");
+ if ((fd2 = open(tfn, O_RDONLY, 0)) == -1) {
+ say(tfn, "&open");
+ goto err;
+ }
+ if (fstat(fd1, &sb1) == -1) {
+ say(MANDOC_DB, "&fstat");
+ goto err;
+ }
+ if (fstat(fd2, &sb2) == -1) {
+ say(tfn, "&fstat");
+ goto err;
}
+ if (sb1.st_size != sb2.st_size)
+ goto err;
+ if ((cp1 = mmap(NULL, sb1.st_size, PROT_READ, MAP_PRIVATE,
+ fd1, 0)) == MAP_FAILED) {
+ say(MANDOC_DB, "&mmap");
+ goto err;
+ }
+ if ((cp2 = mmap(NULL, sb2.st_size, PROT_READ, MAP_PRIVATE,
+ fd2, 0)) == MAP_FAILED) {
+ say(tfn, "&mmap");
+ goto err;
+ }
+ for (i = 0; i < sb1.st_size; i++)
+ if (cp1[i] != cp2[i])
+ goto err;
+ goto out;
+
+err:
+ exitcode = (int)MANDOCLEVEL_SYSERR;
+ say(MANDOC_DB, "Data changed, but cannot replace database");
out:
+ if (cp1 != MAP_FAILED)
+ munmap(cp1, sb1.st_size);
+ if (cp2 != MAP_FAILED)
+ munmap(cp2, sb2.st_size);
+ if (fd1 != -1)
+ close(fd1);
+ if (fd2 != -1)
+ close(fd2);
+ unlink(tfn);
*strrchr(tfn, '/') = '\0';
- switch (child = fork()) {
- case -1:
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say("", "&fork rm");
- return;
- case 0:
- execlp("rm", "rm", "-rf", tfn, (char *)NULL);
- say("", "&exec rm");
- exit((int)MANDOCLEVEL_SYSERR);
- default:
- break;
- }
- if (waitpid(child, &status, 0) == -1) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say("", "&wait rm");
- } else if (WIFSIGNALED(status) || WEXITSTATUS(status)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say("", "%s: Cannot remove temporary directory", tfn);
- }
+ rmdir(tfn);
}
static int
diff --git a/mansearch.c b/mansearch.c
index 0d60c3bed731..784c17bee714 100644
--- a/mansearch.c
+++ b/mansearch.c
@@ -1,4 +1,4 @@
-/* $Id: mansearch.c,v 1.76 2017/08/02 13:29:04 schwarze Exp $ */
+/* $Id: mansearch.c,v 1.77 2017/08/22 17:50:11 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -188,6 +188,16 @@ mansearch(const struct mansearch *search,
mpage = *res + cur;
mandoc_asprintf(&mpage->file, "%s/%s",
paths->paths[i], page->file + 1);
+ if (access(chdir_status ? page->file + 1 :
+ mpage->file, R_OK) == -1) {
+ warn("%s", mpage->file);
+ warnx("outdated mandoc.db contains "
+ "bogus %s entry, run makewhatis %s",
+ page->file + 1, paths->paths[i]);
+ free(mpage->file);
+ free(rp);
+ continue;
+ }
mpage->names = buildnames(page);
mpage->output = buildoutput(outkey, page);
mpage->ipath = i;
diff --git a/mdoc.7 b/mdoc.7
index 5a1863c8a43b..5c07434cd80e 100644
--- a/mdoc.7
+++ b/mdoc.7
@@ -1,7 +1,7 @@
-.\" $Id: mdoc.7,v 1.269 2017/07/20 16:24:53 schwarze Exp $
+.\" $Id: mdoc.7,v 1.271 2018/07/28 18:34:15 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2010, 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2010, 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 20 2017 $
+.Dd $Mdocdate: July 28 2018 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -674,12 +674,10 @@ Examples:
.Ss \&Ao
Begin a block enclosed by angle brackets.
Does not have any head arguments.
-.Pp
-Examples:
-.Dl \&.Fl -key= \&Ns \&Ao \&Ar val \&Ac
-.Pp
-See also
-.Sx \&Aq .
+This macro is almost never useful.
+See
+.Sx \&Aq
+for more details.
.Ss \&Ap
Inserts an apostrophe without any surrounding whitespace.
This is generally used as a grammatical device when referring to the verb
@@ -689,19 +687,45 @@ Examples:
.Dl \&.Fn execve \&Ap d
.Ss \&Aq
Encloses its arguments in angle brackets.
+The only important use case is for email addresses.
+See
+.Sx \&Mt
+for an example.
.Pp
-Examples:
-.Dl \&.Fl -key= \&Ns \&Aq \&Ar val
+Occasionally, it is used for names of characters and keys, for example:
+.Bd -literal -offset indent
+Press the
+\&.Aq escape
+key to ...
+.Ed
.Pp
-.Em Remarks :
-this macro is often abused for rendering URIs, which should instead use
+For URIs, use
.Sx \&Lk
+instead, and
+.Sx \&In
+for
+.Dq #include
+directives.
+Never wrap
+.Sx \&Ar
+in
+.Sx \&Aq .
+.Pp
+Since
+.Sx \&Aq
+usually renders with non-ASCII characters in non-ASCII output modes,
+do not use it where the ASCII characters
+.Sq <
+and
+.Sq >
+are required as syntax elements.
+Instead, use these characters directly in such cases, combining them
+with the macros
+.Sx \&Pf ,
+.Sx \&Ns ,
or
-.Sx \&Mt ,
-or to note pre-processor
-.Dq Li #include
-statements, which should use
-.Sx \&In .
+.Sx \&Eo
+as needed.
.Pp
See also
.Sx \&Ao .
@@ -1210,7 +1234,7 @@ The
.Ar month
is the full English month name, the
.Ar day
-is an optionally zero-padded numeral, and the
+is an integer number, and the
.Ar year
is the full four-digit year.
.Pp
@@ -1240,8 +1264,8 @@ If no date string is given, the current date is used.
.Pp
Examples:
.Dl \&.Dd $\&Mdocdate$
-.Dl \&.Dd $\&Mdocdate: July 21 2007$
-.Dl \&.Dd July 21, 2007
+.Dl \&.Dd $\&Mdocdate: July 2 2018$
+.Dl \&.Dd July 2, 2018
.Pp
See also
.Sx \&Dt
diff --git a/mdoc.c b/mdoc.c
index 7afcc5d29e1c..71803531ddfb 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.267 2017/06/17 13:06:16 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.268 2017/08/11 16:56:21 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -297,8 +297,8 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
if (end - c < 3)
break;
if (c[1] != ' ' ||
- isalpha((unsigned char)c[-2]) == 0 ||
- isalpha((unsigned char)c[-1]) == 0 ||
+ isalnum((unsigned char)c[-2]) == 0 ||
+ isalnum((unsigned char)c[-1]) == 0 ||
(c[-2] == 'n' && c[-1] == 'c') ||
(c[-2] == 'v' && c[-1] == 's'))
continue;
diff --git a/mdoc_html.c b/mdoc_html.c
index 0b4b9adf34f2..f50de8a77af0 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -1,7 +1,7 @@
-/* $Id: mdoc_html.c,v 1.294 2017/07/15 17:57:51 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.310 2018/07/27 17:49:31 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -34,8 +34,6 @@
#include "html.h"
#include "main.h"
-#define INDENT 5
-
#define MDOC_ARGS const struct roff_meta *meta, \
struct roff_node *n, \
struct html *h
@@ -50,14 +48,17 @@ struct htmlmdoc {
};
static char *cond_id(const struct roff_node *);
-static void print_mdoc_head(MDOC_ARGS);
+static void print_mdoc_head(const struct roff_meta *,
+ struct html *);
static void print_mdoc_node(MDOC_ARGS);
static void print_mdoc_nodelist(MDOC_ARGS);
static void synopsis_pre(struct html *,
const struct roff_node *);
-static void mdoc_root_post(MDOC_ARGS);
-static int mdoc_root_pre(MDOC_ARGS);
+static void mdoc_root_post(const struct roff_meta *,
+ struct html *);
+static int mdoc_root_pre(const struct roff_meta *,
+ struct html *);
static void mdoc__x_post(MDOC_ARGS);
static int mdoc__x_pre(MDOC_ARGS);
@@ -284,30 +285,34 @@ synopsis_pre(struct html *h, const struct roff_node *n)
void
html_mdoc(void *arg, const struct roff_man *mdoc)
{
- struct html *h;
- struct tag *t;
+ struct html *h;
+ struct roff_node *n;
+ struct tag *t;
h = (struct html *)arg;
+ n = mdoc->first->child;
if ((h->oflags & HTML_FRAGMENT) == 0) {
print_gen_decls(h);
print_otag(h, TAG_HTML, "");
+ if (n->type == ROFFT_COMMENT)
+ print_gen_comment(h, n);
t = print_otag(h, TAG_HEAD, "");
- print_mdoc_head(&mdoc->meta, mdoc->first->child, h);
+ print_mdoc_head(&mdoc->meta, h);
print_tagq(h, t);
print_otag(h, TAG_BODY, "");
}
- mdoc_root_pre(&mdoc->meta, mdoc->first->child, h);
+ mdoc_root_pre(&mdoc->meta, h);
t = print_otag(h, TAG_DIV, "c", "manual-text");
- print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h);
+ print_mdoc_nodelist(&mdoc->meta, n, h);
print_tagq(h, t);
- mdoc_root_post(&mdoc->meta, mdoc->first->child, h);
+ mdoc_root_post(&mdoc->meta, h);
print_tagq(h, NULL);
}
static void
-print_mdoc_head(MDOC_ARGS)
+print_mdoc_head(const struct roff_meta *meta, struct html *h)
{
char *cp;
@@ -344,7 +349,7 @@ print_mdoc_node(MDOC_ARGS)
int child;
struct tag *t;
- if (n->flags & NODE_NOPRT)
+ if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
return;
child = 1;
@@ -429,7 +434,7 @@ print_mdoc_node(MDOC_ARGS)
}
static void
-mdoc_root_post(MDOC_ARGS)
+mdoc_root_post(const struct roff_meta *meta, struct html *h)
{
struct tag *t, *tt;
@@ -446,7 +451,7 @@ mdoc_root_post(MDOC_ARGS)
}
static int
-mdoc_root_pre(MDOC_ARGS)
+mdoc_root_pre(const struct roff_meta *meta, struct html *h)
{
struct tag *t, *tt;
char *volume, *title;
@@ -495,7 +500,7 @@ cond_id(const struct roff_node *n)
(n->parent->tok == MDOC_Xo &&
n->parent->parent->prev == NULL &&
n->parent->parent->parent->tok == MDOC_It)))
- return html_make_id(n);
+ return html_make_id(n, 1);
return NULL;
}
@@ -506,11 +511,10 @@ mdoc_sh_pre(MDOC_ARGS)
switch (n->type) {
case ROFFT_HEAD:
- id = html_make_id(n);
+ id = html_make_id(n, 1);
print_otag(h, TAG_H1, "cTi", "Sh", id);
if (id != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
break;
case ROFFT_BODY:
if (n->sec == SEC_AUTHORS)
@@ -530,11 +534,10 @@ mdoc_ss_pre(MDOC_ARGS)
if (n->type != ROFFT_HEAD)
return 1;
- id = html_make_id(n);
+ id = html_make_id(n, 1);
print_otag(h, TAG_H2, "cTi", "Ss", id);
if (id != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
return 1;
}
@@ -544,9 +547,8 @@ mdoc_fl_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- print_otag(h, TAG_B, "cTi", "Fl", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
+ print_otag(h, TAG_CODE, "cTi", "Fl", id);
print_text(h, "\\-");
if (!(n->child == NULL &&
@@ -564,9 +566,8 @@ mdoc_cm_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- print_otag(h, TAG_B, "cTi", "Cm", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
+ print_otag(h, TAG_CODE, "cTi", "Cm", id);
return 1;
}
@@ -576,10 +577,9 @@ mdoc_nd_pre(MDOC_ARGS)
if (n->type != ROFFT_BODY)
return 1;
- /* XXX: this tag in theory can contain block elements. */
-
print_text(h, "\\(em");
- print_otag(h, TAG_SPAN, "cT", "Nd");
+ /* Cannot use TAG_SPAN because it may contain blocks. */
+ print_otag(h, TAG_DIV, "cT", "Nd");
return 1;
}
@@ -591,7 +591,7 @@ mdoc_nm_pre(MDOC_ARGS)
print_otag(h, TAG_TD, "");
/* FALLTHROUGH */
case ROFFT_ELEM:
- print_otag(h, TAG_B, "cT", "Nm");
+ print_otag(h, TAG_CODE, "cT", "Nm");
return 1;
case ROFFT_BODY:
print_otag(h, TAG_TD, "");
@@ -661,7 +661,6 @@ mdoc_it_pre(MDOC_ARGS)
{
const struct roff_node *bl;
struct tag *t;
- const char *cattr;
enum mdoc_list type;
bl = n->parent;
@@ -671,42 +670,6 @@ mdoc_it_pre(MDOC_ARGS)
switch (type) {
case LIST_bullet:
- cattr = "It-bullet";
- break;
- case LIST_dash:
- case LIST_hyphen:
- cattr = "It-dash";
- break;
- case LIST_item:
- cattr = "It-item";
- break;
- case LIST_enum:
- cattr = "It-enum";
- break;
- case LIST_diag:
- cattr = "It-diag";
- break;
- case LIST_hang:
- cattr = "It-hang";
- break;
- case LIST_inset:
- cattr = "It-inset";
- break;
- case LIST_ohang:
- cattr = "It-ohang";
- break;
- case LIST_tag:
- cattr = "It-tag";
- break;
- case LIST_column:
- cattr = "It-column";
- break;
- default:
- break;
- }
-
- switch (type) {
- case LIST_bullet:
case LIST_dash:
case LIST_hyphen:
case LIST_item:
@@ -715,7 +678,7 @@ mdoc_it_pre(MDOC_ARGS)
case ROFFT_HEAD:
return 0;
case ROFFT_BODY:
- print_otag(h, TAG_LI, "c", cattr);
+ print_otag(h, TAG_LI, "");
break;
default:
break;
@@ -727,13 +690,10 @@ mdoc_it_pre(MDOC_ARGS)
case LIST_ohang:
switch (n->type) {
case ROFFT_HEAD:
- print_otag(h, TAG_DT, "c", cattr);
- if (type == LIST_diag)
- print_otag(h, TAG_B, "c", cattr);
+ print_otag(h, TAG_DT, "");
break;
case ROFFT_BODY:
- print_otag(h, TAG_DD, "csw*+l", cattr,
- bl->norm->Bl.width);
+ print_otag(h, TAG_DD, "");
break;
default:
break;
@@ -746,24 +706,21 @@ mdoc_it_pre(MDOC_ARGS)
(n->parent->prev == NULL ||
n->parent->prev->body == NULL ||
n->parent->prev->body->child != NULL)) {
- t = print_otag(h, TAG_DT, "csw*+-l",
- cattr, bl->norm->Bl.width);
+ t = print_otag(h, TAG_DT, "");
print_text(h, "\\ ");
print_tagq(h, t);
- t = print_otag(h, TAG_DD, "c", cattr);
+ t = print_otag(h, TAG_DD, "");
print_text(h, "\\ ");
print_tagq(h, t);
}
- print_otag(h, TAG_DT, "csw*+-l", cattr,
- bl->norm->Bl.width);
+ print_otag(h, TAG_DT, "");
break;
case ROFFT_BODY:
if (n->child == NULL) {
- print_otag(h, TAG_DD, "css?", cattr,
- "width", "auto");
+ print_otag(h, TAG_DD, "s", "width", "auto");
print_text(h, "\\ ");
} else
- print_otag(h, TAG_DD, "c", cattr);
+ print_otag(h, TAG_DD, "");
break;
default:
break;
@@ -774,10 +731,10 @@ mdoc_it_pre(MDOC_ARGS)
case ROFFT_HEAD:
break;
case ROFFT_BODY:
- print_otag(h, TAG_TD, "c", cattr);
+ print_otag(h, TAG_TD, "");
break;
default:
- print_otag(h, TAG_TR, "c", cattr);
+ print_otag(h, TAG_TR, "");
}
default:
break;
@@ -789,40 +746,20 @@ mdoc_it_pre(MDOC_ARGS)
static int
mdoc_bl_pre(MDOC_ARGS)
{
- char cattr[21];
- struct tag *t;
+ char cattr[28];
struct mdoc_bl *bl;
- size_t i;
enum htmltag elemtype;
- bl = &n->norm->Bl;
-
switch (n->type) {
case ROFFT_BODY:
return 1;
-
case ROFFT_HEAD:
- if (bl->type != LIST_column || bl->ncols == 0)
- return 0;
-
- /*
- * For each column, print out the <COL> tag with our
- * suggested width. The last column gets min-width, as
- * in terminal mode it auto-sizes to the width of the
- * screen and we want to preserve that behaviour.
- */
-
- t = print_otag(h, TAG_COLGROUP, "");
- for (i = 0; i < bl->ncols - 1; i++)
- print_otag(h, TAG_COL, "sw+w", bl->cols[i]);
- print_otag(h, TAG_COL, "swW", bl->cols[i]);
- print_tagq(h, t);
return 0;
-
default:
break;
}
+ bl = &n->norm->Bl;
switch (bl->type) {
case LIST_bullet:
elemtype = TAG_UL;
@@ -859,9 +796,9 @@ mdoc_bl_pre(MDOC_ARGS)
break;
case LIST_tag:
if (bl->offs)
- print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs);
- print_otag(h, TAG_DL, "csw*+l", bl->comp ?
- "Bl-tag Bl-compact" : "Bl-tag", bl->width);
+ print_otag(h, TAG_DIV, "c", "Bd-indent");
+ print_otag(h, TAG_DL, "c", bl->comp ?
+ "Bl-tag Bl-compact" : "Bl-tag");
return 1;
case LIST_column:
elemtype = TAG_TABLE;
@@ -870,9 +807,11 @@ mdoc_bl_pre(MDOC_ARGS)
default:
abort();
}
+ if (bl->offs != NULL)
+ (void)strlcat(cattr, " Bd-indent", sizeof(cattr));
if (bl->comp)
(void)strlcat(cattr, " Bl-compact", sizeof(cattr));
- print_otag(h, elemtype, "cswl", cattr, bl->offs);
+ print_otag(h, elemtype, "c", cattr);
return 1;
}
@@ -904,7 +843,7 @@ mdoc_d1_pre(MDOC_ARGS)
if (n->type != ROFFT_BLOCK)
return 1;
- print_otag(h, TAG_DIV, "c", "D1");
+ print_otag(h, TAG_DIV, "c", "Bd Bd-indent");
if (n->tok == MDOC_Dl)
print_otag(h, TAG_CODE, "c", "Li");
@@ -917,7 +856,7 @@ mdoc_sx_pre(MDOC_ARGS)
{
char *id;
- id = html_make_id(n);
+ id = html_make_id(n, 0);
print_otag(h, TAG_A, "cThR", "Sx", id);
free(id);
return 1;
@@ -926,7 +865,7 @@ mdoc_sx_pre(MDOC_ARGS)
static int
mdoc_bd_pre(MDOC_ARGS)
{
- int comp, offs, sv;
+ int comp, sv;
struct roff_node *nn;
if (n->type == ROFFT_HEAD)
@@ -951,18 +890,9 @@ mdoc_bd_pre(MDOC_ARGS)
if (n->norm->Bd.offs == NULL ||
! strcmp(n->norm->Bd.offs, "left"))
- offs = 0;
- else if ( ! strcmp(n->norm->Bd.offs, "indent"))
- offs = INDENT;
- else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
- offs = INDENT * 2;
- else
- offs = -1;
-
- if (offs == -1)
- print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs);
+ print_otag(h, TAG_DIV, "c", "Bd");
else
- print_otag(h, TAG_DIV, "cshl", "Bd", offs);
+ print_otag(h, TAG_DIV, "c", "Bd Bd-indent");
if (n->norm->Bd.type != DISP_unfilled &&
n->norm->Bd.type != DISP_literal)
@@ -1014,14 +944,14 @@ mdoc_bd_pre(MDOC_ARGS)
static int
mdoc_pa_pre(MDOC_ARGS)
{
- print_otag(h, TAG_I, "cT", "Pa");
+ print_otag(h, TAG_SPAN, "cT", "Pa");
return 1;
}
static int
mdoc_ad_pre(MDOC_ARGS)
{
- print_otag(h, TAG_I, "c", "Ad");
+ print_otag(h, TAG_SPAN, "c", "Ad");
return 1;
}
@@ -1053,7 +983,7 @@ static int
mdoc_cd_pre(MDOC_ARGS)
{
synopsis_pre(h, n);
- print_otag(h, TAG_B, "cT", "Cd");
+ print_otag(h, TAG_CODE, "cT", "Cd");
return 1;
}
@@ -1063,9 +993,8 @@ mdoc_dv_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
print_otag(h, TAG_CODE, "cTi", "Dv", id);
- free(id);
return 1;
}
@@ -1075,9 +1004,8 @@ mdoc_ev_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
print_otag(h, TAG_CODE, "cTi", "Ev", id);
- free(id);
return 1;
}
@@ -1090,12 +1018,11 @@ mdoc_er_pre(MDOC_ARGS)
(n->parent->tok == MDOC_It ||
(n->parent->tok == MDOC_Bq &&
n->parent->parent->parent->tok == MDOC_It)) ?
- html_make_id(n) : NULL;
+ html_make_id(n, 1) : NULL;
if (id != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
print_otag(h, TAG_CODE, "cTi", "Er", id);
- free(id);
return 1;
}
@@ -1142,11 +1069,11 @@ mdoc_fd_pre(MDOC_ARGS)
assert(n->type == ROFFT_TEXT);
if (strcmp(n->string, "#include")) {
- print_otag(h, TAG_B, "cT", "Fd");
+ print_otag(h, TAG_CODE, "cT", "Fd");
return 1;
}
- print_otag(h, TAG_B, "cT", "In");
+ print_otag(h, TAG_CODE, "cT", "In");
print_text(h, n->string);
if (NULL != (n = n->next)) {
@@ -1232,7 +1159,7 @@ mdoc_fn_pre(MDOC_ARGS)
print_tagq(h, t);
}
- t = print_otag(h, TAG_B, "cT", "Fn");
+ t = print_otag(h, TAG_CODE, "cT", "Fn");
if (sp)
print_text(h, sp);
@@ -1245,7 +1172,7 @@ mdoc_fn_pre(MDOC_ARGS)
for (n = n->child->next; n; n = n->next) {
if (NODE_SYNPRETTY & n->flags)
- t = print_otag(h, TAG_VAR, "cTss?", "Fa",
+ t = print_otag(h, TAG_VAR, "cTs", "Fa",
"white-space", "nowrap");
else
t = print_otag(h, TAG_VAR, "cT", "Fa");
@@ -1375,7 +1302,7 @@ mdoc_fo_pre(MDOC_ARGS)
return 0;
assert(n->child->string);
- t = print_otag(h, TAG_B, "cT", "Fn");
+ t = print_otag(h, TAG_CODE, "cT", "Fn");
print_text(h, n->child->string);
print_tagq(h, t);
return 0;
@@ -1399,7 +1326,7 @@ mdoc_in_pre(MDOC_ARGS)
struct tag *t;
synopsis_pre(h, n);
- print_otag(h, TAG_B, "cT", "In");
+ print_otag(h, TAG_CODE, "cT", "In");
/*
* The first argument of the `In' gets special treatment as
@@ -1444,9 +1371,8 @@ mdoc_ic_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- print_otag(h, TAG_B, "cTi", "Ic", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
+ print_otag(h, TAG_CODE, "cTi", "Ic", id);
return 1;
}
@@ -1478,20 +1404,16 @@ mdoc_bf_pre(MDOC_ARGS)
return 1;
if (FONT_Em == n->norm->Bf.font)
- cattr = "Em";
+ cattr = "Bf Em";
else if (FONT_Sy == n->norm->Bf.font)
- cattr = "Sy";
+ cattr = "Bf Sy";
else if (FONT_Li == n->norm->Bf.font)
- cattr = "Li";
+ cattr = "Bf Li";
else
- cattr = "No";
-
- /*
- * We want this to be inline-formatted, but needs to be div to
- * accept block children.
- */
+ cattr = "Bf No";
- print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1);
+ /* Cannot use TAG_SPAN because it may contain blocks. */
+ print_otag(h, TAG_DIV, "c", cattr);
return 1;
}
@@ -1501,9 +1423,8 @@ mdoc_ms_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
- print_otag(h, TAG_B, "cTi", "Ms", id);
- free(id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
+ print_otag(h, TAG_SPAN, "cTi", "Ms", id);
return 1;
}
@@ -1542,9 +1463,8 @@ mdoc_no_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
print_otag(h, TAG_SPAN, "ci", "No", id);
- free(id);
return 1;
}
@@ -1554,9 +1474,8 @@ mdoc_li_pre(MDOC_ARGS)
char *id;
if ((id = cond_id(n)) != NULL)
- print_otag(h, TAG_A, "chR", "selflink", id);
+ print_otag(h, TAG_A, "chR", "permalink", id);
print_otag(h, TAG_CODE, "ci", "Li", id);
- free(id);
return 1;
}
@@ -1712,7 +1631,8 @@ mdoc_quote_pre(MDOC_ARGS)
case MDOC_Op:
print_text(h, "\\(lB");
h->flags |= HTML_NOSPACE;
- print_otag(h, TAG_SPAN, "c", "Op");
+ /* Cannot use TAG_SPAN because it may contain blocks. */
+ print_otag(h, TAG_IDIV, "c", "Op");
break;
case MDOC_En:
if (NULL == n->norm->Es ||
diff --git a/mdoc_man.c b/mdoc_man.c
index cf552ce902bb..bcf9207f79cc 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_man.c,v 1.122 2017/06/14 22:51:25 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.126 2018/04/11 17:11:13 schwarze Exp $ */
/*
- * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -202,8 +202,8 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = {
{ NULL, pre_bk, post_bk, NULL, NULL }, /* Bx */
{ NULL, pre_skip, NULL, NULL, NULL }, /* Db */
{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
- { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */
- { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Dq */
+ { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */
+ { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */
{ NULL, NULL, NULL, NULL, NULL }, /* Ec */
{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
@@ -610,6 +610,14 @@ man_mdoc(void *arg, const struct roff_man *mdoc)
{
struct roff_node *n;
+ printf(".\\\" Automatically generated from an mdoc input file."
+ " Do not edit.\n");
+ for (n = mdoc->first->child; n != NULL; n = n->next) {
+ if (n->type != ROFFT_COMMENT)
+ break;
+ printf(".\\\"%s\n", n->string);
+ }
+
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
mdoc->meta.title,
(mdoc->meta.msec == NULL ? "" : mdoc->meta.msec),
@@ -624,7 +632,7 @@ man_mdoc(void *arg, const struct roff_man *mdoc)
fontqueue.head = fontqueue.tail = mandoc_malloc(8);
*fontqueue.tail = 'R';
}
- for (n = mdoc->first->child; n != NULL; n = n->next)
+ for (; n != NULL; n = n->next)
print_node(&mdoc->meta, n);
putchar('\n');
}
@@ -1408,7 +1416,7 @@ pre_it(DECL_ARGS)
if (bln->norm->Bl.type == LIST_diag)
print_line(".B \"", 0);
else
- print_line(".R \"", 0);
+ print_line(".BR \\& \"", 0);
outflags &= ~MMAN_spc;
return 1;
case LIST_bullet:
@@ -1547,7 +1555,6 @@ static int
pre_lk(DECL_ARGS)
{
const struct roff_node *link, *descr, *punct;
- int display;
if ((link = n->child) == NULL)
return 0;
@@ -1570,12 +1577,6 @@ pre_lk(DECL_ARGS)
}
/* Link target. */
- display = man_strlen(link->string) >= 26;
- if (display) {
- print_line(".RS", MMAN_Bk_susp);
- print_word("6n");
- outflags |= MMAN_nl;
- }
font_push('B');
print_word(link->string);
font_pop();
@@ -1585,8 +1586,6 @@ pre_lk(DECL_ARGS)
print_word(punct->string);
punct = punct->next;
}
- if (display)
- print_line(".RE", MMAN_nl);
return 0;
}
diff --git a/mdoc_markdown.c b/mdoc_markdown.c
index 0b0f184821e5..e73440a4e5cd 100644
--- a/mdoc_markdown.c
+++ b/mdoc_markdown.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_markdown.c,v 1.23 2017/06/14 01:31:26 schwarze Exp $ */
+/* $Id: mdoc_markdown.c,v 1.24 2018/04/11 17:11:13 schwarze Exp $ */
/*
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -294,7 +294,7 @@ md_node(struct roff_node *n)
const struct md_act *act;
int cond, process_children;
- if (n->flags & NODE_NOPRT)
+ if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
return;
if (outflags & MD_nonl)
diff --git a/mdoc_state.c b/mdoc_state.c
index d9cad18b1052..2d8563f5bf16 100644
--- a/mdoc_state.c
+++ b/mdoc_state.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_state.c,v 1.8 2017/05/05 15:17:32 schwarze Exp $ */
+/* $Id: mdoc_state.c,v 1.9 2017/11/29 20:05:33 schwarze Exp $ */
/*
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -208,19 +208,24 @@ state_bd(STATE_ARGS)
static void
state_bl(STATE_ARGS)
{
+ struct mdoc_arg *args;
+ size_t i;
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;
+ args = n->parent->args;
+ for (i = 0; i < args->argc; i++) {
+ switch(args->argv[i].arg) {
+ case MDOC_Diag:
+ n->norm->Bl.type = LIST_diag;
+ return;
+ case MDOC_Column:
+ n->norm->Bl.type = LIST_column;
+ return;
+ default:
+ break;
+ }
}
}
diff --git a/mdoc_term.c b/mdoc_term.c
index 4e420c5c2114..cf3e7ef3dd64 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -1,7 +1,7 @@
-/* $Id: mdoc_term.c,v 1.364 2017/06/14 17:51:15 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.367 2018/04/11 17:11:13 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -283,7 +283,9 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc)
p->defindent = 5;
term_begin(p, print_mdoc_head, print_mdoc_foot,
&mdoc->meta);
- while (n != NULL && n->flags & NODE_NOPRT)
+ while (n != NULL &&
+ (n->type == ROFFT_COMMENT ||
+ n->flags & NODE_NOPRT))
n = n->next;
if (n != NULL) {
if (n->tok != MDOC_Sh)
@@ -312,7 +314,7 @@ print_mdoc_node(DECL_ARGS)
struct termpair npair;
size_t offset, rmargin;
- if (n->flags & NODE_NOPRT)
+ if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
return;
chld = 1;
@@ -567,7 +569,9 @@ print_bvspace(struct termp *p,
/* Do not vspace directly after Ss/Sh. */
nn = n;
- while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT)
+ while (nn->prev != NULL &&
+ (nn->prev->type == ROFFT_COMMENT ||
+ nn->prev->flags & NODE_NOPRT))
nn = nn->prev;
while (nn->prev == NULL) {
do {
@@ -1550,7 +1554,8 @@ termp_ss_pre(DECL_ARGS)
case ROFFT_BLOCK:
term_newln(p);
for (nn = n->prev; nn != NULL; nn = nn->prev)
- if ((nn->flags & NODE_NOPRT) == 0)
+ if (nn->type != ROFFT_COMMENT &&
+ (nn->flags & NODE_NOPRT) == 0)
break;
if (nn != NULL)
term_vspace(p);
@@ -1664,7 +1669,7 @@ termp_quote_pre(DECL_ARGS)
/* FALLTHROUGH */
case MDOC_Do:
case MDOC_Dq:
- term_word(p, "\\(Lq");
+ term_word(p, "\\(lq");
break;
case MDOC_En:
if (NULL == n->norm->Es ||
@@ -1722,7 +1727,7 @@ termp_quote_post(DECL_ARGS)
/* FALLTHROUGH */
case MDOC_Do:
case MDOC_Dq:
- term_word(p, "\\(Rq");
+ term_word(p, "\\(rq");
break;
case MDOC_En:
if (n->norm->Es == NULL ||
@@ -1940,7 +1945,6 @@ static int
termp_lk_pre(DECL_ARGS)
{
const struct roff_node *link, *descr, *punct;
- int display;
if ((link = n->child) == NULL)
return 0;
@@ -1966,11 +1970,6 @@ termp_lk_pre(DECL_ARGS)
}
/* Link target. */
- display = term_strlen(p, link->string) >= 26;
- if (display) {
- term_newln(p);
- p->tcol->offset += term_len(p, p->defindent + 1);
- }
term_fontpush(p, TERMFONT_BOLD);
term_word(p, link->string);
term_fontpop(p);
@@ -1981,8 +1980,6 @@ termp_lk_pre(DECL_ARGS)
term_word(p, punct->string);
punct = punct->next;
}
- if (display)
- term_newln(p);
return 0;
}
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 3a9b86f3fd2b..b36d3c0a926c 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -1,7 +1,7 @@
-/* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.360 2018/08/01 16:00:58 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -53,10 +53,11 @@ enum check_ineq {
typedef void (*v_post)(POST_ARGS);
static int build_list(struct roff_man *, int);
-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 void check_text(struct roff_man *, int, int, char *);
+static void check_text_em(struct roff_man *, int, int, char *);
static void check_toptext(struct roff_man *, int, int, const char *);
static int child_an(const struct roff_node *);
static size_t macro2len(enum roff_tok);
@@ -169,12 +170,12 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */
NULL, /* %V */
NULL, /* Ac */
- post_delim_nb, /* Ao */
+ NULL, /* Ao */
post_delim_nb, /* Aq */
post_at, /* At */
NULL, /* Bc */
post_bf, /* Bf */
- post_delim_nb, /* Bo */
+ NULL, /* Bo */
NULL, /* Bq */
post_xx, /* Bsx */
post_bx, /* Bx */
@@ -194,16 +195,16 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
post_xx, /* Ox */
NULL, /* Pc */
NULL, /* Pf */
- post_delim_nb, /* Po */
+ NULL, /* Po */
post_delim_nb, /* Pq */
NULL, /* Qc */
post_delim_nb, /* Ql */
- post_delim_nb, /* Qo */
+ NULL, /* Qo */
post_delim_nb, /* Qq */
NULL, /* Re */
post_rs, /* Rs */
NULL, /* Sc */
- post_delim_nb, /* So */
+ NULL, /* So */
post_delim_nb, /* Sq */
post_sm, /* Sm */
post_sx, /* Sx */
@@ -214,7 +215,7 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
NULL, /* Xo */
post_fo, /* Fo */
NULL, /* Fc */
- post_delim_nb, /* Oo */
+ NULL, /* Oo */
NULL, /* Oc */
post_bk, /* Bk */
NULL, /* Ek */
@@ -227,7 +228,7 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
post_delim_nb, /* Lk */
post_defaults, /* Mt */
post_delim_nb, /* Brq */
- post_delim_nb, /* Bro */
+ NULL, /* Bro */
NULL, /* Brc */
NULL, /* %C */
post_es, /* Es */
@@ -288,7 +289,7 @@ static const char * const secnames[SEC__MAX] = {
void
mdoc_node_validate(struct roff_man *mdoc)
{
- struct roff_node *n;
+ struct roff_node *n, *np;
const v_post *p;
n = mdoc->last;
@@ -305,15 +306,21 @@ mdoc_node_validate(struct roff_man *mdoc)
mdoc->next = ROFF_NEXT_SIBLING;
switch (n->type) {
case ROFFT_TEXT:
+ np = n->parent;
if (n->sec != SEC_SYNOPSIS ||
- (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
+ (np->tok != MDOC_Cd && np->tok != MDOC_Fd))
check_text(mdoc, n->line, n->pos, n->string);
- if (n->parent->tok == MDOC_It ||
- (n->parent->type == ROFFT_BODY &&
- (n->parent->tok == MDOC_Sh ||
- n->parent->tok == MDOC_Ss)))
+ if (np->tok != MDOC_Ql && np->tok != MDOC_Dl &&
+ (np->tok != MDOC_Bd ||
+ (mdoc->flags & MDOC_LITERAL) == 0) &&
+ (np->tok != MDOC_It || np->type != ROFFT_HEAD ||
+ np->parent->parent->norm->Bl.type != LIST_diag))
+ check_text_em(mdoc, n->line, n->pos, n->string);
+ if (np->tok == MDOC_It || (np->type == ROFFT_BODY &&
+ (np->tok == MDOC_Sh || np->tok == MDOC_Ss)))
check_toptext(mdoc, n->line, n->pos, n->string);
break;
+ case ROFFT_COMMENT:
case ROFFT_EQN:
case ROFFT_TBL:
break;
@@ -395,6 +402,57 @@ check_text(struct roff_man *mdoc, int ln, int pos, char *p)
}
static void
+check_text_em(struct roff_man *mdoc, int ln, int pos, char *p)
+{
+ const struct roff_node *np, *nn;
+ char *cp;
+
+ np = mdoc->last->prev;
+ nn = mdoc->last->next;
+
+ /* Look for em-dashes wrongly encoded as "--". */
+
+ for (cp = p; *cp != '\0'; cp++) {
+ if (cp[0] != '-' || cp[1] != '-')
+ continue;
+ cp++;
+
+ /* Skip input sequences of more than two '-'. */
+
+ if (cp[1] == '-') {
+ while (cp[1] == '-')
+ cp++;
+ continue;
+ }
+
+ /* Skip "--" directly attached to something else. */
+
+ if ((cp - p > 1 && cp[-2] != ' ') ||
+ (cp[1] != '\0' && cp[1] != ' '))
+ continue;
+
+ /* Require a letter right before or right afterwards. */
+
+ if ((cp - p > 2 ?
+ isalpha((unsigned char)cp[-3]) :
+ np != NULL &&
+ np->type == ROFFT_TEXT &&
+ *np->string != '\0' &&
+ isalpha((unsigned char)np->string[
+ strlen(np->string) - 1])) ||
+ (cp[1] != '\0' && cp[2] != '\0' ?
+ isalpha((unsigned char)cp[2]) :
+ nn != NULL &&
+ nn->type == ROFFT_TEXT &&
+ isalpha((unsigned char)*nn->string))) {
+ mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse,
+ ln, pos + (int)(cp - p) - 1, NULL);
+ break;
+ }
+ }
+}
+
+static void
check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p)
{
const char *cp, *cpr;
@@ -530,8 +588,7 @@ post_delim_nb(POST_ARGS)
/* At least three alphabetic words with a sentence ending. */
if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em ||
- tok == MDOC_Li || tok == MDOC_Po || tok == MDOC_Pq ||
- tok == MDOC_Sy)) {
+ tok == MDOC_Li || tok == MDOC_Pq || tok == MDOC_Sy)) {
nw = 0;
for (cp = lc - 1; cp >= nch->string; cp--) {
if (*cp == ' ') {
@@ -947,10 +1004,10 @@ post_lb(POST_ARGS)
roff_word_alloc(mdoc, n->line, n->pos, "library");
mdoc->last->flags = NODE_NOSRC;
- roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq");
+ roff_word_alloc(mdoc, n->line, n->pos, "\\(lq");
mdoc->last->flags = NODE_DELIMO | NODE_NOSRC;
mdoc->last = mdoc->last->next;
- roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq");
+ roff_word_alloc(mdoc, n->line, n->pos, "\\(rq");
mdoc->last->flags = NODE_DELIMC | NODE_NOSRC;
mdoc->last = n;
}
@@ -1914,7 +1971,10 @@ post_root(POST_ARGS)
arch++;
if (*arch == NULL) {
n = mdoc->first->child;
- while (n->tok != MDOC_Dt)
+ while (n->tok != MDOC_Dt ||
+ n->child == NULL ||
+ n->child->next == NULL ||
+ n->child->next->next == NULL)
n = n->next;
n = n->child->next->next;
mandoc_vmsg(MANDOCERR_ARCH_BAD,
@@ -1928,8 +1988,10 @@ post_root(POST_ARGS)
/* Check that we begin with a proper `Sh'. */
n = mdoc->first->child;
- while (n != NULL && n->tok >= MDOC_Dd &&
- mdoc_macros[n->tok].flags & MDOC_PROLOGUE)
+ while (n != NULL &&
+ (n->type == ROFFT_COMMENT ||
+ (n->tok >= MDOC_Dd &&
+ mdoc_macros[n->tok].flags & MDOC_PROLOGUE)))
n = n->next;
if (n == NULL)
diff --git a/out.h b/out.h
index f6aceb9c13f4..9f0a541d5dfd 100644
--- a/out.h
+++ b/out.h
@@ -1,4 +1,4 @@
-/* $Id: out.h,v 1.31 2017/06/27 18:25:02 schwarze Exp $ */
+/* $Id: out.h,v 1.32 2018/06/25 16:54:59 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -54,11 +54,6 @@ struct rofftbl {
void *arg; /* passed to sulen, slen, and len */
};
-#define SCALE_VS_INIT(p, v) \
- do { (p)->unit = SCALE_VS; \
- (p)->scale = (v); } \
- while (/* CONSTCOND */ 0)
-
#define SCALE_HS_INIT(p, v) \
do { (p)->unit = SCALE_EN; \
(p)->scale = (v); } \
diff --git a/read.c b/read.c
index 1af1b2836383..0a583445f2cd 100644
--- a/read.c
+++ b/read.c
@@ -1,7 +1,7 @@
-/* $Id: read.c,v 1.192 2017/07/20 14:36:36 schwarze Exp $ */
+/* $Id: read.c,v 1.196 2018/07/28 18:34:15 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2018 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
@@ -94,9 +94,10 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"generic style suggestion",
"legacy man(7) date format",
+ "normalizing date format to",
"lower case character in document title",
"duplicate RCS id",
- "typo in section name",
+ "possible typo in section name",
"unterminated quoted argument",
"useless macro",
"consider using OS macro",
@@ -106,6 +107,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"no blank before trailing delimiter",
"fill mode already enabled, skipping",
"fill mode already disabled, skipping",
+ "verbatim \"--\", maybe consider using \\(em",
"function name without markup",
"whitespace at end of input line",
"bad comment style",
@@ -556,6 +558,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
gzFile gz;
size_t off;
ssize_t ssz;
+ int gzerrnum, retval;
if (fstat(fd, &st) == -1) {
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
@@ -583,9 +586,22 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
}
if (curp->gzip) {
+ /*
+ * Duplicating the file descriptor is required
+ * because we will have to call gzclose(3)
+ * to free memory used internally by zlib,
+ * but that will also close the file descriptor,
+ * which this function must not do.
+ */
+ if ((fd = dup(fd)) == -1) {
+ mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
+ "dup: %s", strerror(errno));
+ return 0;
+ }
if ((gz = gzdopen(fd, "rb")) == NULL) {
mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
"gzdopen: %s", strerror(errno));
+ close(fd);
return 0;
}
} else
@@ -598,6 +614,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
*with_mmap = 0;
off = 0;
+ retval = 0;
fb->sz = 0;
fb->buf = NULL;
for (;;) {
@@ -614,19 +631,29 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
read(fd, fb->buf + (int)off, fb->sz - off);
if (ssz == 0) {
fb->sz = off;
- return 1;
+ retval = 1;
+ break;
}
if (ssz == -1) {
- mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0,
- "read: %s", strerror(errno));
+ if (curp->gzip)
+ (void)gzerror(gz, &gzerrnum);
+ mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "read: %s",
+ curp->gzip && gzerrnum != Z_ERRNO ?
+ zError(gzerrnum) : strerror(errno));
break;
}
off += (size_t)ssz;
}
- free(fb->buf);
- fb->buf = NULL;
- return 0;
+ if (curp->gzip && (gzerrnum = gzclose(gz)) != Z_OK)
+ mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "gzclose: %s",
+ gzerrnum == Z_ERRNO ? strerror(errno) :
+ zError(gzerrnum));
+ if (retval == 0) {
+ free(fb->buf);
+ fb->buf = NULL;
+ }
+ return retval;
}
static void
diff --git a/roff.7 b/roff.7
index 74780e9a7704..8cb922c70676 100644
--- a/roff.7
+++ b/roff.7
@@ -1,7 +1,7 @@
-.\" $Id: roff.7,v 1.94 2017/07/05 12:25:17 schwarze Exp $
+.\" $Id: roff.7,v 1.96 2018/04/10 00:52:30 schwarze Exp $
.\"
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2010,2011,2013-2015,2017 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 5 2017 $
+.Dd $Mdocdate: April 10 2018 $
.Dt ROFF 7
.Os
.Sh NAME
@@ -1348,7 +1348,7 @@ Currently unsupported.
.It Ic \&nop Ar body
Execute the rest of the input line as a request or macro line.
Currently unsupported.
-.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression
+.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression Op Ar stepsize
Define or change a register.
A register is an arbitrary string value that defines some sort of state,
which influences parsing and/or formatting.
@@ -1360,6 +1360,14 @@ below.
If it is prefixed by a sign, the register will be
incremented or decremented instead of assigned to.
.Pp
+The
+.Ar stepsize
+is used by the
+.Ic \en+
+auto-increment feature.
+It remains unchanged when omitted while changing an existing register,
+and it defaults to 0 when defining a new register.
+.Pp
The following
.Ar register
is handled specially:
@@ -1471,7 +1479,7 @@ This is a groff extension and currently ignored.
.It Ic \&rchar Ar glyph ...
Remove glyph definitions.
Currently unsupported.
-.It Ic \&rd Op Ar prompt Op Ar agument ...
+.It Ic \&rd Op Ar prompt Op Ar argument ...
Read from standard input.
Currently ignored.
.It Ic \&recursionlimit Ar maxrec maxtail
@@ -1996,13 +2004,19 @@ and
Character
.Ar number
on the current font.
-.Ss \en Ns Bq Ar name
+.Ss \en Ns Oo +|- Oc Ns Bq Ar name
Interpolate the number register
.Ar name .
For short names, there are variants
.No \en Ns Ar c
and
.No \en( Ns Ar cc .
+If the optional sign is specified,
+the register is first incremented or decremented by the
+.Ar stepsize
+that was specified in the relevant
+.Ic \&nr
+request, and the changed value is interpolated.
.Ss \eo\(aq Ns Ar string Ns \(aq
Overstrike, writing all the characters contained in the
.Ar string
diff --git a/roff.c b/roff.c
index e2e498da0ce4..86e145e36685 100644
--- a/roff.c
+++ b/roff.c
@@ -1,7 +1,7 @@
-/* $Id: roff.c,v 1.324 2017/07/14 17:16:16 schwarze Exp $ */
+/* $Id: roff.c,v 1.329 2018/08/01 15:40:17 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -46,6 +46,7 @@
#define ROFFDEF_STD (1 << 4) /* mdoc(7) or man(7) macro. */
#define ROFFDEF_ANY (ROFFDEF_USER | ROFFDEF_PRE | \
ROFFDEF_REN | ROFFDEF_STD)
+#define ROFFDEF_UNDEF (1 << 5) /* Completely undefined. */
/* --- data types --------------------------------------------------------- */
@@ -72,6 +73,7 @@ struct roffkv {
struct roffreg {
struct roffstr key;
int val;
+ int step;
struct roffreg *next;
};
@@ -181,11 +183,11 @@ static void roff_freestr(struct roffkv *);
static size_t roff_getname(struct roff *, char **, int, int);
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_getregn(struct roff *,
+ const char *, size_t, char);
static int roff_getregro(const struct roff *,
const char *name);
-static const char *roff_getstrn(const struct roff *,
+static const char *roff_getstrn(struct roff *,
const char *, size_t, int *);
static int roff_hasregn(const struct roff *,
const char *, size_t);
@@ -206,6 +208,8 @@ static enum rofferr roff_res(struct roff *, struct buf *, int, int);
static enum rofferr roff_rm(ROFF_ARGS);
static enum rofferr roff_rn(ROFF_ARGS);
static enum rofferr roff_rr(ROFF_ARGS);
+static void roff_setregn(struct roff *, const char *,
+ size_t, int, char, int);
static void roff_setstr(struct roff *,
const char *, const char *, int);
static void roff_setstrn(struct roffkv **, const char *,
@@ -758,7 +762,7 @@ roff_alloc(struct mparse *parse, int options)
r = mandoc_calloc(1, sizeof(struct roff));
r->parse = parse;
- r->reqtab = roffhash_alloc(0, ROFF_USERDEF);
+ r->reqtab = roffhash_alloc(0, ROFF_RENAMED);
r->options = options;
r->format = options & (MPARSE_MDOC | MPARSE_MAN);
r->rstackpos = -1;
@@ -1118,8 +1122,10 @@ static enum rofferr
roff_res(struct roff *r, struct buf *buf, int ln, int pos)
{
char ubuf[24]; /* buffer to print the number */
+ struct roff_node *n; /* used for header comments */
const char *start; /* start of the string to process */
char *stesc; /* start of an escape sequence ('\\') */
+ char *ep; /* end of comment string */
const char *stnam; /* start of the name, after "[(*" */
const char *cp; /* end of the name, e.g. before ']' */
const char *res; /* the string to be substituted */
@@ -1134,6 +1140,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
int done; /* no more input available */
int deftype; /* type of definition to paste */
int rcsid; /* kind of RCS id seen */
+ char sign; /* increment number register */
char term; /* character terminating the escape */
/* Search forward for comments. */
@@ -1168,14 +1175,35 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
/* Handle trailing whitespace. */
- cp = strchr(stesc--, '\0') - 1;
- if (*cp == '\n') {
+ ep = strchr(stesc--, '\0') - 1;
+ if (*ep == '\n') {
done = 1;
- cp--;
+ ep--;
}
- if (*cp == ' ' || *cp == '\t')
+ if (*ep == ' ' || *ep == '\t')
mandoc_msg(MANDOCERR_SPACE_EOL, r->parse,
- ln, cp - buf->buf, NULL);
+ ln, ep - buf->buf, NULL);
+
+ /*
+ * Save comments preceding the title macro
+ * in the syntax tree.
+ */
+
+ if (r->format == 0) {
+ while (*ep == ' ' || *ep == '\t')
+ ep--;
+ ep[1] = '\0';
+ n = roff_node_alloc(r->man,
+ ln, stesc + 1 - buf->buf,
+ ROFFT_COMMENT, TOKEN_NONE);
+ n->string = mandoc_strdup(stesc + 2);
+ roff_node_append(r->man, n);
+ n->flags |= NODE_VALID | NODE_ENDED;
+ r->man->next = ROFF_NEXT_SIBLING;
+ }
+
+ /* Discard comments. */
+
while (stesc > start && stesc[-1] == ' ')
stesc--;
*stesc = '\0';
@@ -1244,6 +1272,9 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
term = cp[1];
/* FALLTHROUGH */
case 'n':
+ sign = cp[1];
+ if (sign == '+' || sign == '-')
+ cp++;
res = ubuf;
break;
default:
@@ -1348,7 +1379,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
case 'n':
if (arg_complete)
(void)snprintf(ubuf, sizeof(ubuf), "%d",
- roff_getregn(r, stnam, naml));
+ roff_getregn(r, stnam, naml, sign));
else
ubuf[0] = '\0';
break;
@@ -1639,6 +1670,11 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos)
}
if (t != TOKEN_NONE)
*pos = cp - buf;
+ else if (deftype == ROFFDEF_UNDEF) {
+ /* Using an undefined macro defines it to be empty. */
+ roff_setstrn(&r->strtab, mac, maclen, "", 0, 0);
+ roff_setstrn(&r->rentab, mac, maclen, NULL, 0, 0);
+ }
return t;
}
@@ -2515,20 +2551,29 @@ roff_evalnum(struct roff *r, int ln, const char *v,
void
roff_setreg(struct roff *r, const char *name, int val, char sign)
{
+ roff_setregn(r, name, strlen(name), val, sign, INT_MIN);
+}
+
+static void
+roff_setregn(struct roff *r, const char *name, size_t len,
+ int val, char sign, int step)
+{
struct roffreg *reg;
/* Search for an existing register with the same name. */
reg = r->regtab;
- while (reg && strcmp(name, reg->key.p))
+ while (reg != NULL && (reg->key.sz != len ||
+ strncmp(reg->key.p, name, len) != 0))
reg = reg->next;
if (NULL == reg) {
/* Create a new register. */
reg = mandoc_malloc(sizeof(struct roffreg));
- reg->key.p = mandoc_strdup(name);
- reg->key.sz = strlen(name);
+ reg->key.p = mandoc_strndup(name, len);
+ reg->key.sz = len;
reg->val = 0;
+ reg->step = 0;
reg->next = r->regtab;
r->regtab = reg;
}
@@ -2539,6 +2584,8 @@ roff_setreg(struct roff *r, const char *name, int val, char sign)
reg->val -= val;
else
reg->val = val;
+ if (step != INT_MIN)
+ reg->step = step;
}
/*
@@ -2572,26 +2619,13 @@ roff_getregro(const struct roff *r, const char *name)
}
int
-roff_getreg(const struct roff *r, const char *name)
+roff_getreg(struct roff *r, const char *name)
{
- struct roffreg *reg;
- int val;
-
- if ('.' == name[0] && '\0' != name[1] && '\0' == name[2]) {
- val = roff_getregro(r, name + 1);
- if (-1 != val)
- return val;
- }
-
- for (reg = r->regtab; reg; reg = reg->next)
- if (0 == strcmp(name, reg->key.p))
- return reg->val;
-
- return 0;
+ return roff_getregn(r, name, strlen(name), '\0');
}
static int
-roff_getregn(const struct roff *r, const char *name, size_t len)
+roff_getregn(struct roff *r, const char *name, size_t len, char sign)
{
struct roffreg *reg;
int val;
@@ -2602,11 +2636,24 @@ roff_getregn(const struct roff *r, const char *name, size_t len)
return val;
}
- for (reg = r->regtab; reg; reg = reg->next)
+ for (reg = r->regtab; reg; reg = reg->next) {
if (len == reg->key.sz &&
- 0 == strncmp(name, reg->key.p, len))
+ 0 == strncmp(name, reg->key.p, len)) {
+ switch (sign) {
+ case '+':
+ reg->val += reg->step;
+ break;
+ case '-':
+ reg->val -= reg->step;
+ break;
+ default:
+ break;
+ }
return reg->val;
+ }
+ }
+ roff_setregn(r, name, len, 0, '\0', INT_MIN);
return 0;
}
@@ -2646,9 +2693,9 @@ roff_freereg(struct roffreg *reg)
static enum rofferr
roff_nr(ROFF_ARGS)
{
- char *key, *val;
+ char *key, *val, *step;
size_t keysz;
- int iv;
+ int iv, is, len;
char sign;
key = val = buf->buf + pos;
@@ -2658,15 +2705,22 @@ roff_nr(ROFF_ARGS)
keysz = roff_getname(r, &val, ln, pos);
if (key[keysz] == '\\')
return ROFF_IGN;
- key[keysz] = '\0';
sign = *val;
if (sign == '+' || sign == '-')
val++;
- if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE))
- roff_setreg(r, key, iv, sign);
+ len = 0;
+ if (roff_evalnum(r, ln, val, &len, &iv, ROFFNUM_SCALE) == 0)
+ return ROFF_IGN;
+ step = val + len;
+ while (isspace((unsigned char)*step))
+ step++;
+ if (roff_evalnum(r, ln, step, NULL, &is, 0) == 0)
+ is = INT_MIN;
+
+ roff_setregn(r, key, keysz, iv, sign, is);
return ROFF_IGN;
}
@@ -2791,6 +2845,7 @@ roff_TE(ROFF_ARGS)
free(buf->buf);
buf->buf = mandoc_strdup(".sp");
buf->sz = 4;
+ *offs = 0;
return ROFF_REPARSE;
}
r->tbl = NULL;
@@ -3310,6 +3365,7 @@ roff_userdef(ROFF_ARGS)
ln, (int)(cp - n1), NULL);
free(buf->buf);
buf->buf = n1;
+ *offs = 0;
return ROFF_IGN;
}
@@ -3404,6 +3460,7 @@ roff_renamed(ROFF_ARGS)
buf->buf[pos] == '\0' ? "" : " ", buf->buf + pos) + 1;
free(buf->buf);
buf->buf = nbuf;
+ *offs = 0;
return ROFF_CONT;
}
@@ -3537,62 +3594,95 @@ roff_setstrn(struct roffkv **r, const char *name, size_t namesz,
}
static const char *
-roff_getstrn(const struct roff *r, const char *name, size_t len,
+roff_getstrn(struct roff *r, const char *name, size_t len,
int *deftype)
{
const struct roffkv *n;
- int i;
+ int found, i;
enum roff_tok tok;
- if (*deftype & ROFFDEF_USER) {
- for (n = r->strtab; n != NULL; n = n->next) {
- if (strncmp(name, n->key.p, len) == 0 &&
- n->key.p[len] == '\0' &&
- n->val.p != NULL) {
- *deftype = ROFFDEF_USER;
- return n->val.p;
- }
+ found = 0;
+ for (n = r->strtab; n != NULL; n = n->next) {
+ if (strncmp(name, n->key.p, len) != 0 ||
+ n->key.p[len] != '\0' || n->val.p == NULL)
+ continue;
+ if (*deftype & ROFFDEF_USER) {
+ *deftype = ROFFDEF_USER;
+ return n->val.p;
+ } else {
+ found = 1;
+ break;
}
}
- if (*deftype & ROFFDEF_PRE) {
- for (i = 0; i < PREDEFS_MAX; i++) {
- if (strncmp(name, predefs[i].name, len) == 0 &&
- predefs[i].name[len] == '\0') {
- *deftype = ROFFDEF_PRE;
- return predefs[i].str;
- }
+ for (n = r->rentab; n != NULL; n = n->next) {
+ if (strncmp(name, n->key.p, len) != 0 ||
+ n->key.p[len] != '\0' || n->val.p == NULL)
+ continue;
+ if (*deftype & ROFFDEF_REN) {
+ *deftype = ROFFDEF_REN;
+ return n->val.p;
+ } else {
+ found = 1;
+ break;
}
}
- if (*deftype & ROFFDEF_REN) {
- for (n = r->rentab; n != NULL; n = n->next) {
- if (strncmp(name, n->key.p, len) == 0 &&
- n->key.p[len] == '\0' &&
- n->val.p != NULL) {
- *deftype = ROFFDEF_REN;
- return n->val.p;
- }
+ for (i = 0; i < PREDEFS_MAX; i++) {
+ if (strncmp(name, predefs[i].name, len) != 0 ||
+ predefs[i].name[len] != '\0')
+ continue;
+ if (*deftype & ROFFDEF_PRE) {
+ *deftype = ROFFDEF_PRE;
+ return predefs[i].str;
+ } else {
+ found = 1;
+ break;
}
}
- if (*deftype & ROFFDEF_STD) {
- if (r->man->macroset != MACROSET_MAN) {
- for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) {
- if (strncmp(name, roff_name[tok], len) == 0 &&
- roff_name[tok][len] == '\0') {
- *deftype = ROFFDEF_STD;
- return NULL;
- }
+ if (r->man->macroset != MACROSET_MAN) {
+ for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) {
+ if (strncmp(name, roff_name[tok], len) != 0 ||
+ roff_name[tok][len] != '\0')
+ continue;
+ if (*deftype & ROFFDEF_STD) {
+ *deftype = ROFFDEF_STD;
+ return NULL;
+ } else {
+ found = 1;
+ break;
}
}
- if (r->man->macroset != MACROSET_MDOC) {
- for (tok = MAN_TH; tok < MAN_MAX; tok++) {
- if (strncmp(name, roff_name[tok], len) == 0 &&
- roff_name[tok][len] == '\0') {
- *deftype = ROFFDEF_STD;
- return NULL;
- }
+ }
+ if (r->man->macroset != MACROSET_MDOC) {
+ for (tok = MAN_TH; tok < MAN_MAX; tok++) {
+ if (strncmp(name, roff_name[tok], len) != 0 ||
+ roff_name[tok][len] != '\0')
+ continue;
+ if (*deftype & ROFFDEF_STD) {
+ *deftype = ROFFDEF_STD;
+ return NULL;
+ } else {
+ found = 1;
+ break;
}
}
}
+
+ if (found == 0 && *deftype != ROFFDEF_ANY) {
+ if (*deftype & ROFFDEF_REN) {
+ /*
+ * This might still be a request,
+ * so do not treat it as undefined yet.
+ */
+ *deftype = ROFFDEF_UNDEF;
+ return NULL;
+ }
+
+ /* Using an undefined string defines it to be empty. */
+
+ roff_setstrn(&r->strtab, name, len, "", 0, 0);
+ roff_setstrn(&r->rentab, name, len, NULL, 0, 0);
+ }
+
*deftype = 0;
return NULL;
}
diff --git a/roff.h b/roff.h
index 8b28d5960974..f0da74bd9ac6 100644
--- a/roff.h
+++ b/roff.h
@@ -1,4 +1,4 @@
-/* $Id: roff.h,v 1.58 2017/07/08 14:51:05 schwarze Exp $ */
+/* $Id: roff.h,v 1.59 2018/04/11 17:11:13 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -61,6 +61,7 @@ enum roff_type {
ROFFT_TAIL,
ROFFT_ELEM,
ROFFT_TEXT,
+ ROFFT_COMMENT,
ROFFT_TBL,
ROFFT_EQN
};
diff --git a/roff_html.c b/roff_html.c
index 53ae6d7ca2d0..6a06c0d8789d 100644
--- a/roff_html.c
+++ b/roff_html.c
@@ -1,7 +1,7 @@
-/* $Id: roff_html.c,v 1.11 2017/06/24 14:38:33 schwarze Exp $ */
+/* $Id: roff_html.c,v 1.12 2018/06/25 14:53:58 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -82,15 +82,5 @@ roff_html_pre_ce(ROFF_HTML_ARGS)
static void
roff_html_pre_sp(ROFF_HTML_ARGS)
{
- struct roffsu su;
-
- SCALE_VS_INIT(&su, 1);
- if ((n = n->child) != NULL) {
- if (a2roffsu(n->string, &su, SCALE_VS) == NULL)
- su.scale = 1.0;
- else if (su.scale < 0.0)
- su.scale = 0.0;
- }
- print_otag(h, TAG_DIV, "suh", &su);
- print_text(h, "\\~"); /* So the div isn't empty. */
+ print_paragraph(h);
}
diff --git a/st.in b/st.in
index 6087c768fbf8..557a70d10db9 100644
--- a/st.in
+++ b/st.in
@@ -1,4 +1,4 @@
-/* $Id: st.in,v 1.29 2017/06/24 13:49:29 schwarze Exp $ */
+/* $Id: st.in,v 1.30 2018/04/05 09:17:26 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -28,49 +28,49 @@
* REMEMBER TO ADD NEW STANDARDS TO MDOC.7!
*/
-LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1", "IEEE Std 1003.1 (\\(LqPOSIX.1\\(Rq)")
-LINE("-p1003.1b", "IEEE Std 1003.1b (\\(LqPOSIX.1b\\(Rq)")
-LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(LqPOSIX.1b\\(Rq)")
-LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(LqPOSIX.1c\\(Rq)")
-LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(LqPOSIX.1g\\(Rq)")
-LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(LqPOSIX.1i\\(Rq)")
-LINE("-p1003.2", "IEEE Std 1003.2 (\\(LqPOSIX.2\\(Rq)")
-LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(LqPOSIX.2\\(Rq)")
-LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(LqPOSIX.2\\(Rq)")
-LINE("-isoC", "ISO/IEC 9899:1990 (\\(LqISO\\~C90\\(Rq)")
-LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(LqISO\\~C90\\(Rq)")
-LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(LqISO\\~C90, Amendment 1\\(Rq)")
-LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(LqISO\\~C90, Technical Corrigendum 1\\(Rq)")
-LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(LqISO\\~C90, Technical Corrigendum 2\\(Rq)")
-LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(LqISO\\~C99\\(Rq)")
-LINE("-isoC-2011", "ISO/IEC 9899:2011 (\\(LqISO\\~C11\\(Rq)")
-LINE("-iso9945-1-90", "ISO/IEC 9945-1:1990 (\\(LqPOSIX.1\\(Rq)")
-LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(LqPOSIX.1\\(Rq)")
-LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(LqPOSIX.2\\(Rq)")
-LINE("-ansiC", "ANSI X3.159-1989 (\\(LqANSI\\~C89\\(Rq)")
-LINE("-ansiC-89", "ANSI X3.159-1989 (\\(LqANSI\\~C89\\(Rq)")
+LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
+LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)")
+LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)")
+LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)")
+LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)")
+LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)")
+LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
+LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)")
+LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)")
+LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
+LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
+LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO\\~C90, Amendment 1\\(rq)")
+LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(lqISO\\~C90, Technical Corrigendum 1\\(rq)")
+LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(lqISO\\~C90, Technical Corrigendum 2\\(rq)")
+LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(lqISO\\~C99\\(rq)")
+LINE("-isoC-2011", "ISO/IEC 9899:2011 (\\(lqISO\\~C11\\(rq)")
+LINE("-iso9945-1-90", "ISO/IEC 9945-1:1990 (\\(lqPOSIX.1\\(rq)")
+LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
+LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)")
+LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
+LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
LINE("-ieee754", "IEEE Std 754-1985")
LINE("-iso8802-3", "ISO 8802-3: 1989")
LINE("-iso8601", "ISO 8601")
-LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(LqOpen Firmware\\(Rq)")
-LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(LqXPG3\\(Rq)")
-LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(LqXPG4\\(Rq)")
-LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(LqXPG4.2\\(Rq)")
-LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(LqXBD5\\(Rq)")
-LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(LqXCU5\\(Rq)")
-LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(LqXSH4.2\\(Rq)")
-LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(LqXSH5\\(Rq)")
-LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(LqXNS5\\(Rq)")
-LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(LqXNS5.2\\(Rq)")
-LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(LqXCURSES4.2\\(Rq)")
-LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(LqSUSv1\\(Rq)")
-LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(LqSUSv2\\(Rq)")
-LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(LqSUSv3\\(Rq)")
-LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(LqSUSv4\\(Rq)")
-LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(LqSVID4\\(Rq)")
+LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)")
+LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)")
+LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)")
+LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)")
+LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)")
+LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)")
+LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)")
+LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)")
+LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)")
+LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)")
+LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)")
+LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(lqSUSv1\\(rq)")
+LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(lqSUSv2\\(rq)")
+LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(lqSUSv3\\(rq)")
+LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(lqSUSv4\\(rq)")
+LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
diff --git a/tag.c b/tag.c
index 21ac6b32e4d3..c0832c4f74b7 100644
--- a/tag.c
+++ b/tag.c
@@ -1,4 +1,4 @@
-/* $Id: tag.c,v 1.18 2017/02/17 14:31:52 schwarze Exp $ */
+/* $Id: tag.c,v 1.19 2018/02/23 16:47:10 schwarze Exp $ */
/*
* Copyright (c) 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -213,6 +213,9 @@ tag_write(void)
ohash_delete(&tag_data);
if (stream != NULL)
fclose(stream);
+ else
+ close(tag_files.tfd);
+ tag_files.tfd = -1;
}
void
diff --git a/tbl.7 b/tbl.7
index e2f84538370b..3883b40904ee 100644
--- a/tbl.7
+++ b/tbl.7
@@ -1,4 +1,4 @@
-.\" $Id: tbl.7,v 1.28 2017/06/28 00:59:57 schwarze Exp $
+.\" $Id: tbl.7,v 1.29 2017/10/17 23:19:12 schwarze Exp $
.\"
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2014, 2015, 2017 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: June 28 2017 $
+.Dd $Mdocdate: October 17 2017 $
.Dt TBL 7
.Os
.Sh NAME
@@ -420,7 +420,9 @@ The GNU reimplementation of tbl, part of the groff package, was released
in 1990 by James Clark.
A standalone tbl implementation was written by Kristaps Dzonsons in
2010.
-This formed the basis of the implementation that is part of the
+This formed the basis of the implementation that first appeared in
+.Ox 4.9
+as a part of the
.Xr mandoc 1
utility.
.Sh AUTHORS
diff --git a/tbl_html.c b/tbl_html.c
index d59f1635d013..b87804fda354 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -1,4 +1,4 @@
-/* $Id: tbl_html.c,v 1.23 2017/07/31 16:14:10 schwarze Exp $ */
+/* $Id: tbl_html.c,v 1.24 2018/06/25 13:45:57 schwarze Exp $ */
/*
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -79,23 +79,14 @@ html_tbl_sulen(const struct roffsu *su, void *arg)
static void
html_tblopen(struct html *h, const struct tbl_span *sp)
{
- struct tag *t;
- int ic;
-
if (h->tbl.cols == NULL) {
h->tbl.len = html_tbl_len;
h->tbl.slen = html_tbl_strlen;
h->tbl.sulen = html_tbl_sulen;
tblcalc(&h->tbl, sp, 0, 0);
}
-
assert(NULL == h->tblt);
h->tblt = print_otag(h, TAG_TABLE, "c", "tbl");
-
- t = print_otag(h, TAG_COLGROUP, "");
- for (ic = 0; ic < sp->opts->cols; ic++)
- print_otag(h, TAG_COL, "shw", h->tbl.cols[ic].width);
- print_tagq(h, t);
}
void
diff --git a/term_ascii.c b/term_ascii.c
index e819c0ef8a86..f47ffd75d9c3 100644
--- a/term_ascii.c
+++ b/term_ascii.c
@@ -1,7 +1,7 @@
-/* $Id: term_ascii.c,v 1.58 2017/06/14 14:24:20 schwarze Exp $ */
+/* $Id: term_ascii.c,v 1.61 2018/05/20 21:37:34 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,11 +21,13 @@
#include <assert.h>
#if HAVE_WCHAR
+#include <langinfo.h>
#include <locale.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#if HAVE_WCHAR
#include <wchar.h>
@@ -100,7 +102,17 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
v = TERMENC_LOCALE == enc ?
setlocale(LC_CTYPE, "") :
setlocale(LC_CTYPE, UTF8_LOCALE);
- if (NULL != v && MB_CUR_MAX > 1) {
+
+ /*
+ * We only support UTF-8,
+ * so revert to ASCII for anything else.
+ */
+
+ if (v != NULL &&
+ strcmp(nl_langinfo(CODESET), "UTF-8") != 0)
+ v = setlocale(LC_CTYPE, "C");
+
+ if (v != NULL && MB_CUR_MAX > 1) {
p->enc = enc;
p->advance = locale_advance;
p->endline = locale_endline;
@@ -121,6 +133,8 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
if (outopts->synopsisonly)
p->synopsisonly = 1;
+ assert(p->defindent < UINT16_MAX);
+ assert(p->defrmargin < UINT16_MAX);
return p;
}
@@ -159,6 +173,8 @@ ascii_setwidth(struct termp *p, int iop, int width)
p->defrmargin -= width;
else
p->defrmargin = 0;
+ if (p->defrmargin > 1000)
+ p->defrmargin = 1000;
p->lastrmargin = p->tcol->rmargin;
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
}
@@ -227,6 +243,7 @@ ascii_advance(struct termp *p, size_t len)
{
size_t i;
+ assert(len < UINT16_MAX);
for (i = 0; i < len; i++)
putchar(' ');
}
@@ -294,17 +311,17 @@ ascii_uc2str(int uc)
"<88>", "<89>", "<8A>", "<8B>", "<8C>", "<8D>", "<8E>", "<8F>",
"<90>", "<91>", "<92>", "<93>", "<94>", "<95>", "<96>", "<97>",
"<98>", "<99>", "<9A>", "<9B>", "<9C>", "<9D>", "<9E>", "<9F>",
- nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<sec>",
+ nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<section>",
"\"", "(C)", "_\ba", "<<", "~", "", "(R)", "-",
- "<deg>","+-", "2", "3", "'", ",\bu", "<par>",".",
- ",", "1", "_\bo", ">>", "1/4", "1/2", "3/4", "?",
+ "<degree>","+-","^2", "^3", "'","<micro>","<paragraph>",".",
+ ",", "^1", "_\bo", ">>", "1/4", "1/2", "3/4", "?",
"`\bA", "'\bA", "^\bA", "~\bA", "\"\bA","o\bA", "AE", ",\bC",
"`\bE", "'\bE", "^\bE", "\"\bE","`\bI", "'\bI", "^\bI", "\"\bI",
- "-\bD", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x",
+ "Dh", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x",
"/\bO", "`\bU", "'\bU", "^\bU", "\"\bU","'\bY", "Th", "ss",
"`\ba", "'\ba", "^\ba", "~\ba", "\"\ba","o\ba", "ae", ",\bc",
"`\be", "'\be", "^\be", "\"\be","`\bi", "'\bi", "^\bi", "\"\bi",
- "d", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","-:-",
+ "dh", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","/",
"/\bo", "`\bu", "'\bu", "^\bu", "\"\bu","'\by", "th", "\"\by",
"A", "a", "A", "a", "A", "a", "'\bC", "'\bc",
"^\bC", "^\bc", "C", "c", "C", "c", "D", "d",
@@ -364,6 +381,7 @@ locale_advance(struct termp *p, size_t len)
{
size_t i;
+ assert(len < UINT16_MAX);
for (i = 0; i < len; i++)
putwchar(L' ');
}
diff --git a/term_ps.c b/term_ps.c
index 9638ae4cb9a3..2cd94c923156 100644
--- a/term_ps.c
+++ b/term_ps.c
@@ -1,7 +1,8 @@
-/* $Id: term_ps.c,v 1.85 2017/06/07 17:38:26 schwarze Exp $ */
+/* $Id: term_ps.c,v 1.91 2017/11/10 23:42:52 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2017 Marc Espie <espie@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
@@ -66,6 +67,7 @@ struct termp_ps {
size_t pscol; /* visible column (AFM units) */
size_t pscolnext; /* used for overstrike */
size_t psrow; /* visible row (AFM units) */
+ size_t lastrow; /* psrow of the previous word */
char *psmarg; /* margin buf */
size_t psmargsz; /* margin buf size */
size_t psmargcur; /* cur index in margin buf */
@@ -77,6 +79,7 @@ struct termp_ps {
size_t lineheight; /* line height (AFM units) */
size_t top; /* body top (AFM units) */
size_t bottom; /* body bottom (AFM units) */
+ const char *medianame; /* for DocumentMedia and PageSize */
size_t height; /* page height (AFM units */
size_t width; /* page width (AFM units) */
size_t lastwidth; /* page width before last ll */
@@ -108,7 +111,7 @@ 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, int);
-static struct termp *pspdf_alloc(const struct manoutput *);
+static struct termp *pspdf_alloc(const struct manoutput *, enum termtype);
static void pdf_obj(struct termp *, size_t);
/*
@@ -511,27 +514,17 @@ static const struct font fonts[TERMFONT__MAX] = {
void *
pdf_alloc(const struct manoutput *outopts)
{
- struct termp *p;
-
- if (NULL != (p = pspdf_alloc(outopts)))
- p->type = TERMTYPE_PDF;
-
- return p;
+ return pspdf_alloc(outopts, TERMTYPE_PDF);
}
void *
ps_alloc(const struct manoutput *outopts)
{
- struct termp *p;
-
- if (NULL != (p = pspdf_alloc(outopts)))
- p->type = TERMTYPE_PS;
-
- return p;
+ return pspdf_alloc(outopts, TERMTYPE_PS);
}
static struct termp *
-pspdf_alloc(const struct manoutput *outopts)
+pspdf_alloc(const struct manoutput *outopts, enum termtype type)
{
struct termp *p;
unsigned int pagex, pagey;
@@ -541,6 +534,7 @@ pspdf_alloc(const struct manoutput *outopts)
p = mandoc_calloc(1, sizeof(*p));
p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol));
p->maxtcol = 1;
+ p->type = type;
p->enc = TERMENC_ASCII;
p->fontq = mandoc_reallocarray(NULL,
@@ -559,6 +553,7 @@ pspdf_alloc(const struct manoutput *outopts)
/* Default to US letter (millimetres). */
+ p->ps->medianame = "Letter";
pagex = 216;
pagey = 279;
@@ -570,20 +565,26 @@ pspdf_alloc(const struct manoutput *outopts)
*/
pp = outopts->paper;
- if (pp && strcasecmp(pp, "letter")) {
- if (0 == strcasecmp(pp, "a3")) {
+ if (pp != NULL && strcasecmp(pp, "letter") != 0) {
+ if (strcasecmp(pp, "a3") == 0) {
+ p->ps->medianame = "A3";
pagex = 297;
pagey = 420;
- } else if (0 == strcasecmp(pp, "a4")) {
+ } else if (strcasecmp(pp, "a4") == 0) {
+ p->ps->medianame = "A4";
pagex = 210;
pagey = 297;
- } else if (0 == strcasecmp(pp, "a5")) {
+ } else if (strcasecmp(pp, "a5") == 0) {
+ p->ps->medianame = "A5";
pagex = 148;
pagey = 210;
- } else if (0 == strcasecmp(pp, "legal")) {
+ } else if (strcasecmp(pp, "legal") == 0) {
+ p->ps->medianame = "Legal";
pagex = 216;
pagey = 356;
- } else if (2 != sscanf(pp, "%ux%u", &pagex, &pagey))
+ } else if (sscanf(pp, "%ux%u", &pagex, &pagey) == 2)
+ p->ps->medianame = "CustomSize";
+ else
warnx("%s: Unknown paper", pp);
}
@@ -596,8 +597,8 @@ pspdf_alloc(const struct manoutput *outopts)
/* Remember millimetres -> AFM units. */
- pagex = PNT2AFM(p, ((double)pagex * 2.834));
- pagey = PNT2AFM(p, ((double)pagey * 2.834));
+ pagex = PNT2AFM(p, ((double)pagex * 72.0 / 25.4));
+ pagey = PNT2AFM(p, ((double)pagey * 72.0 / 25.4));
/* Margins are 1/9 the page x and y. */
@@ -733,7 +734,7 @@ ps_closepage(struct termp *p)
/*
* Close out a page that we've already flushed to output. In
- * PostScript, we simply note that the page must be showed. In
+ * PostScript, we simply note that the page must be shown. In
* PDF, we must now create the Length, Resource, and Page node
* for the page contents.
*/
@@ -742,8 +743,6 @@ ps_closepage(struct termp *p)
ps_printf(p, "%s", p->ps->psmarg);
if (TERMTYPE_PS != p->type) {
- ps_printf(p, "ET\n");
-
len = p->ps->pdfbytes - p->ps->pdflastpg;
base = p->ps->pages * 4 + p->ps->pdfbody;
@@ -759,7 +758,7 @@ ps_closepage(struct termp *p)
ps_printf(p, "/Font <<\n");
for (i = 0; i < (int)TERMFONT__MAX; i++)
ps_printf(p, "/F%d %d 0 R\n", i, 3 + i);
- ps_printf(p, ">>\n>>\n");
+ ps_printf(p, ">>\n>>\nendobj\n");
/* Page node. */
pdf_obj(p, base + 3);
@@ -824,7 +823,7 @@ ps_end(struct termp *p)
ps_printf(p, "<<\n");
ps_printf(p, "/Type /Catalog\n");
ps_printf(p, "/Pages 2 0 R\n");
- ps_printf(p, ">>\n");
+ ps_printf(p, ">>\nendobj\n");
xref = p->ps->pdfbytes;
ps_printf(p, "xref\n");
ps_printf(p, "0 %zu\n", base + 1);
@@ -848,6 +847,7 @@ ps_end(struct termp *p)
static void
ps_begin(struct termp *p)
{
+ size_t width, height;
int i;
/*
@@ -865,6 +865,7 @@ ps_begin(struct termp *p)
p->ps->flags = PS_MARGINS;
p->ps->pscol = p->ps->left;
p->ps->psrow = p->ps->header;
+ p->ps->lastrow = 0; /* impossible row */
ps_setfont(p, TERMFONT_NONE);
@@ -889,21 +890,44 @@ ps_begin(struct termp *p)
*/
if (TERMTYPE_PS == p->type) {
+ width = AFM2PNT(p, p->ps->width);
+ height = AFM2PNT(p, p->ps->height);
+
ps_printf(p, "%%!PS-Adobe-3.0\n");
ps_printf(p, "%%%%DocumentData: Clean7Bit\n");
ps_printf(p, "%%%%Orientation: Portrait\n");
ps_printf(p, "%%%%Pages: (atend)\n");
ps_printf(p, "%%%%PageOrder: Ascend\n");
- ps_printf(p, "%%%%DocumentMedia: "
- "Default %zu %zu 0 () ()\n",
- (size_t)AFM2PNT(p, p->ps->width),
- (size_t)AFM2PNT(p, p->ps->height));
+ ps_printf(p, "%%%%DocumentMedia: man-%s %zu %zu 0 () ()\n",
+ p->ps->medianame, width, height);
ps_printf(p, "%%%%DocumentNeededResources: font");
for (i = 0; i < (int)TERMFONT__MAX; i++)
ps_printf(p, " %s", fonts[i].name);
- ps_printf(p, "\n%%%%EndComments\n");
+ ps_printf(p, "\n%%%%DocumentSuppliedResources: "
+ "procset MandocProcs 1.0 0\n");
+ ps_printf(p, "%%%%EndComments\n");
+ ps_printf(p, "%%%%BeginProlog\n");
+ ps_printf(p, "%%%%BeginResource: procset MandocProcs "
+ "10170 10170\n");
+ /* The font size is effectively hard-coded for now. */
+ ps_printf(p, "/fs %zu def\n", p->ps->scale);
+ for (i = 0; i < (int)TERMFONT__MAX; i++)
+ ps_printf(p, "/f%d { /%s fs selectfont } def\n",
+ i, fonts[i].name);
+ ps_printf(p, "/s { 3 1 roll moveto show } bind def\n");
+ ps_printf(p, "/c { exch currentpoint exch pop "
+ "moveto show } bind def\n");
+ ps_printf(p, "%%%%EndResource\n");
+ ps_printf(p, "%%%%EndProlog\n");
+ ps_printf(p, "%%%%BeginSetup\n");
+ ps_printf(p, "%%%%BeginFeature: *PageSize %s\n",
+ p->ps->medianame);
+ ps_printf(p, "<</PageSize [%zu %zu]>>setpagedevice\n",
+ width, height);
+ ps_printf(p, "%%%%EndFeature\n");
+ ps_printf(p, "%%%%EndSetup\n");
} else {
ps_printf(p, "%%PDF-1.1\n");
pdf_obj(p, 1);
@@ -918,7 +942,7 @@ ps_begin(struct termp *p)
ps_printf(p, "/Subtype /Type1\n");
ps_printf(p, "/Name /F%d\n", i);
ps_printf(p, "/BaseFont /%s\n", fonts[i].name);
- ps_printf(p, ">>\n");
+ ps_printf(p, ">>\nendobj\n");
}
}
@@ -943,9 +967,7 @@ ps_pletter(struct termp *p, int c)
if (TERMTYPE_PS == p->type) {
ps_printf(p, "%%%%Page: %zu %zu\n",
p->ps->pages + 1, p->ps->pages + 1);
- ps_printf(p, "/%s %zu selectfont\n",
- fonts[(int)p->ps->lastf].name,
- p->ps->scale);
+ ps_printf(p, "f%d\n", (int)p->ps->lastf);
} else {
pdf_obj(p, p->ps->pdfbody +
p->ps->pages * 4);
@@ -970,10 +992,13 @@ ps_pletter(struct termp *p, int c)
ps_printf(p, "%.3f %.3f Td\n(",
AFM2PNT(p, p->ps->pscol),
AFM2PNT(p, p->ps->psrow));
- } else
- ps_printf(p, "%.3f %.3f moveto\n(",
- AFM2PNT(p, p->ps->pscol),
- AFM2PNT(p, p->ps->psrow));
+ } else {
+ ps_printf(p, "%.3f", AFM2PNT(p, p->ps->pscol));
+ if (p->ps->psrow != p->ps->lastrow)
+ ps_printf(p, " %.3f",
+ AFM2PNT(p, p->ps->psrow));
+ ps_printf(p, "(");
+ }
p->ps->flags |= PS_INLINE;
}
@@ -1021,10 +1046,14 @@ ps_pclose(struct termp *p)
if ( ! (PS_INLINE & p->ps->flags))
return;
- if (TERMTYPE_PS != p->type) {
+ if (TERMTYPE_PS != p->type)
ps_printf(p, ") Tj\nET\n");
- } else
- ps_printf(p, ") show\n");
+ else if (p->ps->psrow == p->ps->lastrow)
+ ps_printf(p, ")c\n");
+ else {
+ ps_printf(p, ")s\n");
+ p->ps->lastrow = p->ps->psrow;
+ }
p->ps->flags &= ~PS_INLINE;
}
@@ -1243,8 +1272,7 @@ ps_setfont(struct termp *p, enum termfont f)
return;
if (TERMTYPE_PS == p->type)
- ps_printf(p, "/%s %zu selectfont\n",
- fonts[(int)f].name, p->ps->scale);
+ ps_printf(p, "f%d\n", (int)f);
else
ps_printf(p, "/F%d %zu Tf\n",
(int)f, p->ps->scale);
diff --git a/test-noop.c b/test-noop.c
new file mode 100644
index 000000000000..95485db80176
--- /dev/null
+++ b/test-noop.c
@@ -0,0 +1,5 @@
+int
+main(void)
+{
+ return 0;
+}
diff --git a/test-strndup.c b/test-strndup.c
new file mode 100644
index 000000000000..82e4e547e097
--- /dev/null
+++ b/test-strndup.c
@@ -0,0 +1,10 @@
+#include <string.h>
+
+int
+main(void)
+{
+ char *s;
+
+ s = strndup("123", 2);
+ return s[0] != '1' ? 1 : s[1] != '2' ? 2 : s[2] != '\0' ? 3 : 0;
+}
diff --git a/tree.c b/tree.c
index 7d18b9d9e686..b9774e1cd8e1 100644
--- a/tree.c
+++ b/tree.c
@@ -1,7 +1,7 @@
-/* $Id: tree.c,v 1.77 2017/07/08 14:51:05 schwarze Exp $ */
+/* $Id: tree.c,v 1.78 2018/04/11 17:11:13 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -115,6 +115,9 @@ print_mdoc(const struct roff_node *n, int indent)
case ROFFT_TEXT:
t = "text";
break;
+ case ROFFT_COMMENT:
+ t = "comment";
+ break;
case ROFFT_TBL:
break;
case ROFFT_EQN:
@@ -126,6 +129,7 @@ print_mdoc(const struct roff_node *n, int indent)
switch (n->type) {
case ROFFT_TEXT:
+ case ROFFT_COMMENT:
p = n->string;
break;
case ROFFT_BODY:
@@ -231,6 +235,9 @@ print_man(const struct roff_node *n, int indent)
case ROFFT_TEXT:
t = "text";
break;
+ case ROFFT_COMMENT:
+ t = "comment";
+ break;
case ROFFT_BLOCK:
t = "block";
break;
@@ -251,6 +258,7 @@ print_man(const struct roff_node *n, int indent)
switch (n->type) {
case ROFFT_TEXT:
+ case ROFFT_COMMENT:
p = n->string;
break;
case ROFFT_ELEM: