From 0f63dfd0918fdce2379f3d3215a87e62049febd9 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Wed, 25 Dec 2013 11:53:40 +0100 Subject: [PATCH] mdocml: update to stable snapshot as per 12/23/13 Courtesy-of: Ingo Schwarze --- contrib/mdocml/Makefile | 19 ++- contrib/mdocml/NEWS | 39 +++-- contrib/mdocml/README.DRAGONFLY | 11 +- contrib/mdocml/TODO | 25 ++- contrib/mdocml/apropos_db.c | 20 ++- contrib/mdocml/catman.c | 7 +- contrib/mdocml/cgi.c | 41 ++++- contrib/mdocml/config.h | 6 +- contrib/mdocml/config.h.post | 3 + contrib/mdocml/index.sgml | 117 +++++++++---- contrib/mdocml/libmandoc.h | 13 +- contrib/mdocml/libmdoc.h | 10 +- contrib/mdocml/man.c | 21 ++- contrib/mdocml/man.h | 4 +- contrib/mdocml/man_html.c | 30 +++- contrib/mdocml/man_macro.c | 17 +- contrib/mdocml/man_term.c | 50 +++++- contrib/mdocml/man_validate.c | 19 ++- contrib/mdocml/mandoc.3 | 8 +- contrib/mdocml/mandoc.c | 9 +- contrib/mdocml/mandoc.h | 5 +- contrib/mdocml/mandoc_char.7 | 17 +- contrib/mdocml/mandocdb.c | 26 +-- contrib/mdocml/manpath.c | 4 +- contrib/mdocml/mdoc.7 | 39 ++++- contrib/mdocml/mdoc.c | 31 +++- contrib/mdocml/mdoc_argv.c | 14 +- contrib/mdocml/mdoc_macro.c | 239 ++++++++++++++++----------- contrib/mdocml/mdoc_term.c | 65 ++++++-- contrib/mdocml/mdoc_validate.c | 23 ++- contrib/mdocml/out.c | 5 +- contrib/mdocml/roff.7 | 24 ++- contrib/mdocml/roff.c | 282 ++++++++++++++++++++++++-------- contrib/mdocml/term.c | 31 ++-- contrib/mdocml/term.h | 5 +- 35 files changed, 895 insertions(+), 384 deletions(-) diff --git a/contrib/mdocml/Makefile b/contrib/mdocml/Makefile index 044d087281..39772c94d1 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mdocml/Makefile @@ -31,7 +31,7 @@ STATIC = -static # Linux requires -pthread to statically link with libdb. #STATIC += -pthread -CFLAGS += -g -DHAVE_CONFIG_H -DVERSION="\"$(VERSION)\"" +CFLAGS += -g -DHAVE_CONFIG_H CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings PREFIX = /usr/local WWWPREFIX = /var/www @@ -309,7 +309,7 @@ clean: rm -f catman $(CATMAN_OBJS) rm -f demandoc $(DEMANDOC_OBJS) rm -f mandoc $(MANDOC_OBJS) - rm -f config.h config.log $(COMPAT_OBJS) + rm -f config.log $(COMPAT_OBJS) rm -f mdocml.tar.gz rm -f index.html $(INDEX_OBJS) rm -rf *.dSYM @@ -390,31 +390,32 @@ config.h: config.h.pre config.h.post rm -f config.log ( cat config.h.pre; \ echo; \ - if $(CC) $(CFLAGS) -Werror -o test-fgetln test-fgetln.c >> config.log 2>&1; then \ + echo '#define VERSION "$(VERSION)"'; \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-fgetln test-fgetln.c >> config.log 2>&1; then \ echo '#define HAVE_FGETLN'; \ rm test-fgetln; \ fi; \ - if $(CC) $(CFLAGS) -Werror -o test-strptime test-strptime.c >> config.log 2>&1; then \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-strptime test-strptime.c >> config.log 2>&1; then \ echo '#define HAVE_STRPTIME'; \ rm test-strptime; \ fi; \ - if $(CC) $(CFLAGS) -Werror -o test-getsubopt test-getsubopt.c >> config.log 2>&1; then \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-getsubopt test-getsubopt.c >> config.log 2>&1; then \ echo '#define HAVE_GETSUBOPT'; \ rm test-getsubopt; \ fi; \ - if $(CC) $(CFLAGS) -Werror -o test-strlcat test-strlcat.c >> config.log 2>&1; then \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-strlcat test-strlcat.c >> config.log 2>&1; then \ echo '#define HAVE_STRLCAT'; \ rm test-strlcat; \ fi; \ - if $(CC) $(CFLAGS) -Werror -o test-mmap test-mmap.c >> config.log 2>&1; then \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-mmap test-mmap.c >> config.log 2>&1; then \ echo '#define HAVE_MMAP'; \ rm test-mmap; \ fi; \ - if $(CC) $(CFLAGS) -Werror -o test-strlcpy test-strlcpy.c >> config.log 2>&1; then \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-strlcpy test-strlcpy.c >> config.log 2>&1; then \ echo '#define HAVE_STRLCPY'; \ rm test-strlcpy; \ fi; \ - if $(CC) $(CFLAGS) -Werror -o test-betoh64 test-betoh64.c >> config.log 2>&1; then \ + if $(CC) $(CFLAGS) -Werror -Wno-unused -o test-betoh64 test-betoh64.c >> config.log 2>&1; then \ echo '#define HAVE_BETOH64'; \ rm test-betoh64; \ fi; \ diff --git a/contrib/mdocml/NEWS b/contrib/mdocml/NEWS index 784b89b0eb..99e71cac2a 100644 --- a/contrib/mdocml/NEWS +++ b/contrib/mdocml/NEWS @@ -1,4 +1,4 @@ -$Id: NEWS,v 1.2 2013/10/05 13:15:51 schwarze Exp $ +$Id: NEWS,v 1.3 2013/10/13 16:06:50 schwarze Exp $ This file lists the most important changes in the mdocml.bsd.lv distribution. @@ -130,13 +130,16 @@ Changes in version 1.11.1, released on April 4, 2011 * The earlier libroff, libmdoc, and libman soup have been merged into a single library, libmandoc, which manages all aspects of parsing real manuals, from line-handling to tbl(7) parsing. - * Beyond this structural change, initial eqn(7) functionality is in - place. For the time being, this is limited to the recognition of - equation blocks; future version of mdocml will expand upon this - framework. * As usual, many general fixes and improvements have also occurred. In particular, a great deal of redundancy and superfluous code has been removed with the merging of the backend libraries. + * see also the changes in 1.10.10 + +Changes in version 1.10.10, March 20, 2011, NOT released + + * Initial eqn(7) functionality is in place. For the time being, + this is limited to the recognition of equation blocks; + future version of mdocml will expand upon this framework. Changes in version 1.10.9, released on January 7, 2011 @@ -150,19 +153,23 @@ Changes in version 1.10.9, released on January 7, 2011 Changes in version 1.10.8, released on December 24, 2010 - * Significant improvements merged from OpenBSD downstream, including - - many new roff(7) components, - - in-line implementation of troff's soelim(1), - - broken-block handling, - - overhauled error classifications, and - - cleaned up handling of error conditions. - * Also overhauled the -Thtml and -Txhtml output modes. They now display + * Overhauled the -Thtml and -Txhtml output modes. They now display readable output in arbitrary browsers, including text-based ones like lynx(1). See HTML and XHTML manuals in the DOCUMENTATION section for examples. Attention: available style-sheet classes have been considerably changed! See the example.style.css file for details. Lastly, libmdoc and libman have been cleaned up and reduced in size and complexity. + * see also the changes in 1.10.7 + +Changes in version 1.10.7, December 6, 2010, NOT released + + Significant improvements merged from OpenBSD downstream, including: + * many new roff(7) components, + * in-line implementation of troff's soelim(1), + * broken-block handling, + * overhauled error classifications, and + * cleaned up handling of error conditions. Changes in version 1.10.6, released on September 27, 2010 @@ -194,12 +201,16 @@ Changes in version 1.10.4, released on July 12, 2010 * Lots of features developed during both "Summer of Code" and the OpenBSD c2k10 hackathon: * minimal "ds" roff(7) symbols are supported - * "Bk" mdoc(7) support * beautified SYNOPSIS section output - * variable font-width and paper-size support in mandoc(1) -Tps output * acceptance of scope-block breakage in mdoc(7) * clarify error message status * many minor bug-fixes and formatting issues resolved + * see also changes in 1.10.3 + +Changes in version 1.10.3, June 29, 2010, NOT released + + * variable font-width and paper-size support in mandoc(1) -Tps output + * "Bk" mdoc(7) support Changes in version 1.10.2, released on June 19, 2010 diff --git a/contrib/mdocml/README.DRAGONFLY b/contrib/mdocml/README.DRAGONFLY index 40a57cfeba..f2753d1674 100644 --- a/contrib/mdocml/README.DRAGONFLY +++ b/contrib/mdocml/README.DRAGONFLY @@ -11,11 +11,8 @@ sha1 = 6a86cc4f373bcc51aa8bf1a7499db368e977a166 Local modifications applied to the following files: config.h - lib.in (upstream sync) + Makefile msec.in - man_macro.c (upstream sync) - mandoc.3 (upstream sync) - mdoc.7 (upstream sync) - mdoc_man.c (upstream sync) - mdoc_validate.c (upstream sync) - st.in (upstream sync) + +The source code is currently kept in sync with the stable branch of +the upstream CVS for collaboration purposes. diff --git a/contrib/mdocml/TODO b/contrib/mdocml/TODO index 0aebbd38b4..ee7bee5352 100644 --- a/contrib/mdocml/TODO +++ b/contrib/mdocml/TODO @@ -1,19 +1,13 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.157 2013/09/27 21:12:34 schwarze Exp $ +* $Id: TODO,v 1.160 2013/12/15 21:30:13 schwarze Exp $ ************************************************************************ ************************************************************************ * crashes ************************************************************************ -- .Bl -tag followed by a text node preceding the first .It should not - throw a FATAL error, but only a normal ERROR. Putting this into the - HEAD of an implicit .It might be cleanest, inserting an implicit .Pp - or just dumping the orphan stuff directly into the BODY of the .Bl - might be easier to implement, and all options can no doubt be made - to yield correct (i.e. groff bug-compatible) rendering. - Anthony J. Bentley on discuss@ Sun, 22 Sep 2013 16:33:21 -0600 +None known. ************************************************************************ * missing features @@ -46,6 +40,12 @@ - .fc (field control) found by naddy@ in xloadimage(1) +- .ll (line length) + found by naddy@ in textproc/enchant(1) Sat, 12 Oct 2013 03:27:10 +0200 + +- .nr third argument (auto-increment step size, requires \n+) + found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700 + - .ns (no-space mode) occurs in xine-config(1) reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500 @@ -67,6 +67,9 @@ found in cclive(1) DocBook output Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600 +- \n+ and \n- numerical register increment and decrement + found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700 + - using undefined strings or macros defines them to be empty wl@ Mon, 14 Nov 2011 14:37:01 +0000 @@ -159,6 +162,9 @@ --- missing misc features ---------------------------------------------- +- italic correction (\/) in PostScript mode + Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46 + - The whatis(1) utility looks for whole words in Nm. If the file name of a page does not agree with the contents of any of its Nm macros (e.g. pool(9)), add the file name as an Nm entry @@ -182,6 +188,9 @@ noted by stsp@ Sat, 24 Apr 2010 09:17:55 +0200 reminded by nicm@ Mon, 3 May 2010 09:52:41 +0100 +- look at pages generated from Texinfo source by yat2m, e.g. security/gnupg + First impression is not that bad. + - check compatibility with Plan9: http://swtch.com/usr/local/plan9/tmac/tmac.an http://swtch.com/plan9port/man/man7/man.html diff --git a/contrib/mdocml/apropos_db.c b/contrib/mdocml/apropos_db.c index 61002ee5d3..786fc7bd8f 100644 --- a/contrib/mdocml/apropos_db.c +++ b/contrib/mdocml/apropos_db.c @@ -1,4 +1,4 @@ -/* $Id: apropos_db.c,v 1.32.2.1 2013/10/02 21:03:26 schwarze Exp $ */ +/* $Id: apropos_db.c,v 1.32.2.3 2013/10/10 23:43:04 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -30,14 +30,19 @@ #include #include -#if defined(__linux__) -# include -# include -#elif defined(__APPLE__) +#if defined(__APPLE__) # include -# include +#elif defined(__linux__) +# include +#elif defined(__sun) +# include #else # include +#endif + +#if defined(__linux__) || defined(__sun) +# include +#else # include #endif @@ -414,11 +419,10 @@ apropos_search(int pathsz, char **paths, const struct opts *opts, { struct rectree tree; struct mchars *mc; - int i, rc; + int i; memset(&tree, 0, sizeof(struct rectree)); - rc = 0; mc = mchars_alloc(); *sz = 0; *resp = NULL; diff --git a/contrib/mdocml/catman.c b/contrib/mdocml/catman.c index c755d27057..8767e5e3f6 100644 --- a/contrib/mdocml/catman.c +++ b/contrib/mdocml/catman.c @@ -1,4 +1,4 @@ -/* $Id: catman.c,v 1.11 2012/06/08 10:33:48 kristaps Exp $ */ +/* $Id: catman.c,v 1.11.2.2 2013/10/11 00:06:48 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -31,7 +31,7 @@ #include #include -#ifdef __linux__ +#if defined(__linux__) || defined(__sun) # include #else # include @@ -212,9 +212,6 @@ indexhtml(char *src, size_t ssz, char *dst, size_t dsz) const char *f; char *d; char fname[MAXPATHLEN]; - pid_t pid; - - pid = -1; xstrlcpy(fname, dst, MAXPATHLEN); xstrlcat(fname, "/", MAXPATHLEN); diff --git a/contrib/mdocml/cgi.c b/contrib/mdocml/cgi.c index 6d40fcde42..64bde45ce2 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mdocml/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.45 2013/06/05 02:00:26 schwarze Exp $ */ +/* $Id: cgi.c,v 1.46 2013/10/11 00:06:48 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * @@ -34,6 +34,13 @@ #include #include +#if defined(__sun) +/* for stat() */ +#include +#include +#include +#endif + #include "apropos_db.h" #include "mandoc.h" #include "mdoc.h" @@ -42,7 +49,7 @@ #include "manpath.h" #include "mandocdb.h" -#ifdef __linux__ +#if defined(__linux__) || defined(__sun) # include #else # include @@ -1097,11 +1104,20 @@ static int pathstop(DIR *dir) { struct dirent *d; +#if defined(__sun) + struct stat sb; +#endif - while (NULL != (d = readdir(dir))) + while (NULL != (d = readdir(dir))) { +#if defined(__sun) + stat(d->d_name, &sb); + if (S_IFREG & sb.st_mode) +#else if (DT_REG == d->d_type) +#endif if (0 == strcmp(d->d_name, "catman.conf")) return(1); + } return(0); } @@ -1118,6 +1134,9 @@ pathgen(DIR *dir, char *path, struct req *req) DIR *cd; int rc; size_t sz, ssz; +#if defined(__sun) + struct stat sb; +#endif sz = strlcat(path, "/", PATH_MAX); if (sz >= PATH_MAX) { @@ -1133,7 +1152,13 @@ pathgen(DIR *dir, char *path, struct req *req) rc = 0; while (0 == rc && NULL != (d = readdir(dir))) { - if (DT_DIR != d->d_type || strcmp(d->d_name, "etc")) +#if defined(__sun) + stat(d->d_name, &sb); + if (!(S_IFDIR & sb.st_mode) +#else + if (DT_DIR != d->d_type +#endif + || strcmp(d->d_name, "etc")) continue; path[(int)sz] = '\0'; @@ -1182,7 +1207,13 @@ pathgen(DIR *dir, char *path, struct req *req) rewinddir(dir); while (NULL != (d = readdir(dir))) { - if (DT_DIR != d->d_type || '.' == d->d_name[0]) +#if defined(__sun) + stat(d->d_name, &sb); + if (!(S_IFDIR & sb.st_mode) +#else + if (DT_DIR != d->d_type +#endif + || '.' == d->d_name[0]) continue; path[(int)sz] = '\0'; diff --git a/contrib/mdocml/config.h b/contrib/mdocml/config.h index 235bfd15ec..eabe675b37 100644 --- a/contrib/mdocml/config.h +++ b/contrib/mdocml/config.h @@ -7,13 +7,14 @@ #include +#define VERSION "1.12.2" +#define HAVE_FGETLN #define HAVE_STRPTIME #define HAVE_GETSUBOPT #define HAVE_STRLCAT #define HAVE_MMAP #define HAVE_STRLCPY -#define VERSION "1.12.2" #define OSNAME "DragonFly 3.7" #include @@ -37,6 +38,9 @@ # if defined(__APPLE__) # define betoh64(x) OSSwapBigToHostInt64(x) # define htobe64(x) OSSwapHostToBigInt64(x) +# elif defined(__sun) +# define betoh64(x) BE_64(x) +# define htobe64(x) BE_64(x) # else # define betoh64(x) be64toh(x) # endif diff --git a/contrib/mdocml/config.h.post b/contrib/mdocml/config.h.post index cee82aa1c3..9a33671b56 100644 --- a/contrib/mdocml/config.h.post +++ b/contrib/mdocml/config.h.post @@ -19,6 +19,9 @@ # if defined(__APPLE__) # define betoh64(x) OSSwapBigToHostInt64(x) # define htobe64(x) OSSwapHostToBigInt64(x) +# elif defined(__sun) +# define betoh64(x) BE_64(x) +# define htobe64(x) BE_64(x) # else # define betoh64(x) be64toh(x) # endif diff --git a/contrib/mdocml/index.sgml b/contrib/mdocml/index.sgml index e716635702..c645ddddb9 100644 --- a/contrib/mdocml/index.sgml +++ b/contrib/mdocml/index.sgml @@ -7,6 +7,7 @@

