Commit 050aa803 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

cmdline-opts: first test version of a new man page generator kit

See MANPAGE.md for the description of how this works. Each command line
option is now described in a separate .d file.
parent ebf985c1
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
# curl man page generator

This is the curl man page generator. It generates a single nroff man page
output from the set of sources files in this directory.

There is one source file for each supported command line option. The format is
described below.

## Option files

Each command line option is described in a file named `<long name>.d`, where
option name is written without any prefixing dashes. Like the file name for
the -v, --verbose option is named `verbose.d`.

Each file has a set of meta-data and a body of text.

### Meta-data

    Short: (single letter, without dash)
    Long: (long form name, without dashes)
    Arg: (the argument the option takes)
    Magic: (description of "magic" options)
    Tags: (space separated list)
    Protocols: (space separated list for which protocols this option works)
    Added: (version number in which this was added)
    Mutexed: (space separated list of options this overrides)
    Requires: (space separated list of features this option requres)
    See-also: (space separated list of related options)
    --- (end of meta-data)

### Body

The body of the description. Only refer to options with their long form option
version, like --verbose. The output generator will replace such with the
correct markup that shows both short and long version.

## Header

`page-header` is the nroff formatted file that will be output before the
generated options output.

## Generate

`perl gen.pl`

This command outputs an nroff file, meant to become `curl.1`. The full curl
man page.
+23 −0
Original line number Diff line number Diff line
Short: c
Long: cookie-jar
Arg: <filename>
Protocols: HTTP
---
Specify to which file you want curl to write all cookies after a completed
operation. Curl writes all cookies from its in-memory cookie storage to the
given file at the end of operations. If no cookies are known, no data will be
written. The file will be written using the Netscape cookie file format. If
you set the file name to a single dash, "-", the cookies will be written to
stdout.

This command line option will activate the cookie engine that makes curl
record and use cookies. Another way to activate it is to use the --cookie
option.

If the cookie jar can't be created or written to, the whole curl operation
won't fail or even report an error clearly. Using --verbose will get a warning
displayed, but that is the only visible feedback you get about this possibly
lethal situation.

If this option is used several times, the last specified file name will be
used.
+35 −0
Original line number Diff line number Diff line
Short: b
Long: cookie
Arg: <name=data>
Protocols: HTTP
---
Pass the data to the HTTP server in the Cookie header. It is supposedly
the data previously received from the server in a "Set-Cookie:" line.  The
data should be in the format "NAME1=VALUE1; NAME2=VALUE2".

If no '=' symbol is used in the argument, it is instead treated as a filename
to read previously stored cookie from. This option also activates the cookie
engine which will make curl record incoming cookies, which may be handy if
you're using this in combination with the --location option or do multiple URL
transfers on the same invoke.

The file format of the file to read cookies from should be plain HTTP headers
(Set-Cookie style) or the Netscape/Mozilla cookie file format.

The file specified with --cookie is only used as input. No cookies will be
written to the file. To store cookies, use the --cookie-jar option.

Exercise caution if you are using this option and multiple transfers may
occur.  If you use the NAME1=VALUE1; format, or in a file use the Set-Cookie
format and don't specify a domain, then the cookie is sent for any domain
(even after redirects are followed) and cannot be modified by a server-set
cookie. If the cookie engine is enabled and a server sets a cookie of the same
name then both will be sent on a future transfer to that server, likely not
what you intended.  To address these issues set a domain in Set-Cookie (doing
that will include sub domains) or use the Netscape format.

If this option is used several times, the last one will be used.

Users very often want to both read cookies from a file and write updated
cookies back to a file, so using both --cookie and --cookie-jar in the same
command line is common.
+216 −0
Original line number Diff line number Diff line
#!/usr/bin/perl

my $some_dir=".";

opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!";
my @s = grep { /\.d$/ && -f "$some_dir/$_" } readdir($dh);
closedir $dh;

my %optshort;
my %optlong;

# get the long name version, return the man page string
sub manpageify {
    my ($k)=@_;
    my $l;
    if($optlong{$k} ne "") {
        # both short + long
        $l = "\\fI-".$optlong{$k}.", --$k\\fP";
    }
    else {
        # only long
        $l = "\\fI--$k\\fP";
    }
    return $l;
}

