diff options
-rw-r--r-- | mandoc.1 | 13 | ||||
-rw-r--r-- | mandoc.h | 2 | ||||
-rw-r--r-- | read.c | 2 | ||||
-rw-r--r-- | regress/roff/Makefile | 4 | ||||
-rw-r--r-- | regress/roff/char/Makefile | 6 | ||||
-rw-r--r-- | regress/roff/char/badarg.in | 10 | ||||
-rw-r--r-- | regress/roff/char/badarg.out_ascii | 13 | ||||
-rw-r--r-- | regress/roff/char/badarg.out_lint | 6 | ||||
-rw-r--r-- | regress/roff/char/basic.in | 11 | ||||
-rw-r--r-- | regress/roff/char/basic.out_ascii | 13 | ||||
-rw-r--r-- | roff.7 | 13 | ||||
-rw-r--r-- | roff.c | 73 |
12 files changed, 160 insertions, 6 deletions
@@ -1606,6 +1606,12 @@ or .Cm off . The invalid argument is moved out of the macro, which leaves the macro empty, causing it to toggle the spacing mode. +.It Sy "argument contains two font escapes" +.Pq roff +The second argument of a +.Ic char +request contains more than one font escape sequence. +A wrong font may remain active after using the character. .It Sy "unknown font, skipping request" .Pq man , tbl A @@ -1959,6 +1965,13 @@ macro fails to specify the list type. The argument of a .Ic \&ce request is not a number. +.It Sy "argument is not a character" +.Pq roff +The first argument of a +.Ic char +request is neither a single ASCII character +nor a single character escape sequence. +The request is ignored including all its arguments. .It Sy "missing manual name, using \(dq\(dq" .Pq mdoc The first call to @@ -158,6 +158,7 @@ enum mandocerr { MANDOCERR_LB_BAD, /* unknown library name: Lb ... */ MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */ MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */ + MANDOCERR_CHAR_FONT, /* argument contains two font escapes */ MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */ MANDOCERR_TR_ODD, /* odd number of characters in request: tr char */ @@ -212,6 +213,7 @@ enum mandocerr { MANDOCERR_BD_NOARG, /* skipping display without arguments: Bd */ MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */ MANDOCERR_CE_NONUM, /* argument is not numeric, using 1: ce ... */ + MANDOCERR_CHAR_ARG, /* argument is not a character: char ... */ MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */ MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */ MANDOCERR_ST_BAD, /* unknown standard specifier: St standard */ @@ -198,6 +198,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "unknown library name", "invalid content in Rs block", "invalid Boolean argument", + "argument contains two font escapes", "unknown font, skipping request", "odd number of characters in request", @@ -252,6 +253,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "skipping display without arguments", "missing list type, using -item", "argument is not numeric, using 1", + "argument is not a character", "missing manual name, using \"\"", "uname(3) system call failed, using UNKNOWN", "unknown standard specifier", diff --git a/regress/roff/Makefile b/regress/roff/Makefile index f338f83d..036a66e5 100644 --- a/regress/roff/Makefile +++ b/regress/roff/Makefile @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile,v 1.26 2018/08/24 22:56:37 schwarze Exp $ +# $OpenBSD: Makefile,v 1.27 2018/08/25 16:46:28 schwarze Exp $ SUBDIR = args cond esc scale string -SUBDIR += br cc de ds ft ig it ll na nr po ps +SUBDIR += br cc char de ds ft ig it ll na nr po ps SUBDIR += return rm rn shift sp ta ti tr while .include "../Makefile.sub" diff --git a/regress/roff/char/Makefile b/regress/roff/char/Makefile new file mode 100644 index 00000000..ebd68458 --- /dev/null +++ b/regress/roff/char/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2018/08/25 16:43:52 schwarze Exp $ + +REGRESS_TARGETS = basic badarg +LINT_TARGETS = badarg + +.include <bsd.regress.mk> diff --git a/regress/roff/char/badarg.in b/regress/roff/char/badarg.in new file mode 100644 index 00000000..3b343640 --- /dev/null +++ b/regress/roff/char/badarg.in @@ -0,0 +1,10 @@ +.\" $OpenBSD: badarg.in,v 1.1 2018/08/25 16:43:52 schwarze Exp $ +.TH CHAR-BADARG 1 "August 25, 2018" +.SH NAME +char-badarg \(en char requests with invalid arguments +.SH DESCRIPTION +.char +.char \fR myval +.char \[myc]x myval +.char xy myval +myc: <\[myc]> x diff --git a/regress/roff/char/badarg.out_ascii b/regress/roff/char/badarg.out_ascii new file mode 100644 index 00000000..287479a8 --- /dev/null +++ b/regress/roff/char/badarg.out_ascii @@ -0,0 +1,13 @@ +CHAR-BADARG(1) General Commands Manual CHAR-BADARG(1) + + + +NNAAMMEE + char-badarg - char requests with invalid arguments + +DDEESSCCRRIIPPTTIIOONN + myc: <> x + + + +OpenBSD August 25, 2018 CHAR-BADARG(1) diff --git a/regress/roff/char/badarg.out_lint b/regress/roff/char/badarg.out_lint new file mode 100644 index 00000000..e07faa3c --- /dev/null +++ b/regress/roff/char/badarg.out_lint @@ -0,0 +1,6 @@ +mandoc: badarg.in:6:6: ERROR: argument is not a character: char +mandoc: badarg.in:7:7: ERROR: argument is not a character: char \fR myval +mandoc: badarg.in:8:7: WARNING: invalid escape sequence: \[myc] +mandoc: badarg.in:8:7: ERROR: argument is not a character: char \[myc]x myval +mandoc: badarg.in:9:7: ERROR: argument is not a character: char xy myval +mandoc: badarg.in:10:7: WARNING: invalid escape sequence: \[myc] diff --git a/regress/roff/char/basic.in b/regress/roff/char/basic.in new file mode 100644 index 00000000..cfa1880a --- /dev/null +++ b/regress/roff/char/basic.in @@ -0,0 +1,11 @@ +.\" $OpenBSD: basic.in,v 1.1 2018/08/25 16:43:52 schwarze Exp $ +.TH CHAR-BASIC 1 "August 25, 2018" +.SH NAME +char-basic \(en the char request +.SH DESCRIPTION +initial text +.char \[myc] myval +.char x y +.char \[boldX] \fBX +\[boldX] \[myc] +final text diff --git a/regress/roff/char/basic.out_ascii b/regress/roff/char/basic.out_ascii new file mode 100644 index 00000000..85207cee --- /dev/null +++ b/regress/roff/char/basic.out_ascii @@ -0,0 +1,13 @@ +CHAR-BASIC(1) General Commands Manual CHAR-BASIC(1) + + + +NNAAMMEE + char-basic - the char request + +DDEESSCCRRIIPPTTIIOONN + initial text XX myval final teyt + + + +OpenBSD August 25, 2018 CHAR-BASIC(1) @@ -507,9 +507,16 @@ This is a groff extension and currently ignored. .It Ic \&ch Ar macroname Op Ar dist Change a trap location. Currently ignored. -.It Ic \&char Ar glyphname Op Ar string -Define a new glyph. -Currently unsupported. +.It Ic \&char Ar glyph Op Ar string +Define or redefine the ASCII character or character escape sequence +.Ar glyph +to be rendered as +.Ar string , +which can be empty. +Only partially supported in +.Xr mandoc 1 ; +may interact incorrectly with +.Ic \&tr . .It Ic \&chop Ar stringname Remove the last character from a macro, string, or diversion. Currently unsupported. @@ -176,6 +176,7 @@ static int roff_br(ROFF_ARGS); static int roff_cblock(ROFF_ARGS); static int roff_cc(ROFF_ARGS); static int roff_ccond(struct roff *, int, int); +static int roff_char(ROFF_ARGS); static int roff_cond(ROFF_ARGS); static int roff_cond_text(ROFF_ARGS); static int roff_cond_sub(ROFF_ARGS); @@ -397,7 +398,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_insec, NULL, NULL, 0 }, /* cf */ { roff_line_ignore, NULL, NULL, 0 }, /* cflags */ { roff_line_ignore, NULL, NULL, 0 }, /* ch */ - { roff_unsupp, NULL, NULL, 0 }, /* char */ + { roff_char, NULL, NULL, 0 }, /* char */ { roff_unsupp, NULL, NULL, 0 }, /* chop */ { roff_line_ignore, NULL, NULL, 0 }, /* class */ { roff_insec, NULL, NULL, 0 }, /* close */ @@ -3322,6 +3323,76 @@ roff_cc(ROFF_ARGS) } static int +roff_char(ROFF_ARGS) +{ + const char *p, *kp, *vp; + size_t ksz, vsz; + int font; + + /* Parse the character to be replaced. */ + + kp = buf->buf + pos; + p = kp + 1; + if (*kp == '\0' || (*kp == '\\' && + mandoc_escape(&p, NULL, NULL) != ESCAPE_SPECIAL) || + (*p != ' ' && *p != '\0')) { + mandoc_vmsg(MANDOCERR_CHAR_ARG, r->parse, + ln, pos, "char %s", kp); + return ROFF_IGN; + } + ksz = p - kp; + while (*p == ' ') + p++; + + /* + * If the replacement string contains a font escape sequence, + * we have to restore the font at the end. + */ + + vp = p; + vsz = strlen(p); + font = 0; + while (*p != '\0') { + if (*p++ != '\\') + continue; + switch (mandoc_escape(&p, NULL, NULL)) { + case ESCAPE_FONT: + case ESCAPE_FONTROMAN: + case ESCAPE_FONTITALIC: + case ESCAPE_FONTBOLD: + case ESCAPE_FONTBI: + case ESCAPE_FONTPREV: + font++; + break; + default: + break; + } + } + if (font > 1) + mandoc_msg(MANDOCERR_CHAR_FONT, r->parse, + ln, vp - buf->buf, vp); + + /* + * Approximate the effect of .char using the .tr tables. + * XXX In groff, .char and .tr interact differently. + */ + + if (ksz == 1) { + if (r->xtab == NULL) + r->xtab = mandoc_calloc(128, sizeof(*r->xtab)); + assert((unsigned int)*kp < 128); + free(r->xtab[(int)*kp].p); + r->xtab[(int)*kp].sz = mandoc_asprintf(&r->xtab[(int)*kp].p, + "%s%s", vp, font ? "\fP" : ""); + } else { + roff_setstrn(&r->xmbtab, kp, ksz, vp, vsz, 0); + if (font) + roff_setstrn(&r->xmbtab, kp, ksz, "\\fP", 3, 1); + } + return ROFF_IGN; +} + +static int roff_ec(ROFF_ARGS) { const char *p; |