Import mandoc snapshot 2019-07-23
This commit is contained in:
parent
8f0c701250
commit
a5efdeedef
@ -29,7 +29,7 @@ dbm.o: dbm.c config.h mansearch.h dbm_map.h dbm.h
|
||||
dbm_map.o: dbm_map.c config.h mansearch.h dbm_map.h dbm.h
|
||||
demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h mandoc_parse.h
|
||||
eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.h eqn.h libmandoc.h eqn_parse.h
|
||||
eqn_html.o: eqn_html.c config.h mandoc.h eqn.h out.h html.h
|
||||
eqn_html.o: eqn_html.c config.h mandoc.h roff.h eqn.h out.h html.h
|
||||
eqn_term.o: eqn_term.c config.h eqn.h out.h term.h
|
||||
html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h
|
||||
lib.o: lib.c config.h roff.h libmdoc.h lib.in
|
||||
@ -37,16 +37,16 @@ main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h ma
|
||||
man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
man_html.o: man_html.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h html.h main.h
|
||||
man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
man_term.o: man_term.c config.h mandoc_aux.h roff.h man.h out.h term.h main.h
|
||||
man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h tag.h main.h
|
||||
man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h roff_int.h
|
||||
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||
mandoc_msg.o: mandoc_msg.c mandoc.h
|
||||
mandoc_msg.o: mandoc_msg.c config.h mandoc.h
|
||||
mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h
|
||||
mandoc_xr.o: mandoc_xr.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.h
|
||||
mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h main.h manconf.h
|
||||
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h manconf.h mansearch.h dba_array.h dba.h
|
||||
manpath.o: manpath.c config.h mandoc_aux.h manconf.h
|
||||
manpath.o: manpath.c config.h mandoc_aux.h mandoc.h manconf.h
|
||||
mansearch.o: mansearch.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
@ -67,10 +67,10 @@ roff_term.o: roff_term.c mandoc.h roff.h out.h term.h
|
||||
roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h
|
||||
soelim.o: soelim.c config.h compat_stringlist.h
|
||||
st.o: st.c config.h mandoc.h roff.h libmdoc.h
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h tag.h
|
||||
tbl.o: tbl.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_parse.h tbl_int.h
|
||||
tbl_data.o: tbl_data.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tbl_html.o: tbl_html.c config.h mandoc.h tbl.h out.h html.h
|
||||
tbl_html.o: tbl_html.c config.h mandoc.h roff.h tbl.h out.h html.h
|
||||
tbl_layout.o: tbl_layout.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tbl_opts.o: tbl_opts.c config.h mandoc.h tbl.h libmandoc.h tbl_int.h
|
||||
tbl_term.o: tbl_term.c config.h mandoc.h tbl.h out.h term.h
|
||||
|
26
TODO
26
TODO
@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.289 2019/03/04 13:01:57 schwarze Exp $
|
||||
* $Id: TODO,v 1.295 2019/06/11 16:04:36 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@ -62,6 +62,27 @@ are mere guesses, and some may be wrong.
|
||||
needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
||||
loc ** exist *** algo *** size * imp ***
|
||||
|
||||
- .als only works for macros in mandoc, not for user-defined strings.
|
||||
Also, the "val" field in struct roffkv would have to be replaced
|
||||
with a pointer to a reference-counted wrapper, and an alias
|
||||
would have to point to the same wrapper as the original.
|
||||
.als to undefined does nothing; the alias is not created.
|
||||
.rm'ing the original leaves the alias to point to the old value.
|
||||
.de .als .de changes both, but
|
||||
.de .als .rm .de only changes the new value, not the alias.
|
||||
Found in groffer(1) version 1.19
|
||||
Jan Stary 20 Apr 2019 20:16:54 +0200
|
||||
loc * exist ** algo ** size ** imp *
|
||||
|
||||
- roff string condition comparisons fail when vars contain quotes:
|
||||
.ds s '
|
||||
.if '\*s'' \&...
|
||||
hard to fix because of the basic architecture (string replacement
|
||||
happens before roff(7) syntax parsing)
|
||||
Found in groffer(1) version 1.19
|
||||
Jan Stary 20 Apr 2019 20:16:54 +0200
|
||||
loc * exist *** algo *** size ** imp *
|
||||
|
||||
--- missing mdoc features ----------------------------------------------
|
||||
|
||||
- .Bl -column .Xo support is missing
|
||||
@ -264,6 +285,9 @@ are mere guesses, and some may be wrong.
|
||||
https://github.com/schmonz/ikiwiki/compare/mandoc
|
||||
Amitai Schlair Mon, 19 May 2014 14:05:53 -0400
|
||||
|
||||
- check compatibility with
|
||||
https://git.sr.ht/~sircmpwn/scdoc
|
||||
|
||||
- check features of the Slackware man.conf(5) format
|
||||
Carsten Kunze Wed, 11 Mar 2015 17:57:24 +0100
|
||||
|
||||
|
4
arch.c
4
arch.c
@ -1,4 +1,4 @@
|
||||
/* $Id: arch.c,v 1.14 2019/03/04 13:01:57 schwarze Exp $ */
|
||||
/* $Id: arch.c,v 1.15 2019/05/21 07:52:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -26,7 +26,7 @@ arch_valid(const char *arch, enum mandoc_os os)
|
||||
const char *openbsd_arch[] = {
|
||||
"alpha", "amd64", "arm64", "armv7", "hppa", "i386",
|
||||
"landisk", "loongson", "luna88k", "macppc", "mips64",
|
||||
"octeon", "sgi", "socppc", "sparc64", NULL
|
||||
"octeon", "sgi", "sparc64", NULL
|
||||
};
|
||||
const char *netbsd_arch[] = {
|
||||
"acorn26", "acorn32", "algor", "alpha", "amiga",
|
||||
|
3
cgi.c
3
cgi.c
@ -1,4 +1,4 @@
|
||||
/* $Id: cgi.c,v 1.166 2019/03/06 12:32:41 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.167 2019/07/10 12:49:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017, 2018 Ingo Schwarze <schwarze@usta.de>
|
||||
@ -869,7 +869,6 @@ resp_format(const struct req *req, const char *file)
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
conf.fragment = 1;
|
||||
conf.style = mandoc_strdup(CSS_DIR "/mandoc.css");
|
||||
conf.toc = 1;
|
||||
usepath = strcmp(req->q.manpath, req->p[0]);
|
||||
mandoc_asprintf(&conf.man, "/%s%s%s%s%%N.%%S",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
|
4
configure
vendored
4
configure
vendored
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.70 2019/03/06 16:04:31 schwarze Exp $
|
||||
# $Id: configure,v 1.71 2019/07/01 22:56:24 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
@ -529,7 +529,7 @@ fi
|
||||
echo "extern char *mkdtemp(char *);"
|
||||
|
||||
if [ ${HAVE_PROGNAME} -eq 0 ]; then
|
||||
echo "extern const char *getprogname(void);"
|
||||
echo "extern const char *getprogname(void);"
|
||||
echo "extern void setprogname(const char *);"
|
||||
fi
|
||||
|
||||
|
2
dbm.c
2
dbm.c
@ -1,4 +1,4 @@
|
||||
/* $Id: dbm.c,v 1.6 2018/11/19 19:22:07 schwarze Exp $ */
|
||||
/* $Id: dbm.c,v 1.7 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: dbm_map.h,v 1.1 2016/07/19 21:31:55 schwarze Exp $ */
|
||||
/* $Id: dbm_map.h,v 1.2 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
6
eqn.7
6
eqn.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: eqn.7,v 1.37 2017/09/04 10:35:27 schwarze Exp $
|
||||
.\" $Id: eqn.7,v 1.38 2019/04/23 17:57:49 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2014 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 4 2017 $
|
||||
.Dd $Mdocdate: April 23 2019 $
|
||||
.Dt EQN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -470,7 +470,7 @@ commands are also ignored.
|
||||
.%T System for Typesetting Mathematics
|
||||
.%J Communications of the ACM
|
||||
.%V 18
|
||||
.%P 151\(en157
|
||||
.%P pp. 151\(en157
|
||||
.%D March, 1975
|
||||
.Re
|
||||
.Rs
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: eqn_html.c,v 1.18 2018/12/13 05:23:38 schwarze Exp $ */
|
||||
/* $Id: eqn_html.c,v 1.19 2019/03/17 18:21:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "eqn.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
74
html.c
74
html.c
@ -1,4 +1,4 @@
|
||||
/* $Id: html.c,v 1.254 2019/03/03 13:02:11 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.255 2019/04/30 15:53:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -120,6 +120,7 @@ static void print_ctag(struct html *, struct tag *);
|
||||
static int print_escape(struct html *, char);
|
||||
static int print_encode(struct html *, const char *, const char *, int);
|
||||
static void print_href(struct html *, const char *, const char *, int);
|
||||
static void print_metaf(struct html *);
|
||||
|
||||
|
||||
void *
|
||||
@ -222,55 +223,49 @@ print_gen_head(struct html *h)
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
void
|
||||
print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
int
|
||||
html_setfont(struct html *h, enum mandoc_esc font)
|
||||
{
|
||||
enum htmlfont font;
|
||||
|
||||
switch (deco) {
|
||||
switch (font) {
|
||||
case ESCAPE_FONTPREV:
|
||||
font = h->metal;
|
||||
break;
|
||||
case ESCAPE_FONTITALIC:
|
||||
font = HTMLFONT_ITALIC;
|
||||
break;
|
||||
case ESCAPE_FONTBOLD:
|
||||
font = HTMLFONT_BOLD;
|
||||
break;
|
||||
case ESCAPE_FONTBI:
|
||||
font = HTMLFONT_BI;
|
||||
break;
|
||||
case ESCAPE_FONTCW:
|
||||
font = HTMLFONT_CW;
|
||||
case ESCAPE_FONTROMAN:
|
||||
break;
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTROMAN:
|
||||
font = HTMLFONT_NONE;
|
||||
font = ESCAPE_FONTROMAN;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
h->metal = h->metac;
|
||||
h->metac = font;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
print_metaf(struct html *h)
|
||||
{
|
||||
if (h->metaf) {
|
||||
print_tagq(h, h->metaf);
|
||||
h->metaf = NULL;
|
||||
}
|
||||
|
||||
h->metal = h->metac;
|
||||
h->metac = font;
|
||||
|
||||
switch (font) {
|
||||
case HTMLFONT_ITALIC:
|
||||
switch (h->metac) {
|
||||
case ESCAPE_FONTITALIC:
|
||||
h->metaf = print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_BOLD:
|
||||
case ESCAPE_FONTBOLD:
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
break;
|
||||
case HTMLFONT_BI:
|
||||
case ESCAPE_FONTBI:
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_CW:
|
||||
case ESCAPE_FONTCW:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
break;
|
||||
default:
|
||||
@ -479,7 +474,8 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse)
|
||||
case ESCAPE_FONTROMAN:
|
||||
if (0 == norecurse) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_metaf(h, esc);
|
||||
if (html_setfont(h, esc))
|
||||
print_metaf(h);
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
}
|
||||
continue;
|
||||
@ -806,27 +802,9 @@ print_text(struct html *h, const char *word)
|
||||
print_word(h, " ");
|
||||
}
|
||||
|
||||
assert(NULL == h->metaf);
|
||||
switch (h->metac) {
|
||||
case HTMLFONT_ITALIC:
|
||||
h->metaf = print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_BOLD:
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
break;
|
||||
case HTMLFONT_BI:
|
||||
h->metaf = print_otag(h, TAG_B, "");
|
||||
print_otag(h, TAG_I, "");
|
||||
break;
|
||||
case HTMLFONT_CW:
|
||||
h->metaf = print_otag(h, TAG_SPAN, "c", "Li");
|
||||
break;
|
||||
default:
|
||||
print_indent(h);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(word);
|
||||
assert(h->metaf == NULL);
|
||||
print_metaf(h);
|
||||
print_indent(h);
|
||||
if ( ! print_encode(h, word, NULL, 0)) {
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
@ -834,7 +812,7 @@ print_text(struct html *h, const char *word)
|
||||
} else
|
||||
h->flags |= HTML_NOSPACE | HTML_NONEWLINE;
|
||||
|
||||
if (h->metaf) {
|
||||
if (h->metaf != NULL) {
|
||||
print_tagq(h, h->metaf);
|
||||
h->metaf = NULL;
|
||||
}
|
||||
|
17
html.h
17
html.h
@ -1,4 +1,4 @@
|
||||
/* $Id: html.h,v 1.102 2019/03/01 10:57:18 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.103 2019/04/30 15:53:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -69,15 +69,6 @@ enum htmltag {
|
||||
TAG_MAX
|
||||
};
|
||||
|
||||
enum htmlfont {
|
||||
HTMLFONT_NONE = 0,
|
||||
HTMLFONT_BOLD,
|
||||
HTMLFONT_ITALIC,
|
||||
HTMLFONT_BI,
|
||||
HTMLFONT_CW,
|
||||
HTMLFONT_MAX
|
||||
};
|
||||
|
||||
struct tag {
|
||||
struct tag *next;
|
||||
int refcnt;
|
||||
@ -111,8 +102,8 @@ struct html {
|
||||
char *base_includes; /* base for include href */
|
||||
char *style; /* style-sheet URI */
|
||||
struct tag *metaf; /* current open font scope */
|
||||
enum htmlfont metal; /* last used font */
|
||||
enum htmlfont metac; /* current font mode */
|
||||
enum mandoc_esc metal; /* last used font */
|
||||
enum mandoc_esc metac; /* current font mode */
|
||||
int oflags; /* output options */
|
||||
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
|
||||
#define HTML_TOC (1 << 1) /* emit a table of contents */
|
||||
@ -128,7 +119,6 @@ void roff_html_pre(struct html *, const struct roff_node *);
|
||||
void print_gen_comment(struct html *, struct roff_node *);
|
||||
void print_gen_decls(struct html *);
|
||||
void print_gen_head(struct html *);
|
||||
void print_metaf(struct html *, enum mandoc_esc);
|
||||
struct tag *print_otag(struct html *, enum htmltag, const char *, ...);
|
||||
void print_tagq(struct html *, const struct tag *);
|
||||
void print_stagq(struct html *, const struct tag *);
|
||||
@ -141,3 +131,4 @@ void print_endline(struct html *);
|
||||
void html_close_paragraph(struct html *);
|
||||
enum roff_tok html_fillmode(struct html *, enum roff_tok);
|
||||
char *html_make_id(const struct roff_node *, int);
|
||||
int html_setfont(struct html *, enum mandoc_esc);
|
||||
|
4
lib.in
4
lib.in
@ -1,4 +1,4 @@
|
||||
/* $Id: lib.in,v 1.21 2019/03/04 17:35:21 schwarze Exp $ */
|
||||
/* $Id: lib.in,v 1.22 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
@ -43,7 +43,7 @@ LINE("libcipher", "FreeSec Crypt Library (libcipher, \\-lcipher)")
|
||||
LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)")
|
||||
LINE("libcrypt", "Crypt Library (libcrypt, \\-lcrypt)")
|
||||
LINE("libcurses", "Curses Library (libcurses, \\-lcurses)")
|
||||
LINE("libcuse", "Userland Character Device Library (libcuse, \\-lcuse)")
|
||||
LINE("libcuse", "Userland Character Device Library (libcuse, \\-lcuse)")
|
||||
LINE("libdevattr", "Device attribute and event library (libdevattr, \\-ldevattr)")
|
||||
LINE("libdevctl", "Device Control Library (libdevctl, \\-ldevctl)")
|
||||
LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)")
|
||||
|
80
libroff.h
80
libroff.h
@ -1,80 +0,0 @@
|
||||
/* $Id: libroff.h,v 1.42 2017/07/08 17:52:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 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
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
enum tbl_part {
|
||||
TBL_PART_OPTS, /* in options (first line) */
|
||||
TBL_PART_LAYOUT, /* describing layout */
|
||||
TBL_PART_DATA, /* creating data rows */
|
||||
TBL_PART_CDATA /* continue previous row */
|
||||
};
|
||||
|
||||
struct tbl_node {
|
||||
struct mparse *parse; /* parse point */
|
||||
int pos; /* invocation column */
|
||||
int line; /* invocation line */
|
||||
enum tbl_part part;
|
||||
struct tbl_opts opts;
|
||||
struct tbl_row *first_row;
|
||||
struct tbl_row *last_row;
|
||||
struct tbl_span *first_span;
|
||||
struct tbl_span *current_span;
|
||||
struct tbl_span *last_span;
|
||||
struct tbl_node *next;
|
||||
};
|
||||
|
||||
struct eqn_node {
|
||||
struct mparse *parse; /* main parser, for error reporting */
|
||||
struct roff_node *node; /* syntax tree of this equation */
|
||||
struct eqn_def *defs; /* array of definitions */
|
||||
char *data; /* source code of this equation */
|
||||
char *start; /* first byte of the current token */
|
||||
char *end; /* first byte of the next token */
|
||||
size_t defsz; /* number of definitions */
|
||||
size_t sz; /* length of the source code */
|
||||
size_t toksz; /* length of the current token */
|
||||
int gsize; /* default point size */
|
||||
int delim; /* in-line delimiters enabled */
|
||||
char odelim; /* in-line opening delimiter */
|
||||
char cdelim; /* in-line closing delimiter */
|
||||
};
|
||||
|
||||
struct eqn_def {
|
||||
char *key;
|
||||
size_t keysz;
|
||||
char *val;
|
||||
size_t valsz;
|
||||
};
|
||||
|
||||
|
||||
struct tbl_node *tbl_alloc(int, int, struct mparse *);
|
||||
void tbl_restart(int, int, struct tbl_node *);
|
||||
void tbl_free(struct tbl_node *);
|
||||
void tbl_reset(struct tbl_node *);
|
||||
void tbl_read(struct tbl_node *, int, const char *, int);
|
||||
void tbl_option(struct tbl_node *, int, const char *, int *);
|
||||
void tbl_layout(struct tbl_node *, int, const char *, int);
|
||||
void tbl_data(struct tbl_node *, int, const char *, int);
|
||||
void tbl_cdata(struct tbl_node *, int, const char *, int);
|
||||
const struct tbl_span *tbl_span(struct tbl_node *);
|
||||
int tbl_end(struct tbl_node *);
|
||||
struct eqn_node *eqn_alloc(struct mparse *);
|
||||
void eqn_box_free(struct eqn_box *);
|
||||
void eqn_free(struct eqn_node *);
|
||||
void eqn_parse(struct eqn_node *);
|
||||
void eqn_read(struct eqn_node *, const char *);
|
||||
void eqn_reset(struct eqn_node *);
|
359
main.c
359
main.c
@ -1,4 +1,4 @@
|
||||
/* $Id: main.c,v 1.322 2019/03/06 10:18:58 schwarze Exp $ */
|
||||
/* $Id: main.c,v 1.332 2019/07/19 20:27:25 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -21,6 +21,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h> /* MACHINE */
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
@ -97,13 +98,10 @@ static int fs_lookup(const struct manpaths *,
|
||||
static int fs_search(const struct mansearch *,
|
||||
const struct manpaths *, int, char**,
|
||||
struct manpage **, size_t *);
|
||||
static int koptions(int *, char *);
|
||||
static void moptions(int *, char *);
|
||||
static void outdata_alloc(struct curparse *);
|
||||
static void parse(struct curparse *, int, const char *);
|
||||
static void passthrough(const char *, int, int);
|
||||
static void passthrough(int, int);
|
||||
static pid_t spawn_pager(struct tag_files *);
|
||||
static int toptions(struct curparse *, char *);
|
||||
static void usage(enum argmode) __attribute__((__noreturn__));
|
||||
static int woptions(struct curparse *, char *);
|
||||
|
||||
@ -125,7 +123,7 @@ main(int argc, char *argv[])
|
||||
char *conf_file, *defpaths, *auxpaths;
|
||||
char *oarg, *tagarg;
|
||||
unsigned char *uc;
|
||||
size_t i, sz;
|
||||
size_t i, sz, ssz;
|
||||
int prio, best_prio;
|
||||
enum outmode outmode;
|
||||
int fd, startdir;
|
||||
@ -154,10 +152,11 @@ main(int argc, char *argv[])
|
||||
return mandocdb(argc, argv);
|
||||
|
||||
#if HAVE_PLEDGE
|
||||
if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1) {
|
||||
mandoc_msg(MANDOCERR_PLEDGE, 0, 0, "%s", strerror(errno));
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SANDBOX_INIT
|
||||
if (sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, NULL) == -1)
|
||||
errx((int)MANDOCLEVEL_SYSERR, "sandbox_init");
|
||||
@ -221,19 +220,29 @@ main(int argc, char *argv[])
|
||||
outmode = OUTMODE_ALL;
|
||||
break;
|
||||
case 'I':
|
||||
if (strncmp(optarg, "os=", 3)) {
|
||||
warnx("-I %s: Bad argument", optarg);
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
if (strncmp(optarg, "os=", 3) != 0) {
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
|
||||
"-I %s", optarg);
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
if (curp.os_s != NULL) {
|
||||
warnx("-I %s: Duplicate argument", optarg);
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
mandoc_msg(MANDOCERR_BADARG_DUPE, 0, 0,
|
||||
"-I %s", optarg);
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
curp.os_s = mandoc_strdup(optarg + 3);
|
||||
break;
|
||||
case 'K':
|
||||
if ( ! koptions(&options, optarg))
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
options &= ~(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||
if (strcmp(optarg, "utf-8") == 0)
|
||||
options |= MPARSE_UTF8;
|
||||
else if (strcmp(optarg, "iso-8859-1") == 0)
|
||||
options |= MPARSE_LATIN1;
|
||||
else if (strcmp(optarg, "us-ascii") != 0) {
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
|
||||
"-K %s", optarg);
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
search.argmode = ARG_EXPR;
|
||||
@ -258,12 +267,37 @@ main(int argc, char *argv[])
|
||||
search.sec = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
if ( ! toptions(&curp, optarg))
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
if (strcmp(optarg, "ascii") == 0)
|
||||
curp.outtype = OUTT_ASCII;
|
||||
else if (strcmp(optarg, "lint") == 0) {
|
||||
curp.outtype = OUTT_LINT;
|
||||
mandoc_msg_setoutfile(stdout);
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
} else if (strcmp(optarg, "tree") == 0)
|
||||
curp.outtype = OUTT_TREE;
|
||||
else if (strcmp(optarg, "man") == 0)
|
||||
curp.outtype = OUTT_MAN;
|
||||
else if (strcmp(optarg, "html") == 0)
|
||||
curp.outtype = OUTT_HTML;
|
||||
else if (strcmp(optarg, "markdown") == 0)
|
||||
curp.outtype = OUTT_MARKDOWN;
|
||||
else if (strcmp(optarg, "utf8") == 0)
|
||||
curp.outtype = OUTT_UTF8;
|
||||
else if (strcmp(optarg, "locale") == 0)
|
||||
curp.outtype = OUTT_LOCALE;
|
||||
else if (strcmp(optarg, "ps") == 0)
|
||||
curp.outtype = OUTT_PS;
|
||||
else if (strcmp(optarg, "pdf") == 0)
|
||||
curp.outtype = OUTT_PDF;
|
||||
else {
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
|
||||
"-T %s", optarg);
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
if ( ! woptions(&curp, optarg))
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
if (woptions(&curp, optarg) == -1)
|
||||
return mandoc_msg_getrc();
|
||||
break;
|
||||
case 'w':
|
||||
outmode = OUTMODE_FLN;
|
||||
@ -299,12 +333,9 @@ main(int argc, char *argv[])
|
||||
search.outkey = oarg;
|
||||
else {
|
||||
while (oarg != NULL) {
|
||||
thisarg = oarg;
|
||||
if (manconf_output(&conf.output,
|
||||
strsep(&oarg, ","), 0) == 0)
|
||||
continue;
|
||||
warnx("-O %s: Bad argument", thisarg);
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
strsep(&oarg, ","), 0) == -1)
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,9 +359,13 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
#if HAVE_PLEDGE
|
||||
if (!use_pager)
|
||||
if (pledge("stdio rpath", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
if (use_pager == 0) {
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse arguments. */
|
||||
@ -355,7 +390,7 @@ main(int argc, char *argv[])
|
||||
} else if (argc > 1 &&
|
||||
((uc = (unsigned char *)argv[0]) != NULL) &&
|
||||
((isdigit(uc[0]) && (uc[1] == '\0' ||
|
||||
(isalpha(uc[1]) && uc[2] == '\0'))) ||
|
||||
isalpha(uc[1]))) ||
|
||||
(uc[0] == 'n' && uc[1] == '\0'))) {
|
||||
search.sec = (char *)uc;
|
||||
argv++;
|
||||
@ -395,7 +430,7 @@ main(int argc, char *argv[])
|
||||
usage(search.argmode);
|
||||
|
||||
if (sz == 0 && search.argmode == ARG_NAME)
|
||||
fs_search(&search, &conf.manpath,
|
||||
(void)fs_search(&search, &conf.manpath,
|
||||
argc, argv, &res, &sz);
|
||||
|
||||
if (search.argmode == ARG_NAME) {
|
||||
@ -403,7 +438,10 @@ main(int argc, char *argv[])
|
||||
if (strchr(argv[c], '/') == NULL)
|
||||
continue;
|
||||
if (access(argv[c], R_OK) == -1) {
|
||||
warn("%s", argv[c]);
|
||||
mandoc_msg_setinfilename(argv[c]);
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD,
|
||||
0, 0, "%s", strerror(errno));
|
||||
mandoc_msg_setinfilename(NULL);
|
||||
continue;
|
||||
}
|
||||
res = mandoc_reallocarray(res,
|
||||
@ -411,6 +449,7 @@ main(int argc, char *argv[])
|
||||
res[sz].file = mandoc_strdup(argv[c]);
|
||||
res[sz].names = NULL;
|
||||
res[sz].output = NULL;
|
||||
res[sz].bits = 0;
|
||||
res[sz].ipath = SIZE_MAX;
|
||||
res[sz].sec = 10;
|
||||
res[sz].form = FORM_SRC;
|
||||
@ -433,7 +472,7 @@ main(int argc, char *argv[])
|
||||
|
||||
if (outmode == OUTMODE_ONE) {
|
||||
argc = 1;
|
||||
best_prio = 20;
|
||||
best_prio = 40;
|
||||
} else if (outmode == OUTMODE_ALL)
|
||||
argc = (int)sz;
|
||||
|
||||
@ -452,10 +491,21 @@ main(int argc, char *argv[])
|
||||
sec = res[i].file;
|
||||
sec += strcspn(sec, "123456789");
|
||||
if (sec[0] == '\0')
|
||||
continue;
|
||||
continue; /* No section at all. */
|
||||
prio = sec_prios[sec[0] - '1'];
|
||||
if (sec[1] != '/')
|
||||
prio += 10;
|
||||
if (search.sec != NULL) {
|
||||
ssz = strlen(search.sec);
|
||||
if (strncmp(sec, search.sec, ssz) == 0)
|
||||
sec += ssz;
|
||||
} else
|
||||
sec++; /* Prefer without suffix. */
|
||||
if (*sec != '/')
|
||||
prio += 10; /* Wrong dir name. */
|
||||
if (search.sec != NULL &&
|
||||
(strlen(sec) <= ssz + 3 ||
|
||||
strcmp(sec + strlen(sec) - ssz,
|
||||
search.sec) != 0))
|
||||
prio += 20; /* Wrong file ext. */
|
||||
if (prio >= best_prio)
|
||||
continue;
|
||||
best_prio = prio;
|
||||
@ -477,16 +527,26 @@ main(int argc, char *argv[])
|
||||
|
||||
#if HAVE_PLEDGE
|
||||
if (use_pager) {
|
||||
if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1) {
|
||||
mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
} else {
|
||||
if (pledge("stdio rpath", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
return mandoc_msg_getrc();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (search.argmode == ARG_FILE)
|
||||
moptions(&options, auxpaths);
|
||||
if (search.argmode == ARG_FILE && auxpaths != NULL) {
|
||||
if (strcmp(auxpaths, "doc") == 0)
|
||||
options |= MPARSE_MDOC;
|
||||
else if (strcmp(auxpaths, "an") == 0)
|
||||
options |= MPARSE_MAN;
|
||||
}
|
||||
|
||||
mchars_alloc();
|
||||
curp.mp = mparse_alloc(options, curp.os_e, curp.os_s);
|
||||
@ -494,7 +554,8 @@ main(int argc, char *argv[])
|
||||
if (argc < 1) {
|
||||
if (use_pager) {
|
||||
tag_files = tag_init();
|
||||
tag_files->tagname = conf.output.tag;
|
||||
if (tag_files != NULL)
|
||||
tag_files->tagname = conf.output.tag;
|
||||
}
|
||||
thisarg = "<stdin>";
|
||||
mandoc_msg_setinfilename(thisarg);
|
||||
@ -527,30 +588,31 @@ main(int argc, char *argv[])
|
||||
} else
|
||||
thisarg = *argv;
|
||||
|
||||
mandoc_msg_setinfilename(thisarg);
|
||||
fd = mparse_open(curp.mp, thisarg);
|
||||
if (fd != -1) {
|
||||
if (use_pager) {
|
||||
use_pager = 0;
|
||||
tag_files = tag_init();
|
||||
tag_files->tagname = conf.output.tag;
|
||||
if (tag_files != NULL)
|
||||
tag_files->tagname = conf.output.tag;
|
||||
}
|
||||
|
||||
mandoc_msg_setinfilename(thisarg);
|
||||
if (resp == NULL || resp->form == FORM_SRC)
|
||||
parse(&curp, fd, thisarg);
|
||||
else
|
||||
passthrough(resp->file, fd,
|
||||
conf.output.synopsisonly);
|
||||
mandoc_msg_setinfilename(NULL);
|
||||
passthrough(fd, conf.output.synopsisonly);
|
||||
|
||||
if (ferror(stdout)) {
|
||||
if (tag_files != NULL) {
|
||||
warn("%s", tag_files->ofn);
|
||||
mandoc_msg(MANDOCERR_WRITE, 0, 0,
|
||||
"%s: %s", tag_files->ofn,
|
||||
strerror(errno));
|
||||
tag_unlink();
|
||||
tag_files = NULL;
|
||||
} else
|
||||
warn("stdout");
|
||||
mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
|
||||
mandoc_msg(MANDOCERR_WRITE, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -560,8 +622,10 @@ main(int argc, char *argv[])
|
||||
terminal_sepline(curp.outdata);
|
||||
}
|
||||
} else
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0,
|
||||
"%s: %s", thisarg, strerror(errno));
|
||||
mandoc_msg(resp == NULL ? MANDOCERR_BADARG_BAD :
|
||||
MANDOCERR_OPEN, 0, 0, "%s", strerror(errno));
|
||||
|
||||
mandoc_msg_setinfilename(NULL);
|
||||
|
||||
if (curp.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK)
|
||||
break;
|
||||
@ -653,8 +717,8 @@ main(int argc, char *argv[])
|
||||
continue;
|
||||
|
||||
if (pid == -1) {
|
||||
warn("wait");
|
||||
mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
|
||||
mandoc_msg(MANDOCERR_WAIT, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (!WIFSTOPPED(status))
|
||||
@ -663,14 +727,16 @@ main(int argc, char *argv[])
|
||||
signum = WSTOPSIG(status);
|
||||
}
|
||||
tag_unlink();
|
||||
}
|
||||
} else if (curp.outtype != OUTT_LINT &&
|
||||
(search.argmode == ARG_FILE || sz > 0))
|
||||
mandoc_msg_summary();
|
||||
|
||||
return (int)mandoc_msg_getrc();
|
||||
}
|
||||
|
||||
static void
|
||||
usage(enum argmode argmode)
|
||||
{
|
||||
|
||||
switch (argmode) {
|
||||
case ARG_FILE:
|
||||
fputs("usage: mandoc [-ac] [-I os=name] "
|
||||
@ -701,6 +767,7 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
const char *sec, const char *arch, const char *name,
|
||||
struct manpage **res, size_t *ressz)
|
||||
{
|
||||
struct stat sb;
|
||||
glob_t globinfo;
|
||||
struct manpage *page;
|
||||
char *file;
|
||||
@ -710,13 +777,13 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
form = FORM_SRC;
|
||||
mandoc_asprintf(&file, "%s/man%s/%s.%s",
|
||||
paths->paths[ipath], sec, name, sec);
|
||||
if (access(file, R_OK) != -1)
|
||||
if (stat(file, &sb) != -1)
|
||||
goto found;
|
||||
free(file);
|
||||
|
||||
mandoc_asprintf(&file, "%s/cat%s/%s.0",
|
||||
paths->paths[ipath], sec, name);
|
||||
if (access(file, R_OK) != -1) {
|
||||
if (stat(file, &sb) != -1) {
|
||||
form = FORM_CAT;
|
||||
goto found;
|
||||
}
|
||||
@ -725,7 +792,7 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
if (arch != NULL) {
|
||||
mandoc_asprintf(&file, "%s/man%s/%s/%s.%s",
|
||||
paths->paths[ipath], sec, arch, name, sec);
|
||||
if (access(file, R_OK) != -1)
|
||||
if (stat(file, &sb) != -1)
|
||||
goto found;
|
||||
free(file);
|
||||
}
|
||||
@ -734,37 +801,42 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
|
||||
paths->paths[ipath], sec, name);
|
||||
globres = glob(file, 0, NULL, &globinfo);
|
||||
if (globres != 0 && globres != GLOB_NOMATCH)
|
||||
warn("%s: glob", file);
|
||||
mandoc_msg(MANDOCERR_GLOB, 0, 0,
|
||||
"%s: %s", file, strerror(errno));
|
||||
free(file);
|
||||
if (globres == 0)
|
||||
file = mandoc_strdup(*globinfo.gl_pathv);
|
||||
globfree(&globinfo);
|
||||
if (globres == 0)
|
||||
goto found;
|
||||
if (globres == 0) {
|
||||
if (stat(file, &sb) != -1)
|
||||
goto found;
|
||||
free(file);
|
||||
}
|
||||
if (res != NULL || ipath + 1 != paths->sz)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
mandoc_asprintf(&file, "%s.%s", name, sec);
|
||||
globres = access(file, R_OK);
|
||||
globres = stat(file, &sb);
|
||||
free(file);
|
||||
return globres != -1;
|
||||
return globres;
|
||||
|
||||
found:
|
||||
warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
|
||||
name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
|
||||
if (res == NULL) {
|
||||
free(file);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
*res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
|
||||
*res = mandoc_reallocarray(*res, ++*ressz, sizeof(**res));
|
||||
page = *res + (*ressz - 1);
|
||||
page->file = file;
|
||||
page->names = NULL;
|
||||
page->output = NULL;
|
||||
page->bits = NAME_FILE & NAME_MASK;
|
||||
page->ipath = ipath;
|
||||
page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
|
||||
page->form = form;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -786,14 +858,14 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
for (ipath = 0; ipath < paths->sz; ipath++) {
|
||||
if (cfg->sec != NULL) {
|
||||
if (fs_lookup(paths, ipath, cfg->sec,
|
||||
cfg->arch, *argv, res, ressz) &&
|
||||
cfg->arch, *argv, res, ressz) != -1 &&
|
||||
cfg->firstmatch)
|
||||
return 1;
|
||||
return 0;
|
||||
} else for (isec = 0; isec < nsec; isec++)
|
||||
if (fs_lookup(paths, ipath, sections[isec],
|
||||
cfg->arch, *argv, res, ressz) &&
|
||||
cfg->arch, *argv, res, ressz) != -1 &&
|
||||
cfg->firstmatch)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
if (res != NULL && *ressz == lastsz &&
|
||||
strchr(*argv, '/') == NULL) {
|
||||
@ -812,7 +884,7 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -919,7 +991,7 @@ check_xr(void)
|
||||
search.firstmatch = 1;
|
||||
if (mansearch(&search, &paths, 1, &xr->name, NULL, &sz))
|
||||
continue;
|
||||
if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz))
|
||||
if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz) != -1)
|
||||
continue;
|
||||
if (xr->count == 1)
|
||||
mandoc_msg(MANDOCERR_XR_BAD, xr->line,
|
||||
@ -959,34 +1031,34 @@ outdata_alloc(struct curparse *curp)
|
||||
}
|
||||
|
||||
static void
|
||||
passthrough(const char *file, int fd, int synopsis_only)
|
||||
passthrough(int fd, int synopsis_only)
|
||||
{
|
||||
const char synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS";
|
||||
const char synr[] = "SYNOPSIS";
|
||||
|
||||
FILE *stream;
|
||||
const char *syscall;
|
||||
char *line, *cp;
|
||||
size_t linesz;
|
||||
ssize_t len, written;
|
||||
int print;
|
||||
int lno, print;
|
||||
|
||||
stream = NULL;
|
||||
line = NULL;
|
||||
linesz = 0;
|
||||
|
||||
if (fflush(stdout) == EOF) {
|
||||
syscall = "fflush";
|
||||
goto fail;
|
||||
mandoc_msg(MANDOCERR_FFLUSH, 0, 0, "%s", strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((stream = fdopen(fd, "r")) == NULL) {
|
||||
close(fd);
|
||||
syscall = "fdopen";
|
||||
goto fail;
|
||||
mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
print = 0;
|
||||
lno = print = 0;
|
||||
while ((len = getline(&line, &linesz, stream)) != -1) {
|
||||
lno++;
|
||||
cp = line;
|
||||
if (synopsis_only) {
|
||||
if (print) {
|
||||
@ -1004,94 +1076,20 @@ passthrough(const char *file, int fd, int synopsis_only)
|
||||
}
|
||||
}
|
||||
for (; len > 0; len -= written) {
|
||||
if ((written = write(STDOUT_FILENO, cp, len)) != -1)
|
||||
continue;
|
||||
fclose(stream);
|
||||
syscall = "write";
|
||||
goto fail;
|
||||
if ((written = write(STDOUT_FILENO, cp, len)) == -1) {
|
||||
mandoc_msg(MANDOCERR_WRITE, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(stream)) {
|
||||
fclose(stream);
|
||||
syscall = "getline";
|
||||
goto fail;
|
||||
}
|
||||
if (ferror(stream))
|
||||
mandoc_msg(MANDOCERR_GETLINE, lno, 0, "%s", strerror(errno));
|
||||
|
||||
done:
|
||||
free(line);
|
||||
fclose(stream);
|
||||
return;
|
||||
|
||||
fail:
|
||||
free(line);
|
||||
warn("%s: SYSERR: %s", file, syscall);
|
||||
mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
static int
|
||||
koptions(int *options, char *arg)
|
||||
{
|
||||
|
||||
if ( ! strcmp(arg, "utf-8")) {
|
||||
*options |= MPARSE_UTF8;
|
||||
*options &= ~MPARSE_LATIN1;
|
||||
} else if ( ! strcmp(arg, "iso-8859-1")) {
|
||||
*options |= MPARSE_LATIN1;
|
||||
*options &= ~MPARSE_UTF8;
|
||||
} else if ( ! strcmp(arg, "us-ascii")) {
|
||||
*options &= ~(MPARSE_UTF8 | MPARSE_LATIN1);
|
||||
} else {
|
||||
warnx("-K %s: Bad argument", arg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
moptions(int *options, char *arg)
|
||||
{
|
||||
|
||||
if (arg == NULL)
|
||||
return;
|
||||
if (strcmp(arg, "doc") == 0)
|
||||
*options |= MPARSE_MDOC;
|
||||
else if (strcmp(arg, "an") == 0)
|
||||
*options |= MPARSE_MAN;
|
||||
}
|
||||
|
||||
static int
|
||||
toptions(struct curparse *curp, char *arg)
|
||||
{
|
||||
|
||||
if (0 == strcmp(arg, "ascii"))
|
||||
curp->outtype = OUTT_ASCII;
|
||||
else if (0 == strcmp(arg, "lint")) {
|
||||
curp->outtype = OUTT_LINT;
|
||||
mandoc_msg_setoutfile(stdout);
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
} else if (0 == strcmp(arg, "tree"))
|
||||
curp->outtype = OUTT_TREE;
|
||||
else if (0 == strcmp(arg, "man"))
|
||||
curp->outtype = OUTT_MAN;
|
||||
else if (0 == strcmp(arg, "html"))
|
||||
curp->outtype = OUTT_HTML;
|
||||
else if (0 == strcmp(arg, "markdown"))
|
||||
curp->outtype = OUTT_MARKDOWN;
|
||||
else if (0 == strcmp(arg, "utf8"))
|
||||
curp->outtype = OUTT_UTF8;
|
||||
else if (0 == strcmp(arg, "locale"))
|
||||
curp->outtype = OUTT_LOCALE;
|
||||
else if (0 == strcmp(arg, "ps"))
|
||||
curp->outtype = OUTT_PS;
|
||||
else if (0 == strcmp(arg, "pdf"))
|
||||
curp->outtype = OUTT_PDF;
|
||||
else {
|
||||
warnx("-T %s: Bad argument", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (stream != NULL)
|
||||
fclose(stream);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1135,7 +1133,7 @@ woptions(struct curparse *curp, char *arg)
|
||||
mandoc_msg_setmin(MANDOCERR_UNSUPP);
|
||||
break;
|
||||
case 7:
|
||||
mandoc_msg_setmin(MANDOCERR_MAX);
|
||||
mandoc_msg_setmin(MANDOCERR_BADARG);
|
||||
break;
|
||||
case 8:
|
||||
mandoc_msg_setmin(MANDOCERR_BASE);
|
||||
@ -1146,11 +1144,11 @@ woptions(struct curparse *curp, char *arg)
|
||||
curp->os_e = MANDOC_OS_NETBSD;
|
||||
break;
|
||||
default:
|
||||
warnx("-W %s: Bad argument", o);
|
||||
return 0;
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0, "-W %s", o);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pid_t
|
||||
@ -1196,7 +1194,7 @@ spawn_pager(struct tag_files *tag_files)
|
||||
|
||||
use_ofn = 1;
|
||||
#if HAVE_LESS_T
|
||||
if ((cmdlen = strlen(argv[0])) >= 4) {
|
||||
if (*tag_files->tfn != '\0' && (cmdlen = strlen(argv[0])) >= 4) {
|
||||
cp = argv[0] + cmdlen - 4;
|
||||
if (strcmp(cp, "less") == 0) {
|
||||
argv[argc++] = mandoc_strdup("-T");
|
||||
@ -1215,15 +1213,19 @@ spawn_pager(struct tag_files *tag_files)
|
||||
|
||||
switch (pager_pid = fork()) {
|
||||
case -1:
|
||||
err((int)MANDOCLEVEL_SYSERR, "fork");
|
||||
mandoc_msg(MANDOCERR_FORK, 0, 0, "%s", strerror(errno));
|
||||
exit(mandoc_msg_getrc());
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
(void)setpgid(pager_pid, 0);
|
||||
(void)tcsetpgrp(tag_files->ofd, pager_pid);
|
||||
#if HAVE_PLEDGE
|
||||
if (pledge("stdio rpath tmppath tty proc", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
if (pledge("stdio rpath tmppath tty proc", NULL) == -1) {
|
||||
mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
exit(mandoc_msg_getrc());
|
||||
}
|
||||
#endif
|
||||
tag_files->pager_pid = pager_pid;
|
||||
return pager_pid;
|
||||
@ -1231,8 +1233,10 @@ spawn_pager(struct tag_files *tag_files)
|
||||
|
||||
/* The child process becomes the pager. */
|
||||
|
||||
if (dup2(tag_files->ofd, STDOUT_FILENO) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pager stdout");
|
||||
if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
_exit(mandoc_msg_getrc());
|
||||
}
|
||||
close(tag_files->ofd);
|
||||
assert(tag_files->tfd == -1);
|
||||
|
||||
@ -1242,5 +1246,6 @@ spawn_pager(struct tag_files *tag_files)
|
||||
nanosleep(&timeout, NULL);
|
||||
|
||||
execvp(argv[0], argv);
|
||||
err((int)MANDOCLEVEL_SYSERR, "exec %s", argv[0]);
|
||||
mandoc_msg(MANDOCERR_EXEC, 0, 0, "%s: %s", argv[0], strerror(errno));
|
||||
_exit(mandoc_msg_getrc());
|
||||
}
|
||||
|
16
man.7
16
man.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.7,v 1.143 2019/03/02 22:04:40 schwarze Exp $
|
||||
.\" $Id: man.7,v 1.144 2019/07/09 03:46:59 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011-2015,2017,2018,2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -17,7 +17,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: March 2 2019 $
|
||||
.Dd $Mdocdate: July 9 2019 $
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -160,7 +160,9 @@ This has no effect unless the tabulator positions were changed with the
|
||||
.Ic ta
|
||||
request.
|
||||
.It Ic EE
|
||||
This is a non-standard GNU extension.
|
||||
This is a non-standard Version 9
|
||||
.At
|
||||
extension later adopted by GNU.
|
||||
In
|
||||
.Xr mandoc 1 ,
|
||||
it does the same as the
|
||||
@ -168,7 +170,9 @@ it does the same as the
|
||||
.Ic fi
|
||||
request (switch to fill mode).
|
||||
.It Ic EX
|
||||
This is a non-standard GNU extension.
|
||||
This is a non-standard Version 9
|
||||
.At
|
||||
extension later adopted by GNU.
|
||||
In
|
||||
.Xr mandoc 1 ,
|
||||
it does the same as the
|
||||
@ -496,8 +500,8 @@ The syntax is as follows:
|
||||
.It Ic BI Ta n Ta current Ta \&
|
||||
.It Ic BR Ta n Ta current Ta \&
|
||||
.It Ic DT Ta 0 Ta current Ta \&
|
||||
.It Ic EE Ta 0 Ta current Ta GNU
|
||||
.It Ic EX Ta 0 Ta current Ta GNU
|
||||
.It Ic EE Ta 0 Ta current Ta Version 9 At
|
||||
.It Ic EX Ta 0 Ta current Ta Version 9 At
|
||||
.It Ic I Ta n Ta next-line Ta \&
|
||||
.It Ic IB Ta n Ta current Ta \&
|
||||
.It Ic IR Ta n Ta current Ta \&
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man_html.c,v 1.173 2019/03/02 16:30:53 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.174 2019/04/30 15:53:00 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -203,9 +203,9 @@ print_man_node(MAN_ARGS)
|
||||
* Close out scope of font prior to opening a macro
|
||||
* scope.
|
||||
*/
|
||||
if (HTMLFONT_NONE != h->metac) {
|
||||
if (h->metac != ESCAPE_FONTROMAN) {
|
||||
h->metal = h->metac;
|
||||
h->metac = HTMLFONT_NONE;
|
||||
h->metac = ESCAPE_FONTROMAN;
|
||||
}
|
||||
|
||||
/*
|
||||
|
108
man_term.c
108
man_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: man_term.c,v 1.228 2019/01/05 21:18:26 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.232 2019/07/23 17:53:35 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -27,10 +27,12 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "tag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MAXMARGINS 64 /* maximum number of indented scopes */
|
||||
@ -92,6 +94,8 @@ static void post_SY(DECL_ARGS);
|
||||
static void post_TP(DECL_ARGS);
|
||||
static void post_UR(DECL_ARGS);
|
||||
|
||||
static void tag_man(struct termp *, struct roff_node *);
|
||||
|
||||
static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL, 0 }, /* TH */
|
||||
{ pre_SH, post_SH, 0 }, /* SH */
|
||||
@ -146,7 +150,7 @@ terminal_man(void *arg, const struct roff_meta *man)
|
||||
{
|
||||
struct mtermp mt;
|
||||
struct termp *p;
|
||||
struct roff_node *n;
|
||||
struct roff_node *n, *nc, *nn;
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
@ -165,18 +169,23 @@ terminal_man(void *arg, const struct roff_meta *man)
|
||||
|
||||
n = man->first->child;
|
||||
if (p->synopsisonly) {
|
||||
while (n != NULL) {
|
||||
if (n->tok == MAN_SH &&
|
||||
n->child->child->type == ROFFT_TEXT &&
|
||||
!strcmp(n->child->child->string, "SYNOPSIS")) {
|
||||
if (n->child->next->child != NULL)
|
||||
print_man_nodelist(p, &mt,
|
||||
n->child->next->child, man);
|
||||
term_newln(p);
|
||||
for (nn = NULL; n != NULL; n = n->next) {
|
||||
if (n->tok != MAN_SH)
|
||||
continue;
|
||||
nc = n->child->child;
|
||||
if (nc->type != ROFFT_TEXT)
|
||||
continue;
|
||||
if (strcmp(nc->string, "SYNOPSIS") == 0)
|
||||
break;
|
||||
}
|
||||
n = n->next;
|
||||
if (nn == NULL && strcmp(nc->string, "NAME") == 0)
|
||||
nn = n;
|
||||
}
|
||||
if (n == NULL)
|
||||
n = nn;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (n != NULL && (n = n->child->next->child) != NULL)
|
||||
print_man_nodelist(p, &mt, n, man);
|
||||
term_newln(p);
|
||||
} else {
|
||||
term_begin(p, print_man_head, print_man_foot, man);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -310,7 +319,7 @@ pre_alternate(DECL_ARGS)
|
||||
assert(nn->type == ROFFT_TEXT);
|
||||
term_word(p, nn->string);
|
||||
if (nn->flags & NODE_EOS)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
if (nn->next != NULL)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
@ -529,8 +538,10 @@ pre_IP(DECL_ARGS)
|
||||
case ROFFT_HEAD:
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
if (n->child != NULL)
|
||||
if (n->child != NULL) {
|
||||
print_man_node(p, mt, n->child, meta);
|
||||
tag_man(p, n->child);
|
||||
}
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->tcol->offset = mt->offset + len;
|
||||
@ -610,6 +621,18 @@ pre_TP(DECL_ARGS)
|
||||
while (nn != NULL && (nn->flags & NODE_LINE) == 0)
|
||||
nn = nn->next;
|
||||
|
||||
if (nn == NULL)
|
||||
return 0;
|
||||
|
||||
if (nn->type == ROFFT_TEXT)
|
||||
tag_man(p, nn);
|
||||
else if (nn->child != NULL &&
|
||||
nn->child->type == ROFFT_TEXT &&
|
||||
(nn->tok == MAN_B || nn->tok == MAN_BI ||
|
||||
nn->tok == MAN_BR || nn->tok == MAN_I ||
|
||||
nn->tok == MAN_IB || nn->tok == MAN_IR))
|
||||
tag_man(p, nn->child);
|
||||
|
||||
while (nn != NULL) {
|
||||
print_man_node(p, mt, nn, meta);
|
||||
nn = nn->next;
|
||||
@ -1143,3 +1166,60 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
|
||||
}
|
||||
free(title);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading whitespace, dashes, backslashes, and font escapes,
|
||||
* then create a tag if the first following byte is a letter.
|
||||
* Priority is high unless whitespace is present.
|
||||
*/
|
||||
static void
|
||||
tag_man(struct termp *p, struct roff_node *n)
|
||||
{
|
||||
const char *cp, *arg;
|
||||
int prio, sz;
|
||||
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
cp = n->string;
|
||||
prio = 1;
|
||||
for (;;) {
|
||||
switch (*cp) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
prio = INT_MAX;
|
||||
/* FALLTHROUGH */
|
||||
case '-':
|
||||
cp++;
|
||||
break;
|
||||
case '\\':
|
||||
cp++;
|
||||
switch (mandoc_escape(&cp, &arg, &sz)) {
|
||||
case ESCAPE_FONT:
|
||||
case ESCAPE_FONTROMAN:
|
||||
case ESCAPE_FONTITALIC:
|
||||
case ESCAPE_FONTBOLD:
|
||||
case ESCAPE_FONTPREV:
|
||||
case ESCAPE_FONTBI:
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
if (sz != 1)
|
||||
return;
|
||||
switch (*arg) {
|
||||
case '&':
|
||||
case '-':
|
||||
case 'e':
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isalpha((unsigned char)*cp))
|
||||
tag_put(cp, prio, p->line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man_validate.c,v 1.146 2018/12/31 10:04:39 schwarze Exp $ */
|
||||
/* $Id: man_validate.c,v 1.149 2019/06/27 15:07:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
typedef void (*v_check)(CHKARGS);
|
||||
|
||||
static void check_abort(CHKARGS);
|
||||
static void check_abort(CHKARGS) __attribute__((__noreturn__));
|
||||
static void check_par(CHKARGS);
|
||||
static void check_part(CHKARGS);
|
||||
static void check_root(CHKARGS);
|
||||
@ -185,8 +185,7 @@ check_root(CHKARGS)
|
||||
|
||||
man->meta.title = mandoc_strdup("");
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
man->meta.date = man->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(man, NULL, n->line, n->pos);
|
||||
man->meta.date = mandoc_normdate(man, NULL, n->line, n->pos);
|
||||
}
|
||||
|
||||
if (man->meta.os_e &&
|
||||
@ -369,8 +368,8 @@ post_TH(CHKARGS)
|
||||
/* ->TITLE<- MSEC DATE OS VOL */
|
||||
|
||||
n = n->child;
|
||||
if (n && n->string) {
|
||||
for (p = n->string; '\0' != *p; p++) {
|
||||
if (n != NULL && n->string != NULL) {
|
||||
for (p = n->string; *p != '\0'; p++) {
|
||||
/* Only warn about this once... */
|
||||
if (isalpha((unsigned char)*p) &&
|
||||
! isupper((unsigned char)*p)) {
|
||||
@ -388,9 +387,9 @@ post_TH(CHKARGS)
|
||||
|
||||
/* TITLE ->MSEC<- DATE OS VOL */
|
||||
|
||||
if (n)
|
||||
if (n != NULL)
|
||||
n = n->next;
|
||||
if (n && n->string)
|
||||
if (n != NULL && n->string != NULL)
|
||||
man->meta.msec = mandoc_strdup(n->string);
|
||||
else {
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
@ -400,17 +399,16 @@ post_TH(CHKARGS)
|
||||
|
||||
/* TITLE MSEC ->DATE<- OS VOL */
|
||||
|
||||
if (n)
|
||||
if (n != NULL)
|
||||
n = n->next;
|
||||
if (n && n->string && '\0' != n->string[0]) {
|
||||
man->meta.date = man->quick ?
|
||||
mandoc_strdup(n->string) :
|
||||
mandoc_normdate(man, n->string, n->line, n->pos);
|
||||
} else {
|
||||
if (n != NULL && n->string != NULL && n->string[0] != '\0')
|
||||
man->meta.date = mandoc_normdate(man,
|
||||
n->string, n->line, n->pos);
|
||||
else {
|
||||
man->meta.date = mandoc_strdup("");
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING,
|
||||
n ? n->line : nb->line,
|
||||
n ? n->pos : nb->pos, "TH");
|
||||
n == NULL ? nb->line : n->line,
|
||||
n == NULL ? nb->pos : n->pos, "TH");
|
||||
}
|
||||
|
||||
/* TITLE MSEC DATE ->OS<- VOL */
|
||||
|
63
mandoc.1
63
mandoc.1
@ -1,7 +1,7 @@
|
||||
.\" $Id: mandoc.1,v 1.237 2019/02/23 18:53:54 schwarze Exp $
|
||||
.\" $Id: mandoc.1,v 1.240 2019/07/10 19:39:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2012, 2014-2019 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
|
||||
@ -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: February 23 2019 $
|
||||
.Dd $Mdocdate: July 10 2019 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -222,7 +222,8 @@ reads from standard input.
|
||||
.Pp
|
||||
The options
|
||||
.Fl fhklw
|
||||
are also supported and are documented in man(1).
|
||||
are also supported and are documented in
|
||||
.Xr man 1 .
|
||||
In
|
||||
.Fl f
|
||||
and
|
||||
@ -697,7 +698,7 @@ No input files have been read.
|
||||
.It 6
|
||||
An operating system error occurred, for example exhaustion
|
||||
of memory, file descriptors, or process table entries.
|
||||
Such errors cause
|
||||
Such errors may cause
|
||||
.Nm
|
||||
to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
.El
|
||||
@ -777,6 +778,13 @@ fields.
|
||||
.Pp
|
||||
Message levels have the following meanings:
|
||||
.Bl -tag -width "warning"
|
||||
.It Cm syserr
|
||||
An operating system error occurred.
|
||||
There isn't necessarily anything wrong with the input files.
|
||||
Output may all the same be missing or incomplete.
|
||||
.It Cm badarg
|
||||
Invalid command line arguments were specified.
|
||||
No input files have been read and no output is produced.
|
||||
.It Cm unsupp
|
||||
An input file uses unsupported low-level
|
||||
.Xr roff 7
|
||||
@ -825,8 +833,7 @@ Messages of the
|
||||
.Cm error ,
|
||||
and
|
||||
.Cm unsupp
|
||||
levels except those about non-existent or unreadable input files
|
||||
are hidden unless their level, or a lower level, is requested using a
|
||||
levels are hidden unless their level, or a lower level, is requested using a
|
||||
.Fl W
|
||||
option or
|
||||
.Fl T Cm lint
|
||||
@ -1699,9 +1706,12 @@ The meaning of blank input lines is only well-defined in non-fill mode:
|
||||
In fill mode, line breaks of text input lines are not supposed to be
|
||||
significant.
|
||||
However, for compatibility with groff, blank lines in fill mode
|
||||
are replaced with
|
||||
are formatted like
|
||||
.Ic \&sp
|
||||
requests.
|
||||
To request a paragraph break, use
|
||||
.Ic \&Pp
|
||||
instead of a blank line.
|
||||
.It Sy "tab in filled text"
|
||||
.Pq mdoc , man
|
||||
The meaning of tab characters is only well-defined in non-fill mode:
|
||||
@ -2238,6 +2248,43 @@ macro or of an undefined macro.
|
||||
The macro is ignored, and its arguments are handled
|
||||
as if they were a text line.
|
||||
.El
|
||||
.Ss Bad command line arguments
|
||||
.Bl -ohang
|
||||
.It Sy "bad command line argument"
|
||||
The argument following one of the
|
||||
.Fl IKMmOTW
|
||||
command line options is invalid, or a
|
||||
.Ar file
|
||||
given as a command line argument cannot be opened.
|
||||
.It Sy "duplicate command line argument"
|
||||
The
|
||||
.Fl I
|
||||
command line option was specified twice.
|
||||
.It Sy "option has a superfluous value"
|
||||
An argument to the
|
||||
.Fl O
|
||||
option has a value but does not accept one.
|
||||
.It Sy "missing option value"
|
||||
An argument to the
|
||||
.Fl O
|
||||
option has no argument but requires one.
|
||||
.It Sy "bad option value"
|
||||
An argument to the
|
||||
.Fl O
|
||||
.Cm indent
|
||||
or
|
||||
.Cm width
|
||||
option has an invalid value.
|
||||
.It Sy "duplicate option value"
|
||||
The same
|
||||
.Fl O
|
||||
option is specified more than once.
|
||||
.It Sy "no such tag"
|
||||
The
|
||||
.Fl O Cm tag
|
||||
option was specified but the tag was not found in any of the displayed
|
||||
manual pages.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr apropos 1 ,
|
||||
.Xr man 1 ,
|
||||
|
17
mandoc.c
17
mandoc.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.c,v 1.114 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.116 2019/06/27 15:07:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -494,9 +494,10 @@ time2a(time_t t)
|
||||
size_t ssz;
|
||||
int isz;
|
||||
|
||||
buf = NULL;
|
||||
tm = localtime(&t);
|
||||
if (tm == NULL)
|
||||
return NULL;
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Reserve space:
|
||||
@ -520,7 +521,8 @@ time2a(time_t t)
|
||||
* of looking at LC_TIME.
|
||||
*/
|
||||
|
||||
if ((isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)) == -1)
|
||||
isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday);
|
||||
if (isz < 0 || isz > 4)
|
||||
goto fail;
|
||||
p += isz;
|
||||
|
||||
@ -530,7 +532,7 @@ time2a(time_t t)
|
||||
|
||||
fail:
|
||||
free(buf);
|
||||
return NULL;
|
||||
return mandoc_strdup("");
|
||||
}
|
||||
|
||||
char *
|
||||
@ -539,12 +541,15 @@ mandoc_normdate(struct roff_man *man, char *in, int ln, int pos)
|
||||
char *cp;
|
||||
time_t t;
|
||||
|
||||
if (man->quick)
|
||||
return mandoc_strdup(in == NULL ? "" : in);
|
||||
|
||||
/* No date specified: use today's date. */
|
||||
|
||||
if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0) {
|
||||
if (in == NULL || *in == '\0')
|
||||
mandoc_msg(MANDOCERR_DATE_MISSING, ln, pos, NULL);
|
||||
if (in == NULL || *in == '\0' || strcmp(in, "$" "Mdocdate$") == 0)
|
||||
return time2a(time(NULL));
|
||||
}
|
||||
|
||||
/* Valid mdoc(7) date format. */
|
||||
|
||||
|
29
mandoc.css
29
mandoc.css
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.css,v 1.45 2019/03/01 10:57:18 schwarze Exp $ */
|
||||
/* $Id: mandoc.css,v 1.46 2019/06/02 16:57:13 schwarze Exp $ */
|
||||
/*
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*
|
||||
@ -10,8 +10,13 @@
|
||||
|
||||
/* Global defaults. */
|
||||
|
||||
html { max-width: 65em; }
|
||||
body { font-family: Helvetica,Arial,sans-serif; }
|
||||
html { max-width: 65em;
|
||||
--bg: #FFFFFF;
|
||||
--fg: #000000; }
|
||||
body { background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: Helvetica,Arial,sans-serif; }
|
||||
h1 { font-size: 110%; }
|
||||
table { margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
border-collapse: collapse; }
|
||||
@ -69,8 +74,7 @@ td.foot-os { text-align: right; }
|
||||
section.Sh { }
|
||||
h1.Sh { margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: -3.2em;
|
||||
font-size: 110%; }
|
||||
margin-left: -3.2em; }
|
||||
section.Ss { }
|
||||
h2.Ss { margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
@ -310,14 +314,14 @@ h1.Sh::before, h2.Ss::before, .St::before, .Sx::before, .Sy::before,
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
box-shadow: 0 0 .35em #000;
|
||||
box-shadow: 0 0 .35em var(--fg);
|
||||
padding: .15em .25em;
|
||||
white-space: nowrap;
|
||||
font-family: Helvetica,Arial,sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
background: #fff; }
|
||||
background: var(--bg);
|
||||
color: var(--fg); }
|
||||
.An:hover::before, .Ar:hover::before, .Cd:hover::before, .Cm:hover::before,
|
||||
.Dv:hover::before, .Em:hover::before, .Er:hover::before, .Ev:hover::before,
|
||||
.Fa:hover::before, .Fd:hover::before, .Fl:hover::before, .Fn:hover::before,
|
||||
@ -345,3 +349,12 @@ h1.Sh, h2.Ss { margin-left: 0em; }
|
||||
.HP { margin-left: 2em;
|
||||
text-indent: -2em; }
|
||||
}
|
||||
|
||||
/* Overrides for a dark color scheme for accessibility. */
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html { --bg: #1E1F21;
|
||||
--fg: #EEEFF1; }
|
||||
:link { color: #BAD7FF; }
|
||||
:visited { color: #F6BAFF; }
|
||||
}
|
||||
|
35
mandoc.h
35
mandoc.h
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc.h,v 1.262 2018/12/16 00:17:02 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.264 2019/07/14 18:16:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012-2019 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
|
||||
@ -193,7 +193,6 @@ enum mandocerr {
|
||||
MANDOCERR_TBLDATA_BLK, /* data block open at end of tbl: macro */
|
||||
|
||||
/* related to document structure and macros */
|
||||
MANDOCERR_FILE, /* cannot open file */
|
||||
MANDOCERR_PROLOG_REP, /* duplicate prologue macro: macro */
|
||||
MANDOCERR_DT_LATE, /* skipping late title macro: Dt args */
|
||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||
@ -242,6 +241,35 @@ enum mandocerr {
|
||||
MANDOCERR_TBLLAYOUT_MOD, /* unsupported tbl layout modifier: m */
|
||||
MANDOCERR_TBLMACRO, /* ignoring macro in table: macro */
|
||||
|
||||
MANDOCERR_BADARG, /* ===== start of bad invocations ===== */
|
||||
|
||||
MANDOCERR_BADARG_BAD, /* bad argument */
|
||||
MANDOCERR_BADARG_DUPE, /* duplicate argument */
|
||||
MANDOCERR_BADVAL, /* does not take a value */
|
||||
MANDOCERR_BADVAL_MISS, /* missing argument value */
|
||||
MANDOCERR_BADVAL_BAD, /* bad argument value */
|
||||
MANDOCERR_BADVAL_DUPE, /* duplicate argument value */
|
||||
MANDOCERR_TAG, /* no such tag */
|
||||
|
||||
MANDOCERR_SYSERR, /* ===== start of system errors ===== */
|
||||
|
||||
MANDOCERR_DUP,
|
||||
MANDOCERR_EXEC,
|
||||
MANDOCERR_FDOPEN,
|
||||
MANDOCERR_FFLUSH,
|
||||
MANDOCERR_FORK,
|
||||
MANDOCERR_FSTAT,
|
||||
MANDOCERR_GETLINE,
|
||||
MANDOCERR_GLOB,
|
||||
MANDOCERR_GZCLOSE,
|
||||
MANDOCERR_GZDOPEN,
|
||||
MANDOCERR_MKSTEMP,
|
||||
MANDOCERR_OPEN,
|
||||
MANDOCERR_PLEDGE,
|
||||
MANDOCERR_READ,
|
||||
MANDOCERR_WAIT,
|
||||
MANDOCERR_WRITE,
|
||||
|
||||
MANDOCERR_MAX
|
||||
};
|
||||
|
||||
@ -281,6 +309,7 @@ enum mandoclevel mandoc_msg_getrc(void);
|
||||
void mandoc_msg_setrc(enum mandoclevel);
|
||||
void mandoc_msg(enum mandocerr, int, int, const char *, ...)
|
||||
__attribute__((__format__ (__printf__, 4, 5)));
|
||||
void mandoc_msg_summary(void);
|
||||
void mchars_alloc(void);
|
||||
void mchars_free(void);
|
||||
int mchars_num2char(const char *, size_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_char.7,v 1.75 2018/12/15 19:30:26 schwarze Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.76 2019/03/31 19:17:26 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -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: December 15 2018 $
|
||||
.Dd $Mdocdate: March 31 2019 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -107,8 +107,8 @@ supporting it, for example in
|
||||
.Fl T Cm utf8
|
||||
and
|
||||
.Fl T Cm html .
|
||||
But currently, no practically relevant manual page formatter actually
|
||||
requires that subtlety, so in manual pages just write plain
|
||||
But currently, no practically relevant manual page formatter requires
|
||||
that subtlety, so in manual pages, it is sufficient to write plain
|
||||
.Sq -
|
||||
to represent hyphen, minus, and hyphen-minus.
|
||||
.Pp
|
||||
|
101
mandoc_headers.3
101
mandoc_headers.3
@ -1,4 +1,20 @@
|
||||
.Dd $Mdocdate: December 30 2018 $
|
||||
.\" $Id: mandoc_headers.3,v 1.31 2019/03/17 18:21:45 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014-2019 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
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: March 17 2019 $
|
||||
.Dt MANDOC_HEADERS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -129,19 +145,19 @@ and the function
|
||||
Uses pointers to the types
|
||||
.Vt struct ohash
|
||||
from
|
||||
.Pa mandoc_ohash.h ,
|
||||
.Qq Pa mandoc_ohash.h ,
|
||||
.Vt struct mdoc_arg
|
||||
and
|
||||
.Vt union mdoc_data
|
||||
from
|
||||
.Pa mdoc.h ,
|
||||
.Qq Pa mdoc.h ,
|
||||
.Vt struct tbl_span
|
||||
from
|
||||
.Pa tbl.h ,
|
||||
.Qq Pa tbl.h ,
|
||||
and
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa eqn.h
|
||||
.Qq Pa eqn.h
|
||||
as opaque struct members.
|
||||
.It Qq Pa tbl.h
|
||||
Data structures for the
|
||||
@ -184,13 +200,13 @@ Top level parser interface, for use in the main program
|
||||
and in the main parser, but not in formatters.
|
||||
.Pp
|
||||
Requires
|
||||
.Pa mandoc.h
|
||||
.Qq Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandocerr
|
||||
and
|
||||
.Vt enum mandoclevel
|
||||
and
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
for
|
||||
.Vt enum mandoc_os .
|
||||
.Pp
|
||||
@ -202,7 +218,7 @@ for function prototypes.
|
||||
Uses
|
||||
.Vt struct roff_meta
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa mandoc_xr.h
|
||||
Cross reference validation; intended for use in the main program
|
||||
@ -251,11 +267,11 @@ described in
|
||||
Uses the types
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
and
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff_int.h
|
||||
.Qq Pa roff_int.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
@ -269,7 +285,7 @@ described in
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
@ -305,7 +321,7 @@ for function prototypes.
|
||||
Uses the type
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa roff_int.h
|
||||
Parser internals shared by multiple parsers.
|
||||
@ -334,24 +350,24 @@ and the two special functions
|
||||
and
|
||||
.Fn mdoc_argv_free
|
||||
because the latter two are needed by
|
||||
.Qq Pa roff.c .
|
||||
.Pa roff.c .
|
||||
.Pp
|
||||
Uses the types
|
||||
.Vt struct ohash
|
||||
from
|
||||
.Pa mandoc_ohash.h ,
|
||||
.Qq Pa mandoc_ohash.h ,
|
||||
.Vt struct roff_node
|
||||
and
|
||||
.Vt struct roff_meta
|
||||
from
|
||||
.Pa roff.h ,
|
||||
.Qq Pa roff.h ,
|
||||
.Vt struct roff
|
||||
from
|
||||
.Pa roff.c ,
|
||||
and
|
||||
.Vt struct mdoc_arg
|
||||
from
|
||||
.Pa mdoc.h
|
||||
.Qq Pa mdoc.h
|
||||
as opaque types for function prototypes.
|
||||
.It Qq Pa libmdoc.h
|
||||
Requires
|
||||
@ -372,14 +388,14 @@ parser.
|
||||
Uses the types
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h ,
|
||||
.Qq Pa roff.h ,
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff_int.h ,
|
||||
.Qq Pa roff_int.h ,
|
||||
and
|
||||
.Vt struct mdoc_arg
|
||||
from
|
||||
.Pa mdoc.h
|
||||
.Qq Pa mdoc.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
@ -399,11 +415,11 @@ parser.
|
||||
Uses the types
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
and
|
||||
.Vt struct roff_man
|
||||
from
|
||||
.Pa roff_int.h
|
||||
.Qq Pa roff_int.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
@ -437,12 +453,12 @@ and
|
||||
Uses the type
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa mandoc.h
|
||||
.Qq Pa mandoc.h
|
||||
as an opaque type for function prototypes.
|
||||
Uses the types
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
and
|
||||
.Vt struct eqn_def
|
||||
from
|
||||
@ -466,11 +482,11 @@ Provides the functions documented in
|
||||
Uses the types
|
||||
.Vt struct tbl_span
|
||||
from
|
||||
.Pa tbl.h
|
||||
.Qq Pa tbl.h
|
||||
and
|
||||
.Vt struct tbl_node
|
||||
from
|
||||
.Pa tbl_int.h
|
||||
.Qq Pa tbl_int.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
@ -523,11 +539,11 @@ and
|
||||
Uses
|
||||
.Vt struct tbl_span
|
||||
from
|
||||
.Pa mandoc.h
|
||||
.Qq Pa mandoc.h
|
||||
as an opaque type for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa mansearch.h .
|
||||
.Qq Pa mansearch.h .
|
||||
.It Qq Pa term.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
@ -558,27 +574,30 @@ Uses
|
||||
and
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa mandoc.h
|
||||
.Qq Pa mandoc.h
|
||||
and
|
||||
.Vt struct roff_meta
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa html.h
|
||||
.Qq Pa html.h
|
||||
or
|
||||
.Pa mansearch.h .
|
||||
.Qq Pa mansearch.h .
|
||||
.It Qq Pa html.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t ,
|
||||
.Pa mandoc.h
|
||||
.Qq Pa mandoc.h
|
||||
for
|
||||
.Vt enum mandoc_esc ,
|
||||
.Qq Pa roff.h
|
||||
for
|
||||
.Vt enum roff_tok ,
|
||||
and
|
||||
.Qq Pa out.h
|
||||
for
|
||||
@ -602,17 +621,17 @@ Uses
|
||||
and
|
||||
.Vt struct eqn_box
|
||||
from
|
||||
.Pa mandoc.h
|
||||
.Qq Pa mandoc.h
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa term.h
|
||||
.Qq Pa term.h
|
||||
or
|
||||
.Pa mansearch.h .
|
||||
.Qq Pa mansearch.h .
|
||||
.It Qq Pa tag.h
|
||||
Requires
|
||||
.In sys/types.h
|
||||
@ -631,7 +650,7 @@ Provides the top level steering functions for all formatters.
|
||||
Uses the type
|
||||
.Vt struct roff_meta
|
||||
from
|
||||
.Pa roff.h
|
||||
.Qq Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa manconf.h
|
||||
Requires
|
||||
@ -671,12 +690,12 @@ and
|
||||
Uses
|
||||
.Vt struct manpaths
|
||||
from
|
||||
.Pa manconf.h
|
||||
.Qq Pa manconf.h
|
||||
as an opaque type for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa out.h ,
|
||||
.Pa term.h ,
|
||||
.Qq Pa out.h ,
|
||||
.Qq Pa term.h ,
|
||||
or
|
||||
.Pa html.h .
|
||||
.Qq Pa html.h .
|
||||
.El
|
||||
|
53
mandoc_msg.c
53
mandoc_msg.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc_msg.c,v 1.6 2019/03/06 15:55:38 schwarze Exp $ */
|
||||
/* $Id: mandoc_msg.c,v 1.8 2019/07/14 18:16:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014-2019 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
|
||||
@ -29,8 +29,8 @@ static const enum mandocerr lowest_type[MANDOCLEVEL_MAX] = {
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_ERROR,
|
||||
MANDOCERR_UNSUPP,
|
||||
MANDOCERR_MAX,
|
||||
MANDOCERR_MAX
|
||||
MANDOCERR_BADARG,
|
||||
MANDOCERR_SYSERR
|
||||
};
|
||||
|
||||
static const char *const level_name[MANDOCLEVEL_MAX] = {
|
||||
@ -193,7 +193,6 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
||||
"data block open at end of tbl",
|
||||
|
||||
/* related to document structure and macros */
|
||||
NULL,
|
||||
"duplicate prologue macro",
|
||||
"skipping late title macro",
|
||||
"input stack limit exceeded, infinite loop?",
|
||||
@ -240,11 +239,40 @@ static const char *const type_message[MANDOCERR_MAX] = {
|
||||
"eqn delim option in tbl",
|
||||
"unsupported tbl layout modifier",
|
||||
"ignoring macro in table",
|
||||
|
||||
/* bad command line arguments */
|
||||
NULL,
|
||||
"bad command line argument",
|
||||
"duplicate command line argument",
|
||||
"option has a superfluous value",
|
||||
"missing option value",
|
||||
"bad option value",
|
||||
"duplicate option value",
|
||||
"no such tag",
|
||||
|
||||
/* system errors */
|
||||
NULL,
|
||||
"dup",
|
||||
"exec",
|
||||
"fdopen",
|
||||
"fflush",
|
||||
"fork",
|
||||
"fstat",
|
||||
"getline",
|
||||
"glob",
|
||||
"gzclose",
|
||||
"gzdopen",
|
||||
"mkstemp",
|
||||
"open",
|
||||
"pledge",
|
||||
"read",
|
||||
"wait",
|
||||
"write",
|
||||
};
|
||||
|
||||
static FILE *fileptr = NULL;
|
||||
static const char *filename = NULL;
|
||||
static enum mandocerr min_type = MANDOCERR_MAX;
|
||||
static enum mandocerr min_type = MANDOCERR_BADARG;
|
||||
static enum mandoclevel rc = MANDOCLEVEL_OK;
|
||||
|
||||
|
||||
@ -297,10 +325,10 @@ mandoc_msg(enum mandocerr t, int line, int col, const char *fmt, ...)
|
||||
va_list ap;
|
||||
enum mandoclevel level;
|
||||
|
||||
if (t < min_type && t != MANDOCERR_FILE)
|
||||
if (t < min_type)
|
||||
return;
|
||||
|
||||
level = MANDOCLEVEL_UNSUPP;
|
||||
level = MANDOCLEVEL_SYSERR;
|
||||
while (t < lowest_type[level])
|
||||
level--;
|
||||
mandoc_msg_setrc(level);
|
||||
@ -327,3 +355,12 @@ mandoc_msg(enum mandocerr t, int line, int col, const char *fmt, ...)
|
||||
}
|
||||
fputc('\n', fileptr);
|
||||
}
|
||||
|
||||
void
|
||||
mandoc_msg_summary(void)
|
||||
{
|
||||
if (fileptr != NULL && rc != MANDOCLEVEL_OK)
|
||||
fprintf(fileptr,
|
||||
"%s: see above the output for %s messages\n",
|
||||
getprogname(), level_name[rc]);
|
||||
}
|
||||
|
19
mandocdb.c
19
mandocdb.c
@ -1,7 +1,7 @@
|
||||
/* $Id: mandocdb.c,v 1.262 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.263 2019/05/03 18:17:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -1186,9 +1186,11 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
mlink->next = mlink_dest->next;
|
||||
mlink_dest->next = mpage->mlinks;
|
||||
mpage->mlinks = NULL;
|
||||
goto nextpage;
|
||||
}
|
||||
goto nextpage;
|
||||
} else if (meta != NULL && meta->macroset == MACROSET_MDOC) {
|
||||
meta->macroset = MACROSET_NONE;
|
||||
}
|
||||
if (meta != NULL && meta->macroset == MACROSET_MDOC) {
|
||||
mpage->form = FORM_SRC;
|
||||
mpage->sec = meta->msec;
|
||||
mpage->sec = mandoc_strdup(
|
||||
@ -1208,12 +1210,15 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
}
|
||||
|
||||
assert(mpage->desc == NULL);
|
||||
if (meta == NULL) {
|
||||
mpage->form = FORM_CAT;
|
||||
if (meta == NULL || meta->sodest != NULL) {
|
||||
mpage->sec = mandoc_strdup(mlink->dsec);
|
||||
mpage->arch = mandoc_strdup(mlink->arch);
|
||||
mpage->title = mandoc_strdup(mlink->name);
|
||||
parse_cat(mpage, fd);
|
||||
if (meta == NULL) {
|
||||
mpage->form = FORM_CAT;
|
||||
parse_cat(mpage, fd);
|
||||
} else
|
||||
mpage->form = FORM_SRC;
|
||||
} else if (meta->macroset == MACROSET_MDOC)
|
||||
parse_mdoc(mpage, meta, meta->first);
|
||||
else
|
||||
|
98
manpath.c
98
manpath.c
@ -1,6 +1,6 @@
|
||||
/* $Id: manpath.c,v 1.37 2018/11/22 11:30:23 schwarze Exp $ */
|
||||
/* $Id: manpath.c,v 1.40 2019/07/10 19:39:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011,2014,2015,2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -21,20 +21,19 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "manconf.h"
|
||||
|
||||
static void manconf_file(struct manconf *, const char *);
|
||||
static void manpath_add(struct manpaths *, const char *, int);
|
||||
static void manpath_parseline(struct manpaths *, char *, int);
|
||||
static void manpath_add(struct manpaths *, const char *, char);
|
||||
static void manpath_parseline(struct manpaths *, char *, char);
|
||||
|
||||
|
||||
void
|
||||
@ -44,11 +43,11 @@ manconf_parse(struct manconf *conf, const char *file,
|
||||
char *insert;
|
||||
|
||||
/* Always prepend -m. */
|
||||
manpath_parseline(&conf->manpath, auxp, 1);
|
||||
manpath_parseline(&conf->manpath, auxp, 'm');
|
||||
|
||||
/* If -M is given, it overrides everything else. */
|
||||
if (NULL != defp) {
|
||||
manpath_parseline(&conf->manpath, defp, 1);
|
||||
manpath_parseline(&conf->manpath, defp, 'M');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -66,13 +65,13 @@ manconf_parse(struct manconf *conf, const char *file,
|
||||
/* Prepend man.conf(5) to MANPATH. */
|
||||
if (':' == defp[0]) {
|
||||
manconf_file(conf, file);
|
||||
manpath_parseline(&conf->manpath, defp, 0);
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append man.conf(5) to MANPATH. */
|
||||
if (':' == defp[strlen(defp) - 1]) {
|
||||
manpath_parseline(&conf->manpath, defp, 0);
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
manconf_file(conf, file);
|
||||
return;
|
||||
}
|
||||
@ -81,28 +80,28 @@ manconf_parse(struct manconf *conf, const char *file,
|
||||
insert = strstr(defp, "::");
|
||||
if (NULL != insert) {
|
||||
*insert++ = '\0';
|
||||
manpath_parseline(&conf->manpath, defp, 0);
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
manconf_file(conf, file);
|
||||
manpath_parseline(&conf->manpath, insert + 1, 0);
|
||||
manpath_parseline(&conf->manpath, insert + 1, '\0');
|
||||
return;
|
||||
}
|
||||
|
||||
/* MANPATH overrides man.conf(5) completely. */
|
||||
manpath_parseline(&conf->manpath, defp, 0);
|
||||
manpath_parseline(&conf->manpath, defp, '\0');
|
||||
}
|
||||
|
||||
void
|
||||
manpath_base(struct manpaths *dirs)
|
||||
{
|
||||
char path_base[] = MANPATH_BASE;
|
||||
manpath_parseline(dirs, path_base, 0);
|
||||
manpath_parseline(dirs, path_base, '\0');
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a FULL pathname from a colon-separated list of arrays.
|
||||
*/
|
||||
static void
|
||||
manpath_parseline(struct manpaths *dirs, char *path, int complain)
|
||||
manpath_parseline(struct manpaths *dirs, char *path, char option)
|
||||
{
|
||||
char *dir;
|
||||
|
||||
@ -110,7 +109,7 @@ manpath_parseline(struct manpaths *dirs, char *path, int complain)
|
||||
return;
|
||||
|
||||
for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
|
||||
manpath_add(dirs, dir, complain);
|
||||
manpath_add(dirs, dir, option);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -118,33 +117,32 @@ manpath_parseline(struct manpaths *dirs, char *path, int complain)
|
||||
* Grow the array one-by-one for simplicity's sake.
|
||||
*/
|
||||
static void
|
||||
manpath_add(struct manpaths *dirs, const char *dir, int complain)
|
||||
manpath_add(struct manpaths *dirs, const char *dir, char option)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
struct stat sb;
|
||||
char *cp;
|
||||
size_t i;
|
||||
|
||||
if (NULL == (cp = realpath(dir, buf))) {
|
||||
if (complain)
|
||||
warn("manpath: %s", dir);
|
||||
return;
|
||||
}
|
||||
if ((cp = realpath(dir, buf)) == NULL)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < dirs->sz; i++)
|
||||
if (0 == strcmp(dirs->paths[i], dir))
|
||||
if (strcmp(dirs->paths[i], dir) == 0)
|
||||
return;
|
||||
|
||||
if (stat(cp, &sb) == -1) {
|
||||
if (complain)
|
||||
warn("manpath: %s", dir);
|
||||
return;
|
||||
}
|
||||
if (stat(cp, &sb) == -1)
|
||||
goto fail;
|
||||
|
||||
dirs->paths = mandoc_reallocarray(dirs->paths,
|
||||
dirs->sz + 1, sizeof(char *));
|
||||
|
||||
dirs->sz + 1, sizeof(*dirs->paths));
|
||||
dirs->paths[dirs->sz++] = mandoc_strdup(cp);
|
||||
return;
|
||||
|
||||
fail:
|
||||
if (option != '\0')
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
|
||||
"-%c %s: %s", option, dir, strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
@ -210,7 +208,7 @@ manconf_file(struct manconf *conf, const char *file)
|
||||
*ep = '\0';
|
||||
/* FALLTHROUGH */
|
||||
case 0: /* manpath */
|
||||
manpath_add(&conf->manpath, cp, 0);
|
||||
manpath_add(&conf->manpath, cp, '\0');
|
||||
*manpath_default = '\0';
|
||||
break;
|
||||
case 1: /* output */
|
||||
@ -225,7 +223,7 @@ manconf_file(struct manconf *conf, const char *file)
|
||||
|
||||
out:
|
||||
if (*manpath_default != '\0')
|
||||
manpath_parseline(&conf->manpath, manpath_default, 0);
|
||||
manpath_parseline(&conf->manpath, manpath_default, '\0');
|
||||
}
|
||||
|
||||
int
|
||||
@ -235,14 +233,15 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
"includes", "man", "paper", "style", "indent", "width",
|
||||
"tag", "fragment", "mdoc", "noval", "toc"
|
||||
};
|
||||
const size_t ntoks = sizeof(toks) / sizeof(toks[0]);
|
||||
|
||||
const char *errstr;
|
||||
char *oldval;
|
||||
size_t len, tok;
|
||||
|
||||
for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {
|
||||
for (tok = 0; tok < ntoks; tok++) {
|
||||
len = strlen(toks[tok]);
|
||||
if ( ! strncmp(cp, toks[tok], len) &&
|
||||
if (strncmp(cp, toks[tok], len) == 0 &&
|
||||
strchr(" = ", cp[len]) != NULL) {
|
||||
cp += len;
|
||||
if (*cp == '=')
|
||||
@ -254,11 +253,11 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
}
|
||||
|
||||
if (tok < 6 && *cp == '\0') {
|
||||
warnx("-O %s=?: Missing argument value", toks[tok]);
|
||||
mandoc_msg(MANDOCERR_BADVAL_MISS, 0, 0, "-O %s=?", toks[tok]);
|
||||
return -1;
|
||||
}
|
||||
if (tok > 6 && *cp != '\0') {
|
||||
warnx("-O %s: Does not take a value: %s", toks[tok], cp);
|
||||
if (tok > 6 && tok < ntoks && *cp != '\0') {
|
||||
mandoc_msg(MANDOCERR_BADVAL, 0, 0, "-O %s=%s", toks[tok], cp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -299,7 +298,8 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
conf->indent = strtonum(cp, 0, 1000, &errstr);
|
||||
if (errstr == NULL)
|
||||
return 0;
|
||||
warnx("-O indent=%s is %s", cp, errstr);
|
||||
mandoc_msg(MANDOCERR_BADVAL_BAD, 0, 0,
|
||||
"-O indent=%s is %s", cp, errstr);
|
||||
return -1;
|
||||
case 5:
|
||||
if (conf->width) {
|
||||
@ -309,7 +309,8 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
conf->width = strtonum(cp, 1, 1000, &errstr);
|
||||
if (errstr == NULL)
|
||||
return 0;
|
||||
warnx("-O width=%s is %s", cp, errstr);
|
||||
mandoc_msg(MANDOCERR_BADVAL_BAD, 0, 0,
|
||||
"-O width=%s is %s", cp, errstr);
|
||||
return -1;
|
||||
case 6:
|
||||
if (conf->tag != NULL) {
|
||||
@ -331,13 +332,16 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
|
||||
conf->toc = 1;
|
||||
return 0;
|
||||
default:
|
||||
if (fromfile)
|
||||
warnx("-O %s: Bad argument", cp);
|
||||
mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0, "-O %s", cp);
|
||||
return -1;
|
||||
}
|
||||
if (fromfile) {
|
||||
free(oldval);
|
||||
return 0;
|
||||
} else {
|
||||
mandoc_msg(MANDOCERR_BADVAL_DUPE, 0, 0,
|
||||
"-O %s=%s: already set to %s", toks[tok], cp, oldval);
|
||||
free(oldval);
|
||||
return -1;
|
||||
}
|
||||
if (fromfile == 0)
|
||||
warnx("-O %s=%s: Option already set to %s",
|
||||
toks[tok], cp, oldval);
|
||||
free(oldval);
|
||||
return -1;
|
||||
}
|
||||
|
10
mansearch.c
10
mansearch.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mansearch.c,v 1.80 2018/12/13 11:55:46 schwarze Exp $ */
|
||||
/* $Id: mansearch.c,v 1.82 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -199,6 +199,7 @@ mansearch(const struct mansearch *search,
|
||||
}
|
||||
mpage->names = buildnames(page);
|
||||
mpage->output = buildoutput(outkey, page);
|
||||
mpage->bits = search->firstmatch ? rp->bits : 0;
|
||||
mpage->ipath = i;
|
||||
mpage->sec = *page->sect - '0';
|
||||
if (mpage->sec < 0 || mpage->sec > 9)
|
||||
@ -294,8 +295,10 @@ manmerge_term(struct expr *e, struct ohash *htab)
|
||||
break;
|
||||
slot = ohash_lookup_memory(htab,
|
||||
(char *)&res, sizeof(res.page), res.page);
|
||||
if ((rp = ohash_find(htab, slot)) != NULL)
|
||||
if ((rp = ohash_find(htab, slot)) != NULL) {
|
||||
rp->bits |= res.bits;
|
||||
continue;
|
||||
}
|
||||
rp = mandoc_malloc(sizeof(*rp));
|
||||
*rp = res;
|
||||
ohash_insert(htab, slot, rp);
|
||||
@ -408,7 +411,8 @@ manpage_compare(const void *vp1, const void *vp2)
|
||||
|
||||
mp1 = vp1;
|
||||
mp2 = vp2;
|
||||
if ((diff = mp1->sec - mp2->sec))
|
||||
if ((diff = mp2->bits - mp1->bits) ||
|
||||
(diff = mp1->sec - mp2->sec))
|
||||
return diff;
|
||||
|
||||
/* Fall back to alphabetic ordering of names. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mansearch.h,v 1.29 2018/11/22 12:01:46 schwarze Exp $ */
|
||||
/* $Id: mansearch.h,v 1.30 2019/04/30 18:51:57 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -92,6 +92,7 @@ struct manpage {
|
||||
char *file; /* to be prefixed by manpath */
|
||||
char *names; /* a list of names with sections */
|
||||
char *output; /* user-defined additional output */
|
||||
uint64_t bits; /* name type mask */
|
||||
size_t ipath; /* number of the manpath */
|
||||
int sec; /* section number, 10 means invalid */
|
||||
enum form form;
|
||||
|
38
mdoc.7
38
mdoc.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: mdoc.7,v 1.276 2019/02/07 15:45:53 schwarze Exp $
|
||||
.\" $Id: mdoc.7,v 1.279 2019/07/15 19:20:30 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2018 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: February 7 2019 $
|
||||
.Dd $Mdocdate: July 15 2019 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -596,6 +596,13 @@ block.
|
||||
Book or journal page number of an
|
||||
.Ic \&Rs
|
||||
block.
|
||||
Conventionally, the argument starts with
|
||||
.Ql p.\&
|
||||
for a single page or
|
||||
.Ql pp.\&
|
||||
for a range of pages, for example:
|
||||
.Pp
|
||||
.Dl .%P pp. 42\e(en47
|
||||
.It Ic \&%Q Ar name
|
||||
Institutional author (school, government, etc.) of an
|
||||
.Ic \&Rs
|
||||
@ -1156,17 +1163,19 @@ declarations.
|
||||
This practise is discouraged.
|
||||
.It Ic \&Cm Ar keyword ...
|
||||
Command modifiers.
|
||||
Typically used for fixed strings passed as arguments, unless
|
||||
Typically used for fixed strings passed as arguments to interactive
|
||||
commands, to commands in interpreted scripts, or to configuration
|
||||
file directives, unless
|
||||
.Ic \&Fl
|
||||
is more appropriate.
|
||||
Also useful when specifying configuration options or keys.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl ".Nm mt Fl f Ar device Cm rewind"
|
||||
.Dl ".Nm ps Fl o Cm pid , Ns Cm command"
|
||||
.Dl ".Nm dd Cm if= Ns Ar file1 Cm of= Ns Ar file2"
|
||||
.Dl ".Cm IdentityFile Pa ~/.ssh/id_rsa"
|
||||
.Dl ".Cm LogLevel Dv DEBUG"
|
||||
.Dl ".Ic set Fl o Cm vi"
|
||||
.Dl ".Ic lookup Cm file bind"
|
||||
.Dl ".Ic permit Ar identity Op Cm as Ar target"
|
||||
.It Ic \&D1 Ar line
|
||||
One-line indented display.
|
||||
This is formatted by the default rules and is useful for simple indented
|
||||
@ -1677,10 +1686,10 @@ This macro is not implemented in
|
||||
.Xr mandoc 1 .
|
||||
It was used to include the contents of a (header) file literally.
|
||||
.It Ic \&Ic Ar keyword ...
|
||||
Designate an internal or interactive command.
|
||||
This is similar to
|
||||
.Ic \&Cm
|
||||
but used for instructions rather than values.
|
||||
Internal or interactive command, or configuration instruction
|
||||
in a configuration file.
|
||||
See also
|
||||
.Ic \&Cm .
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Ic :wq
|
||||
@ -2969,7 +2978,7 @@ exclamation mark
|
||||
Note that even a period preceded by a backslash
|
||||
.Pq Sq \e.\&
|
||||
gets this special handling; use
|
||||
.Sq \e&.
|
||||
.Sq \e&.\&
|
||||
to prevent that.
|
||||
.Pp
|
||||
Many in-line macros interrupt their scope when they encounter
|
||||
@ -2996,6 +3005,13 @@ in the same way as a plain
|
||||
.Sq \&|
|
||||
character.
|
||||
Using this predefined string is not recommended in new manuals.
|
||||
.Pp
|
||||
Appending a zero-width space
|
||||
.Pq Sq \e&
|
||||
to the end of an input line is also useful to prevent the interpretation
|
||||
of a trailing period, exclamation or question mark as the end of a
|
||||
sentence, for example when an abbreviation happens to occur
|
||||
at the end of a text or macro input line.
|
||||
.Ss Font handling
|
||||
In
|
||||
.Nm
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_argv.c,v 1.119 2018/12/21 17:15:19 schwarze Exp $ */
|
||||
/* $Id: mdoc_argv.c,v 1.120 2019/07/11 17:06:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012, 2014-2019 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
|
||||
@ -454,6 +454,7 @@ args(struct roff_man *mdoc, int line, int *pos,
|
||||
mandoc_msg(MANDOCERR_ARG_QUOTE, line, *pos, NULL);
|
||||
mdoc->flags &= ~MDOC_PHRASELIT;
|
||||
}
|
||||
mdoc->flags &= ~MDOC_PHRASEQL;
|
||||
return ARGS_EOLN;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_markdown.c,v 1.30 2018/12/30 00:49:55 schwarze Exp $ */
|
||||
/* $Id: mdoc_markdown.c,v 1.31 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
|
25
mdoc_term.c
25
mdoc_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_term.c,v 1.372 2019/01/04 03:39:01 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.374 2019/06/27 12:20:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -253,7 +253,7 @@ static int fn_prio;
|
||||
void
|
||||
terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
{
|
||||
struct roff_node *n;
|
||||
struct roff_node *n, *nn;
|
||||
struct termp *p;
|
||||
size_t save_defindent;
|
||||
|
||||
@ -265,16 +265,20 @@ terminal_mdoc(void *arg, const struct roff_meta *mdoc)
|
||||
|
||||
n = mdoc->first->child;
|
||||
if (p->synopsisonly) {
|
||||
while (n != NULL) {
|
||||
if (n->tok == MDOC_Sh && n->sec == SEC_SYNOPSIS) {
|
||||
if (n->child->next->child != NULL)
|
||||
print_mdoc_nodelist(p, NULL,
|
||||
mdoc, n->child->next->child);
|
||||
term_newln(p);
|
||||
for (nn = NULL; n != NULL; n = n->next) {
|
||||
if (n->tok != MDOC_Sh)
|
||||
continue;
|
||||
if (n->sec == SEC_SYNOPSIS)
|
||||
break;
|
||||
}
|
||||
n = n->next;
|
||||
if (nn == NULL && n->sec == SEC_NAME)
|
||||
nn = n;
|
||||
}
|
||||
if (n == NULL)
|
||||
n = nn;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (n != NULL && (n = n->child->next->child) != NULL)
|
||||
print_mdoc_nodelist(p, NULL, mdoc, n);
|
||||
term_newln(p);
|
||||
} else {
|
||||
save_defindent = p->defindent;
|
||||
if (p->defindent == 0)
|
||||
@ -352,6 +356,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
* produce output. Note that some pre-handlers do so.
|
||||
*/
|
||||
|
||||
act = NULL;
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
if (n->flags & NODE_LINE) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_validate.c,v 1.371 2019/03/04 13:01:57 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.374 2019/06/27 15:07:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -64,7 +64,7 @@ static size_t macro2len(enum roff_tok);
|
||||
static void rewrite_macro2len(struct roff_man *, char **);
|
||||
static int similar(const char *, const char *);
|
||||
|
||||
static void post_abort(POST_ARGS);
|
||||
static void post_abort(POST_ARGS) __attribute__((__noreturn__));
|
||||
static void post_an(POST_ARGS);
|
||||
static void post_an_norm(POST_ARGS);
|
||||
static void post_at(POST_ARGS);
|
||||
@ -1903,8 +1903,7 @@ post_root(POST_ARGS)
|
||||
/* Add missing prologue data. */
|
||||
|
||||
if (mdoc->meta.date == NULL)
|
||||
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(mdoc, NULL, 0, 0);
|
||||
mdoc->meta.date = mandoc_normdate(mdoc, NULL, 0, 0);
|
||||
|
||||
if (mdoc->meta.title == NULL) {
|
||||
mandoc_msg(MANDOCERR_DT_NOTITLE, 0, 0, "EOF");
|
||||
@ -2519,21 +2518,10 @@ post_dd(POST_ARGS)
|
||||
mandoc_msg(MANDOCERR_PROLOG_ORDER,
|
||||
n->line, n->pos, "Dd after Os");
|
||||
|
||||
if (n->child == NULL || n->child->string[0] == '\0') {
|
||||
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
|
||||
mandoc_normdate(mdoc, NULL, n->line, n->pos);
|
||||
return;
|
||||
}
|
||||
|
||||
datestr = NULL;
|
||||
deroff(&datestr, n);
|
||||
if (mdoc->quick)
|
||||
mdoc->meta.date = datestr;
|
||||
else {
|
||||
mdoc->meta.date = mandoc_normdate(mdoc,
|
||||
datestr, n->line, n->pos);
|
||||
free(datestr);
|
||||
}
|
||||
mdoc->meta.date = mandoc_normdate(mdoc, datestr, n->line, n->pos);
|
||||
free(datestr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
4
out.c
4
out.c
@ -1,4 +1,4 @@
|
||||
/* $Id: out.c,v 1.77 2018/12/13 11:55:47 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.78 2019/03/29 21:27:06 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -149,7 +149,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
|
||||
gp = &first_group;
|
||||
for (dp = sp->first; dp != NULL; dp = dp->next) {
|
||||
icol = dp->layout->col;
|
||||
while (icol > maxcol)
|
||||
while (maxcol < icol + dp->hspans)
|
||||
tbl->cols[++maxcol].spacing = SIZE_MAX;
|
||||
col = tbl->cols + icol;
|
||||
col->flags |= dp->layout->flags;
|
||||
|
39
read.c
39
read.c
@ -1,4 +1,4 @@
|
||||
/* $Id: read.c,v 1.211 2019/01/11 17:04:44 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.214 2019/07/10 19:39:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -157,7 +157,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
ln.sz = 256;
|
||||
ln.buf = mandoc_malloc(ln.sz);
|
||||
ln.next = NULL;
|
||||
firstln = loop = NULL;
|
||||
firstln = lastln = loop = NULL;
|
||||
lnn = curp->line;
|
||||
pos = 0;
|
||||
inloop = 0;
|
||||
@ -255,6 +255,8 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
/* XXX Ugly hack to mark the end of the input. */
|
||||
|
||||
if (i == blk.sz || blk.buf[i] == '\0') {
|
||||
if (pos + 2 > ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
ln.buf[pos++] = '\n';
|
||||
ln.buf[pos] = '\0';
|
||||
}
|
||||
@ -429,9 +431,8 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
|
||||
int gzerrnum, retval;
|
||||
|
||||
if (fstat(fd, &st) == -1) {
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0,
|
||||
"fstat: %s", strerror(errno));
|
||||
return 0;
|
||||
mandoc_msg(MANDOCERR_FSTAT, 0, 0, "%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -444,13 +445,13 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
|
||||
if (curp->gzip == 0 && S_ISREG(st.st_mode)) {
|
||||
if (st.st_size > 0x7fffffff) {
|
||||
mandoc_msg(MANDOCERR_TOOLARGE, 0, 0, NULL);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
*with_mmap = 1;
|
||||
fb->sz = (size_t)st.st_size;
|
||||
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (fb->buf != MAP_FAILED)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (curp->gzip) {
|
||||
@ -462,15 +463,15 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
|
||||
* which this function must not do.
|
||||
*/
|
||||
if ((fd = dup(fd)) == -1) {
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0,
|
||||
"dup: %s", strerror(errno));
|
||||
return 0;
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if ((gz = gzdopen(fd, "rb")) == NULL) {
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0,
|
||||
"gzdopen: %s", strerror(errno));
|
||||
mandoc_msg(MANDOCERR_GZDOPEN, 0, 0,
|
||||
"%s", strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
gz = NULL;
|
||||
@ -482,7 +483,7 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
|
||||
|
||||
*with_mmap = 0;
|
||||
off = 0;
|
||||
retval = 0;
|
||||
retval = -1;
|
||||
fb->sz = 0;
|
||||
fb->buf = NULL;
|
||||
for (;;) {
|
||||
@ -498,13 +499,13 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
|
||||
read(fd, fb->buf + (int)off, fb->sz - off);
|
||||
if (ssz == 0) {
|
||||
fb->sz = off;
|
||||
retval = 1;
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
if (ssz == -1) {
|
||||
if (curp->gzip)
|
||||
(void)gzerror(gz, &gzerrnum);
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0, "read: %s",
|
||||
mandoc_msg(MANDOCERR_READ, 0, 0, "%s",
|
||||
curp->gzip && gzerrnum != Z_ERRNO ?
|
||||
zError(gzerrnum) : strerror(errno));
|
||||
break;
|
||||
@ -513,10 +514,10 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
|
||||
}
|
||||
|
||||
if (curp->gzip && (gzerrnum = gzclose(gz)) != Z_OK)
|
||||
mandoc_msg(MANDOCERR_FILE, 0, 0, "gzclose: %s",
|
||||
mandoc_msg(MANDOCERR_GZCLOSE, 0, 0, "%s",
|
||||
gzerrnum == Z_ERRNO ? strerror(errno) :
|
||||
zError(gzerrnum));
|
||||
if (retval == 0) {
|
||||
if (retval == -1) {
|
||||
free(fb->buf);
|
||||
fb->buf = NULL;
|
||||
}
|
||||
@ -555,7 +556,7 @@ mparse_readfd(struct mparse *curp, int fd, const char *filename)
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP, curp->line, 0, NULL);
|
||||
return;
|
||||
}
|
||||
if (read_whole_file(curp, fd, &blk, &with_mmap) == 0)
|
||||
if (read_whole_file(curp, fd, &blk, &with_mmap) == -1)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
15
roff.7
15
roff.7
@ -1,4 +1,4 @@
|
||||
.\" $Id: roff.7,v 1.111 2019/01/01 03:45:29 schwarze Exp $
|
||||
.\" $Id: roff.7,v 1.114 2019/07/15 19:20:30 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010-2019 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: January 1 2019 $
|
||||
.Dd $Mdocdate: July 15 2019 $
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -315,12 +315,18 @@ delimiters
|
||||
The proper spacing is also intelligently preserved if a sentence ends at
|
||||
the boundary of a macro line.
|
||||
.Pp
|
||||
If an input line happens to end with a period, exclamation or question
|
||||
mark that isn't the end of a sentence, append a zero-width space
|
||||
.Pq Sq \e& .
|
||||
.Pp
|
||||
Examples:
|
||||
.Bd -literal -offset indent -compact
|
||||
Do not end sentences mid-line like this. Instead,
|
||||
end a sentence like this.
|
||||
A macro would end like this:
|
||||
\&.Xr mandoc 1 \&.
|
||||
An abbreviation at the end of an input line needs escaping, e.g.\e&
|
||||
like this.
|
||||
.Ed
|
||||
.Sh REQUEST SYNTAX
|
||||
A request or macro line consists of:
|
||||
@ -503,10 +509,9 @@ This is a Heirloom extension and currently unsupported.
|
||||
.It Ic \&br
|
||||
Break the output line.
|
||||
.It Ic \&break
|
||||
Break out of a
|
||||
Break out of the innermost
|
||||
.Ic \&while
|
||||
loop.
|
||||
Currently unsupported.
|
||||
.It Ic \&breakchar Ar char ...
|
||||
Optional line break characters.
|
||||
This is a Heirloom extension and currently ignored.
|
||||
@ -2279,7 +2284,7 @@ code.
|
||||
.Pp
|
||||
The special semantics of the
|
||||
.Cm nS
|
||||
number register is an idiosyncracy of
|
||||
number register is an idiosyncrasy of
|
||||
.Ox
|
||||
manuals and not supported by other
|
||||
.Xr mdoc 7
|
||||
|
66
roff.c
66
roff.c
@ -1,4 +1,4 @@
|
||||
/* $Id: roff.c,v 1.363 2019/02/06 21:11:43 schwarze Exp $ */
|
||||
/* $Id: roff.c,v 1.366 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -133,15 +133,18 @@ struct roff {
|
||||
char escape; /* escape character */
|
||||
};
|
||||
|
||||
/*
|
||||
* A macro definition, condition, or ignored block.
|
||||
*/
|
||||
struct roffnode {
|
||||
enum roff_tok tok; /* type of node */
|
||||
struct roffnode *parent; /* up one in stack */
|
||||
int line; /* parse line */
|
||||
int col; /* parse col */
|
||||
char *name; /* node name, e.g. macro name */
|
||||
char *end; /* end-rules: custom token */
|
||||
int endspan; /* end-rules: next-line or infty */
|
||||
int rule; /* current evaluation rule */
|
||||
char *end; /* custom end macro of the block */
|
||||
int endspan; /* scope to: 1=eol 2=next line -1=\} */
|
||||
int rule; /* content is: 1=evaluated 0=skipped */
|
||||
};
|
||||
|
||||
#define ROFF_ARGS struct roff *r, /* parse ctx */ \
|
||||
@ -181,6 +184,7 @@ static int roff_als(ROFF_ARGS);
|
||||
static int roff_block(ROFF_ARGS);
|
||||
static int roff_block_text(ROFF_ARGS);
|
||||
static int roff_block_sub(ROFF_ARGS);
|
||||
static int roff_break(ROFF_ARGS);
|
||||
static int roff_cblock(ROFF_ARGS);
|
||||
static int roff_cc(ROFF_ARGS);
|
||||
static int roff_ccond(struct roff *, int, int);
|
||||
@ -400,7 +404,7 @@ static struct roffmac roffs[TOKEN_NONE] = {
|
||||
{ roff_unsupp, NULL, NULL, 0 }, /* boxa */
|
||||
{ roff_line_ignore, NULL, NULL, 0 }, /* bp */
|
||||
{ roff_unsupp, NULL, NULL, 0 }, /* BP */
|
||||
{ roff_unsupp, NULL, NULL, 0 }, /* break */
|
||||
{ roff_break, NULL, NULL, 0 }, /* break */
|
||||
{ roff_line_ignore, NULL, NULL, 0 }, /* breakchar */
|
||||
{ roff_line_ignore, NULL, NULL, 0 }, /* brnl */
|
||||
{ roff_noarg, NULL, NULL, 0 }, /* brp */
|
||||
@ -685,7 +689,7 @@ roffhash_find(struct ohash *htab, const char *name, size_t sz)
|
||||
|
||||
/*
|
||||
* Pop the current node off of the stack of roff instructions currently
|
||||
* pending.
|
||||
* pending. Return 1 if it is a loop or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
roffnode_pop(struct roff *r)
|
||||
@ -779,7 +783,7 @@ roff_reset(struct roff *r)
|
||||
void
|
||||
roff_free(struct roff *r)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
roff_free1(r);
|
||||
for (i = 0; i < r->mstacksz; i++)
|
||||
@ -1586,7 +1590,7 @@ char *
|
||||
roff_getarg(struct roff *r, char **cpp, int ln, int *pos)
|
||||
{
|
||||
struct buf buf;
|
||||
char *cp, *start;
|
||||
char *cp, *start;
|
||||
int newesc, pairs, quoted, white;
|
||||
|
||||
/* Quoting can only start with a new word. */
|
||||
@ -2002,6 +2006,10 @@ roff_cblock(ROFF_ARGS)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop all nodes ending at the end of the current input line.
|
||||
* Return the number of loops ended.
|
||||
*/
|
||||
static int
|
||||
roffnode_cleanscope(struct roff *r)
|
||||
{
|
||||
@ -2016,6 +2024,11 @@ roffnode_cleanscope(struct roff *r)
|
||||
return inloop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the closing \} of a conditional block.
|
||||
* Apart from generating warnings, this only pops nodes.
|
||||
* Return the number of loops ended.
|
||||
*/
|
||||
static int
|
||||
roff_ccond(struct roff *r, int ln, int ppos)
|
||||
{
|
||||
@ -2235,6 +2248,7 @@ roff_block_text(ROFF_ARGS)
|
||||
static int
|
||||
roff_cond_sub(ROFF_ARGS)
|
||||
{
|
||||
struct roffnode *bl;
|
||||
char *ep;
|
||||
int endloop, irc, rr;
|
||||
enum roff_tok t;
|
||||
@ -2282,9 +2296,21 @@ roff_cond_sub(ROFF_ARGS)
|
||||
*/
|
||||
|
||||
t = roff_parse(r, buf->buf, &pos, ln, ppos);
|
||||
irc |= t != TOKEN_NONE && (rr || roffs[t].flags & ROFFMAC_STRUCT) ?
|
||||
(*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs) :
|
||||
rr ? ROFF_CONT : ROFF_IGN;
|
||||
if (t == ROFF_break) {
|
||||
if (irc & ROFF_LOOPMASK)
|
||||
irc = ROFF_IGN | ROFF_LOOPEXIT;
|
||||
else if (rr) {
|
||||
for (bl = r->last; bl != NULL; bl = bl->parent) {
|
||||
bl->rule = 0;
|
||||
if (bl->tok == ROFF_while)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (t != TOKEN_NONE &&
|
||||
(rr || roffs[t].flags & ROFFMAC_STRUCT))
|
||||
irc |= (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs);
|
||||
else
|
||||
irc |= rr ? ROFF_CONT : ROFF_IGN;
|
||||
return irc;
|
||||
}
|
||||
|
||||
@ -3482,6 +3508,17 @@ roff_als(ROFF_ARGS)
|
||||
return ROFF_IGN;
|
||||
}
|
||||
|
||||
/*
|
||||
* The .break request only makes sense inside conditionals,
|
||||
* and that case is already handled in roff_cond_sub().
|
||||
*/
|
||||
static int
|
||||
roff_break(ROFF_ARGS)
|
||||
{
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, ln, pos, "break");
|
||||
return ROFF_IGN;
|
||||
}
|
||||
|
||||
static int
|
||||
roff_cc(ROFF_ARGS)
|
||||
{
|
||||
@ -3804,6 +3841,11 @@ roff_userdef(ROFF_ARGS)
|
||||
char *arg, *ap, *dst, *src;
|
||||
size_t sz;
|
||||
|
||||
/* If the macro is empty, ignore it altogether. */
|
||||
|
||||
if (*r->current_string == '\0')
|
||||
return ROFF_IGN;
|
||||
|
||||
/* Initialize a new macro stack context. */
|
||||
|
||||
if (++r->mstackpos == r->mstacksz) {
|
||||
@ -3851,7 +3893,7 @@ roff_userdef(ROFF_ARGS)
|
||||
buf->sz = strlen(buf->buf) + 1;
|
||||
*offs = 0;
|
||||
|
||||
return buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?
|
||||
return buf->buf[buf->sz - 2] == '\n' ?
|
||||
ROFF_REPARSE | ROFF_USERCALL : ROFF_IGN | ROFF_APPEND;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: roff_html.c,v 1.19 2019/01/07 07:26:29 schwarze Exp $ */
|
||||
/* $Id: roff_html.c,v 1.20 2019/04/30 15:53:01 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -94,7 +94,7 @@ roff_html_pre_ft(ROFF_HTML_ARGS)
|
||||
const char *cp;
|
||||
|
||||
cp = n->child->string;
|
||||
print_metaf(h, mandoc_font(cp, (int)strlen(cp)));
|
||||
html_setfont(h, mandoc_font(cp, (int)strlen(cp)));
|
||||
}
|
||||
|
||||
static void
|
||||
|
49
tag.c
49
tag.c
@ -1,6 +1,6 @@
|
||||
/* $Id: tag.c,v 1.21 2018/11/22 11:30:23 schwarze Exp $ */
|
||||
/* $Id: tag.c,v 1.24 2019/07/22 03:21:50 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2015, 2016, 2018, 2019 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
|
||||
@ -18,9 +18,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if HAVE_ERR
|
||||
#include <err.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
@ -32,6 +30,7 @@
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc_ohash.h"
|
||||
#include "mandoc.h"
|
||||
#include "tag.h"
|
||||
|
||||
struct tag_entry {
|
||||
@ -83,8 +82,10 @@ tag_init(void)
|
||||
|
||||
/* Save the original standard output for use by the pager. */
|
||||
|
||||
if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1)
|
||||
if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Create both temporary output files. */
|
||||
|
||||
@ -92,12 +93,20 @@ tag_init(void)
|
||||
sizeof(tag_files.ofn));
|
||||
(void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
|
||||
sizeof(tag_files.tfn));
|
||||
if ((ofd = mkstemp(tag_files.ofn)) == -1)
|
||||
if ((ofd = mkstemp(tag_files.ofn)) == -1) {
|
||||
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
|
||||
"%s: %s", tag_files.ofn, strerror(errno));
|
||||
goto fail;
|
||||
if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1)
|
||||
}
|
||||
if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1) {
|
||||
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
|
||||
"%s: %s", tag_files.tfn, strerror(errno));
|
||||
goto fail;
|
||||
if (dup2(ofd, STDOUT_FILENO) == -1)
|
||||
}
|
||||
if (dup2(ofd, STDOUT_FILENO) == -1) {
|
||||
mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
close(ofd);
|
||||
|
||||
/*
|
||||
@ -142,11 +151,11 @@ tag_put(const char *s, int prio, size_t line)
|
||||
s += 2;
|
||||
|
||||
/*
|
||||
* Skip whitespace and whatever follows it,
|
||||
* Skip whitespace and escapes and whatever follows,
|
||||
* and if there is any, downgrade the priority.
|
||||
*/
|
||||
|
||||
len = strcspn(s, " \t");
|
||||
len = strcspn(s, " \t\\");
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
@ -216,21 +225,27 @@ tag_write(void)
|
||||
struct tag_entry *entry;
|
||||
size_t i;
|
||||
unsigned int slot;
|
||||
int empty;
|
||||
|
||||
if (tag_files.tfd <= 0)
|
||||
return;
|
||||
if (tag_files.tagname != NULL && ohash_find(&tag_data,
|
||||
ohash_qlookup(&tag_data, tag_files.tagname)) == NULL) {
|
||||
warnx("%s: no such tag", tag_files.tagname);
|
||||
mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname);
|
||||
tag_files.tagname = NULL;
|
||||
}
|
||||
stream = fdopen(tag_files.tfd, "w");
|
||||
if ((stream = fdopen(tag_files.tfd, "w")) == NULL)
|
||||
mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
|
||||
empty = 1;
|
||||
entry = ohash_first(&tag_data, &slot);
|
||||
while (entry != NULL) {
|
||||
if (stream != NULL && entry->prio >= 0)
|
||||
for (i = 0; i < entry->nlines; i++)
|
||||
if (stream != NULL && entry->prio >= 0) {
|
||||
for (i = 0; i < entry->nlines; i++) {
|
||||
fprintf(stream, "%s %s %zu\n",
|
||||
entry->s, tag_files.ofn, entry->lines[i]);
|
||||
empty = 0;
|
||||
}
|
||||
}
|
||||
free(entry->lines);
|
||||
free(entry);
|
||||
entry = ohash_next(&tag_data, &slot);
|
||||
@ -241,6 +256,10 @@ tag_write(void)
|
||||
else
|
||||
close(tag_files.tfd);
|
||||
tag_files.tfd = -1;
|
||||
if (empty) {
|
||||
unlink(tag_files.tfn);
|
||||
*tag_files.tfn = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_html.c,v 1.32 2019/01/06 04:55:09 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.33 2019/03/17 18:21:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "tbl.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
49
tbl_term.c
49
tbl_term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_term.c,v 1.68 2019/02/09 21:02:47 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.72 2019/07/01 22:56:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -46,7 +46,8 @@ static void tbl_fill_border(struct termp *, int, size_t);
|
||||
static void tbl_fill_char(struct termp *, char, size_t);
|
||||
static void tbl_fill_string(struct termp *, const char *, size_t);
|
||||
static void tbl_hrule(struct termp *, const struct tbl_span *,
|
||||
const struct tbl_span *, int);
|
||||
const struct tbl_span *, const struct tbl_span *,
|
||||
int);
|
||||
static void tbl_literal(struct termp *, const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_number(struct termp *, const struct tbl_opts *,
|
||||
@ -163,7 +164,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
const struct tbl_cell *cp, *cpn, *cpp, *cps;
|
||||
const struct tbl_dat *dp;
|
||||
static size_t offset;
|
||||
size_t save_offset;
|
||||
size_t save_offset;
|
||||
size_t coloff, tsz;
|
||||
int hspans, ic, more;
|
||||
int dvert, fc, horiz, lhori, rhori, uvert;
|
||||
@ -222,9 +223,9 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
|
||||
if (tp->enc == TERMENC_ASCII &&
|
||||
sp->opts->opts & TBL_OPT_DBOX)
|
||||
tbl_hrule(tp, NULL, sp, TBL_OPT_DBOX);
|
||||
tbl_hrule(tp, NULL, sp, sp, TBL_OPT_DBOX);
|
||||
if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX))
|
||||
tbl_hrule(tp, NULL, sp, TBL_OPT_BOX);
|
||||
tbl_hrule(tp, NULL, sp, sp, TBL_OPT_BOX);
|
||||
}
|
||||
|
||||
/* Set up the columns. */
|
||||
@ -342,7 +343,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
|
||||
more = 0;
|
||||
if (horiz)
|
||||
tbl_hrule(tp, sp->prev, sp, 0);
|
||||
tbl_hrule(tp, sp->prev, sp, sp->next, 0);
|
||||
else {
|
||||
cp = sp->layout->first;
|
||||
cpn = sp->next == NULL ? NULL :
|
||||
@ -557,12 +558,12 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
tp->tcol->rmargin = tp->maxrmargin;
|
||||
if (sp->next == NULL) {
|
||||
if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX)) {
|
||||
tbl_hrule(tp, sp, NULL, TBL_OPT_BOX);
|
||||
tbl_hrule(tp, sp, sp, NULL, TBL_OPT_BOX);
|
||||
tp->skipvsp = 1;
|
||||
}
|
||||
if (tp->enc == TERMENC_ASCII &&
|
||||
sp->opts->opts & TBL_OPT_DBOX) {
|
||||
tbl_hrule(tp, sp, NULL, TBL_OPT_DBOX);
|
||||
tbl_hrule(tp, sp, sp, NULL, TBL_OPT_DBOX);
|
||||
tp->skipvsp = 2;
|
||||
}
|
||||
assert(tp->tbl.cols);
|
||||
@ -571,7 +572,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
} else if (horiz == 0 && sp->opts->opts & TBL_OPT_ALLBOX &&
|
||||
(sp->next == NULL || sp->next->pos == TBL_SPAN_DATA ||
|
||||
sp->next->next != NULL))
|
||||
tbl_hrule(tp, sp, sp->next, TBL_OPT_ALLBOX);
|
||||
tbl_hrule(tp, sp, sp, sp->next, TBL_OPT_ALLBOX);
|
||||
|
||||
tp->tcol->offset = save_offset;
|
||||
tp->flags &= ~TERMP_NONOSPACE;
|
||||
@ -579,9 +580,10 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
|
||||
static void
|
||||
tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
const struct tbl_span *spn, int flags)
|
||||
const struct tbl_span *sp, const struct tbl_span *spn, int flags)
|
||||
{
|
||||
const struct tbl_cell *cpp; /* Layout cell above this line. */
|
||||
const struct tbl_cell *cp; /* Layout cell in this line. */
|
||||
const struct tbl_cell *cpn; /* Layout cell below this line. */
|
||||
const struct tbl_dat *dpn; /* Data cell below this line. */
|
||||
const struct roffcol *col; /* Contains width and spacing. */
|
||||
@ -592,6 +594,7 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
int uw, dw; /* Vertical line widths. */
|
||||
|
||||
cpp = spp == NULL ? NULL : spp->layout->first;
|
||||
cp = sp == NULL ? NULL : sp->layout->first;
|
||||
cpn = spn == NULL ? NULL : spn->layout->first;
|
||||
dpn = NULL;
|
||||
if (spn != NULL) {
|
||||
@ -600,11 +603,11 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
else if (spn->next != NULL)
|
||||
dpn = spn->next->first;
|
||||
}
|
||||
opts = spn == NULL ? spp->opts->opts : spn->opts->opts;
|
||||
opts = sp->opts->opts;
|
||||
bw = opts & TBL_OPT_DBOX ? (tp->enc == TERMENC_UTF8 ? 2 : 1) :
|
||||
opts & (TBL_OPT_BOX | TBL_OPT_ALLBOX) ? 1 : 0;
|
||||
hw = flags == TBL_OPT_DBOX || flags == TBL_OPT_BOX ? bw :
|
||||
spn->pos == TBL_SPAN_DHORIZ ? 2 : 1;
|
||||
sp->pos == TBL_SPAN_DHORIZ ? 2 : 1;
|
||||
|
||||
/* Print the left end of the line. */
|
||||
|
||||
@ -619,14 +622,19 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
(spp == NULL || cpn == NULL ||
|
||||
cpn->pos != TBL_CELL_DOWN ? BRIGHT * hw : 0), 1);
|
||||
|
||||
col = tp->tbl.cols;
|
||||
for (;;) {
|
||||
col = tp->tbl.cols + (cpn == NULL ? cpp->col : cpn->col);
|
||||
if (cp == NULL)
|
||||
col++;
|
||||
else
|
||||
col = tp->tbl.cols + cp->col;
|
||||
|
||||
/* Print the horizontal line inside this column. */
|
||||
|
||||
lw = cpp == NULL || cpn == NULL ||
|
||||
(cpn->pos != TBL_CELL_DOWN &&
|
||||
(dpn == NULL || strcmp(dpn->string, "\\^") != 0))
|
||||
(dpn == NULL || dpn->string == NULL ||
|
||||
strcmp(dpn->string, "\\^") != 0))
|
||||
? hw : 0;
|
||||
tbl_direct_border(tp, BHORIZ * lw,
|
||||
col->width + col->spacing / 2);
|
||||
@ -645,7 +653,10 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
uw = 1;
|
||||
}
|
||||
cpp = cpp->next;
|
||||
}
|
||||
} else if (spp != NULL && opts & TBL_OPT_ALLBOX)
|
||||
uw = 1;
|
||||
if (cp != NULL)
|
||||
cp = cp->next;
|
||||
if (cpn != NULL) {
|
||||
if (flags != TBL_OPT_DBOX) {
|
||||
dw = cpn->vert;
|
||||
@ -655,8 +666,9 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
cpn = cpn->next;
|
||||
while (dpn != NULL && dpn->layout != cpn)
|
||||
dpn = dpn->next;
|
||||
}
|
||||
if (cpp == NULL && cpn == NULL)
|
||||
} else if (spn != NULL && opts & TBL_OPT_ALLBOX)
|
||||
dw = 1;
|
||||
if (col + 1 == tp->tbl.cols + sp->opts->cols)
|
||||
break;
|
||||
|
||||
/* Vertical lines do not cross spanned cells. */
|
||||
@ -670,7 +682,8 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
|
||||
|
||||
rw = cpp == NULL || cpn == NULL ||
|
||||
(cpn->pos != TBL_CELL_DOWN &&
|
||||
(dpn == NULL || strcmp(dpn->string, "\\^") != 0))
|
||||
(dpn == NULL || dpn->string == NULL ||
|
||||
strcmp(dpn->string, "\\^") != 0))
|
||||
? hw : 0;
|
||||
|
||||
/* The line crossing at the end of this column. */
|
||||
|
4
term.c
4
term.c
@ -1,4 +1,4 @@
|
||||
/* $Id: term.c,v 1.280 2019/01/15 12:16:18 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.281 2019/06/03 20:23:41 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -281,6 +281,8 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
|
||||
case ASCII_BREAK:
|
||||
vn = vis;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
/* Can break at the end of a word. */
|
||||
if (breakline || vn > vtarget)
|
||||
|
Loading…
Reference in New Issue
Block a user