cmdline: for new tools avoid introduce new negative switches, and properly align --help texts

Negative switches are a bad un-normalized thing. We alerady have some,
but we should try harder to avoid intrdoucing new ones.

Hence, instead of adding two switches:

        --foobar
        --no-foobar

Let's instead use the syntax

        --foobar
        --foobar=yes
        --foobar=no

Where the first two are equivalent. The boolean argument is parsed
following the usual rules.

Change all new negative switches this way.

This patch also properly aligns the --help table, so that single char
switches always get a column separate of the long switches.
This commit is contained in:
Lennart Poettering 2014-08-20 00:15:05 +02:00
parent f9ffbca2fb
commit dad29dff19
4 changed files with 101 additions and 67 deletions

View file

@ -1202,7 +1202,7 @@ static void help(void) {
" services, which finished TIMESPAN earlier, than the\n" " services, which finished TIMESPAN earlier, than the\n"
" latest in the branch. The unit of TIMESPAN is seconds\n" " latest in the branch. The unit of TIMESPAN is seconds\n"
" unless specified with a different unit, i.e. 50ms\n" " unless specified with a different unit, i.e. 50ms\n"
" --no-man Do not check for existence of man pages\n\n" " --man[=BOOL] Do [not] check for existence of man pages\n\n"
"Commands:\n" "Commands:\n"
" time Print time spent in the kernel before reaching userspace\n" " time Print time spent in the kernel before reaching userspace\n"
" blame Print list of running units ordered by time to init\n" " blame Print list of running units ordered by time to init\n"
@ -1230,7 +1230,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DOT_TO_PATTERN, ARG_DOT_TO_PATTERN,
ARG_FUZZ, ARG_FUZZ,
ARG_NO_PAGER, ARG_NO_PAGER,
ARG_NO_MAN, ARG_MAN,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -1244,7 +1244,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN }, { "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN },
{ "fuzz", required_argument, NULL, ARG_FUZZ }, { "fuzz", required_argument, NULL, ARG_FUZZ },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-man", no_argument, NULL, ARG_NO_MAN }, { "man", optional_argument, NULL, ARG_MAN },
{ "host", required_argument, NULL, 'H' }, { "host", required_argument, NULL, 'H' },
{ "machine", required_argument, NULL, 'M' }, { "machine", required_argument, NULL, 'M' },
{} {}
@ -1315,8 +1315,18 @@ static int parse_argv(int argc, char *argv[]) {
arg_host = optarg; arg_host = optarg;
break; break;
case ARG_NO_MAN: case ARG_MAN:
arg_man = false; if (optarg) {
r = parse_boolean(optarg);
if (r < 0) {
log_error("Failed to parse --man= argument.");
return -EINVAL;
}
arg_man = !!r;
} else
arg_man = true;
break; break;
case '?': case '?':

View file

@ -1134,25 +1134,24 @@ static int parse_config(void) {
static void help(void) { static void help(void) {
printf("%s [OPTIONS...] {FILE|-}...\n\n" printf("%s [OPTIONS...] {FILE|-}...\n\n"
"Write external journal events to journal file(s).\n\n" "Write external journal events to journal file(s).\n\n"
"Options:\n" " -h --help Show this help\n"
" --url=URL Read events from systemd-journal-gatewayd at URL\n" " --version Show package version\n"
" --getter=COMMAND Read events from the output of COMMAND\n" " --url=URL Read events from systemd-journal-gatewayd at URL\n"
" --listen-raw=ADDR Listen for connections at ADDR\n" " --getter=COMMAND Read events from the output of COMMAND\n"
" --listen-http=ADDR Listen for HTTP connections at ADDR\n" " --listen-raw=ADDR Listen for connections at ADDR\n"
" --listen-https=ADDR Listen for HTTPS connections at ADDR\n" " --listen-http=ADDR Listen for HTTP connections at ADDR\n"
" --listen-https=ADDR Listen for HTTPS connections at ADDR\n"
" -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n" " -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n"
" --[no-]compress Use XZ-compression in the output journal (default: yes)\n" " --compress[=BOOL] Use XZ-compression in the output journal (default: yes)\n"
" --[no-]seal Use Event sealing in the output journal (default: no)\n" " --seal[=BOOL] Use Event sealing in the output journal (default: no)\n"
" --key=FILENAME Specify key in PEM format (default:\n" " --key=FILENAME Specify key in PEM format (default:\n"
" \"" PRIV_KEY_FILE "\")\n" " \"" PRIV_KEY_FILE "\")\n"
" --cert=FILENAME Specify certificate in PEM format (default:\n" " --cert=FILENAME Specify certificate in PEM format (default:\n"
" \"" CERT_FILE "\")\n" " \"" CERT_FILE "\")\n"
" --trust=FILENAME|all Specify CA certificate or disable checking (default:\n" " --trust=FILENAME|all Specify CA certificate or disable checking (default:\n"
" \"" TRUST_FILE "\")\n" " \"" TRUST_FILE "\")\n"
" --gnutls-log=CATEGORY...\n" " --gnutls-log=CATEGORY...\n"
" Specify a list of gnutls logging categories\n" " Specify a list of gnutls logging categories\n"
" -h --help Show this help and exit\n"
" --version Print version string and exit\n"
"\n" "\n"
"Note: file descriptors from sd_listen_fds() will be consumed, too.\n" "Note: file descriptors from sd_listen_fds() will be consumed, too.\n"
, program_invocation_short_name); , program_invocation_short_name);
@ -1168,9 +1167,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_GETTER, ARG_GETTER,
ARG_SPLIT_MODE, ARG_SPLIT_MODE,
ARG_COMPRESS, ARG_COMPRESS,
ARG_NO_COMPRESS,
ARG_SEAL, ARG_SEAL,
ARG_NO_SEAL,
ARG_KEY, ARG_KEY,
ARG_CERT, ARG_CERT,
ARG_TRUST, ARG_TRUST,
@ -1187,10 +1184,8 @@ static int parse_argv(int argc, char *argv[]) {
{ "listen-https", required_argument, NULL, ARG_LISTEN_HTTPS }, { "listen-https", required_argument, NULL, ARG_LISTEN_HTTPS },
{ "output", required_argument, NULL, 'o' }, { "output", required_argument, NULL, 'o' },
{ "split-mode", required_argument, NULL, ARG_SPLIT_MODE }, { "split-mode", required_argument, NULL, ARG_SPLIT_MODE },
{ "compress", no_argument, NULL, ARG_COMPRESS }, { "compress", optional_argument, NULL, ARG_COMPRESS },
{ "no-compress", no_argument, NULL, ARG_NO_COMPRESS }, { "seal", optional_argument, NULL, ARG_SEAL },
{ "seal", no_argument, NULL, ARG_SEAL },
{ "no-seal", no_argument, NULL, ARG_NO_SEAL },
{ "key", required_argument, NULL, ARG_KEY }, { "key", required_argument, NULL, ARG_KEY },
{ "cert", required_argument, NULL, ARG_CERT }, { "cert", required_argument, NULL, ARG_CERT },
{ "trust", required_argument, NULL, ARG_TRUST }, { "trust", required_argument, NULL, ARG_TRUST },
@ -1332,16 +1327,31 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_COMPRESS: case ARG_COMPRESS:
arg_compress = true; if (optarg) {
break; r = parse_boolean(optarg);
case ARG_NO_COMPRESS: if (r < 0) {
arg_compress = false; log_error("Failed to parse --compress= parameter.");
return -EINVAL;
}
arg_compress = !!r;
} else
arg_compress = true;
break; break;
case ARG_SEAL: case ARG_SEAL:
arg_seal = true; if (optarg) {
break; r = parse_boolean(optarg);
case ARG_NO_SEAL: if (r < 0) {
arg_seal = false; log_error("Failed to parse --seal= parameter.");
return -EINVAL;
}
arg_seal = !!r;
} else
arg_seal = true;
break; break;
case ARG_GNUTLS_LOG: { case ARG_GNUTLS_LOG: {

View file

@ -505,24 +505,25 @@ static int parse_config(void) {
static void help(void) { static void help(void) {
printf("%s -u URL {FILE|-}...\n\n" printf("%s -u URL {FILE|-}...\n\n"
"Upload journal events to a remote server.\n\n" "Upload journal events to a remote server.\n\n"
"Options:\n" " -h --help Show this help\n"
" -u --url=URL Upload to this address\n" " --version Show package version\n"
" --key=FILENAME Specify key in PEM format\n" " -u --url=URL Upload to this address\n"
" --cert=FILENAME Specify certificate in PEM format\n" " --key=FILENAME Specify key in PEM format\n"
" --trust=FILENAME Specify CA certificate in PEM format\n" " --cert=FILENAME Specify certificate in PEM format\n"
" --system Use the system journal\n" " --trust=FILENAME Specify CA certificate in PEM format\n"
" --user Use the user journal for the current user\n" " --system Use the system journal\n"
" -m --merge Use all available journals\n" " --user Use the user journal for the current user\n"
" -M --machine=CONTAINER Operate on local container\n" " -m --merge Use all available journals\n"
" -D --directory=PATH Use journal files from directory\n" " -M --machine=CONTAINER Operate on local container\n"
" --file=PATH Use this journal file\n" " -D --directory=PATH Use journal files from directory\n"
" --cursor=CURSOR Start at the specified cursor\n" " --file=PATH Use this journal file\n"
" --after-cursor=CURSOR Start after the specified cursor\n" " --cursor=CURSOR Start at the specified cursor\n"
" --[no-]follow Do [not] wait for input\n" " --after-cursor=CURSOR Start after the specified cursor\n"
" --save-state[=FILE] Save uploaded cursors (default \n" " --follow[=BOOL] Do [not] wait for input\n"
" " STATE_FILE ")\n" " --save-state[=FILE] Save uploaded cursors (default \n"
" -h --help Show this help and exit\n" " " STATE_FILE ")\n"
" --version Print version string and exit\n" " -h --help Show this help and exit\n"
" --version Print version string and exit\n"
, program_invocation_short_name); , program_invocation_short_name);
} }
@ -538,7 +539,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_CURSOR, ARG_CURSOR,
ARG_AFTER_CURSOR, ARG_AFTER_CURSOR,
ARG_FOLLOW, ARG_FOLLOW,
ARG_NO_FOLLOW,
ARG_SAVE_STATE, ARG_SAVE_STATE,
}; };
@ -557,8 +557,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "file", required_argument, NULL, ARG_FILE }, { "file", required_argument, NULL, ARG_FILE },
{ "cursor", required_argument, NULL, ARG_CURSOR }, { "cursor", required_argument, NULL, ARG_CURSOR },
{ "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR }, { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
{ "follow", no_argument, NULL, ARG_FOLLOW }, { "follow", optional_argument, NULL, ARG_FOLLOW },
{ "no-follow", no_argument, NULL, ARG_NO_FOLLOW },
{ "save-state", optional_argument, NULL, ARG_SAVE_STATE }, { "save-state", optional_argument, NULL, ARG_SAVE_STATE },
{} {}
}; };
@ -675,11 +674,17 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_FOLLOW: case ARG_FOLLOW:
arg_follow = true; if (optarg) {
break; r = parse_boolean(optarg);
if (r < 0) {
log_error("Failed to parse --follow= parameter.");
return -EINVAL;
}
arg_follow = !!r;
} else
arg_follow = true;
case ARG_NO_FOLLOW:
arg_follow = false;
break; break;
case ARG_SAVE_STATE: case ARG_SAVE_STATE:

View file

@ -466,14 +466,14 @@ static void help(void) {
" -p --protocol=PROTOCOL Look via protocol\n" " -p --protocol=PROTOCOL Look via protocol\n"
" -t --type=TYPE Query RR with DNS type\n" " -t --type=TYPE Query RR with DNS type\n"
" -c --class=CLASS Query RR with DNS class\n" " -c --class=CLASS Query RR with DNS class\n"
" --no-legend Do not print column headers\n" " --legend[=BOOL] Do [not] print column headers\n"
, program_invocation_short_name); , program_invocation_short_name);
} }
static int parse_argv(int argc, char *argv[]) { static int parse_argv(int argc, char *argv[]) {
enum { enum {
ARG_VERSION = 0x100, ARG_VERSION = 0x100,
ARG_NO_LEGEND, ARG_LEGEND,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -481,7 +481,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION }, { "version", no_argument, NULL, ARG_VERSION },
{ "type", required_argument, NULL, 't' }, { "type", required_argument, NULL, 't' },
{ "class", required_argument, NULL, 'c' }, { "class", required_argument, NULL, 'c' },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND }, { "legend", optional_argument, NULL, ARG_LEGEND },
{ "protocol", required_argument, NULL, 'p' }, { "protocol", required_argument, NULL, 'p' },
{} {}
}; };
@ -548,8 +548,17 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_NO_LEGEND: case ARG_LEGEND:
arg_legend = false; if (optarg) {
r = parse_boolean(optarg);
if (r < 0) {
log_error("Failed to parse --legend= argument");
return r;
}
arg_legend = !!r;
} else
arg_legend = false;
break; break;
case 'p': case 'p':