From d672f8cb82878baf3834e938c4c416f4493952cf Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Sat, 15 Dec 2018 19:30:25 +0000 Subject: Several improvements to escape sequence handling. * Add the missing special character \_ (underscore). * Partial implementations of \a (leader character) and \E (uninterpreted escape character). * Parse and ignore \r (reverse line feed). * Add a WARNING message about undefined escape sequences. * Add an UNSUPP message about unsupported escape sequences. * Mark \! and \? (transparent throughput) and \O (suppress output) as unsupported. * Treat the various variants of zero-width spaces as one-byte escape sequences rather than as special characters, to avoid defining bogus forms with square brackets. * For special characters with one-byte names, do not define bogus forms with square brackets, except for \[-], which is valid. * In the form with square brackets, undefined special characters do not fall back to printing the name verbatim, not even for one-byte names. * Starting a special character name with a blank is an error. * Undefined escape sequences never abort formatting of the input string, not even in HTML output mode. * Document the newly handled escapes, and a few that were missing. * Regression tests for most of the above. --- TODO | 12 +---- chars.c | 22 +++----- html.c | 10 ++-- mandoc.1 | 20 +++++-- mandoc.c | 96 +++++++++++++++++++++++++++------ mandoc.h | 6 ++- mandoc_char.7 | 12 +++-- mandoc_msg.c | 2 + mdoc_man.c | 3 +- mdoc_markdown.c | 5 +- regress/char/accent/Makefile | 1 + regress/char/accent/nocombine.in | 12 ++--- regress/char/accent/nocombine.out_ascii | 6 +-- regress/char/accent/nocombine.out_lint | 2 + regress/char/accent/nocombine.out_utf8 | 6 +-- regress/char/space/Makefile | 3 +- regress/char/space/esct-man.in | 14 ++++- regress/char/space/esct-man.out_ascii | 6 ++- regress/char/space/esct-man.out_lint | 10 ++-- regress/char/space/invalid.in | 15 ++++++ regress/char/space/invalid.out_ascii | 21 ++++++++ regress/char/space/invalid.out_lint | 9 ++++ regress/roff/esc/Makefile | 5 +- regress/roff/esc/O.in | 15 ++++++ regress/roff/esc/O.out_ascii | 21 ++++++++ regress/roff/esc/O.out_lint | 5 ++ regress/roff/esc/ignore.in | 18 +++---- regress/roff/esc/ignore.out_ascii | 19 ++++--- regress/roff/esc/ignore.out_lint | 5 +- regress/roff/esc/invalid.in | 28 ++++++++++ regress/roff/esc/invalid.out_ascii | 34 ++++++++++++ regress/roff/esc/invalid.out_lint | 43 +++++++++++++++ regress/roff/esc/one.in | 18 +++---- regress/roff/esc/one.out_ascii | 18 ++++--- regress/roff/esc/unsupp.in | 8 +++ regress/roff/esc/unsupp.out_ascii | 14 +++++ regress/roff/esc/unsupp.out_lint | 5 ++ roff.7 | 47 +++++++++++++++- roff.c | 49 +++++++++++------ term.c | 20 +++---- 40 files changed, 522 insertions(+), 143 deletions(-) create mode 100644 regress/char/accent/nocombine.out_lint create mode 100644 regress/char/space/invalid.in create mode 100644 regress/char/space/invalid.out_ascii create mode 100644 regress/char/space/invalid.out_lint create mode 100644 regress/roff/esc/O.in create mode 100644 regress/roff/esc/O.out_ascii create mode 100644 regress/roff/esc/O.out_lint create mode 100644 regress/roff/esc/invalid.in create mode 100644 regress/roff/esc/invalid.out_ascii create mode 100644 regress/roff/esc/invalid.out_lint create mode 100644 regress/roff/esc/unsupp.in create mode 100644 regress/roff/esc/unsupp.out_ascii create mode 100644 regress/roff/esc/unsupp.out_lint diff --git a/TODO b/TODO index f7b9dd4b..5b5ae6b5 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,6 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.280 2018/11/29 01:55:02 schwarze Exp $ +* $Id: TODO,v 1.281 2018/12/15 19:30:25 schwarze Exp $ ************************************************************************ Many issues are annotated for difficulty as follows: @@ -75,12 +75,6 @@ are mere guesses, and some may be wrong. Found by naddy@ in devel/cutils cobfusc(1) Mon, 16 Feb 2015 19:10:52 +0100 loc *** exist *** algo *** size ** imp * -- check for missing roff escape sequences, implement those that are - trivial even if not usually appearing in manual pages, gracefully - ignore the non-trivial ones, document what they are supposed to do - and what mandoc does instead - loc * exist ** algo * size * imp * - --- missing mdoc features ---------------------------------------------- - .Bl -column .Xo support is missing @@ -534,10 +528,6 @@ are mere guesses, and some may be wrong. output without intervening whitespace, in particular after a macro line (from the mdoclint TODO) -- mandoc_special does not really check the escape sequence, - but just the overall format - loc ** exist ** algo *** size ** imp ** - - makewhatis -p complains about language subdirectories: /usr/local/man//ru: Unknown directory part diff --git a/chars.c b/chars.c index 3ef273c1..24166dbd 100644 --- a/chars.c +++ b/chars.c @@ -1,7 +1,7 @@ -/* $Id: chars.c,v 1.77 2018/12/14 01:18:25 schwarze Exp $ */ +/* $Id: chars.c,v 1.78 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze + * Copyright (c) 2011,2014,2015,2017,2018 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 @@ -48,21 +48,13 @@ static struct ln lines[] = { { " ", ascii_nbrsp, 0x00a0 }, { "~", ascii_nbrsp, 0x00a0 }, { "0", " ", 0x2002 }, - { "|", "", 0 }, - { "^", "", 0 }, - { "&", "", 0 }, - { ")", "", 0 }, - { "%", "", 0 }, { ":", ascii_break, 0 }, - /* XXX The following three do not really belong here. */ - { "t", "", 0 }, - { "c", "", 0 }, - { "}", "", 0 }, /* Lines. */ { "ba", "|", 0x007c }, { "br", "|", 0x2502 }, { "ul", "_", 0x005f }, + { "_", "_", 0x005f }, { "ru", "_", 0x005f }, { "rn", "-", 0x203e }, { "bb", "|", 0x00a6 }, @@ -465,7 +457,7 @@ mchars_spec2cp(const char *p, size_t sz) end = p + sz; ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end)); - return ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1; + return ln != NULL ? ln->unicode : -1; } int @@ -495,10 +487,8 @@ mchars_spec2str(const char *p, size_t sz, size_t *rsz) end = p + sz; ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end)); - if (ln == NULL) { - *rsz = 1; - return sz == 1 ? p : NULL; - } + if (ln == NULL) + return NULL; *rsz = strlen(ln->ascii); return ln->ascii; diff --git a/html.c b/html.c index ce90dfbd..da381a47 100644 --- a/html.c +++ b/html.c @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.245 2018/12/04 18:29:38 schwarze Exp $ */ +/* $Id: html.c,v 1.246 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze @@ -402,9 +402,6 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse) continue; esc = mandoc_escape(&p, &seq, &len); - if (ESCAPE_ERROR == esc) - break; - switch (esc) { case ESCAPE_FONT: case ESCAPE_FONTPREV: @@ -422,6 +419,8 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse) case ESCAPE_SKIPCHAR: h->flags |= HTML_SKIPCHAR; continue; + case ESCAPE_ERROR: + continue; default: break; } @@ -446,6 +445,9 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse) if (c <= 0) continue; break; + case ESCAPE_UNDEF: + c = *seq; + break; case ESCAPE_DEVICE: print_word(h, "html"); continue; diff --git a/mandoc.1 b/mandoc.1 index 24000357..bea806b4 100644 --- a/mandoc.1 +++ b/mandoc.1 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.1,v 1.231 2018/11/22 11:30:23 schwarze Exp $ +.\" $Id: mandoc.1,v 1.232 2018/12/15 19:30:26 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2012, 2014-2018 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: November 22 2018 $ +.Dd $Mdocdate: December 15 2018 $ .Dt MANDOC 1 .Os .Sh NAME @@ -1676,7 +1676,8 @@ Start it on a new input line to help formatters produce correct spacing. .It Sy "invalid escape sequence" .Pq roff An escape sequence has an invalid opening argument delimiter, lacks the -closing argument delimiter, or the argument has too few characters. +closing argument delimiter, the argument is of an invalid form, or it is +a character escape sequence with an invalid name. If the argument is incomplete, .Ic \e* and @@ -1689,6 +1690,12 @@ and .Ic \ew to the length of the incomplete argument. All other invalid escape sequences are ignored. +.It Sy "undefined escape, printing literally" +.Pq roff +In an escape sequence, the first character +right after the leading backslash is invalid. +That character is printed literally, +which is equivalent to ignoring the backslash. .It Sy "undefined string, using \(dq\(dq" .Pq roff If a string is used without being defined before, @@ -2154,6 +2161,13 @@ implementations but not by .Nm was found in an input file. It is replaced by a question mark. +.It Sy "unsupported escape sequence" +.Pq roff +An input file contains an escape sequence supported by GNU troff +or Heirloom troff but not by +.Nm , +and it is likely that this will cause information loss +or considerable misformatting. .It Sy "unsupported roff request" .Pq roff An input file contains a diff --git a/mandoc.c b/mandoc.c index 2957b7c0..50882ba0 100644 --- a/mandoc.c +++ b/mandoc.c @@ -1,4 +1,4 @@ -/* $Id: mandoc.c,v 1.110 2018/12/14 06:33:14 schwarze Exp $ */ +/* $Id: mandoc.c,v 1.111 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze @@ -55,6 +55,14 @@ mandoc_escape(const char **end, const char **start, int *sz) if (NULL == sz) sz = &local_sz; + /* + * Treat "\E" just like "\"; + * it only makes a difference in copy mode. + */ + + if (**end == 'E') + ++*end; + /* * Beyond the backslash, at least one input character * is part of the escape sequence. With one exception @@ -77,6 +85,10 @@ mandoc_escape(const char **end, const char **start, int *sz) *sz = 2; break; case '[': + if (**start == ' ') { + ++*end; + return ESCAPE_ERROR; + } gly = ESCAPE_SPECIAL; term = ']'; break; @@ -91,11 +103,26 @@ mandoc_escape(const char **end, const char **start, int *sz) /* * Escapes taking no arguments at all. */ - case 'd': - case 'u': + case '!': + case '?': + return ESCAPE_UNSUPP; + case '%': + case '&': + case ')': case ',': case '/': + case '^': + case 'a': + case 'd': + case 'r': + case 't': + case 'u': + case '{': + case '|': + case '}': return ESCAPE_IGNORE; + case 'c': + return ESCAPE_NOSPACE; case 'p': return ESCAPE_BREAK; @@ -113,28 +140,46 @@ mandoc_escape(const char **end, const char **start, int *sz) * 'X' is the trigger. These have opaque sub-strings. */ case 'F': + case 'f': case 'g': case 'k': case 'M': case 'm': case 'n': + case 'O': case 'V': case 'Y': - gly = ESCAPE_IGNORE; - /* FALLTHROUGH */ - case 'f': - if (ESCAPE_ERROR == gly) - gly = ESCAPE_FONT; + gly = (*start)[-1] == 'f' ? ESCAPE_FONT : ESCAPE_IGNORE; switch (**start) { case '(': + if ((*start)[-1] == 'O') + gly = ESCAPE_ERROR; *start = ++*end; *sz = 2; break; case '[': + if ((*start)[-1] == 'O') + gly = (*start)[1] == '5' ? + ESCAPE_UNSUPP : ESCAPE_ERROR; *start = ++*end; term = ']'; break; default: + if ((*start)[-1] == 'O') { + switch (**start) { + case '0': + gly = ESCAPE_UNSUPP; + break; + case '1': + case '2': + case '3': + case '4': + break; + default: + gly = ESCAPE_ERROR; + break; + } + } *sz = 1; break; } @@ -257,18 +302,29 @@ mandoc_escape(const char **end, const char **start, int *sz) break; /* - * Anything else is assumed to be a glyph. - * In this case, pass back the character after the backslash. + * Several special characters can be encoded as + * one-byte escape sequences without using \[]. */ - default: + case ' ': + case '\'': + case '-': + case '.': + case '0': + case ':': + case '_': + case '`': + case 'e': + case '~': gly = ESCAPE_SPECIAL; + /* FALLTHROUGH */ + default: + if (gly == ESCAPE_ERROR) + gly = ESCAPE_UNDEF; *start = --*end; *sz = 1; break; } - assert(ESCAPE_ERROR != gly); - /* * Read up to the terminating character, * paying attention to nested escapes. @@ -291,6 +347,15 @@ mandoc_escape(const char **end, const char **start, int *sz) } } *sz = (*end)++ - *start; + + /* + * The file chars.c only provides one common list + * of character names, but \[-] == \- is the only + * one of the characters with one-byte names that + * allows enclosing the name in brackets. + */ + if (gly == ESCAPE_SPECIAL && *sz == 1 && **start != '-') + return ESCAPE_ERROR; } else { assert(*sz > 0); if ((size_t)*sz > strlen(*start)) @@ -346,10 +411,6 @@ mandoc_escape(const char **end, const char **start, int *sz) break; case ESCAPE_SPECIAL: if (**start == 'c') { - if (*sz == 1) { - gly = ESCAPE_NOSPACE; - break; - } if (*sz < 6 || *sz > 7 || strncmp(*start, "char", 4) != 0 || (int)strspn(*start + 4, "0123456789") + 4 < *sz) @@ -431,6 +492,7 @@ mandoc_getarg(char **cpp, int ln, int *pos) * backslashes and backslash-t to literal tabs. */ switch (cp[1]) { + case 'a': case 't': cp[0] = '\t'; /* FALLTHROUGH */ diff --git a/mandoc.h b/mandoc.h index 6a2f1f30..0519d041 100644 --- a/mandoc.h +++ b/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.260 2018/12/14 05:18:02 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.261 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons * Copyright (c) 2012-2018 Ingo Schwarze @@ -169,6 +169,7 @@ enum mandocerr { MANDOCERR_FI_TAB, /* tab in filled text */ MANDOCERR_EOS, /* new sentence, new line */ MANDOCERR_ESC_BAD, /* invalid escape sequence: esc */ + MANDOCERR_ESC_UNDEF, /* undefined escape, printing literally: char */ MANDOCERR_STR_UNDEF, /* undefined string, using "": name */ /* related to tables */ @@ -231,6 +232,7 @@ enum mandocerr { MANDOCERR_TOOLARGE, /* input too large */ MANDOCERR_CHAR_UNSUPP, /* unsupported control character: number */ + MANDOCERR_ESC_UNSUPP, /* unsupported escape sequence: escape */ MANDOCERR_REQ_UNSUPP, /* unsupported roff request: request */ MANDOCERR_WHILE_NEST, /* nested .while loops */ MANDOCERR_WHILE_OUTOF, /* end of scope with open .while loop */ @@ -245,7 +247,9 @@ enum mandocerr { enum mandoc_esc { ESCAPE_ERROR = 0, /* bail! unparsable escape */ + ESCAPE_UNSUPP, /* unsupported escape; ignore it */ ESCAPE_IGNORE, /* escape to be ignored */ + ESCAPE_UNDEF, /* undefined escape; print literal character */ ESCAPE_SPECIAL, /* a regular special character */ ESCAPE_FONT, /* a generic font mode */ ESCAPE_FONTBOLD, /* bold font mode */ diff --git a/mandoc_char.7 b/mandoc_char.7 index 8fe71b0c..578f37f1 100644 --- a/mandoc_char.7 +++ b/mandoc_char.7 @@ -1,8 +1,8 @@ -.\" $Id: mandoc_char.7,v 1.74 2018/08/21 01:59:22 schwarze Exp $ +.\" $Id: mandoc_char.7,v 1.75 2018/12/15 19:30:26 schwarze Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons -.\" Copyright (c) 2011, 2013, 2015, 2017 Ingo Schwarze +.\" Copyright (c) 2011,2013,2015,2017,2018 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 @@ -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: August 21 2018 $ +.Dd $Mdocdate: December 15 2018 $ .Dt MANDOC_CHAR 7 .Os .Sh NAME @@ -266,11 +266,13 @@ Spacing: .It Em Input Ta Em Description .It Sq \e\ \& Ta unpaddable non-breaking space .It \e\(ti Ta paddable non-breaking space -.It \e0 Ta unpaddable, breaking digit-width space +.It \e0 Ta digit-width space allowing line break .It \e| Ta one-sixth \e(em narrow space, zero width in nroff mode .It \e^ Ta one-twelfth \e(em half-narrow space, zero width in nroff -.It \e& Ta zero-width space +.It \e& Ta zero-width non-breaking space +.It \e) Ta zero-width space transparent to end-of-sentence detection .It \e% Ta zero-width space allowing hyphenation +.It \e: Ta zero-width space allowing line break .El .Pp Lines: diff --git a/mandoc_msg.c b/mandoc_msg.c index d2ccb91f..b49555d1 100644 --- a/mandoc_msg.c +++ b/mandoc_msg.c @@ -167,6 +167,7 @@ static const char *const type_message[MANDOCERR_MAX] = { "tab in filled text", "new sentence, new line", "invalid escape sequence", + "undefined escape, printing literally", "undefined string, using \"\"", /* related to tables */ @@ -228,6 +229,7 @@ static const char *const type_message[MANDOCERR_MAX] = { "unsupported feature", "input too large", "unsupported control character", + "unsupported escape sequence", "unsupported roff request", "nested .while loops", "end of scope with open .while loop", diff --git a/mdoc_man.c b/mdoc_man.c index f3689dfc..c4e0be79 100644 --- a/mdoc_man.c +++ b/mdoc_man.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_man.c,v 1.129 2018/12/03 21:00:10 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.130 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2011-2018 Ingo Schwarze * @@ -325,6 +325,7 @@ man_strlen(const char *cp) case ESCAPE_UNICODE: case ESCAPE_NUMBERED: case ESCAPE_SPECIAL: + case ESCAPE_UNDEF: case ESCAPE_OVERSTRIKE: if (skip) skip = 0; diff --git a/mdoc_markdown.c b/mdoc_markdown.c index fcc63638..35bae5bc 100644 --- a/mdoc_markdown.c +++ b/mdoc_markdown.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_markdown.c,v 1.28 2018/12/03 21:00:10 schwarze Exp $ */ +/* $Id: mdoc_markdown.c,v 1.29 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2017, 2018 Ingo Schwarze * @@ -589,6 +589,9 @@ md_word(const char *s) case ESCAPE_SPECIAL: uc = mchars_spec2cp(seq, sz); break; + case ESCAPE_UNDEF: + uc = *seq; + break; case ESCAPE_DEVICE: md_rawword("markdown"); continue; diff --git a/regress/char/accent/Makefile b/regress/char/accent/Makefile index 4bc149a7..3712217e 100644 --- a/regress/char/accent/Makefile +++ b/regress/char/accent/Makefile @@ -3,5 +3,6 @@ REGRESS_TARGETS = nocombine utf8only combine SKIP_ASCII = utf8only combine UTF8_TARGETS = nocombine utf8only combine +LINT_TARGETS = nocombine .include diff --git a/regress/char/accent/nocombine.in b/regress/char/accent/nocombine.in index a81d446b..637d337e 100644 --- a/regress/char/accent/nocombine.in +++ b/regress/char/accent/nocombine.in @@ -1,17 +1,17 @@ .\" $OpenBSD: nocombine.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $ -.TH CHAR-ACCENT-NOCOMBINE 1 "March 8, 2014" +.TH CHAR-ACCENT-NOCOMBINE 1 "December 15, 2018" .SH NAME \fBchar-accent-nocombine\fR - non-combining accents .SH DESCRIPTION bare acute accent: e'e .br -escaped acute accent: e\'e +escaped acute accent: e\'e\[']e .br acute accent sequence: e\(aae .br bare grave accent: e`e .br -escaped grave accent: e\`e +escaped grave accent: e\`e\[`]e .br acute grave sequence: e\(gae .br @@ -20,15 +20,15 @@ hungarian umlaut: e\(a"e .\" XXX This is ridiculous. .\" XXX groff prints the macron as an underscore in the previous line. .\" macron: e\(a-e -.br +.\" .br .\" XXX groff doesn't have a dot in ASCII mode, only in UTF-8 mode. .\" dotted: e\(a.e -.br +.\" .br circumflex: e\(a^e .br .\" XXX groff uses a backspace for this one in ASCII mode. .\" breve: e\(abe -.br +.\" .br cedilla: e\(ace .br dieresis: e\(ade diff --git a/regress/char/accent/nocombine.out_ascii b/regress/char/accent/nocombine.out_ascii index bc1cce15..0f18ac4a 100644 --- a/regress/char/accent/nocombine.out_ascii +++ b/regress/char/accent/nocombine.out_ascii @@ -7,10 +7,10 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN bare acute accent: e'e - escaped acute accent: e'e + escaped acute accent: e'ee acute accent sequence: e'e bare grave accent: e`e - escaped grave accent: e`e + escaped grave accent: e`ee acute grave sequence: e`e hungarian umlaut: e"e circumflex: e^e @@ -25,4 +25,4 @@ DDEESSCCRRIIPPTTIIOONN -OpenBSD March 8, 2014 CHAR-ACCENT-NOCOMBINE(1) +OpenBSD December 15, 2018 CHAR-ACCENT-NOCOMBINE(1) diff --git a/regress/char/accent/nocombine.out_lint b/regress/char/accent/nocombine.out_lint new file mode 100644 index 00000000..c9de4162 --- /dev/null +++ b/regress/char/accent/nocombine.out_lint @@ -0,0 +1,2 @@ +mandoc: nocombine.in:8:27: WARNING: invalid escape sequence: \['] +mandoc: nocombine.in:14:27: WARNING: invalid escape sequence: \[`] diff --git a/regress/char/accent/nocombine.out_utf8 b/regress/char/accent/nocombine.out_utf8 index 3aa441a2..497bf6fd 100644 --- a/regress/char/accent/nocombine.out_utf8 +++ b/regress/char/accent/nocombine.out_utf8 @@ -7,10 +7,10 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN bare acute accent: e'e - escaped acute accent: e´e + escaped acute accent: e´ee acute accent sequence: e´e bare grave accent: e`e - escaped grave accent: e`e + escaped grave accent: e`ee acute grave sequence: e`e hungarian umlaut: e˝e circumflex: e^e @@ -25,4 +25,4 @@ DDEESSCCRRIIPPTTIIOONN -OpenBSD March 8, 2014 CHAR-ACCENT-NOCOMBINE(1) +OpenBSD December 15, 2018 CHAR-ACCENT-NOCOMBINE(1) diff --git a/regress/char/space/Makefile b/regress/char/space/Makefile index b6095de3..50c81c4a 100644 --- a/regress/char/space/Makefile +++ b/regress/char/space/Makefile @@ -3,11 +3,12 @@ REGRESS_TARGETS = leading-mdoc leading-man multiple trailing-mdoc zerowidth REGRESS_TARGETS += eos eos-man break nobreak REGRESS_TARGETS += tab tab-man esct-mdoc esct-man +REGRESS_TARGETS += invalid UTF8_TARGETS = zerowidth HTML_TARGETS = zerowidth -LINT_TARGETS = trailing-mdoc tab tab-man esct-mdoc esct-man +LINT_TARGETS = trailing-mdoc tab tab-man esct-mdoc esct-man invalid .include diff --git a/regress/char/space/esct-man.in b/regress/char/space/esct-man.in index e7afeefe..f290d9e2 100644 --- a/regress/char/space/esct-man.in +++ b/regress/char/space/esct-man.in @@ -1,5 +1,5 @@ .\" $OpenBSD: esct-man.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $ -.TH SPACE-ESCT-MAN 1 2013-06-20 +.TH SPACE-ESCT-MAN 1 "December 15, 2018" .SH NAME SPACE-T-MAN \- the t escape sequence in pages with man macros .SH DESCRIPTION @@ -9,10 +9,14 @@ single tab .br single\tescape-t .br +single\aescape-a +.br double tab .br double\t\tescape-t .br +double\a\aescape-a +.br \tThis line starts with escape-t and comes close to the right margin. \tThe next line starts with escape-t as well. .sp @@ -20,8 +24,10 @@ In a literal display: .nf single tab single\tescape-t +single\aescape-a double tab double\t\tescape-t +double\a\aescape-a .fi .sp After the IP macro: @@ -29,7 +35,13 @@ After the IP macro: text .IP single\tescape-t 3n text +.\" XXX not implemented +.\" .IP single\aescape-a 3n +.\" text .PP After font macros: .br .B single\ttab +.\" XXX not implemented +.\" .br +.\" .B single\aleader diff --git a/regress/char/space/esct-man.out_ascii b/regress/char/space/esct-man.out_ascii index 29fbabea..3056cc72 100644 --- a/regress/char/space/esct-man.out_ascii +++ b/regress/char/space/esct-man.out_ascii @@ -9,16 +9,20 @@ DDEESSCCRRIIPPTTIIOONN In plain text: single tab singleescape-t + singleescape-a double tab doubleescape-t + doubleescape-a This line starts with escape-t and comes close to the right margin. The next line starts with escape-t as well. In a literal display: single tab singleescape-t + singleescape-a double tab doubleescape-t + doubleescape-a After the IP macro: @@ -33,4 +37,4 @@ DDEESSCCRRIIPPTTIIOONN -OpenBSD 2013-06-20 SPACE-ESCT-MAN(1) +OpenBSD December 15, 2018 SPACE-ESCT-MAN(1) diff --git a/regress/char/space/esct-man.out_lint b/regress/char/space/esct-man.out_lint index c625b3a3..2fa8ba9c 100644 --- a/regress/char/space/esct-man.out_lint +++ b/regress/char/space/esct-man.out_lint @@ -1,6 +1,6 @@ mandoc: esct-man.in:8:7: WARNING: tab in filled text -mandoc: esct-man.in:12:7: WARNING: tab in filled text -mandoc: esct-man.in:12:8: WARNING: tab in filled text -mandoc: esct-man.in:28:11: WARNING: tab in filled text -mandoc: esct-man.in:30:11: WARNING: tab in filled text -mandoc: esct-man.in:35:10: WARNING: tab in filled text +mandoc: esct-man.in:14:7: WARNING: tab in filled text +mandoc: esct-man.in:14:8: WARNING: tab in filled text +mandoc: esct-man.in:34:11: WARNING: tab in filled text +mandoc: esct-man.in:36:11: WARNING: tab in filled text +mandoc: esct-man.in:44:10: WARNING: tab in filled text diff --git a/regress/char/space/invalid.in b/regress/char/space/invalid.in new file mode 100644 index 00000000..c4692453 --- /dev/null +++ b/regress/char/space/invalid.in @@ -0,0 +1,15 @@ +.\" $OpenBSD$ +.TH SPACE-INVALID 1 "December 15, 2018" +.SH NAME +SPACE-INVALID \- invalid whitespace escape sequences +.SH DESCRIPTION +.nf +blank: a\[hy]b\[ hy]c +percent: a\%b\[%]c +ampersand: a\&b\[&]c +colon: a\:b\[:]c +caret: a\^b\[^]c +underline: a\_b\[_]c +pipe: a\|b\[|]c +tilde: a\~b\[~]c +digit-width: a\0b\[0]c diff --git a/regress/char/space/invalid.out_ascii b/regress/char/space/invalid.out_ascii new file mode 100644 index 00000000..bf3b5a16 --- /dev/null +++ b/regress/char/space/invalid.out_ascii @@ -0,0 +1,21 @@ +SPACE-INVALID(1) General Commands Manual SPACE-INVALID(1) + + + +NNAAMMEE + SPACE-INVALID - invalid whitespace escape sequences + +DDEESSCCRRIIPPTTIIOONN + blank: a-bhy]c + percent: abc + ampersand: abc + colon: abc + caret: abc + underline: a_bc + pipe: abc + tilde: a bc + digit-width: a bc + + + +OpenBSD December 15, 2018 SPACE-INVALID(1) diff --git a/regress/char/space/invalid.out_lint b/regress/char/space/invalid.out_lint new file mode 100644 index 00000000..c05ef38f --- /dev/null +++ b/regress/char/space/invalid.out_lint @@ -0,0 +1,9 @@ +mandoc: invalid.in:7:15: WARNING: invalid escape sequence: \[ +mandoc: invalid.in:8:14: WARNING: invalid escape sequence: \[%] +mandoc: invalid.in:9:16: WARNING: invalid escape sequence: \[&] +mandoc: invalid.in:10:12: WARNING: invalid escape sequence: \[:] +mandoc: invalid.in:11:12: WARNING: invalid escape sequence: \[^] +mandoc: invalid.in:12:16: WARNING: invalid escape sequence: \[_] +mandoc: invalid.in:13:11: WARNING: invalid escape sequence: \[|] +mandoc: invalid.in:14:12: WARNING: invalid escape sequence: \[~] +mandoc: invalid.in:15:18: WARNING: invalid escape sequence: \[0] diff --git a/regress/roff/esc/Makefile b/regress/roff/esc/Makefile index 32589479..74f153d5 100644 --- a/regress/roff/esc/Makefile +++ b/regress/roff/esc/Makefile @@ -1,6 +1,7 @@ # $OpenBSD: Makefile,v 1.11 2015/04/29 18:32:57 schwarze Exp $ -REGRESS_TARGETS = one two multi B c c_man e f h l o p w z ignore -LINT_TARGETS = B h l w ignore +REGRESS_TARGETS = one two multi B c c_man e f h l O o p w z +REGRESS_TARGETS += ignore invalid unsupp +LINT_TARGETS = B h l O w ignore invalid unsupp .include diff --git a/regress/roff/esc/O.in b/regress/roff/esc/O.in new file mode 100644 index 00000000..d446ebb6 --- /dev/null +++ b/regress/roff/esc/O.in @@ -0,0 +1,15 @@ +.\" $OpenBSD$ +.TH ESC-O 1 "December 15, 2018" +.SH NAME +esc-O \- escape sequence to suppress output +.SH DESCRIPTION +.nf +O1: a\O1b +O2: a\O2b +O3: a\O3b +O4: a\O4b +O5: a\O5b +O52: a\O(52b +O5n: a\O[5dummy]b +O6: a\O6b +O0: a\O0\&\O1b diff --git a/regress/roff/esc/O.out_ascii b/regress/roff/esc/O.out_ascii new file mode 100644 index 00000000..d2e5668c --- /dev/null +++ b/regress/roff/esc/O.out_ascii @@ -0,0 +1,21 @@ +ESC-O(1) General Commands Manual ESC-O(1) + + + +NNAAMMEE + esc-O - escape sequence to suppress output + +DDEESSCCRRIIPPTTIIOONN + O1: ab + O2: ab + O3: ab + O4: ab + O5: ab + O52: ab + O5n: ab + O6: ab + O0: ab + + + +OpenBSD December 15, 2018 ESC-O(1) diff --git a/regress/roff/esc/O.out_lint b/regress/roff/esc/O.out_lint new file mode 100644 index 00000000..ee91008d --- /dev/null +++ b/regress/roff/esc/O.out_lint @@ -0,0 +1,5 @@ +mandoc: O.in:11:6: WARNING: invalid escape sequence: \O5 +mandoc: O.in:12:7: WARNING: invalid escape sequence: \O(52 +mandoc: O.in:13:7: UNSUPP: unsupported escape sequence: \O[5dummy] +mandoc: O.in:14:6: WARNING: invalid escape sequence: \O6 +mandoc: O.in:15:6: UNSUPP: unsupported escape sequence: \O0 diff --git a/regress/roff/esc/ignore.in b/regress/roff/esc/ignore.in index d41be2e1..48507f44 100644 --- a/regress/roff/esc/ignore.in +++ b/regress/roff/esc/ignore.in @@ -1,15 +1,13 @@ .\" $OpenBSD: ignore.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $ -.Dd $Mdocdate: July 4 2017 $ -.Dt ESC-IGNORE 1 -.Os -.Sh NAME -.Nm esc-ignore -.Nd ignored roff escape sequences -.Sh DESCRIPTION +.TH ESC-IGNORE 1 "December 15, 2018" +.SH NAME +esc-ignore \- ignored roff escape sequences +.SH DESCRIPTION +.nf +closing parenthesis: a\)b\[)]c +comma: a\,b\[,]c +slash: a\/b\[/]c multiform: a\kxb\k(xyc\k[xyz]d -.br quoted: a\R'myreg 0'b\R'myreg \A'y'0'c -.br sizes: a\s0b\s(12c\s[123]d\s'123'e\s'1\w'xy'2'f -.br signed sizes: a\s-0b\s-(12c\s-[123]d\s-'123'e\s-'1\w'xy'2'f\s- diff --git a/regress/roff/esc/ignore.out_ascii b/regress/roff/esc/ignore.out_ascii index fa16f389..eaee36c0 100644 --- a/regress/roff/esc/ignore.out_ascii +++ b/regress/roff/esc/ignore.out_ascii @@ -1,12 +1,19 @@ ESC-IGNORE(1) General Commands Manual ESC-IGNORE(1) + + NNAAMMEE - eesscc--iiggnnoorree - ignored roff escape sequences + esc-ignore - ignored roff escape sequences DDEESSCCRRIIPPTTIIOONN - multiform: abcd - quoted: abc - sizes: abcdef - signed sizes: abcdef + closing parenthesis: abc + comma: abc + slash: abc + multiform: abcd + quoted: abc + sizes: abcdef + signed sizes: abcdef + + -OpenBSD July 4, 2017 OpenBSD +OpenBSD December 15, 2018 ESC-IGNORE(1) diff --git a/regress/roff/esc/ignore.out_lint b/regress/roff/esc/ignore.out_lint index 95eba933..0f33c929 100644 --- a/regress/roff/esc/ignore.out_lint +++ b/regress/roff/esc/ignore.out_lint @@ -1 +1,4 @@ -mandoc: ignore.in:15:60: WARNING: invalid escape sequence: \s- +mandoc: ignore.in:7:26: WARNING: invalid escape sequence: \[)] +mandoc: ignore.in:8:12: WARNING: invalid escape sequence: \[,] +mandoc: ignore.in:9:12: WARNING: invalid escape sequence: \[/] +mandoc: ignore.in:13:60: WARNING: invalid escape sequence: \s- diff --git a/regress/roff/esc/invalid.in b/regress/roff/esc/invalid.in new file mode 100644 index 00000000..b2e77159 --- /dev/null +++ b/regress/roff/esc/invalid.in @@ -0,0 +1,28 @@ +.\" $OpenBSD$ +.TH ESC-INVALID 1 "December 15, 2018" +.SH NAME +esc-invalid \- invalid roff escape sequences +.SH DESCRIPTION +.nf +plus: a\+b\[+]c +semicolon: a\;b\[;]c +less than: a\b\[>]c +at: a\@b\[@]c +square bracket: a\]b +curly braces: a\[{]b\[}]c +digit: a\1b\[1]c +G: a\Gb\[G]c +I: a\Ib\[I]c +i: a\ib\[i]c +J: a\Jb\[J]c +j: a\jb\[j]c +K: a\Kb\[K]c +P: a\Pb\[P]c +Q: a\Qb\[Q]c +q: a\qb\[q]c +T: a\Tb\[T]c +U: a\Ub\[U]c +W: a\Wb\[W]c +y: a\yb\[y]c diff --git a/regress/roff/esc/invalid.out_ascii b/regress/roff/esc/invalid.out_ascii new file mode 100644 index 00000000..24915262 --- /dev/null +++ b/regress/roff/esc/invalid.out_ascii @@ -0,0 +1,34 @@ +ESC-INVALID(1) General Commands Manual ESC-INVALID(1) + + + +NNAAMMEE + esc-invalid - invalid roff escape sequences + +DDEESSCCRRIIPPTTIIOONN + plus: a+bc + semicolon: a;bc + less than: abc + at: a@bc + square bracket: a]b + curly braces: abc + digit: a1bc + G: aGbc + I: aIbc + i: aibc + J: aJbc + j: ajbc + K: aKbc + P: aPbc + Q: aQbc + q: aqbc + T: aTbc + U: aUbc + W: aWbc + y: aybc + + + +OpenBSD December 15, 2018 ESC-INVALID(1) diff --git a/regress/roff/esc/invalid.out_lint b/regress/roff/esc/invalid.out_lint new file mode 100644 index 00000000..a0afa7ae --- /dev/null +++ b/regress/roff/esc/invalid.out_lint @@ -0,0 +1,43 @@ +mandoc: invalid.in:7:11: WARNING: invalid escape sequence: \[+] +mandoc: invalid.in:7:8: WARNING: undefined escape, printing literally: \+ +mandoc: invalid.in:8:16: WARNING: invalid escape sequence: \[;] +mandoc: invalid.in:8:13: WARNING: undefined escape, printing literally: \; +mandoc: invalid.in:9:16: WARNING: invalid escape sequence: \[<] +mandoc: invalid.in:9:13: WARNING: undefined escape, printing literally: \< +mandoc: invalid.in:10:15: WARNING: invalid escape sequence: \[=] +mandoc: invalid.in:10:12: WARNING: undefined escape, printing literally: \= +mandoc: invalid.in:11:19: WARNING: invalid escape sequence: \[>] +mandoc: invalid.in:11:16: WARNING: undefined escape, printing literally: \> +mandoc: invalid.in:12:9: WARNING: invalid escape sequence: \[@] +mandoc: invalid.in:12:6: WARNING: undefined escape, printing literally: \@ +mandoc: invalid.in:13:18: WARNING: undefined escape, printing literally: \] +mandoc: invalid.in:14:21: WARNING: invalid escape sequence: \[}] +mandoc: invalid.in:14:16: WARNING: invalid escape sequence: \[{] +mandoc: invalid.in:15:12: WARNING: invalid escape sequence: \[1] +mandoc: invalid.in:15:9: WARNING: undefined escape, printing literally: \1 +mandoc: invalid.in:16:8: WARNING: invalid escape sequence: \[G] +mandoc: invalid.in:16:5: WARNING: undefined escape, printing literally: \G +mandoc: invalid.in:17:8: WARNING: invalid escape sequence: \[I] +mandoc: invalid.in:17:5: WARNING: undefined escape, printing literally: \I +mandoc: invalid.in:18:8: WARNING: invalid escape sequence: \[i] +mandoc: invalid.in:18:5: WARNING: undefined escape, printing literally: \i +mandoc: invalid.in:19:8: WARNING: invalid escape sequence: \[J] +mandoc: invalid.in:19:5: WARNING: undefined escape, printing literally: \J +mandoc: invalid.in:20:8: WARNING: invalid escape sequence: \[j] +mandoc: invalid.in:20:5: WARNING: undefined escape, printing literally: \j +mandoc: invalid.in:21:8: WARNING: invalid escape sequence: \[K] +mandoc: invalid.in:21:5: WARNING: undefined escape, printing literally: \K +mandoc: invalid.in:22:8: WARNING: invalid escape sequence: \[P] +mandoc: invalid.in:22:5: WARNING: undefined escape, printing literally: \P +mandoc: invalid.in:23:8: WARNING: invalid escape sequence: \[Q] +mandoc: invalid.in:23:5: WARNING: undefined escape, printing literally: \Q +mandoc: invalid.in:24:8: WARNING: invalid escape sequence: \[q] +mandoc: invalid.in:24:5: WARNING: undefined escape, printing literally: \q +mandoc: invalid.in:25:8: WARNING: invalid escape sequence: \[T] +mandoc: invalid.in:25:5: WARNING: undefined escape, printing literally: \T +mandoc: invalid.in:26:8: WARNING: invalid escape sequence: \[U] +mandoc: invalid.in:26:5: WARNING: undefined escape, printing literally: \U +mandoc: invalid.in:27:8: WARNING: invalid escape sequence: \[W] +mandoc: invalid.in:27:5: WARNING: undefined escape, printing literally: \W +mandoc: invalid.in:28:8: WARNING: invalid escape sequence: \[y] +mandoc: invalid.in:28:5: WARNING: undefined escape, printing literally: \y diff --git a/regress/roff/esc/one.in b/regress/roff/esc/one.in index 6edf9f64..6a4b22a8 100644 --- a/regress/roff/esc/one.in +++ b/regress/roff/esc/one.in @@ -1,17 +1,11 @@ .\" $OpenBSD: one.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $ -.Dd $Mdocdate: July 4 2017 $ -.Dt ESC-ONE 1 -.Os -.Sh NAME -.Nm esc-one -.Nd roff one-character escape sequences -.Sh DESCRIPTION +.TH ESC-ONE 1 "December 15, 2018" +.SH NAME +esc-one \- roff one-character escape sequences +.SH DESCRIPTION +.nf backslash: >\e< -.br -minus: >\-< -.br +minus: >\-|\[-]< acute: >\'< -.br grave: >\`< -.br normal character: >\q< diff --git a/regress/roff/esc/one.out_ascii b/regress/roff/esc/one.out_ascii index bc88dcf2..1eb5f1f2 100644 --- a/regress/roff/esc/one.out_ascii +++ b/regress/roff/esc/one.out_ascii @@ -1,13 +1,17 @@ ESC-ONE(1) General Commands Manual ESC-ONE(1) + + NNAAMMEE - eesscc--oonnee - roff one-character escape sequences + esc-one - roff one-character escape sequences DDEESSCCRRIIPPTTIIOONN - backslash: >\< - minus: >-< - acute: >'< - grave: >`< - normal character: >q< + backslash: >\< + minus: >-|-< + acute: >'< + grave: >`< + normal character: >q< + + -OpenBSD July 4, 2017 OpenBSD +OpenBSD December 15, 2018 ESC-ONE(1) diff --git a/regress/roff/esc/unsupp.in b/regress/roff/esc/unsupp.in new file mode 100644 index 00000000..819f6c33 --- /dev/null +++ b/regress/roff/esc/unsupp.in @@ -0,0 +1,8 @@ +.\" $OpenBSD$ +.TH ESC-UNSUPP 1 "December 15, 2018" +.SH NAME +esc-unsupp \- unsupported escape sequences +.SH DESCRIPTION +.nf +exclamation mark: a\!b\[!]c +question mark: a\?\&\?b\[?]c diff --git a/regress/roff/esc/unsupp.out_ascii b/regress/roff/esc/unsupp.out_ascii new file mode 100644 index 00000000..22613e54 --- /dev/null +++ b/regress/roff/esc/unsupp.out_ascii @@ -0,0 +1,14 @@ +ESC-UNSUPP(1) General Commands Manual ESC-UNSUPP(1) + + + +NNAAMMEE + esc-unsupp - unsupported escape sequences + +DDEESSCCRRIIPPTTIIOONN + exclamation mark: abc + question mark: abc + + + +OpenBSD December 15, 2018 ESC-UNSUPP(1) diff --git a/regress/roff/esc/unsupp.out_lint b/regress/roff/esc/unsupp.out_lint new file mode 100644 index 00000000..d3cc4bf1 --- /dev/null +++ b/regress/roff/esc/unsupp.out_lint @@ -0,0 +1,5 @@ +mandoc: unsupp.in:7:23: WARNING: invalid escape sequence: \[!] +mandoc: unsupp.in:7:20: UNSUPP: unsupported escape sequence: \! +mandoc: unsupp.in:8:24: WARNING: invalid escape sequence: \[?] +mandoc: unsupp.in:8:21: UNSUPP: unsupported escape sequence: \? +mandoc: unsupp.in:8:17: UNSUPP: unsupported escape sequence: \? diff --git a/roff.7 b/roff.7 index ad678453..7541c549 100644 --- a/roff.7 +++ b/roff.7 @@ -1,4 +1,4 @@ -.\" $Id: roff.7,v 1.107 2018/10/04 15:32:09 schwarze Exp $ +.\" $Id: roff.7,v 1.108 2018/12/15 19:30:26 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons .\" Copyright (c) 2010-2018 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: October 4 2018 $ +.Dd $Mdocdate: December 15 2018 $ .Dt ROFF 7 .Os .Sh NAME @@ -1844,6 +1844,11 @@ The escape sequence backslash-space .Pq Sq \e\ \& is an unpaddable space-sized non-breaking space character; see .Sx Whitespace . +.It Ic \e! +Embed text up to and including the end of the input line into the +current diversion or into intermediate output without interpreting +requests, macros, and escapes. +Currently unsupported. .It Ic \e\(dq The rest of the input line is treated as .Sx Comments . @@ -1870,6 +1875,10 @@ instead. .Sx Special Characters with two-letter names, see .Xr mandoc_char 7 . +.It Ic \e) +Zero-width space transparent to end-of-sentence detection; +ignored by +.Xr mandoc 1 . .It Ic \e*[ Ns Ar name Ns Ic \&] Interpolate the string with the .Ar name . @@ -1907,6 +1916,15 @@ Special character .It Ic \e/ Right italic correction (groff extension); ignored by .Xr mandoc 1 . +.It Ic \e: +Breaking the line is allowed at this point of the word +without inserting a hyphen. +.It Ic \e? +Embed the text up to the next +.Ic \e? +into the current diversion without interpreting requests, macros, +and escapes. +This is a groff extension and currently unsupported. .It Ic \e[ Ns Ar name Ns Ic \&] .Sx Special Characters with names of arbitrary length, see @@ -1914,6 +1932,10 @@ with names of arbitrary length, see .It Ic \e^ One-twelfth em half-narrow space character, effectively zero-width in .Xr mandoc 1 . +.It Ic \e_ +Underline special character; use +.Ic \e(ul +instead. .It Ic \e` Grave accent special character; use .Ic \e(ga @@ -1934,6 +1956,9 @@ Digit width space character. .It Ic \eA\(aq Ns Ar string Ns Ic \(aq Anchor definition; ignored by .Xr mandoc 1 . +.It Ic \ea +Leader character; ignored by +.Xr mandoc 1 . .It Ic \eB\(aq Ns Ar string Ns Ic \(aq Interpolate .Sq 1 @@ -1961,6 +1986,13 @@ Draw graphics function; ignored by .It Ic \ed Move down by half a line; ignored by .Xr mandoc 1 . +.It Ic \eE +Escape character intended to not be interpreted in copy mode. +In +.Xr mandoc 1 , +it does the same as +.Ic \e +itself for now. .It Ic \ee Backslash special character. .It Ic \eF[ Ns Ar name Ns Ic \&] @@ -2042,6 +2074,14 @@ the register is first incremented or decremented by the that was specified in the relevant .Ic \&nr request, and the changed value is interpolated. +.It Ic \eO Ns Ar digit , Ic \eO[5 Ns arguments Ns Ic \&] +Suppress output. +This is a groff extension and currently unsupported. +With an argument of +.Ic 1 , 2 , 3 , +or +.Ic 4 , +it is ignored. .It Ic \eo\(aq Ns Ar string Ns Ic \(aq Overstrike, writing all the characters contained in the .Ar string @@ -2053,6 +2093,9 @@ Break the output line at the end of the current word. .It Ic \eR\(aq Ns Ar name Oo +|- Oc Ns Ar number Ns Ic \(aq Set number register; ignored by .Xr mandoc 1 . +.It Ic \er +Move up by one line; ignored by +.Xr mandoc 1 . .It Ic \eS\(aq Ns Ar number Ns Ic \(aq Slant output; ignored by .Xr mandoc 1 . diff --git a/roff.c b/roff.c index a303c86b..96a5b33d 100644 --- a/roff.c +++ b/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.351 2018/12/14 06:33:14 schwarze Exp $ */ +/* $Id: roff.c,v 1.352 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze @@ -1154,6 +1154,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) struct roff_node *n; /* used for header comments */ const char *start; /* start of the string to process */ char *stesc; /* start of an escape sequence ('\\') */ + const char *esct; /* type of esccape sequence */ char *ep; /* end of comment string */ const char *stnam; /* start of the name, after "[(*" */ const char *cp; /* end of the name, e.g. before ']' */ @@ -1163,7 +1164,6 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) size_t naml; /* actual length of the escape name */ size_t asz; /* length of the replacement */ size_t rsz; /* length of the rest of the string */ - enum mandoc_esc esc; /* type of the escape sequence */ int inaml; /* length returned from mandoc_escape() */ int expand_count; /* to avoid infinite loops */ int npos; /* position in numeric expression */ @@ -1172,6 +1172,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) int done; /* no more input available */ int deftype; /* type of definition to paste */ int rcsid; /* kind of RCS id seen */ + enum mandocerr err; /* for escape sequence problems */ char sign; /* increment number register */ char term; /* character terminating the escape */ @@ -1304,7 +1305,10 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) term = '\0'; cp = stesc + 1; - switch (*cp) { + if (*cp == 'E') + cp++; + esct = cp; + switch (*esct) { case '*': case '$': res = NULL; @@ -1320,12 +1324,26 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) res = ubuf; break; default: - esc = mandoc_escape(&cp, &stnam, &inaml); - if (esc == ESCAPE_ERROR || - (esc == ESCAPE_SPECIAL && - mchars_spec2cp(stnam, inaml) < 0)) - mandoc_msg(MANDOCERR_ESC_BAD, - ln, (int)(stesc - buf->buf), + err = MANDOCERR_OK; + switch(mandoc_escape(&cp, &stnam, &inaml)) { + case ESCAPE_SPECIAL: + if (mchars_spec2cp(stnam, inaml) >= 0) + break; + /* FALLTHROUGH */ + case ESCAPE_ERROR: + err = MANDOCERR_ESC_BAD; + break; + case ESCAPE_UNDEF: + err = MANDOCERR_ESC_UNDEF; + break; + case ESCAPE_UNSUPP: + err = MANDOCERR_ESC_UNSUPP; + break; + default: + break; + } + if (err != MANDOCERR_OK) + mandoc_msg(err, ln, (int)(stesc - buf->buf), "%.*s", (int)(cp - stesc), stesc); stesc--; continue; @@ -1382,7 +1400,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) cp++; break; } - if (*cp++ != '\\' || stesc[1] != 'w') { + if (*cp++ != '\\' || *esct != 'w') { naml++; continue; } @@ -1390,6 +1408,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) case ESCAPE_SPECIAL: case ESCAPE_UNICODE: case ESCAPE_NUMBERED: + case ESCAPE_UNDEF: case ESCAPE_OVERSTRIKE: naml++; break; @@ -1403,7 +1422,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) * undefined, resume searching for escapes. */ - switch (stesc[1]) { + switch (*esct) { case '*': if (arg_complete) { deftype = ROFFDEF_USER | ROFFDEF_PRE; @@ -1430,15 +1449,15 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) break; } ctx = r->mstack + r->mstackpos; - npos = stesc[2] - '1'; + npos = esct[1] - '1'; if (npos >= 0 && npos <= 8) { res = npos < ctx->argc ? ctx->argv[npos] : ""; break; } - if (stesc[2] == '*') + if (esct[1] == '*') quote_args = 0; - else if (stesc[2] == '@') + else if (esct[1] == '@') quote_args = 1; else { mandoc_msg(MANDOCERR_ARG_NONUM, ln, @@ -1500,7 +1519,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) } if (res == NULL) { - if (stesc[1] == '*') + if (*esct == '*') mandoc_msg(MANDOCERR_STR_UNDEF, ln, (int)(stesc - buf->buf), "%.*s", (int)naml, stnam); diff --git a/term.c b/term.c index 264d0896..d91c90aa 100644 --- a/term.c +++ b/term.c @@ -1,4 +1,4 @@ -/* $Id: term.c,v 1.276 2018/10/25 01:32:41 schwarze Exp $ */ +/* $Id: term.c,v 1.277 2018/12/15 19:30:26 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2018 Ingo Schwarze @@ -477,9 +477,6 @@ term_word(struct termp *p, const char *word) word++; esc = mandoc_escape(&word, &seq, &sz); - if (ESCAPE_ERROR == esc) - continue; - switch (esc) { case ESCAPE_UNICODE: uc = mchars_num2uc(seq + 1, sz - 1); @@ -500,6 +497,9 @@ term_word(struct termp *p, const char *word) encode1(p, uc); } continue; + case ESCAPE_UNDEF: + uc = *seq; + break; case ESCAPE_FONTBOLD: term_fontrepl(p, TERMFONT_BOLD); continue; @@ -587,6 +587,9 @@ term_word(struct termp *p, const char *word) case ESCAPE_SPECIAL: uc = mchars_spec2cp(cp, sz); break; + case ESCAPE_UNDEF: + uc = *seq; + break; default: uc = -1; break; @@ -845,12 +848,8 @@ term_strlen(const struct termp *p, const char *cp) switch (*cp) { case '\\': cp++; - esc = mandoc_escape(&cp, &seq, &ssz); - if (ESCAPE_ERROR == esc) - continue; - rhs = NULL; - + esc = mandoc_escape(&cp, &seq, &ssz); switch (esc) { case ESCAPE_UNICODE: uc = mchars_num2uc(seq + 1, ssz - 1); @@ -871,6 +870,9 @@ term_strlen(const struct termp *p, const char *cp) sz += cond_width(p, uc, &skip); } continue; + case ESCAPE_UNDEF: + uc = *seq; + break; case ESCAPE_DEVICE: if (p->type == TERMTYPE_PDF) { rhs = "pdf"; -- cgit v1.2.3