git: a271d8fd33b5 - stable/14 - mandoc: Vendor import of upstream at 2025-04-08
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 14 Jul 2025 16:47:21 UTC
The branch stable/14 has been updated by ziaee:
URL: https://cgit.FreeBSD.org/src/commit/?id=a271d8fd33b5356a06b0d18b16a7a1eb9d5af980
commit a271d8fd33b5356a06b0d18b16a7a1eb9d5af980
Author: Alexander Ziaee <ziaee@FreeBSD.org>
AuthorDate: 2025-06-12 21:25:42 +0000
Commit: Alexander Ziaee <ziaee@FreeBSD.org>
CommitDate: 2025-07-14 16:44:45 +0000
mandoc: Vendor import of upstream at 2025-04-08
Interesting changes:
+ correct legacy mandoc date typo, reported on our very own bugzilla
+ improve libmandoc manual
+ strengthen recommendations to omit macros from title lines in mdoc(7)
+ improve html5 compliance in html output
+ improve RFC linking in markdown output
+ libmandoc and mdoc manuals have been improved
+ support arithmetic operations in tbl(7) column widths for DocBook
+ define the St -isoC-2023 macro for referencing the C23 spec
Approved by: mhorne (mentor, implicit)
Reviewed by: imp
Discussed with: adrian, bapt, brooks
Closes: https://github.com/freebsd/freebsd-src/pull/1689
(cherry picked from commit 80c12959679ab203459dc20eb9ece3a7328b7de5)
---
contrib/mandoc/TODO | 11 +++-
contrib/mandoc/libmandoc.h | 3 +-
contrib/mandoc/man.1 | 38 ++++++++++-
contrib/mandoc/mandoc.1 | 14 ++--
contrib/mandoc/mandoc.3 | 37 ++++++++++-
contrib/mandoc/mandoc.css | 5 +-
contrib/mandoc/mandoc.h | 5 +-
contrib/mandoc/mandoc_msg.c | 3 +-
contrib/mandoc/mdoc.7 | 36 +++++-----
contrib/mandoc/mdoc_html.c | 61 ++++++++++++-----
contrib/mandoc/mdoc_man.c | 7 +-
contrib/mandoc/mdoc_markdown.c | 35 +++++++++-
contrib/mandoc/out.c | 10 +--
contrib/mandoc/roff.c | 146 +++++++++++++++++++++--------------------
contrib/mandoc/st.c | 2 +-
contrib/mandoc/tbl.c | 3 +-
contrib/mandoc/tbl.h | 3 +-
contrib/mandoc/tbl_layout.c | 36 +++++-----
18 files changed, 304 insertions(+), 151 deletions(-)
diff --git a/contrib/mandoc/TODO b/contrib/mandoc/TODO
index 58d0d6937746..3f5a449af68f 100644
--- a/contrib/mandoc/TODO
+++ b/contrib/mandoc/TODO
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
-* $Id: TODO,v 1.335 2024/09/21 12:08:54 schwarze Exp $
+* $Id: TODO,v 1.337 2025/04/08 21:53:14 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -234,6 +234,11 @@ are mere guesses, and some may be wrong.
--- missing man features -----------------------------------------------
+- When calling less(1), specify -P to print "name(sec) lines ..."
+ in the bottom line instead of "/tmp/man..."
+ Jan Engelhardt (SuSE) via Matej Cepl 06 Apr 2025 14:42:52 +0200
+ loc * exist * algo * size * imp **
+
- MANWIDTH
Markus Waldeck <waldeck at gmx dot de> 9 Jun 2015 05:49:56 +0200
Laura Morales <lauretas at mail dot com> 26 Apr 2018 08:15:55 +0200
@@ -483,6 +488,10 @@ are mere guesses, and some may be wrong.
reveals lots of bugs both in groff and mandoc...
reported by bentley@ Wed, 22 May 2013 23:49:30 -0600
+- Make an underlined blank an underscore rather than a blank in both
+ groff and mandoc terminal output (likely tricky, needs investigation)
+ job@ 21 Jan 2025 18:03:52 +0000
+
--- PostScript and PDF issues ------------------------------------------
- PDF output doesn't use a monospaced font for .Bd -literal
diff --git a/contrib/mandoc/libmandoc.h b/contrib/mandoc/libmandoc.h
index ab7c29be510f..76183423603d 100644
--- a/contrib/mandoc/libmandoc.h
+++ b/contrib/mandoc/libmandoc.h
@@ -1,4 +1,4 @@
-/* $Id: libmandoc.h,v 1.80 2021/06/27 17:57:54 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.81 2025/01/05 16:58:22 schwarze Exp $ */
/*
* Copyright (c) 2013-2015,2017,2018,2020 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -78,6 +78,7 @@ void roff_userret(struct roff *);
void roff_endparse(struct roff *);
void roff_setreg(struct roff *, const char *, int, char);
int roff_getreg(struct roff *, const char *);
+int roff_evalnum(int, const char *, int *, int *, char, int);
char *roff_strdup(const struct roff *, const char *);
char *roff_getarg(struct roff *, char **, int, int *);
int roff_getcontrol(const struct roff *,
diff --git a/contrib/mandoc/man.1 b/contrib/mandoc/man.1
index 888cabb4502b..b37d410e9130 100644
--- a/contrib/mandoc/man.1
+++ b/contrib/mandoc/man.1
@@ -1,4 +1,4 @@
-.\" $Id: man.1,v 1.41 2022/08/04 11:32:23 schwarze Exp $
+.\" $Id: man.1,v 1.42 2025/01/26 14:43:25 schwarze Exp $
.\"
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -31,7 +31,7 @@
.\"
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
.\"
-.Dd $Mdocdate: August 4 2022 $
+.Dd $Mdocdate: January 26 2025 $
.Dt MAN 1
.Os
.Sh NAME
@@ -58,7 +58,19 @@ a specific category
.Pq Ar section
or
machine architecture
-.Pq Ar subsection .
+.Pq Ar subsection ,
+or searched for with
+.Fl k
+using
+.Xr apropos 1
+search expressions.
+The default pager,
+.Xr less 1 ,
+supports the command
+.Ic :t
+to jump to definitions of specific terms (see
+.Dv MANPAGER ,
+below).
.Pp
The options are as follows:
.Bl -tag -width Ds
@@ -345,6 +357,26 @@ See
.Xr mandoc 1
for details.
.Sh EXAMPLES
+Show all manual pages that mention the
+.Ev PWD
+environment variable:
+.Pp
+.Dl $ man -ak Ev=PWD
+.Pp
+Show the
+.Xr ksh 1
+manual and jump to the place where the
+.Ic pwd
+builtin command is described:
+.Pp
+.Dl $ man -O tag=pwd ksh
+.Pp
+Equivalently, use the command
+.Ql man ksh ,
+then type
+.Ql :tpwd
+and press the return key.
+.Pp
Format a page for pasting extracts into an email message \(em
avoid printing any UTF-8 characters, reduce the width to ease
quoting in replies, and remove markup:
diff --git a/contrib/mandoc/mandoc.1 b/contrib/mandoc/mandoc.1
index b1e0cf118336..32a3e2811513 100644
--- a/contrib/mandoc/mandoc.1
+++ b/contrib/mandoc/mandoc.1
@@ -1,6 +1,6 @@
-.\" $Id: mandoc.1,v 1.267 2023/11/13 19:13:01 schwarze Exp $
+.\" $Id: mandoc.1,v 1.270 2025/03/03 14:07:51 schwarze Exp $
.\"
-.\" Copyright (c) 2012, 2014-2023 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2012, 2014-2023, 2025 Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -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 13 2023 $
+.Dd $Mdocdate: March 3 2025 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -954,7 +954,7 @@ The
macro uses the legacy
.Xr man 7
date format
-.Dq yyyy-dd-mm .
+.Dq yyyy-mm-dd .
Consider using the conventional
.Xr mdoc 7
date format
@@ -1896,6 +1896,12 @@ The invalid character is discarded.
A table layout specification contains an opening parenthesis,
but no matching closing parenthesis.
The rest of the input line, starting from the parenthesis, has no effect.
+.It Sy "ignoring invalid column width in tbl layout"
+.Pq tbl
+A column width specifier in a table layout is empty, zero, or not a valid
+numerical expression.
+The width specifier is ignored and the column is made wide enough
+to accommodate all its data cells.
.It Sy "ignoring excessive spacing in tbl layout"
.Pq tbl
A spacing modifier in a table layout is unreasonably large.
diff --git a/contrib/mandoc/mandoc.3 b/contrib/mandoc/mandoc.3
index 4ecfbdebd8c2..6b759558e488 100644
--- a/contrib/mandoc/mandoc.3
+++ b/contrib/mandoc/mandoc.3
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.3,v 1.44 2018/12/30 00:49:55 schwarze Exp $
+.\" $Id: mandoc.3,v 1.46 2025/02/25 17:03:54 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: December 30 2018 $
+.Dd $Mdocdate: February 25 2025 $
.Dt MANDOC 3
.Os
.Sh NAME
@@ -33,6 +33,8 @@
.In sys/types.h
.In stdio.h
.In mandoc.h
+.In roff.h
+.In mandoc_parse.h
.Pp
.Fd "#define ASCII_NBRSP"
.Fd "#define ASCII_HYPH"
@@ -141,6 +143,37 @@ or invoke
.Fn mparse_reset
and go back to step 2 to parse new files.
.El
+.Pp
+The design goals of the
+.Nm mandoc
+library are limited to providing the functionality required by the
+.Xr mandoc 1
+program.
+Consequently, the functions documented in the present manual page
+do not aim for API stability.
+Any third-party program using them typically requires adjustments after every
+.Nm mandoc
+release.
+Linking such a program requires
+.Fl lz
+because
+.Fn mparse_readfd
+calls
+.Xr gzdopen 3 ,
+.Xr gzread 3 ,
+.Xr gzerror 3 ,
+and
+.Xr gzclose 3 .
+For
+.Xr mandoc 1
+itself, the
+.Pa ./configure
+script automatically adds
+.Fl lz
+to the
+.Ev LDADD
+.Xr make 1
+variable.
.Sh REFERENCE
This section documents the functions, types, and variables available
via
diff --git a/contrib/mandoc/mandoc.css b/contrib/mandoc/mandoc.css
index 1dae127059d6..88432b9322b7 100644
--- a/contrib/mandoc/mandoc.css
+++ b/contrib/mandoc/mandoc.css
@@ -1,4 +1,4 @@
-/* $Id: mandoc.css,v 1.52 2022/07/06 14:34:59 schwarze Exp $ */
+/* $Id: mandoc.css,v 1.54 2025/01/25 03:18:55 schwarze Exp $ */
/*
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
*
@@ -179,7 +179,8 @@ h3.Ss { margin-top: 1.2em;
.RsP { }
.RsQ { }
.RsR { }
-.RsT { text-decoration: underline; }
+.RsT { font-style: normal;
+ font-weight: normal; }
.RsU { }
.RsV { }
diff --git a/contrib/mandoc/mandoc.h b/contrib/mandoc/mandoc.h
index 9ab68327ecb4..ccbf90392f4c 100644
--- a/contrib/mandoc/mandoc.h
+++ b/contrib/mandoc/mandoc.h
@@ -1,6 +1,6 @@
-/* $Id: mandoc.h,v 1.282 2023/10/21 17:10:17 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.283 2025/01/05 18:14:39 schwarze Exp $ */
/*
- * Copyright (c) 2012-2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -193,6 +193,7 @@ enum mandocerr {
MANDOCERR_TBLLAYOUT_NONE, /* empty tbl layout */
MANDOCERR_TBLLAYOUT_CHAR, /* invalid character in tbl layout: char */
MANDOCERR_TBLLAYOUT_PAR, /* unmatched parenthesis in tbl layout */
+ MANDOCERR_TBLLAYOUT_WIDTH, /* invalid column width in tbl layout */
MANDOCERR_TBLLAYOUT_SPC, /* ignoring excessive spacing in tbl layout */
MANDOCERR_TBLDATA_NONE, /* tbl without any data cells */
MANDOCERR_TBLDATA_SPAN, /* ignoring data in spanned tbl cell: data */
diff --git a/contrib/mandoc/mandoc_msg.c b/contrib/mandoc/mandoc_msg.c
index baa709c70c83..b4ba9cec9683 100644
--- a/contrib/mandoc/mandoc_msg.c
+++ b/contrib/mandoc/mandoc_msg.c
@@ -1,6 +1,6 @@
/* $OpenBSD: mandoc_msg.c,v 1.8 2020/01/19 17:59:01 schwarze Exp $ */
/*
- * Copyright (c) 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -192,6 +192,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
"empty tbl layout",
"invalid character in tbl layout",
"unmatched parenthesis in tbl layout",
+ "ignoring invalid column width in tbl layout",
"ignoring excessive spacing in tbl layout",
"tbl without any data cells",
"ignoring data in spanned tbl cell",
diff --git a/contrib/mandoc/mdoc.7 b/contrib/mandoc/mdoc.7
index 9dbce2127361..edd74eafa328 100644
--- a/contrib/mandoc/mdoc.7
+++ b/contrib/mandoc/mdoc.7
@@ -1,4 +1,4 @@
-.\" $Id: mdoc.7,v 1.294 2024/09/22 10:34:58 schwarze Exp $
+.\" $Id: mdoc.7,v 1.296 2025/01/27 03:17:33 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 22 2024 $
+.Dd $Mdocdate: January 27 2025 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -2304,13 +2304,14 @@ Close single-quoted context opened by
Begin a new section.
For a list of conventional manual sections, see
.Sx MANUAL STRUCTURE .
-These sections should be used unless it's absolutely necessary that
-custom sections be used.
-.Pp
-Section names should be unique so that they may be keyed by
-.Ic \&Sx .
-Although this macro is parsed, it should not consist of child node or it
-may not be linked with
+Use the conventional sections where applicable.
+For unusually long and complicated manual pages,
+adding custom sections is occasionally useful.
+.Pp
+Avoid using macros inside the
+.Ar TITLE LINE
+and keep that line unique within the manual page,
+such that it can be pointed to with
.Ic \&Sx .
.Pp
See also
@@ -2360,10 +2361,10 @@ the conventional sections described in
.Sx MANUAL STRUCTURE
rarely have subsections.
.Pp
-Sub-section names should be unique so that they may be keyed by
-.Ic \&Sx .
-Although this macro is parsed, it should not consist of child node or it
-may not be linked with
+Avoid using macros inside the
+.Ar Title line
+and keep that line unique within the manual page,
+such that it can be pointed to with
.Ic \&Sx .
.Pp
See also
@@ -2405,12 +2406,17 @@ The original C standard.
.It \-isoC-99
.St -isoC-99
.br
-The second major version of the C language standard.
+Edition 2 of the C language standard.
.Pp
.It \-isoC-2011
.St -isoC-2011
.br
-The third major version of the C language standard.
+Edition 3 of the C language standard.
+.Pp
+.It \-isoC-2023
+.St -isoC-2023
+.br
+Edition 5 of the C language standard.
.El
.It POSIX.1 before XPG4.2
.Pp
diff --git a/contrib/mandoc/mdoc_html.c b/contrib/mandoc/mdoc_html.c
index 74d753a76bfb..b67eac4be233 100644
--- a/contrib/mandoc/mdoc_html.c
+++ b/contrib/mandoc/mdoc_html.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_html.c,v 1.350 2022/07/06 16:05:40 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.353 2025/01/25 00:22:28 schwarze Exp $ */
/*
- * Copyright (c) 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2022 Anna Vyalkova <cyber@sysrq.in>
*
@@ -1456,7 +1456,7 @@ mdoc_rs_pre(MDOC_ARGS)
case ROFFT_BODY:
if (n->sec == SEC_SEE_ALSO)
print_otag(h, TAG_P, "c", "Pp");
- print_otag(h, TAG_CITE, "c", "Rs");
+ print_otag(h, TAG_SPAN, "c", "Rs");
break;
default:
abort();
@@ -1494,10 +1494,13 @@ static int
mdoc__x_pre(MDOC_ARGS)
{
struct roff_node *nn;
- const char *cattr;
+ const unsigned char *cp;
+ const char *cattr, *arg;
+ char *url;
enum htmltag t;
t = TAG_SPAN;
+ arg = n->child->string;
switch (n->tok) {
case MDOC__A:
@@ -1507,7 +1510,7 @@ mdoc__x_pre(MDOC_ARGS)
print_text(h, "and");
break;
case MDOC__B:
- t = TAG_I;
+ t = TAG_CITE;
cattr = "RsB";
break;
case MDOC__C:
@@ -1537,13 +1540,32 @@ mdoc__x_pre(MDOC_ARGS)
cattr = "RsQ";
break;
case MDOC__R:
+ if (strncmp(arg, "RFC ", 4) == 0) {
+ cp = arg += 4;
+ while (isdigit(*cp))
+ cp++;
+ if (*cp == '\0') {
+ mandoc_asprintf(&url, "https://www.rfc-"
+ "editor.org/rfc/rfc%s.html", arg);
+ print_otag(h, TAG_A, "ch", "RsR", url);
+ free(url);
+ return 1;
+ }
+ }
cattr = "RsR";
break;
case MDOC__T:
- cattr = "RsT";
+ t = TAG_CITE;
+ if (n->parent != NULL && n->parent->tok == MDOC_Rs &&
+ n->parent->norm->Rs.quote_T) {
+ print_text(h, "\\(lq");
+ h->flags |= HTML_NOSPACE;
+ cattr = "RsT";
+ } else
+ cattr = "RsB";
break;
case MDOC__U:
- print_otag(h, TAG_A, "ch", "RsU", n->child->string);
+ print_otag(h, TAG_A, "ch", "RsU", arg);
return 1;
case MDOC__V:
cattr = "RsV";
@@ -1561,14 +1583,23 @@ mdoc__x_post(MDOC_ARGS)
{
struct roff_node *nn;
- if (n->tok == MDOC__A &&
- (nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A &&
- ((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) &&
- ((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A))
- return;
-
- /* TODO: %U */
-
+ switch (n->tok) {
+ case MDOC__A:
+ if ((nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A &&
+ ((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) &&
+ ((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A))
+ return;
+ break;
+ case MDOC__T:
+ if (n->parent != NULL && n->parent->tok == MDOC_Rs &&
+ n->parent->norm->Rs.quote_T) {
+ h->flags |= HTML_NOSPACE;
+ print_text(h, "\\(rq");
+ }
+ break;
+ default:
+ break;
+ }
if (n->parent == NULL || n->parent->tok != MDOC_Rs)
return;
diff --git a/contrib/mandoc/mdoc_man.c b/contrib/mandoc/mdoc_man.c
index d4fd88304fb0..5438b2ba5941 100644
--- a/contrib/mandoc/mdoc_man.c
+++ b/contrib/mandoc/mdoc_man.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_man.c,v 1.138 2023/04/28 19:11:04 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.139 2025/01/24 22:37:24 schwarze Exp $ */
/*
- * Copyright (c) 2011-2021 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2021, 2025 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -796,6 +796,9 @@ post_percent(DECL_ARGS)
if (mdoc_man_act(n->tok)->pre == pre_em)
font_pop();
+ if (n->parent == NULL || n->parent->tok != MDOC_Rs)
+ return;
+
if ((nn = roff_node_next(n)) != NULL) {
np = roff_node_prev(n);
nnn = nn == NULL ? NULL : roff_node_next(nn);
diff --git a/contrib/mandoc/mdoc_markdown.c b/contrib/mandoc/mdoc_markdown.c
index ecad77e308e6..06ca839a58b8 100644
--- a/contrib/mandoc/mdoc_markdown.c
+++ b/contrib/mandoc/mdoc_markdown.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_markdown.c,v 1.38 2024/08/13 12:44:00 schwarze Exp $ */
+/* $Id: mdoc_markdown.c,v 1.39 2025/01/20 07:01:17 schwarze Exp $ */
/*
- * Copyright (c) 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2017, 2018, 2020, 2025 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -85,6 +85,7 @@ static int md_pre_Sh(struct roff_node *);
static int md_pre_Sm(struct roff_node *);
static int md_pre_Vt(struct roff_node *);
static int md_pre_Xr(struct roff_node *);
+static int md_pre__R(struct roff_node *);
static int md_pre__T(struct roff_node *);
static int md_pre_br(struct roff_node *);
@@ -159,7 +160,7 @@ static const struct md_act md_acts[MDOC_MAX - MDOC_Dd] = {
{ NULL, NULL, md_post_pc, NULL, NULL }, /* %N */
{ NULL, NULL, md_post_pc, NULL, NULL }, /* %O */
{ NULL, NULL, md_post_pc, NULL, NULL }, /* %P */
- { NULL, NULL, md_post_pc, NULL, NULL }, /* %R */
+ { NULL, md_pre__R, md_post_pc, NULL, NULL }, /* %R */
{ NULL, md_pre__T, md_post__T, NULL, NULL }, /* %T */
{ NULL, NULL, md_post_pc, NULL, NULL }, /* %V */
{ NULL, NULL, NULL, NULL, NULL }, /* Ac */
@@ -1580,6 +1581,34 @@ md_pre_Xr(struct roff_node *n)
return 0;
}
+static int
+md_pre__R(struct roff_node *n)
+{
+ const unsigned char *cp;
+ const char *arg;
+
+ arg = n->child->string;
+
+ if (strncmp(arg, "RFC ", 4) != 0)
+ return 1;
+ cp = arg += 4;
+ while (isdigit(*cp))
+ cp++;
+ if (*cp != '\0')
+ return 1;
+
+ md_rawword("[RFC ");
+ outflags &= ~MD_spc;
+ md_rawword(arg);
+ outflags &= ~MD_spc;
+ md_rawword("](http://www.rfc-editor.org/rfc/rfc");
+ outflags &= ~MD_spc;
+ md_rawword(arg);
+ outflags &= ~MD_spc;
+ md_rawword(".html)");
+ return 0;
+}
+
static int
md_pre__T(struct roff_node *n)
{
diff --git a/contrib/mandoc/out.c b/contrib/mandoc/out.c
index bb29f78c9701..f6f5859a1629 100644
--- a/contrib/mandoc/out.c
+++ b/contrib/mandoc/out.c
@@ -1,4 +1,4 @@
-/* $Id: out.c,v 1.85 2021/10/17 21:05:54 schwarze Exp $ */
+/* $Id: out.c,v 1.86 2025/01/05 18:14:39 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021
@@ -117,7 +117,6 @@ void
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
size_t offset, size_t rmargin)
{
- struct roffsu su;
const struct tbl_opts *opts;
const struct tbl_span *sp;
const struct tbl_dat *dp;
@@ -159,13 +158,6 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
continue;
/* Handle explicit width specifications. */
-
- if (dp->layout->wstr != NULL &&
- dp->layout->width == 0 &&
- a2roffsu(dp->layout->wstr, &su, SCALE_EN)
- != NULL)
- dp->layout->width =
- (*tbl->sulen)(&su, tbl->arg);
if (col->width < dp->layout->width)
col->width = dp->layout->width;
if (dp->layout->spacing != SIZE_MAX &&
diff --git a/contrib/mandoc/roff.c b/contrib/mandoc/roff.c
index bdb02101c053..7425b56873a0 100644
--- a/contrib/mandoc/roff.c
+++ b/contrib/mandoc/roff.c
@@ -1,6 +1,6 @@
-/* $Id: roff.c,v 1.400 2023/10/24 20:53:12 schwarze Exp $ */
+/* $Id: roff.c,v 1.405 2025/04/08 14:05:09 schwarze Exp $ */
/*
- * Copyright (c) 2010-2015, 2017-2023 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015, 2017-2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -192,10 +192,8 @@ static int roff_ec(ROFF_ARGS);
static int roff_eo(ROFF_ARGS);
static int roff_eqndelim(struct roff *, struct buf *, int);
static int roff_evalcond(struct roff *, int, char *, int *);
-static int roff_evalnum(struct roff *, int,
- const char *, int *, int *, int);
-static int roff_evalpar(struct roff *, int,
- const char *, int *, int *, int);
+static int roff_evalpar(int, const char *, int *, int *,
+ char, int);
static int roff_evalstrcond(const char *, int *);
static int roff_expand(struct roff *, struct buf *,
int, int, char);
@@ -204,8 +202,8 @@ static void roff_expand_patch(struct buf *, int,
static void roff_free1(struct roff *);
static void roff_freereg(struct roffreg *);
static void roff_freestr(struct roffkv *);
-static size_t roff_getname(struct roff *, char **, int, int);
-static int roff_getnum(const char *, int *, int *, int);
+static size_t roff_getname(char **, int, int);
+static int roff_getnum(const char *, int *, int *, char, int);
static int roff_getop(const char *, int *, char *);
static int roff_getregn(struct roff *,
const char *, size_t, char);
@@ -258,9 +256,6 @@ static int roff_userdef(ROFF_ARGS);
/* --- constant data ------------------------------------------------------ */
-#define ROFFNUM_SCALE (1 << 0) /* Honour scaling in roff_getnum(). */
-#define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */
-
const char *__roff_name[MAN_MAX + 1] = {
"br", "ce", "fi", "ft",
"ll", "mc", "nf",
@@ -1529,8 +1524,8 @@ roff_expand(struct roff *r, struct buf *buf, int ln, int pos, char ec)
case 'B':
npos = 0;
ubuf[0] = iendarg > iarg && iend > iendarg &&
- roff_evalnum(r, ln, buf->buf + iarg, &npos,
- NULL, ROFFNUM_SCALE) &&
+ roff_evalnum(ln, buf->buf + iarg, &npos,
+ NULL, 'u', 0) &&
npos == iendarg - iarg ? '1' : '0';
ubuf[1] = '\0';
res = ubuf;
@@ -2002,7 +1997,7 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos)
return TOKEN_NONE;
mac = cp;
- maclen = roff_getname(r, &cp, ln, ppos);
+ maclen = roff_getname(&cp, ln, ppos);
deftype = ROFFDEF_USER | ROFFDEF_REN;
r->current_string = roff_getstrn(r, mac, maclen, &deftype);
@@ -2155,7 +2150,7 @@ roff_block(ROFF_ARGS)
namesz = 0;
} else {
iname = cp;
- namesz = roff_getname(r, &cp, ln, ppos);
+ namesz = roff_getname(&cp, ln, ppos);
iname[namesz] = '\0';
}
@@ -2226,7 +2221,7 @@ roff_block(ROFF_ARGS)
/* Get the custom end marker. */
iname = cp;
- namesz = roff_getname(r, &cp, ln, ppos);
+ namesz = roff_getname(&cp, ln, ppos);
/* Resolve the end marker if it is indirect. */
@@ -2427,74 +2422,81 @@ roff_cond_text(ROFF_ARGS)
/* --- handling of numeric and conditional expressions -------------------- */
/*
- * Parse a single signed integer number. Stop at the first non-digit.
+ * Parse a single signed decimal number. Stop at the first non-digit.
* If there is at least one digit, return success and advance the
* parse point, else return failure and let the parse point unchanged.
* Ignore overflows, treat them just like the C language.
*/
static int
-roff_getnum(const char *v, int *pos, int *res, int flags)
+roff_getnum(const char *v, int *pos, int *res, char unit, int skipspace)
{
- int myres, scaled, n, p;
-
- if (NULL == res)
- res = &myres;
+ double frac, myres;
+ int n, p;
p = *pos;
n = v[p] == '-';
if (n || v[p] == '+')
p++;
- if (flags & ROFFNUM_WHITE)
+ if (skipspace)
while (isspace((unsigned char)v[p]))
p++;
- for (*res = 0; isdigit((unsigned char)v[p]); p++)
- *res = 10 * *res + v[p] - '0';
+ for (myres = 0.0; isdigit((unsigned char)v[p]); p++)
+ myres = myres * 10.0 + (v[p] - '0');
+ if (v[p] == '.')
+ for (frac = 0.1; isdigit((unsigned char)v[++p]); frac *= 0.1)
+ myres += frac * (v[p] - '0');
+
if (p == *pos + n)
return 0;
if (n)
- *res = -*res;
+ myres *= -1.0;
/* Each number may be followed by one optional scaling unit. */
- switch (v[p]) {
+ if (v[p] != '\0' && strchr("ficvPmnpuM", v[p]) != NULL) {
+ if (unit != '\0')
+ unit = v[p];
+ p++;
+ }
+
+ switch (unit) {
case 'f':
- scaled = *res * 65536;
+ myres *= 65536.0;
break;
case 'i':
- scaled = *res * 240;
+ myres *= 240.0;
break;
case 'c':
- scaled = *res * 240 / 2.54;
+ myres *= 24000.0;
+ myres /= 254.0;
break;
case 'v':
case 'P':
- scaled = *res * 40;
+ myres *= 40.0;
break;
case 'm':
case 'n':
- scaled = *res * 24;
+ myres *= 24.0;
break;
case 'p':
- scaled = *res * 10 / 3;
+ myres *= 40.0;
+ myres /= 12.0;
break;
case 'u':
- scaled = *res;
break;
case 'M':
- scaled = *res * 6 / 25;
+ myres *= 24.0;
+ myres /= 100.0;
break;
default:
- scaled = *res;
- p--;
break;
}
- if (flags & ROFFNUM_SCALE)
- *res = scaled;
-
- *pos = p + 1;
+ if (res != NULL)
+ *res = myres;
+ *pos = p;
return 1;
}
@@ -2616,7 +2618,7 @@ roff_evalcond(struct roff *r, int ln, char *v, int *pos)
while (*cp == ' ')
cp++;
name = cp;
- sz = roff_getname(r, &cp, ln, cp - v);
+ sz = roff_getname(&cp, ln, cp - v);
if (sz == 0)
istrue = 0;
else if (v[*pos] == 'r')
@@ -2633,7 +2635,7 @@ roff_evalcond(struct roff *r, int ln, char *v, int *pos)
}
savepos = *pos;
- if (roff_evalnum(r, ln, v, pos, &number, ROFFNUM_SCALE))
+ if (roff_evalnum(ln, v, pos, &number, 'u', 0))
return (number > 0) == wanttrue;
else if (*pos == savepos)
return roff_evalstrcond(v, pos) == wanttrue;
@@ -2771,7 +2773,7 @@ roff_ds(ROFF_ARGS)
if (*name == '\0')
return ROFF_IGN;
- namesz = roff_getname(r, &string, ln, pos);
+ namesz = roff_getname(&string, ln, pos);
switch (name[namesz]) {
case '\\':
return ROFF_IGN;
@@ -2862,15 +2864,15 @@ roff_getop(const char *v, int *pos, char *res)
* or a single signed integer number.
*/
static int
-roff_evalpar(struct roff *r, int ln,
- const char *v, int *pos, int *res, int flags)
+roff_evalpar(int ln, const char *v, int *pos, int *res, char unit,
+ int skipspace)
{
if ('(' != v[*pos])
- return roff_getnum(v, pos, res, flags);
+ return roff_getnum(v, pos, res, unit, skipspace);
(*pos)++;
- if ( ! roff_evalnum(r, ln, v, pos, res, flags | ROFFNUM_WHITE))
+ if ( ! roff_evalnum(ln, v, pos, res, unit, 1))
return 0;
/*
@@ -2891,9 +2893,9 @@ roff_evalpar(struct roff *r, int ln,
* Evaluate a complete numeric expression.
* Proceed left to right, there is no concept of precedence.
*/
-static int
-roff_evalnum(struct roff *r, int ln, const char *v,
- int *pos, int *res, int flags)
+int
+roff_evalnum(int ln, const char *v, int *pos, int *res, char unit,
+ int skipspace)
{
int mypos, operand2;
char operator;
@@ -2903,29 +2905,29 @@ roff_evalnum(struct roff *r, int ln, const char *v,
pos = &mypos;
}
- if (flags & ROFFNUM_WHITE)
+ if (skipspace)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
- if ( ! roff_evalpar(r, ln, v, pos, res, flags))
+ if ( ! roff_evalpar(ln, v, pos, res, unit, skipspace))
return 0;
while (1) {
- if (flags & ROFFNUM_WHITE)
+ if (skipspace)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
if ( ! roff_getop(v, pos, &operator))
break;
- if (flags & ROFFNUM_WHITE)
+ if (skipspace)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
- if ( ! roff_evalpar(r, ln, v, pos, &operand2, flags))
+ if ( ! roff_evalpar(ln, v, pos, &operand2, unit, skipspace))
return 0;
- if (flags & ROFFNUM_WHITE)
+ if (skipspace)
while (isspace((unsigned char)v[*pos]))
(*pos)++;
@@ -3062,6 +3064,8 @@ roff_getregro(const struct roff *r, const char *name)
return 24;
case 'j': /* Always adjust left margin only. */
return 0;
+ case 'l': /* Fixed line width for DocBook. */
+ return 78 * 24;
case 'T': /* Some output device is always defined. */
return 1;
case 'V': /* Fixed vertical resolution. */
@@ -3155,7 +3159,7 @@ roff_nr(ROFF_ARGS)
if (*key == '\0')
return ROFF_IGN;
- keysz = roff_getname(r, &val, ln, pos);
+ keysz = roff_getname(&val, ln, pos);
if (key[keysz] == '\\' || key[keysz] == '\t')
return ROFF_IGN;
@@ -3164,13 +3168,13 @@ roff_nr(ROFF_ARGS)
val++;
len = 0;
- if (roff_evalnum(r, ln, val, &len, &iv, ROFFNUM_SCALE) == 0)
+ if (roff_evalnum(ln, val, &len, &iv, 'u', 0) == 0)
return ROFF_IGN;
step = val + len;
while (isspace((unsigned char)*step))
step++;
- if (roff_evalnum(r, ln, step, NULL, &is, 0) == 0)
+ if (roff_evalnum(ln, step, NULL, &is, '\0', 0) == 0)
is = INT_MIN;
roff_setregn(r, key, keysz, iv, sign, is);
@@ -3187,7 +3191,7 @@ roff_rr(ROFF_ARGS)
name = cp = buf->buf + pos;
if (*name == '\0')
return ROFF_IGN;
- namesz = roff_getname(r, &cp, ln, pos);
+ namesz = roff_getname(&cp, ln, pos);
name[namesz] = '\0';
prev = &r->regtab;
@@ -3217,7 +3221,7 @@ roff_rm(ROFF_ARGS)
cp = buf->buf + pos;
while (*cp != '\0') {
name = cp;
- namesz = roff_getname(r, &cp, ln, (int)(cp - buf->buf));
+ namesz = roff_getname(&cp, ln, (int)(cp - buf->buf));
*** 180 LINES SKIPPED ***