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
This commit is contained in:
+10
-1
@@ -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
|
||||
|
||||
@@ -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 *,
|
||||
|
||||
+35
-3
@@ -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:
|
||||
|
||||
+10
-4
@@ -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.
|
||||
|
||||
+35
-2
@@ -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
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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",
|
||||
|
||||
+20
-14
@@ -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.
|
||||
Use the conventional sections where applicable.
|
||||
For unusually long and complicated manual pages,
|
||||
adding custom sections is occasionally useful.
|
||||
.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
|
||||
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
|
||||
|
||||
+46
-15
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
+75
-71
@@ -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));
|
||||
roff_setstrn(&r->strtab, name, namesz, NULL, 0, 0);
|
||||
roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0);
|
||||
if (name[namesz] == '\\' || name[namesz] == '\t')
|
||||
@@ -3233,7 +3237,7 @@ roff_it(ROFF_ARGS)
|
||||
|
||||
/* Parse the number of lines. */
|
||||
|
||||
if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) {
|
||||
if ( ! roff_evalnum(ln, buf->buf, &pos, &iv, '\0', 0)) {
|
||||
mandoc_msg(MANDOCERR_IT_NONUM,
|
||||
ln, ppos, "%s", buf->buf + 1);
|
||||
return ROFF_IGN;
|
||||
@@ -3500,8 +3504,8 @@ roff_onearg(ROFF_ARGS)
|
||||
r->man->last->flags |= NODE_NOSRC;
|
||||
}
|
||||
npos = 0;
|
||||
if (roff_evalnum(r, ln, r->man->last->string, &npos,
|
||||
&roffce_lines, 0) == 0) {
|
||||
if (roff_evalnum(ln, r->man->last->string, &npos,
|
||||
&roffce_lines, '\0', 0) == 0) {
|
||||
mandoc_msg(MANDOCERR_CE_NONUM,
|
||||
ln, pos, "ce %s", buf->buf + pos);
|
||||
roffce_lines = 1;
|
||||
@@ -3554,12 +3558,12 @@ roff_als(ROFF_ARGS)
|
||||
if (*newn == '\0')
|
||||
return ROFF_IGN;
|
||||
|
||||
newsz = roff_getname(r, &oldn, ln, pos);
|
||||
newsz = roff_getname(&oldn, ln, pos);
|
||||
if (newn[newsz] == '\\' || newn[newsz] == '\t' || *oldn == '\0')
|
||||
return ROFF_IGN;
|
||||
|
||||
end = oldn;
|
||||
oldsz = roff_getname(r, &end, ln, oldn - buf->buf);
|
||||
oldsz = roff_getname(&end, ln, oldn - buf->buf);
|
||||
if (oldsz == 0)
|
||||
return ROFF_IGN;
|
||||
|
||||
@@ -3836,12 +3840,12 @@ roff_rn(ROFF_ARGS)
|
||||
if (*oldn == '\0')
|
||||
return ROFF_IGN;
|
||||
|
||||
oldsz = roff_getname(r, &newn, ln, pos);
|
||||
oldsz = roff_getname(&newn, ln, pos);
|
||||
if (oldn[oldsz] == '\\' || oldn[oldsz] == '\t' || *newn == '\0')
|
||||
return ROFF_IGN;
|
||||
|
||||
end = newn;
|
||||
newsz = roff_getname(r, &end, ln, newn - buf->buf);
|
||||
newsz = roff_getname(&end, ln, newn - buf->buf);
|
||||
if (newsz == 0)
|
||||
return ROFF_IGN;
|
||||
|
||||
@@ -3883,7 +3887,7 @@ roff_shift(ROFF_ARGS)
|
||||
argpos = pos;
|
||||
levels = 1;
|
||||
if (buf->buf[pos] != '\0' &&
|
||||
roff_evalnum(r, ln, buf->buf, &pos, &levels, 0) == 0) {
|
||||
roff_evalnum(ln, buf->buf, &pos, &levels, '\0', 0) == 0) {
|
||||
mandoc_msg(MANDOCERR_CE_NONUM,
|
||||
ln, pos, "shift %s", buf->buf + pos);
|
||||
levels = 1;
|
||||
@@ -4026,7 +4030,7 @@ roff_renamed(ROFF_ARGS)
|
||||
* and advance the pointer to the next word.
|
||||
*/
|
||||
static size_t
|
||||
roff_getname(struct roff *r, char **cpp, int ln, int pos)
|
||||
roff_getname(char **cpp, int ln, int pos)
|
||||
{
|
||||
char *name, *cp;
|
||||
int namesz, inam, iend;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* $Id: st.c,v 1.18 2024/06/16 18:49:04 schwarze Exp $ */
|
||||
/* $Id: st.c,v 1.19 2025/01/02 13:34:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: tbl.c,v 1.46 2018/12/14 06:33:14 schwarze Exp $ */
|
||||
/* $Id: tbl.c,v 1.47 2025/01/05 18:14:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -118,7 +118,6 @@ tbl_free(struct tbl_node *tbl)
|
||||
while (rp->first != NULL) {
|
||||
cp = rp->first;
|
||||
rp->first = cp->next;
|
||||
free(cp->wstr);
|
||||
free(cp);
|
||||
}
|
||||
free(rp);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: tbl.h,v 1.2 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/* $Id: tbl.h,v 1.3 2025/01/05 18:14:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014,2015,2017,2018,2021 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -51,7 +51,6 @@ enum tbl_cellt {
|
||||
*/
|
||||
struct tbl_cell {
|
||||
struct tbl_cell *next; /* Layout cell to the right. */
|
||||
char *wstr; /* Min width represented as a string. */
|
||||
size_t width; /* Minimum column width. */
|
||||
size_t spacing; /* To the right of the column. */
|
||||
int vert; /* Width of subsequent vertical line. */
|
||||
|
||||
+21
-15
@@ -1,8 +1,8 @@
|
||||
/* $Id: tbl_layout.c,v 1.50 2021/08/10 12:55:04 schwarze Exp $ */
|
||||
/* $Id: tbl_layout.c,v 1.51 2025/01/05 18:14:39 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021
|
||||
* Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021, 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
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -67,7 +67,6 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long spacing;
|
||||
size_t sz;
|
||||
int isz;
|
||||
enum mandoc_esc fontesc;
|
||||
|
||||
@@ -138,20 +137,27 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
cp->flags |= TBL_CELL_UP;
|
||||
goto mod;
|
||||
case 'w':
|
||||
sz = 0;
|
||||
if (p[*pos] == '(') {
|
||||
(*pos)++;
|
||||
while (p[*pos + sz] != '\0' && p[*pos + sz] != ')')
|
||||
sz++;
|
||||
} else
|
||||
while (isdigit((unsigned char)p[*pos + sz]))
|
||||
sz++;
|
||||
if (sz) {
|
||||
free(cp->wstr);
|
||||
cp->wstr = mandoc_strndup(p + *pos, sz);
|
||||
*pos += sz;
|
||||
if (p[*pos] == ')')
|
||||
isz = 0;
|
||||
if (roff_evalnum(ln, p, pos, &isz, 'n', 1) == 0 ||
|
||||
p[*pos] != ')')
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT_WIDTH,
|
||||
ln, *pos, "%s", p + *pos);
|
||||
else {
|
||||
/* Convert from BU to EN and round. */
|
||||
cp->width = (isz + 11) /24;
|
||||
(*pos)++;
|
||||
}
|
||||
} else {
|
||||
cp->width = 0;
|
||||
while (isdigit((unsigned char)p[*pos])) {
|
||||
cp->width *= 10;
|
||||
cp->width += p[(*pos)++] - '0';
|
||||
}
|
||||
if (cp->width == 0)
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT_WIDTH,
|
||||
ln, *pos, "%s", p + *pos);
|
||||
}
|
||||
goto mod;
|
||||
case 'x':
|
||||
|
||||
Reference in New Issue
Block a user