summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2010-06-26 17:56:44 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2010-06-26 17:56:44 +0000
commitb8356f8ddb7db759bb2d0127e1d696abbc40a6b7 (patch)
treec6440ef0074ad1cb8ade3e95a121ba58e421aa40 /usr.bin
parent3d32c5d68dc8f6ddc0ced4e6c6b8148e0c22c1cb (diff)
merge release 1.10.2
* bug fixes: - interaction of ASCII_HYPH with special chars (found by Ulrich Spoerlein) - handling of roff conditionals (found by Ulrich Spoerlein) - .Bd -offset will no more default to 6n * maintenance: - more caching of .Bd and .Bl arguments for efficiency - deconstify man(7) validation routines - add FreeBSD library names (provided by Ulrich Spoerlein) * start PostScript font-switching
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/mandoc/Makefile4
-rw-r--r--usr.bin/mandoc/lib.in29
-rw-r--r--usr.bin/mandoc/libman.h6
-rw-r--r--usr.bin/mandoc/libmandoc.h6
-rw-r--r--usr.bin/mandoc/main.c8
-rw-r--r--usr.bin/mandoc/man_validate.c10
-rw-r--r--usr.bin/mandoc/mandoc.16
-rw-r--r--usr.bin/mandoc/mandoc.c86
-rw-r--r--usr.bin/mandoc/mandoc.h8
-rw-r--r--usr.bin/mandoc/mdoc.725
-rw-r--r--usr.bin/mandoc/mdoc.c10
-rw-r--r--usr.bin/mandoc/mdoc.h29
-rw-r--r--usr.bin/mandoc/mdoc_action.c185
-rw-r--r--usr.bin/mandoc/mdoc_argv.c6
-rw-r--r--usr.bin/mandoc/mdoc_html.c70
-rw-r--r--usr.bin/mandoc/mdoc_term.c161
-rw-r--r--usr.bin/mandoc/mdoc_validate.c184
-rw-r--r--usr.bin/mandoc/roff.719
-rw-r--r--usr.bin/mandoc/roff.c97
-rw-r--r--usr.bin/mandoc/term.c9
-rw-r--r--usr.bin/mandoc/term.h6
-rw-r--r--usr.bin/mandoc/term_ps.c203
22 files changed, 673 insertions, 494 deletions
diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile
index 965fab9ad32..d6847a8cc83 100644
--- a/usr.bin/mandoc/Makefile
+++ b/usr.bin/mandoc/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.40 2010/06/10 22:50:10 schwarze Exp $
+# $OpenBSD: Makefile,v 1.41 2010/06/26 17:56:43 schwarze Exp $
.include <bsd.own.mk>
-VERSION=1.10.1
+VERSION=1.10.2
CFLAGS+=-DVERSION=\"${VERSION}\"
CFLAGS+=-W -Wall -Wstrict-prototypes
diff --git a/usr.bin/mandoc/lib.in b/usr.bin/mandoc/lib.in
index 5a51a34c590..05ea04cfcbf 100644
--- a/usr.bin/mandoc/lib.in
+++ b/usr.bin/mandoc/lib.in
@@ -1,6 +1,6 @@
-/* $Id: lib.in,v 1.4 2010/05/15 22:04:31 schwarze Exp $ */
+/* $Id: lib.in,v 1.5 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,25 +27,42 @@ LINE("libarchive", "Reading and Writing Streaming Archives Library (libarchive,
LINE("libarm", "ARM Architecture Library (libarm, \\-larm)")
LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)")
LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)")
+LINE("libbsm", "Basic Security Module User 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("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("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("libedit", "Command Line Editor Library (libedit, \\-ledit)")
LINE("libelf", "ELF Parsing Library (libelf, \\-lelf)")
LINE("libevent", "Event Notification Library (libevent, \\-levent)")
LINE("libfetch", "File Transfer Library for URLs (libfetch, \\-lfetch)")
LINE("libform", "Curses Form Library (libform, \\-lform)")
+LINE("libgeom", "Userland API Library for kernel GEOM subsystem (libgeom, \\-lgeom)")
+LINE("libgpib", "General-Purpose Instrument Bus (GPIB) library (libgpib, \\-lgpib)")
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("libjail", "Jail Library (libjail, \\-ljail)")
+LINE("libkiconv", "Kernel side iconv library (libkiconv, \\-lkiconv)")
+LINE("libkse", "N:M Threading Library (libkse, \\-lkse)")
LINE("libkvm", "Kernel Data Access Library (libkvm, \\-lkvm)")
LINE("libm", "Math Library (libm, \\-lm)")
LINE("libm68k", "m68k Architecture Library (libm68k, \\-lm68k)")
LINE("libmagic", "Magic Number Recognition Library (libmagic, \\-lmagic)")
+LINE("libmd", "Message Digest (MD4, MD5, etc.) Support Library (libmd, \\-lmd)")
+LINE("libmemstat", "Kernel Memory Allocator Statistics Library (libmemstat, \\-lmemstat)")
LINE("libmenu", "Curses Menu Library (libmenu, \\-lmenu)")
+LINE("libnetgraph", "Netgraph User Library (libnetgraph, \\-lnetgraph)")
LINE("libnetpgp", "Netpgp signing, verification, encryption and decryption (libnetpgp, \\-lnetpgp)")
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
@@ -58,11 +75,19 @@ LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
LINE("librefuse", "File System in Userspace Convenience Library (librefuse, \\-lrefuse)")
LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
+LINE("librpcsec_gss", "RPC GSS-API Authentication Library (librpcsec_gss, \\-lrpcsec_gss)")
+LINE("librpcsvc", "RPC Service Library (librpcsvc, \\-lrpcsvc)")
LINE("librt", "POSIX Real\\-time Library (librt, -lrt)")
+LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)")
LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
LINE("libterminfo", "Terminal Information Library (libterminfo, \\-lterminfo)")
+LINE("libthr", "1:1 Threading Library (libthr, \\-lthr)")
+LINE("libufs", "UFS File System Access Library (libufs, \\-lufs)")
+LINE("libugidfw", "File System Firewall Interface Library (libugidfw, \\-lugidfw)")
+LINE("libulog", "User Login Record Library (libulog, \\-lulog)")
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("libz", "Compression Library (libz, \\-lz)")
diff --git a/usr.bin/mandoc/libman.h b/usr.bin/mandoc/libman.h
index 2b8333ae9be..d187aba5c5e 100644
--- a/usr.bin/mandoc/libman.h
+++ b/usr.bin/mandoc/libman.h
@@ -1,6 +1,6 @@
-/* $Id: libman.h,v 1.21 2010/05/24 02:27:31 schwarze Exp $ */
+/* $Id: libman.h,v 1.22 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -79,7 +79,7 @@ int man_args(struct man *, int, int *, char *, char **);
int man_vmsg(struct man *, enum mandocerr,
int, int, const char *, ...);
int man_valid_post(struct man *);
-int man_valid_pre(struct man *, const struct man_node *);
+int man_valid_pre(struct man *, struct man_node *);
int man_action_post(struct man *);
int man_action_pre(struct man *, struct man_node *);
int man_unscope(struct man *,
diff --git a/usr.bin/mandoc/libmandoc.h b/usr.bin/mandoc/libmandoc.h
index 4ceac4bfe37..9001dc797d7 100644
--- a/usr.bin/mandoc/libmandoc.h
+++ b/usr.bin/mandoc/libmandoc.h
@@ -1,6 +1,6 @@
-/* $Id: libmandoc.h,v 1.5 2010/05/26 02:39:58 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.6 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,7 @@
__BEGIN_DECLS
-int mandoc_special(const char *);
+int mandoc_special(char *);
void *mandoc_calloc(size_t, size_t);
char *mandoc_strdup(const char *);
void *mandoc_malloc(size_t);
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c
index 91566c31aa3..129ebac3aec 100644
--- a/usr.bin/mandoc/main.c
+++ b/usr.bin/mandoc/main.c
@@ -1,6 +1,6 @@
-/* $Id: main.c,v 1.36 2010/06/10 22:50:10 schwarze Exp $ */
+/* $Id: main.c,v 1.37 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -98,6 +98,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"unterminated quoted string",
"argument requires the width argument",
"superfluous width argument",
+ "ignoring argument",
"bad date argument",
"bad width argument",
"unknown manual section",
@@ -132,12 +133,13 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"macro requires argument(s)",
"no title in document",
"missing list type",
+ "missing display type",
"line argument(s) will be lost",
"body argument(s) will be lost",
"column syntax is inconsistent",
"missing font type",
- "missing display type",
"displays may not be nested",
+ "unsupported display type",
"no scope to rewind: syntax violated",
"scope broken, syntax violated",
"line scope broken, syntax violated",
diff --git a/usr.bin/mandoc/man_validate.c b/usr.bin/mandoc/man_validate.c
index b36b9c1d9e2..8658846720a 100644
--- a/usr.bin/mandoc/man_validate.c
+++ b/usr.bin/mandoc/man_validate.c
@@ -1,6 +1,6 @@
-/* $Id: man_validate.c,v 1.26 2010/05/26 02:39:58 schwarze Exp $ */
+/* $Id: man_validate.c,v 1.27 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,7 +27,7 @@
#include "libman.h"
#include "libmandoc.h"
-#define CHKARGS struct man *m, const struct man_node *n
+#define CHKARGS struct man *m, struct man_node *n
typedef int (*v_check)(CHKARGS);
@@ -97,7 +97,7 @@ static const struct man_valid man_valids[MAN_MAX] = {
int
-man_valid_pre(struct man *m, const struct man_node *n)
+man_valid_pre(struct man *m, struct man_node *n)
{
v_check *cp;
@@ -200,7 +200,7 @@ check_title(CHKARGS)
static int
check_text(CHKARGS)
{
- const char *p;
+ char *p;
int pos, c;
assert(n->string);
diff --git a/usr.bin/mandoc/mandoc.1 b/usr.bin/mandoc/mandoc.1
index 4cd7d651ce6..4d9398f9e19 100644
--- a/usr.bin/mandoc/mandoc.1
+++ b/usr.bin/mandoc/mandoc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: mandoc.1,v 1.31 2010/06/10 22:50:10 schwarze Exp $
+.\" $OpenBSD: mandoc.1,v 1.32 2010/06/26 17:56:43 schwarze Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 10 2010 $
+.Dd $Mdocdate: June 26 2010 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -348,7 +348,7 @@ cause rendered documents to appear as they do in
.Pp
Special characters are rendered in decimal-encoded UTF-8.
.Ss PostScript Output
-PostScript Level 1 pages may be generated by
+PostScript Level 2 pages may be generated by
.Fl T Ns Cm ps .
Output pages are US-letter sized (215.9 x 279.4 mm) and rendered in
fixed, 10-point Courier font.
diff --git a/usr.bin/mandoc/mandoc.c b/usr.bin/mandoc/mandoc.c
index e83a98aa8ab..b652e5e2190 100644
--- a/usr.bin/mandoc/mandoc.c
+++ b/usr.bin/mandoc/mandoc.c
@@ -1,6 +1,6 @@
-/* $Id: mandoc.c,v 1.13 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.14 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -23,20 +23,42 @@
#include <string.h>
#include <time.h>
+#include "mandoc.h"
#include "libmandoc.h"
-static int a2time(time_t *, const char *, const char *);
+static int a2time(time_t *, const char *, const char *);
+static int spec_norm(char *, int);
+
+
+/*
+ * "Normalise" a special string by converting its ASCII_HYPH entries
+ * into actual hyphens.
+ */
+static int
+spec_norm(char *p, int sz)
+{
+ int i;
+
+ for (i = 0; i < sz; i++)
+ if (ASCII_HYPH == p[i])
+ p[i] = '-';
+
+ return(sz);
+}
int
-mandoc_special(const char *p)
+mandoc_special(char *p)
{
int terminator; /* Terminator for \s. */
int lim; /* Limit for N in \s. */
int c, i;
+ char *sv;
+ sv = p;
+
if ('\\' != *p++)
- return(0);
+ return(spec_norm(sv, 0));
switch (*p) {
case ('\''):
@@ -45,6 +67,8 @@ mandoc_special(const char *p)
/* FALLTHROUGH */
case ('q'):
/* FALLTHROUGH */
+ case (ASCII_HYPH):
+ /* FALLTHROUGH */
case ('-'):
/* FALLTHROUGH */
case ('~'):
@@ -68,12 +92,12 @@ mandoc_special(const char *p)
case (':'):
/* FALLTHROUGH */
case ('c'):
- return(2);
+ /* FALLTHROUGH */
case ('e'):
- return(2);
+ return(spec_norm(sv, 2));
case ('s'):
if ('\0' == *++p)
- return(2);
+ return(spec_norm(sv, 2));
c = 2;
terminator = 0;
@@ -103,21 +127,21 @@ mandoc_special(const char *p)
if (*p == '\'') {
if (terminator)
- return(0);
+ return(spec_norm(sv, 0));
lim = 0;
terminator = 1;
++p;
++c;
} else if (*p == '[') {
if (terminator)
- return(0);
+ return(spec_norm(sv, 0));
lim = 0;
terminator = 2;
++p;
++c;
} else if (*p == '(') {
if (terminator)
- return(0);
+ return(spec_norm(sv, 0));
lim = 2;
terminator = 3;
++p;
@@ -127,7 +151,7 @@ mandoc_special(const char *p)
/* TODO: needs to handle floating point. */
if ( ! isdigit((u_char)*p))
- return(0);
+ return(spec_norm(sv, 0));
for (i = 0; isdigit((u_char)*p); i++) {
if (lim && i >= lim)
@@ -138,52 +162,52 @@ mandoc_special(const char *p)
if (terminator && terminator < 3) {
if (1 == terminator && *p != '\'')
- return(0);
+ return(spec_norm(sv, 0));
if (2 == terminator && *p != ']')
- return(0);
+ return(spec_norm(sv, 0));
++p;
++c;
}
- return(c);
+ return(spec_norm(sv, c));
case ('f'):
/* FALLTHROUGH */
case ('F'):
/* FALLTHROUGH */
case ('*'):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
switch (*p) {
case ('('):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- return(4);
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
+ return(spec_norm(sv, 4));
case ('['):
for (c = 3, p++; *p && ']' != *p; p++, c++)
- if ( ! isgraph((u_char)*p))
+ if (isspace((u_char)*p))
break;
- return(*p == ']' ? c : 0);
+ return(spec_norm(sv, *p == ']' ? c : 0));
default:
break;
}
- return(3);
+ return(spec_norm(sv, 3));
case ('('):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- return(4);
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
+ return(spec_norm(sv, 4));
case ('['):
break;
default:
- return(0);
+ return(spec_norm(sv, 0));
}
for (c = 3, p++; *p && ']' != *p; p++, c++)
- if ( ! isgraph((u_char)*p))
+ if (isspace((u_char)*p))
break;
- return(*p == ']' ? c : 0);
+ return(spec_norm(sv, *p == ']' ? c : 0));
}
diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h
index 6e1efa9e14e..696da7ce450 100644
--- a/usr.bin/mandoc/mandoc.h
+++ b/usr.bin/mandoc/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.6 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.7 2010/06/26 17:56:43 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -36,7 +36,9 @@ enum mandocerr {
MANDOCERR_BADESCAPE, /* bad escape sequence */
MANDOCERR_BADQUOTE, /* unterminated quoted string */
MANDOCERR_NOWIDTHARG, /* argument requires the width argument */
+ /* FIXME: merge with MANDOCERR_IGNARGV. */
MANDOCERR_WIDTHARG, /* superfluous width argument */
+ MANDOCERR_IGNARGV, /* macro ignoring argv */
MANDOCERR_BADDATE, /* bad date argument */
MANDOCERR_BADWIDTH, /* bad width argument */
MANDOCERR_BADMSEC, /* unknown manual section */
@@ -74,6 +76,7 @@ enum mandocerr {
MANDOCERR_NOARGV, /* macro requires argument(s) */
MANDOCERR_NOTITLE, /* no title in document */
MANDOCERR_LISTTYPE, /* missing list type */
+ MANDOCERR_DISPTYPE, /* missing display type */
MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
MANDOCERR_BODYLOST, /* body argument(s) will be lost */
#define MANDOCERR_ERROR MANDOCERR_BODYLOST
@@ -82,9 +85,8 @@ enum mandocerr {
/* FIXME: this should be a MANDOCERR_ERROR */
MANDOCERR_FONTTYPE, /* missing font type */
/* FIXME: this should be a MANDOCERR_ERROR */
- MANDOCERR_DISPTYPE, /* missing display type */
- /* FIXME: this should be a MANDOCERR_ERROR */
MANDOCERR_NESTEDDISP, /* displays may not be nested */
+ MANDOCERR_BADDISP, /* unsupported display type */
MANDOCERR_SYNTNOSCOPE, /* request scope close w/none open */
MANDOCERR_SYNTSCOPE, /* scope broken, syntax violated */
MANDOCERR_SYNTLINESCOPE, /* line scope broken, syntax violated */
diff --git a/usr.bin/mandoc/mdoc.7 b/usr.bin/mandoc/mdoc.7
index aebf9c5417a..cba102ea04c 100644
--- a/usr.bin/mandoc/mdoc.7
+++ b/usr.bin/mandoc/mdoc.7
@@ -1,4 +1,4 @@
-.\" $Id: mdoc.7,v 1.35 2010/06/08 00:11:47 schwarze Exp $
+.\" $Id: mdoc.7,v 1.36 2010/06/26 17:56:43 schwarze Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 8 2010 $
+.Dd $Mdocdate: June 26 2010 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -1094,10 +1094,7 @@ As a scaling unit following the syntax described in
As the calculated string length of the opaque string.
.El
.Pp
-If unset, it will revert to the value of
-.Ar 8n
-as described in
-.Sx Scaling Widths .
+If not provided an argument, it will be ignored.
.It Fl compact
Do not assert a vertical space before the block.
.It Fl file Ar file
@@ -2169,6 +2166,9 @@ Heirloom troff, the other significant troff implementation accepting
.Pp
.Bl -dash -compact
.It
+Old groff fails to assert a newline before
+.Sx \&Bd Fl ragged compact .
+.It
groff behaves inconsistently when encountering
.Pf non- Sx \&Fa
children of
@@ -2243,16 +2243,15 @@ In quoted literals, groff allowed pair-wise double-quotes to produce a
standalone double-quote in formatted output.
This idiosyncratic behaviour is not applicable in mandoc.
.It
-Display types
+Display offsets
.Sx \&Bd
-.Fl center
+.Fl offset Ar center
and
-.Fl right
-are aliases for
-.Fl left
-in mandoc. Furthermore, the
+.Fl offset Ar right
+are disregarded in mandoc.
+Furthermore, the
.Fl file Ar file
-argument is ignored.
+argument is not supported in mandoc.
Lastly, since text is not right-justified in mandoc (or even groff),
.Fl ragged
and
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index aec75eae499..d0e60ef0980 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.56 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.57 2010/06/26 17:56:43 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -564,7 +564,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
*/
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
- LIST_column == n->data.list) {
+ LIST_column == n->data.Bl.type) {
/* `Bl' is open without any children. */
m->flags |= MDOC_FREECOL;
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
@@ -573,7 +573,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
NULL != n->parent &&
MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->data.list) {
+ LIST_column == n->parent->data.Bl.type) {
/* `Bl' has block-level `It' children. */
m->flags |= MDOC_FREECOL;
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
@@ -779,7 +779,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
*/
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
- LIST_column == n->data.list) {
+ LIST_column == n->data.Bl.type) {
m->flags |= MDOC_FREECOL;
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
goto err;
@@ -795,7 +795,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
NULL != n->parent &&
MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->data.list) {
+ LIST_column == n->parent->data.Bl.type) {
m->flags |= MDOC_FREECOL;
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
goto err;
diff --git a/usr.bin/mandoc/mdoc.h b/usr.bin/mandoc/mdoc.h
index 80e04579da4..dc51b4e92a6 100644
--- a/usr.bin/mandoc/mdoc.h
+++ b/usr.bin/mandoc/mdoc.h
@@ -1,6 +1,6 @@
-/* $Id: mdoc.h,v 1.27 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.28 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -263,6 +263,28 @@ enum mdoc_list {
LIST_tag
};
+enum mdoc_disp {
+ DISP__NONE = 0,
+ DISP_centred,
+ DISP_ragged,
+ DISP_unfilled,
+ DISP_filled,
+ DISP_literal
+};
+
+struct mdoc_bd {
+ const char *offs; /* -offset */
+ enum mdoc_disp type; /* -ragged, etc. */
+ int comp; /* -compact */
+};
+
+struct mdoc_bl {
+ const char *width; /* -width */
+ const char *offs; /* -offset */
+ enum mdoc_list type; /* -tag, -enum, etc. */
+ int comp; /* -compact */
+};
+
/* Node in AST. */
struct mdoc_node {
struct mdoc_node *parent; /* parent AST node */
@@ -288,7 +310,8 @@ struct mdoc_node {
char *string; /* TEXT */
union {
- enum mdoc_list list; /* for `Bl' nodes */
+ struct mdoc_bl Bl;
+ struct mdoc_bd Bd;
} data;
};
diff --git a/usr.bin/mandoc/mdoc_action.c b/usr.bin/mandoc/mdoc_action.c
index dbb100c3123..9aafbdfe9df 100644
--- a/usr.bin/mandoc/mdoc_action.c
+++ b/usr.bin/mandoc/mdoc_action.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_action.c,v 1.40 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mdoc_action.c,v 1.41 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -64,9 +64,7 @@ static int post_st(POST_ARGS);
static int post_std(POST_ARGS);
static int pre_bd(PRE_ARGS);
-static int pre_bl(PRE_ARGS);
static int pre_dl(PRE_ARGS);
-static int pre_offset(PRE_ARGS);
static const struct actions mdoc_actions[MDOC_MAX] = {
{ NULL, NULL }, /* Ap */
@@ -80,7 +78,7 @@ static const struct actions mdoc_actions[MDOC_MAX] = {
{ pre_dl, post_display }, /* Dl */
{ pre_bd, post_display }, /* Bd */
{ NULL, NULL }, /* Ed */
- { pre_bl, post_bl }, /* Bl */
+ { NULL, post_bl }, /* Bl */
{ NULL, NULL }, /* El */
{ NULL, NULL }, /* It */
{ NULL, NULL }, /* Ad */
@@ -629,33 +627,34 @@ static int
post_bl_tagwidth(POST_ARGS)
{
struct mdoc_node *nn;
- size_t sz;
+ size_t sz, ssz;
int i;
char buf[NUMSIZ];
- /* Defaults to ten ens. */
-
- sz = 10; /* XXX: make this a macro value. */
+ sz = 10;
for (nn = n->body->child; nn; nn = nn->next) {
- if (MDOC_It == nn->tok)
- break;
- }
+ if (MDOC_It != nn->tok)
+ continue;
- if (nn) {
assert(MDOC_BLOCK == nn->type);
nn = nn->head->child;
- if (MDOC_TEXT != nn->type) {
- sz = mdoc_macro2len(nn->tok);
- if (sz == 0) {
- if ( ! mdoc_nmsg(m, n, MANDOCERR_NOWIDTHARG))
- return(0);
- sz = 10;
- }
- } else
+
+ if (MDOC_TEXT == nn->type) {
sz = strlen(nn->string) + 1;
+ break;
+ }
+
+ if (0 != (ssz = mdoc_macro2len(nn->tok)))
+ sz = ssz;
+ else if ( ! mdoc_nmsg(m, n, MANDOCERR_NOWIDTHARG))
+ return(0);
+
+ break;
}
+ /* Defaults to ten ens. */
+
snprintf(buf, NUMSIZ, "%zun", sz);
/*
@@ -663,19 +662,21 @@ post_bl_tagwidth(POST_ARGS)
* We're guaranteed that a MDOC_Width doesn't already exist.
*/
- nn = n;
- assert(nn->args);
- i = (int)(nn->args->argc)++;
-
- nn->args->argv = mandoc_realloc(nn->args->argv,
- nn->args->argc * sizeof(struct mdoc_argv));
-
- nn->args->argv[i].arg = MDOC_Width;
- nn->args->argv[i].line = n->line;
- nn->args->argv[i].pos = n->pos;
- nn->args->argv[i].sz = 1;
- nn->args->argv[i].value = mandoc_malloc(sizeof(char *));
- nn->args->argv[i].value[0] = mandoc_strdup(buf);
+ assert(n->args);
+ i = (int)(n->args->argc)++;
+
+ n->args->argv = mandoc_realloc(n->args->argv,
+ n->args->argc * sizeof(struct mdoc_argv));
+
+ n->args->argv[i].arg = MDOC_Width;
+ n->args->argv[i].line = n->line;
+ n->args->argv[i].pos = n->pos;
+ n->args->argv[i].sz = 1;
+ n->args->argv[i].value = mandoc_malloc(sizeof(char *));
+ n->args->argv[i].value[0] = mandoc_strdup(buf);
+
+ /* Set our width! */
+ n->data.Bl.width = n->args->argv[i].value[0];
return(1);
}
@@ -692,36 +693,35 @@ post_bl_width(POST_ARGS)
int i;
enum mdoct tok;
char buf[NUMSIZ];
- char *p;
-
- if (NULL == n->args)
- return(1);
-
- for (i = 0; i < (int)n->args->argc; i++)
- if (MDOC_Width == n->args->argv[i].arg)
- break;
-
- if (i == (int)n->args->argc)
- return(1);
- p = n->args->argv[i].value[0];
/*
* If the value to -width is a macro, then we re-write it to be
* the macro's width as set in share/tmac/mdoc/doc-common.
*/
- if (0 == strcmp(p, "Ds"))
+ if (0 == strcmp(n->data.Bl.width, "Ds"))
width = 6;
- else if (MDOC_MAX == (tok = mdoc_hash_find(p)))
+ else if (MDOC_MAX == (tok = mdoc_hash_find(n->data.Bl.width)))
return(1);
else if (0 == (width = mdoc_macro2len(tok)))
return(mdoc_nmsg(m, n, MANDOCERR_BADWIDTH));
/* The value already exists: free and reallocate it. */
+ assert(n->args);
+
+ for (i = 0; i < (int)n->args->argc; i++)
+ if (MDOC_Width == n->args->argv[i].arg)
+ break;
+
+ assert(i < (int)n->args->argc);
+
snprintf(buf, NUMSIZ, "%zun", width);
free(n->args->argv[i].value[0]);
n->args->argv[i].value[0] = mandoc_strdup(buf);
+
+ /* Set our width! */
+ n->data.Bl.width = n->args->argv[i].value[0];
return(1);
}
@@ -737,7 +737,9 @@ post_bl_head(POST_ARGS)
int i, c;
struct mdoc_node *np, *nn, *nnp;
- if (NULL == n->child)
+ if (LIST_column != n->data.Bl.type)
+ return(1);
+ else if (NULL == n->child)
return(1);
np = n->parent;
@@ -747,8 +749,7 @@ post_bl_head(POST_ARGS)
if (MDOC_Column == np->args->argv[c].arg)
break;
- if (c == (int)np->args->argc)
- return(1);
+ assert(c < (int)np->args->argc);
assert(0 == np->args->argv[c].sz);
/*
@@ -778,7 +779,8 @@ post_bl_head(POST_ARGS)
static int
post_bl(POST_ARGS)
{
- int i, r, len;
+ struct mdoc_node *nn;
+ const char *ww;
if (MDOC_HEAD == n->type)
return(post_bl_head(m, n));
@@ -793,21 +795,27 @@ post_bl(POST_ARGS)
* rewritten into real lengths).
*/
- len = (int)(n->args ? n->args->argc : 0);
+ ww = n->data.Bl.width;
- for (r = i = 0; i < len; i++) {
- if (MDOC_Tag == n->args->argv[i].arg)
- r |= 1 << 0;
- if (MDOC_Width == n->args->argv[i].arg)
- r |= 1 << 1;
- }
-
- if (r & (1 << 0) && ! (r & (1 << 1))) {
+ if (LIST_tag == n->data.Bl.type && NULL == n->data.Bl.width) {
if ( ! post_bl_tagwidth(m, n))
return(0);
- } else if (r & (1 << 1))
+ } else if (NULL != n->data.Bl.width) {
if ( ! post_bl_width(m, n))
return(0);
+ } else
+ return(1);
+
+ assert(n->data.Bl.width);
+
+ /* If it has changed, propogate new width to children. */
+
+ if (ww == n->data.Bl.width)
+ return(1);
+
+ for (nn = n->child; nn; nn = nn->next)
+ if (MDOC_Bl == nn->tok)
+ nn->data.Bl.width = n->data.Bl.width;
return(1);
}
@@ -827,7 +835,6 @@ post_pa(POST_ARGS)
np = n;
m->next = MDOC_NEXT_CHILD;
- /* XXX: make into macro value. */
if ( ! mdoc_word_alloc(m, n->line, n->pos, "~"))
return(0);
m->last = np;
@@ -933,61 +940,17 @@ pre_dl(PRE_ARGS)
}
-/* ARGSUSED */
-static int
-pre_offset(PRE_ARGS)
-{
- int i;
-
- /*
- * Make sure that an empty offset produces an 8n length space as
- * stipulated by mdoc.samples.
- */
-
- for (i = 0; n->args && i < (int)n->args->argc; i++) {
- if (MDOC_Offset != n->args->argv[i].arg)
- continue;
- if (n->args->argv[i].sz)
- break;
- assert(1 == n->args->refcnt);
- /* If no value set, length of <string>. */
- n->args->argv[i].sz++;
- n->args->argv[i].value = mandoc_malloc(sizeof(char *));
- n->args->argv[i].value[0] = mandoc_strdup("8n");
- break;
- }
-
- return(1);
-}
-
-
-static int
-pre_bl(PRE_ARGS)
-{
-
- if (MDOC_BLOCK == n->type)
- return(pre_offset(m, n));
- return(1);
-}
-
-
static int
pre_bd(PRE_ARGS)
{
- int i;
- if (MDOC_BLOCK == n->type)
- return(pre_offset(m, n));
if (MDOC_BODY != n->type)
return(1);
- /* Enter literal context if `Bd -literal' or `-unfilled'. */
-
- for (n = n->parent, i = 0; i < (int)n->args->argc; i++)
- if (MDOC_Literal == n->args->argv[i].arg)
- m->flags |= MDOC_LITERAL;
- else if (MDOC_Unfilled == n->args->argv[i].arg)
- m->flags |= MDOC_LITERAL;
+ if (DISP_literal == n->data.Bd.type)
+ m->flags |= MDOC_LITERAL;
+ if (DISP_unfilled == n->data.Bd.type)
+ m->flags |= MDOC_LITERAL;
return(1);
}
diff --git a/usr.bin/mandoc/mdoc_argv.c b/usr.bin/mandoc/mdoc_argv.c
index ef98643e148..a556aa1d768 100644
--- a/usr.bin/mandoc/mdoc_argv.c
+++ b/usr.bin/mandoc/mdoc_argv.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_argv.c,v 1.30 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mdoc_argv.c,v 1.31 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -355,7 +355,7 @@ mdoc_args(struct mdoc *m, int line, int *pos,
if (MDOC_Bl == n->tok)
break;
- if (n && LIST_column == n->data.list) {
+ if (n && LIST_column == n->data.Bl.type) {
fl |= ARGS_TABSEP;
fl &= ~ARGS_DELIM;
}
diff --git a/usr.bin/mandoc/mdoc_html.c b/usr.bin/mandoc/mdoc_html.c
index bf7fc126b9c..4fac42a6faa 100644
--- a/usr.bin/mandoc/mdoc_html.c
+++ b/usr.bin/mandoc/mdoc_html.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_html.c,v 1.21 2010/06/08 00:11:47 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.22 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -1031,11 +1031,13 @@ mdoc_it_pre(MDOC_ARGS)
if (MDOC_BLOCK != n->type)
bl = bl->parent;
- type = bl->data.list;
+ SCALE_HS_INIT(&offs, 0);
- /* Set default width and offset. */
+ type = bl->data.Bl.type;
+ comp = bl->data.Bl.comp;
- SCALE_HS_INIT(&offs, 0);
+ if (bl->data.Bl.offs)
+ a2offs(bl->data.Bl.offs, &offs);
switch (type) {
case (LIST_enum):
@@ -1052,23 +1054,15 @@ mdoc_it_pre(MDOC_ARGS)
break;
}
- /* Get width, offset, and compact arguments. */
+ if (bl->data.Bl.width)
+ a2width(bl->data.Bl.width, &width);
wp = -1;
- for (comp = i = 0; bl->args && i < (int)bl->args->argc; i++)
+ for (i = 0; bl->args && i < (int)bl->args->argc; i++)
switch (bl->args->argv[i].arg) {
case (MDOC_Column):
wp = i; /* Save for later. */
break;
- case (MDOC_Width):
- a2width(bl->args->argv[i].value[0], &width);
- break;
- case (MDOC_Offset):
- a2offs(bl->args->argv[i].value[0], &offs);
- break;
- case (MDOC_Compact):
- comp = 1;
- break;
default:
break;
}
@@ -1119,7 +1113,7 @@ mdoc_bl_pre(MDOC_ARGS)
return(0);
if (MDOC_BLOCK != n->type)
return(1);
- if (LIST_enum != n->data.list)
+ if (LIST_enum != n->data.Bl.type)
return(1);
ord = malloc(sizeof(struct ord));
@@ -1143,7 +1137,7 @@ mdoc_bl_post(MDOC_ARGS)
if (MDOC_BLOCK != n->type)
return;
- if (LIST_enum != n->data.list)
+ if (LIST_enum != n->data.Bl.type)
return;
ord = h->ords.head;
@@ -1349,42 +1343,19 @@ static int
mdoc_bd_pre(MDOC_ARGS)
{
struct htmlpair tag[2];
- int type, comp, i;
- const struct mdoc_node *bl, *nn;
+ int comp;
+ const struct mdoc_node *nn;
struct roffsu su;
- if (MDOC_BLOCK == n->type)
- bl = n;
- else if (MDOC_HEAD == n->type)
+ if (MDOC_HEAD == n->type)
return(0);
- else
- bl = n->parent;
SCALE_VS_INIT(&su, 0);
- type = comp = 0;
- for (i = 0; bl->args && i < (int)bl->args->argc; i++)
- switch (bl->args->argv[i].arg) {
- case (MDOC_Offset):
- a2offs(bl->args->argv[i].value[0], &su);
- break;
- case (MDOC_Compact):
- comp = 1;
- break;
- case (MDOC_Centred):
- /* FALLTHROUGH */
- case (MDOC_Ragged):
- /* FALLTHROUGH */
- case (MDOC_Filled):
- /* FALLTHROUGH */
- case (MDOC_Unfilled):
- /* FALLTHROUGH */
- case (MDOC_Literal):
- type = bl->args->argv[i].arg;
- break;
- default:
- break;
- }
+ if (n->data.Bd.offs)
+ a2offs(n->data.Bd.offs, &su);
+
+ comp = n->data.Bd.comp;
/* FIXME: -centered, etc. formatting. */
/* FIXME: does not respect -offset ??? */
@@ -1411,7 +1382,8 @@ mdoc_bd_pre(MDOC_ARGS)
return(1);
}
- if (MDOC_Unfilled != type && MDOC_Literal != type)
+ if (DISP_unfilled != n->data.Bd.type &&
+ DISP_literal != n->data.Bd.type)
return(1);
PAIR_CLASS_INIT(&tag[0], "lit");
diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c
index bbdae2807e0..00d8d9ab19d 100644
--- a/usr.bin/mandoc/mdoc_term.c
+++ b/usr.bin/mandoc/mdoc_term.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_term.c,v 1.87 2010/06/10 22:50:10 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.88 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -48,15 +48,12 @@ struct termact {
void (*post)(DECL_ARGS);
};
-static size_t a2width(const struct mdoc_argv *, int);
+static size_t a2width(const char *);
static size_t a2height(const struct mdoc_node *);
-static size_t a2offs(const struct mdoc_argv *);
+static size_t a2offs(const char *);
static int arg_hasattr(int, const struct mdoc_node *);
-static int arg_getattrs(const int *, int *, size_t,
- const struct mdoc_node *);
static int arg_getattr(int, const struct mdoc_node *);
-static int arg_disptype(const struct mdoc_node *);
static void print_bvspace(struct termp *,
const struct mdoc_node *,
const struct mdoc_node *);
@@ -473,62 +470,33 @@ a2height(const struct mdoc_node *n)
static size_t
-a2width(const struct mdoc_argv *arg, int pos)
+a2width(const char *v)
{
struct roffsu su;
- assert(arg->value[pos]);
- if ( ! a2roffsu(arg->value[pos], &su, SCALE_MAX))
- SCALE_HS_INIT(&su, strlen(arg->value[pos]));
+ assert(v);
+ if ( ! a2roffsu(v, &su, SCALE_MAX))
+ SCALE_HS_INIT(&su, strlen(v));
return(term_hspan(&su));
}
-static int
-arg_disptype(const struct mdoc_node *n)
-{
- int i, len;
-
- assert(MDOC_BLOCK == n->type);
-
- len = (int)(n->args ? n->args->argc : 0);
-
- for (i = 0; i < len; i++)
- switch (n->args->argv[i].arg) {
- case (MDOC_Centred):
- /* FALLTHROUGH */
- case (MDOC_Ragged):
- /* FALLTHROUGH */
- case (MDOC_Filled):
- /* FALLTHROUGH */
- case (MDOC_Unfilled):
- /* FALLTHROUGH */
- case (MDOC_Literal):
- return(n->args->argv[i].arg);
- default:
- break;
- }
-
- return(-1);
-}
-
-
static size_t
-a2offs(const struct mdoc_argv *arg)
+a2offs(const char *v)
{
struct roffsu su;
- if ('\0' == arg->value[0][0])
+ if ('\0' == *v)
return(0);
- else if (0 == strcmp(arg->value[0], "left"))
+ else if (0 == strcmp(v, "left"))
return(0);
- else if (0 == strcmp(arg->value[0], "indent"))
+ else if (0 == strcmp(v, "indent"))
return(INDENT + 1);
- else if (0 == strcmp(arg->value[0], "indent-two"))
+ else if (0 == strcmp(v, "indent-two"))
return((INDENT + 1) * 2);
- else if ( ! a2roffsu(arg->value[0], &su, SCALE_MAX))
- SCALE_HS_INIT(&su, strlen(arg->value[0]));
+ else if ( ! a2roffsu(v, &su, SCALE_MAX))
+ SCALE_HS_INIT(&su, strlen(v));
return(term_hspan(&su));
}
@@ -548,39 +516,21 @@ arg_hasattr(int arg, const struct mdoc_node *n)
/*
* Get the index of an argument in a node's argument list or -1 if it
- * does not exist. See arg_getattrs().
+ * does not exist.
*/
static int
arg_getattr(int v, const struct mdoc_node *n)
{
- int val;
-
- return(arg_getattrs(&v, &val, 1, n) ? val : -1);
-}
-
-
-/*
- * Walk through the argument list for a node and fill an array "vals"
- * with the positions of the argument structures listed in "keys".
- * Return the number of elements that were written into "vals", which
- * can be zero.
- */
-static int
-arg_getattrs(const int *keys, int *vals,
- size_t sz, const struct mdoc_node *n)
-{
- int i, j, k;
+ int i;
if (NULL == n->args)
return(0);
- for (k = i = 0; i < (int)n->args->argc; i++)
- for (j = 0; j < (int)sz; j++)
- if (n->args->argv[i].arg == keys[j]) {
- vals[j] = i;
- k++;
- }
- return(k);
+ for (i = 0; i < (int)n->args->argc; i++)
+ if (n->args->argv[i].arg == v)
+ return(i);
+
+ return(-1);
}
@@ -597,7 +547,10 @@ print_bvspace(struct termp *p,
const struct mdoc_node *nn;
term_newln(p);
- if (arg_hasattr(MDOC_Compact, bl))
+
+ if (MDOC_Bd == bl->tok && bl->data.Bd.comp)
+ return;
+ if (MDOC_Bl == bl->tok && bl->data.Bl.comp)
return;
/* Do not vspace directly after Ss/Sh. */
@@ -616,13 +569,13 @@ print_bvspace(struct termp *p,
/* A `-column' does not assert vspace within the list. */
- if (MDOC_Bl == bl->tok && LIST_column == bl->data.list)
+ if (MDOC_Bl == bl->tok && LIST_column == bl->data.Bl.type)
if (n->prev && MDOC_It == n->prev->tok)
return;
/* A `-diag' without body does not vspace. */
- if (MDOC_Bl == bl->tok && LIST_diag == bl->data.list)
+ if (MDOC_Bl == bl->tok && LIST_diag == bl->data.Bl.type)
if (n->prev && MDOC_It == n->prev->tok) {
assert(n->prev->body);
if (NULL == n->prev->body->child)
@@ -666,7 +619,7 @@ termp_it_pre(DECL_ARGS)
{
const struct mdoc_node *bl, *nn;
char buf[7];
- int i, keys[3], vals[3];
+ int i, col;
size_t width, offset, ncols, dcol;
enum mdoc_list type;
@@ -676,18 +629,7 @@ termp_it_pre(DECL_ARGS)
}
bl = n->parent->parent->parent;
-
- /* Get list width, offset, and list type from argument list. */
-
- keys[0] = MDOC_Width;
- keys[1] = MDOC_Offset;
- keys[2] = MDOC_Column;
-
- vals[0] = vals[1] = vals[2] = -1;
-
- arg_getattrs(keys, vals, 3, bl);
-
- type = bl->data.list;
+ type = bl->data.Bl.type;
/*
* First calculate width and offset. This is pretty easy unless
@@ -697,13 +639,16 @@ termp_it_pre(DECL_ARGS)
width = offset = 0;
- if (vals[1] >= 0)
- offset = a2offs(&bl->args->argv[vals[1]]);
+ if (bl->data.Bl.offs)
+ offset = a2offs(bl->data.Bl.offs);
switch (type) {
case (LIST_column):
if (MDOC_HEAD == n->type)
break;
+
+ col = arg_getattr(MDOC_Column, bl);
+
/*
* Imitate groff's column handling:
* - For each earlier column, add its width.
@@ -713,7 +658,7 @@ termp_it_pre(DECL_ARGS)
* column.
* - For more than 5 columns, add only one column.
*/
- ncols = bl->args->argv[vals[2]].sz;
+ ncols = bl->args->argv[col].sz;
/* LINTED */
dcol = ncols < 5 ? 4 : ncols == 5 ? 3 : 1;
@@ -726,8 +671,7 @@ termp_it_pre(DECL_ARGS)
nn->prev && i < (int)ncols;
nn = nn->prev, i++)
offset += dcol + a2width
- (&bl->args->argv[vals[2]], i);
-
+ (bl->args->argv[col].value[i]);
/*
* When exceeding the declared number of columns, leave
@@ -742,10 +686,10 @@ termp_it_pre(DECL_ARGS)
* Use the declared column widths, extended as explained
* in the preceding paragraph.
*/
- width = a2width(&bl->args->argv[vals[2]], i) + dcol;
+ width = a2width(bl->args->argv[col].value[i]) + dcol;
break;
default:
- if (vals[0] < 0)
+ if (NULL == bl->data.Bl.width)
break;
/*
@@ -753,7 +697,8 @@ termp_it_pre(DECL_ARGS)
* number for buffering single arguments. See the above
* handling for column for how this changes.
*/
- width = a2width(&bl->args->argv[vals[0]], 0) + 2;
+ assert(bl->data.Bl.width);
+ width = a2width(bl->data.Bl.width) + 2;
break;
}
@@ -1015,7 +960,7 @@ termp_it_post(DECL_ARGS)
if (MDOC_BLOCK == n->type)
return;
- type = n->parent->parent->parent->data.list;
+ type = n->parent->parent->parent->data.Bl.type;
switch (type) {
case (LIST_item):
@@ -1628,7 +1573,6 @@ static int
termp_bd_pre(DECL_ARGS)
{
size_t tabwidth;
- int i, type;
size_t rm, rmax;
const struct mdoc_node *nn;
@@ -1638,13 +1582,8 @@ termp_bd_pre(DECL_ARGS)
} else if (MDOC_HEAD == n->type)
return(0);
- nn = n->parent;
-
- type = arg_disptype(nn);
- assert(-1 != type);
-
- if (-1 != (i = arg_getattr(MDOC_Offset, nn)))
- p->offset += a2offs(&nn->args->argv[i]);
+ if (n->data.Bd.offs)
+ p->offset += a2offs(n->data.Bd.offs);
/*
* If -ragged or -filled are specified, the block does nothing
@@ -1654,7 +1593,8 @@ termp_bd_pre(DECL_ARGS)
* lines are allowed.
*/
- if (MDOC_Literal != type && MDOC_Unfilled != type)
+ if (DISP_literal != n->data.Bd.type &&
+ DISP_unfilled != n->data.Bd.type)
return(1);
tabwidth = p->tabwidth;
@@ -1671,8 +1611,8 @@ termp_bd_pre(DECL_ARGS)
NULL == nn->next)
term_flushln(p);
}
- p->tabwidth = tabwidth;
+ p->tabwidth = tabwidth;
p->rmargin = rm;
p->maxrmargin = rmax;
return(0);
@@ -1683,19 +1623,16 @@ termp_bd_pre(DECL_ARGS)
static void
termp_bd_post(DECL_ARGS)
{
- int type;
size_t rm, rmax;
if (MDOC_BODY != n->type)
return;
- type = arg_disptype(n->parent);
- assert(-1 != type);
-
rm = p->rmargin;
rmax = p->maxrmargin;
- if (MDOC_Literal == type || MDOC_Unfilled == type)
+ if (DISP_literal == n->data.Bd.type ||
+ DISP_unfilled == n->data.Bd.type)
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index 7d336d05567..2baad2bc213 100644
--- a/usr.bin/mandoc/mdoc_validate.c
+++ b/usr.bin/mandoc/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.60 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.61 2010/06/26 17:56:43 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -43,12 +43,10 @@ struct valids {
static int check_parent(PRE_ARGS, enum mdoct, enum mdoc_type);
static int check_stdarg(PRE_ARGS);
-static int check_text(struct mdoc *, int, int, const char *);
+static int check_text(struct mdoc *, int, int, char *);
static int check_argv(struct mdoc *,
- const struct mdoc_node *,
- const struct mdoc_argv *);
-static int check_args(struct mdoc *,
- const struct mdoc_node *);
+ struct mdoc_node *, struct mdoc_argv *);
+static int check_args(struct mdoc *, struct mdoc_node *);
static int err_child_lt(struct mdoc *, const char *, int);
static int warn_child_lt(struct mdoc *, const char *, int);
static int err_child_gt(struct mdoc *, const char *, int);
@@ -273,7 +271,7 @@ mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
{
v_pre *p;
int line, pos;
- const char *tp;
+ char *tp;
if (MDOC_TEXT == n->type) {
tp = n->string;
@@ -415,7 +413,7 @@ check_stdarg(PRE_ARGS)
static int
-check_args(struct mdoc *m, const struct mdoc_node *n)
+check_args(struct mdoc *m, struct mdoc_node *n)
{
int i;
@@ -432,8 +430,7 @@ check_args(struct mdoc *m, const struct mdoc_node *n)
static int
-check_argv(struct mdoc *m, const struct mdoc_node *n,
- const struct mdoc_argv *v)
+check_argv(struct mdoc *m, struct mdoc_node *n, struct mdoc_argv *v)
{
int i;
@@ -453,7 +450,7 @@ check_argv(struct mdoc *m, const struct mdoc_node *n,
static int
-check_text(struct mdoc *mdoc, int line, int pos, const char *p)
+check_text(struct mdoc *mdoc, int line, int pos, char *p)
{
int c;
@@ -531,15 +528,17 @@ pre_display(PRE_ARGS)
static int
pre_bl(PRE_ARGS)
{
- int i, width, offs, cmpt, dupl;
+ int i, comp, dup;
+ const char *offs, *width;
enum mdoc_list lt;
if (MDOC_BLOCK != n->type) {
assert(n->parent);
assert(MDOC_BLOCK == n->parent->type);
assert(MDOC_Bl == n->parent->tok);
- assert(LIST__NONE != n->parent->data.list);
- n->data.list = n->parent->data.list;
+ assert(LIST__NONE != n->parent->data.Bl.type);
+ memcpy(&n->data.Bl, &n->parent->data.Bl,
+ sizeof(struct mdoc_bl));
return(1);
}
@@ -549,13 +548,13 @@ pre_bl(PRE_ARGS)
* ones. If we find no list type, we default to LIST_item.
*/
- assert(LIST__NONE == n->data.list);
- offs = width = cmpt = -1;
+ assert(LIST__NONE == n->data.Bl.type);
/* LINTED */
for (i = 0; n->args && i < (int)n->args->argc; i++) {
lt = LIST__NONE;
- dupl = 0;
+ dup = comp = 0;
+ width = offs = NULL;
switch (n->args->argv[i].arg) {
/* Set list types. */
case (MDOC_Bullet):
@@ -593,43 +592,54 @@ pre_bl(PRE_ARGS)
break;
/* Set list arguments. */
case (MDOC_Compact):
- if (cmpt >= 0)
- dupl++;
- cmpt = i;
+ dup = n->data.Bl.comp;
+ comp = 1;
break;
case (MDOC_Width):
- if (width >= 0)
- dupl++;
- width = i;
+ dup = (NULL != n->data.Bl.width);
+ width = n->args->argv[i].value[0];
break;
case (MDOC_Offset):
- if (offs >= 0)
- dupl++;
- offs = i;
+ /* NB: this can be empty! */
+ if (n->args->argv[i].sz) {
+ offs = n->args->argv[i].value[0];
+ dup = (NULL != n->data.Bl.offs);
+ break;
+ }
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV))
+ return(0);
break;
}
/* Check: duplicate auxiliary arguments. */
- if (dupl)
- if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
- return(0);
+ if (dup && ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+ return(0);
+
+ if (comp && ! dup)
+ n->data.Bl.comp = comp;
+ if (offs && ! dup)
+ n->data.Bl.offs = offs;
+ if (width && ! dup)
+ n->data.Bl.width = width;
/* Check: multiple list types. */
- if (LIST__NONE != lt && n->data.list != LIST__NONE)
+ if (LIST__NONE != lt && n->data.Bl.type != LIST__NONE)
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
return(0);
/* Assign list type. */
- if (LIST__NONE != lt && n->data.list == LIST__NONE)
- n->data.list = lt;
+ if (LIST__NONE != lt && n->data.Bl.type == LIST__NONE)
+ n->data.Bl.type = lt;
/* The list type should come first. */
- if (n->data.list == LIST__NONE)
- if (width >= 0 || offs >= 0 || cmpt >= 0)
+ if (n->data.Bl.type == LIST__NONE)
+ if (n->data.Bl.width ||
+ n->data.Bl.offs ||
+ n->data.Bl.comp)
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
return(0);
@@ -638,10 +648,10 @@ pre_bl(PRE_ARGS)
/* Allow lists to default to LIST_item. */
- if (LIST__NONE == n->data.list) {
+ if (LIST__NONE == n->data.Bl.type) {
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE))
return(0);
- n->data.list = LIST_item;
+ n->data.Bl.type = LIST_item;
}
/*
@@ -650,9 +660,9 @@ pre_bl(PRE_ARGS)
* and must also be warned.
*/
- switch (n->data.list) {
+ switch (n->data.Bl.type) {
case (LIST_tag):
- if (width >= 0)
+ if (n->data.Bl.width)
break;
if (mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
break;
@@ -666,7 +676,7 @@ pre_bl(PRE_ARGS)
case (LIST_inset):
/* FALLTHROUGH */
case (LIST_item):
- if (width < 0)
+ if (NULL == n->data.Bl.width)
break;
if (mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
break;
@@ -682,43 +692,97 @@ pre_bl(PRE_ARGS)
static int
pre_bd(PRE_ARGS)
{
- int i, type, err;
+ int i, dup, comp;
+ enum mdoc_disp dt;
+ const char *offs;
- if (MDOC_BLOCK != n->type)
+ if (MDOC_BLOCK != n->type) {
+ assert(n->parent);
+ assert(MDOC_BLOCK == n->parent->type);
+ assert(MDOC_Bd == n->parent->tok);
+ assert(DISP__NONE != n->parent->data.Bd.type);
+ memcpy(&n->data.Bd, &n->parent->data.Bd,
+ sizeof(struct mdoc_bd));
return(1);
- if (NULL == n->args) {
- mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE);
- return(0);
}
- /* Make sure that only one type of display is specified. */
+ assert(DISP__NONE == n->data.Bd.type);
/* LINTED */
- for (i = 0, err = type = 0; ! err &&
- i < (int)n->args->argc; i++)
+ for (i = 0; n->args && i < (int)n->args->argc; i++) {
+ dt = DISP__NONE;
+ dup = comp = 0;
+ offs = NULL;
+
switch (n->args->argv[i].arg) {
case (MDOC_Centred):
- /* FALLTHROUGH */
+ dt = DISP_centred;
+ break;
case (MDOC_Ragged):
- /* FALLTHROUGH */
+ dt = DISP_ragged;
+ break;
case (MDOC_Unfilled):
- /* FALLTHROUGH */
+ dt = DISP_unfilled;
+ break;
case (MDOC_Filled):
- /* FALLTHROUGH */
+ dt = DISP_filled;
+ break;
case (MDOC_Literal):
- if (0 == type++)
+ dt = DISP_literal;
+ break;
+ case (MDOC_File):
+ mdoc_nmsg(mdoc, n, MANDOCERR_BADDISP);
+ return(0);
+ case (MDOC_Offset):
+ /* NB: this can be empty! */
+ if (n->args->argv[i].sz) {
+ offs = n->args->argv[i].value[0];
+ dup = (NULL != n->data.Bd.offs);
break;
- if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPREP))
+ }
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV))
return(0);
break;
- default:
+ case (MDOC_Compact):
+ comp = 1;
+ dup = n->data.Bd.comp;
break;
+ default:
+ abort();
+ /* NOTREACHED */
}
- if (type)
- return(1);
- mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE);
- return(0);
+ /* Check whether we have duplicates. */
+
+ if (dup && ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+ return(0);
+
+ /* Make our auxiliary assignments. */
+
+ if (offs && ! dup)
+ n->data.Bd.offs = offs;
+ if (comp && ! dup)
+ n->data.Bd.comp = comp;
+
+ /* Check whether a type has already been assigned. */
+
+ if (DISP__NONE != dt && n->data.Bd.type != DISP__NONE)
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPREP))
+ return(0);
+
+ /* Make our type assignment. */
+
+ if (DISP__NONE != dt && n->data.Bd.type == DISP__NONE)
+ n->data.Bd.type = dt;
+ }
+
+ if (DISP__NONE == n->data.Bd.type) {
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE))
+ return(0);
+ n->data.Bd.type = DISP_ragged;
+ }
+
+ return(1);
}
@@ -976,7 +1040,7 @@ post_it(POST_ARGS)
return(1);
n = mdoc->last->parent->parent;
- lt = n->data.list;
+ lt = n->data.Bl.type;
if (LIST__NONE == lt) {
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_LISTTYPE);
@@ -1068,7 +1132,7 @@ post_bl_head(POST_ARGS)
assert(mdoc->last->parent);
n = mdoc->last->parent;
- if (LIST_column == n->data.list) {
+ if (LIST_column == n->data.Bl.type) {
for (i = 0; i < (int)n->args->argc; i++)
if (MDOC_Column == n->args->argv[i].arg)
break;
diff --git a/usr.bin/mandoc/roff.7 b/usr.bin/mandoc/roff.7
index 65fca6dbb95..a2303dbad7d 100644
--- a/usr.bin/mandoc/roff.7
+++ b/usr.bin/mandoc/roff.7
@@ -1,4 +1,4 @@
-.\" $Id: roff.7,v 1.4 2010/06/06 20:30:08 schwarze Exp $
+.\" $Id: roff.7,v 1.5 2010/06/26 17:56:43 schwarze Exp $
.\"
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 6 2010 $
+.Dd $Mdocdate: June 26 2010 $
.Dt ROFF 7
.Os
.Sh NAME
@@ -173,8 +173,19 @@ BODY...
BODY
.Ed
.Pp
-COND is a conditional (for the time being, this always evaluates to
-false).
+COND is a conditional statement.
+roff allows for complicated conditionals; mandoc is much simpler.
+At this time, mandoc supports only
+.Sq n ,
+evaluating to true;
+and
+.Sq t ,
+.Sq e ,
+and
+.Sq o ,
+evaluating to false.
+All other invocations are read up to the next end of line or space and
+evaluate as false.
.Pp
If the BODY section is begun by an escaped brace
.Sq \e{ ,
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 1169b559bad..b20c3a98d9d 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.4 2010/06/06 20:30:08 schwarze Exp $ */
+/* $Id: roff.c,v 1.5 2010/06/26 17:56:43 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -103,6 +103,7 @@ static enum rofferr roff_ccond(ROFF_ARGS);
static enum rofferr roff_cond(ROFF_ARGS);
static enum rofferr roff_cond_text(ROFF_ARGS);
static enum rofferr roff_cond_sub(ROFF_ARGS);
+static enum roffrule roff_evalcond(const char *, int *);
static enum rofferr roff_line(ROFF_ARGS);
/* See roff_hash_find() */
@@ -621,11 +622,21 @@ roff_cond_sub(ROFF_ARGS)
{
enum rofft t;
enum roffrule rr;
+ struct roffnode *l;
ppos = pos;
rr = r->last->rule;
- roff_cond_text(r, tok, bufp, szp, ln, ppos, pos, offs);
+ /*
+ * Clean out scope. If we've closed ourselves, then don't
+ * continue.
+ */
+
+ l = r->last;
+ roffnode_cleanscope(r);
+
+ if (l != r->last)
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
@@ -674,12 +685,37 @@ roff_cond_text(ROFF_ARGS)
}
+static enum roffrule
+roff_evalcond(const char *v, int *pos)
+{
+
+ switch (v[*pos]) {
+ case ('n'):
+ (*pos)++;
+ return(ROFFRULE_ALLOW);
+ case ('e'):
+ /* FALLTHROUGH */
+ case ('o'):
+ /* FALLTHROUGH */
+ case ('t'):
+ (*pos)++;
+ return(ROFFRULE_DENY);
+ default:
+ break;
+ }
+
+ while (v[*pos] && ' ' != v[*pos])
+ (*pos)++;
+ return(ROFFRULE_DENY);
+}
+
+
/* ARGSUSED */
static enum rofferr
roff_cond(ROFF_ARGS)
{
- int cpos; /* position of the condition */
int sv;
+ enum roffrule rule;
/* Stack overflow! */
@@ -688,20 +724,22 @@ roff_cond(ROFF_ARGS)
return(ROFF_ERR);
}
- cpos = pos;
+ /* First, evaluate the conditional. */
- if (ROFF_if == tok || ROFF_ie == tok) {
- /*
- * Read ahead past the conditional. FIXME: this does
- * not work, as conditionals don't end on whitespace,
- * but are parsed according to a formal grammar. It's
- * good enough for now, however.
- */
- while ((*bufp)[pos] && ' ' != (*bufp)[pos])
- pos++;
- }
+ if (ROFF_el == tok) {
+ /*
+ * An `.el' will get the value of the current rstack
+ * entry set in prior `ie' calls or defaults to DENY.
+ */
+ if (r->rstackpos < 0)
+ rule = ROFFRULE_DENY;
+ else
+ rule = r->rstack[r->rstackpos];
+ } else
+ rule = roff_evalcond(*bufp, &pos);
sv = pos;
+
while (' ' == (*bufp)[pos])
pos++;
@@ -711,30 +749,18 @@ roff_cond(ROFF_ARGS)
* really doing anything. Warn about this. It's probably
* wrong.
*/
+
if ('\0' == (*bufp)[pos] && sv != pos) {
- if ( ! (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL))
- return(ROFF_ERR);
- return(ROFF_IGN);
+ if ((*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL))
+ return(ROFF_IGN);
+ return(ROFF_ERR);
}
if ( ! roffnode_push(r, tok, ln, ppos))
return(ROFF_ERR);
- /* XXX: Implement more conditionals. */
+ r->last->rule = rule;
- if (ROFF_if == tok || ROFF_ie == tok)
- r->last->rule = 'n' == (*bufp)[cpos] ?
- ROFFRULE_ALLOW : ROFFRULE_DENY;
- else if (ROFF_el == tok) {
- /*
- * An `.el' will get the value of the current rstack
- * entry set in prior `ie' calls or defaults to DENY.
- */
- if (r->rstackpos < 0)
- r->last->rule = ROFFRULE_DENY;
- else
- r->last->rule = r->rstack[r->rstackpos];
- }
if (ROFF_ie == tok) {
/*
* An if-else will put the NEGATION of the current
@@ -746,9 +772,18 @@ roff_cond(ROFF_ARGS)
else
r->rstack[r->rstackpos] = ROFFRULE_DENY;
}
+
+ /* If the parent has false as its rule, then so do we. */
+
if (r->last->parent && ROFFRULE_DENY == r->last->parent->rule)
r->last->rule = ROFFRULE_DENY;
+ /*
+ * Determine scope. If we're invoked with "\{" trailing the
+ * conditional, then we're in a multiline scope. Else our scope
+ * expires on the next line.
+ */
+
r->last->endspan = 1;
if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) {
diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c
index cc3d22722c8..7a465e8a744 100644
--- a/usr.bin/mandoc/term.c
+++ b/usr.bin/mandoc/term.c
@@ -1,6 +1,6 @@
-/* $Id: term.c,v 1.37 2010/06/10 22:50:10 schwarze Exp $ */
+/* $Id: term.c,v 1.38 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -599,10 +599,7 @@ encode(struct termp *p, const char *word, size_t sz)
* character by character.
*/
- if (TERMTYPE_PS == p->type) {
- buffera(p, word, sz);
- return;
- } else if (TERMFONT_NONE == (f = term_fonttop(p))) {
+ if (TERMFONT_NONE == (f = term_fonttop(p))) {
buffera(p, word, sz);
return;
}
diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h
index 1183164a78c..5b4aa3b4a58 100644
--- a/usr.bin/mandoc/term.h
+++ b/usr.bin/mandoc/term.h
@@ -1,6 +1,6 @@
-/* $Id: term.h,v 1.20 2010/06/10 22:50:10 schwarze Exp $ */
+/* $Id: term.h,v 1.21 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -50,6 +50,8 @@ struct termp_ps {
size_t psmargsz; /* margin buf size */
size_t psmargcur; /* current pos in margin buf */
size_t pspage; /* current page */
+ char last; /* character buffer */
+ enum termfont lastf; /* last set font */
};
struct termp {
diff --git a/usr.bin/mandoc/term_ps.c b/usr.bin/mandoc/term_ps.c
index 8d887c74d4a..e5b4710eb3b 100644
--- a/usr.bin/mandoc/term_ps.c
+++ b/usr.bin/mandoc/term_ps.c
@@ -1,6 +1,6 @@
-/* $Id: term_ps.c,v 1.1 2010/06/10 22:50:10 schwarze Exp $ */
+/* $Id: term_ps.c,v 1.2 2010/06/26 17:56:43 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -53,13 +53,18 @@
} \
} while (/* CONSTCOND */ 0)
+
static void ps_letter(struct termp *, char);
static void ps_begin(struct termp *);
static void ps_end(struct termp *);
static void ps_advance(struct termp *, size_t);
static void ps_endline(struct termp *);
+static void ps_fclose(struct termp *);
+static void ps_pclose(struct termp *);
+static void ps_pletter(struct termp *, char);
static void ps_printf(struct termp *, const char *, ...);
static void ps_putchar(struct termp *, char);
+static void ps_setfont(struct termp *, enum termfont);
void *
@@ -161,6 +166,8 @@ ps_end(struct termp *p)
* well as just one.
*/
+ assert(0 == p->engine.ps.psstate);
+ assert('\0' == p->engine.ps.last);
assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]);
printf("%s", p->engine.ps.psmarg);
printf("showpage\n");
@@ -172,68 +179,60 @@ static void
ps_begin(struct termp *p)
{
- /*
- * Emit the standard PostScript prologue, set our initial page
- * position, then run pageopen() on the initial page.
+ /*
+ * Print margins into margin buffer. Nothing gets output to the
+ * screen yet, so we don't need to initialise the primary state.
*/
- printf("%s\n", "%!PS");
- printf("%s\n", "/Courier");
- printf("%s\n", "10 selectfont");
-
- p->engine.ps.psstate = 0;
-
if (p->engine.ps.psmarg) {
assert(p->engine.ps.psmargsz);
p->engine.ps.psmarg[0] = '\0';
}
p->engine.ps.psmargcur = 0;
-
- /*
- * Now dump the margins into our margin buffer. If we don't do
- * this, we'd break any current state to run the header and
- * footer with each and evern new page.
- */
-
+ p->engine.ps.psstate = PS_MARGINS;
p->engine.ps.pscol = PS_CHAR_LEFT;
p->engine.ps.psrow = PS_CHAR_TOPMARG;
- p->engine.ps.psstate |= PS_MARGINS;
+ ps_setfont(p, TERMFONT_NONE);
(*p->headf)(p, p->argf);
(*p->endline)(p);
- p->engine.ps.psstate &= ~PS_MARGINS;
- assert(0 == p->engine.ps.psstate);
-
p->engine.ps.pscol = PS_CHAR_LEFT;
p->engine.ps.psrow = PS_CHAR_BOTMARG;
- p->engine.ps.psstate |= PS_MARGINS;
(*p->footf)(p, p->argf);
(*p->endline)(p);
p->engine.ps.psstate &= ~PS_MARGINS;
+
assert(0 == p->engine.ps.psstate);
+ assert(p->engine.ps.psmarg);
+ assert('\0' != p->engine.ps.psmarg[0]);
+ /*
+ * Print header and initialise page state. Following this,
+ * stuff gets printed to the screen, so make sure we're sane.
+ */
+
+ printf("%s\n", "%!PS");
+ ps_setfont(p, TERMFONT_NONE);
p->engine.ps.pscol = PS_CHAR_LEFT;
p->engine.ps.psrow = PS_CHAR_TOP;
-
- assert(p->engine.ps.psmarg);
- assert('\0' != p->engine.ps.psmarg[0]);
}
static void
-ps_letter(struct termp *p, char c)
+ps_pletter(struct termp *p, char c)
{
+ /*
+ * If we're not in a PostScript "word" context, then open one
+ * now at the current cursor.
+ */
+
if ( ! (PS_INLINE & p->engine.ps.psstate)) {
- /*
- * If we're not in a PostScript "word" context, then
- * open one now at the current cursor.
- */
ps_printf(p, "%zu %zu moveto\n(",
p->engine.ps.pscol,
p->engine.ps.psrow);
@@ -260,21 +259,118 @@ ps_letter(struct termp *p, char c)
}
/* Write the character and adjust where we are on the page. */
+
ps_putchar(p, c);
p->engine.ps.pscol += PS_CHAR_WIDTH;
}
static void
-ps_advance(struct termp *p, size_t len)
+ps_pclose(struct termp *p)
{
- if (PS_INLINE & p->engine.ps.psstate) {
- /* Dump out any existing line scope. */
- ps_printf(p, ") show\n");
- p->engine.ps.psstate &= ~PS_INLINE;
+ /*
+ * Spit out that we're exiting a word context (this is a
+ * "partial close" because we don't check the last-char buffer
+ * or anything).
+ */
+
+ if ( ! (PS_INLINE & p->engine.ps.psstate))
+ return;
+
+ ps_printf(p, ") show\n");
+ p->engine.ps.psstate &= ~PS_INLINE;
+}
+
+
+static void
+ps_fclose(struct termp *p)
+{
+
+ /*
+ * Strong closure: if we have a last-char, spit it out after
+ * checking that we're in the right font mode. This will of
+ * course open a new scope, if applicable.
+ *
+ * Following this, close out any scope that's open.
+ */
+
+ if ('\0' != p->engine.ps.last) {
+ if (p->engine.ps.lastf != TERMFONT_NONE) {
+ ps_pclose(p);
+ ps_setfont(p, TERMFONT_NONE);
+ }
+ ps_pletter(p, p->engine.ps.last);
+ p->engine.ps.last = '\0';
}
+ if ( ! (PS_INLINE & p->engine.ps.psstate))
+ return;
+
+ ps_pclose(p);
+}
+
+
+static void
+ps_letter(struct termp *p, char c)
+{
+ char cc;
+
+ /*
+ * State machine dictates whether to buffer the last character
+ * or not. Basically, encoded words are detected by checking if
+ * we're an "8" and switching on the buffer. Then we put "8" in
+ * our buffer, and on the next charater, flush both character
+ * and buffer. Thus, "regular" words are detected by having a
+ * regular character and a regular buffer character.
+ */
+
+ if ('\0' == p->engine.ps.last) {
+ assert(8 != c);
+ p->engine.ps.last = c;
+ return;
+ } else if (8 == p->engine.ps.last) {
+ assert(8 != c);
+ p->engine.ps.last = '\0';
+ } else if (8 == c) {
+ assert(8 != p->engine.ps.last);
+ if ('_' == p->engine.ps.last) {
+ if (p->engine.ps.lastf != TERMFONT_UNDER) {
+ ps_pclose(p);
+ ps_setfont(p, TERMFONT_UNDER);
+ }
+ } else if (p->engine.ps.lastf != TERMFONT_BOLD) {
+ ps_pclose(p);
+ ps_setfont(p, TERMFONT_BOLD);
+ }
+ p->engine.ps.last = c;
+ return;
+ } else {
+ if (p->engine.ps.lastf != TERMFONT_NONE) {
+ ps_pclose(p);
+ ps_setfont(p, TERMFONT_NONE);
+ }
+ cc = p->engine.ps.last;
+ p->engine.ps.last = c;
+ c = cc;
+ }
+
+ ps_pletter(p, c);
+}
+
+
+static void
+ps_advance(struct termp *p, size_t len)
+{
+
+ /*
+ * Advance some spaces. This can probably be made smarter,
+ * i.e., to have multiple space-separated words in the same
+ * scope, but this is easier: just close out the current scope
+ * and readjust our column settings.
+ */
+
+ ps_fclose(p);
p->engine.ps.pscol += len ? len * PS_CHAR_WIDTH : 0;
}
@@ -283,14 +379,24 @@ static void
ps_endline(struct termp *p)
{
- if (PS_INLINE & p->engine.ps.psstate) {
- ps_printf(p, ") show\n");
- p->engine.ps.psstate &= ~PS_INLINE;
- }
+ /* Close out any scopes we have open: we're at eoln. */
+
+ ps_fclose(p);
+
+ /*
+ * If we're in the margin, don't try to recalculate our current
+ * row. XXX: if the column tries to be fancy with multiple
+ * lines, we'll do nasty stuff.
+ */
if (PS_MARGINS & p->engine.ps.psstate)
return;
+ /*
+ * Put us down a line. If we're at the page bottom, spit out a
+ * showpage and restart our row.
+ */
+
p->engine.ps.pscol = PS_CHAR_LEFT;
if (p->engine.ps.psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {
p->engine.ps.psrow -= PS_CHAR_HEIGHT;
@@ -302,3 +408,20 @@ ps_endline(struct termp *p)
printf("showpage\n");
p->engine.ps.psrow = PS_CHAR_TOP;
}
+
+
+static void
+ps_setfont(struct termp *p, enum termfont f)
+{
+
+ if (TERMFONT_BOLD == f)
+ ps_printf(p, "/Courier-Bold\n");
+ else if (TERMFONT_UNDER == f)
+ ps_printf(p, "/Courier-Oblique\n");
+ else
+ ps_printf(p, "/Courier\n");
+
+ ps_printf(p, "10 selectfont\n");
+ p->engine.ps.lastf = f;
+}
+