1*6236dae4SAndroid Build Coastguard Worker#!/usr/bin/env perl 2*6236dae4SAndroid Build Coastguard Worker#*************************************************************************** 3*6236dae4SAndroid Build Coastguard Worker# _ _ ____ _ 4*6236dae4SAndroid Build Coastguard Worker# Project ___| | | | _ \| | 5*6236dae4SAndroid Build Coastguard Worker# / __| | | | |_) | | 6*6236dae4SAndroid Build Coastguard Worker# | (__| |_| | _ <| |___ 7*6236dae4SAndroid Build Coastguard Worker# \___|\___/|_| \_\_____| 8*6236dae4SAndroid Build Coastguard Worker# 9*6236dae4SAndroid Build Coastguard Worker# Copyright (C) Daniel Stenberg, <[email protected]>, et al. 10*6236dae4SAndroid Build Coastguard Worker# 11*6236dae4SAndroid Build Coastguard Worker# This software is licensed as described in the file COPYING, which 12*6236dae4SAndroid Build Coastguard Worker# you should have received as part of this distribution. The terms 13*6236dae4SAndroid Build Coastguard Worker# are also available at https://curl.se/docs/copyright.html. 14*6236dae4SAndroid Build Coastguard Worker# 15*6236dae4SAndroid Build Coastguard Worker# You may opt to use, copy, modify, merge, publish, distribute and/or sell 16*6236dae4SAndroid Build Coastguard Worker# copies of the Software, and permit persons to whom the Software is 17*6236dae4SAndroid Build Coastguard Worker# furnished to do so, under the terms of the COPYING file. 18*6236dae4SAndroid Build Coastguard Worker# 19*6236dae4SAndroid Build Coastguard Worker# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20*6236dae4SAndroid Build Coastguard Worker# KIND, either express or implied. 21*6236dae4SAndroid Build Coastguard Worker# 22*6236dae4SAndroid Build Coastguard Worker# SPDX-License-Identifier: curl 23*6236dae4SAndroid Build Coastguard Worker# 24*6236dae4SAndroid Build Coastguard Worker########################################################################### 25*6236dae4SAndroid Build Coastguard Worker 26*6236dae4SAndroid Build Coastguard Worker=begin comment 27*6236dae4SAndroid Build Coastguard Worker 28*6236dae4SAndroid Build Coastguard WorkerConverts a curldown file to nroff (manpage). 29*6236dae4SAndroid Build Coastguard Worker 30*6236dae4SAndroid Build Coastguard Worker=end comment 31*6236dae4SAndroid Build Coastguard Worker=cut 32*6236dae4SAndroid Build Coastguard Worker 33*6236dae4SAndroid Build Coastguard Workeruse strict; 34*6236dae4SAndroid Build Coastguard Workeruse warnings; 35*6236dae4SAndroid Build Coastguard Worker 36*6236dae4SAndroid Build Coastguard Workermy $cd2nroff = "0.1"; # to keep check 37*6236dae4SAndroid Build Coastguard Workermy $dir; 38*6236dae4SAndroid Build Coastguard Workermy $extension; 39*6236dae4SAndroid Build Coastguard Workermy $keepfilename; 40*6236dae4SAndroid Build Coastguard Worker 41*6236dae4SAndroid Build Coastguard Workerwhile(@ARGV) { 42*6236dae4SAndroid Build Coastguard Worker if($ARGV[0] eq "-d") { 43*6236dae4SAndroid Build Coastguard Worker shift @ARGV; 44*6236dae4SAndroid Build Coastguard Worker $dir = shift @ARGV; 45*6236dae4SAndroid Build Coastguard Worker } 46*6236dae4SAndroid Build Coastguard Worker elsif($ARGV[0] eq "-e") { 47*6236dae4SAndroid Build Coastguard Worker shift @ARGV; 48*6236dae4SAndroid Build Coastguard Worker $extension = shift @ARGV; 49*6236dae4SAndroid Build Coastguard Worker } 50*6236dae4SAndroid Build Coastguard Worker elsif($ARGV[0] eq "-k") { 51*6236dae4SAndroid Build Coastguard Worker shift @ARGV; 52*6236dae4SAndroid Build Coastguard Worker $keepfilename = 1; 53*6236dae4SAndroid Build Coastguard Worker } 54*6236dae4SAndroid Build Coastguard Worker elsif($ARGV[0] eq "-h") { 55*6236dae4SAndroid Build Coastguard Worker print <<HELP 56*6236dae4SAndroid Build Coastguard WorkerUsage: cd2nroff [options] [file.md] 57*6236dae4SAndroid Build Coastguard Worker 58*6236dae4SAndroid Build Coastguard Worker-d <dir> Write the output to the file name from the meta-data in the 59*6236dae4SAndroid Build Coastguard Worker specified directory, instead of writing to stdout 60*6236dae4SAndroid Build Coastguard Worker-e <ext> If -d is used, this option can provide an added "extension", arbitrary 61*6236dae4SAndroid Build Coastguard Worker text really, to append to the file name. 62*6236dae4SAndroid Build Coastguard Worker-h This help text, 63*6236dae4SAndroid Build Coastguard Worker-v Show version then exit 64*6236dae4SAndroid Build Coastguard WorkerHELP 65*6236dae4SAndroid Build Coastguard Worker ; 66*6236dae4SAndroid Build Coastguard Worker exit 0; 67*6236dae4SAndroid Build Coastguard Worker } 68*6236dae4SAndroid Build Coastguard Worker elsif($ARGV[0] eq "-v") { 69*6236dae4SAndroid Build Coastguard Worker print "cd2nroff version $cd2nroff\n"; 70*6236dae4SAndroid Build Coastguard Worker exit 0; 71*6236dae4SAndroid Build Coastguard Worker } 72*6236dae4SAndroid Build Coastguard Worker else { 73*6236dae4SAndroid Build Coastguard Worker last; 74*6236dae4SAndroid Build Coastguard Worker } 75*6236dae4SAndroid Build Coastguard Worker} 76*6236dae4SAndroid Build Coastguard Worker 77*6236dae4SAndroid Build Coastguard Workeruse POSIX qw(strftime); 78*6236dae4SAndroid Build Coastguard Workermy @ts; 79*6236dae4SAndroid Build Coastguard Workerif (defined($ENV{SOURCE_DATE_EPOCH})) { 80*6236dae4SAndroid Build Coastguard Worker @ts = gmtime($ENV{SOURCE_DATE_EPOCH}); 81*6236dae4SAndroid Build Coastguard Worker} else { 82*6236dae4SAndroid Build Coastguard Worker @ts = localtime; 83*6236dae4SAndroid Build Coastguard Worker} 84*6236dae4SAndroid Build Coastguard Workermy $date = strftime "%Y-%m-%d", @ts; 85*6236dae4SAndroid Build Coastguard Worker 86*6236dae4SAndroid Build Coastguard Workersub outseealso { 87*6236dae4SAndroid Build Coastguard Worker my (@sa) = @_; 88*6236dae4SAndroid Build Coastguard Worker my $comma = 0; 89*6236dae4SAndroid Build Coastguard Worker my @o; 90*6236dae4SAndroid Build Coastguard Worker push @o, ".SH SEE ALSO\n"; 91*6236dae4SAndroid Build Coastguard Worker for my $s (sort @sa) { 92*6236dae4SAndroid Build Coastguard Worker push @o, sprintf "%s.BR $s", $comma ? ",\n": ""; 93*6236dae4SAndroid Build Coastguard Worker $comma = 1; 94*6236dae4SAndroid Build Coastguard Worker } 95*6236dae4SAndroid Build Coastguard Worker push @o, "\n"; 96*6236dae4SAndroid Build Coastguard Worker return @o; 97*6236dae4SAndroid Build Coastguard Worker} 98*6236dae4SAndroid Build Coastguard Worker 99*6236dae4SAndroid Build Coastguard Workersub outprotocols { 100*6236dae4SAndroid Build Coastguard Worker my (@p) = @_; 101*6236dae4SAndroid Build Coastguard Worker my $comma = 0; 102*6236dae4SAndroid Build Coastguard Worker my @o; 103*6236dae4SAndroid Build Coastguard Worker push @o, ".SH PROTOCOLS\n"; 104*6236dae4SAndroid Build Coastguard Worker 105*6236dae4SAndroid Build Coastguard Worker if($p[0] eq "TLS") { 106*6236dae4SAndroid Build Coastguard Worker push @o, "This functionality affects all TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc."; 107*6236dae4SAndroid Build Coastguard Worker } 108*6236dae4SAndroid Build Coastguard Worker else { 109*6236dae4SAndroid Build Coastguard Worker my @s = sort @p; 110*6236dae4SAndroid Build Coastguard Worker push @o, "This functionality affects "; 111*6236dae4SAndroid Build Coastguard Worker for my $e (sort @s) { 112*6236dae4SAndroid Build Coastguard Worker push @o, sprintf "%s%s", 113*6236dae4SAndroid Build Coastguard Worker $comma ? (($e eq $s[-1]) ? " and " : ", "): "", 114*6236dae4SAndroid Build Coastguard Worker lc($e); 115*6236dae4SAndroid Build Coastguard Worker $comma = 1; 116*6236dae4SAndroid Build Coastguard Worker } 117*6236dae4SAndroid Build Coastguard Worker if($#s == 0) { 118*6236dae4SAndroid Build Coastguard Worker if($s[0] eq "All") { 119*6236dae4SAndroid Build Coastguard Worker push @o, " supported protocols"; 120*6236dae4SAndroid Build Coastguard Worker } 121*6236dae4SAndroid Build Coastguard Worker else { 122*6236dae4SAndroid Build Coastguard Worker push @o, " only"; 123*6236dae4SAndroid Build Coastguard Worker } 124*6236dae4SAndroid Build Coastguard Worker } 125*6236dae4SAndroid Build Coastguard Worker } 126*6236dae4SAndroid Build Coastguard Worker push @o, "\n"; 127*6236dae4SAndroid Build Coastguard Worker return @o; 128*6236dae4SAndroid Build Coastguard Worker} 129*6236dae4SAndroid Build Coastguard Worker 130*6236dae4SAndroid Build Coastguard Workersub outtls { 131*6236dae4SAndroid Build Coastguard Worker my (@t) = @_; 132*6236dae4SAndroid Build Coastguard Worker my $comma = 0; 133*6236dae4SAndroid Build Coastguard Worker my @o; 134*6236dae4SAndroid Build Coastguard Worker if($t[0] eq "All") { 135*6236dae4SAndroid Build Coastguard Worker push @o, "\nAll TLS backends support this option."; 136*6236dae4SAndroid Build Coastguard Worker } 137*6236dae4SAndroid Build Coastguard Worker else { 138*6236dae4SAndroid Build Coastguard Worker push @o, "\nThis option works only with the following TLS backends:\n"; 139*6236dae4SAndroid Build Coastguard Worker my @s = sort @t; 140*6236dae4SAndroid Build Coastguard Worker for my $e (@s) { 141*6236dae4SAndroid Build Coastguard Worker push @o, sprintf "%s$e", 142*6236dae4SAndroid Build Coastguard Worker $comma ? (($e eq $s[-1]) ? " and " : ", "): ""; 143*6236dae4SAndroid Build Coastguard Worker $comma = 1; 144*6236dae4SAndroid Build Coastguard Worker } 145*6236dae4SAndroid Build Coastguard Worker } 146*6236dae4SAndroid Build Coastguard Worker push @o, "\n"; 147*6236dae4SAndroid Build Coastguard Worker return @o; 148*6236dae4SAndroid Build Coastguard Worker} 149*6236dae4SAndroid Build Coastguard Worker 150*6236dae4SAndroid Build Coastguard Workermy %knownprotos = ( 151*6236dae4SAndroid Build Coastguard Worker 'DICT' => 1, 152*6236dae4SAndroid Build Coastguard Worker 'FILE' => 1, 153*6236dae4SAndroid Build Coastguard Worker 'FTP' => 1, 154*6236dae4SAndroid Build Coastguard Worker 'FTPS' => 1, 155*6236dae4SAndroid Build Coastguard Worker 'GOPHER' => 1, 156*6236dae4SAndroid Build Coastguard Worker 'GOPHERS' => 1, 157*6236dae4SAndroid Build Coastguard Worker 'HTTP' => 1, 158*6236dae4SAndroid Build Coastguard Worker 'HTTPS' => 1, 159*6236dae4SAndroid Build Coastguard Worker 'IMAP' => 1, 160*6236dae4SAndroid Build Coastguard Worker 'IMAPS' => 1, 161*6236dae4SAndroid Build Coastguard Worker 'LDAP' => 1, 162*6236dae4SAndroid Build Coastguard Worker 'LDAPS' => 1, 163*6236dae4SAndroid Build Coastguard Worker 'MQTT' => 1, 164*6236dae4SAndroid Build Coastguard Worker 'POP3' => 1, 165*6236dae4SAndroid Build Coastguard Worker 'POP3S' => 1, 166*6236dae4SAndroid Build Coastguard Worker 'RTMP' => 1, 167*6236dae4SAndroid Build Coastguard Worker 'RTMPS' => 1, 168*6236dae4SAndroid Build Coastguard Worker 'RTSP' => 1, 169*6236dae4SAndroid Build Coastguard Worker 'SCP' => 1, 170*6236dae4SAndroid Build Coastguard Worker 'SFTP' => 1, 171*6236dae4SAndroid Build Coastguard Worker 'SMB' => 1, 172*6236dae4SAndroid Build Coastguard Worker 'SMBS' => 1, 173*6236dae4SAndroid Build Coastguard Worker 'SMTP' => 1, 174*6236dae4SAndroid Build Coastguard Worker 'SMTPS' => 1, 175*6236dae4SAndroid Build Coastguard Worker 'TELNET' => 1, 176*6236dae4SAndroid Build Coastguard Worker 'TFTP' => 1, 177*6236dae4SAndroid Build Coastguard Worker 'WS' => 1, 178*6236dae4SAndroid Build Coastguard Worker 'WSS' => 1, 179*6236dae4SAndroid Build Coastguard Worker 'TLS' => 1, 180*6236dae4SAndroid Build Coastguard Worker 'TCP' => 1, 181*6236dae4SAndroid Build Coastguard Worker 'QUIC' => 1, 182*6236dae4SAndroid Build Coastguard Worker 'All' => 1 183*6236dae4SAndroid Build Coastguard Worker ); 184*6236dae4SAndroid Build Coastguard Worker 185*6236dae4SAndroid Build Coastguard Workermy %knowntls = ( 186*6236dae4SAndroid Build Coastguard Worker 'BearSSL' => 1, 187*6236dae4SAndroid Build Coastguard Worker 'GnuTLS' => 1, 188*6236dae4SAndroid Build Coastguard Worker 'mbedTLS' => 1, 189*6236dae4SAndroid Build Coastguard Worker 'OpenSSL' => 1, 190*6236dae4SAndroid Build Coastguard Worker 'rustls' => 1, 191*6236dae4SAndroid Build Coastguard Worker 'Schannel' => 1, 192*6236dae4SAndroid Build Coastguard Worker 'Secure Transport' => 1, 193*6236dae4SAndroid Build Coastguard Worker 'wolfSSL' => 1, 194*6236dae4SAndroid Build Coastguard Worker 'All' => 1, 195*6236dae4SAndroid Build Coastguard Worker ); 196*6236dae4SAndroid Build Coastguard Worker 197*6236dae4SAndroid Build Coastguard Workersub single { 198*6236dae4SAndroid Build Coastguard Worker my @seealso; 199*6236dae4SAndroid Build Coastguard Worker my @proto; 200*6236dae4SAndroid Build Coastguard Worker my @tls; 201*6236dae4SAndroid Build Coastguard Worker my $d; 202*6236dae4SAndroid Build Coastguard Worker my ($f)=@_; 203*6236dae4SAndroid Build Coastguard Worker my $copyright; 204*6236dae4SAndroid Build Coastguard Worker my $errors = 0; 205*6236dae4SAndroid Build Coastguard Worker my $fh; 206*6236dae4SAndroid Build Coastguard Worker my $line; 207*6236dae4SAndroid Build Coastguard Worker my $list; 208*6236dae4SAndroid Build Coastguard Worker my $tlslist; 209*6236dae4SAndroid Build Coastguard Worker my $section; 210*6236dae4SAndroid Build Coastguard Worker my $source; 211*6236dae4SAndroid Build Coastguard Worker my $addedin; 212*6236dae4SAndroid Build Coastguard Worker my $spdx; 213*6236dae4SAndroid Build Coastguard Worker my $start = 0; 214*6236dae4SAndroid Build Coastguard Worker my $title; 215*6236dae4SAndroid Build Coastguard Worker 216*6236dae4SAndroid Build Coastguard Worker if(defined($f)) { 217*6236dae4SAndroid Build Coastguard Worker if(!open($fh, "<:crlf", "$f")) { 218*6236dae4SAndroid Build Coastguard Worker print STDERR "cd2nroff failed to open '$f' for reading: $!\n"; 219*6236dae4SAndroid Build Coastguard Worker return 1; 220*6236dae4SAndroid Build Coastguard Worker } 221*6236dae4SAndroid Build Coastguard Worker } 222*6236dae4SAndroid Build Coastguard Worker else { 223*6236dae4SAndroid Build Coastguard Worker $f = "STDIN"; 224*6236dae4SAndroid Build Coastguard Worker $fh = \*STDIN; 225*6236dae4SAndroid Build Coastguard Worker binmode($fh, ":crlf"); 226*6236dae4SAndroid Build Coastguard Worker } 227*6236dae4SAndroid Build Coastguard Worker while(<$fh>) { 228*6236dae4SAndroid Build Coastguard Worker $line++; 229*6236dae4SAndroid Build Coastguard Worker if(!$start) { 230*6236dae4SAndroid Build Coastguard Worker if(/^---/) { 231*6236dae4SAndroid Build Coastguard Worker # header starts here 232*6236dae4SAndroid Build Coastguard Worker $start = 1; 233*6236dae4SAndroid Build Coastguard Worker } 234*6236dae4SAndroid Build Coastguard Worker next; 235*6236dae4SAndroid Build Coastguard Worker } 236*6236dae4SAndroid Build Coastguard Worker if(/^Title: *(.*)/i) { 237*6236dae4SAndroid Build Coastguard Worker $title=$1; 238*6236dae4SAndroid Build Coastguard Worker } 239*6236dae4SAndroid Build Coastguard Worker elsif(/^Section: *(.*)/i) { 240*6236dae4SAndroid Build Coastguard Worker $section=$1; 241*6236dae4SAndroid Build Coastguard Worker } 242*6236dae4SAndroid Build Coastguard Worker elsif(/^Source: *(.*)/i) { 243*6236dae4SAndroid Build Coastguard Worker $source=$1; 244*6236dae4SAndroid Build Coastguard Worker } 245*6236dae4SAndroid Build Coastguard Worker elsif(/^See-also: +(.*)/i) { 246*6236dae4SAndroid Build Coastguard Worker $list = 1; # 1 for see-also 247*6236dae4SAndroid Build Coastguard Worker push @seealso, $1; 248*6236dae4SAndroid Build Coastguard Worker } 249*6236dae4SAndroid Build Coastguard Worker elsif(/^See-also: */i) { 250*6236dae4SAndroid Build Coastguard Worker if($seealso[0]) { 251*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: bad See-Also, needs list\n"; 252*6236dae4SAndroid Build Coastguard Worker return 2; 253*6236dae4SAndroid Build Coastguard Worker } 254*6236dae4SAndroid Build Coastguard Worker $list = 1; # 1 for see-also 255*6236dae4SAndroid Build Coastguard Worker } 256*6236dae4SAndroid Build Coastguard Worker elsif(/^Protocol:/i) { 257*6236dae4SAndroid Build Coastguard Worker $list = 2; # 2 for protocol 258*6236dae4SAndroid Build Coastguard Worker } 259*6236dae4SAndroid Build Coastguard Worker elsif(/^TLS-backend:/i) { 260*6236dae4SAndroid Build Coastguard Worker $list = 3; # 3 for TLS backend 261*6236dae4SAndroid Build Coastguard Worker } 262*6236dae4SAndroid Build Coastguard Worker elsif(/^Added-in: *(.*)/i) { 263*6236dae4SAndroid Build Coastguard Worker $addedin=$1; 264*6236dae4SAndroid Build Coastguard Worker if(($addedin !~ /^[0-9.]+[0-9]\z/) && 265*6236dae4SAndroid Build Coastguard Worker ($addedin ne "n/a")) { 266*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: invalid version number in Added-in line: $addedin\n"; 267*6236dae4SAndroid Build Coastguard Worker return 2; 268*6236dae4SAndroid Build Coastguard Worker } 269*6236dae4SAndroid Build Coastguard Worker } 270*6236dae4SAndroid Build Coastguard Worker elsif(/^ +- (.*)/i) { 271*6236dae4SAndroid Build Coastguard Worker # the only lists we support are see-also and protocol 272*6236dae4SAndroid Build Coastguard Worker if($list == 1) { 273*6236dae4SAndroid Build Coastguard Worker push @seealso, $1; 274*6236dae4SAndroid Build Coastguard Worker } 275*6236dae4SAndroid Build Coastguard Worker elsif($list == 2) { 276*6236dae4SAndroid Build Coastguard Worker push @proto, $1; 277*6236dae4SAndroid Build Coastguard Worker } 278*6236dae4SAndroid Build Coastguard Worker elsif($list == 3) { 279*6236dae4SAndroid Build Coastguard Worker push @tls, $1; 280*6236dae4SAndroid Build Coastguard Worker } 281*6236dae4SAndroid Build Coastguard Worker else { 282*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: list item without owner?\n"; 283*6236dae4SAndroid Build Coastguard Worker return 2; 284*6236dae4SAndroid Build Coastguard Worker } 285*6236dae4SAndroid Build Coastguard Worker } 286*6236dae4SAndroid Build Coastguard Worker # REUSE-IgnoreStart 287*6236dae4SAndroid Build Coastguard Worker elsif(/^C: (.*)/i) { 288*6236dae4SAndroid Build Coastguard Worker $copyright=$1; 289*6236dae4SAndroid Build Coastguard Worker } 290*6236dae4SAndroid Build Coastguard Worker elsif(/^SPDX-License-Identifier: (.*)/i) { 291*6236dae4SAndroid Build Coastguard Worker $spdx=$1; 292*6236dae4SAndroid Build Coastguard Worker } 293*6236dae4SAndroid Build Coastguard Worker # REUSE-IgnoreEnd 294*6236dae4SAndroid Build Coastguard Worker elsif(/^---/) { 295*6236dae4SAndroid Build Coastguard Worker # end of the header section 296*6236dae4SAndroid Build Coastguard Worker if(!$title) { 297*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'Title:' in $f\n"; 298*6236dae4SAndroid Build Coastguard Worker return 1; 299*6236dae4SAndroid Build Coastguard Worker } 300*6236dae4SAndroid Build Coastguard Worker if(!$section) { 301*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'Section:' in $f\n"; 302*6236dae4SAndroid Build Coastguard Worker return 2; 303*6236dae4SAndroid Build Coastguard Worker } 304*6236dae4SAndroid Build Coastguard Worker if(!$source) { 305*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'Source:' in $f\n"; 306*6236dae4SAndroid Build Coastguard Worker return 2; 307*6236dae4SAndroid Build Coastguard Worker } 308*6236dae4SAndroid Build Coastguard Worker if(($source eq "libcurl") && !$addedin) { 309*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'Added-in:' in $f\n"; 310*6236dae4SAndroid Build Coastguard Worker return 2; 311*6236dae4SAndroid Build Coastguard Worker } 312*6236dae4SAndroid Build Coastguard Worker if(!$seealso[0]) { 313*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'See-also:' present\n"; 314*6236dae4SAndroid Build Coastguard Worker return 2; 315*6236dae4SAndroid Build Coastguard Worker } 316*6236dae4SAndroid Build Coastguard Worker if(!$copyright) { 317*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'C:' field present\n"; 318*6236dae4SAndroid Build Coastguard Worker return 2; 319*6236dae4SAndroid Build Coastguard Worker } 320*6236dae4SAndroid Build Coastguard Worker if(!$spdx) { 321*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no 'SPDX-License-Identifier:' field present\n"; 322*6236dae4SAndroid Build Coastguard Worker return 2; 323*6236dae4SAndroid Build Coastguard Worker } 324*6236dae4SAndroid Build Coastguard Worker if($section == 3) { 325*6236dae4SAndroid Build Coastguard Worker if(!$proto[0]) { 326*6236dae4SAndroid Build Coastguard Worker printf STDERR "$f:$line:1:ERROR: missing Protocol:\n"; 327*6236dae4SAndroid Build Coastguard Worker exit 2; 328*6236dae4SAndroid Build Coastguard Worker } 329*6236dae4SAndroid Build Coastguard Worker my $tls = 0; 330*6236dae4SAndroid Build Coastguard Worker for my $p (@proto) { 331*6236dae4SAndroid Build Coastguard Worker if($p eq "TLS") { 332*6236dae4SAndroid Build Coastguard Worker $tls = 1; 333*6236dae4SAndroid Build Coastguard Worker } 334*6236dae4SAndroid Build Coastguard Worker if(!$knownprotos{$p}) { 335*6236dae4SAndroid Build Coastguard Worker printf STDERR "$f:$line:1:ERROR: invalid protocol used: $p:\n"; 336*6236dae4SAndroid Build Coastguard Worker exit 2; 337*6236dae4SAndroid Build Coastguard Worker } 338*6236dae4SAndroid Build Coastguard Worker } 339*6236dae4SAndroid Build Coastguard Worker # This is for TLS, require TLS-backend: 340*6236dae4SAndroid Build Coastguard Worker if($tls) { 341*6236dae4SAndroid Build Coastguard Worker if(!$tls[0]) { 342*6236dae4SAndroid Build Coastguard Worker printf STDERR "$f:$line:1:ERROR: missing TLS-backend:\n"; 343*6236dae4SAndroid Build Coastguard Worker exit 2; 344*6236dae4SAndroid Build Coastguard Worker } 345*6236dae4SAndroid Build Coastguard Worker for my $t (@tls) { 346*6236dae4SAndroid Build Coastguard Worker if(!$knowntls{$t}) { 347*6236dae4SAndroid Build Coastguard Worker printf STDERR "$f:$line:1:ERROR: invalid TLS backend: $t:\n"; 348*6236dae4SAndroid Build Coastguard Worker exit 2; 349*6236dae4SAndroid Build Coastguard Worker } 350*6236dae4SAndroid Build Coastguard Worker } 351*6236dae4SAndroid Build Coastguard Worker } 352*6236dae4SAndroid Build Coastguard Worker } 353*6236dae4SAndroid Build Coastguard Worker last; 354*6236dae4SAndroid Build Coastguard Worker } 355*6236dae4SAndroid Build Coastguard Worker else { 356*6236dae4SAndroid Build Coastguard Worker chomp; 357*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: unrecognized header keyword: '$_'\n"; 358*6236dae4SAndroid Build Coastguard Worker $errors++; 359*6236dae4SAndroid Build Coastguard Worker } 360*6236dae4SAndroid Build Coastguard Worker } 361*6236dae4SAndroid Build Coastguard Worker 362*6236dae4SAndroid Build Coastguard Worker if(!$start) { 363*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: no header present\n"; 364*6236dae4SAndroid Build Coastguard Worker return 2; 365*6236dae4SAndroid Build Coastguard Worker } 366*6236dae4SAndroid Build Coastguard Worker 367*6236dae4SAndroid Build Coastguard Worker my @desc; 368*6236dae4SAndroid Build Coastguard Worker my $quote = 0; 369*6236dae4SAndroid Build Coastguard Worker my $blankline = 0; 370*6236dae4SAndroid Build Coastguard Worker my $header = 0; 371*6236dae4SAndroid Build Coastguard Worker 372*6236dae4SAndroid Build Coastguard Worker # cut off the leading path from the file name, if any 373*6236dae4SAndroid Build Coastguard Worker $f =~ s/^(.*[\\\/])//; 374*6236dae4SAndroid Build Coastguard Worker 375*6236dae4SAndroid Build Coastguard Worker push @desc, ".\\\" generated by cd2nroff $cd2nroff from $f\n"; 376*6236dae4SAndroid Build Coastguard Worker push @desc, ".TH $title $section \"$date\" $source\n"; 377*6236dae4SAndroid Build Coastguard Worker while(<$fh>) { 378*6236dae4SAndroid Build Coastguard Worker $line++; 379*6236dae4SAndroid Build Coastguard Worker 380*6236dae4SAndroid Build Coastguard Worker $d = $_; 381*6236dae4SAndroid Build Coastguard Worker 382*6236dae4SAndroid Build Coastguard Worker if($quote) { 383*6236dae4SAndroid Build Coastguard Worker if($quote == 4) { 384*6236dae4SAndroid Build Coastguard Worker # remove the indentation 385*6236dae4SAndroid Build Coastguard Worker if($d =~ /^ (.*)/) { 386*6236dae4SAndroid Build Coastguard Worker push @desc, "$1\n"; 387*6236dae4SAndroid Build Coastguard Worker next; 388*6236dae4SAndroid Build Coastguard Worker } 389*6236dae4SAndroid Build Coastguard Worker else { 390*6236dae4SAndroid Build Coastguard Worker # end of quote 391*6236dae4SAndroid Build Coastguard Worker $quote = 0; 392*6236dae4SAndroid Build Coastguard Worker push @desc, ".fi\n"; 393*6236dae4SAndroid Build Coastguard Worker next; 394*6236dae4SAndroid Build Coastguard Worker } 395*6236dae4SAndroid Build Coastguard Worker } 396*6236dae4SAndroid Build Coastguard Worker if(/^~~~/) { 397*6236dae4SAndroid Build Coastguard Worker # end of quote 398*6236dae4SAndroid Build Coastguard Worker $quote = 0; 399*6236dae4SAndroid Build Coastguard Worker push @desc, ".fi\n"; 400*6236dae4SAndroid Build Coastguard Worker next; 401*6236dae4SAndroid Build Coastguard Worker } 402*6236dae4SAndroid Build Coastguard Worker # convert single backslahes to doubles 403*6236dae4SAndroid Build Coastguard Worker $d =~ s/\\/\\\\/g; 404*6236dae4SAndroid Build Coastguard Worker # lines starting with a period needs it escaped 405*6236dae4SAndroid Build Coastguard Worker $d =~ s/^\./\\&./; 406*6236dae4SAndroid Build Coastguard Worker push @desc, $d; 407*6236dae4SAndroid Build Coastguard Worker next; 408*6236dae4SAndroid Build Coastguard Worker } 409*6236dae4SAndroid Build Coastguard Worker 410*6236dae4SAndroid Build Coastguard Worker # remove single line HTML comments 411*6236dae4SAndroid Build Coastguard Worker $d =~ s/<!--.*?-->//g; 412*6236dae4SAndroid Build Coastguard Worker 413*6236dae4SAndroid Build Coastguard Worker # **bold** 414*6236dae4SAndroid Build Coastguard Worker $d =~ s/\*\*(\S.*?)\*\*/\\fB$1\\fP/g; 415*6236dae4SAndroid Build Coastguard Worker # *italics* 416*6236dae4SAndroid Build Coastguard Worker $d =~ s/\*(\S.*?)\*/\\fI$1\\fP/g; 417*6236dae4SAndroid Build Coastguard Worker 418*6236dae4SAndroid Build Coastguard Worker if($d =~ /[^\\][\<\>]/) { 419*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:ERROR: un-escaped < or > used\n"; 420*6236dae4SAndroid Build Coastguard Worker $errors++; 421*6236dae4SAndroid Build Coastguard Worker } 422*6236dae4SAndroid Build Coastguard Worker # convert backslash-'<' or '> to just the second character 423*6236dae4SAndroid Build Coastguard Worker $d =~ s/\\([<>])/$1/g; 424*6236dae4SAndroid Build Coastguard Worker 425*6236dae4SAndroid Build Coastguard Worker # mentions of curl symbols with manpages use italics by default 426*6236dae4SAndroid Build Coastguard Worker $d =~ s/((lib|)curl([^ ]*\(3\)))/\\fI$1\\fP/gi; 427*6236dae4SAndroid Build Coastguard Worker 428*6236dae4SAndroid Build Coastguard Worker # backticked becomes italics 429*6236dae4SAndroid Build Coastguard Worker $d =~ s/\`(.*?)\`/\\fI$1\\fP/g; 430*6236dae4SAndroid Build Coastguard Worker 431*6236dae4SAndroid Build Coastguard Worker if(/^## (.*)/) { 432*6236dae4SAndroid Build Coastguard Worker my $word = $1; 433*6236dae4SAndroid Build Coastguard Worker # if there are enclosing quotes, remove them first 434*6236dae4SAndroid Build Coastguard Worker $word =~ s/[\"\'\`](.*)[\"\'\`]\z/$1/; 435*6236dae4SAndroid Build Coastguard Worker 436*6236dae4SAndroid Build Coastguard Worker # enclose in double quotes if there is a space present 437*6236dae4SAndroid Build Coastguard Worker if($word =~ / /) { 438*6236dae4SAndroid Build Coastguard Worker push @desc, ".IP \"$word\"\n"; 439*6236dae4SAndroid Build Coastguard Worker } 440*6236dae4SAndroid Build Coastguard Worker else { 441*6236dae4SAndroid Build Coastguard Worker push @desc, ".IP $word\n"; 442*6236dae4SAndroid Build Coastguard Worker } 443*6236dae4SAndroid Build Coastguard Worker $header = 1; 444*6236dae4SAndroid Build Coastguard Worker } 445*6236dae4SAndroid Build Coastguard Worker elsif(/^##/) { 446*6236dae4SAndroid Build Coastguard Worker # end of IP sequence 447*6236dae4SAndroid Build Coastguard Worker push @desc, ".PP\n"; 448*6236dae4SAndroid Build Coastguard Worker $header = 1; 449*6236dae4SAndroid Build Coastguard Worker } 450*6236dae4SAndroid Build Coastguard Worker elsif(/^# (.*)/) { 451*6236dae4SAndroid Build Coastguard Worker my $word = $1; 452*6236dae4SAndroid Build Coastguard Worker # if there are enclosing quotes, remove them first 453*6236dae4SAndroid Build Coastguard Worker $word =~ s/[\"\'](.*)[\"\']\z/$1/; 454*6236dae4SAndroid Build Coastguard Worker 455*6236dae4SAndroid Build Coastguard Worker if($word eq "PROTOCOLS") { 456*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:WARN: PROTOCOLS section in source file\n"; 457*6236dae4SAndroid Build Coastguard Worker } 458*6236dae4SAndroid Build Coastguard Worker elsif($word eq "AVAILABILITY") { 459*6236dae4SAndroid Build Coastguard Worker print STDERR "$f:$line:1:WARN: AVAILABILITY section in source file\n"; 460*6236dae4SAndroid Build Coastguard Worker } 461*6236dae4SAndroid Build Coastguard Worker elsif($word eq "%PROTOCOLS%") { 462*6236dae4SAndroid Build Coastguard Worker # insert the generated PROTOCOLS section 463*6236dae4SAndroid Build Coastguard Worker push @desc, outprotocols(@proto); 464*6236dae4SAndroid Build Coastguard Worker 465*6236dae4SAndroid Build Coastguard Worker if($proto[0] eq "TLS") { 466*6236dae4SAndroid Build Coastguard Worker push @desc, outtls(@tls); 467*6236dae4SAndroid Build Coastguard Worker } 468*6236dae4SAndroid Build Coastguard Worker $header = 1; 469*6236dae4SAndroid Build Coastguard Worker next; 470*6236dae4SAndroid Build Coastguard Worker } 471*6236dae4SAndroid Build Coastguard Worker elsif($word eq "%AVAILABILITY%") { 472*6236dae4SAndroid Build Coastguard Worker if($addedin ne "n/a") { 473*6236dae4SAndroid Build Coastguard Worker # insert the generated AVAILABILITY section 474*6236dae4SAndroid Build Coastguard Worker push @desc, ".SH AVAILABILITY\n"; 475*6236dae4SAndroid Build Coastguard Worker push @desc, "Added in curl $addedin\n"; 476*6236dae4SAndroid Build Coastguard Worker } 477*6236dae4SAndroid Build Coastguard Worker $header = 1; 478*6236dae4SAndroid Build Coastguard Worker next; 479*6236dae4SAndroid Build Coastguard Worker } 480*6236dae4SAndroid Build Coastguard Worker push @desc, ".SH $word\n"; 481*6236dae4SAndroid Build Coastguard Worker $header = 1; 482*6236dae4SAndroid Build Coastguard Worker } 483*6236dae4SAndroid Build Coastguard Worker elsif(/^~~~c/) { 484*6236dae4SAndroid Build Coastguard Worker # start of a code section, not indented 485*6236dae4SAndroid Build Coastguard Worker $quote = 1; 486*6236dae4SAndroid Build Coastguard Worker push @desc, "\n" if($blankline && !$header); 487*6236dae4SAndroid Build Coastguard Worker $header = 0; 488*6236dae4SAndroid Build Coastguard Worker push @desc, ".nf\n"; 489*6236dae4SAndroid Build Coastguard Worker } 490*6236dae4SAndroid Build Coastguard Worker elsif(/^~~~/) { 491*6236dae4SAndroid Build Coastguard Worker # start of a quote section; not code, not indented 492*6236dae4SAndroid Build Coastguard Worker $quote = 1; 493*6236dae4SAndroid Build Coastguard Worker push @desc, "\n" if($blankline && !$header); 494*6236dae4SAndroid Build Coastguard Worker $header = 0; 495*6236dae4SAndroid Build Coastguard Worker push @desc, ".nf\n"; 496*6236dae4SAndroid Build Coastguard Worker } 497*6236dae4SAndroid Build Coastguard Worker elsif(/^ (.*)/) { 498*6236dae4SAndroid Build Coastguard Worker # quoted, indented by 4 space 499*6236dae4SAndroid Build Coastguard Worker $quote = 4; 500*6236dae4SAndroid Build Coastguard Worker push @desc, "\n" if($blankline && !$header); 501*6236dae4SAndroid Build Coastguard Worker $header = 0; 502*6236dae4SAndroid Build Coastguard Worker push @desc, ".nf\n$1\n"; 503*6236dae4SAndroid Build Coastguard Worker } 504*6236dae4SAndroid Build Coastguard Worker elsif(/^[ \t]*\n/) { 505*6236dae4SAndroid Build Coastguard Worker # count and ignore blank lines 506*6236dae4SAndroid Build Coastguard Worker $blankline++; 507*6236dae4SAndroid Build Coastguard Worker } 508*6236dae4SAndroid Build Coastguard Worker else { 509*6236dae4SAndroid Build Coastguard Worker # don't output newlines if this is the first content after a 510*6236dae4SAndroid Build Coastguard Worker # header 511*6236dae4SAndroid Build Coastguard Worker push @desc, "\n" if($blankline && !$header); 512*6236dae4SAndroid Build Coastguard Worker $blankline = 0; 513*6236dae4SAndroid Build Coastguard Worker $header = 0; 514*6236dae4SAndroid Build Coastguard Worker 515*6236dae4SAndroid Build Coastguard Worker # quote minuses in the output 516*6236dae4SAndroid Build Coastguard Worker $d =~ s/([^\\])-/$1\\-/g; 517*6236dae4SAndroid Build Coastguard Worker # replace single quotes 518*6236dae4SAndroid Build Coastguard Worker $d =~ s/\'/\\(aq/g; 519*6236dae4SAndroid Build Coastguard Worker # handle double quotes first on the line 520*6236dae4SAndroid Build Coastguard Worker $d =~ s/^(\s*)\"/$1\\&\"/; 521*6236dae4SAndroid Build Coastguard Worker 522*6236dae4SAndroid Build Coastguard Worker # lines starting with a period needs it escaped 523*6236dae4SAndroid Build Coastguard Worker $d =~ s/^\./\\&./; 524*6236dae4SAndroid Build Coastguard Worker 525*6236dae4SAndroid Build Coastguard Worker if($d =~ /^(.*) /) { 526*6236dae4SAndroid Build Coastguard Worker printf STDERR "$f:$line:%d:ERROR: 2 spaces detected\n", 527*6236dae4SAndroid Build Coastguard Worker length($1); 528*6236dae4SAndroid Build Coastguard Worker $errors++; 529*6236dae4SAndroid Build Coastguard Worker } 530*6236dae4SAndroid Build Coastguard Worker if($d =~ /^[ \t]*\n/) { 531*6236dae4SAndroid Build Coastguard Worker # replaced away all contents 532*6236dae4SAndroid Build Coastguard Worker $blankline= 1; 533*6236dae4SAndroid Build Coastguard Worker } 534*6236dae4SAndroid Build Coastguard Worker else { 535*6236dae4SAndroid Build Coastguard Worker push @desc, $d; 536*6236dae4SAndroid Build Coastguard Worker } 537*6236dae4SAndroid Build Coastguard Worker } 538*6236dae4SAndroid Build Coastguard Worker } 539*6236dae4SAndroid Build Coastguard Worker if($fh != \*STDIN) { 540*6236dae4SAndroid Build Coastguard Worker close($fh); 541*6236dae4SAndroid Build Coastguard Worker } 542*6236dae4SAndroid Build Coastguard Worker push @desc, outseealso(@seealso); 543*6236dae4SAndroid Build Coastguard Worker if($dir) { 544*6236dae4SAndroid Build Coastguard Worker if($keepfilename) { 545*6236dae4SAndroid Build Coastguard Worker $title = $f; 546*6236dae4SAndroid Build Coastguard Worker $title =~ s/\.[^.]*$//; 547*6236dae4SAndroid Build Coastguard Worker } 548*6236dae4SAndroid Build Coastguard Worker my $outfile = "$dir/$title.$section"; 549*6236dae4SAndroid Build Coastguard Worker if(defined($extension)) { 550*6236dae4SAndroid Build Coastguard Worker $outfile .= $extension; 551*6236dae4SAndroid Build Coastguard Worker } 552*6236dae4SAndroid Build Coastguard Worker if(!open(O, ">", $outfile)) { 553*6236dae4SAndroid Build Coastguard Worker print STDERR "Failed to open $outfile : $!\n"; 554*6236dae4SAndroid Build Coastguard Worker return 1; 555*6236dae4SAndroid Build Coastguard Worker } 556*6236dae4SAndroid Build Coastguard Worker print O @desc; 557*6236dae4SAndroid Build Coastguard Worker close(O); 558*6236dae4SAndroid Build Coastguard Worker } 559*6236dae4SAndroid Build Coastguard Worker else { 560*6236dae4SAndroid Build Coastguard Worker print @desc; 561*6236dae4SAndroid Build Coastguard Worker } 562*6236dae4SAndroid Build Coastguard Worker return $errors; 563*6236dae4SAndroid Build Coastguard Worker} 564*6236dae4SAndroid Build Coastguard Worker 565*6236dae4SAndroid Build Coastguard Workerif(@ARGV) { 566*6236dae4SAndroid Build Coastguard Worker for my $f (@ARGV) { 567*6236dae4SAndroid Build Coastguard Worker my $r = single($f); 568*6236dae4SAndroid Build Coastguard Worker if($r) { 569*6236dae4SAndroid Build Coastguard Worker exit $r; 570*6236dae4SAndroid Build Coastguard Worker } 571*6236dae4SAndroid Build Coastguard Worker } 572*6236dae4SAndroid Build Coastguard Worker} 573*6236dae4SAndroid Build Coastguard Workerelse { 574*6236dae4SAndroid Build Coastguard Worker exit single(); 575*6236dae4SAndroid Build Coastguard Worker} 576