docs: ascii version of manpage without nroff

Create ASCII version of manpage without nroff

 - build src/tool_hugegelp.c from the ascii manpage
 - move the the manpage and the ascii version build to docs/cmdline-opts
 - remove all use of nroff from the build process
 - should make the build entirely reproducible (by avoiding nroff)

 - partly reverts 2620aa9 to build libcurl option man pages one by one
   in cmake because the appveyor builds got all crazy until I did

The ASCII version of the manpage

 - is built with gen.pl, just like the manpage is
 - has a right-justified column making the appearance similar to the previous
   version
 - uses a 4-space indent per level (instead of the old version's 7)
 - does not do hyphenation of words (which nroff does)

History

  We first made the curl build use nroff for building the hugehelp file in
  December 1998, for curl 5.2.

Closes #13047
This commit is contained in:
Daniel Stenberg 2024-03-04 17:22:17 +01:00
parent 9978d40ddb
commit f03c85635f
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
22 changed files with 280 additions and 257 deletions

View File

@ -68,35 +68,6 @@ macro(curl_internal_test CURL_TEST)
endif()
endmacro()
macro(curl_nroff_check)
find_program(NROFF NAMES gnroff nroff)
if(NROFF)
# Need a way to write to stdin, this will do
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
# Tests for a valid nroff option to generate a manpage
foreach(_MANOPT "-man" "-mandoc")
execute_process(COMMAND "${NROFF}" ${_MANOPT}
OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
ERROR_QUIET)
# Save the option if it was valid
if(NROFF_MANOPT_OUTPUT)
message("Found *nroff option: -- ${_MANOPT}")
set(NROFF_MANOPT ${_MANOPT})
set(NROFF_USEFUL ON)
break()
endif()
endforeach()
# No need for the temporary file
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
if(NOT NROFF_USEFUL)
message(WARNING "Found no *nroff option to get plaintext from man pages")
endif()
else()
message(WARNING "Found no *nroff program")
endif()
endmacro()
macro(optional_dependency DEPENDENCY)
set(CURL_${DEPENDENCY} AUTO CACHE STRING "Build curl with ${DEPENDENCY} support (AUTO, ON or OFF)")
set_property(CACHE CURL_${DEPENDENCY} PROPERTY STRINGS AUTO ON OFF)

View File

@ -312,13 +312,10 @@ option(ENABLE_CURL_MANUAL "to build the man page for curl and enable its -M/--ma
if(ENABLE_CURL_MANUAL OR BUILD_LIBCURL_DOCS)
if(PERL_FOUND)
curl_nroff_check()
if(NROFF_USEFUL)
set(HAVE_MANUAL_TOOLS ON)
endif()
set(HAVE_MANUAL_TOOLS ON)
endif()
if(NOT HAVE_MANUAL_TOOLS)
message(WARNING "Perl not found, or nroff not useful. Will not build manuals.")
message(WARNING "Perl not found. Will not build manuals.")
endif()
endif()

View File

@ -36,9 +36,9 @@ following software installed:
o libtool 1.4.2 (or later)
o GNU m4 (required by autoconf)
o nroff + perl
o perl
If you don't have nroff and perl and you for some reason don't want to
install them, you can rename the source file src/tool_hugehelp.c.cvs to
src/tool_hugehelp.c and avoid having to generate this file. This will
give you a stubbed version of the file that doesn't contain actual content.
If you don't have perl and don't want to install it, you can rename the
source file src/tool_hugehelp.c.cvs to src/tool_hugehelp.c and avoid having
to generate this file. This will give you a stubbed version of the file
that doesn't contain actual content.

View File

@ -134,7 +134,7 @@ CLEANFILES = $(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ) \
bin_SCRIPTS = curl-config
SUBDIRS = lib src scripts
SUBDIRS = lib docs src scripts
DIST_SUBDIRS = $(SUBDIRS) tests packages scripts include docs
pkgconfigdir = $(libdir)/pkgconfig

View File

@ -3826,10 +3826,6 @@ AC_CHECK_DECL([fseeko],
CURL_CHECK_NONBLOCKING_SOCKET
dnl ************************************************************
dnl nroff tool stuff
dnl
AC_PATH_PROG( PERL, perl, ,
$PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin )
AC_SUBST(PERL)
@ -3844,40 +3840,6 @@ fi
dnl set variable for use in automakefile(s)
AM_CONDITIONAL(BUILD_DOCS, test x"$BUILD_DOCS" = x1)
AC_PATH_PROGS( NROFF, gnroff nroff, ,
$PATH:/usr/bin/:/usr/local/bin )
AC_SUBST(NROFF)
if test -n "$NROFF"; then
dnl only check for nroff options if an nroff command was found
AC_MSG_CHECKING([how to use *nroff to get plain text from man pages])
MANOPT="-man"
mancheck=`echo foo | $NROFF $MANOPT 2>/dev/null`
if test -z "$mancheck"; then
MANOPT="-mandoc"
mancheck=`echo foo | $NROFF $MANOPT 2>/dev/null`
if test -z "$mancheck"; then
MANOPT=""
AC_MSG_RESULT([failed])
AC_MSG_WARN([found no *nroff option to get plaintext from man pages])
else
AC_MSG_RESULT([$MANOPT])
fi
else
AC_MSG_RESULT([$MANOPT])
fi
AC_SUBST(MANOPT)
fi
if test -z "$MANOPT"
then
dnl if no nroff tool was found, or no option that could convert man pages
dnl was found, then disable the built-in manual stuff
AC_MSG_WARN([disabling built-in manual])
USE_MANUAL="no";
fi
dnl *************************************************************************
dnl If the manual variable still is set, then we go with providing a built-in
dnl manual

View File

@ -43,7 +43,6 @@ versions of libs and build tools.
- GNU M4 1.4
- perl 5.6
- roffit 0.5
- nroff any version that supports `-man [in] [out]`
- cmake 3.7
Library Symbols

View File

@ -30,16 +30,14 @@ MK_CA_DOCS = mk-ca-bundle.1
CURLCONF_DOCS = curl-config.1
endif
man_MANS = $(abs_builddir)/curl.1 curl-config.1
man_MANS = curl-config.1
CURLPAGES = curl-config.md mk-ca-bundle.md
# Build targets in this file (.) before cmdline-opts to ensure that
# the curl.1 rule below runs first
SUBDIRS = . cmdline-opts libcurl
DIST_SUBDIRS = $(SUBDIRS) examples
if BUILD_DOCS
CLEANFILES = curl.1 mk-ca-bundle.1 curl-config.1
CLEANFILES = mk-ca-bundle.1 curl-config.1
endif
EXTRA_DIST = \
@ -112,20 +110,6 @@ SUFFIXES = .1 .md
all: $(MK_CA_DOCS)
# $(abs_builddir) is to disable VPATH when searching for this file, which
# would otherwise find the copy in $(srcdir) which breaks the $(HUGE)
# rule in src/Makefile.am in out-of-tree builds that references the file in the
# build directory.
#
# First, seed the used copy of curl.1 with the prebuilt copy (in an out-of-tree
# build), then run make recursively to rebuild it only if its dependencies
# have changed.
$(abs_builddir)/curl.1:
if test "$(top_builddir)x" != "$(top_srcdir)x" -a -e "$(srcdir)/curl.1"; then \
$(INSTALL_DATA) "$(srcdir)/curl.1" $@ \
&& touch -r "$(srcdir)/curl.1" $@; fi
cd cmdline-opts && $(MAKE)
.md.1:
$(CD2)$(CD2NROFF)
@ -135,6 +119,3 @@ mk-ca-bundle.1: mk-ca-bundle.md
distclean:
rm -f $(CLEANFILES)
dist-hook:
cp $(builddir)/curl.1 $(builddir)/curl.1.dist

View File

@ -177,7 +177,6 @@
18.29 --retry and transfer timeouts
19. Build
19.1 avoid nroff
19.2 Enable PIE and RELRO by default
19.3 Do not use GNU libtool on OpenBSD
19.4 Package curl for Windows in a signed installer
@ -1291,14 +1290,6 @@
19. Build
19.1 avoid nroff
With the switch to the markdown-like documentation format since curl 8.6.0,
it should (with a manageable amount of work) be possible to render an ASCII
version of the man page without involving nroff and thus remove that
dependency for building the hugehelp file, used to build in the man page into
the curl command line tool.
19.2 Enable PIE and RELRO by default
Especially when having programs that execute curl via the command line, PIE

View File

@ -21,7 +21,8 @@
# SPDX-License-Identifier: curl
#
###########################################################################
set(MANPAGE "${CURL_BINARY_DIR}/docs/curl.1")
set(MANPAGE "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.1")
set(ASCIIPAGE "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt")
# Load DPAGES and OTHERPAGES from shared file
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
@ -29,6 +30,7 @@ include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
add_custom_command(OUTPUT "${MANPAGE}"
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && "${PERL_EXECUTABLE}" "./gen.pl" mainpage ${DPAGES} > "${MANPAGE}"
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && "${PERL_EXECUTABLE}" "./gen.pl" ascii ${DPAGES} > "${ASCIIPAGE}"
VERBATIM
)
add_custom_target(generate-curl.1 ALL DEPENDS "${MANPAGE}")

View File

@ -24,7 +24,10 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
MANPAGE = $(top_builddir)/docs/curl.1
MANPAGE = curl.1
ASCIIPAGE = curl.txt
man_MANS = $(MANPAGE)
include Makefile.inc
@ -35,10 +38,21 @@ GN_0 = @echo " GENERATE" $@;
GN_1 =
GN_ = $(GN_0)
all: $(MANPAGE)
if BUILD_DOCS
CLEANFILES = $(MANPAGE) $(ASCIIPAGE)
all: $(MANPAGE) $(ASCIIPAGE)
endif
$(MANPAGE): $(DPAGES) $(SUPPORT) mainpage.idx Makefile.inc gen.pl
$(GEN)(rm -f $(MANPAGE) && cd $(srcdir) && @PERL@ ./gen.pl mainpage $(DPAGES) > $(builddir)/manpage.tmp.$$$$ && mv $(builddir)/manpage.tmp.$$$$ $(MANPAGE))
$(GEN)(rm -f $(MANPAGE) && (cd $(srcdir) && @PERL@ ./gen.pl mainpage $(DPAGES)) > manpage.tmp.$$$$ && mv manpage.tmp.$$$$ $(MANPAGE))
$(ASCIIPAGE): $(DPAGES) $(SUPPORT) mainpage.idx Makefile.inc gen.pl
$(GEN)(rm -f $(ASCIIPAGE) && (cd $(srcdir) && @PERL@ ./gen.pl ascii $(DPAGES)) > asciipage.tmp.$$$$ && mv asciipage.tmp.$$$$ $(ASCIIPAGE))
listhelp:
./gen.pl listhelp $(DPAGES) > $(top_builddir)/src/tool_listhelp.c
dist-hook: $(MANPAGE)
cp $(MANPAGE) $(MANPAGE).dist

View File

@ -1,6 +1,6 @@
<!-- Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. -->
<!-- SPDX-License-Identifier: curl -->
# "PROGRESS METER"
# PROGRESS METER
curl normally displays a progress meter during operations, indicating the
amount of transferred data, transfer speeds and estimated time left, etc. The

View File

@ -93,11 +93,115 @@ sub manpageify {
return $l;
}
my $colwidth=78; # max number of columns
sub justline {
my ($lvl, @line) = @_;
my $w = -1;
my $spaces = -1;
my $width = $colwidth - ($lvl * 4);
for(@line) {
$w += length($_);
$w++;
$spaces++;
}
my $inject = $width - $w;
my $ratio = 0; # stay at zero if no spaces at all
if($spaces) {
$ratio = $inject / $spaces;
}
my $spare = 0;
print ' ' x ($lvl * 4);
my $prev;
for(@line) {
while($spare >= 0.90) {
print " ";
$spare--;
}
printf "%s%s", $prev?" ":"", $_;
$prev = 1;
$spare += $ratio;
}
print "\n";
}
sub lastline {
my ($lvl, @line) = @_;
print ' ' x ($lvl * 4);
my $prev = 0;
for(@line) {
printf "%s%s", $prev?" ":"", $_;
$prev = 1;
}
print "\n";
}
sub outputpara {
my ($lvl, $f) = @_;
$f =~ s/\n/ /g;
my $w = 0;
my @words = split(/ */, $f);
my $width = $colwidth - ($lvl * 4);
my @line;
for my $e (@words) {
my $l = length($e);
my $spaces = scalar(@line);
if(($w + $l + $spaces) >= $width) {
justline($lvl, @line);
undef @line;
$w = 0;
}
push @line, $e;
$w += $l; # new width
}
if($w) {
lastline($lvl, @line);
print "\n";
}
}
sub printdesc {
my @desc = @_;
my $exam = 0;
for my $d (@desc) {
print $d;
my ($manpage, $baselvl, @desc) = @_;
if($manpage) {
for my $d (@desc) {
print $d;
}
}
else {
my $p = -1;
my $para;
for my $l (@desc) {
my $lvl;
if($l !~ /^[\n\r]+/) {
# get the indent level off the string
$l =~ s/^\[([0-9q]*)\]//;
$lvl = $1;
}
if(($p =~ /q/) && ($lvl !~ /q/)) {
# the previous was quoted, this is not
print "\n";
}
if($lvl != $p) {
outputpara($baselvl + $p, $para);
$para = "";
}
if($lvl =~ /q/) {
# quoted, do not right-justify
chomp $l;
lastline($baselvl + $lvl + 1, $l);
}
else {
$para .= $l;
}
$p = $lvl;
}
outputpara($baselvl + $p, $para);
}
}
@ -123,12 +227,13 @@ sub overrides {
}
sub protocols {
my ($standalone, $data)=@_;
my ($manpage, $standalone, $data)=@_;
if($standalone) {
return ".SH \"PROTOCOLS\"\n$data\n";
}
else {
return "($data) ";
return " ($data) " if($manpage);
return "[1]($data) " if(!$manpage);
}
}
@ -164,13 +269,14 @@ sub added {
}
sub render {
my ($fh, $f, $line) = @_;
my ($manpage, $fh, $f, $line) = @_;
my @desc;
my $tablemode = 0;
my $header = 0;
# if $top is TRUE, it means a top-level page and not a command line option
my $top = ($line == 1);
my $quote;
my $level;
$start = 0;
while(<$fh>) {
@ -196,7 +302,8 @@ sub render {
$blankline++;
next;
}
push @desc, ".SH $1\n";
push @desc, ".SH $1\n" if($manpage);
push @desc, "[0]$1\n" if(!$manpage);
next;
}
elsif(/^###/) {
@ -211,19 +318,24 @@ sub render {
# remove backticks from headers
$words =~ s/\`//g;
# if there is a space, it needs quotes
if($word =~ / /) {
# if there is a space, it needs quotes for man page
if(($word =~ / /) && $manpage) {
$word = "\"$word\"";
}
$level = 1;
if($top == 1) {
push @desc, ".IP $word\n";
push @desc, ".IP $word\n" if($manpage);
push @desc, "\n" if(!$manpage);
push @desc, "[1]$word\n" if(!$manpage);
}
else {
if(!$tablemode) {
push @desc, ".RS\n";
push @desc, ".RS\n" if($manpage);
$tablemode = 1;
}
push @desc, ".IP $word\n";
push @desc, ".IP $word\n" if($manpage);
push @desc, "\n" if(!$manpage);
push @desc, "[1]$word\n" if(!$manpage);
}
$header = 1;
next;
@ -236,7 +348,7 @@ sub render {
if($tablemode) {
# end of table
push @desc, ".RE\n.IP\n";
$tablmode = 0;
$tablemode = 0;
}
$header = 1;
next;
@ -253,7 +365,7 @@ sub render {
}
elsif($d =~ /^ (.*)/) {
my $word = $1;
if(!$quote) {
if(!$quote && $manpage) {
push @desc, ".nf\n";
}
$quote = 1;
@ -261,7 +373,7 @@ sub render {
}
elsif($quote && ($d !~ /^ (.*)/)) {
# end of quote
push @desc, ".fi\n";
push @desc, ".fi\n" if($manpage);
$quote = 0;
}
@ -293,40 +405,50 @@ sub render {
# convert backslash-'<' or '> to just the second character
$d =~ s/\\([><])/$1/g;
# convert single backslash to double-backslash
$d =~ s/\\/\\\\/g;
$d =~ s/\\/\\\\/g if($manpage);
if(!$quote && $d =~ /--/) {
$d =~ s/--([a-z0-9.-]+)/manpageify($1)/ge;
if($manpage) {
if(!$quote && $d =~ /--/) {
$d =~ s/--([a-z0-9.-]+)/manpageify($1)/ge;
}
# quote minuses in the output
$d =~ s/([^\\])-/$1\\-/g;
# replace single quotes
$d =~ s/\'/\\(aq/g;
# handle double quotes or periods first on the line
$d =~ s/^([\.\"])/\\&$1/;
# **bold**
$d =~ s/\*\*(\S.*?)\*\*/\\fB$1\\fP/g;
# *italics*
$d =~ s/\*(\S.*?)\*/\\fI$1\\fP/g;
}
else {
# **bold**
$d =~ s/\*\*(\S.*?)\*\*/$1/g;
# *italics*
$d =~ s/\*(\S.*?)\*/$1/g;
}
# quote minuses in the output
$d =~ s/([^\\])-/$1\\-/g;
# replace single quotes
$d =~ s/\'/\\(aq/g;
# handle double quotes or periods first on the line
$d =~ s/^([\.\"])/\\&$1/;
# **bold**
$d =~ s/\*\*(\S.*?)\*\*/\\fB$1\\fP/g;
# *italics*
$d =~ s/\*(\S.*?)\*/\\fI$1\\fP/g;
# trim trailing spaces
$d =~ s/[ \t]+\z//;
push @desc, "\n" if($blankline && !$header);
$blankline = 0;
push @desc, $d;
push @desc, $d if($manpage);
my $qstr = $quote ? "q": "";
push @desc, "[".(1 + $level)."$qstr]$d" if(!$manpage);
$header = 0;
}
if($tablemode) {
# end of table
push @desc, ".RE\n.IP\n";
push @desc, ".RE\n.IP\n" if($manpage);
}
return @desc;
}
sub single {
my ($f, $standalone)=@_;
my ($manpage, $f, $standalone)=@_;
my $fh;
open($fh, "<:crlf", "$f") ||
return 1;
@ -476,7 +598,7 @@ sub single {
return 2;
}
my @desc = render($fh, $f, $line);
my @desc = render($manpage, $fh, $f, $line);
close($fh);
if($tablemode) {
# end of table
@ -499,17 +621,21 @@ sub single {
}
# quote "bare" minuses in opt
$opt =~ s/-/\\-/g;
$opt =~ s/-/\\-/g if($manpage);
if($standalone) {
print ".TH curl 1 \"30 Nov 2016\" \"curl 7.52.0\" \"curl manual\"\n";
print ".SH OPTION\n";
print "curl $opt\n";
}
else {
elsif($manpage) {
print ".IP \"$opt\"\n";
}
else {
lastline(1, $opt);
}
my @leading;
if($protocols) {
print protocols($standalone, $protocols);
push @leading, protocols($manpage, $standalone, $protocols);
}
if($standalone) {
@ -517,15 +643,15 @@ sub single {
}
if($experimental) {
print "**WARNING**: this option is experimental. Do not use in production.\n\n";
push @leading, "**WARNING**: this option is experimental. Do not use in production.\n\n";
}
printdesc(@desc);
undef @desc;
my $pre = $manpage ? "\n": "[1]";
if($scope) {
if($scope eq "global") {
print "\nThis option is global and does not need to be specified for each use of --next.\n";
push @desc, "\n" if(!$manpage);
push @desc, "${pre}This option is global and does not need to be specified for each use of --next.\n";
}
else {
print STDERR "$f:$line:1:ERROR: unrecognized scope: '$scope'\n";
@ -533,13 +659,16 @@ sub single {
}
}
printdesc($manpage, 2, (@leading, @desc));
undef @desc;
my @extra;
if($multi eq "single") {
push @extra, "\nIf --$long is provided several times, the last set ".
push @extra, "${pre}If --$long is provided several times, the last set ".
"value is used.\n";
}
elsif($multi eq "append") {
push @extra, "\n--$long can be used several times in a command line\n";
push @extra, "${pre}--$long can be used several times in a command line\n";
}
elsif($multi eq "boolean") {
my $rev = "no-$long";
@ -549,13 +678,14 @@ sub single {
$rev = $long;
$rev =~ s/^no-//;
}
my $dashes = $manpage ? "\\-\\-" : "--";
push @extra,
"\nProviding --$long multiple times has no extra effect.\n".
"Disable it again with \\-\\-$rev.\n";
"${pre}Providing --$long multiple times has no extra effect.\n".
"Disable it again with $dashes$rev.\n";
}
elsif($multi eq "mutex") {
push @extra,
"\nProviding --$long multiple times has no extra effect.\n";
"${pre}Providing --$long multiple times has no extra effect.\n";
}
elsif($multi eq "custom") {
; # left for the text to describe
@ -565,7 +695,7 @@ sub single {
return 2;
}
printdesc(@extra);
printdesc($manpage, 2, @extra);
my @foot;
@ -581,7 +711,7 @@ sub single {
if(!$helplong{$k}) {
print STDERR "$f:$line:1:WARN: see-also a non-existing option: $k\n";
}
my $l = manpageify($k);
my $l = $manpage ? manpageify($k) : "--$k";
my $sep = " and";
if($and && ($i < $and)) {
$sep = ",";
@ -592,7 +722,7 @@ sub single {
push @foot, seealso($standalone, $mstr);
if($requires) {
my $l = manpageify($long);
my $l = $manpage ? manpageify($long) : "--$long";
push @foot, "$l requires that the underlying libcurl".
" was built to support $requires. ";
}
@ -603,7 +733,7 @@ sub single {
if(!$helplong{$k}) {
print STDERR "WARN: $f mutexes a non-existing option: $k\n";
}
my $l = manpageify($k);
my $l = $manpage ? manpageify($k) : "--$k";
$mstr .= sprintf "%s$l", $mstr?" and ":"";
}
push @foot, overrides($standalone,
@ -612,16 +742,26 @@ sub single {
if($examples[0]) {
my $s ="";
$s="s" if($examples[1]);
print "\nExample$s:\n.nf\n";
foreach my $e (@examples) {
$e =~ s!\$URL!https://example.com!g;
#$e =~ s/-/\\-/g;
#$e =~ s/\'/\\(aq/g;
# convert single backslahes to doubles
$e =~ s/\\/\\\\/g;
print " curl $e\n";
if($manpage) {
print "\nExample$s:\n";
print ".nf\n";
foreach my $e (@examples) {
$e =~ s!\$URL!https://example.com!g;
# convert single backslahes to doubles
$e =~ s/\\/\\\\/g;
print " curl $e\n";
}
print ".fi\n";
}
else {
my @ex;
push @ex, "[0q]Example$s:\n";
foreach my $e (@examples) {
$e =~ s!\$URL!https://example.com!g;
push @ex, "[0q] curl $e\n";
}
printdesc($manpage, 2, @ex);
}
print ".fi\n";
}
if($added) {
push @foot, added($standalone, $added);
@ -629,8 +769,13 @@ sub single {
if($foot[0]) {
print "\n";
my $f = join("", @foot);
$f =~ s/ +\z//; # remove trailing space
print "$f\n";
if($manpage) {
$f =~ s/ +\z//; # remove trailing space
print "$f\n";
}
else {
printdesc($manpage, 2, "[1]$f");
}
}
return 0;
}
@ -695,12 +840,12 @@ sub indexoptions {
}
sub header {
my ($f)=@_;
my ($manpage, $f)=@_;
my $fh;
open($fh, "<:crlf", "$f");
my @d = render($fh, $f, 1);
my @d = render($manpage, $fh, $f, 1);
close($fh);
printdesc(@d);
printdesc($manpage, 0, @d);
}
sub listhelp {
@ -854,7 +999,8 @@ sub sortnames {
}
sub mainpage {
my (@files) = @_;
my ($manpage, @files) = @_;
# $manpage is 1 for nroff, 0 for ASCII
my $ret;
my $fh;
open($fh, "<:crlf", "mainpage.idx") ||
@ -889,7 +1035,7 @@ sub mainpage {
.\\"
.TH curl 1 "$date" "curl $version" "curl Manual"
HEADER
;
if ($manpage);
while(<$fh>) {
my $f = $_;
@ -901,12 +1047,12 @@ HEADER
if(/^%options/) {
# output docs for all options
foreach my $f (sort sortnames @files) {
$ret += single($f, 0);
$ret += single($manpage, $f, 0);
}
}
else {
# render the file
header($f);
header($manpage, $f);
}
}
close($fh);
@ -937,7 +1083,12 @@ sub getargs {
my ($f, @s) = @_;
if($f eq "mainpage") {
listglobals(@s);
mainpage(@s);
mainpage(1, @s);
return;
}
elsif($f eq "ascii") {
listglobals(@s);
mainpage(0, @s);
return;
}
elsif($f eq "listhelp") {
@ -957,7 +1108,7 @@ sub getargs {
return;
}
print "Usage: gen.pl <mainpage/listhelp/single FILE/protos/listcats> [files]\n";
print "Usage: gen.pl <mainpage/ascii/listhelp/single FILE/protos/listcats> [files]\n";
}
#------------------------------------------------------------------------

View File

@ -26,26 +26,21 @@ transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
function(add_manual_pages _listname)
unset(_rofffiles)
unset(_mdfiles)
foreach(_file IN LISTS ${_listname})
list(APPEND _rofffiles "${CMAKE_CURRENT_BINARY_DIR}/${_file}")
set(_rofffile "${CMAKE_CURRENT_BINARY_DIR}/${_file}")
if(_file STREQUAL "libcurl-symbols.3")
# Special case, an auto-generated file.
string(REPLACE ".3" ".md" _mdfile "${CMAKE_CURRENT_BINARY_DIR}/${_file}")
else()
string(REPLACE ".3" ".md" _mdfile "${_file}")
string(REPLACE ".3" ".md" _mdfile "${CMAKE_CURRENT_SOURCE_DIR}/${_file}")
endif()
list(APPEND _mdfiles "${_mdfile}")
add_custom_command(OUTPUT "${_rofffile}"
COMMAND "${PERL_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/scripts/cd2nroff ${_mdfile} > ${_rofffile}
DEPENDS "${_mdfile}"
VERBATIM
)
endforeach()
add_custom_command(OUTPUT ${_rofffiles}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${PROJECT_SOURCE_DIR}/scripts/cd2nroff -k -d "${CMAKE_CURRENT_BINARY_DIR}" ${_mdfiles}
DEPENDS ${_mdfiles}
VERBATIM
)
endfunction()
add_custom_command(OUTPUT libcurl-symbols.md

View File

@ -77,3 +77,6 @@ if USE_FISH_COMPLETION
fi
endif
endif
distclean:
rm -f $(CLEANFILES)

View File

@ -113,7 +113,7 @@ sub single {
if(defined($f)) {
if(!open($fh, "<:crlf", "$f")) {
print STDERR "Failed to open $f : $!\n";
print STDERR "cd2nroff failed to open '$f' for reading: $!\n";
return 1;
}
}

View File

@ -26,23 +26,18 @@ add_definitions(-DBUILDING_CURL)
if(ENABLE_CURL_MANUAL AND HAVE_MANUAL_TOOLS)
add_definitions("-DUSE_MANUAL")
# Use the C locale to ensure that only ASCII characters appear in the
# embedded text. NROFF and MANOPT are set in the parent CMakeLists.txt
add_custom_command(
OUTPUT tool_hugehelp.c
COMMAND ${CMAKE_COMMAND} -E echo "#include \"tool_setup.h\"" > tool_hugehelp.c
COMMAND ${CMAKE_COMMAND} -E echo "#ifndef HAVE_LIBZ" >> tool_hugehelp.c
COMMAND env LC_ALL=C "${NROFF}" ${NROFF_MANOPT}
"${CURL_BINARY_DIR}/docs/curl.1" |
"${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" >> tool_hugehelp.c
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" < "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt" >> tool_hugehelp.c
COMMAND ${CMAKE_COMMAND} -E echo "#else" >> tool_hugehelp.c
COMMAND env LC_ALL=C "${NROFF}" ${NROFF_MANOPT}
"${CURL_BINARY_DIR}/docs/curl.1" |
"${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" -c >> tool_hugehelp.c
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl" -c < "${CURL_BINARY_DIR}/docs/cmdline-opts/curl.txt" >> tool_hugehelp.c
COMMAND ${CMAKE_COMMAND} -E echo "#endif /* HAVE_LIBZ */" >> tool_hugehelp.c
DEPENDS
generate-curl.1
"${CURL_BINARY_DIR}/docs/curl.1"
"${CURL_BINARY_DIR}/docs/cmdline-opts/curl.1"
"${CMAKE_CURRENT_SOURCE_DIR}/mkhelp.pl"
"${CMAKE_CURRENT_SOURCE_DIR}/tool_hugehelp.h"
VERBATIM)

View File

@ -96,7 +96,7 @@ EXTRA_DIST = mkhelp.pl \
Makefile.mk curl.rc Makefile.inc CMakeLists.txt .checksrc
# Use absolute directory to disable VPATH
MANPAGE=$(abs_top_builddir)/docs/curl.1
ASCIIPAGE=$(abs_top_builddir)/docs/cmdline-opts/curl.txt
MKHELP=$(top_srcdir)/src/mkhelp.pl
HUGE=tool_hugehelp.c
@ -113,24 +113,24 @@ CS_ = $(CS_0)
if USE_MANUAL
# Here are the stuff to create a built-in manual
$(MANPAGE):
$(ASCIIPAGE):
cd $(top_builddir)/docs && $(MAKE)
if HAVE_LIBZ
# This generates the tool_hugehelp.c file in both uncompressed and
# compressed formats.
$(HUGE): $(MANPAGE) $(MKHELP)
$(HUGE): $(ASCIIPAGE) $(MKHELP)
$(HUGECMD) (echo '#include "tool_setup.h"' > $(HUGE); \
echo '#ifndef HAVE_LIBZ' >> $(HUGE); \
$(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) >> $(HUGE); \
$(PERL) $(MKHELP) < $(ASCIIPAGE) >> $(HUGE); \
echo '#else' >> $(HUGE); \
$(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) -c >> $(HUGE); \
$(PERL) $(MKHELP) -c < $(ASCIIPAGE) >> $(HUGE); \
echo '#endif /* HAVE_LIBZ */' >> $(HUGE) )
else # HAVE_LIBZ
# This generates the tool_hugehelp.c file uncompressed only
$(HUGE): $(MANPAGE) $(MKHELP)
$(HUGE): $(ASCIIPAGE) $(MKHELP)
$(HUGECMD)(echo '#include "tool_setup.h"' > $(HUGE); \
$(NROFF) $(MANPAGE) | $(PERL) $(MKHELP) >> $(HUGE) )
$(PERL) $(MKHELP) < $(ASCIIPAGE) >> $(HUGE) )
endif
else # USE_MANUAL

View File

@ -44,45 +44,8 @@ push @out, " \\___|\\___/|_| \\_\\_____|\n";
my $olen=0;
while (<STDIN>) {
my $line = $_;
# this should be removed:
$line =~ s/(.|_)//g;
# remove trailing CR from line. msysgit checks out files as line+CRLF
$line =~ s/\r$//;
$line =~ s/\x1b\x5b[0-9]+m//g; # escape sequence
if($line =~ /^([ \t]*\n|curl)/i) {
# cut off headers and empty lines
$wline++; # count number of cut off lines
next;
}
my $text = $line;
$text =~ s/^\s+//g; # cut off preceding...
$text =~ s/\s+$//g; # and trailing whitespaces
$tlen = length($text);
if($wline && ($olen == $tlen)) {
# if the previous line with contents was exactly as long as
# this line, then we ignore the newlines!
# We do this magic because a header may abort a paragraph at
# any line, but we don't want that to be noticed in the output
# here
$wline=0;
}
$olen = $tlen;
if($wline) {
# we only make one empty line max
$wline = 0;
push @out, "\n";
}
push @out, $line;
}
push @out, "\n"; # just an extra newline
print <<HEAD
/*

View File

@ -52,7 +52,6 @@ SPDX-License-Identifier: curl
- stunnel (for HTTPS and FTPS tests)
- OpenSSH or SunSSH (for SCP and SFTP tests)
- nghttpx (for HTTP/2 and HTTP/3 tests)
- nroff (for --manual tests)
- An available `en_US.UTF-8` locale
### Installation of python-impacket

View File

@ -15,7 +15,7 @@ none
</server>
<name>
Verify the nroff of man pages
Verify the nroff of manpages
</name>
<command type="perl">

View File

@ -220,8 +220,8 @@ close($r);
#########################################################################
# parse the curl.1 man page, extract all documented command line options
# The man page may or may not be rebuilt, so check both possible locations
open($r, "<", "$buildroot/docs/curl.1") || open($r, "<", "$root/docs/curl.1") ||
die "no input file";
open($r, "<", "$buildroot/docs/cmdline-opts/curl.1") || open($r, "<", "$root/docs/cmdline-opts/curl.1") ||
die "failed getting curl.1";
my @manpage; # store all parsed parameters
while(<$r>) {
chomp;

View File

@ -23,13 +23,13 @@
#
###########################################################################
#
# scan nroff pages to find basic syntactic problems such as unbalanced \f
# scan manpages to find basic syntactic problems such as unbalanced \f
# codes or references to non-existing curl man pages.
my $docsroot = $ARGV[0];
if(!$docsroot || ($docsroot eq "-g")) {
print "Usage: nroff-scan.pl <docs root dir> [nroff files]\n";
print "Usage: test1140.pl <docs root dir> [manpages]\n";
exit;
}