curl: --help [option] displays documentation for given cmdline option
Since the documentation text blob might be gzipped, it needs to search for what to output in a streaming manner. It then first searches for "\nALL OPTIONS". Then, it looks for the start to display at "\n -[option]" and stops again at "\n -". Except for the last option in the man page, which ends at "\nFILES" - the subtitle for the section following all options in the manpage. Test 1707 to 1710 verify Closes #13997
This commit is contained in:
parent
9b1e4b4632
commit
9a0cf56471
@ -148,7 +148,6 @@
|
||||
18. Command line tool
|
||||
18.1 sync
|
||||
18.2 glob posts
|
||||
18.3 -h option
|
||||
18.4 --proxycommand
|
||||
18.5 UTF-8 filenames in Content-Disposition
|
||||
18.6 Option to make -Z merge lined based outputs on stdout
|
||||
@ -1037,12 +1036,6 @@
|
||||
Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
|
||||
This is easily scripted though.
|
||||
|
||||
18.3 -h option
|
||||
|
||||
Support "curl -h --insecure" etc to output the manpage section for the
|
||||
--insecure command line option in the terminal. Should be possible to work
|
||||
with either long or short versions of command line options.
|
||||
|
||||
18.4 --proxycommand
|
||||
|
||||
Allow the user to make curl run a command and use its stdio to make requests
|
||||
|
||||
@ -24,3 +24,5 @@ clean option state, except for the options that are global. Global options
|
||||
retain their values and meaning even after --next.
|
||||
|
||||
The following options are global: `%GLOBALS`.
|
||||
|
||||
# ALL OPTIONS
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Long: help
|
||||
Arg: <category>
|
||||
Arg: <subject>
|
||||
Short: h
|
||||
Help: Get help for commands
|
||||
Category: important curl
|
||||
@ -12,15 +12,28 @@ See-also:
|
||||
- verbose
|
||||
Example:
|
||||
- --help all
|
||||
- --help --insecure
|
||||
- --help -f
|
||||
---
|
||||
|
||||
# `--help`
|
||||
|
||||
Usage help. List all curl command line options within the given **category**.
|
||||
Usage help. Provide help for the subject given as an optional argument.
|
||||
|
||||
If no argument is provided, curl displays the most important command line
|
||||
arguments.
|
||||
|
||||
For category **all**, curl displays help for all options.
|
||||
The argument can either be a **category** or a **command line option**. When a
|
||||
category is provided, curl shows all command line options within the given
|
||||
category. Specify category `all` to list all available options.
|
||||
|
||||
If **category** is specified, curl displays all available help categories.
|
||||
If `category` is specified, curl displays all available help categories.
|
||||
|
||||
If the provided subject is instead an existing command line option, specified
|
||||
either in its short form with a single dash and a single letter, or in the
|
||||
long form with two dashes and a longer name, curl displays a help text for
|
||||
that option in the terminal.
|
||||
|
||||
The help output is extensive for some options.
|
||||
|
||||
If the provided command line option is not known, curl says so.
|
||||
|
||||
@ -23,13 +23,6 @@
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Yeah, I know, probably 1000 other persons already wrote a script like
|
||||
# this, but I'll tell ya:
|
||||
|
||||
# THEY DON'T FIT ME :-)
|
||||
|
||||
# Get readme file as parameter:
|
||||
|
||||
if($ARGV[0] eq "-c") {
|
||||
$c=1;
|
||||
shift @ARGV;
|
||||
@ -53,6 +46,8 @@ print <<HEAD
|
||||
*/
|
||||
#ifdef USE_MANUAL
|
||||
#include "tool_hugehelp.h"
|
||||
#include "tool_help.h"
|
||||
|
||||
HEAD
|
||||
;
|
||||
if($c) {
|
||||
@ -111,23 +106,25 @@ static void zfree_func(voidpf opaque, voidpf ptr)
|
||||
(void) opaque;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#define HEADERLEN 10
|
||||
|
||||
/* Decompress and send to stdout a gzip-compressed buffer */
|
||||
void hugehelp(void)
|
||||
{
|
||||
unsigned char *buf;
|
||||
int status, headerlen;
|
||||
int status;
|
||||
z_stream z;
|
||||
|
||||
/* Make sure no gzip options are set */
|
||||
if(hugehelpgz[3] & 0xfe)
|
||||
return;
|
||||
|
||||
headerlen = 10;
|
||||
memset(&z, 0, sizeof(z_stream));
|
||||
z.zalloc = (alloc_func)zalloc_func;
|
||||
z.zfree = (free_func)zfree_func;
|
||||
z.avail_in = (unsigned int)(sizeof(hugehelpgz) - headerlen);
|
||||
z.next_in = (unsigned char *)hugehelpgz + headerlen;
|
||||
z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN);
|
||||
z.next_in = (unsigned char *)hugehelpgz + HEADERLEN;
|
||||
|
||||
if(inflateInit2(&z, -MAX_WBITS) != Z_OK)
|
||||
return;
|
||||
@ -144,7 +141,49 @@ void hugehelp(void)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break; /* Error */
|
||||
break; /* error */
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
inflateEnd(&z);
|
||||
}
|
||||
/* Show the help text for the 'arg' curl argument on stdout */
|
||||
void showhelp(const char *trigger, const char *arg, const char *endarg)
|
||||
{
|
||||
unsigned char *buf;
|
||||
int status;
|
||||
z_stream z;
|
||||
struct scan_ctx ctx;
|
||||
inithelpscan(&ctx, trigger, arg, endarg);
|
||||
|
||||
/* Make sure no gzip options are set */
|
||||
if(hugehelpgz[3] & 0xfe)
|
||||
return;
|
||||
|
||||
memset(&z, 0, sizeof(z_stream));
|
||||
z.zalloc = (alloc_func)zalloc_func;
|
||||
z.zfree = (free_func)zfree_func;
|
||||
z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN);
|
||||
z.next_in = (unsigned char *)hugehelpgz + HEADERLEN;
|
||||
|
||||
if(inflateInit2(&z, -MAX_WBITS) != Z_OK)
|
||||
return;
|
||||
|
||||
buf = malloc(BUF_SIZE);
|
||||
if(buf) {
|
||||
while(1) {
|
||||
z.avail_out = BUF_SIZE;
|
||||
z.next_out = buf;
|
||||
status = inflate(&z, Z_SYNC_FLUSH);
|
||||
if(status == Z_OK || status == Z_STREAM_END) {
|
||||
size_t len = BUF_SIZE - z.avail_out;
|
||||
if(!helpscan(buf, len, &ctx))
|
||||
break;
|
||||
if(status == Z_STREAM_END)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break; /* error */
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
@ -188,6 +227,21 @@ void hugehelp(void)
|
||||
while(curlman[i])
|
||||
puts(curlman[i++]);
|
||||
}
|
||||
|
||||
/* Show the help text for the 'arg' curl argument on stdout */
|
||||
void showhelp(const char *trigger, const char *arg, const char *endarg)
|
||||
{
|
||||
int i = 0;
|
||||
struct scan_ctx ctx;
|
||||
inithelpscan(&ctx, trigger, arg, endarg);
|
||||
while(curlman[i]) {
|
||||
size_t len = strlen(curlman[i]);
|
||||
if(!helpscan((unsigned char *)curlman[i], len, &ctx) ||
|
||||
!helpscan((unsigned char *)"\\n", 1, &ctx))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
ENDLINE
|
||||
;
|
||||
|
||||
|
||||
@ -71,306 +71,16 @@ static ParameterError getstr(char **str, const char *val, bool allowblank)
|
||||
return PARAM_OK;
|
||||
}
|
||||
|
||||
/* one enum for every command line option. The name is the verbatim long
|
||||
option name, but in uppercase with periods and minuses replaced with
|
||||
underscores using a "C_" prefix. */
|
||||
typedef enum {
|
||||
C_ABSTRACT_UNIX_SOCKET,
|
||||
C_ALPN,
|
||||
C_ALT_SVC,
|
||||
C_ANYAUTH,
|
||||
C_APPEND,
|
||||
C_AWS_SIGV4,
|
||||
C_BASIC,
|
||||
C_BUFFER,
|
||||
C_CA_NATIVE,
|
||||
C_CACERT,
|
||||
C_CAPATH,
|
||||
C_CERT,
|
||||
C_CERT_STATUS,
|
||||
C_CERT_TYPE,
|
||||
C_CIPHERS,
|
||||
C_CLOBBER,
|
||||
C_COMPRESSED,
|
||||
C_COMPRESSED_SSH,
|
||||
C_CONFIG,
|
||||
C_CONNECT_TIMEOUT,
|
||||
C_CONNECT_TO,
|
||||
C_CONTINUE_AT,
|
||||
C_COOKIE,
|
||||
C_COOKIE_JAR,
|
||||
C_CREATE_DIRS,
|
||||
C_CREATE_FILE_MODE,
|
||||
C_CRLF,
|
||||
C_CRLFILE,
|
||||
C_CURVES,
|
||||
C_DATA,
|
||||
C_DATA_ASCII,
|
||||
C_DATA_BINARY,
|
||||
C_DATA_RAW,
|
||||
C_DATA_URLENCODE,
|
||||
C_DELEGATION,
|
||||
C_DIGEST,
|
||||
C_DISABLE,
|
||||
C_DISABLE_EPRT,
|
||||
C_DISABLE_EPSV,
|
||||
C_DISALLOW_USERNAME_IN_URL,
|
||||
C_DNS_INTERFACE,
|
||||
C_DNS_IPV4_ADDR,
|
||||
C_DNS_IPV6_ADDR,
|
||||
C_DNS_SERVERS,
|
||||
C_DOH_CERT_STATUS,
|
||||
C_DOH_INSECURE,
|
||||
C_DOH_URL,
|
||||
C_DUMP_CA_EMBED,
|
||||
C_DUMP_HEADER,
|
||||
C_ECH,
|
||||
C_EGD_FILE,
|
||||
C_ENGINE,
|
||||
C_EPRT,
|
||||
C_EPSV,
|
||||
C_ETAG_COMPARE,
|
||||
C_ETAG_SAVE,
|
||||
C_EXPECT100_TIMEOUT,
|
||||
C_FAIL,
|
||||
C_FAIL_EARLY,
|
||||
C_FAIL_WITH_BODY,
|
||||
C_FALSE_START,
|
||||
C_FORM,
|
||||
C_FORM_ESCAPE,
|
||||
C_FORM_STRING,
|
||||
C_FTP_ACCOUNT,
|
||||
C_FTP_ALTERNATIVE_TO_USER,
|
||||
C_FTP_CREATE_DIRS,
|
||||
C_FTP_METHOD,
|
||||
C_FTP_PASV,
|
||||
C_FTP_PORT,
|
||||
C_FTP_PRET,
|
||||
C_FTP_SKIP_PASV_IP,
|
||||
C_FTP_SSL,
|
||||
C_FTP_SSL_CCC,
|
||||
C_FTP_SSL_CCC_MODE,
|
||||
C_FTP_SSL_CONTROL,
|
||||
C_FTP_SSL_REQD,
|
||||
C_GET,
|
||||
C_GLOBOFF,
|
||||
C_HAPPY_EYEBALLS_TIMEOUT_MS,
|
||||
C_HAPROXY_CLIENTIP,
|
||||
C_HAPROXY_PROTOCOL,
|
||||
C_HEAD,
|
||||
C_HEADER,
|
||||
C_HELP,
|
||||
C_HOSTPUBMD5,
|
||||
C_HOSTPUBSHA256,
|
||||
C_HSTS,
|
||||
C_HTTP0_9,
|
||||
C_HTTP1_0,
|
||||
C_HTTP1_1,
|
||||
C_HTTP2,
|
||||
C_HTTP2_PRIOR_KNOWLEDGE,
|
||||
C_HTTP3,
|
||||
C_HTTP3_ONLY,
|
||||
C_IGNORE_CONTENT_LENGTH,
|
||||
C_INCLUDE,
|
||||
C_INSECURE,
|
||||
C_INTERFACE,
|
||||
C_IPFS_GATEWAY,
|
||||
C_IPV4,
|
||||
C_IPV6,
|
||||
C_JSON,
|
||||
C_JUNK_SESSION_COOKIES,
|
||||
C_KEEPALIVE,
|
||||
C_KEEPALIVE_CNT,
|
||||
C_KEEPALIVE_TIME,
|
||||
C_KEY,
|
||||
C_KEY_TYPE,
|
||||
C_KRB,
|
||||
C_KRB4,
|
||||
C_LIBCURL,
|
||||
C_LIMIT_RATE,
|
||||
C_LIST_ONLY,
|
||||
C_LOCAL_PORT,
|
||||
C_LOCATION,
|
||||
C_LOCATION_TRUSTED,
|
||||
C_LOGIN_OPTIONS,
|
||||
C_MAIL_AUTH,
|
||||
C_MAIL_FROM,
|
||||
C_MAIL_RCPT,
|
||||
C_MAIL_RCPT_ALLOWFAILS,
|
||||
C_MANUAL,
|
||||
C_MAX_FILESIZE,
|
||||
C_MAX_REDIRS,
|
||||
C_MAX_TIME,
|
||||
C_METALINK,
|
||||
C_MPTCP,
|
||||
C_NEGOTIATE,
|
||||
C_NETRC,
|
||||
C_NETRC_FILE,
|
||||
C_NETRC_OPTIONAL,
|
||||
C_NEXT,
|
||||
C_NOPROXY,
|
||||
C_NPN,
|
||||
C_NTLM,
|
||||
C_NTLM_WB,
|
||||
C_OAUTH2_BEARER,
|
||||
C_OUTPUT,
|
||||
C_OUTPUT_DIR,
|
||||
C_PARALLEL,
|
||||
C_PARALLEL_IMMEDIATE,
|
||||
C_PARALLEL_MAX,
|
||||
C_PASS,
|
||||
C_PATH_AS_IS,
|
||||
C_PINNEDPUBKEY,
|
||||
C_POST301,
|
||||
C_POST302,
|
||||
C_POST303,
|
||||
C_PREPROXY,
|
||||
C_PROGRESS_BAR,
|
||||
C_PROGRESS_METER,
|
||||
C_PROTO,
|
||||
C_PROTO_DEFAULT,
|
||||
C_PROTO_REDIR,
|
||||
C_PROXY,
|
||||
C_PROXY_ANYAUTH,
|
||||
C_PROXY_BASIC,
|
||||
C_PROXY_CA_NATIVE,
|
||||
C_PROXY_CACERT,
|
||||
C_PROXY_CAPATH,
|
||||
C_PROXY_CERT,
|
||||
C_PROXY_CERT_TYPE,
|
||||
C_PROXY_CIPHERS,
|
||||
C_PROXY_CRLFILE,
|
||||
C_PROXY_DIGEST,
|
||||
C_PROXY_HEADER,
|
||||
C_PROXY_HTTP2,
|
||||
C_PROXY_INSECURE,
|
||||
C_PROXY_KEY,
|
||||
C_PROXY_KEY_TYPE,
|
||||
C_PROXY_NEGOTIATE,
|
||||
C_PROXY_NTLM,
|
||||
C_PROXY_PASS,
|
||||
C_PROXY_PINNEDPUBKEY,
|
||||
C_PROXY_SERVICE_NAME,
|
||||
C_PROXY_SSL_ALLOW_BEAST,
|
||||
C_PROXY_SSL_AUTO_CLIENT_CERT,
|
||||
C_PROXY_TLS13_CIPHERS,
|
||||
C_PROXY_TLSAUTHTYPE,
|
||||
C_PROXY_TLSPASSWORD,
|
||||
C_PROXY_TLSUSER,
|
||||
C_PROXY_TLSV1,
|
||||
C_PROXY_USER,
|
||||
C_PROXY1_0,
|
||||
C_PROXYTUNNEL,
|
||||
C_PUBKEY,
|
||||
C_QUOTE,
|
||||
C_RANDOM_FILE,
|
||||
C_RANGE,
|
||||
C_RATE,
|
||||
C_RAW,
|
||||
C_REFERER,
|
||||
C_REMOTE_HEADER_NAME,
|
||||
C_REMOTE_NAME,
|
||||
C_REMOTE_NAME_ALL,
|
||||
C_REMOTE_TIME,
|
||||
C_REMOVE_ON_ERROR,
|
||||
C_REQUEST,
|
||||
C_REQUEST_TARGET,
|
||||
C_RESOLVE,
|
||||
C_RETRY,
|
||||
C_RETRY_ALL_ERRORS,
|
||||
C_RETRY_CONNREFUSED,
|
||||
C_RETRY_DELAY,
|
||||
C_RETRY_MAX_TIME,
|
||||
C_SASL_AUTHZID,
|
||||
C_SASL_IR,
|
||||
C_SERVICE_NAME,
|
||||
C_SESSIONID,
|
||||
C_SHOW_ERROR,
|
||||
C_SHOW_HEADERS,
|
||||
C_SILENT,
|
||||
C_SOCKS4,
|
||||
C_SOCKS4A,
|
||||
C_SOCKS5,
|
||||
C_SOCKS5_BASIC,
|
||||
C_SOCKS5_GSSAPI,
|
||||
C_SOCKS5_GSSAPI_NEC,
|
||||
C_SOCKS5_GSSAPI_SERVICE,
|
||||
C_SOCKS5_HOSTNAME,
|
||||
C_SPEED_LIMIT,
|
||||
C_SPEED_TIME,
|
||||
C_SSL,
|
||||
C_SSL_ALLOW_BEAST,
|
||||
C_SSL_AUTO_CLIENT_CERT,
|
||||
C_SSL_NO_REVOKE,
|
||||
C_SSL_REQD,
|
||||
C_SSL_REVOKE_BEST_EFFORT,
|
||||
C_SSLV2,
|
||||
C_SSLV3,
|
||||
C_STDERR,
|
||||
C_STYLED_OUTPUT,
|
||||
C_SUPPRESS_CONNECT_HEADERS,
|
||||
C_TCP_FASTOPEN,
|
||||
C_TCP_NODELAY,
|
||||
C_TELNET_OPTION,
|
||||
C_TEST_EVENT,
|
||||
C_TFTP_BLKSIZE,
|
||||
C_TFTP_NO_OPTIONS,
|
||||
C_TIME_COND,
|
||||
C_TLS_MAX,
|
||||
C_TLS13_CIPHERS,
|
||||
C_TLSAUTHTYPE,
|
||||
C_TLSPASSWORD,
|
||||
C_TLSUSER,
|
||||
C_TLSV1,
|
||||
C_TLSV1_0,
|
||||
C_TLSV1_1,
|
||||
C_TLSV1_2,
|
||||
C_TLSV1_3,
|
||||
C_TR_ENCODING,
|
||||
C_TRACE,
|
||||
C_TRACE_ASCII,
|
||||
C_TRACE_CONFIG,
|
||||
C_TRACE_IDS,
|
||||
C_TRACE_TIME,
|
||||
C_IP_TOS,
|
||||
C_UNIX_SOCKET,
|
||||
C_UPLOAD_FILE,
|
||||
C_URL,
|
||||
C_URL_QUERY,
|
||||
C_USE_ASCII,
|
||||
C_USER,
|
||||
C_USER_AGENT,
|
||||
C_VARIABLE,
|
||||
C_VERBOSE,
|
||||
C_VERSION,
|
||||
C_VLAN_PRIORITY,
|
||||
C_WDEBUG,
|
||||
C_WRITE_OUT,
|
||||
C_XATTR
|
||||
} cmdline_t;
|
||||
|
||||
struct LongShort {
|
||||
const char *lname; /* long name option */
|
||||
enum {
|
||||
ARG_NONE, /* stand-alone but not a boolean */
|
||||
ARG_BOOL, /* accepts a --no-[name] prefix */
|
||||
ARG_STRG, /* requires an argument */
|
||||
ARG_FILE /* requires an argument, usually a filename */
|
||||
} desc;
|
||||
char letter; /* short name option or ' ' */
|
||||
cmdline_t cmd;
|
||||
};
|
||||
|
||||
/* this array MUST be alphasorted based on the 'lname' */
|
||||
static const struct LongShort aliases[]= {
|
||||
{"abstract-unix-socket", ARG_FILE, ' ', C_ABSTRACT_UNIX_SOCKET},
|
||||
{"alpn", ARG_BOOL, ' ', C_ALPN},
|
||||
{"alpn", ARG_BOOL|ARG_NO, ' ', C_ALPN},
|
||||
{"alt-svc", ARG_STRG, ' ', C_ALT_SVC},
|
||||
{"anyauth", ARG_BOOL, ' ', C_ANYAUTH},
|
||||
{"append", ARG_BOOL, 'a', C_APPEND},
|
||||
{"aws-sigv4", ARG_STRG, ' ', C_AWS_SIGV4},
|
||||
{"basic", ARG_BOOL, ' ', C_BASIC},
|
||||
{"buffer", ARG_BOOL, 'N', C_BUFFER},
|
||||
{"buffer", ARG_BOOL|ARG_NO, 'N', C_BUFFER},
|
||||
{"ca-native", ARG_BOOL, ' ', C_CA_NATIVE},
|
||||
{"cacert", ARG_FILE, ' ', C_CACERT},
|
||||
{"capath", ARG_FILE, ' ', C_CAPATH},
|
||||
@ -378,7 +88,7 @@ static const struct LongShort aliases[]= {
|
||||
{"cert-status", ARG_BOOL, ' ', C_CERT_STATUS},
|
||||
{"cert-type", ARG_STRG, ' ', C_CERT_TYPE},
|
||||
{"ciphers", ARG_STRG, ' ', C_CIPHERS},
|
||||
{"clobber", ARG_BOOL, ' ', C_CLOBBER},
|
||||
{"clobber", ARG_BOOL|ARG_NO, ' ', C_CLOBBER},
|
||||
{"compressed", ARG_BOOL, ' ', C_COMPRESSED},
|
||||
{"compressed-ssh", ARG_BOOL, ' ', C_COMPRESSED_SSH},
|
||||
{"config", ARG_FILE, 'K', C_CONFIG},
|
||||
@ -468,7 +178,7 @@ static const struct LongShort aliases[]= {
|
||||
{"ipv6", ARG_NONE, '6', C_IPV6},
|
||||
{"json", ARG_STRG, ' ', C_JSON},
|
||||
{"junk-session-cookies", ARG_BOOL, 'j', C_JUNK_SESSION_COOKIES},
|
||||
{"keepalive", ARG_BOOL, ' ', C_KEEPALIVE},
|
||||
{"keepalive", ARG_BOOL|ARG_NO, ' ', C_KEEPALIVE},
|
||||
{"keepalive-cnt", ARG_STRG, ' ', C_KEEPALIVE_CNT},
|
||||
{"keepalive-time", ARG_STRG, ' ', C_KEEPALIVE_TIME},
|
||||
{"key", ARG_FILE, ' ', C_KEY},
|
||||
@ -498,7 +208,7 @@ static const struct LongShort aliases[]= {
|
||||
{"netrc-optional", ARG_BOOL, ' ', C_NETRC_OPTIONAL},
|
||||
{"next", ARG_NONE, ':', C_NEXT},
|
||||
{"noproxy", ARG_STRG, ' ', C_NOPROXY},
|
||||
{"npn", ARG_BOOL, ' ', C_NPN},
|
||||
{"npn", ARG_BOOL|ARG_NO, ' ', C_NPN},
|
||||
{"ntlm", ARG_BOOL, ' ', C_NTLM},
|
||||
{"ntlm-wb", ARG_BOOL, ' ', C_NTLM_WB},
|
||||
{"oauth2-bearer", ARG_STRG, ' ', C_OAUTH2_BEARER},
|
||||
@ -515,7 +225,7 @@ static const struct LongShort aliases[]= {
|
||||
{"post303", ARG_BOOL, ' ', C_POST303},
|
||||
{"preproxy", ARG_STRG, ' ', C_PREPROXY},
|
||||
{"progress-bar", ARG_BOOL, '#', C_PROGRESS_BAR},
|
||||
{"progress-meter", ARG_BOOL, ' ', C_PROGRESS_METER},
|
||||
{"progress-meter", ARG_BOOL|ARG_NO, ' ', C_PROGRESS_METER},
|
||||
{"proto", ARG_STRG, ' ', C_PROTO},
|
||||
{"proto-default", ARG_STRG, ' ', C_PROTO_DEFAULT},
|
||||
{"proto-redir", ARG_STRG, ' ', C_PROTO_REDIR},
|
||||
@ -573,7 +283,7 @@ static const struct LongShort aliases[]= {
|
||||
{"sasl-authzid", ARG_STRG, ' ', C_SASL_AUTHZID},
|
||||
{"sasl-ir", ARG_BOOL, ' ', C_SASL_IR},
|
||||
{"service-name", ARG_STRG, ' ', C_SERVICE_NAME},
|
||||
{"sessionid", ARG_BOOL, ' ', C_SESSIONID},
|
||||
{"sessionid", ARG_BOOL|ARG_NO, ' ', C_SESSIONID},
|
||||
{"show-error", ARG_BOOL, 'S', C_SHOW_ERROR},
|
||||
{"show-headers", ARG_BOOL, 'i', C_SHOW_HEADERS},
|
||||
{"silent", ARG_BOOL, 's', C_SILENT},
|
||||
@ -1029,7 +739,7 @@ static int findarg(const void *a, const void *b)
|
||||
return strcmp(aa->lname, bb->lname);
|
||||
}
|
||||
|
||||
static const struct LongShort *single(char letter)
|
||||
const struct LongShort *findshortopt(char letter)
|
||||
{
|
||||
static const struct LongShort *singles[128 - ' ']; /* ASCII => pointer */
|
||||
static bool singles_done = FALSE;
|
||||
@ -1295,6 +1005,15 @@ static ParameterError set_rate(struct GlobalConfig *global,
|
||||
return err;
|
||||
}
|
||||
|
||||
const struct LongShort *findlongopt(const char *opt)
|
||||
{
|
||||
struct LongShort key;
|
||||
key.lname = opt;
|
||||
|
||||
return bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]),
|
||||
sizeof(aliases[0]), findarg);
|
||||
}
|
||||
|
||||
|
||||
ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
char *nextarg, /* NULL if unset */
|
||||
@ -1336,7 +1055,6 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
const char *word = ('-' == flag[0]) ? flag + 2 : flag;
|
||||
bool noflagged = FALSE;
|
||||
bool expand = FALSE;
|
||||
struct LongShort key;
|
||||
|
||||
if(!strncmp(word, "no-", 3)) {
|
||||
/* disable this option but ignore the "no-" part when looking for it */
|
||||
@ -1349,10 +1067,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
word += 7;
|
||||
expand = TRUE;
|
||||
}
|
||||
key.lname = word;
|
||||
|
||||
a = bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]),
|
||||
sizeof(aliases[0]), findarg);
|
||||
a = findlongopt(word);
|
||||
if(a) {
|
||||
longopt = TRUE;
|
||||
}
|
||||
@ -1360,7 +1076,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
err = PARAM_OPTION_UNKNOWN;
|
||||
goto error;
|
||||
}
|
||||
if(noflagged && (a->desc != ARG_BOOL)) {
|
||||
if(noflagged && (ARGTYPE(a->desc) != ARG_BOOL)) {
|
||||
/* --no- prefixed an option that is not boolean! */
|
||||
err = PARAM_NO_NOT_BOOLEAN;
|
||||
goto error;
|
||||
@ -1369,8 +1085,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
struct curlx_dynbuf nbuf;
|
||||
bool replaced;
|
||||
|
||||
if((a->desc != ARG_STRG) &&
|
||||
(a->desc != ARG_FILE)) {
|
||||
if((ARGTYPE(a->desc) != ARG_STRG) &&
|
||||
(ARGTYPE(a->desc) != ARG_FILE)) {
|
||||
/* --expand on an option that is not a string or a filename */
|
||||
err = PARAM_EXPAND_ERROR;
|
||||
goto error;
|
||||
@ -1397,15 +1113,15 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
cmdline_t cmd;
|
||||
|
||||
if(!longopt && !a) {
|
||||
a = single(*parse);
|
||||
a = findshortopt(*parse);
|
||||
if(!a) {
|
||||
err = PARAM_OPTION_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
letter = a->letter;
|
||||
cmd = a->cmd;
|
||||
if(a->desc >= ARG_STRG) {
|
||||
cmd = (cmdline_t)a->cmd;
|
||||
if(ARGTYPE(a->desc) >= ARG_STRG) {
|
||||
/* this option requires an extra parameter */
|
||||
if(!longopt && parse[1]) {
|
||||
nextarg = (char *)&parse[1]; /* this is the actual extra parameter */
|
||||
@ -1422,7 +1138,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
*usedarg = TRUE; /* mark it as used */
|
||||
}
|
||||
|
||||
if((a->desc == ARG_FILE) &&
|
||||
if((ARGTYPE(a->desc) == ARG_FILE) &&
|
||||
(nextarg[0] == '-') && nextarg[1]) {
|
||||
/* if the filename looks like a command line option */
|
||||
warnf(global, "The filename argument '%s' looks like a flag.",
|
||||
@ -1434,7 +1150,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
nextarg);
|
||||
}
|
||||
}
|
||||
else if((a->desc == ARG_NONE) && !toggle) {
|
||||
else if((ARGTYPE(a->desc) == ARG_NONE) && !toggle) {
|
||||
err = PARAM_NO_PREFIX;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -25,6 +25,301 @@
|
||||
***************************************************************************/
|
||||
#include "tool_setup.h"
|
||||
|
||||
/* one enum for every command line option. The name is the verbatim long
|
||||
option name, but in uppercase with periods and minuses replaced with
|
||||
underscores using a "C_" prefix. */
|
||||
typedef enum {
|
||||
C_ABSTRACT_UNIX_SOCKET,
|
||||
C_ALPN,
|
||||
C_ALT_SVC,
|
||||
C_ANYAUTH,
|
||||
C_APPEND,
|
||||
C_AWS_SIGV4,
|
||||
C_BASIC,
|
||||
C_BUFFER,
|
||||
C_CA_NATIVE,
|
||||
C_CACERT,
|
||||
C_CAPATH,
|
||||
C_CERT,
|
||||
C_CERT_STATUS,
|
||||
C_CERT_TYPE,
|
||||
C_CIPHERS,
|
||||
C_CLOBBER,
|
||||
C_COMPRESSED,
|
||||
C_COMPRESSED_SSH,
|
||||
C_CONFIG,
|
||||
C_CONNECT_TIMEOUT,
|
||||
C_CONNECT_TO,
|
||||
C_CONTINUE_AT,
|
||||
C_COOKIE,
|
||||
C_COOKIE_JAR,
|
||||
C_CREATE_DIRS,
|
||||
C_CREATE_FILE_MODE,
|
||||
C_CRLF,
|
||||
C_CRLFILE,
|
||||
C_CURVES,
|
||||
C_DATA,
|
||||
C_DATA_ASCII,
|
||||
C_DATA_BINARY,
|
||||
C_DATA_RAW,
|
||||
C_DATA_URLENCODE,
|
||||
C_DELEGATION,
|
||||
C_DIGEST,
|
||||
C_DISABLE,
|
||||
C_DISABLE_EPRT,
|
||||
C_DISABLE_EPSV,
|
||||
C_DISALLOW_USERNAME_IN_URL,
|
||||
C_DNS_INTERFACE,
|
||||
C_DNS_IPV4_ADDR,
|
||||
C_DNS_IPV6_ADDR,
|
||||
C_DNS_SERVERS,
|
||||
C_DOH_CERT_STATUS,
|
||||
C_DOH_INSECURE,
|
||||
C_DOH_URL,
|
||||
C_DUMP_CA_EMBED,
|
||||
C_DUMP_HEADER,
|
||||
C_ECH,
|
||||
C_EGD_FILE,
|
||||
C_ENGINE,
|
||||
C_EPRT,
|
||||
C_EPSV,
|
||||
C_ETAG_COMPARE,
|
||||
C_ETAG_SAVE,
|
||||
C_EXPECT100_TIMEOUT,
|
||||
C_FAIL,
|
||||
C_FAIL_EARLY,
|
||||
C_FAIL_WITH_BODY,
|
||||
C_FALSE_START,
|
||||
C_FORM,
|
||||
C_FORM_ESCAPE,
|
||||
C_FORM_STRING,
|
||||
C_FTP_ACCOUNT,
|
||||
C_FTP_ALTERNATIVE_TO_USER,
|
||||
C_FTP_CREATE_DIRS,
|
||||
C_FTP_METHOD,
|
||||
C_FTP_PASV,
|
||||
C_FTP_PORT,
|
||||
C_FTP_PRET,
|
||||
C_FTP_SKIP_PASV_IP,
|
||||
C_FTP_SSL,
|
||||
C_FTP_SSL_CCC,
|
||||
C_FTP_SSL_CCC_MODE,
|
||||
C_FTP_SSL_CONTROL,
|
||||
C_FTP_SSL_REQD,
|
||||
C_GET,
|
||||
C_GLOBOFF,
|
||||
C_HAPPY_EYEBALLS_TIMEOUT_MS,
|
||||
C_HAPROXY_CLIENTIP,
|
||||
C_HAPROXY_PROTOCOL,
|
||||
C_HEAD,
|
||||
C_HEADER,
|
||||
C_HELP,
|
||||
C_HOSTPUBMD5,
|
||||
C_HOSTPUBSHA256,
|
||||
C_HSTS,
|
||||
C_HTTP0_9,
|
||||
C_HTTP1_0,
|
||||
C_HTTP1_1,
|
||||
C_HTTP2,
|
||||
C_HTTP2_PRIOR_KNOWLEDGE,
|
||||
C_HTTP3,
|
||||
C_HTTP3_ONLY,
|
||||
C_IGNORE_CONTENT_LENGTH,
|
||||
C_INCLUDE,
|
||||
C_INSECURE,
|
||||
C_INTERFACE,
|
||||
C_IPFS_GATEWAY,
|
||||
C_IPV4,
|
||||
C_IPV6,
|
||||
C_JSON,
|
||||
C_JUNK_SESSION_COOKIES,
|
||||
C_KEEPALIVE,
|
||||
C_KEEPALIVE_CNT,
|
||||
C_KEEPALIVE_TIME,
|
||||
C_KEY,
|
||||
C_KEY_TYPE,
|
||||
C_KRB,
|
||||
C_KRB4,
|
||||
C_LIBCURL,
|
||||
C_LIMIT_RATE,
|
||||
C_LIST_ONLY,
|
||||
C_LOCAL_PORT,
|
||||
C_LOCATION,
|
||||
C_LOCATION_TRUSTED,
|
||||
C_LOGIN_OPTIONS,
|
||||
C_MAIL_AUTH,
|
||||
C_MAIL_FROM,
|
||||
C_MAIL_RCPT,
|
||||
C_MAIL_RCPT_ALLOWFAILS,
|
||||
C_MANUAL,
|
||||
C_MAX_FILESIZE,
|
||||
C_MAX_REDIRS,
|
||||
C_MAX_TIME,
|
||||
C_METALINK,
|
||||
C_MPTCP,
|
||||
C_NEGOTIATE,
|
||||
C_NETRC,
|
||||
C_NETRC_FILE,
|
||||
C_NETRC_OPTIONAL,
|
||||
C_NEXT,
|
||||
C_NOPROXY,
|
||||
C_NPN,
|
||||
C_NTLM,
|
||||
C_NTLM_WB,
|
||||
C_OAUTH2_BEARER,
|
||||
C_OUTPUT,
|
||||
C_OUTPUT_DIR,
|
||||
C_PARALLEL,
|
||||
C_PARALLEL_IMMEDIATE,
|
||||
C_PARALLEL_MAX,
|
||||
C_PASS,
|
||||
C_PATH_AS_IS,
|
||||
C_PINNEDPUBKEY,
|
||||
C_POST301,
|
||||
C_POST302,
|
||||
C_POST303,
|
||||
C_PREPROXY,
|
||||
C_PROGRESS_BAR,
|
||||
C_PROGRESS_METER,
|
||||
C_PROTO,
|
||||
C_PROTO_DEFAULT,
|
||||
C_PROTO_REDIR,
|
||||
C_PROXY,
|
||||
C_PROXY_ANYAUTH,
|
||||
C_PROXY_BASIC,
|
||||
C_PROXY_CA_NATIVE,
|
||||
C_PROXY_CACERT,
|
||||
C_PROXY_CAPATH,
|
||||
C_PROXY_CERT,
|
||||
C_PROXY_CERT_TYPE,
|
||||
C_PROXY_CIPHERS,
|
||||
C_PROXY_CRLFILE,
|
||||
C_PROXY_DIGEST,
|
||||
C_PROXY_HEADER,
|
||||
C_PROXY_HTTP2,
|
||||
C_PROXY_INSECURE,
|
||||
C_PROXY_KEY,
|
||||
C_PROXY_KEY_TYPE,
|
||||
C_PROXY_NEGOTIATE,
|
||||
C_PROXY_NTLM,
|
||||
C_PROXY_PASS,
|
||||
C_PROXY_PINNEDPUBKEY,
|
||||
C_PROXY_SERVICE_NAME,
|
||||
C_PROXY_SSL_ALLOW_BEAST,
|
||||
C_PROXY_SSL_AUTO_CLIENT_CERT,
|
||||
C_PROXY_TLS13_CIPHERS,
|
||||
C_PROXY_TLSAUTHTYPE,
|
||||
C_PROXY_TLSPASSWORD,
|
||||
C_PROXY_TLSUSER,
|
||||
C_PROXY_TLSV1,
|
||||
C_PROXY_USER,
|
||||
C_PROXY1_0,
|
||||
C_PROXYTUNNEL,
|
||||
C_PUBKEY,
|
||||
C_QUOTE,
|
||||
C_RANDOM_FILE,
|
||||
C_RANGE,
|
||||
C_RATE,
|
||||
C_RAW,
|
||||
C_REFERER,
|
||||
C_REMOTE_HEADER_NAME,
|
||||
C_REMOTE_NAME,
|
||||
C_REMOTE_NAME_ALL,
|
||||
C_REMOTE_TIME,
|
||||
C_REMOVE_ON_ERROR,
|
||||
C_REQUEST,
|
||||
C_REQUEST_TARGET,
|
||||
C_RESOLVE,
|
||||
C_RETRY,
|
||||
C_RETRY_ALL_ERRORS,
|
||||
C_RETRY_CONNREFUSED,
|
||||
C_RETRY_DELAY,
|
||||
C_RETRY_MAX_TIME,
|
||||
C_SASL_AUTHZID,
|
||||
C_SASL_IR,
|
||||
C_SERVICE_NAME,
|
||||
C_SESSIONID,
|
||||
C_SHOW_ERROR,
|
||||
C_SHOW_HEADERS,
|
||||
C_SILENT,
|
||||
C_SOCKS4,
|
||||
C_SOCKS4A,
|
||||
C_SOCKS5,
|
||||
C_SOCKS5_BASIC,
|
||||
C_SOCKS5_GSSAPI,
|
||||
C_SOCKS5_GSSAPI_NEC,
|
||||
C_SOCKS5_GSSAPI_SERVICE,
|
||||
C_SOCKS5_HOSTNAME,
|
||||
C_SPEED_LIMIT,
|
||||
C_SPEED_TIME,
|
||||
C_SSL,
|
||||
C_SSL_ALLOW_BEAST,
|
||||
C_SSL_AUTO_CLIENT_CERT,
|
||||
C_SSL_NO_REVOKE,
|
||||
C_SSL_REQD,
|
||||
C_SSL_REVOKE_BEST_EFFORT,
|
||||
C_SSLV2,
|
||||
C_SSLV3,
|
||||
C_STDERR,
|
||||
C_STYLED_OUTPUT,
|
||||
C_SUPPRESS_CONNECT_HEADERS,
|
||||
C_TCP_FASTOPEN,
|
||||
C_TCP_NODELAY,
|
||||
C_TELNET_OPTION,
|
||||
C_TEST_EVENT,
|
||||
C_TFTP_BLKSIZE,
|
||||
C_TFTP_NO_OPTIONS,
|
||||
C_TIME_COND,
|
||||
C_TLS_MAX,
|
||||
C_TLS13_CIPHERS,
|
||||
C_TLSAUTHTYPE,
|
||||
C_TLSPASSWORD,
|
||||
C_TLSUSER,
|
||||
C_TLSV1,
|
||||
C_TLSV1_0,
|
||||
C_TLSV1_1,
|
||||
C_TLSV1_2,
|
||||
C_TLSV1_3,
|
||||
C_TR_ENCODING,
|
||||
C_TRACE,
|
||||
C_TRACE_ASCII,
|
||||
C_TRACE_CONFIG,
|
||||
C_TRACE_IDS,
|
||||
C_TRACE_TIME,
|
||||
C_IP_TOS,
|
||||
C_UNIX_SOCKET,
|
||||
C_UPLOAD_FILE,
|
||||
C_URL,
|
||||
C_URL_QUERY,
|
||||
C_USE_ASCII,
|
||||
C_USER,
|
||||
C_USER_AGENT,
|
||||
C_VARIABLE,
|
||||
C_VERBOSE,
|
||||
C_VERSION,
|
||||
C_VLAN_PRIORITY,
|
||||
C_WDEBUG,
|
||||
C_WRITE_OUT,
|
||||
C_XATTR
|
||||
} cmdline_t;
|
||||
|
||||
#define ARG_NONE 0 /* stand-alone but not a boolean */
|
||||
#define ARG_BOOL 1 /* accepts a --no-[name] prefix */
|
||||
#define ARG_STRG 2 /* requires an argument */
|
||||
#define ARG_FILE 3 /* requires an argument, usually a filename */
|
||||
|
||||
#define ARG_TYPEMASK 0x03
|
||||
#define ARGTYPE(x) ((x) & ARG_TYPEMASK)
|
||||
|
||||
#define ARG_NO 0x80 /* set if the option is documented as --no-* */
|
||||
|
||||
struct LongShort {
|
||||
const char *lname; /* long name option */
|
||||
unsigned char desc; /* type, see ARG_* */
|
||||
char letter; /* short name option or ' ' */
|
||||
unsigned short cmd;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PARAM_OK = 0,
|
||||
PARAM_OPTION_AMBIGUOUS,
|
||||
@ -57,6 +352,9 @@ typedef enum {
|
||||
struct GlobalConfig;
|
||||
struct OperationConfig;
|
||||
|
||||
const struct LongShort *findlongopt(const char *opt);
|
||||
const struct LongShort *findshortopt(char letter);
|
||||
|
||||
ParameterError getparameter(const char *flag, char *nextarg,
|
||||
argv_item_t cleararg,
|
||||
bool *usedarg,
|
||||
|
||||
116
src/tool_help.c
116
src/tool_help.c
@ -31,6 +31,8 @@
|
||||
#include "tool_util.h"
|
||||
#include "tool_version.h"
|
||||
#include "tool_cb_prg.h"
|
||||
#include "tool_hugehelp.h"
|
||||
#include "tool_getparam.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
@ -160,18 +162,84 @@ static void get_categories_list(unsigned int width)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_MANUAL
|
||||
|
||||
void inithelpscan(struct scan_ctx *ctx,
|
||||
const char *trigger,
|
||||
const char *arg,
|
||||
const char *endarg)
|
||||
{
|
||||
ctx->trigger = trigger;
|
||||
ctx->tlen = strlen(trigger);
|
||||
ctx->arg = arg;
|
||||
ctx->flen = strlen(arg);
|
||||
ctx->endarg = endarg;
|
||||
ctx->elen = strlen(endarg);
|
||||
DEBUGASSERT((ctx->elen < sizeof(ctx->rbuf)) ||
|
||||
(ctx->flen < sizeof(ctx->rbuf)));
|
||||
ctx->show = 0;
|
||||
ctx->olen = 0;
|
||||
memset(ctx->rbuf, 0, sizeof(ctx->rbuf));
|
||||
}
|
||||
|
||||
bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < len; i++) {
|
||||
if(!ctx->show) {
|
||||
/* wait for the trigger */
|
||||
memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->tlen - 1);
|
||||
ctx->rbuf[ctx->tlen - 1] = buf[i];
|
||||
if(!memcmp(ctx->rbuf, ctx->trigger, ctx->tlen))
|
||||
ctx->show++;
|
||||
continue;
|
||||
}
|
||||
/* past the trigger */
|
||||
if(ctx->show == 1) {
|
||||
memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->flen - 1);
|
||||
ctx->rbuf[ctx->flen - 1] = buf[i];
|
||||
if(!memcmp(ctx->rbuf, ctx->arg, ctx->flen)) {
|
||||
/* match, now output until endarg */
|
||||
fputs(&ctx->arg[1], stdout);
|
||||
ctx->show++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* show until the end */
|
||||
memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->elen - 1);
|
||||
ctx->rbuf[ctx->elen - 1] = buf[i];
|
||||
if(!memcmp(ctx->rbuf, ctx->endarg, ctx->elen))
|
||||
return FALSE;
|
||||
|
||||
if(buf[i] == '\n') {
|
||||
DEBUGASSERT(ctx->olen < sizeof(ctx->obuf));
|
||||
ctx->obuf[ctx->olen++] = 0;
|
||||
ctx->olen = 0;
|
||||
puts(ctx->obuf);
|
||||
}
|
||||
else
|
||||
ctx->obuf[ctx->olen++] = buf[i];
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void tool_help(char *category)
|
||||
{
|
||||
unsigned int cols = get_terminal_columns();
|
||||
puts("Usage: curl [options...] <url>");
|
||||
/* If no category was provided */
|
||||
if(!category) {
|
||||
const char *category_note = "\nThis is not the full help; this "
|
||||
"menu is split into categories.\nUse \"--help category\" to get "
|
||||
"an overview of all categories, which are:";
|
||||
const char *category_note2 = "For all options use the manual"
|
||||
" or \"--help all\".";
|
||||
const char *category_note2 =
|
||||
"Use \"--help all\" to list all options"
|
||||
#ifdef USE_MANUAL
|
||||
"\nUse \"--help [option]\" to view documentation for a given option"
|
||||
#endif
|
||||
;
|
||||
puts("Usage: curl [options...] <url>");
|
||||
print_category(CURLHELP_IMPORTANT, cols);
|
||||
puts(category_note);
|
||||
get_categories_list(cols);
|
||||
@ -184,6 +252,48 @@ void tool_help(char *category)
|
||||
/* Lets handle the string "category" differently to not print an errormsg */
|
||||
else if(curl_strequal(category, "category"))
|
||||
get_categories();
|
||||
else if(category[0] == '-') {
|
||||
#ifdef USE_MANUAL
|
||||
/* command line option help */
|
||||
const struct LongShort *a = NULL;
|
||||
if(category[1] == '-') {
|
||||
char *lookup = &category[2];
|
||||
bool noflagged = FALSE;
|
||||
if(!strncmp(lookup, "no-", 3)) {
|
||||
lookup += 3;
|
||||
noflagged = TRUE;
|
||||
}
|
||||
a = findlongopt(lookup);
|
||||
if(noflagged && (ARGTYPE(a->desc) != ARG_BOOL))
|
||||
/* a --no- prefix for a non-boolean is not specifying a proper
|
||||
option */
|
||||
a = NULL;
|
||||
}
|
||||
else if(!category[2])
|
||||
a = findshortopt(category[1]);
|
||||
if(!a) {
|
||||
fprintf(tool_stderr, "Incorrect option name to show help for,"
|
||||
" see curl -h\n");
|
||||
}
|
||||
else {
|
||||
char cmdbuf[80];
|
||||
if(a->letter != ' ')
|
||||
msnprintf(cmdbuf, sizeof(cmdbuf), "\n -%c, --", a->letter);
|
||||
else if(a->desc & ARG_NO)
|
||||
msnprintf(cmdbuf, sizeof(cmdbuf), "\n --no-%s", a->lname);
|
||||
else
|
||||
msnprintf(cmdbuf, sizeof(cmdbuf), "\n %s", category);
|
||||
if(a->cmd == C_XATTR)
|
||||
/* this is the last option, which then ends when FILES starts */
|
||||
showhelp("\nALL OPTIONS\n", cmdbuf, "\nFILES");
|
||||
else
|
||||
showhelp("\nALL OPTIONS\n", cmdbuf, "\n -");
|
||||
}
|
||||
#else
|
||||
fprintf(tool_stderr, "Cannot comply. "
|
||||
"This curl was built without built-in manual\n");
|
||||
#endif
|
||||
}
|
||||
/* Otherwise print category and handle the case if the cat was not found */
|
||||
else if(get_category_content(category, cols)) {
|
||||
puts("Unknown category provided, here is a list of all categories:\n");
|
||||
|
||||
@ -28,6 +28,24 @@
|
||||
void tool_help(char *category);
|
||||
void tool_list_engines(void);
|
||||
void tool_version_info(void);
|
||||
struct scan_ctx {
|
||||
const char *trigger;
|
||||
size_t tlen;
|
||||
const char *arg;
|
||||
size_t flen;
|
||||
const char *endarg;
|
||||
size_t elen;
|
||||
size_t olen;
|
||||
char rbuf[40];
|
||||
char obuf[80];
|
||||
unsigned char show; /* start as at 0.
|
||||
trigger match moves it to 1
|
||||
arg match moves it to 2
|
||||
endarg stops the search */
|
||||
};
|
||||
void inithelpscan(struct scan_ctx *ctx, const char *trigger,
|
||||
const char *arg, const char *endarg);
|
||||
bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx);
|
||||
|
||||
struct helptxt {
|
||||
const char *opt;
|
||||
|
||||
@ -27,5 +27,12 @@
|
||||
|
||||
void hugehelp(void)
|
||||
{
|
||||
puts("This is a silly replacement for the actual file.");
|
||||
puts("built-in manual was disabled at build-time");
|
||||
}
|
||||
|
||||
void showhelp(const char *arg, const char *endarg)
|
||||
{
|
||||
(void)arg;
|
||||
(void)endarg;
|
||||
hugehelp();
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
***************************************************************************/
|
||||
#include "tool_setup.h"
|
||||
|
||||
void showhelp(const char *trigger, const char *arg, const char *endarg);
|
||||
|
||||
#ifdef USE_MANUAL
|
||||
void hugehelp(void);
|
||||
#else
|
||||
|
||||
@ -266,7 +266,7 @@ const struct helptxt helptext[] = {
|
||||
{"-H, --header <header/@file>",
|
||||
"Pass custom header(s) to server",
|
||||
CURLHELP_HTTP | CURLHELP_IMAP | CURLHELP_SMTP},
|
||||
{"-h, --help <category>",
|
||||
{"-h, --help <subject>",
|
||||
"Get help for commands",
|
||||
CURLHELP_IMPORTANT | CURLHELP_CURL},
|
||||
{" --hostpubmd5 <md5>",
|
||||
|
||||
@ -50,6 +50,7 @@ TESTSCRIPTS = \
|
||||
test1486.pl \
|
||||
test1488.pl \
|
||||
test1544.pl \
|
||||
test1707.pl \
|
||||
test971.pl
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
||||
@ -221,7 +221,8 @@ test1670 test1671 \
|
||||
\
|
||||
test1680 test1681 test1682 test1683 \
|
||||
\
|
||||
test1700 test1701 test1702 test1703 test1704 test1705 test1706 \
|
||||
test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \
|
||||
test1708 test1709 test1710 \
|
||||
\
|
||||
test1800 test1801 \
|
||||
\
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<features>
|
||||
manual
|
||||
</features>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
@ -34,7 +37,7 @@ curl important --help
|
||||
Usage: curl [options...] <url>
|
||||
-d, --data <data> HTTP POST data
|
||||
-f, --fail Fail fast with no output on HTTP errors
|
||||
-h, --help <category> Get help for commands
|
||||
-h, --help <subject> Get help for commands
|
||||
-o, --output <file> Write to file instead of stdout
|
||||
-O, --remote-name Write output to file named as remote file
|
||||
-i, --show-headers Show response headers in output
|
||||
@ -50,7 +53,8 @@ Use "--help category" to get an overview of all categories, which are:
|
||||
auth, connection, curl, deprecated, dns, file, ftp, global, http, imap, ldap,
|
||||
output, pop3, post, proxy, scp, sftp, smtp, ssh, telnet, tftp, timeout, tls,
|
||||
upload, verbose.
|
||||
For all options use the manual or "--help all".
|
||||
Use "--help all" to list all options
|
||||
Use "--help [option]" to view documentation for a given option
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
||||
@ -31,7 +31,6 @@ curl invalid category --help
|
||||
0
|
||||
</errorcode>
|
||||
<stdout mode="text">
|
||||
Usage: curl [options...] <url>
|
||||
Unknown category provided, here is a list of all categories:
|
||||
|
||||
auth Authentication methods
|
||||
|
||||
@ -35,7 +35,6 @@ curl file category --help
|
||||
0
|
||||
</errorcode>
|
||||
<stdout mode="text">
|
||||
Usage: curl [options...] <url>
|
||||
file: FILE protocol
|
||||
--create-file-mode <mode> File mode for created files
|
||||
-I, --head Show document info only
|
||||
|
||||
@ -35,7 +35,6 @@ curl file category --help with lower/upper mix
|
||||
0
|
||||
</errorcode>
|
||||
<stdout mode="text">
|
||||
Usage: curl [options...] <url>
|
||||
file: FILE protocol
|
||||
--create-file-mode <mode> File mode for created files
|
||||
-I, --head Show document info only
|
||||
|
||||
27
tests/data/test1707
Normal file
27
tests/data/test1707
Normal file
@ -0,0 +1,27 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
curl
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<features>
|
||||
manual
|
||||
</features>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
|
||||
<name>
|
||||
Verify curl -h --insecure
|
||||
</name>
|
||||
|
||||
<command type="perl">
|
||||
%SRCDIR/test1707.pl %CURL --insecure %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt
|
||||
</command>
|
||||
</client>
|
||||
|
||||
</testcase>
|
||||
27
tests/data/test1708
Normal file
27
tests/data/test1708
Normal file
@ -0,0 +1,27 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
curl
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<features>
|
||||
manual
|
||||
</features>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
|
||||
<name>
|
||||
Verify curl -h -F
|
||||
</name>
|
||||
|
||||
<command type="perl">
|
||||
%SRCDIR/test1707.pl %CURL -F %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt
|
||||
</command>
|
||||
</client>
|
||||
|
||||
</testcase>
|
||||
32
tests/data/test1709
Normal file
32
tests/data/test1709
Normal file
@ -0,0 +1,32 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
curl
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<features>
|
||||
manual
|
||||
</features>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
|
||||
<name>
|
||||
Verify curl -h --badone
|
||||
</name>
|
||||
|
||||
<command>
|
||||
-h --badone
|
||||
</command>
|
||||
</client>
|
||||
|
||||
<verify>
|
||||
<stderr mode="text">
|
||||
Incorrect option name to show help for, see curl -h
|
||||
</stderr>
|
||||
</verify>
|
||||
</testcase>
|
||||
27
tests/data/test1710
Normal file
27
tests/data/test1710
Normal file
@ -0,0 +1,27 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
curl
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<features>
|
||||
manual
|
||||
</features>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
|
||||
<name>
|
||||
Verify curl -h --no-clobber
|
||||
</name>
|
||||
|
||||
<command type="perl">
|
||||
%SRCDIR/test1707.pl %CURL --no-clobber %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt
|
||||
</command>
|
||||
</client>
|
||||
|
||||
</testcase>
|
||||
121
tests/test1707.pl
Executable file
121
tests/test1707.pl
Executable file
@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env perl
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
# This script grew out of help from Przemyslaw Iskra and Balint Szilakszi
|
||||
# a late evening in the #curl IRC channel.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $curl = shift @ARGV;
|
||||
my $opt = shift @ARGV;
|
||||
my $output = shift @ARGV;
|
||||
my $txt = shift @ARGV;
|
||||
|
||||
my $longopt;
|
||||
my $shortopt;
|
||||
if($opt =~ /^--/) {
|
||||
$longopt = $opt;
|
||||
}
|
||||
else {
|
||||
$shortopt = $opt;
|
||||
}
|
||||
|
||||
# first run the help command
|
||||
system("$curl -h $opt > $output");
|
||||
my @curlout;
|
||||
open(O, "<$output");
|
||||
push @curlout, <O>;
|
||||
close(O);
|
||||
|
||||
# figure out the short+long option combo using -h all*/
|
||||
open(C, "$curl -h all|");
|
||||
if($shortopt) {
|
||||
while(<C>) {
|
||||
if(/^ +$opt, ([^ ]*)/) {
|
||||
$longopt = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(<C>) {
|
||||
my $f = $_;
|
||||
if(/ $opt /) {
|
||||
if($f =~ /^ *(-(.)), $longopt/) {
|
||||
$shortopt = $1;
|
||||
}
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(C);
|
||||
|
||||
my $fullopt;
|
||||
if($shortopt) {
|
||||
$fullopt = "$shortopt, $longopt";
|
||||
}
|
||||
else {
|
||||
$fullopt = $longopt;
|
||||
}
|
||||
|
||||
open(R, "<$txt");
|
||||
my $show = 0;
|
||||
my @txtout;
|
||||
while(<R>) {
|
||||
if(/^ $fullopt/) {
|
||||
$show = 1;
|
||||
}
|
||||
elsif(/^ -/ && $show) {
|
||||
last;
|
||||
}
|
||||
if($show) {
|
||||
push @txtout, $_;
|
||||
}
|
||||
}
|
||||
close(R);
|
||||
|
||||
my $error;
|
||||
if(scalar(@curlout) != scalar(@txtout)) {
|
||||
printf "curl -h $opt is %d lines, $txt says %d lines\n",
|
||||
scalar(@curlout), scalar(@txtout);
|
||||
$error++;
|
||||
}
|
||||
else {
|
||||
# same size, compare line by line
|
||||
for my $i (0 .. $#curlout) {
|
||||
# trim CRLF from the data
|
||||
$curlout[$i] =~ s/[\r\n]//g;
|
||||
$txtout[$i] =~ s/[\r\n]//g;
|
||||
if($curlout[$i] ne $txtout[$i]) {
|
||||
printf "Line %d\n", $i;
|
||||
printf "-h : %s\n", $curlout[$i];
|
||||
printf "file : %s\n", $txtout[$i];
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
}
|
||||
exit $error;
|
||||
Loading…
Reference in New Issue
Block a user