cli: changing nmcli output to better fit both computer and human needs

The output is basically tabular with fields (columns) presenting specific pieces of info.
Each line represents a single object. It's possible to switch to multiline output using
'--multiline' option. In that mode single object is presented on more lines - each field
on its line.
Terse mode now uses ':' as field separator. It also escapes all occurences of ':' and '\'
inside field values to ease parsing. The escaping behaviour can be controlled through
'--escape' option. By default, escaping is switched on in tabular mode. When using terse
mode ('--terse'), '--fields' option is mandatory for specifying required fields. That helps
for flexibility and backwards compatibility.
Not all output is converted yet.
This commit is contained in:
Jiří Klimeš
2010-03-18 15:39:15 +01:00
parent 15351042ba
commit 55949277bd
6 changed files with 727 additions and 283 deletions

View File

@@ -45,7 +45,7 @@
#include "devices.h"
#include "network-manager.h"
#define NMCLI_VERSION "0.1"
#define NMCLI_VERSION "0.2"
typedef struct {
@@ -64,10 +64,13 @@ usage (const char *prog_name)
fprintf (stderr,
_("Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n\n"
"OPTIONS\n"
" -t[erse] terse output\n"
" -p[retty] pretty output\n"
" -v[ersion] show program version\n"
" -h[elp] print this help\n\n"
" -t[erse] terse output\n"
" -p[retty] pretty output\n"
" -m[ultiline] multiline output\n"
" -f[ields] <field1,field2,...>|all|common specify fields to output\n"
" -e[scape] yes|no escape columns separators in values\n"
" -v[ersion] show program version\n"
" -h[elp] print this help\n\n"
"OBJECT\n"
" nm NetworkManager status\n"
" con NetworkManager connections\n"
@@ -132,9 +135,57 @@ parse_command_line (NmCli *nmc, int argc, char **argv)
if (opt[1] == '-')
opt++;
if (matches (opt, "-terse") == 0) {
nmc->print_output = NMC_PRINT_TERSE;
if (nmc->print_output == NMC_PRINT_TERSE) {
g_string_printf (nmc->return_text, _("Option '--terse' is specified the second time."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
else if (nmc->print_output == NMC_PRINT_PRETTY) {
g_string_printf (nmc->return_text, _("Option '--terse' is mutually exclusive with '--pretty'."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
else
nmc->print_output = NMC_PRINT_TERSE;
} else if (matches (opt, "-pretty") == 0) {
nmc->print_output = NMC_PRINT_PRETTY;
if (nmc->print_output == NMC_PRINT_PRETTY) {
g_string_printf (nmc->return_text, _("Option '--pretty' is specified the second time."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
else if (nmc->print_output == NMC_PRINT_TERSE) {
g_string_printf (nmc->return_text, _("Option '--pretty' is mutually exclusive with '--terse'."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
else
nmc->print_output = NMC_PRINT_PRETTY;
} else if (matches (opt, "-multiline") == 0) {
nmc->multiline_output = TRUE;
} else if (matches (opt, "-escape") == 0) {
next_arg (&argc, &argv);
if (argc <= 1) {
g_string_printf (nmc->return_text, _("Error: missing argument for '%s' option."), opt);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
if (!strcmp (argv[1], "yes"))
nmc->escape_values = TRUE;
else if (!strcmp (argv[1], "no"))
nmc->escape_values = FALSE;
else {
g_string_printf (nmc->return_text, _("Error: '%s' is not valid argument for '%s' option."), argv[1], opt);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
} else if (matches (opt, "-fields") == 0) {
next_arg (&argc, &argv);
if (argc <= 1) {
g_string_printf (nmc->return_text, _("Error: fields for '%s' options are missing."), opt);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
nmc->required_fields = g_strdup (argv[1]);
} else if (matches (opt, "-version") == 0) {
printf (_("nmcli tool, version %s\n"), NMCLI_VERSION);
return NMC_RESULT_SUCCESS;
@@ -150,6 +201,20 @@ parse_command_line (NmCli *nmc, int argc, char **argv)
argv++;
}
/* Some validity options checks */
if (nmc->print_output == NMC_PRINT_TERSE) {
if (!nmc->required_fields) {
g_string_printf (nmc->return_text, _("Option '--terse' requires specifying '--fields'."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
} else if ( !strcasecmp (nmc->required_fields, "all")
|| !strcasecmp (nmc->required_fields, "common")) {
g_string_printf (nmc->return_text, _("Option '--terse' requires specific '--fields' option, not 'all' or 'common'."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
}
if (argc > 1)
return do_cmd (nmc, argv[1], argc-1, argv+1);
@@ -217,6 +282,11 @@ nmc_init (NmCli *nmc)
nmc->should_wait = FALSE;
nmc->print_output = NMC_PRINT_NORMAL;
nmc->multiline_output = FALSE;
nmc->escape_values = TRUE;
nmc->required_fields = NULL;
nmc->allowed_fields = NULL;
memset (&nmc->print_fields, '\0', sizeof (NmcPrintFields));
}
static void
@@ -231,6 +301,10 @@ nmc_cleanup (NmCli *nmc)
g_slist_free (nmc->system_connections);
g_slist_free (nmc->user_connections);
g_free (nmc->required_fields);
if (nmc->print_fields.indices)
g_array_free (nmc->print_fields.indices, TRUE);
}
static gboolean