+ Puffy mdocml – UNIX manpage compiler, current version @VERSION@ (@VDATE@)

@@ -20,25 +21,33 @@

mdocml is a suite of tools compiling mdoc, the roff macro package of choice for BSD manual pages, and man, the predominant historical package for - UNIX manuals. The mission of mdocml is to deprecate groff, the GNU troff implementation, for displaying mdoc - pages whilst providing token support for man. + UNIX manuals. + It is small, ISO C, ISC-licensed, and quite fast.

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

-

- mdocml consists of the libmandoc validating compiler and mandoc, which interfaces with the compiler library to format output for UNIX terminals (with + The tool set features mandoc, + based on the libmandoc validating compiler, + to format output for UNIX terminals (with support for wide-character locales), XHTML, HTML, PostScript, and PDF. It also includes preconv, for recoding multibyte manuals; demandoc, for emitting only text parts of manuals; mandocdb, for indexing manuals; and apropos, whatis, and man.cgi (via catman) for semantic search of manual content. - It is a BSD.lv project. +

+

+ mdocml has predominantly been developed on OpenBSD + and is both an OpenBSD + and a BSD.lv project. + We strive to support all interested free operating systems, in particular + NetBSD, + DragonFly, + FreeBSD, + Minix 3, + and GNU/Linux, + as well as all systems running the pkgsrc portable package build system. + All of these projects have helped to make mdocml better, by providing feedback and advice, + bug reports, and patches.

Disambiguation: mdocml is often referred to by its installed binary, mandoc. @@ -47,13 +56,12 @@ Sources

- mdocml is in plain-old ANSI C and should build and run on any modern system; however, you'll - need libdb to build apropos, whatis, man.cgi, catman, and mandocdb (this is installed by default on BSD UNIX - systems — see the Makefile if you're running Linux). To build and install into /usr/local/, just - run make install. Be careful: the preconv, apropos, and whatis binary names are - usually taken by existing utilities. + mdocml should build and run on any modern system with + libdb + (this is installed by default on BSD UNIX systems — see the Makefile if you're running Linux). + To build and install into /usr/local/, just run make install. + Be careful: the preconv, apropos, and whatis installed binary names + may be taken by existing utilities.

Downstream @@ -61,8 +69,7 @@

Several systems come bundled with mdocml utilities. If your system does not appear below, the maintainers have not contacted me and it should not be considered - official. - Please contact us if you plan on maintaining a downstream version! + official, so please contact us if you plan on maintaining a downstream version!

@@ -71,7 +78,7 @@ @@ -86,7 +93,7 @@ @@ -104,7 +111,7 @@ @@ -116,7 +123,7 @@ @@ -231,6 +238,25 @@
DragonFly BSD - contrib/mdocml (1.12.1 sources) + contrib/mdocml (1.12.2 sources) lib/libmandoc usr.bin/mandoc (build system)
FreeBSD 9.x, 8.x - ports/textproc/mdocml (1.12.1 port) + ports/textproc/mdocml (1.12.1 port)
pkgsrc - textproc/mdocml (1.12.0 port) + textproc/mdocml (1.12.2 port)
Alpine Linux - aports/main/mdocml (1.12.1 port) + aports/main/mdocml (1.12.2 port)
+

+ Supplementary Information +

+

Contact

@@ -278,7 +304,7 @@ News

- 02-10-2013: version 1.12.2 + 05-10-2013: version 1.12.2

The mdoc(7) to man(7) converter, @@ -320,11 +346,8 @@ For mandoc developers, we now provide a tbl(3) library manual and gmdiff, a very small, very simplistic groff-versus-mandoc output comparison tool.

-

- See NEWS for historical notes. -

- 23-03-2011: version 1.12.1 + 23-03-2012: version 1.12.1

Significant work on apropos and mandocdb. These tools are @@ -347,16 +370,42 @@

Lastly, I'm no longer providing binaries, as nobody has asked for them.

-

- See cvsweb for - historical notes. -

+

+ History +

+
    +
  • + Release notes going back to release 1.9.15, February 18, 2010. + Briefly explaining the most important changes in each release in relatively easy terms. + Very many changes are not mentioned here. +
  • +
  • + Development history going back to the beginning of the project, November 22, 2008. + One-line entries for important commits, releases, merges, hackathons and talks. + Makes it easy to find out who did what, and when, and when it became available where. + However, this is still incomplete, mentioning only a small fraction of all commits, + and to keep the size down, the individual entries are extremely terse and technical. + Feel free to look up more details and longer explanations about individual entries + in the ChangeLog or in CVS. +
  • +
  • + CVS ChangeLog going back to the beginning of the project. + Very technical information of varying quality, strictly chronological. + All commits are mentioned, but some messages neglect to mention some changes. + Partly terse, partly detailed and verbose. In any case, the ChangeLog is very long - + more than 25,000 lines, more than 700 kB. +
  • +
  • + CVS web interface, going back to the beginning of the project. + Source code, diffs and commit messages for each source file. The real thing. +
  • +

Copyright © 2008–2011 Kristaps Dzonsons, © 2013 Ingo Schwarze, - $Date: 2013/10/05 14:05:09 $ + $Date: 2013/11/07 22:09:54 $

diff --git a/contrib/mdocml/libmandoc.h b/contrib/mdocml/libmandoc.h index 9b3ffee179..3c005e106d 100644 --- a/contrib/mdocml/libmandoc.h +++ b/contrib/mdocml/libmandoc.h @@ -1,6 +1,7 @@ -/* $Id: libmandoc.h,v 1.32 2012/11/19 17:57:23 schwarze Exp $ */ +/* $Id: libmandoc.h,v 1.35 2013/12/15 21:23:52 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons + * Copyright (c) 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,11 +30,6 @@ enum rofferr { ROFF_ERR /* badness: puke and stop */ }; -enum regs { - REG_nS = 0, /* nS register */ - REG__MAX -}; - __BEGIN_DECLS struct roff; @@ -72,9 +68,8 @@ void roff_reset(struct roff *); enum rofferr roff_parseln(struct roff *, int, char **, size_t *, int, int *); void roff_endparse(struct roff *); -int roff_regisset(const struct roff *, enum regs); -unsigned int roff_regget(const struct roff *, enum regs); -void roff_regunset(struct roff *, enum regs); +void roff_setreg(struct roff *, const char *, int, char sign); +int roff_getreg(const struct roff *, const char *); char *roff_strdup(const struct roff *, const char *); int roff_getcontrol(const struct roff *, const char *, int *); diff --git a/contrib/mdocml/libmdoc.h b/contrib/mdocml/libmdoc.h index 8a389a4a56..3f14519d3b 100644 --- a/contrib/mdocml/libmdoc.h +++ b/contrib/mdocml/libmdoc.h @@ -1,6 +1,7 @@ -/* $Id: libmdoc.h,v 1.81 2012/11/17 00:26:33 schwarze Exp $ */ +/* $Id: libmdoc.h,v 1.82 2013/10/21 23:47:58 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -34,6 +35,8 @@ struct mdoc { #define MDOC_PPHRASE (1 << 5) /* within a partial phrase */ #define MDOC_FREECOL (1 << 6) /* `It' invocation should close */ #define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */ +#define MDOC_KEEP (1 << 8) /* in a word keep */ +#define MDOC_SMOFF (1 << 9) /* spacing is off */ enum mdoc_next next; /* where to put the next node */ struct mdoc_node *last; /* the last node parsed */ struct mdoc_node *first; /* the first node parsed */ @@ -57,8 +60,8 @@ struct mdoc_macro { #define MDOC_PARSED (1 << 1) #define MDOC_EXPLICIT (1 << 2) #define MDOC_PROLOGUE (1 << 3) -#define MDOC_IGNDELIM (1 << 4) - /* Reserved words in arguments treated as text. */ +#define MDOC_IGNDELIM (1 << 4) +#define MDOC_JOIN (1 << 5) }; enum margserr { @@ -107,6 +110,7 @@ __BEGIN_DECLS int mdoc_macro(MACRO_PROT_ARGS); int mdoc_word_alloc(struct mdoc *, int, int, const char *); +void mdoc_word_append(struct mdoc *, const char *); int mdoc_elem_alloc(struct mdoc *, int, int, enum mdoct, struct mdoc_arg *); int mdoc_block_alloc(struct mdoc *, int, int, diff --git a/contrib/mdocml/man.c b/contrib/mdocml/man.c index 24ffc6389f..e6e1c28992 100644 --- a/contrib/mdocml/man.c +++ b/contrib/mdocml/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.119 2012/11/17 00:26:33 schwarze Exp $ */ +/* $Id: man.c,v 1.121 2013/11/10 22:54:40 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -40,7 +40,8 @@ const char *const __man_macronames[MAN_MAX] = { "RI", "na", "sp", "nf", "fi", "RE", "RS", "DT", "UC", "PD", "AT", "in", - "ft", "OP", "EX", "EE" + "ft", "OP", "EX", "EE", + "UR", "UE" }; const char * const *man_macronames = __man_macronames; @@ -428,16 +429,22 @@ man_ptext(struct man *man, int line, char *buf, int offs) return(man_descope(man, line, offs)); } - /* Pump blank lines directly into the backend. */ - for (i = offs; ' ' == buf[i]; i++) /* Skip leading whitespace. */ ; + /* + * Blank lines are ignored right after headings + * but add a single vertical space elsewhere. + */ + if ('\0' == buf[i]) { /* Allocate a blank entry. */ - if ( ! man_elem_alloc(man, line, offs, MAN_sp)) - return(0); - man->next = MAN_NEXT_SIBLING; + if (MAN_SH != man->last->tok && + MAN_SS != man->last->tok) { + if ( ! man_elem_alloc(man, line, offs, MAN_sp)) + return(0); + man->next = MAN_NEXT_SIBLING; + } return(1); } diff --git a/contrib/mdocml/man.h b/contrib/mdocml/man.h index e85da9aef0..ef9480f276 100644 --- a/contrib/mdocml/man.h +++ b/contrib/mdocml/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.61 2012/06/02 20:16:23 schwarze Exp $ */ +/* $Id: man.h,v 1.62 2013/10/17 20:54:58 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -54,6 +54,8 @@ enum mant { MAN_OP, MAN_EX, MAN_EE, + MAN_UR, + MAN_UE, MAN_MAX }; diff --git a/contrib/mdocml/man_html.c b/contrib/mdocml/man_html.c index 100188bd52..2c4e220a11 100644 --- a/contrib/mdocml/man_html.c +++ b/contrib/mdocml/man_html.c @@ -1,6 +1,7 @@ -/* $Id: man_html.c,v 1.89 2012/11/17 00:26:33 schwarze Exp $ */ +/* $Id: man_html.c,v 1.90 2013/10/17 20:54:58 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons + * Copyright (c) 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -70,6 +71,7 @@ static int man_RS_pre(MAN_ARGS); static int man_SH_pre(MAN_ARGS); static int man_SM_pre(MAN_ARGS); static int man_SS_pre(MAN_ARGS); +static int man_UR_pre(MAN_ARGS); static int man_alt_pre(MAN_ARGS); static int man_br_pre(MAN_ARGS); static int man_ign_pre(MAN_ARGS); @@ -115,6 +117,8 @@ static const struct htmlman mans[MAN_MAX] = { { man_OP_pre, NULL }, /* OP */ { man_literal_pre, NULL }, /* EX */ { man_literal_pre, NULL }, /* EE */ + { man_UR_pre, NULL }, /* UR */ + { NULL, NULL }, /* UE */ }; /* @@ -688,3 +692,27 @@ man_RS_pre(MAN_ARGS) print_otag(h, TAG_DIV, 1, &tag); return(1); } + +/* ARGSUSED */ +static int +man_UR_pre(MAN_ARGS) +{ + struct htmlpair tag[2]; + + n = n->child; + assert(MAN_HEAD == n->type); + if (n->nchild) { + assert(MAN_TEXT == n->child->type); + PAIR_CLASS_INIT(&tag[0], "link-ext"); + PAIR_HREF_INIT(&tag[1], n->child->string); + print_otag(h, TAG_A, 2, tag); + } + + assert(MAN_BODY == n->next->type); + if (n->next->nchild) + n = n->next; + + print_man_nodelist(man, n->child, mh, h); + + return(0); +} diff --git a/contrib/mdocml/man_macro.c b/contrib/mdocml/man_macro.c index e9cb8984d8..d89298e2af 100644 --- a/contrib/mdocml/man_macro.c +++ b/contrib/mdocml/man_macro.c @@ -1,7 +1,7 @@ -/* $Id: man_macro.c,v 1.75 2012/11/17 00:26:33 schwarze Exp $ */ +/* $Id: man_macro.c,v 1.78 2013/12/22 13:25:17 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2012 Ingo Schwarze + * Copyright (c) 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -88,6 +88,8 @@ const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, 0 }, /* OP */ { in_line_eoln, MAN_BSCOPE }, /* EX */ { in_line_eoln, MAN_BSCOPE }, /* EE */ + { blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */ + { blk_close, 0 }, /* UE */ }; const struct man_macro * const man_macros = __man_macros; @@ -284,6 +286,9 @@ blk_close(MACRO_PROT_ARGS) case (MAN_RE): ntok = MAN_RS; break; + case (MAN_UE): + ntok = MAN_UR; + break; default: abort(); /* NOTREACHED */ @@ -293,10 +298,12 @@ blk_close(MACRO_PROT_ARGS) if (ntok == nn->tok && MAN_BLOCK == nn->type) break; - if (NULL != nn) - man_unscope(man, nn, MANDOCERR_MAX); - else + if (NULL == nn) { man_pmsg(man, line, ppos, MANDOCERR_NOSCOPE); + if ( ! rew_scope(MAN_BLOCK, man, MAN_PP)) + return(0); + } else + man_unscope(man, nn, MANDOCERR_MAX); return(1); } diff --git a/contrib/mdocml/man_term.c b/contrib/mdocml/man_term.c index db5719ce1a..4bd62443b4 100644 --- a/contrib/mdocml/man_term.c +++ b/contrib/mdocml/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.136 2013/01/05 22:19:12 schwarze Exp $ */ +/* $Id: man_term.c,v 1.139 2013/12/22 23:34:13 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze @@ -78,6 +78,7 @@ static int pre_RS(DECL_ARGS); static int pre_SH(DECL_ARGS); static int pre_SS(DECL_ARGS); static int pre_TP(DECL_ARGS); +static int pre_UR(DECL_ARGS); static int pre_alternate(DECL_ARGS); static int pre_ft(DECL_ARGS); static int pre_ign(DECL_ARGS); @@ -91,6 +92,7 @@ static void post_RS(DECL_ARGS); static void post_SH(DECL_ARGS); static void post_SS(DECL_ARGS); static void post_TP(DECL_ARGS); +static void post_UR(DECL_ARGS); static const struct termact termacts[MAN_MAX] = { { pre_sp, NULL, MAN_NOTEXT }, /* br */ @@ -129,6 +131,8 @@ static const struct termact termacts[MAN_MAX] = { { pre_OP, NULL, 0 }, /* OP */ { pre_literal, NULL, 0 }, /* EX */ { pre_literal, NULL, 0 }, /* EE */ + { pre_UR, post_UR, 0 }, /* UR */ + { NULL, NULL, 0 }, /* UE */ }; @@ -261,7 +265,8 @@ pre_literal(DECL_ARGS) if (MAN_HP == n->parent->tok && p->rmargin < p->maxrmargin) { p->offset = p->rmargin; p->rmargin = p->maxrmargin; - p->flags &= ~(TERMP_NOBREAK | TERMP_TWOSPACE); + p->trailspace = 0; + p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; } @@ -531,7 +536,7 @@ pre_HP(DECL_ARGS) if ( ! (MANT_LITERAL & mt->fl)) { p->flags |= TERMP_NOBREAK; - p->flags |= TERMP_TWOSPACE; + p->trailspace = 2; } len = mt->lmargin[mt->lmargincur]; @@ -566,7 +571,7 @@ post_HP(DECL_ARGS) case (MAN_BODY): term_newln(p); p->flags &= ~TERMP_NOBREAK; - p->flags &= ~TERMP_TWOSPACE; + p->trailspace = 0; p->offset = mt->offset; p->rmargin = p->maxrmargin; break; @@ -609,6 +614,7 @@ pre_IP(DECL_ARGS) break; case (MAN_HEAD): p->flags |= TERMP_NOBREAK; + p->trailspace = 1; break; case (MAN_BLOCK): print_bvspace(p, n, mt->pardist); @@ -671,10 +677,12 @@ post_IP(DECL_ARGS) case (MAN_HEAD): term_flushln(p); p->flags &= ~TERMP_NOBREAK; + p->trailspace = 0; p->rmargin = p->maxrmargin; break; case (MAN_BODY): term_newln(p); + p->offset = mt->offset; break; default: break; @@ -693,6 +701,7 @@ pre_TP(DECL_ARGS) switch (n->type) { case (MAN_HEAD): p->flags |= TERMP_NOBREAK; + p->trailspace = 1; break; case (MAN_BODY): p->flags |= TERMP_NOSPACE; @@ -740,8 +749,8 @@ pre_TP(DECL_ARGS) case (MAN_BODY): p->offset = mt->offset + len; p->rmargin = p->maxrmargin; + p->trailspace = 0; p->flags &= ~TERMP_NOBREAK; - p->flags &= ~TERMP_TWOSPACE; break; default: break; @@ -762,6 +771,7 @@ post_TP(DECL_ARGS) break; case (MAN_BODY): term_newln(p); + p->offset = mt->offset; break; default: break; @@ -939,6 +949,32 @@ post_RS(DECL_ARGS) mt->lmargincur = mt->lmarginsz; } +/* ARGSUSED */ +static int +pre_UR(DECL_ARGS) +{ + + return (MAN_HEAD != n->type); +} + +/* ARGSUSED */ +static void +post_UR(DECL_ARGS) +{ + + if (MAN_BLOCK != n->type) + return; + + term_word(p, "<"); + p->flags |= TERMP_NOSPACE; + + if (NULL != n->child->child) + print_man_node(p, mt, n->child->child, meta); + + p->flags |= TERMP_NOSPACE; + term_word(p, ">"); +} + static void print_man_node(DECL_ARGS) { @@ -1069,6 +1105,7 @@ print_man_foot(struct termp *p, const void *arg) /* Bottom left corner: manual source. */ p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; + p->trailspace = 1; p->offset = 0; p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2; @@ -1091,6 +1128,7 @@ print_man_foot(struct termp *p, const void *arg) p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; + p->trailspace = 0; p->offset = p->rmargin; p->rmargin = p->maxrmargin; @@ -1122,6 +1160,7 @@ print_man_head(struct termp *p, const void *arg) titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; + p->trailspace = 1; p->offset = 0; p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ? (p->maxrmargin - @@ -1144,6 +1183,7 @@ print_man_head(struct termp *p, const void *arg) /* Top right corner: title and section, again. */ p->flags &= ~TERMP_NOBREAK; + p->trailspace = 0; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; diff --git a/contrib/mdocml/man_validate.c b/contrib/mdocml/man_validate.c index 7a9deede11..da2e557ebb 100644 --- a/contrib/mdocml/man_validate.c +++ b/contrib/mdocml/man_validate.c @@ -1,7 +1,7 @@ -/* $Id: man_validate.c,v 1.85 2012/11/17 00:26:33 schwarze Exp $ */ +/* $Id: man_validate.c,v 1.86 2013/10/17 20:54:58 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2012 Ingo Schwarze + * Copyright (c) 2010, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -49,6 +49,7 @@ static int check_eq2(CHKARGS); static int check_le1(CHKARGS); static int check_ge2(CHKARGS); static int check_le5(CHKARGS); +static int check_head1(CHKARGS); static int check_par(CHKARGS); static int check_part(CHKARGS); static int check_root(CHKARGS); @@ -80,6 +81,7 @@ static v_check posts_sec[] = { post_sec, NULL }; static v_check posts_sp[] = { post_vs, check_le1, NULL }; static v_check posts_th[] = { check_ge2, check_le5, post_TH, NULL }; static v_check posts_uc[] = { post_UC, NULL }; +static v_check posts_ur[] = { check_head1, check_part, NULL }; static v_check pres_sec[] = { pre_sec, NULL }; static const struct man_valid man_valids[MAN_MAX] = { @@ -119,6 +121,8 @@ static const struct man_valid man_valids[MAN_MAX] = { { NULL, posts_eq2 }, /* OP */ { NULL, posts_nf }, /* EX */ { NULL, posts_fi }, /* EE */ + { NULL, posts_ur }, /* UR */ + { NULL, NULL }, /* UE */ }; @@ -245,6 +249,17 @@ INEQ_DEFINE(1, <=, le1) INEQ_DEFINE(2, >=, ge2) INEQ_DEFINE(5, <=, le5) +static int +check_head1(CHKARGS) +{ + + if (MAN_HEAD == n->type && 1 != n->nchild) + mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, + n->pos, "line arguments eq 1 (have %d)", n->nchild); + + return(1); +} + static int post_ft(CHKARGS) { diff --git a/contrib/mdocml/mandoc.3 b/contrib/mdocml/mandoc.3 index f6706e3230..4cf093f9d2 100644 --- a/contrib/mdocml/mandoc.3 +++ b/contrib/mdocml/mandoc.3 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.3,v 1.20 2013/09/16 22:54:38 schwarze Exp $ +.\" $Id: mandoc.3,v 1.22 2013/10/06 17:01:52 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 16 2013 $ +.Dd $Mdocdate: October 5 2013 $ .Dt MANDOC 3 .Os .Sh NAME @@ -50,8 +50,8 @@ .In mandoc.h .Ft "enum mandoc_esc" .Fo mandoc_escape -.Fa "const char **end" -.Fa "const char **start" +.Fa "const char const **end" +.Fa "const char const **start" .Fa "int *sz" .Fc .Ft "const struct man_meta *" diff --git a/contrib/mdocml/mandoc.c b/contrib/mdocml/mandoc.c index df510226c4..2936ef9360 100644 --- a/contrib/mdocml/mandoc.c +++ b/contrib/mdocml/mandoc.c @@ -1,4 +1,4 @@ -/* $Id: mandoc.c,v 1.68 2013/08/08 20:07:47 schwarze Exp $ */ +/* $Id: mandoc.c,v 1.70 2013/11/10 21:34:04 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013 Ingo Schwarze @@ -40,7 +40,7 @@ static char *time2a(time_t); enum mandoc_esc -mandoc_escape(const char **end, const char **start, int *sz) +mandoc_escape(const char const **end, const char const **start, int *sz) { const char *local_start; int local_sz; @@ -93,8 +93,11 @@ mandoc_escape(const char **end, const char **start, int *sz) case ('C'): if ('\'' != **start) return(ESCAPE_ERROR); - gly = ESCAPE_SPECIAL; *start = ++*end; + if ('u' == (*start)[0] && '\'' != (*start)[1]) + gly = ESCAPE_UNICODE; + else + gly = ESCAPE_SPECIAL; term = '\''; break; diff --git a/contrib/mdocml/mandoc.h b/contrib/mdocml/mandoc.h index c2406e952c..5170b419b9 100644 --- a/contrib/mdocml/mandoc.h +++ b/contrib/mdocml/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.110 2013/09/16 00:25:07 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.111 2013/10/05 20:30:05 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2012, 2013 Ingo Schwarze @@ -400,7 +400,8 @@ struct man; __BEGIN_DECLS void *mandoc_calloc(size_t, size_t); -enum mandoc_esc mandoc_escape(const char **, const char **, int *); +enum mandoc_esc mandoc_escape(const char const **, + const char const **, int *); void *mandoc_malloc(size_t); void *mandoc_realloc(void *, size_t); char *mandoc_strdup(const char *); diff --git a/contrib/mdocml/mandoc_char.7 b/contrib/mdocml/mandoc_char.7 index 23ccc0aa03..d0a91c244e 100644 --- a/contrib/mdocml/mandoc_char.7 +++ b/contrib/mdocml/mandoc_char.7 @@ -1,4 +1,4 @@ -.\" $Id: mandoc_char.7,v 1.53 2013/07/13 19:41:16 schwarze Exp $ +.\" $Id: mandoc_char.7,v 1.55 2013/12/22 13:18:27 schwarze Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 13 2013 $ +.Dd $Mdocdate: November 10 2013 $ .Dt MANDOC_CHAR 7 .Os .Sh NAME @@ -655,13 +655,18 @@ manual. .It \e*(Ai Ta \*(Ai Ta ANSI standard name .El .Sh UNICODE CHARACTERS -The escape sequence +The escape sequences .Pp -.Dl \e[uXXXX] +.Dl \e[uXXXX] and \eC'uXXXX' .Pp -is interpreted as a Unicode codepoint. +are interpreted as Unicode codepoints. The codepoint must be in the range above U+0080 and less than U+10FFFF. -For compatibility, points must be zero-padded to four characters; if +For compatibility, the hexadecimal digits +.Sq A +to +.Sq F +must be given as uppercase characters, +and points must be zero-padded to four characters; if greater than four characters, no zero padding is allowed. Unicode surrogates are not allowed. .\" .Pp diff --git a/contrib/mdocml/mandocdb.c b/contrib/mdocml/mandocdb.c index 028377ccb7..a7491cafa6 100644 --- a/contrib/mdocml/mandocdb.c +++ b/contrib/mdocml/mandocdb.c @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.49.2.7 2013/10/02 21:03:26 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.49.2.10 2013/11/21 01:53:48 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012 Ingo Schwarze @@ -34,19 +34,21 @@ #include #include -#if defined(__linux__) || defined(__sun) -# include -# include -#elif defined(__APPLE__) +#if defined(__APPLE__) # include -# include +#elif defined(__linux__) +# include +#elif defined(__sun) +# include +# include #else # include -# include #endif -#if defined(__sun) -#include +#if defined(__linux__) || defined(__sun) +# include +#else +# include #endif #include "man.h" @@ -620,6 +622,8 @@ index_merge(const struct of *of, struct mparse *mp, uint64_t vbuf[2]; char type; + static char emptystring[] = ""; + if (warnings) { files = NULL; hash_reset(&files); @@ -732,13 +736,13 @@ index_merge(const struct of *of, struct mparse *mp, } buf_appendb(buf, ")", 2); for (p = buf->cp; '\0' != *p; p++) - *p = tolower(*p); + *p = tolower((unsigned char)*p); key.data = buf->cp; key.size = buf->len; val.data = NULL; val.size = 0; if (0 == skip) - val.data = ""; + val.data = emptystring; else { ch = (*files->get)(files, &key, &val, 0); if (ch < 0) { diff --git a/contrib/mdocml/manpath.c b/contrib/mdocml/manpath.c index 90089323e3..c33e0ecf46 100644 --- a/contrib/mdocml/manpath.c +++ b/contrib/mdocml/manpath.c @@ -1,4 +1,4 @@ -/* $Id: manpath.c,v 1.11 2013/06/05 02:00:26 schwarze Exp $ */ +/* $Id: manpath.c,v 1.12 2013/11/21 01:49:18 schwarze Exp $ */ /* * Copyright (c) 2011 Ingo Schwarze * Copyright (c) 2011 Kristaps Dzonsons @@ -209,7 +209,7 @@ manpath_manconf(struct manpaths *dirs, const char *file) if (strncmp(MAN_CONF_KEY, p, keysz)) continue; p += keysz; - while (isspace(*p)) + while (isspace((unsigned char)*p)) p++; if ('\0' == *p) continue; diff --git a/contrib/mdocml/mdoc.7 b/contrib/mdocml/mdoc.7 index c7e58667f8..f57506a689 100644 --- a/contrib/mdocml/mdoc.7 +++ b/contrib/mdocml/mdoc.7 @@ -1,4 +1,4 @@ -.\" $Id: mdoc.7,v 1.220 2013/08/14 15:08:31 schwarze Exp $ +.\" $Id: mdoc.7,v 1.222 2013/11/02 20:39:49 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010, 2011 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 14 2013 $ +.Dd $Mdocdate: October 6 2013 $ .Dt MDOC 7 .Os .Sh NAME @@ -477,6 +477,7 @@ in the alphabetical .Bl -column "Brq, Bro, Brc" description .It Sx \&Lb Ta function library (one argument) .It Sx \&In Ta include file (one argument) +.It Sx \&Fd Ta other preprocessor directive (>0 arguments) .It Sx \&Ft Ta function type (>0 arguments) .It Sx \&Fo , \&Fc Ta function block: Ar funcname .It Sx \&Fn Ta function name: @@ -1407,9 +1408,12 @@ See also .Sx \&Er and .Sx \&Ev -for special-purpose constants and +for special-purpose constants, .Sx \&Va -for variable symbols. +for variable symbols, and +.Sx \&Fd +for listing preprocessor variable definitions in the +.Em SYNOPSIS . .Ss \&Dx Format the .Dx @@ -1570,15 +1574,32 @@ See also End a function context started by .Sx \&Fo . .Ss \&Fd -Historically used to document include files. -This usage has been deprecated in favour of +Preprocessor directive, in particular for listing it in the +.Em SYNOPSIS . +Historically, it was also used to document include files. +The latter usage has been deprecated in favour of .Sx \&In . -Do not use this macro. +.Pp +Its syntax is as follows: +.Bd -ragged -offset indent +.Pf \. Sx \&Fd +.Li # Ns Ar directive +.Op Ar argument ... +.Ed +.Pp +Examples: +.Dl \&.Fd #define sa_handler __sigaction_u.__sa_handler +.Dl \&.Fd #define SIO_MAXNFDS +.Dl \&.Fd #ifdef FS_DEBUG +.Dl \&.Ft void +.Dl \&.Fn dbg_open \(dqconst char *\(dq +.Dl \&.Fd #endif .Pp See also -.Sx MANUAL STRUCTURE +.Sx MANUAL STRUCTURE , +.Sx \&In , and -.Sx \&In . +.Sx \&Dv . .Ss \&Fl Command-line flag or option. Used when listing arguments to command-line utilities. diff --git a/contrib/mdocml/mdoc.c b/contrib/mdocml/mdoc.c index df68229cfd..228728fccf 100644 --- a/contrib/mdocml/mdoc.c +++ b/contrib/mdocml/mdoc.c @@ -1,7 +1,7 @@ -/* $Id: mdoc.c,v 1.203 2012/11/17 00:26:33 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.205 2013/10/21 23:47:58 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2012 Ingo Schwarze + * Copyright (c) 2010, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -295,12 +295,10 @@ mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs) * whether this mode is on or off. * Note that this mode is also switched by the Sh macro. */ - if (roff_regisset(mdoc->roff, REG_nS)) { - if (roff_regget(mdoc->roff, REG_nS)) - mdoc->flags |= MDOC_SYNOPSIS; - else - mdoc->flags &= ~MDOC_SYNOPSIS; - } + if (roff_getreg(mdoc->roff, "nS")) + mdoc->flags |= MDOC_SYNOPSIS; + else + mdoc->flags &= ~MDOC_SYNOPSIS; return(roff_getcontrol(mdoc->roff, buf, &offs) ? mdoc_pmacro(mdoc, ln, buf, offs) : @@ -584,6 +582,23 @@ mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p) return(1); } +void +mdoc_word_append(struct mdoc *mdoc, const char *p) +{ + struct mdoc_node *n; + char *addstr, *newstr; + + n = mdoc->last; + addstr = roff_strdup(mdoc->roff, p); + if (-1 == asprintf(&newstr, "%s %s", n->string, addstr)) { + perror(NULL); + exit((int)MANDOCLEVEL_SYSERR); + } + free(addstr); + free(n->string); + n->string = newstr; + mdoc->next = MDOC_NEXT_SIBLING; +} static void mdoc_node_free(struct mdoc_node *p) diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mdocml/mdoc_argv.c index a9503ffee9..83f807759d 100644 --- a/contrib/mdocml/mdoc_argv.c +++ b/contrib/mdocml/mdoc_argv.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_argv.c,v 1.86 2012/11/18 00:05:35 schwarze Exp $ */ +/* $Id: mdoc_argv.c,v 1.88 2013/12/22 14:06:36 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2012 Ingo Schwarze @@ -447,6 +447,7 @@ args(struct mdoc *mdoc, int line, int *pos, char *buf, enum argsflag fl, char **v) { char *p, *pp; + int pairs; enum margserr rc; if ('\0' == buf[*pos]) { @@ -540,6 +541,8 @@ args(struct mdoc *mdoc, int line, int *pos, /* * Process a quoted literal. A quote begins with a double-quote * and ends with a double-quote NOT preceded by a double-quote. + * Null-terminate the literal in place. + * Collapse pairs of quotes inside quoted literals. * Whitespace is NOT involved in literal termination. */ @@ -550,13 +553,22 @@ args(struct mdoc *mdoc, int line, int *pos, if (MDOC_PPHRASE & mdoc->flags) mdoc->flags |= MDOC_PHRASELIT; + pairs = 0; for ( ; buf[*pos]; (*pos)++) { + /* Move following text left after quoted quotes. */ + if (pairs) + buf[*pos - pairs] = buf[*pos]; if ('\"' != buf[*pos]) continue; + /* Unquoted quotes end quoted args. */ if ('\"' != buf[*pos + 1]) break; + /* Quoted quotes collapse. */ + pairs++; (*pos)++; } + if (pairs) + buf[*pos - pairs] = '\0'; if ('\0' == buf[*pos]) { if (MDOC_PPHRASE & mdoc->flags) diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mdocml/mdoc_macro.c index 0a5048649d..4a018eedcf 100644 --- a/contrib/mdocml/mdoc_macro.c +++ b/contrib/mdocml/mdoc_macro.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_macro.c,v 1.122 2013/09/15 18:26:46 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.123 2013/10/21 23:47:58 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010, 2012 Ingo Schwarze + * Copyright (c) 2010, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -51,8 +51,8 @@ static int in_line(MACRO_PROT_ARGS); static int obsolete(MACRO_PROT_ARGS); static int phrase_ta(MACRO_PROT_ARGS); -static int dword(struct mdoc *, int, int, - const char *, enum mdelim); +static int dword(struct mdoc *, int, int, const char *, + enum mdelim, int); static int append_delims(struct mdoc *, int, int *, char *); static enum mdoct lookup(enum mdoct, const char *); @@ -70,128 +70,147 @@ static int rew_sub(enum mdoc_type, struct mdoc *, enum mdoct, int, int); const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ap */ { in_line_eoln, MDOC_PROLOGUE }, /* Dd */ { in_line_eoln, MDOC_PROLOGUE }, /* Dt */ { in_line_eoln, MDOC_PROLOGUE }, /* Os */ - { blk_full, MDOC_PARSED }, /* Sh */ - { blk_full, MDOC_PARSED }, /* Ss */ - { in_line_eoln, 0 }, /* Pp */ - { blk_part_imp, MDOC_PARSED }, /* D1 */ - { blk_part_imp, MDOC_PARSED }, /* Dl */ + { blk_full, MDOC_PARSED | MDOC_JOIN }, /* Sh */ + { blk_full, MDOC_PARSED | MDOC_JOIN }, /* Ss */ + { in_line_eoln, 0 }, /* Pp */ + { blk_part_imp, MDOC_PARSED | MDOC_JOIN }, /* D1 */ + { blk_part_imp, MDOC_PARSED | MDOC_JOIN }, /* Dl */ { blk_full, MDOC_EXPLICIT }, /* Bd */ - { blk_exp_close, MDOC_EXPLICIT }, /* Ed */ + { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ed */ { blk_full, MDOC_EXPLICIT }, /* Bl */ - { blk_exp_close, MDOC_EXPLICIT }, /* El */ - { blk_full, MDOC_PARSED }, /* It */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */ + { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* El */ + { blk_full, MDOC_PARSED | MDOC_JOIN }, /* It */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */ + { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* An */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */ { in_line_eoln, 0 }, /* Ex */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */ - { in_line_eoln, 0 }, /* Fd */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */ + { in_line_eoln, 0 }, /* Fd */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */ - { blk_full, 0 }, /* Nd */ - { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */ + { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Li */ + { blk_full, MDOC_JOIN }, /* Nd */ + { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */ { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */ { obsolete, 0 }, /* Ot */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */ { in_line_eoln, 0 }, /* Rv */ - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */ - { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ + { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */ - { in_line_eoln, 0 }, /* %A */ - { in_line_eoln, 0 }, /* %B */ - { in_line_eoln, 0 }, /* %D */ - { in_line_eoln, 0 }, /* %I */ - { in_line_eoln, 0 }, /* %J */ + { in_line_eoln, MDOC_JOIN }, /* %A */ + { in_line_eoln, MDOC_JOIN }, /* %B */ + { in_line_eoln, MDOC_JOIN }, /* %D */ + { in_line_eoln, MDOC_JOIN }, /* %I */ + { in_line_eoln, MDOC_JOIN }, /* %J */ { in_line_eoln, 0 }, /* %N */ - { in_line_eoln, 0 }, /* %O */ + { in_line_eoln, MDOC_JOIN }, /* %O */ { in_line_eoln, 0 }, /* %P */ - { in_line_eoln, 0 }, /* %R */ - { in_line_eoln, 0 }, /* %T */ + { in_line_eoln, MDOC_JOIN }, /* %R */ + { in_line_eoln, MDOC_JOIN }, /* %T */ { in_line_eoln, 0 }, /* %V */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Ac */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Ao */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Aq */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */ - { blk_full, MDOC_EXPLICIT }, /* Bf */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Bc */ + { blk_full, MDOC_EXPLICIT }, /* Bf */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Bo */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Bq */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */ { in_line_eoln, 0 }, /* Db */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */ - { blk_exp_close, MDOC_EXPLICIT }, /* Ef */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Dc */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Do */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Dq */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ec */ + { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ef */ + { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Em */ { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */ - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* No */ - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Ns */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | + MDOC_IGNDELIM | MDOC_JOIN }, /* No */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | + MDOC_IGNDELIM | MDOC_JOIN }, /* Ns */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Pc */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */ - { blk_exp_close, MDOC_EXPLICIT }, /* Re */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Po */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Pq */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Qc */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ql */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Qo */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Qq */ + { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Re */ { blk_full, MDOC_EXPLICIT }, /* Rs */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Sc */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* So */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sq */ { in_line_eoln, 0 }, /* Sm */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */ + { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sx */ + { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sy */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */ - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ux */ { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */ { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */ - { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */ + { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Fc */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Oo */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Oc */ { blk_full, MDOC_EXPLICIT }, /* Bk */ - { blk_exp_close, MDOC_EXPLICIT }, /* Ek */ + { blk_exp_close, MDOC_EXPLICIT | MDOC_JOIN }, /* Ek */ { in_line_eoln, 0 }, /* Bt */ { in_line_eoln, 0 }, /* Hf */ { obsolete, 0 }, /* Fr */ { in_line_eoln, 0 }, /* Ud */ { in_line, 0 }, /* Lb */ - { in_line_eoln, 0 }, /* Lp */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */ - { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */ - { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */ - { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */ - { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */ - { in_line_eoln, 0 }, /* %C */ + { in_line_eoln, 0 }, /* Lp */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */ + { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */ + { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Brq */ + { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Bro */ + { blk_exp_close, MDOC_CALLABLE | MDOC_PARSED | + MDOC_EXPLICIT | MDOC_JOIN }, /* Brc */ + { in_line_eoln, MDOC_JOIN }, /* %C */ { obsolete, 0 }, /* Es */ { obsolete, 0 }, /* En */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */ - { in_line_eoln, 0 }, /* %Q */ + { in_line_eoln, MDOC_JOIN }, /* %Q */ { in_line_eoln, 0 }, /* br */ { in_line_eoln, 0 }, /* sp */ { in_line_eoln, 0 }, /* %U */ - { phrase_ta, MDOC_CALLABLE | MDOC_PARSED }, /* Ta */ + { phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */ }; const struct mdoc_macro * const mdoc_macros = __mdoc_macros; @@ -588,13 +607,21 @@ rew_sub(enum mdoc_type t, struct mdoc *mdoc, * Punctuation consists of those tokens found in mdoc_isdelim(). */ static int -dword(struct mdoc *mdoc, int line, - int col, const char *p, enum mdelim d) +dword(struct mdoc *mdoc, int line, int col, const char *p, + enum mdelim d, int may_append) { if (DELIM_MAX == d) d = mdoc_isdelim(p); + if (may_append && + ! ((MDOC_SYNOPSIS | MDOC_KEEP | MDOC_SMOFF) & mdoc->flags) && + DELIM_NONE == d && MDOC_TEXT == mdoc->last->type && + DELIM_NONE == mdoc_isdelim(mdoc->last->string)) { + mdoc_word_append(mdoc, p); + return(1); + } + if ( ! mdoc_word_alloc(mdoc, line, col, p)) return(0); @@ -638,7 +665,7 @@ append_delims(struct mdoc *mdoc, int line, int *pos, char *buf) else if (ARGS_EOLN == ac) break; - dword(mdoc, line, la, p, DELIM_MAX); + dword(mdoc, line, la, p, DELIM_MAX, 1); /* * If we encounter end-of-sentence symbols, then trigger @@ -680,6 +707,9 @@ blk_exp_close(MACRO_PROT_ARGS) case (MDOC_Ec): maxargs = 1; break; + case (MDOC_Ek): + if ( ! (MDOC_SYNOPSIS & mdoc->flags)) + mdoc->flags &= ~MDOC_KEEP; default: maxargs = 0; break; @@ -782,7 +812,8 @@ blk_exp_close(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, lastarg, p, DELIM_MAX)) + if ( ! dword(mdoc, line, lastarg, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } @@ -948,7 +979,8 @@ in_line(MACRO_PROT_ARGS) if (DELIM_NONE == d) cnt++; - if ( ! dword(mdoc, line, la, p, d)) + if ( ! dword(mdoc, line, la, p, d, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); /* @@ -1067,7 +1099,10 @@ blk_full(MACRO_PROT_ARGS) if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); body = mdoc->last; - } + } + + if (MDOC_Bk == tok) + mdoc->flags |= MDOC_KEEP; ac = ARGS_ERROR; @@ -1112,7 +1147,7 @@ blk_full(MACRO_PROT_ARGS) ARGS_PPHRASE != ac && ARGS_QWORD != ac && DELIM_OPEN == mdoc_isdelim(p)) { - if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0)) return(0); continue; } @@ -1165,7 +1200,8 @@ blk_full(MACRO_PROT_ARGS) MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } @@ -1276,10 +1312,10 @@ blk_part_imp(MACRO_PROT_ARGS) if (NULL == body && ARGS_QWORD != ac && DELIM_OPEN == mdoc_isdelim(p)) { - if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0)) return(0); continue; - } + } if (NULL == body) { if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) @@ -1290,7 +1326,8 @@ blk_part_imp(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } @@ -1416,10 +1453,10 @@ blk_part_exp(MACRO_PROT_ARGS) if (NULL == head && ARGS_QWORD != ac && DELIM_OPEN == mdoc_isdelim(p)) { assert(NULL == body); - if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0)) return(0); continue; - } + } if (NULL == head) { assert(NULL == body); @@ -1437,7 +1474,7 @@ blk_part_exp(MACRO_PROT_ARGS) assert(head); /* No check whether it's a macro! */ if (MDOC_Eo == tok) - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, 0)) return(0); if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos)) @@ -1455,7 +1492,8 @@ blk_part_exp(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } @@ -1559,7 +1597,7 @@ in_line_argn(MACRO_PROT_ARGS) if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && ARGS_QWORD != ac && 0 == j && DELIM_OPEN == mdoc_isdelim(p)) { - if ( ! dword(mdoc, line, la, p, DELIM_OPEN)) + if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0)) return(0); continue; } else if (0 == j) @@ -1593,7 +1631,8 @@ in_line_argn(MACRO_PROT_ARGS) flushed = 1; } - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); j++; } @@ -1664,7 +1703,8 @@ in_line_eoln(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } @@ -1744,7 +1784,7 @@ phrase(struct mdoc *mdoc, int line, int ppos, char *buf) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, 1)) return(0); continue; } @@ -1795,7 +1835,8 @@ phrase_ta(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { - if ( ! dword(mdoc, line, la, p, DELIM_MAX)) + if ( ! dword(mdoc, line, la, p, DELIM_MAX, + MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mdocml/mdoc_term.c index 99c595393a..7207df398f 100644 --- a/contrib/mdocml/mdoc_term.c +++ b/contrib/mdocml/mdoc_term.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_term.c,v 1.249 2013/06/02 18:16:57 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.251 2013/12/23 02:20:09 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2012 Ingo Schwarze + * Copyright (c) 2010, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -424,6 +424,7 @@ print_mdoc_foot(struct termp *p, const void *arg) p->offset = 0; p->rmargin = (p->maxrmargin - term_strlen(p, meta->date) + term_len(p, 1)) / 2; + p->trailspace = 1; p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; term_word(p, meta->os); @@ -438,6 +439,7 @@ print_mdoc_foot(struct termp *p, const void *arg) p->offset = p->rmargin; p->rmargin = p->maxrmargin; + p->trailspace = 0; p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; @@ -489,6 +491,7 @@ print_mdoc_head(struct termp *p, const void *arg) titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; + p->trailspace = 1; p->offset = 0; p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ? (p->maxrmargin - @@ -507,6 +510,7 @@ print_mdoc_head(struct termp *p, const void *arg) term_flushln(p); p->flags &= ~TERMP_NOBREAK; + p->trailspace = 0; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; @@ -794,13 +798,13 @@ termp_it_pre(DECL_ARGS) case (LIST_dash): /* FALLTHROUGH */ case (LIST_hyphen): - if (MDOC_HEAD == n->type) - p->flags |= TERMP_NOBREAK; + if (MDOC_HEAD != n->type) + break; + p->flags |= TERMP_NOBREAK; + p->trailspace = 1; break; case (LIST_hang): - if (MDOC_HEAD == n->type) - p->flags |= TERMP_NOBREAK; - else + if (MDOC_HEAD != n->type) break; /* @@ -812,16 +816,18 @@ termp_it_pre(DECL_ARGS) if (n->next->child && (MDOC_Bl == n->next->child->tok || MDOC_Bd == n->next->child->tok)) - p->flags &= ~TERMP_NOBREAK; - else - p->flags |= TERMP_HANG; + break; + + p->flags |= TERMP_NOBREAK | TERMP_HANG; + p->trailspace = 1; break; case (LIST_tag): - if (MDOC_HEAD == n->type) - p->flags |= TERMP_NOBREAK | TERMP_TWOSPACE; - if (MDOC_HEAD != n->type) break; + + p->flags |= TERMP_NOBREAK; + p->trailspace = 2; + if (NULL == n->next || NULL == n->next->child) p->flags |= TERMP_DANGLE; break; @@ -829,15 +835,20 @@ termp_it_pre(DECL_ARGS) if (MDOC_HEAD == n->type) break; - if (NULL == n->next) + if (NULL == n->next) { p->flags &= ~TERMP_NOBREAK; - else + p->trailspace = 0; + } else { p->flags |= TERMP_NOBREAK; + p->trailspace = 1; + } break; case (LIST_diag): - if (MDOC_HEAD == n->type) - p->flags |= TERMP_NOBREAK; + if (MDOC_HEAD != n->type) + break; + p->flags |= TERMP_NOBREAK; + p->trailspace = 1; break; default: break; @@ -989,8 +1000,8 @@ termp_it_post(DECL_ARGS) p->flags &= ~TERMP_DANGLE; p->flags &= ~TERMP_NOBREAK; - p->flags &= ~TERMP_TWOSPACE; p->flags &= ~TERMP_HANG; + p->trailspace = 0; } @@ -1023,6 +1034,7 @@ termp_nm_pre(DECL_ARGS) if (MDOC_HEAD == n->type && n->next->child) { p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; + p->trailspace = 1; p->rmargin = p->offset + term_len(p, 1); if (NULL == n->child) { p->rmargin += term_strlen(p, meta->name); @@ -1051,6 +1063,7 @@ termp_nm_post(DECL_ARGS) if (MDOC_HEAD == n->type && n->next->child) { term_flushln(p); p->flags &= ~(TERMP_NOBREAK | TERMP_HANG); + p->trailspace = 0; } else if (MDOC_BODY == n->type && n->child) term_flushln(p); } @@ -1525,6 +1538,7 @@ termp_ft_pre(DECL_ARGS) static int termp_fn_pre(DECL_ARGS) { + size_t width, rmargin = 0; int pretty; pretty = MDOC_SYNPRETTY & n->flags; @@ -1534,11 +1548,25 @@ termp_fn_pre(DECL_ARGS) if (NULL == (n = n->child)) return(0); + if (pretty) { + width = term_len(p, 4); + rmargin = p->rmargin; + p->rmargin = p->offset + width; + p->flags |= TERMP_NOBREAK | TERMP_HANG; + } + assert(MDOC_TEXT == n->type); term_fontpush(p, TERMFONT_BOLD); term_word(p, n->string); term_fontpop(p); + if (pretty) { + term_flushln(p); + p->flags &= ~(TERMP_NOBREAK | TERMP_HANG); + p->offset = p->rmargin; + p->rmargin = rmargin; + } + p->flags |= TERMP_NOSPACE; term_word(p, "("); p->flags |= TERMP_NOSPACE; @@ -1561,6 +1589,7 @@ termp_fn_pre(DECL_ARGS) if (pretty) { p->flags |= TERMP_NOSPACE; term_word(p, ";"); + term_flushln(p); } return(0); diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mdocml/mdoc_validate.c index 1655692a00..4cfd620448 100644 --- a/contrib/mdocml/mdoc_validate.c +++ b/contrib/mdocml/mdoc_validate.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.193 2013/09/16 00:25:07 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.198 2013/12/15 21:23:52 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010, 2011, 2012 Ingo Schwarze + * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -889,8 +889,6 @@ pre_sh(PRE_ARGS) if (MDOC_BLOCK != n->type) return(1); - - roff_regunset(mdoc->roff, REG_nS); return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT)); } @@ -1676,10 +1674,16 @@ ebool(struct mdoc *mdoc) assert(MDOC_TEXT == mdoc->last->child->type); - if (0 == strcmp(mdoc->last->child->string, "on")) + if (0 == strcmp(mdoc->last->child->string, "on")) { + if (MDOC_Sm == mdoc->last->tok) + mdoc->flags &= ~MDOC_SMOFF; return(1); - if (0 == strcmp(mdoc->last->child->string, "off")) + } + if (0 == strcmp(mdoc->last->child->string, "off")) { + if (MDOC_Sm == mdoc->last->tok) + mdoc->flags |= MDOC_SMOFF; return(1); + } mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL); return(1); @@ -1986,10 +1990,13 @@ post_sh_head(POST_ARGS) /* The SYNOPSIS gets special attention in other areas. */ - if (SEC_SYNOPSIS == sec) + if (SEC_SYNOPSIS == sec) { + roff_setreg(mdoc->roff, "nS", 1, '='); mdoc->flags |= MDOC_SYNOPSIS; - else + } else { + roff_setreg(mdoc->roff, "nS", 0, '='); mdoc->flags &= ~MDOC_SYNOPSIS; + } /* Mark our last section. */ diff --git a/contrib/mdocml/out.c b/contrib/mdocml/out.c index 1d8c8ab4b6..c931664977 100644 --- a/contrib/mdocml/out.c +++ b/contrib/mdocml/out.c @@ -1,4 +1,4 @@ -/* $Id: out.c,v 1.45 2013/05/31 21:37:17 schwarze Exp $ */ +/* $Id: out.c,v 1.46 2013/10/05 20:30:05 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -142,7 +142,6 @@ void tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) { const struct tbl_dat *dp; - const struct tbl_head *hp; struct roffcol *col; int spans; @@ -156,8 +155,6 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) tbl->cols = mandoc_calloc ((size_t)sp->opts->cols, sizeof(struct roffcol)); - hp = sp->head; - for ( ; sp; sp = sp->next) { if (TBL_SPAN_DATA != sp->pos) continue; diff --git a/contrib/mdocml/roff.7 b/contrib/mdocml/roff.7 index 7c26086e35..bc5507488d 100644 --- a/contrib/mdocml/roff.7 +++ b/contrib/mdocml/roff.7 @@ -1,4 +1,4 @@ -.\" $Id: roff.7,v 1.42 2013/08/08 20:07:47 schwarze Exp $ +.\" $Id: roff.7,v 1.45 2013/12/15 21:23:52 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010, 2011 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 8 2013 $ +.Dd $Mdocdate: October 22 2013 $ .Dt ROFF 7 .Os .Sh NAME @@ -638,6 +638,15 @@ Begin an equation block. See .Xr eqn 7 for a description of the equation language. +.Ss \&fam +Change the font family. +This line-scoped request is intended to have one argument specifying +the font family to be selected. +It is a groff extension, and currently, it is ignored including its +arguments, and the number of arguments is not checked. +.Ss \&hw +Specify hyphenation points in words. +This line-scoped request is currently ignored. .Ss \&hy Set automatic hyphenation mode. This line-scoped request is currently ignored. @@ -805,19 +814,22 @@ the name of the request, macro or string to be undefined. Currently, it is ignored including its arguments, and the number of arguments is not checked. .Ss \&nr -Define a register. +Define or change a register. A register is an arbitrary string value that defines some sort of state, which influences parsing and/or formatting. Its syntax is as follows: .Pp -.D1 Pf \. Cm \&nr Ar name Ar value +.D1 Pf \. Cm \&nr Ar name Oo +|- Oc Ns Ar value .Pp The .Ar value may, at the moment, only be an integer. -So far, only the following register +If it is prefixed by a sign, the register will be +incremented or decremented instead of assigned to. +.Pp +The following register .Ar name -is recognised: +is handled specially: .Bl -tag -width Ds .It Cm nS If set to a positive integer value, certain diff --git a/contrib/mdocml/roff.c b/contrib/mdocml/roff.c index 3ee8adfe6d..e4c43c1362 100644 --- a/contrib/mdocml/roff.c +++ b/contrib/mdocml/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.178 2013/07/13 12:52:07 schwarze Exp $ */ +/* $Id: roff.c,v 1.187 2013/12/15 21:23:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze @@ -46,6 +46,8 @@ enum rofft { ROFF_de1, ROFF_ds, ROFF_el, + ROFF_fam, + ROFF_hw, ROFF_hy, ROFF_ie, ROFF_if, @@ -74,18 +76,8 @@ enum rofft { }; enum roffrule { - ROFFRULE_ALLOW, - ROFFRULE_DENY -}; - -/* - * A single register entity. If "set" is zero, the value of the - * register should be the default one, which is per-register. - * Registers are assumed to be unsigned ints for now. - */ -struct reg { - int set; /* whether set or not */ - unsigned int u; /* unsigned integer */ + ROFFRULE_DENY, + ROFFRULE_ALLOW }; /* @@ -105,6 +97,15 @@ struct roffkv { struct roffkv *next; /* next in list */ }; +/* + * A single number register as part of a singly-linked list. + */ +struct roffreg { + struct roffstr key; + int val; + struct roffreg *next; +}; + struct roff { enum mparset parsetype; /* requested parse type */ struct mparse *parse; /* parse point */ @@ -112,7 +113,7 @@ struct roff { enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */ char control; /* control character */ int rstackpos; /* position in rstack */ - struct reg regs[REG__MAX]; + struct roffreg *regtab; /* number registers */ struct roffkv *strtab; /* user-defined strings & macros */ struct roffkv *xmbtab; /* multi-byte trans table (`tr') */ struct roffstr *xtab; /* single-byte trans table (`tr') */ @@ -183,8 +184,13 @@ static enum rofferr roff_cond_sub(ROFF_ARGS); static enum rofferr roff_ds(ROFF_ARGS); static enum roffrule roff_evalcond(const char *, int *); static void roff_free1(struct roff *); +static void roff_freereg(struct roffreg *); static void roff_freestr(struct roffkv *); static char *roff_getname(struct roff *, char **, int, int); +static int roff_getnum(const char *, int *, int *); +static int roff_getop(const char *, int *, char *); +static int roff_getregn(const struct roff *, + const char *, size_t); static const char *roff_getstrn(const struct roff *, const char *, size_t); static enum rofferr roff_it(ROFF_ARGS); @@ -231,6 +237,8 @@ static struct roffmac roffs[ROFF_MAX] = { { "de1", roff_block, roff_block_text, roff_block_sub, 0, NULL }, { "ds", roff_ds, NULL, NULL, 0, NULL }, { "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, + { "fam", roff_line_ignore, NULL, NULL, 0, NULL }, + { "hw", roff_line_ignore, NULL, NULL, 0, NULL }, { "hy", roff_line_ignore, NULL, NULL, 0, NULL }, { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, @@ -424,6 +432,10 @@ roff_free1(struct roff *r) r->strtab = r->xmbtab = NULL; + roff_freereg(r->regtab); + + r->regtab = NULL; + if (r->xtab) for (i = 0; i < 128; i++) free(r->xtab[i].p); @@ -440,7 +452,6 @@ roff_reset(struct roff *r) roff_free1(r); r->control = 0; - memset(&r->regs, 0, sizeof(struct reg) * REG__MAX); for (i = 0; i < PREDEFS_MAX; i++) roff_setstr(r, predefs[i].name, predefs[i].str, 0); @@ -476,22 +487,23 @@ roff_alloc(enum mparset type, struct mparse *parse) } /* - * Pre-filter each and every line for reserved words (one beginning with - * `\*', e.g., `\*(ab'). These must be handled before the actual line - * is processed. - * This also checks the syntax of regular escapes. + * In the current line, expand user-defined strings ("\*") + * and references to number registers ("\n"). + * Also check the syntax of other escape sequences. */ static enum rofferr roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos) { - enum mandoc_esc esc; + char ubuf[12]; /* buffer to print the number */ const char *stesc; /* start of an escape sequence ('\\') */ 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 */ - int i, maxl, expand_count; - size_t nsz; - char *n; + char *nbuf; /* new buffer to copy bufp to */ + size_t nsz; /* size of the new buffer */ + size_t maxl; /* expected length of the escape name */ + size_t naml; /* actual length of the escape name */ + int expand_count; /* to avoid infinite loops */ expand_count = 0; @@ -501,7 +513,7 @@ again: stesc = cp++; /* - * The second character must be an asterisk. + * The second character must be an asterisk or an n. * If it isn't, skip it anyway: It is escaped, * so it can't start another escape sequence. */ @@ -509,12 +521,16 @@ again: if ('\0' == *cp) return(ROFF_CONT); - if ('*' != *cp) { - res = cp; - esc = mandoc_escape(&cp, NULL, NULL); - if (ESCAPE_ERROR != esc) + switch (*cp) { + case ('*'): + res = NULL; + break; + case ('n'): + res = ubuf; + break; + default: + if (ESCAPE_ERROR != mandoc_escape(&cp, NULL, NULL)) continue; - cp = res; mandoc_msg (MANDOCERR_BADESCAPE, r->parse, ln, (int)(stesc - *bufp), NULL); @@ -525,7 +541,7 @@ again: /* * The third character decides the length - * of the name of the string. + * of the name of the string or register. * Save a pointer to the name. */ @@ -548,7 +564,7 @@ again: /* Advance to the end of the name. */ - for (i = 0; 0 == maxl || i < maxl; i++, cp++) { + for (naml = 0; 0 == maxl || naml < maxl; naml++, cp++) { if ('\0' == *cp) { mandoc_msg (MANDOCERR_BADESCAPE, @@ -565,7 +581,11 @@ again: * undefined, resume searching for escapes. */ - res = roff_getstrn(r, stnam, (size_t)i); + if (NULL == res) + res = roff_getstrn(r, stnam, naml); + else + snprintf(ubuf, sizeof(ubuf), "%d", + roff_getregn(r, stnam, naml)); if (NULL == res) { mandoc_msg @@ -579,15 +599,15 @@ again: pos = stesc - *bufp; nsz = *szp + strlen(res) + 1; - n = mandoc_malloc(nsz); + nbuf = mandoc_malloc(nsz); - strlcpy(n, *bufp, (size_t)(stesc - *bufp + 1)); - strlcat(n, res, nsz); - strlcat(n, cp + (maxl ? 0 : 1), nsz); + strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1)); + strlcat(nbuf, res, nsz); + strlcat(nbuf, cp + (maxl ? 0 : 1), nsz); free(*bufp); - *bufp = n; + *bufp = nbuf; *szp = nsz; if (EXPAND_LIMIT >= ++expand_count) @@ -627,7 +647,7 @@ roff_parsetext(char **bufp, size_t *szp, int pos, int *offs) /* Skip over escapes. */ p++; esc = mandoc_escape - ((const char **)&p, NULL, NULL); + ((const char const **)&p, NULL, NULL); if (ESCAPE_ERROR == esc) break; continue; @@ -698,19 +718,14 @@ roff_parseln(struct roff *r, int ln, char **bufp, assert(ROFF_IGN == e || ROFF_CONT == e); if (ROFF_CONT != e) return(e); - if (r->eqn) - return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); - if (r->tbl) - return(tbl_read(r->tbl, ln, *bufp, pos)); - return(roff_parsetext(bufp, szp, pos, offs)); - } else if ( ! ctl) { - if (r->eqn) - return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); + } + if (r->eqn) + return(eqn_read(&r->eqn, ln, *bufp, ppos, offs)); + if ( ! ctl) { if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); return(roff_parsetext(bufp, szp, pos, offs)); - } else if (r->eqn) - return(eqn_read(&r->eqn, ln, *bufp, ppos, offs)); + } /* * If a scope is open, go to the child handler for that macro, @@ -1116,9 +1131,61 @@ roff_cond_text(ROFF_ARGS) return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); } +static int +roff_getnum(const char *v, int *pos, int *res) +{ + int p, n; + + p = *pos; + n = v[p] == '-'; + if (n) + p++; + + for (*res = 0; isdigit((unsigned char)v[p]); p++) + *res += 10 * *res + v[p] - '0'; + if (p == *pos + n) + return 0; + + if (n) + *res = -*res; + + *pos = p; + return 1; +} + +static int +roff_getop(const char *v, int *pos, char *res) +{ + int e; + + *res = v[*pos]; + e = v[*pos + 1] == '='; + + switch (*res) { + case '=': + break; + case '>': + if (e) + *res = 'g'; + break; + case '<': + if (e) + *res = 'l'; + break; + default: + return(0); + } + + *pos += 1 + e; + + return(*res); +} + static enum roffrule roff_evalcond(const char *v, int *pos) { + int not, lh, rh; + char op; switch (v[*pos]) { case ('n'): @@ -1131,13 +1198,47 @@ roff_evalcond(const char *v, int *pos) case ('t'): (*pos)++; return(ROFFRULE_DENY); + case ('!'): + (*pos)++; + not = 1; + break; default: + not = 0; break; } - while (v[*pos] && ' ' != v[*pos]) - (*pos)++; - return(ROFFRULE_DENY); + if (!roff_getnum(v, pos, &lh)) + return ROFFRULE_DENY; + if (!roff_getop(v, pos, &op)) { + if (lh < 0) + lh = 0; + goto out; + } + if (!roff_getnum(v, pos, &rh)) + return ROFFRULE_DENY; + switch (op) { + case 'g': + lh = lh >= rh; + break; + case 'l': + lh = lh <= rh; + break; + case '=': + lh = lh == rh; + break; + case '>': + lh = lh > rh; + break; + case '<': + lh = lh < rh; + break; + default: + return ROFFRULE_DENY; + } +out: + if (not) + lh = !lh; + return lh ? ROFFRULE_ALLOW : ROFFRULE_DENY; } /* ARGSUSED */ @@ -1258,25 +1359,71 @@ roff_ds(ROFF_ARGS) return(ROFF_IGN); } +void +roff_setreg(struct roff *r, const char *name, int val, char sign) +{ + struct roffreg *reg; + + /* Search for an existing register with the same name. */ + reg = r->regtab; + + while (reg && strcmp(name, reg->key.p)) + 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->val = 0; + reg->next = r->regtab; + r->regtab = reg; + } + + if ('+' == sign) + reg->val += val; + else if ('-' == sign) + reg->val -= val; + else + reg->val = val; +} + int -roff_regisset(const struct roff *r, enum regs reg) +roff_getreg(const struct roff *r, const char *name) { + struct roffreg *reg; - return(r->regs[(int)reg].set); + for (reg = r->regtab; reg; reg = reg->next) + if (0 == strcmp(name, reg->key.p)) + return(reg->val); + + return(0); } -unsigned int -roff_regget(const struct roff *r, enum regs reg) +static int +roff_getregn(const struct roff *r, const char *name, size_t len) { + struct roffreg *reg; - return(r->regs[(int)reg].u); + for (reg = r->regtab; reg; reg = reg->next) + if (len == reg->key.sz && + 0 == strncmp(name, reg->key.p, len)) + return(reg->val); + + return(0); } -void -roff_regunset(struct roff *r, enum regs reg) +static void +roff_freereg(struct roffreg *reg) { + struct roffreg *old_reg; - r->regs[(int)reg].set = 0; + while (NULL != reg) { + free(reg->key.p); + old_reg = reg; + reg = reg->next; + free(old_reg); + } } /* ARGSUSED */ @@ -1285,18 +1432,21 @@ roff_nr(ROFF_ARGS) { const char *key; char *val; + size_t sz; int iv; + char sign; val = *bufp + pos; key = roff_getname(r, &val, ln, pos); - if (0 == strcmp(key, "nS")) { - r->regs[(int)REG_nS].set = 1; - if ((iv = mandoc_strntoi(val, strlen(val), 10)) >= 0) - r->regs[(int)REG_nS].u = (unsigned)iv; - else - r->regs[(int)REG_nS].u = 0u; - } + sign = *val; + if ('+' == sign || '-' == sign) + val++; + + sz = strspn(val, "0123456789"); + iv = sz ? mandoc_strntoi(val, sz, 10) : 0; + + roff_setreg(r, key, iv, sign); return(ROFF_IGN); } diff --git a/contrib/mdocml/term.c b/contrib/mdocml/term.c index 16def7879f..3420c70c46 100644 --- a/contrib/mdocml/term.c +++ b/contrib/mdocml/term.c @@ -1,4 +1,4 @@ -/* $Id: term.c,v 1.210 2013/08/21 21:20:40 schwarze Exp $ */ +/* $Id: term.c,v 1.212 2013/12/23 02:20:09 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze @@ -83,9 +83,8 @@ term_end(struct termp *p) * - TERMP_NOBREAK: this is the most important and is used when making * columns. In short: don't print a newline and instead expect the * next call to do the padding up to the start of the next column. - * - * - TERMP_TWOSPACE: make sure there is room for at least two space - * characters of padding. Otherwise, rather break the line. + * p->trailspace may be set to 0, 1, or 2, depending on how many + * space characters are required at the end of the column. * * - TERMP_DANGLE: don't newline when TERMP_NOBREAK is specified and * the line is overrun, and don't pad-right if it's underrun. @@ -121,7 +120,12 @@ term_flushln(struct termp *p) * First, establish the maximum columns of "visible" content. * This is usually the difference between the right-margin and * an indentation, but can be, for tagged lists or columns, a - * small set of values. + * small set of values. + * + * The following unsigned-signed subtractions look strange, + * but they are actually correct. If the int p->overstep + * is negative, it gets sign extended. Subtracting that + * very large size_t effectively adds a small number to dv. */ assert (p->rmargin >= p->offset); dv = p->rmargin - p->offset; @@ -200,7 +204,11 @@ term_flushln(struct termp *p) if (0 < ntab) vbl += ntab * p->tabwidth; - /* Remove the p->overstep width. */ + /* + * Remove the p->overstep width. + * Again, if p->overstep is negative, + * sign extension does the right thing. + */ bp += (size_t)p->overstep; p->overstep = 0; @@ -269,15 +277,17 @@ term_flushln(struct termp *p) } if (TERMP_HANG & p->flags) { - /* We need one blank after the tag. */ - p->overstep = (int)(vis - maxvis + (*p->width)(p, ' ')); + p->overstep = (int)(vis - maxvis + + p->trailspace * (*p->width)(p, ' ')); /* * If we have overstepped the margin, temporarily move * it to the right and flag the rest of the line to be * shorter. + * If there is a request to keep the columns together, + * allow negative overstep when the column is not full. */ - if (p->overstep < 0) + if (p->trailspace && p->overstep < 0) p->overstep = 0; return; @@ -285,8 +295,7 @@ term_flushln(struct termp *p) return; /* If the column was overrun, break the line. */ - if (maxvis <= vis + - ((TERMP_TWOSPACE & p->flags) ? (*p->width)(p, ' ') : 0)) { + if (maxvis < vis + p->trailspace * (*p->width)(p, ' ')) { (*p->endline)(p); p->viscol = 0; } diff --git a/contrib/mdocml/term.h b/contrib/mdocml/term.h index 6aa9934e95..f49e86fd4f 100644 --- a/contrib/mdocml/term.h +++ b/contrib/mdocml/term.h @@ -1,6 +1,7 @@ -/* $Id: term.h,v 1.94 2013/08/21 21:20:40 schwarze Exp $ */ +/* $Id: term.h,v 1.95 2013/12/22 23:34:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2011, 2012, 2013 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -63,6 +64,7 @@ struct termp { size_t tabwidth; /* Distance of tab positions. */ size_t col; /* Bytes in buf. */ size_t viscol; /* Chars on current line. */ + size_t trailspace; /* See termp_flushln(). */ int overstep; /* See termp_flushln(). */ int skipvsp; /* Vertical space to skip. */ int flags; @@ -73,7 +75,6 @@ struct termp { #define TERMP_NONOSPACE (1 << 7) /* No space (no autounset). */ #define TERMP_DANGLE (1 << 8) /* See term_flushln(). */ #define TERMP_HANG (1 << 9) /* See term_flushln(). */ -#define TERMP_TWOSPACE (1 << 10) /* See term_flushln(). */ #define TERMP_NOSPLIT (1 << 11) /* See termp_an_pre/post(). */ #define TERMP_SPLIT (1 << 12) /* See termp_an_pre/post(). */ #define TERMP_ANPREC (1 << 13) /* See termp_an_pre(). */ -- 2.41.0