sub printdesc {
    my @desc = @_;
    for my $d (@desc) {
        # skip lines starting with space (examples)
        if($d =~ /^[^ ]/) {
            for my $k (keys %optlong) {
                my $l = manpageify($k);
                $d =~ s/--$k(\s)/$l$1/;
            }
        }
        print $d;
    }
}

sub single {
    my ($f)=@_;
    open(F, "<$f");
    my $short;
    my $long;
    my $tags;
    my $added;
    my $protocols;
    my $arg;
    my $mutexed;
    my $requires;
    my $seealso;
    my $magic; # cmdline special option
    while(<F>) {
        if(/^Short: (.)/i) {
            $short=$1;
        }
        elsif(/^Long: (.*)/i) {
            $long=$1;
        }
        elsif(/^Added: (.*)/i) {
            $added=$1;
        }
        elsif(/^Tags: (.*)/i) {
            $tags=$1;
        }
        elsif(/^Arg: (.*)/i) {
            $arg=$1;
        }
        elsif(/^Magic: (.*)/i) {
            $magic=$1;
        }
        elsif(/^Mutexed: (.*)/i) {
            $mutexed=$1;
        }
        elsif(/^Protocols: (.*)/i) {
            $protocols=$1;
        }
        elsif(/^See-also: (.*)/i) {
            $seealso=$1;
        }
        elsif(/^Requires: (.*)/i) {
            $requires=$1;
        }
        elsif(/^---/) {
            last;
        }
    }
    my @dest;
    while(<F>) {
        push @desc, $_;
    }
    close(F);
    my $opt;
    if(defined($short) && $long) {
        $opt = "-$short, --$long";
    }
    elsif($short && !$long) {
        $opt = "-$short";
    }
    elsif($long && !$short) {
        $opt = "--$long";
    }

    if($arg) {
        $opt .= " $arg";
    }

    print ".IP \"$opt\"\n";
    my $o;
    if($protocols) {
        $o++;
        print "($protocols) ";
    }
    if(!$arg && !$mutexed && !$magic) {
        $o++;
        print "[Boolean] ";
    }
    if($magic) {
        $o++;
        print "[cmdline control] ";
    }

    print "\n" if($o);

    printdesc(@desc);
    undef @desc;

    my @foot;
    if($seealso) {
        my @m=split(/ /, $seealso);
        my $mstr;
        for my $k (@m) {
            my $l = manpageify($k);
            $mstr .= sprintf "%s$l", $mstr?" and ":"";
        }
        push @foot, "See also $mstr. ";
    }
    if($requires) {
        my $l = manpageify($long);
        push @foot, "$l requires that the underlying libcurl".
            " was built to support $requires. ";
    }
    if($mutexed) {
        my @m=split(/ /, $mutexed);
        my $mstr;
        for my $k (@m) {
            my $l = manpageify($k);
            $mstr .= sprintf "%s$l", $mstr?" and ":"";
        }
        push @foot, "This option overrides $mstr. ";
    }
    if($added) {
        push @foot, "Added in $added. ";
    }
    if($foot[0]) {
        print "\n";
        print @foot;
        print "\n";
    }
}

sub getshortlong {
    my ($f)=@_;
    open(F, "<$f");
    my $short;
    my $long;

    while(<F>) {
        if(/^Short: (.)/i) {
            $short=$1;
        }
        elsif(/^Long: (.*)/i) {
            $long=$1;
        }
        elsif(/^---/) {
            last;
        }
    }
    close(F);
    if($short) {
        $optshort{$short}=$long;
    }
    if($long) {
        $optlong{$long}=$short;
    }
}

sub indexoptions {
  foreach my $f (@s) {
    getshortlong($f);
  }
}

sub header {
    open(F, "<page-header");
    my @d;
    while(<F>) {
        push @d, $_;
    }
    close(F);
    printdesc(@d);
}

#------------------------------------------------------------------------

# learn all existing options
indexoptions();

# show the page header
header();

# output docs for all options
foreach my $f (sort @s) {
    single($f);
}
+9 −0
Original line number Diff line number Diff line
Short: 0
Long: http1.0
Tags: Versions
Protocols: HTTP
Added:
Mutexed: http1.1 http2
---
Tells curl to use HTTP version 1.0 instead of using its internally preferred
HTTP version.
Loading