about summary refs log tree commit diff
path: root/clients/cli/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/cli/utils.c')
-rw-r--r--clients/cli/utils.c2869
1 files changed, 1436 insertions, 1433 deletions
diff --git a/clients/cli/utils.c b/clients/cli/utils.c
index 5e54fdb1..2e7b22ce 100644
--- a/clients/cli/utils.c
+++ b/clients/cli/utils.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2010 Lennart Poettering
  * Copyright (C) 2010 - 2018 Red Hat, Inc.
@@ -29,113 +29,110 @@
 /*****************************************************************************/
 
 static const char *
-_meta_type_nmc_generic_info_get_name (const NMMetaAbstractInfo *abstract_info, gboolean for_header)
+_meta_type_nmc_generic_info_get_name(const NMMetaAbstractInfo *abstract_info, gboolean for_header)
 {
-	const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info;
+    const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info;
 
-	if (for_header)
-		return info->name_header ?: info->name;
-	return info->name;
+    if (for_header)
+        return info->name_header ?: info->name;
+    return info->name;
 }
 
-static const NMMetaAbstractInfo *const*
-_meta_type_nmc_generic_info_get_nested (const NMMetaAbstractInfo *abstract_info,
-                                        guint *out_len,
-                                        gpointer *out_to_free)
+static const NMMetaAbstractInfo *const *
+_meta_type_nmc_generic_info_get_nested(const NMMetaAbstractInfo *abstract_info,
+                                       guint *                   out_len,
+                                       gpointer *                out_to_free)
 {
-	const NmcMetaGenericInfo *info;
+    const NmcMetaGenericInfo *info;
 
-	info = (const NmcMetaGenericInfo *) abstract_info;
+    info = (const NmcMetaGenericInfo *) abstract_info;
 
-	NM_SET_OUT (out_len, NM_PTRARRAY_LEN (info->nested));
-	return (const NMMetaAbstractInfo *const*) info->nested;
+    NM_SET_OUT(out_len, NM_PTRARRAY_LEN(info->nested));
+    return (const NMMetaAbstractInfo *const *) info->nested;
 }
 
 static gconstpointer
-_meta_type_nmc_generic_info_get_fcn (const NMMetaAbstractInfo *abstract_info,
-                                     const NMMetaEnvironment *environment,
-                                     gpointer environment_user_data,
-                                     gpointer target,
-                                     gpointer target_data,
-                                     NMMetaAccessorGetType get_type,
-                                     NMMetaAccessorGetFlags get_flags,
-                                     NMMetaAccessorGetOutFlags *out_flags,
-                                     gboolean *out_is_default,
-                                     gpointer *out_to_free)
+_meta_type_nmc_generic_info_get_fcn(const NMMetaAbstractInfo * abstract_info,
+                                    const NMMetaEnvironment *  environment,
+                                    gpointer                   environment_user_data,
+                                    gpointer                   target,
+                                    gpointer                   target_data,
+                                    NMMetaAccessorGetType      get_type,
+                                    NMMetaAccessorGetFlags     get_flags,
+                                    NMMetaAccessorGetOutFlags *out_flags,
+                                    gboolean *                 out_is_default,
+                                    gpointer *                 out_to_free)
 {
-	const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info;
-
-	nm_assert (!out_to_free || !*out_to_free);
-	nm_assert (out_flags && !*out_flags);
-
-	if (!NM_IN_SET (get_type,
-	                NM_META_ACCESSOR_GET_TYPE_PARSABLE,
-	                NM_META_ACCESSOR_GET_TYPE_PRETTY,
-	                NM_META_ACCESSOR_GET_TYPE_COLOR))
-		g_return_val_if_reached (NULL);
-
-	/* omitting the out_to_free value is only allowed for COLOR. */
-	nm_assert (out_to_free || NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_COLOR));
-
-	if (info->get_fcn) {
-		return info->get_fcn (environment,
-		                      environment_user_data,
-		                      info,
-		                      target,
-		                      target_data,
-		                      get_type,
-		                      get_flags,
-		                      out_flags,
-		                      out_is_default,
-		                      out_to_free);
-	}
-
-	if (info->nested) {
-		NMC_HANDLE_COLOR (NM_META_COLOR_NONE);
-		return info->name;
-	}
-
-	g_return_val_if_reached (NULL);
+    const NmcMetaGenericInfo *info = (const NmcMetaGenericInfo *) abstract_info;
+
+    nm_assert(!out_to_free || !*out_to_free);
+    nm_assert(out_flags && !*out_flags);
+
+    if (!NM_IN_SET(get_type,
+                   NM_META_ACCESSOR_GET_TYPE_PARSABLE,
+                   NM_META_ACCESSOR_GET_TYPE_PRETTY,
+                   NM_META_ACCESSOR_GET_TYPE_COLOR))
+        g_return_val_if_reached(NULL);
+
+    /* omitting the out_to_free value is only allowed for COLOR. */
+    nm_assert(out_to_free || NM_IN_SET(get_type, NM_META_ACCESSOR_GET_TYPE_COLOR));
+
+    if (info->get_fcn) {
+        return info->get_fcn(environment,
+                             environment_user_data,
+                             info,
+                             target,
+                             target_data,
+                             get_type,
+                             get_flags,
+                             out_flags,
+                             out_is_default,
+                             out_to_free);
+    }
+
+    if (info->nested) {
+        NMC_HANDLE_COLOR(NM_META_COLOR_NONE);
+        return info->name;
+    }
+
+    g_return_val_if_reached(NULL);
 }
 
 const NMMetaType nmc_meta_type_generic_info = {
-	.type_name =         "nmc-generic-info",
-	.get_name =          _meta_type_nmc_generic_info_get_name,
-	.get_nested =        _meta_type_nmc_generic_info_get_nested,
-	.get_fcn =           _meta_type_nmc_generic_info_get_fcn,
+    .type_name  = "nmc-generic-info",
+    .get_name   = _meta_type_nmc_generic_info_get_name,
+    .get_nested = _meta_type_nmc_generic_info_get_nested,
+    .get_fcn    = _meta_type_nmc_generic_info_get_fcn,
 };
 
 /*****************************************************************************/
 
 static const char *
-colorize_string (const NmcConfig *nmc_config,
-                 NMMetaColor color,
-                 const char *str,
-                 char **out_to_free)
+colorize_string(const NmcConfig *nmc_config, NMMetaColor color, const char *str, char **out_to_free)
 {
-	const char *out = str;
+    const char *out = str;
 
-	if (nmc_config && nmc_config->use_colors) {
-		*out_to_free = nmc_colorize (nmc_config, color, "%s", str);
-		out = *out_to_free;
-	}
+    if (nmc_config && nmc_config->use_colors) {
+        *out_to_free = nmc_colorize(nmc_config, color, "%s", str);
+        out          = *out_to_free;
+    }
 
-	return out;
+    return out;
 }
 
 /*****************************************************************************/
 
 static gboolean
-parse_global_arg (NmCli *nmc, const char *arg)
+parse_global_arg(NmCli *nmc, const char *arg)
 {
-	if (nmc_arg_is_option (arg, "ask"))
-		nmc->ask = TRUE;
-	else if (nmc_arg_is_option (arg, "show-secrets"))
-		nmc->nmc_config_mutable.show_secrets = TRUE;
-	else
-		return FALSE;
-
-	return TRUE;
+    if (nmc_arg_is_option(arg, "ask"))
+        nmc->ask = TRUE;
+    else if (nmc_arg_is_option(arg, "show-secrets"))
+        nmc->nmc_config_mutable.show_secrets = TRUE;
+    else
+        return FALSE;
+
+    return TRUE;
 }
 /**
  * next_arg:
@@ -154,88 +151,87 @@ parse_global_arg (NmCli *nmc, const char *arg)
  * -1 otherwise (no more args).
  */
 int
-next_arg (NmCli *nmc, int *argc, const char *const**argv, ...)
+next_arg(NmCli *nmc, int *argc, const char *const **argv, ...)
 {
-	va_list args;
-	const char *cmd_option;
-
-	g_assert (*argc >= 0);
-
-	do {
-		int cmd_option_pos = 1;
-
-		if (*argc > 0) {
-			(*argc)--;
-			(*argv)++;
-		}
-		if (*argc == 0)
-			return -1;
-
-		va_start (args, argv);
-
-		if (nmc && nmc->complete && *argc == 1) {
-			while ((cmd_option = va_arg (args, const char *)))
-				nmc_complete_strings (**argv, cmd_option);
-
-			if (***argv == '-')
-				nmc_complete_strings (**argv, "--ask", "--show-secrets");
-
-			va_end (args);
-			return 0;
-		}
-
-		/* Check command dependent options first */
-		while ((cmd_option = va_arg (args, const char *))) {
-			if (cmd_option[0] == '-' && cmd_option[1] == '-') {
-				/* Match as an option (leading "--" stripped) */
-				if (nmc_arg_is_option (**argv, cmd_option + 2)) {
-					va_end (args);
-					return cmd_option_pos;
-				}
-			} else {
-				/* Match literally. */
-				if (strcmp (**argv, cmd_option) == 0) {
-					va_end (args);
-					return cmd_option_pos;
-				}
-			}
-			cmd_option_pos++;
-		}
-
-		va_end (args);
-
-	} while (nmc && parse_global_arg (nmc, **argv));
-
-	return 0;
+    va_list     args;
+    const char *cmd_option;
+
+    g_assert(*argc >= 0);
+
+    do {
+        int cmd_option_pos = 1;
+
+        if (*argc > 0) {
+            (*argc)--;
+            (*argv)++;
+        }
+        if (*argc == 0)
+            return -1;
+
+        va_start(args, argv);
+
+        if (nmc && nmc->complete && *argc == 1) {
+            while ((cmd_option = va_arg(args, const char *)))
+                nmc_complete_strings(**argv, cmd_option);
+
+            if (***argv == '-')
+                nmc_complete_strings(**argv, "--ask", "--show-secrets");
+
+            va_end(args);
+            return 0;
+        }
+
+        /* Check command dependent options first */
+        while ((cmd_option = va_arg(args, const char *))) {
+            if (cmd_option[0] == '-' && cmd_option[1] == '-') {
+                /* Match as an option (leading "--" stripped) */
+                if (nmc_arg_is_option(**argv, cmd_option + 2)) {
+                    va_end(args);
+                    return cmd_option_pos;
+                }
+            } else {
+                /* Match literally. */
+                if (strcmp(**argv, cmd_option) == 0) {
+                    va_end(args);
+                    return cmd_option_pos;
+                }
+            }
+            cmd_option_pos++;
+        }
+
+        va_end(args);
+
+    } while (nmc && parse_global_arg(nmc, **argv));
+
+    return 0;
 }
 
 gboolean
-nmc_arg_is_help (const char *arg)
+nmc_arg_is_help(const char *arg)
 {
-	if (!arg)
-		return FALSE;
-	if (   matches (arg, "help")
-	    || (g_str_has_prefix (arg, "-")  && matches (arg + 1, "help"))
-	    || (g_str_has_prefix (arg, "--") && matches (arg + 2, "help"))) {
-		return TRUE;
-	}
-	return FALSE;
+    if (!arg)
+        return FALSE;
+    if (matches(arg, "help") || (g_str_has_prefix(arg, "-") && matches(arg + 1, "help"))
+        || (g_str_has_prefix(arg, "--") && matches(arg + 2, "help"))) {
+        return TRUE;
+    }
+    return FALSE;
 }
 
 gboolean
-nmc_arg_is_option (const char *str, const char *opt_name)
+nmc_arg_is_option(const char *str, const char *opt_name)
 {
-	const char *p;
+    const char *p;
 
-	if (!str || !*str)
-		return FALSE;
+    if (!str || !*str)
+        return FALSE;
 
-	if (str[0] != '-')
-		return FALSE;
+    if (str[0] != '-')
+        return FALSE;
 
-	p = (str[1] == '-') ? str + 2 : str + 1;
+    p = (str[1] == '-') ? str + 2 : str + 1;
 
-	return (*p ? matches (p, opt_name) : FALSE);
+    return (*p ? matches(p, opt_name) : FALSE);
 }
 
 /*
@@ -248,70 +244,83 @@ nmc_arg_is_option (const char *str, const char *opt_name)
  * Returns: TRUE on success, FALSE on an error and sets 'error'
  */
 gboolean
-nmc_parse_args (nmc_arg_t *arg_arr, gboolean last, int *argc, const char *const**argv, GError **error)
+nmc_parse_args(nmc_arg_t *         arg_arr,
+               gboolean            last,
+               int *               argc,
+               const char *const **argv,
+               GError **           error)
 {
-	nmc_arg_t *p;
-	gboolean found;
-	gboolean have_mandatory;
-
-	g_return_val_if_fail (arg_arr != NULL, FALSE);
-	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
-	while (*argc > 0) {
-		found = FALSE;
-
-		for (p = arg_arr; p->name; p++) {
-			if (strcmp (**argv, p->name) == 0) {
-
-				if (p->found) {
-					/* Don't allow repeated arguments, because the argument of the same
-					 * name could be used later on the line for another purpose. Assume
-					 * that's the case and return.
-					 */
-					return TRUE;
-				}
-
-				if (p->has_value) {
-					(*argc)--;
-					(*argv)++;
-					if (!*argc) {
-						g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
-						             _("Error: value for '%s' argument is required."), *(*argv-1));
-						return FALSE;
-					}
-					*(p->value) = **argv;
-				}
-				p->found = TRUE;
-				found = TRUE;
-				break;
-			}
-		}
-
-		if (!found) {
-			have_mandatory = TRUE;
-			for (p = arg_arr; p->name; p++) {
-				if (p->mandatory && !p->found) {
-					have_mandatory = FALSE;
-					break;
-				}
-			}
-
-			if (have_mandatory && !last)
-				return TRUE;
-
-			if (p->name)
-				g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
-				             _("Error: Argument '%s' was expected, but '%s' provided."), p->name, **argv);
-			else
-				g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
-				             _("Error: Unexpected argument '%s'"), **argv);
-			return FALSE;
-		}
-
-		next_arg (NULL, argc, argv, NULL);
-	}
-
-	return TRUE;
+    nmc_arg_t *p;
+    gboolean   found;
+    gboolean   have_mandatory;
+
+    g_return_val_if_fail(arg_arr != NULL, FALSE);
+    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+    while (*argc > 0) {
+        found = FALSE;
+
+        for (p = arg_arr; p->name; p++) {
+            if (strcmp(**argv, p->name) == 0) {
+                if (p->found) {
+                    /* Don't allow repeated arguments, because the argument of the same
+                     * name could be used later on the line for another purpose. Assume
+                     * that's the case and return.
+                     */
+                    return TRUE;
+                }
+
+                if (p->has_value) {
+                    (*argc)--;
+                    (*argv)++;
+                    if (!*argc) {
+                        g_set_error(error,
+                                    NMCLI_ERROR,
+                                    NMC_RESULT_ERROR_USER_INPUT,
+                                    _("Error: value for '%s' argument is required."),
+                                    *(*argv - 1));
+                        return FALSE;
+                    }
+                    *(p->value) = **argv;
+                }
+                p->found = TRUE;
+                found    = TRUE;
+                break;
+            }
+        }
+
+        if (!found) {
+            have_mandatory = TRUE;
+            for (p = arg_arr; p->name; p++) {
+                if (p->mandatory && !p->found) {
+                    have_mandatory = FALSE;
+                    break;
+                }
+            }
+
+            if (have_mandatory && !last)
+                return TRUE;
+
+            if (p->name)
+                g_set_error(error,
+                            NMCLI_ERROR,
+                            NMC_RESULT_ERROR_USER_INPUT,
+                            _("Error: Argument '%s' was expected, but '%s' provided."),
+                            p->name,
+                            **argv);
+            else
+                g_set_error(error,
+                            NMCLI_ERROR,
+                            NMC_RESULT_ERROR_USER_INPUT,
+                            _("Error: Unexpected argument '%s'"),
+                            **argv);
+            return FALSE;
+        }
+
+        next_arg(NULL, argc, argv, NULL);
+    }
+
+    return TRUE;
 }
 
 /*
@@ -319,16 +328,12 @@ nmc_parse_args (nmc_arg_t *arg_arr, gboolean last, int *argc, const char *const*
  *  Caller has to free the returned string using g_free()
  */
 char *
-ssid_to_hex (const char *str, gsize len)
+ssid_to_hex(const char *str, gsize len)
 {
-	if (len == 0)
-		return NULL;
-
-	return nm_utils_bin2hexstr_full (str,
-	                                 len,
-	                                 '\0',
-	                                 TRUE,
-	                                 NULL);
+    if (len == 0)
+        return NULL;
+
+    return nm_utils_bin2hexstr_full(str, len, '\0', TRUE, NULL);
 }
 
 /*
@@ -339,13 +344,13 @@ ssid_to_hex (const char *str, gsize len)
  * http://www.termsys.demon.co.uk/vtansi.htm
  */
 void
-nmc_terminal_erase_line (void)
+nmc_terminal_erase_line(void)
 {
-	/* We intentionally use printf(), not g_print() here, to ensure that
-	 * GLib doesn't mistakenly try to convert the string.
-	 */
-	printf ("\33[2K\r");
-	fflush (stdout);
+    /* We intentionally use printf(), not g_print() here, to ensure that
+     * GLib doesn't mistakenly try to convert the string.
+     */
+    printf("\33[2K\r");
+    fflush(stdout);
 }
 
 /*
@@ -354,38 +359,38 @@ nmc_terminal_erase_line (void)
  * by the string passed in 'str' argument.
  */
 void
-nmc_terminal_show_progress (const char *str)
+nmc_terminal_show_progress(const char *str)
 {
-	static int idx = 0;
-	const char slashes[4] = {'|', '/', '-', '\\'};
-
-	nmc_terminal_erase_line ();
-	g_print ("%c %s", slashes[idx++], str ?: "");
-	fflush (stdout);
-	if (idx == 4)
-		idx = 0;
+    static int idx        = 0;
+    const char slashes[4] = {'|', '/', '-', '\\'};
+
+    nmc_terminal_erase_line();
+    g_print("%c %s", slashes[idx++], str ?: "");
+    fflush(stdout);
+    if (idx == 4)
+        idx = 0;
 }
 
 char *
-nmc_colorize (const NmcConfig *nmc_config, NMMetaColor color, const char *fmt, ...)
+nmc_colorize(const NmcConfig *nmc_config, NMMetaColor color, const char *fmt, ...)
 {
-	va_list args;
-	char *str, *colored;
-	const char *ansi_seq = NULL;
+    va_list     args;
+    char *      str, *colored;
+    const char *ansi_seq = NULL;
 
-	va_start (args, fmt);
-	str = g_strdup_vprintf (fmt, args);
-	va_end (args);
+    va_start(args, fmt);
+    str = g_strdup_vprintf(fmt, args);
+    va_end(args);
 
-	if (nmc_config->use_colors)
-		ansi_seq =  nmc_config->palette[color];
+    if (nmc_config->use_colors)
+        ansi_seq = nmc_config->palette[color];
 
-	if (ansi_seq == NULL)
-		return str;
+    if (ansi_seq == NULL)
+        return str;
 
-	colored = g_strdup_printf ("\33[%sm%s\33[0m", ansi_seq, str);
-	g_free (str);
-	return colored;
+    colored = g_strdup_printf("\33[%sm%s\33[0m", ansi_seq, str);
+    g_free(str);
+    return colored;
 }
 
 /*
@@ -394,63 +399,63 @@ nmc_colorize (const NmcConfig *nmc_config, NMMetaColor color, const char *fmt, .
  * or NULL if the string is nul-terminated.
  */
 static int
-nmc_count_color_escape_chars (const char *start, const char *end)
+nmc_count_color_escape_chars(const char *start, const char *end)
 {
-	int num = 0;
-	gboolean inside = FALSE;
-
-	if (end == NULL)
-		end = start + strlen (start);
-
-	while (start < end) {
-		if (*start == '\33' && *(start+1) == '[')
-			inside = TRUE;
-		if (inside)
-			num++;
-		if (*start == 'm')
-			inside = FALSE;
-		start++;
-	}
-	return num;
+    int      num    = 0;
+    gboolean inside = FALSE;
+
+    if (end == NULL)
+        end = start + strlen(start);
+
+    while (start < end) {
+        if (*start == '\33' && *(start + 1) == '[')
+            inside = TRUE;
+        if (inside)
+            num++;
+        if (*start == 'm')
+            inside = FALSE;
+        start++;
+    }
+    return num;
 }
 
 /* Filter out possible ANSI color escape sequences */
 /* It directly modifies the passed string @str. */
 void
-nmc_filter_out_colors_inplace (char *str)
+nmc_filter_out_colors_inplace(char *str)
 {
-	const char *p1;
-	char *p2;
-	gboolean copy_char = TRUE;
-
-	if (!str)
-		return;
-
-	p1 = p2 = str;
-	while (*p1) {
-		if (*p1 == '\33' && *(p1+1) == '[')
-			copy_char = FALSE;
-		if (copy_char)
-			*p2++ = *p1;
-		if (!copy_char && *p1 == 'm')
-			copy_char = TRUE;
-		p1++;
-	}
-	*p2 = '\0';
+    const char *p1;
+    char *      p2;
+    gboolean    copy_char = TRUE;
+
+    if (!str)
+        return;
+
+    p1 = p2 = str;
+    while (*p1) {
+        if (*p1 == '\33' && *(p1 + 1) == '[')
+            copy_char = FALSE;
+        if (copy_char)
+            *p2++ = *p1;
+        if (!copy_char && *p1 == 'm')
+            copy_char = TRUE;
+        p1++;
+    }
+    *p2 = '\0';
 }
 
 /* Filter out possible ANSI color escape sequences */
 char *
-nmc_filter_out_colors (const char *str)
+nmc_filter_out_colors(const char *str)
 {
-	char *filtered;
+    char *filtered;
 
-	if (!str)
-		return NULL;
+    if (!str)
+        return NULL;
 
-	filtered = g_strdup (str);
-	nmc_filter_out_colors_inplace (filtered);
-	return filtered;
+    filtered = g_strdup(str);
+    nmc_filter_out_colors_inplace(filtered);
+    return filtered;
 }
 
 /*
@@ -458,66 +463,68 @@ nmc_filter_out_colors (const char *str)
  * The caller is responsible for freeing the returned string.
  */
 char *
-nmc_get_user_input (const char *ask_str)
+nmc_get_user_input(const char *ask_str)
 {
-	char *line = NULL;
-	size_t line_ln = 0;
-	ssize_t num;
-
-	g_print ("%s", ask_str);
-	num = getline (&line, &line_ln, stdin);
-
-	/* Remove newline from the string */
-	if (num < 1 || (num == 1 && line[0] == '\n')) {
-		g_free (line);
-		line = NULL;
-	} else {
-		if (line[num-1] == '\n')
-			line[num-1] = '\0';
-	}
-
-	return line;
+    char *  line    = NULL;
+    size_t  line_ln = 0;
+    ssize_t num;
+
+    g_print("%s", ask_str);
+    num = getline(&line, &line_ln, stdin);
+
+    /* Remove newline from the string */
+    if (num < 1 || (num == 1 && line[0] == '\n')) {
+        g_free(line);
+        line = NULL;
+    } else {
+        if (line[num - 1] == '\n')
+            line[num - 1] = '\0';
+    }
+
+    return line;
 }
 
 /*
  * Split string in 'line' according to 'delim' to (argument) array.
  */
 int
-nmc_string_to_arg_array (const char *line, const char *delim, gboolean unquote,
-                         char ***argv, int *argc)
+nmc_string_to_arg_array(const char *line,
+                        const char *delim,
+                        gboolean    unquote,
+                        char ***    argv,
+                        int *       argc)
 {
-	gs_free const char **arr0 = NULL;
-	char **arr;
-
-	arr0 = nm_utils_strsplit_set (line ?: "",
-	                              delim ?: " \t");
-	if (!arr0)
-		arr = g_new0 (char *, 1);
-	else
-		arr = g_strdupv ((char **) arr0);
-
-	if (unquote) {
-		int i = 0;
-		char *s;
-		size_t l;
-		const char *quotes = "\"'";
-
-		while (arr[i]) {
-			s = arr[i];
-			l = strlen (s);
-			if (l >= 2) {
-				if (strchr (quotes, s[0]) && s[l-1] == s[0]) {
-					memmove (s, s+1, l-2);
-					s[l-2] = '\0';
-				}
-			}
-			i++;
-		}
-	}
-
-	*argv = arr;
-	*argc = g_strv_length (arr);
-	return 0;
+    gs_free const char **arr0 = NULL;
+    char **              arr;
+
+    arr0 = nm_utils_strsplit_set(line ?: "", delim ?: " \t");
+    if (!arr0)
+        arr = g_new0(char *, 1);
+    else
+        arr = g_strdupv((char **) arr0);
+
+    if (unquote) {
+        int         i = 0;
+        char *      s;
+        size_t      l;
+        const char *quotes = "\"'";
+
+        while (arr[i]) {
+            s = arr[i];
+            l = strlen(s);
+            if (l >= 2) {
+                if (strchr(quotes, s[0]) && s[l - 1] == s[0]) {
+                    memmove(s, s + 1, l - 2);
+                    s[l - 2] = '\0';
+                }
+            }
+            i++;
+        }
+    }
+
+    *argv = arr;
+    *argc = g_strv_length(arr);
+    return 0;
 }
 
 /*
@@ -527,107 +534,109 @@ nmc_string_to_arg_array (const char *line, const char *delim, gboolean unquote,
  * Returns: a newly allocated string. Caller must free it with g_free().
  */
 char *
-nmc_util_strv_for_display (const char *const*strv, gboolean brackets)
+nmc_util_strv_for_display(const char *const *strv, gboolean brackets)
 {
-	GString *result;
-	guint i = 0;
-
-	result = g_string_sized_new (150);
-	if (brackets)
-		g_string_append_c (result, '[');
-	while (strv && strv[i]) {
-		if (result->len > 1)
-			g_string_append (result, ", ");
-		g_string_append (result, strv[i]);
-		i++;
-	}
-	if (brackets)
-		g_string_append_c (result, ']');
-
-	return g_string_free (result, FALSE);
+    GString *result;
+    guint    i = 0;
+
+    result = g_string_sized_new(150);
+    if (brackets)
+        g_string_append_c(result, '[');
+    while (strv && strv[i]) {
+        if (result->len > 1)
+            g_string_append(result, ", ");
+        g_string_append(result, strv[i]);
+        i++;
+    }
+    if (brackets)
+        g_string_append_c(result, ']');
+
+    return g_string_free(result, FALSE);
 }
 
 /*
  * Find out how many columns an UTF-8 string occupies on the screen.
  */
 int
-nmc_string_screen_width (const char *start, const char *end)
+nmc_string_screen_width(const char *start, const char *end)
 {
-	int width = 0;
-	const char *p = start;
+    int         width = 0;
+    const char *p     = start;
 
-	if (end == NULL)
-		end = start + strlen (start);
+    if (end == NULL)
+        end = start + strlen(start);
 
-	while (p < end) {
-		width += g_unichar_iswide (g_utf8_get_char (p)) ? 2 : g_unichar_iszerowidth (g_utf8_get_char (p)) ? 0 : 1;
-		p = g_utf8_next_char (p);
-	}
+    while (p < end) {
+        width += g_unichar_iswide(g_utf8_get_char(p))        ? 2
+                 : g_unichar_iszerowidth(g_utf8_get_char(p)) ? 0
+                                                             : 1;
+        p = g_utf8_next_char(p);
+    }
 
-	/* Subtract color escape sequences as they don't occupy space. */
-	return width - nmc_count_color_escape_chars (start, NULL);
+    /* Subtract color escape sequences as they don't occupy space. */
+    return width - nmc_count_color_escape_chars(start, NULL);
 }
 
 void
-set_val_str (NmcOutputField fields_array[], guint32 idx, char *value)
+set_val_str(NmcOutputField fields_array[], guint32 idx, char *value)
 {
-	fields_array[idx].value = value;
-	fields_array[idx].value_is_array = FALSE;
-	fields_array[idx].free_value = TRUE;
+    fields_array[idx].value          = value;
+    fields_array[idx].value_is_array = FALSE;
+    fields_array[idx].free_value     = TRUE;
 }
 
 void
-set_val_strc (NmcOutputField fields_array[], guint32 idx, const char *value)
+set_val_strc(NmcOutputField fields_array[], guint32 idx, const char *value)
 {
-	fields_array[idx].value = (char *) value;
-	fields_array[idx].value_is_array = FALSE;
-	fields_array[idx].free_value = FALSE;
+    fields_array[idx].value          = (char *) value;
+    fields_array[idx].value_is_array = FALSE;
+    fields_array[idx].free_value     = FALSE;
 }
 
 void
-set_val_arr (NmcOutputField fields_array[], guint32 idx, char **value)
+set_val_arr(NmcOutputField fields_array[], guint32 idx, char **value)
 {
-	fields_array[idx].value = value;
-	fields_array[idx].value_is_array = TRUE;
-	fields_array[idx].free_value = TRUE;
+    fields_array[idx].value          = value;
+    fields_array[idx].value_is_array = TRUE;
+    fields_array[idx].free_value     = TRUE;
 }
 
 void
-set_val_arrc (NmcOutputField fields_array[], guint32 idx, const char **value)
+set_val_arrc(NmcOutputField fields_array[], guint32 idx, const char **value)
 {
-	fields_array[idx].value = (char **) value;
-	fields_array[idx].value_is_array = TRUE;
-	fields_array[idx].free_value = FALSE;
+    fields_array[idx].value          = (char **) value;
+    fields_array[idx].value_is_array = TRUE;
+    fields_array[idx].free_value     = FALSE;
 }
 
 void
-set_val_color_all (NmcOutputField fields_array[], NMMetaColor color)
+set_val_color_all(NmcOutputField fields_array[], NMMetaColor color)
 {
-	int i;
+    int i;
 
-	for (i = 0; fields_array[i].info; i++) {
-		fields_array[i].color = color;
-	}
+    for (i = 0; fields_array[i].info; i++) {
+        fields_array[i].color = color;
+    }
 }
 
 /*
  * Free 'value' members in array of NmcOutputField
  */
 void
-nmc_free_output_field_values (NmcOutputField fields_array[])
+nmc_free_output_field_values(NmcOutputField fields_array[])
 {
-	NmcOutputField *iter = fields_array;
-
-	while (iter && iter->info) {
-		if (iter->free_value) {
-			if (iter->value_is_array)
-				g_strfreev ((char **) iter->value);
-			else
-				g_free ((char *) iter->value);
-			iter->value = NULL;
-		}
-		iter++;
-	}
+    NmcOutputField *iter = fields_array;
+
+    while (iter && iter->info) {
+        if (iter->free_value) {
+            if (iter->value_is_array)
+                g_strfreev((char **) iter->value);
+            else
+                g_free((char *) iter->value);
+            iter->value = NULL;
+        }
+        iter++;
+    }
 }
 
 /*****************************************************************************/
@@ -635,121 +644,129 @@ nmc_free_output_field_values (NmcOutputField fields_array[])
 #define PRINT_DATA_COL_PARENT_NIL (G_MAXUINT)
 
 typedef struct _PrintDataCol {
-	union {
-		const struct _PrintDataCol *parent_col;
-
-		/* while constructing the list of columns in _output_selection_append(), we keep track
-		 * of the parent by index. The reason is, that at that point our columns are still
-		 * tracked in a GArray which is growing (hence, the pointers are changing).
-		 * Later, _output_selection_complete() converts the index into the actual pointer.
-		 */
-		guint _parent_idx;
-	};
-	const NMMetaSelectionItem *selection_item;
-	guint self_idx;
-	bool is_leaf;
+    union {
+        const struct _PrintDataCol *parent_col;
+
+        /* while constructing the list of columns in _output_selection_append(), we keep track
+         * of the parent by index. The reason is, that at that point our columns are still
+         * tracked in a GArray which is growing (hence, the pointers are changing).
+         * Later, _output_selection_complete() converts the index into the actual pointer.
+         */
+        guint _parent_idx;
+    };
+    const NMMetaSelectionItem *selection_item;
+    guint                      self_idx;
+    bool                       is_leaf;
 } PrintDataCol;
 
 static gboolean
-_output_selection_append (GArray *cols,
-                          guint parent_idx,
-                          const NMMetaSelectionItem *selection_item,
-                          GPtrArray *gfree_keeper,
-                          GError **error)
+_output_selection_append(GArray *                   cols,
+                         guint                      parent_idx,
+                         const NMMetaSelectionItem *selection_item,
+                         GPtrArray *                gfree_keeper,
+                         GError **                  error)
 {
-	gs_free gpointer nested_to_free = NULL;
-	guint col_idx;
-	guint i;
-	const NMMetaAbstractInfo *const*nested;
-	NMMetaSelectionResultList *selection;
-
-	col_idx = cols->len;
-
-	{
-		PrintDataCol col = {
-			.selection_item = selection_item,
-			._parent_idx = parent_idx,
-			.self_idx = col_idx,
-			.is_leaf = TRUE,
-		};
-		g_array_append_val (cols, col);
-	}
-
-	nested = nm_meta_abstract_info_get_nested (selection_item->info, NULL, &nested_to_free);
-
-	if (selection_item->sub_selection) {
-		if (!nested) {
-			gs_free char *allowed_fields = NULL;
-
-			if (parent_idx != PRINT_DATA_COL_PARENT_NIL) {
-				const NMMetaSelectionItem *si;
-
-				si = g_array_index (cols, PrintDataCol, parent_idx).selection_item;
-				allowed_fields = nm_meta_abstract_info_get_nested_names_str (si->info, si->self_selection);
-			}
-			if (!allowed_fields) {
-				g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s%s%s'; no such field"),
-				             selection_item->self_selection ?: "", selection_item->self_selection ? "." : "",
-				             selection_item->sub_selection);
-			} else {
-				g_set_error (error, NMCLI_ERROR, 1, _("invalid field '%s%s%s'; allowed fields: [%s]"),
-				             selection_item->self_selection ?: "", selection_item->self_selection ? "." : "",
-				             selection_item->sub_selection,
-				             allowed_fields);
-			}
-			return FALSE;
-		}
-
-		selection = nm_meta_selection_create_parse_one (nested, selection_item->self_selection,
-		                                                selection_item->sub_selection, FALSE, error);
-		if (!selection)
-			return FALSE;
-		nm_assert (selection->num == 1);
-	} else if (nested) {
-		selection = nm_meta_selection_create_all (nested);
-		nm_assert (selection && selection->num > 0);
-	} else
-		selection = NULL;
-
-	if (selection) {
-		g_ptr_array_add (gfree_keeper, selection);
-
-		for (i = 0; i < selection->num; i++) {
-			if (!_output_selection_append (cols,
-			                               col_idx,
-			                               &selection->items[i],
-			                               gfree_keeper,
-			                               error))
-				return FALSE;
-		}
-
-		if (!NM_IN_SET(selection_item->info->meta_type,
-		               &nm_meta_type_setting_info_editor,
-		               &nmc_meta_type_generic_info))
-			g_array_index (cols, PrintDataCol, col_idx).is_leaf = FALSE;
-	}
-
-	return TRUE;
+    gs_free gpointer                 nested_to_free = NULL;
+    guint                            col_idx;
+    guint                            i;
+    const NMMetaAbstractInfo *const *nested;
+    NMMetaSelectionResultList *      selection;
+
+    col_idx = cols->len;
+
+    {
+        PrintDataCol col = {
+            .selection_item = selection_item,
+            ._parent_idx    = parent_idx,
+            .self_idx       = col_idx,
+            .is_leaf        = TRUE,
+        };
+        g_array_append_val(cols, col);
+    }
+
+    nested = nm_meta_abstract_info_get_nested(selection_item->info, NULL, &nested_to_free);
+
+    if (selection_item->sub_selection) {
+        if (!nested) {
+            gs_free char *allowed_fields = NULL;
+
+            if (parent_idx != PRINT_DATA_COL_PARENT_NIL) {
+                const NMMetaSelectionItem *si;
+
+                si = g_array_index(cols, PrintDataCol, parent_idx).selection_item;
+                allowed_fields =
+                    nm_meta_abstract_info_get_nested_names_str(si->info, si->self_selection);
+            }
+            if (!allowed_fields) {
+                g_set_error(error,
+                            NMCLI_ERROR,
+                            1,
+                            _("invalid field '%s%s%s'; no such field"),
+                            selection_item->self_selection ?: "",
+                            selection_item->self_selection ? "." : "",
+                            selection_item->sub_selection);
+            } else {
+                g_set_error(error,
+                            NMCLI_ERROR,
+                            1,
+                            _("invalid field '%s%s%s'; allowed fields: [%s]"),
+                            selection_item->self_selection ?: "",
+                            selection_item->self_selection ? "." : "",
+                            selection_item->sub_selection,
+                            allowed_fields);
+            }
+            return FALSE;
+        }
+
+        selection = nm_meta_selection_create_parse_one(nested,
+                                                       selection_item->self_selection,
+                                                       selection_item->sub_selection,
+                                                       FALSE,
+                                                       error);
+        if (!selection)
+            return FALSE;
+        nm_assert(selection->num == 1);
+    } else if (nested) {
+        selection = nm_meta_selection_create_all(nested);
+        nm_assert(selection && selection->num > 0);
+    } else
+        selection = NULL;
+
+    if (selection) {
+        g_ptr_array_add(gfree_keeper, selection);
+
+        for (i = 0; i < selection->num; i++) {
+            if (!_output_selection_append(cols, col_idx, &selection->items[i], gfree_keeper, error))
+                return FALSE;
+        }
+
+        if (!NM_IN_SET(selection_item->info->meta_type,
+                       &nm_meta_type_setting_info_editor,
+                       &nmc_meta_type_generic_info))
+            g_array_index(cols, PrintDataCol, col_idx).is_leaf = FALSE;
+    }
+
+    return TRUE;
 }
 
 static void
-_output_selection_complete (GArray *cols)
+_output_selection_complete(GArray *cols)
 {
-	guint i;
+    guint i;
 
-	nm_assert (cols);
-	nm_assert (g_array_get_element_size (cols) == sizeof (PrintDataCol));
+    nm_assert(cols);
+    nm_assert(g_array_get_element_size(cols) == sizeof(PrintDataCol));
 
-	for (i = 0; i < cols->len; i++) {
-		PrintDataCol *col = &g_array_index (cols, PrintDataCol, i);
+    for (i = 0; i < cols->len; i++) {
+        PrintDataCol *col = &g_array_index(cols, PrintDataCol, i);
 
-		if (col->_parent_idx == PRINT_DATA_COL_PARENT_NIL)
-			col->parent_col = NULL;
-		else {
-			nm_assert (col->_parent_idx < i);
-			col->parent_col = &g_array_index (cols, PrintDataCol, col->_parent_idx);
-		}
-	}
+        if (col->_parent_idx == PRINT_DATA_COL_PARENT_NIL)
+            col->parent_col = NULL;
+        else {
+            nm_assert(col->_parent_idx < i);
+            col->parent_col = &g_array_index(cols, PrintDataCol, col->_parent_idx);
+        }
+    }
 }
 
 /*****************************************************************************/
@@ -771,48 +788,48 @@ _output_selection_complete (GArray *cols)
  * Returns: %TRUE on success.
  */
 static gboolean
-_output_selection_parse (const NMMetaAbstractInfo *const*fields,
-                         const char *fields_str,
-                         PrintDataCol **out_cols_data,
-                         guint *out_cols_len,
-                         GPtrArray **out_gfree_keeper,
-                         GError **error)
+_output_selection_parse(const NMMetaAbstractInfo *const *fields,
+                        const char *                     fields_str,
+                        PrintDataCol **                  out_cols_data,
+                        guint *                          out_cols_len,
+                        GPtrArray **                     out_gfree_keeper,
+                        GError **                        error)
 {
-	NMMetaSelectionResultList *selection;
-	gs_unref_ptrarray GPtrArray *gfree_keeper = NULL;
-	gs_unref_array GArray *cols = NULL;
-	guint i;
-
-	selection = nm_meta_selection_create_parse_list (fields, fields_str, FALSE, error);
-	if (!selection)
-		return FALSE;
-
-	if (!selection->num) {
-		g_set_error (error, NMCLI_ERROR, 1, _("failure to select field"));
-		g_free (selection);
-		return FALSE;
-	}
-
-	gfree_keeper = g_ptr_array_new_with_free_func (g_free);
-	g_ptr_array_add (gfree_keeper, selection);
-
-	cols = g_array_new (FALSE, TRUE, sizeof (PrintDataCol));
-
-	for (i = 0; i < selection->num; i++) {
-		if (!_output_selection_append (cols,
-		                               PRINT_DATA_COL_PARENT_NIL,
-		                               &selection->items[i],
-		                               gfree_keeper,
-		                               error))
-			return FALSE;
-	}
-
-	_output_selection_complete (cols);
-
-	*out_cols_len = cols->len;
-	*out_cols_data = (PrintDataCol *) g_array_free (g_steal_pointer (&cols), FALSE);
-	*out_gfree_keeper = g_steal_pointer (&gfree_keeper);
-	return TRUE;
+    NMMetaSelectionResultList *selection;
+    gs_unref_ptrarray GPtrArray *gfree_keeper = NULL;
+    gs_unref_array GArray *cols               = NULL;
+    guint                  i;
+
+    selection = nm_meta_selection_create_parse_list(fields, fields_str, FALSE, error);
+    if (!selection)
+        return FALSE;
+
+    if (!selection->num) {
+        g_set_error(error, NMCLI_ERROR, 1, _("failure to select field"));
+        g_free(selection);
+        return FALSE;
+    }
+
+    gfree_keeper = g_ptr_array_new_with_free_func(g_free);
+    g_ptr_array_add(gfree_keeper, selection);
+
+    cols = g_array_new(FALSE, TRUE, sizeof(PrintDataCol));
+
+    for (i = 0; i < selection->num; i++) {
+        if (!_output_selection_append(cols,
+                                      PRINT_DATA_COL_PARENT_NIL,
+                                      &selection->items[i],
+                                      gfree_keeper,
+                                      error))
+            return FALSE;
+    }
+
+    _output_selection_complete(cols);
+
+    *out_cols_len     = cols->len;
+    *out_cols_data    = (PrintDataCol *) g_array_free(g_steal_pointer(&cols), FALSE);
+    *out_gfree_keeper = g_steal_pointer(&gfree_keeper);
+    return TRUE;
 }
 
 /*****************************************************************************/
@@ -838,728 +855,712 @@ _output_selection_parse (const NMMetaAbstractInfo *const*fields,
  *   Caller is responsible for freeing the array.
  */
 GArray *
-parse_output_fields (const char *fields_str,
-                     const NMMetaAbstractInfo *const*fields_array,
-                     gboolean parse_groups,
-                     GPtrArray **out_group_fields,
-                     GError **error)
+parse_output_fields(const char *                     fields_str,
+                    const NMMetaAbstractInfo *const *fields_array,
+                    gboolean                         parse_groups,
+                    GPtrArray **                     out_group_fields,
+                    GError **                        error)
 {
-	gs_free NMMetaSelectionResultList *selection = NULL;
-	GArray *array;
-	GPtrArray *group_fields = NULL;
-	guint i;
+    gs_free NMMetaSelectionResultList *selection = NULL;
+    GArray *                           array;
+    GPtrArray *                        group_fields = NULL;
+    guint                              i;
 
-	g_return_val_if_fail (!error || !*error, NULL);
-	g_return_val_if_fail (!out_group_fields || !*out_group_fields, NULL);
+    g_return_val_if_fail(!error || !*error, NULL);
+    g_return_val_if_fail(!out_group_fields || !*out_group_fields, NULL);
 
-	selection = nm_meta_selection_create_parse_list (fields_array, fields_str, TRUE, error);
-	if (!selection)
-		return NULL;
+    selection = nm_meta_selection_create_parse_list(fields_array, fields_str, TRUE, error);
+    if (!selection)
+        return NULL;
 
-	array = g_array_sized_new (FALSE, FALSE, sizeof (int), selection->num);
-	if (parse_groups && out_group_fields)
-		group_fields = g_ptr_array_new_full (selection->num, g_free);
+    array = g_array_sized_new(FALSE, FALSE, sizeof(int), selection->num);
+    if (parse_groups && out_group_fields)
+        group_fields = g_ptr_array_new_full(selection->num, g_free);
 
-	for (i = 0; i < selection->num; i++) {
-		int idx = selection->items[i].idx;
+    for (i = 0; i < selection->num; i++) {
+        int idx = selection->items[i].idx;
 
-		g_array_append_val (array, idx);
-		if (group_fields)
-			g_ptr_array_add (group_fields, g_strdup (selection->items[i].sub_selection));
-	}
+        g_array_append_val(array, idx);
+        if (group_fields)
+            g_ptr_array_add(group_fields, g_strdup(selection->items[i].sub_selection));
+    }
 
-	if (group_fields)
-		*out_group_fields = group_fields;
-	return array;
+    if (group_fields)
+        *out_group_fields = group_fields;
+    return array;
 }
 
 NmcOutputField *
-nmc_dup_fields_array (const NMMetaAbstractInfo *const*fields, NmcOfFlags flags)
+nmc_dup_fields_array(const NMMetaAbstractInfo *const *fields, NmcOfFlags flags)
 {
-	NmcOutputField *row;
-	gsize l;
+    NmcOutputField *row;
+    gsize           l;
 
-	for (l = 0; fields[l]; l++) {
-	}
+    for (l = 0; fields[l]; l++) {}
 
-	row = g_new0 (NmcOutputField, l + 1);
-	for (l = 0; fields[l]; l++)
-		row[l].info = fields[l];
-	row[0].flags = flags;
-	return row;
+    row = g_new0(NmcOutputField, l + 1);
+    for (l = 0; fields[l]; l++)
+        row[l].info = fields[l];
+    row[0].flags = flags;
+    return row;
 }
 
 void
-nmc_empty_output_fields (NmcOutputData *output_data)
+nmc_empty_output_fields(NmcOutputData *output_data)
 {
-	guint i;
+    guint i;
 
-	/* Free values in field structure */
-	for (i = 0; i < output_data->output_data->len; i++) {
-		NmcOutputField *fld_arr = g_ptr_array_index (output_data->output_data, i);
-		nmc_free_output_field_values (fld_arr);
-	}
+    /* Free values in field structure */
+    for (i = 0; i < output_data->output_data->len; i++) {
+        NmcOutputField *fld_arr = g_ptr_array_index(output_data->output_data, i);
+        nmc_free_output_field_values(fld_arr);
+    }
 
-	/* Empty output_data array */
-	if (output_data->output_data->len > 0)
-		g_ptr_array_remove_range (output_data->output_data, 0, output_data->output_data->len);
+    /* Empty output_data array */
+    if (output_data->output_data->len > 0)
+        g_ptr_array_remove_range(output_data->output_data, 0, output_data->output_data->len);
 
-	g_ptr_array_unref (output_data->output_data);
+    g_ptr_array_unref(output_data->output_data);
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	guint col_idx;
-	const PrintDataCol *col;
-	const char *title;
-	bool title_to_free:1;
+    guint               col_idx;
+    const PrintDataCol *col;
+    const char *        title;
+    bool                title_to_free : 1;
 
-	/* whether the column should be printed. If not %TRUE,
-	 * the column will be skipped. */
-	bool to_print:1;
+    /* whether the column should be printed. If not %TRUE,
+     * the column will be skipped. */
+    bool to_print : 1;
 
-	int width;
+    int width;
 } PrintDataHeaderCell;
 
 typedef enum {
-	PRINT_DATA_CELL_FORMAT_TYPE_PLAIN = 0,
-	PRINT_DATA_CELL_FORMAT_TYPE_STRV,
+    PRINT_DATA_CELL_FORMAT_TYPE_PLAIN = 0,
+    PRINT_DATA_CELL_FORMAT_TYPE_STRV,
 } PrintDataCellFormatType;
 
 typedef struct {
-	guint row_idx;
-	const PrintDataHeaderCell *header_cell;
-	NMMetaColor color;
-	union {
-		const char *plain;
-		const char *const*strv;
-	} text;
-	PrintDataCellFormatType text_format:3;
-	bool text_to_free:1;
+    guint                      row_idx;
+    const PrintDataHeaderCell *header_cell;
+    NMMetaColor                color;
+    union {
+        const char *       plain;
+        const char *const *strv;
+    } text;
+    PrintDataCellFormatType text_format : 3;
+    bool                    text_to_free : 1;
 } PrintDataCell;
 
 static void
-_print_data_header_cell_clear (gpointer cell_p)
+_print_data_header_cell_clear(gpointer cell_p)
 {
-	PrintDataHeaderCell *cell = cell_p;
+    PrintDataHeaderCell *cell = cell_p;
 
-	if (cell->title_to_free) {
-		g_free ((char *) cell->title);
-		cell->title_to_free = FALSE;
-	}
-	cell->title = NULL;
+    if (cell->title_to_free) {
+        g_free((char *) cell->title);
+        cell->title_to_free = FALSE;
+    }
+    cell->title = NULL;
 }
 
 static void
-_print_data_cell_clear_text (PrintDataCell *cell)
+_print_data_cell_clear_text(PrintDataCell *cell)
 {
-	switch (cell->text_format) {
-	case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN:
-		if (cell->text_to_free)
-			g_free ((char *) cell->text.plain);
-		cell->text.plain = NULL;
-		break;
-	case PRINT_DATA_CELL_FORMAT_TYPE_STRV:
-		if (cell->text_to_free)
-			g_strfreev ((char **) cell->text.strv);
-		cell->text.strv = NULL;
-		break;
-	};
-	cell->text_format = PRINT_DATA_CELL_FORMAT_TYPE_PLAIN;
-	cell->text_to_free = FALSE;
+    switch (cell->text_format) {
+    case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN:
+        if (cell->text_to_free)
+            g_free((char *) cell->text.plain);
+        cell->text.plain = NULL;
+        break;
+    case PRINT_DATA_CELL_FORMAT_TYPE_STRV:
+        if (cell->text_to_free)
+            g_strfreev((char **) cell->text.strv);
+        cell->text.strv = NULL;
+        break;
+    };
+    cell->text_format  = PRINT_DATA_CELL_FORMAT_TYPE_PLAIN;
+    cell->text_to_free = FALSE;
 }
 
 static void
-_print_data_cell_clear (gpointer cell_p)
+_print_data_cell_clear(gpointer cell_p)
 {
-	PrintDataCell *cell = cell_p;
+    PrintDataCell *cell = cell_p;
 
-	_print_data_cell_clear_text (cell);
+    _print_data_cell_clear_text(cell);
 }
 
 static void
-_print_fill (const NmcConfig *nmc_config,
-             gpointer const *targets,
-             gpointer targets_data,
-             const PrintDataCol *cols,
-             guint cols_len,
-             GArray **out_header_row,
-             GArray **out_cells)
+_print_fill(const NmcConfig *   nmc_config,
+            gpointer const *    targets,
+            gpointer            targets_data,
+            const PrintDataCol *cols,
+            guint               cols_len,
+            GArray **           out_header_row,
+            GArray **           out_cells)
 {
-	GArray *cells;
-	GArray *header_row;
-	guint i_row, i_col;
-	guint targets_len;
-	NMMetaAccessorGetType text_get_type;
-	NMMetaAccessorGetFlags text_get_flags;
-
-
-	header_row = g_array_sized_new (FALSE, TRUE, sizeof (PrintDataHeaderCell), cols_len);
-	g_array_set_clear_func (header_row, _print_data_header_cell_clear);
-
-	for (i_col = 0; i_col < cols_len; i_col++) {
-		const PrintDataCol *col;
-		PrintDataHeaderCell *header_cell;
-		guint col_idx;
-		const NMMetaAbstractInfo *info;
-
-		col = &cols[i_col];
-		if (!col->is_leaf)
-			continue;
-
-		info = col->selection_item->info;
-
-		col_idx = header_row->len;
-		g_array_set_size (header_row, col_idx + 1);
-
-		header_cell = &g_array_index (header_row, PrintDataHeaderCell, col_idx);
-
-		header_cell->col_idx = col_idx;
-		header_cell->col = col;
-
-		/* by default, the entire column is skipped. That is the case,
-		 * unless we have a cell (below) which opts-in to be printed. */
-		header_cell->to_print = FALSE;
-
-		header_cell->title = nm_meta_abstract_info_get_name (info, TRUE);
-		if (   nmc_config->multiline_output
-		    && col->parent_col
-		    && NM_IN_SET (info->meta_type,
-		                  &nm_meta_type_property_info,
-		                  &nmc_meta_type_generic_info)) {
-			header_cell->title = g_strdup_printf ("%s.%s",
-			                                      nm_meta_abstract_info_get_name (col->parent_col->selection_item->info, FALSE),
-			                                      header_cell->title);
-			header_cell->title_to_free = TRUE;
-		}
-	}
-
-	targets_len = NM_PTRARRAY_LEN (targets);
-
-	cells = g_array_sized_new (FALSE, TRUE, sizeof (PrintDataCell), targets_len * header_row->len);
-	g_array_set_clear_func (cells, _print_data_cell_clear);
-	g_array_set_size (cells, targets_len * header_row->len);
-
-	text_get_type = nmc_print_output_to_accessor_get_type (nmc_config->print_output);
-	text_get_flags = NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV;
-	if (nmc_config->show_secrets)
-		text_get_flags |= NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS;
-
-	for (i_row = 0; i_row < targets_len; i_row++) {
-		gpointer target = targets[i_row];
-		PrintDataCell *cells_line = &g_array_index (cells, PrintDataCell, i_row * header_row->len);
-
-		for (i_col = 0; i_col < header_row->len; i_col++) {
-			char *to_free = NULL;
-			PrintDataCell *cell = &cells_line[i_col];
-			PrintDataHeaderCell *header_cell;
-			const NMMetaAbstractInfo *info;
-			NMMetaAccessorGetOutFlags text_out_flags, color_out_flags;
-			gconstpointer value;
-			gboolean is_default;
-
-			header_cell = &g_array_index (header_row, PrintDataHeaderCell, i_col);
-			info = header_cell->col->selection_item->info;
-
-			cell->row_idx = i_row;
-			cell->header_cell = header_cell;
-
-			value = nm_meta_abstract_info_get (info,
-			                                   nmc_meta_environment,
-			                                   (gpointer) nmc_meta_environment_arg,
-			                                   target,
-			                                   targets_data,
-			                                   text_get_type,
-			                                   text_get_flags,
-			                                   &text_out_flags,
-			                                   &is_default,
-			                                   (gpointer *) &to_free);
-
-			nm_assert (!to_free || value == to_free);
-
-			if (   (   is_default
-			        && nmc_config->overview)
-			    || NM_FLAGS_HAS (text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE)) {
-				/* don't mark the entry for display. This is to shorten the output in case
-				 * the property is the default value. But we only do that, if the user
-				 * opts in to this behavior (-overview), or of the property marks itself
-				 * eligible to be hidden.
-				 *
-				 * In general, only new API shall mark itself eligible to be hidden.
-				 * Long established properties cannot, because it would be a change
-				 * in behavior. */
-			} else
-				header_cell->to_print = TRUE;
-
-			if (NM_FLAGS_HAS (text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_STRV)) {
-				if (nmc_config->multiline_output) {
-					cell->text_format = PRINT_DATA_CELL_FORMAT_TYPE_STRV;
-					cell->text.strv = value;
-					cell->text_to_free = !!to_free;
-				} else {
-					if (value && ((const char *const*) value)[0]) {
-						cell->text.plain = g_strjoinv (" | ", (char **) value);
-						cell->text_to_free = TRUE;
-					}
-					if (to_free)
-						g_strfreev ((char **) to_free);
-				}
-			} else {
-				cell->text.plain = value;
-				cell->text_to_free = !!to_free;
-			}
-
-			cell->color = GPOINTER_TO_INT (nm_meta_abstract_info_get (info,
-			                                                          nmc_meta_environment,
-			                                                          (gpointer) nmc_meta_environment_arg,
-			                                                          target,
-			                                                          targets_data,
-			                                                          NM_META_ACCESSOR_GET_TYPE_COLOR,
-			                                                          NM_META_ACCESSOR_GET_FLAGS_NONE,
-			                                                          &color_out_flags,
-			                                                          NULL,
-			                                                          NULL));
-
-			if (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_PLAIN) {
-				if (   NM_IN_SET (nmc_config->print_output, NMC_PRINT_NORMAL, NMC_PRINT_PRETTY)
-				    && (   !cell->text.plain
-				        || !cell->text.plain[0])) {
-					_print_data_cell_clear_text (cell);
-					cell->text.plain = "--";
-				} else if (!cell->text.plain)
-					cell->text.plain = "";
-				nm_assert (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_PLAIN);
-			}
-		}
-	}
-
-	for (i_col = 0; i_col < header_row->len; i_col++) {
-		PrintDataHeaderCell *header_cell = &g_array_index (header_row, PrintDataHeaderCell, i_col);
-
-		header_cell->width = nmc_string_screen_width (header_cell->title, NULL);
-
-		for (i_row = 0; i_row < targets_len; i_row++) {
-			const PrintDataCell *cells_line = &g_array_index (cells, PrintDataCell, i_row * header_row->len);
-			const PrintDataCell *cell = &cells_line[i_col];
-			const char *const*i_strv;
-
-			switch (cell->text_format) {
-			case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN:
-				header_cell->width = NM_MAX (header_cell->width,
-				                             nmc_string_screen_width (cell->text.plain, NULL));
-				break;
-			case PRINT_DATA_CELL_FORMAT_TYPE_STRV:
-				i_strv = cell->text.strv;
-				if (i_strv) {
-					for (; *i_strv; i_strv++) {
-						header_cell->width = NM_MAX (header_cell->width,
-						                             nmc_string_screen_width (*i_strv, NULL));
-					}
-				}
-				break;
-			}
-		}
-
-		header_cell->width += 1;
-	}
-
-	*out_header_row = header_row;
-	*out_cells = cells;
+    GArray *               cells;
+    GArray *               header_row;
+    guint                  i_row, i_col;
+    guint                  targets_len;
+    NMMetaAccessorGetType  text_get_type;
+    NMMetaAccessorGetFlags text_get_flags;
+
+    header_row = g_array_sized_new(FALSE, TRUE, sizeof(PrintDataHeaderCell), cols_len);
+    g_array_set_clear_func(header_row, _print_data_header_cell_clear);
+
+    for (i_col = 0; i_col < cols_len; i_col++) {
+        const PrintDataCol *      col;
+        PrintDataHeaderCell *     header_cell;
+        guint                     col_idx;
+        const NMMetaAbstractInfo *info;
+
+        col = &cols[i_col];
+        if (!col->is_leaf)
+            continue;
+
+        info = col->selection_item->info;
+
+        col_idx = header_row->len;
+        g_array_set_size(header_row, col_idx + 1);
+
+        header_cell = &g_array_index(header_row, PrintDataHeaderCell, col_idx);
+
+        header_cell->col_idx = col_idx;
+        header_cell->col     = col;
+
+        /* by default, the entire column is skipped. That is the case,
+         * unless we have a cell (below) which opts-in to be printed. */
+        header_cell->to_print = FALSE;
+
+        header_cell->title = nm_meta_abstract_info_get_name(info, TRUE);
+        if (nmc_config->multiline_output && col->parent_col
+            && NM_IN_SET(info->meta_type,
+                         &nm_meta_type_property_info,
+                         &nmc_meta_type_generic_info)) {
+            header_cell->title = g_strdup_printf(
+                "%s.%s",
+                nm_meta_abstract_info_get_name(col->parent_col->selection_item->info, FALSE),
+                header_cell->title);
+            header_cell->title_to_free = TRUE;
+        }
+    }
+
+    targets_len = NM_PTRARRAY_LEN(targets);
+
+    cells = g_array_sized_new(FALSE, TRUE, sizeof(PrintDataCell), targets_len * header_row->len);
+    g_array_set_clear_func(cells, _print_data_cell_clear);
+    g_array_set_size(cells, targets_len * header_row->len);
+
+    text_get_type  = nmc_print_output_to_accessor_get_type(nmc_config->print_output);
+    text_get_flags = NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV;
+    if (nmc_config->show_secrets)
+        text_get_flags |= NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS;
+
+    for (i_row = 0; i_row < targets_len; i_row++) {
+        gpointer       target     = targets[i_row];
+        PrintDataCell *cells_line = &g_array_index(cells, PrintDataCell, i_row * header_row->len);
+
+        for (i_col = 0; i_col < header_row->len; i_col++) {
+            char *                    to_free = NULL;
+            PrintDataCell *           cell    = &cells_line[i_col];
+            PrintDataHeaderCell *     header_cell;
+            const NMMetaAbstractInfo *info;
+            NMMetaAccessorGetOutFlags text_out_flags, color_out_flags;
+            gconstpointer             value;
+            gboolean                  is_default;
+
+            header_cell = &g_array_index(header_row, PrintDataHeaderCell, i_col);
+            info        = header_cell->col->selection_item->info;
+
+            cell->row_idx     = i_row;
+            cell->header_cell = header_cell;
+
+            value = nm_meta_abstract_info_get(info,
+                                              nmc_meta_environment,
+                                              (gpointer) nmc_meta_environment_arg,
+                                              target,
+                                              targets_data,
+                                              text_get_type,
+                                              text_get_flags,
+                                              &text_out_flags,
+                                              &is_default,
+                                              (gpointer *) &to_free);
+
+            nm_assert(!to_free || value == to_free);
+
+            if ((is_default && nmc_config->overview)
+                || NM_FLAGS_HAS(text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE)) {
+                /* don't mark the entry for display. This is to shorten the output in case
+                 * the property is the default value. But we only do that, if the user
+                 * opts in to this behavior (-overview), or of the property marks itself
+                 * eligible to be hidden.
+                 *
+                 * In general, only new API shall mark itself eligible to be hidden.
+                 * Long established properties cannot, because it would be a change
+                 * in behavior. */
+            } else
+                header_cell->to_print = TRUE;
+
+            if (NM_FLAGS_HAS(text_out_flags, NM_META_ACCESSOR_GET_OUT_FLAGS_STRV)) {
+                if (nmc_config->multiline_output) {
+                    cell->text_format  = PRINT_DATA_CELL_FORMAT_TYPE_STRV;
+                    cell->text.strv    = value;
+                    cell->text_to_free = !!to_free;
+                } else {
+                    if (value && ((const char *const *) value)[0]) {
+                        cell->text.plain   = g_strjoinv(" | ", (char **) value);
+                        cell->text_to_free = TRUE;
+                    }
+                    if (to_free)
+                        g_strfreev((char **) to_free);
+                }
+            } else {
+                cell->text.plain   = value;
+                cell->text_to_free = !!to_free;
+            }
+
+            cell->color =
+                GPOINTER_TO_INT(nm_meta_abstract_info_get(info,
+                                                          nmc_meta_environment,
+                                                          (gpointer) nmc_meta_environment_arg,
+                                                          target,
+                                                          targets_data,
+                                                          NM_META_ACCESSOR_GET_TYPE_COLOR,
+                                                          NM_META_ACCESSOR_GET_FLAGS_NONE,
+                                                          &color_out_flags,
+                                                          NULL,
+                                                          NULL));
+
+            if (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_PLAIN) {
+                if (NM_IN_SET(nmc_config->print_output, NMC_PRINT_NORMAL, NMC_PRINT_PRETTY)
+                    && (!cell->text.plain || !cell->text.plain[0])) {
+                    _print_data_cell_clear_text(cell);
+                    cell->text.plain = "--";
+                } else if (!cell->text.plain)
+                    cell->text.plain = "";
+                nm_assert(cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_PLAIN);
+            }
+        }
+    }
+
+    for (i_col = 0; i_col < header_row->len; i_col++) {
+        PrintDataHeaderCell *header_cell = &g_array_index(header_row, PrintDataHeaderCell, i_col);
+
+        header_cell->width = nmc_string_screen_width(header_cell->title, NULL);
+
+        for (i_row = 0; i_row < targets_len; i_row++) {
+            const PrintDataCell *cells_line =
+                &g_array_index(cells, PrintDataCell, i_row * header_row->len);
+            const PrintDataCell *cell = &cells_line[i_col];
+            const char *const *  i_strv;
+
+            switch (cell->text_format) {
+            case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN:
+                header_cell->width =
+                    NM_MAX(header_cell->width, nmc_string_screen_width(cell->text.plain, NULL));
+                break;
+            case PRINT_DATA_CELL_FORMAT_TYPE_STRV:
+                i_strv = cell->text.strv;
+                if (i_strv) {
+                    for (; *i_strv; i_strv++) {
+                        header_cell->width =
+                            NM_MAX(header_cell->width, nmc_string_screen_width(*i_strv, NULL));
+                    }
+                }
+                break;
+            }
+        }
+
+        header_cell->width += 1;
+    }
+
+    *out_header_row = header_row;
+    *out_cells      = cells;
 }
 
 static gboolean
-_print_skip_column (const NmcConfig *nmc_config,
-                    const PrintDataHeaderCell *header_cell)
+_print_skip_column(const NmcConfig *nmc_config, const PrintDataHeaderCell *header_cell)
 {
-	const NMMetaSelectionItem *selection_item;
-	const NMMetaAbstractInfo *info;
-
-	selection_item = header_cell->col->selection_item;
-	info = selection_item->info;
-
-	if (!header_cell->to_print)
-		return TRUE;
-
-	if (nmc_config->multiline_output) {
-		if (info->meta_type == &nm_meta_type_setting_info_editor) {
-			/* we skip the "name" entry for the setting in multiline output. */
-			return TRUE;
-		}
-		if (   info->meta_type == &nmc_meta_type_generic_info
-		    && ((const NmcMetaGenericInfo *) info)->nested) {
-			/* skip the "name" entry for parent generic-infos */
-			return TRUE;
-		}
-	} else {
-		if (   NM_IN_SET (info->meta_type,
-		                  &nm_meta_type_setting_info_editor,
-		                  &nmc_meta_type_generic_info)
-		    && selection_item->sub_selection) {
-			/* in tabular form, we skip the "name" entry for sections that have sub-selections.
-			 * That is, for "ipv4.may-fail", but not for "ipv4". */
-			return TRUE;
-		}
-	}
-	return FALSE;
+    const NMMetaSelectionItem *selection_item;
+    const NMMetaAbstractInfo * info;
+
+    selection_item = header_cell->col->selection_item;
+    info           = selection_item->info;
+
+    if (!header_cell->to_print)
+        return TRUE;
+
+    if (nmc_config->multiline_output) {
+        if (info->meta_type == &nm_meta_type_setting_info_editor) {
+            /* we skip the "name" entry for the setting in multiline output. */
+            return TRUE;
+        }
+        if (info->meta_type == &nmc_meta_type_generic_info
+            && ((const NmcMetaGenericInfo *) info)->nested) {
+            /* skip the "name" entry for parent generic-infos */
+            return TRUE;
+        }
+    } else {
+        if (NM_IN_SET(info->meta_type,
+                      &nm_meta_type_setting_info_editor,
+                      &nmc_meta_type_generic_info)
+            && selection_item->sub_selection) {
+            /* in tabular form, we skip the "name" entry for sections that have sub-selections.
+             * That is, for "ipv4.may-fail", but not for "ipv4". */
+            return TRUE;
+        }
+    }
+    return FALSE;
 }
 
 static void
-_print_do (const NmcConfig *nmc_config,
-           const char *header_name_no_l10n,
-           guint col_len,
-           guint row_len,
-           const PrintDataHeaderCell *header_row,
-           const PrintDataCell *cells)
+_print_do(const NmcConfig *          nmc_config,
+          const char *               header_name_no_l10n,
+          guint                      col_len,
+          guint                      row_len,
+          const PrintDataHeaderCell *header_row,
+          const PrintDataCell *      cells)
 {
-	int width1, width2;
-	int table_width = 0;
-	guint i_row, i_col;
-	nm_auto_free_gstring GString *str = NULL;
-
-	g_assert (col_len);
-
-	/* Main header */
-	if (   nmc_config->print_output == NMC_PRINT_PRETTY
-	    && header_name_no_l10n) {
-		gs_free char *line = NULL;
-		int header_width;
-		const char *header_name = _(header_name_no_l10n);
-
-		header_width = nmc_string_screen_width (header_name, NULL) + 4;
-
-		if (nmc_config->multiline_output) {
-			table_width = NM_MAX (header_width, ML_HEADER_WIDTH);
-			line = g_strnfill (ML_HEADER_WIDTH, '=');
-		} else { /* tabular */
-			table_width = NM_MAX (table_width, header_width);
-			line = g_strnfill (table_width, '=');
-		}
-
-		width1 = strlen (header_name);
-		width2 = nmc_string_screen_width (header_name, NULL);
-		g_print ("%s\n", line);
-		g_print ("%*s\n", (table_width + width2)/2 + width1 - width2, header_name);
-		g_print ("%s\n", line);
-	}
-
-	str = !nmc_config->multiline_output
-	      ? g_string_sized_new (100)
-	      : NULL;
-
-	/* print the header for the tabular form */
-	if (   NM_IN_SET (nmc_config->print_output, NMC_PRINT_NORMAL, NMC_PRINT_PRETTY)
-	    && !nmc_config->multiline_output) {
-		for (i_col = 0; i_col < col_len; i_col++) {
-			const PrintDataHeaderCell *header_cell = &header_row[i_col];
-			const char *title;
-
-			if (_print_skip_column (nmc_config, header_cell))
-				continue;
-
-			title = header_cell->title;
-
-			width1 = strlen (title);
-			width2 = nmc_string_screen_width (title, NULL);  /* Width of the string (in screen columns) */
-			g_string_append_printf (str, "%-*s", (int) (header_cell->width + width1 - width2), title);
-			g_string_append_c (str, ' ');  /* Column separator */
-			table_width += header_cell->width + width1 - width2 + 1;
-		}
-
-		if (str->len)
-			g_string_truncate (str, str->len-1);  /* Chop off last column separator */
-		g_print ("%s\n", str->str);
-		g_string_truncate (str, 0);
-
-		/* Print horizontal separator */
-		if (nmc_config->print_output == NMC_PRINT_PRETTY) {
-			gs_free char *line = NULL;
-
-			g_print ("%s\n", (line = g_strnfill (table_width, '-')));
-		}
-	}
-
-	for (i_row = 0; i_row < row_len; i_row++) {
-		const PrintDataCell *current_line = &cells[i_row * col_len];
-
-		for (i_col = 0; i_col < col_len; i_col++) {
-			const PrintDataCell *cell = &current_line[i_col];
-			const char *const*lines = NULL;
-			guint i_lines, lines_len;
-
-			if (_print_skip_column (nmc_config, cell->header_cell))
-				continue;
-
-			lines_len = 0;
-			switch (cell->text_format) {
-			case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN:
-				lines = &cell->text.plain;
-				lines_len = 1;
-				break;
-			case PRINT_DATA_CELL_FORMAT_TYPE_STRV:
-				nm_assert (nmc_config->multiline_output);
-				lines = cell->text.strv;
-				lines_len = NM_PTRARRAY_LEN (lines);
-				break;
-			}
-
-			for (i_lines = 0; i_lines < lines_len; i_lines++) {
-				gs_free char *text_to_free = NULL;
-				const char *text;
-
-				text = colorize_string (nmc_config, cell->color, lines[i_lines], &text_to_free);
-				if (nmc_config->multiline_output) {
-					gs_free char *prefix = NULL;
-
-					if (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_STRV)
-						prefix = g_strdup_printf ("%s[%u]:", cell->header_cell->title, i_lines + 1);
-					else
-						prefix = g_strdup_printf ("%s:", cell->header_cell->title);
-					width1 = strlen (prefix);
-					width2 = nmc_string_screen_width (prefix, NULL);
-					g_print ("%-*s%s\n",
-					         (int) (  nmc_config->print_output == NMC_PRINT_TERSE
-					               ? 0
-					               : ML_VALUE_INDENT+width1-width2),
-					         prefix,
-					         text);
-				} else {
-					nm_assert (str);
-					if (nmc_config->print_output == NMC_PRINT_TERSE) {
-						if (nmc_config->escape_values) {
-							const char *p = text;
-							while (*p) {
-								if (*p == ':' || *p == '\\')
-									g_string_append_c (str, '\\');  /* Escaping by '\' */
-								g_string_append_c (str, *p);
-								p++;
-							}
-						}
-						else
-							g_string_append_printf (str, "%s", text);
-						g_string_append_c (str, ':');  /* Column separator */
-					} else {
-						const PrintDataHeaderCell *header_cell = &header_row[i_col];
-
-						width1 = strlen (text);
-						width2 = nmc_string_screen_width (text, NULL);  /* Width of the string (in screen columns) */
-						g_string_append_printf (str, "%-*s", (int) (header_cell->width + width1 - width2), text);
-						g_string_append_c (str, ' ');  /* Column separator */
-						table_width += header_cell->width + width1 - width2 + 1;
-					}
-				}
-			}
-		}
-
-		if (!nmc_config->multiline_output) {
-			if (str->len)
-				g_string_truncate (str, str->len-1);  /* Chop off last column separator */
-			g_print ("%s\n", str->str);
-
-			g_string_truncate (str, 0);
-		}
-
-		if (   nmc_config->print_output == NMC_PRINT_PRETTY
-		    && nmc_config->multiline_output) {
-			gs_free char *line = NULL;
-
-			g_print ("%s\n", (line = g_strnfill (ML_HEADER_WIDTH, '-')));
-		}
-	}
+    int                  width1, width2;
+    int                  table_width = 0;
+    guint                i_row, i_col;
+    nm_auto_free_gstring GString *str = NULL;
+
+    g_assert(col_len);
+
+    /* Main header */
+    if (nmc_config->print_output == NMC_PRINT_PRETTY && header_name_no_l10n) {
+        gs_free char *line = NULL;
+        int           header_width;
+        const char *  header_name = _(header_name_no_l10n);
+
+        header_width = nmc_string_screen_width(header_name, NULL) + 4;
+
+        if (nmc_config->multiline_output) {
+            table_width = NM_MAX(header_width, ML_HEADER_WIDTH);
+            line        = g_strnfill(ML_HEADER_WIDTH, '=');
+        } else { /* tabular */
+            table_width = NM_MAX(table_width, header_width);
+            line        = g_strnfill(table_width, '=');
+        }
+
+        width1 = strlen(header_name);
+        width2 = nmc_string_screen_width(header_name, NULL);
+        g_print("%s\n", line);
+        g_print("%*s\n", (table_width + width2) / 2 + width1 - width2, header_name);
+        g_print("%s\n", line);
+    }
+
+    str = !nmc_config->multiline_output ? g_string_sized_new(100) : NULL;
+
+    /* print the header for the tabular form */
+    if (NM_IN_SET(nmc_config->print_output, NMC_PRINT_NORMAL, NMC_PRINT_PRETTY)
+        && !nmc_config->multiline_output) {
+        for (i_col = 0; i_col < col_len; i_col++) {
+            const PrintDataHeaderCell *header_cell = &header_row[i_col];
+            const char *               title;
+
+            if (_print_skip_column(nmc_config, header_cell))
+                continue;
+
+            title = header_cell->title;
+
+            width1 = strlen(title);
+            width2 =
+                nmc_string_screen_width(title, NULL); /* Width of the string (in screen columns) */
+            g_string_append_printf(str,
+                                   "%-*s",
+                                   (int) (header_cell->width + width1 - width2),
+                                   title);
+            g_string_append_c(str, ' '); /* Column separator */
+            table_width += header_cell->width + width1 - width2 + 1;
+        }
+
+        if (str->len)
+            g_string_truncate(str, str->len - 1); /* Chop off last column separator */
+        g_print("%s\n", str->str);
+        g_string_truncate(str, 0);
+
+        /* Print horizontal separator */
+        if (nmc_config->print_output == NMC_PRINT_PRETTY) {
+            gs_free char *line = NULL;
+
+            g_print("%s\n", (line = g_strnfill(table_width, '-')));
+        }
+    }
+
+    for (i_row = 0; i_row < row_len; i_row++) {
+        const PrintDataCell *current_line = &cells[i_row * col_len];
+
+        for (i_col = 0; i_col < col_len; i_col++) {
+            const PrintDataCell *cell  = &current_line[i_col];
+            const char *const *  lines = NULL;
+            guint                i_lines, lines_len;
+
+            if (_print_skip_column(nmc_config, cell->header_cell))
+                continue;
+
+            lines_len = 0;
+            switch (cell->text_format) {
+            case PRINT_DATA_CELL_FORMAT_TYPE_PLAIN:
+                lines     = &cell->text.plain;
+                lines_len = 1;
+                break;
+            case PRINT_DATA_CELL_FORMAT_TYPE_STRV:
+                nm_assert(nmc_config->multiline_output);
+                lines     = cell->text.strv;
+                lines_len = NM_PTRARRAY_LEN(lines);
+                break;
+            }
+
+            for (i_lines = 0; i_lines < lines_len; i_lines++) {
+                gs_free char *text_to_free = NULL;
+                const char *  text;
+
+                text = colorize_string(nmc_config, cell->color, lines[i_lines], &text_to_free);
+                if (nmc_config->multiline_output) {
+                    gs_free char *prefix = NULL;
+
+                    if (cell->text_format == PRINT_DATA_CELL_FORMAT_TYPE_STRV)
+                        prefix = g_strdup_printf("%s[%u]:", cell->header_cell->title, i_lines + 1);
+                    else
+                        prefix = g_strdup_printf("%s:", cell->header_cell->title);
+                    width1 = strlen(prefix);
+                    width2 = nmc_string_screen_width(prefix, NULL);
+                    g_print("%-*s%s\n",
+                            (int) (nmc_config->print_output == NMC_PRINT_TERSE
+                                       ? 0
+                                       : ML_VALUE_INDENT + width1 - width2),
+                            prefix,
+                            text);
+                } else {
+                    nm_assert(str);
+                    if (nmc_config->print_output == NMC_PRINT_TERSE) {
+                        if (nmc_config->escape_values) {
+                            const char *p = text;
+                            while (*p) {
+                                if (*p == ':' || *p == '\\')
+                                    g_string_append_c(str, '\\'); /* Escaping by '\' */
+                                g_string_append_c(str, *p);
+                                p++;
+                            }
+                        } else
+                            g_string_append_printf(str, "%s", text);
+                        g_string_append_c(str, ':'); /* Column separator */
+                    } else {
+                        const PrintDataHeaderCell *header_cell = &header_row[i_col];
+
+                        width1 = strlen(text);
+                        width2 = nmc_string_screen_width(
+                            text,
+                            NULL); /* Width of the string (in screen columns) */
+                        g_string_append_printf(str,
+                                               "%-*s",
+                                               (int) (header_cell->width + width1 - width2),
+                                               text);
+                        g_string_append_c(str, ' '); /* Column separator */
+                        table_width += header_cell->width + width1 - width2 + 1;
+                    }
+                }
+            }
+        }
+
+        if (!nmc_config->multiline_output) {
+            if (str->len)
+                g_string_truncate(str, str->len - 1); /* Chop off last column separator */
+            g_print("%s\n", str->str);
+
+            g_string_truncate(str, 0);
+        }
+
+        if (nmc_config->print_output == NMC_PRINT_PRETTY && nmc_config->multiline_output) {
+            gs_free char *line = NULL;
+
+            g_print("%s\n", (line = g_strnfill(ML_HEADER_WIDTH, '-')));
+        }
+    }
 }
 
 gboolean
-nmc_print (const NmcConfig *nmc_config,
-           gpointer const *targets,
-           gpointer targets_data,
-           const char *header_name_no_l10n,
-           const NMMetaAbstractInfo *const*fields,
-           const char *fields_str,
-           GError **error)
+nmc_print(const NmcConfig *                nmc_config,
+          gpointer const *                 targets,
+          gpointer                         targets_data,
+          const char *                     header_name_no_l10n,
+          const NMMetaAbstractInfo *const *fields,
+          const char *                     fields_str,
+          GError **                        error)
 {
-	gs_unref_ptrarray GPtrArray *gfree_keeper = NULL;
-	gs_free PrintDataCol *cols_data = NULL;
-	guint cols_len;
-	gs_unref_array GArray *header_row = NULL;
-	gs_unref_array GArray *cells = NULL;
-
-	if (!_output_selection_parse (fields,
-	                              fields_str,
-	                              &cols_data,
-	                              &cols_len,
-	                              &gfree_keeper,
-	                              error))
-		return FALSE;
-
-	_print_fill (nmc_config,
-	             targets,
-	             targets_data,
-	             cols_data,
-	             cols_len,
-	             &header_row,
-	             &cells);
-
-	_print_do (nmc_config,
-	           header_name_no_l10n,
-	           header_row->len,
-	           cells->len / header_row->len,
-	           &g_array_index (header_row, PrintDataHeaderCell, 0),
-	           &g_array_index (cells, PrintDataCell, 0));
-
-	return TRUE;
+    gs_unref_ptrarray GPtrArray *gfree_keeper = NULL;
+    gs_free PrintDataCol *cols_data           = NULL;
+    guint                 cols_len;
+    gs_unref_array GArray *header_row = NULL;
+    gs_unref_array GArray *cells      = NULL;
+
+    if (!_output_selection_parse(fields, fields_str, &cols_data, &cols_len, &gfree_keeper, error))
+        return FALSE;
+
+    _print_fill(nmc_config, targets, targets_data, cols_data, cols_len, &header_row, &cells);
+
+    _print_do(nmc_config,
+              header_name_no_l10n,
+              header_row->len,
+              cells->len / header_row->len,
+              &g_array_index(header_row, PrintDataHeaderCell, 0),
+              &g_array_index(cells, PrintDataCell, 0));
+
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 static void
-pager_fallback (void)
+pager_fallback(void)
 {
-	char buf[64];
-	int rb;
-	int errsv;
-
-	do {
-		rb = read (STDIN_FILENO, buf, sizeof (buf));
-		if (rb == -1) {
-			errsv = errno;
-			if (errsv == EINTR)
-				continue;
-			g_printerr (_("Error reading nmcli output: %s\n"), nm_strerror_native (errsv));
-			_exit(EXIT_FAILURE);
-		}
-		if (write (STDOUT_FILENO, buf, rb) == -1) {
-			errsv = errno;
-			g_printerr (_("Error writing nmcli output: %s\n"), nm_strerror_native (errsv));
-			_exit(EXIT_FAILURE);
-		}
-	} while (rb > 0);
-
-	_exit(EXIT_SUCCESS);
+    char buf[64];
+    int  rb;
+    int  errsv;
+
+    do {
+        rb = read(STDIN_FILENO, buf, sizeof(buf));
+        if (rb == -1) {
+            errsv = errno;
+            if (errsv == EINTR)
+                continue;
+            g_printerr(_("Error reading nmcli output: %s\n"), nm_strerror_native(errsv));
+            _exit(EXIT_FAILURE);
+        }
+        if (write(STDOUT_FILENO, buf, rb) == -1) {
+            errsv = errno;
+            g_printerr(_("Error writing nmcli output: %s\n"), nm_strerror_native(errsv));
+            _exit(EXIT_FAILURE);
+        }
+    } while (rb > 0);
+
+    _exit(EXIT_SUCCESS);
 }
 
 pid_t
-nmc_terminal_spawn_pager (const NmcConfig *nmc_config)
+nmc_terminal_spawn_pager(const NmcConfig *nmc_config)
 {
-	const char *pager = getenv ("PAGER");
-	pid_t pager_pid;
-	pid_t parent_pid;
-	int fd[2];
-	int errsv;
-
-	if (   nmc_config->in_editor
-	    || nmc_config->print_output == NMC_PRINT_TERSE
-	    || !nmc_config->use_colors
-	    || g_strcmp0 (pager, "") == 0
-	    || getauxval (AT_SECURE))
-		return 0;
-
-	if (pipe (fd) == -1) {
-		errsv = errno;
-		g_printerr (_("Failed to create pager pipe: %s\n"), nm_strerror_native (errsv));
-		return 0;
-	}
-
-	parent_pid = getpid ();
-
-	pager_pid = fork ();
-	if (pager_pid == -1) {
-		errsv = errno;
-		g_printerr (_("Failed to fork pager: %s\n"), nm_strerror_native (errsv));
-		nm_close (fd[0]);
-		nm_close (fd[1]);
-		return 0;
-	}
-
-	/* In the child start the pager */
-	if (pager_pid == 0) {
-		dup2 (fd[0], STDIN_FILENO);
-		nm_close (fd[0]);
-		nm_close (fd[1]);
-
-		setenv ("LESS", "FRSXMK", 1);
-		setenv ("LESSCHARSET", "utf-8", 1);
-
-		/* Make sure the pager goes away when the parent dies */
-		if (prctl (PR_SET_PDEATHSIG, SIGTERM) < 0)
-			_exit (EXIT_FAILURE);
-
-		/* Check whether our parent died before we were able
-		 * to set the death signal */
-		if (getppid () != parent_pid)
-			_exit (EXIT_SUCCESS);
-
-		if (pager) {
-			execlp (pager, pager, NULL);
-			execl ("/bin/sh", "sh", "-c", pager, NULL);
-		}
-
-		/* Debian's alternatives command for pagers is
-		 * called 'pager'. Note that we do not call
-		 * sensible-pagers here, since that is just a
-		 * shell script that implements a logic that
-		 * is similar to this one anyway, but is
-		 * Debian-specific. */
-		execlp ("pager", "pager", NULL);
-
-		execlp ("less", "less", NULL);
-		execlp ("more", "more", NULL);
-
-		pager_fallback ();
-		/* not reached */
-	}
-
-	/* Return in the parent */
-	if (dup2 (fd[1], STDOUT_FILENO) < 0) {
-		errsv = errno;
-		g_printerr (_("Failed to duplicate pager pipe: %s\n"), nm_strerror_native (errsv));
-	}
-	if (dup2 (fd[1], STDERR_FILENO) < 0) {
-		errsv = errno;
-		g_printerr (_("Failed to duplicate pager pipe: %s\n"), nm_strerror_native (errsv));
-	}
-
-	nm_close (fd[0]);
-	nm_close (fd[1]);
-	return pager_pid;
+    const char *pager = getenv("PAGER");
+    pid_t       pager_pid;
+    pid_t       parent_pid;
+    int         fd[2];
+    int         errsv;
+
+    if (nmc_config->in_editor || nmc_config->print_output == NMC_PRINT_TERSE
+        || !nmc_config->use_colors || g_strcmp0(pager, "") == 0 || getauxval(AT_SECURE))
+        return 0;
+
+    if (pipe(fd) == -1) {
+        errsv = errno;
+        g_printerr(_("Failed to create pager pipe: %s\n"), nm_strerror_native(errsv));
+        return 0;
+    }
+
+    parent_pid = getpid();
+
+    pager_pid = fork();
+    if (pager_pid == -1) {
+        errsv = errno;
+        g_printerr(_("Failed to fork pager: %s\n"), nm_strerror_native(errsv));
+        nm_close(fd[0]);
+        nm_close(fd[1]);
+        return 0;
+    }
+
+    /* In the child start the pager */
+    if (pager_pid == 0) {
+        dup2(fd[0], STDIN_FILENO);
+        nm_close(fd[0]);
+        nm_close(fd[1]);
+
+        setenv("LESS", "FRSXMK", 1);
+        setenv("LESSCHARSET", "utf-8", 1);
+
+        /* Make sure the pager goes away when the parent dies */
+        if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+            _exit(EXIT_FAILURE);
+
+        /* Check whether our parent died before we were able
+         * to set the death signal */
+        if (getppid() != parent_pid)
+            _exit(EXIT_SUCCESS);
+
+        if (pager) {
+            execlp(pager, pager, NULL);
+            execl("/bin/sh", "sh", "-c", pager, NULL);
+        }
+
+        /* Debian's alternatives command for pagers is
+         * called 'pager'. Note that we do not call
+         * sensible-pagers here, since that is just a
+         * shell script that implements a logic that
+         * is similar to this one anyway, but is
+         * Debian-specific. */
+        execlp("pager", "pager", NULL);
+
+        execlp("less", "less", NULL);
+        execlp("more", "more", NULL);
+
+        pager_fallback();
+        /* not reached */
+    }
+
+    /* Return in the parent */
+    if (dup2(fd[1], STDOUT_FILENO) < 0) {
+        errsv = errno;
+        g_printerr(_("Failed to duplicate pager pipe: %s\n"), nm_strerror_native(errsv));
+    }
+    if (dup2(fd[1], STDERR_FILENO) < 0) {
+        errsv = errno;
+        g_printerr(_("Failed to duplicate pager pipe: %s\n"), nm_strerror_native(errsv));
+    }
+
+    nm_close(fd[0]);
+    nm_close(fd[1]);
+    return pager_pid;
 }
 
 /*****************************************************************************/
 
 static const char *
-get_value_to_print (const NmcConfig *nmc_config,
-                    const NmcOutputField *field,
-                    gboolean field_name,
-                    const char *not_set_str,
-                    char **out_to_free)
+get_value_to_print(const NmcConfig *     nmc_config,
+                   const NmcOutputField *field,
+                   gboolean              field_name,
+                   const char *          not_set_str,
+                   char **               out_to_free)
 {
-	gboolean is_array = field->value_is_array;
-	const char *value;
-	const char *out;
-	gs_free char *free_value = NULL;
-
-	nm_assert (out_to_free && !*out_to_free);
-
-	if (field_name)
-		value = nm_meta_abstract_info_get_name (field->info, FALSE);
-	else {
-		value = field->value
-		            ? (is_array
-		                  ? (free_value = g_strjoinv (" | ", (char **) field->value))
-		                  : (*((const char *) field->value))
-		                        ? field->value
-		                        : not_set_str)
-		            : not_set_str;
-	}
-
-	/* colorize the value */
-	out = colorize_string (nmc_config, field->color, value, out_to_free);
-
-	if (out && out == free_value) {
-		nm_assert (!*out_to_free);
-		*out_to_free = g_steal_pointer (&free_value);
-	}
-
-	return out;
+    gboolean      is_array = field->value_is_array;
+    const char *  value;
+    const char *  out;
+    gs_free char *free_value = NULL;
+
+    nm_assert(out_to_free && !*out_to_free);
+
+    if (field_name)
+        value = nm_meta_abstract_info_get_name(field->info, FALSE);
+    else {
+        value = field->value ? (is_array ? (free_value = g_strjoinv(" | ", (char **) field->value))
+                                : (*((const char *) field->value)) ? field->value
+                                                                   : not_set_str)
+                             : not_set_str;
+    }
+
+    /* colorize the value */
+    out = colorize_string(nmc_config, field->color, value, out_to_free);
+
+    if (out && out == free_value) {
+        nm_assert(!*out_to_free);
+        *out_to_free = g_steal_pointer(&free_value);
+    }
+
+    return out;
 }
 
 /*
@@ -1570,251 +1571,253 @@ get_value_to_print (const NmcConfig *nmc_config,
  * of 'field_values' array.
  */
 void
-print_required_fields (const NmcConfig *nmc_config,
-                       NmcPagerData *pager_data,
-                       NmcOfFlags of_flags,
-                       const GArray *indices,
-                       const char *header_name,
-                       int indent,
-                       const NmcOutputField *field_values)
+print_required_fields(const NmcConfig *     nmc_config,
+                      NmcPagerData *        pager_data,
+                      NmcOfFlags            of_flags,
+                      const GArray *        indices,
+                      const char *          header_name,
+                      int                   indent,
+                      const NmcOutputField *field_values)
 {
-	nm_auto_free_gstring GString *str = NULL;
-	int width1, width2;
-	int table_width = 0;
-	const char *not_set_str;
-	int i;
-	gboolean main_header_add = of_flags & NMC_OF_FLAG_MAIN_HEADER_ADD;
-	gboolean main_header_only = of_flags & NMC_OF_FLAG_MAIN_HEADER_ONLY;
-	gboolean field_names = of_flags & NMC_OF_FLAG_FIELD_NAMES;
-	gboolean section_prefix = of_flags & NMC_OF_FLAG_SECTION_PREFIX;
-
-	nm_cli_spawn_pager (nmc_config, pager_data);
-
-	/* --- Main header --- */
-	if (   nmc_config->print_output == NMC_PRINT_PRETTY
-	    && (   main_header_add
-	        || main_header_only)) {
-		gs_free char *line = NULL;
-		int header_width;
-
-		header_width = nmc_string_screen_width (header_name, NULL) + 4;
-
-		if (nmc_config->multiline_output) {
-			table_width = NM_MAX (header_width, ML_HEADER_WIDTH);
-			line = g_strnfill (ML_HEADER_WIDTH, '=');
-		} else { /* tabular */
-			table_width = NM_MAX (table_width, header_width);
-			line = g_strnfill (table_width, '=');
-		}
-
-		width1 = strlen (header_name);
-		width2 = nmc_string_screen_width (header_name, NULL);
-		g_print ("%s\n", line);
-		g_print ("%*s\n", (table_width + width2)/2 + width1 - width2, header_name);
-		g_print ("%s\n", line);
-	}
-
-	if (main_header_only)
-		return;
-
-	/* No field headers are printed in terse mode nor for multiline output */
-	if (   (   nmc_config->print_output == NMC_PRINT_TERSE
-	        || nmc_config->multiline_output)
-	    && field_names)
-		return;
-
-	/* Don't replace empty strings in terse mode */
-	not_set_str = nmc_config->print_output == NMC_PRINT_TERSE ? "" : "--";
-
-	if (nmc_config->multiline_output) {
-		for (i = 0; i < indices->len; i++) {
-			int idx = g_array_index (indices, int, i);
-			gboolean is_array = field_values[idx].value_is_array;
-
-			/* section prefix can't be an array */
-			g_assert (!is_array || !section_prefix || idx != 0);
-
-			if (section_prefix && idx == 0)  /* The first field is section prefix */
-				continue;
-
-			if (is_array) {
-				gs_free char *val_to_free = NULL;
-				const char **p, *val, *print_val;
-				int j;
-
-				/* value is a null-terminated string array */
-
-				for (p = (const char **) field_values[idx].value, j = 1; p && *p; p++, j++) {
-					gs_free char *tmp = NULL;
-
-					val = *p ?: not_set_str;
-					print_val = colorize_string (nmc_config, field_values[idx].color,
-					                             val, &val_to_free);
-					tmp = g_strdup_printf ("%s%s%s[%d]:",
-					                       section_prefix ? (const char*) field_values[0].value : "",
-					                       section_prefix ? "." : "",
-					                       nm_meta_abstract_info_get_name (field_values[idx].info, FALSE),
-					                       j);
-					width1 = strlen (tmp);
-					width2 = nmc_string_screen_width (tmp, NULL);
-					g_print ("%-*s%s\n",
-					         (int) (nmc_config->print_output == NMC_PRINT_TERSE
-					                ? 0
-					                : ML_VALUE_INDENT + width1 - width2),
-					         tmp,
-					         print_val);
-				}
-			} else {
-				gs_free char *val_to_free = NULL;
-				gs_free char *tmp = NULL;
-				const char *hdr_name = (const char*) field_values[0].value;
-				const char *val = (const char*) field_values[idx].value;
-				const char *print_val;
-
-				/* value is a string */
-
-				val = val && *val ? val : not_set_str;
-				print_val = colorize_string (nmc_config, field_values[idx].color,
-				                             val, &val_to_free);
-				tmp = g_strdup_printf ("%s%s%s:",
-				                       section_prefix ? hdr_name : "",
-				                       section_prefix ? "." : "",
-				                       nm_meta_abstract_info_get_name (field_values[idx].info, FALSE));
-				width1 = strlen (tmp);
-				width2 = nmc_string_screen_width (tmp, NULL);
-				g_print ("%-*s%s\n",
-				         (int) (  nmc_config->print_output == NMC_PRINT_TERSE
-				                ? 0
-				                : ML_VALUE_INDENT + width1 - width2),
-				         tmp,
-				         print_val);
-			}
-		}
-		if (nmc_config->print_output == NMC_PRINT_PRETTY) {
-			gs_free char *line = NULL;
-
-			g_print ("%s\n", (line = g_strnfill (ML_HEADER_WIDTH, '-')));
-		}
-
-		return;
-	}
-
-	/* --- Tabular mode: each line = one object --- */
-
-	str = g_string_new (NULL);
-
-	for (i = 0; i < indices->len; i++) {
-		gs_free char *val_to_free = NULL;
-		int idx;
-		const char *value;
-
-		idx = g_array_index (indices, int, i);
-
-		value = get_value_to_print (nmc_config, (NmcOutputField *) field_values+idx, field_names,
-		                            not_set_str, &val_to_free);
-
-		if (nmc_config->print_output == NMC_PRINT_TERSE) {
-			if (nmc_config->escape_values) {
-				const char *p = value;
-				while (*p) {
-					if (*p == ':' || *p == '\\')
-						g_string_append_c (str, '\\');  /* Escaping by '\' */
-					g_string_append_c (str, *p);
-					p++;
-				}
-			}
-			else
-				g_string_append_printf (str, "%s", value);
-			g_string_append_c (str, ':');  /* Column separator */
-		} else {
-			width1 = strlen (value);
-			width2 = nmc_string_screen_width (value, NULL);  /* Width of the string (in screen columns) */
-			g_string_append_printf (str, "%-*s", field_values[idx].width + width1 - width2, strlen (value) > 0 ? value : not_set_str);
-			g_string_append_c (str, ' ');  /* Column separator */
-			table_width += field_values[idx].width + width1 - width2 + 1;
-		}
-	}
-
-	/* Print actual values */
-	if (str->len > 0) {
-		g_string_truncate (str, str->len-1);  /* Chop off last column separator */
-		if (indent > 0) {
-			gs_free char *indent_str = NULL;
-
-			g_string_prepend (str, (indent_str = g_strnfill (indent, ' ')));
-		}
-
-		g_print ("%s\n", str->str);
-
-		/* Print horizontal separator */
-		if (   nmc_config->print_output == NMC_PRINT_PRETTY
-		    && field_names) {
-			gs_free char *line = NULL;
-
-			g_print ("%s\n", (line = g_strnfill (table_width, '-')));
-		}
-	}
+    nm_auto_free_gstring GString *str = NULL;
+    int                           width1, width2;
+    int                           table_width = 0;
+    const char *                  not_set_str;
+    int                           i;
+    gboolean                      main_header_add  = of_flags & NMC_OF_FLAG_MAIN_HEADER_ADD;
+    gboolean                      main_header_only = of_flags & NMC_OF_FLAG_MAIN_HEADER_ONLY;
+    gboolean                      field_names      = of_flags & NMC_OF_FLAG_FIELD_NAMES;
+    gboolean                      section_prefix   = of_flags & NMC_OF_FLAG_SECTION_PREFIX;
+
+    nm_cli_spawn_pager(nmc_config, pager_data);
+
+    /* --- Main header --- */
+    if (nmc_config->print_output == NMC_PRINT_PRETTY && (main_header_add || main_header_only)) {
+        gs_free char *line = NULL;
+        int           header_width;
+
+        header_width = nmc_string_screen_width(header_name, NULL) + 4;
+
+        if (nmc_config->multiline_output) {
+            table_width = NM_MAX(header_width, ML_HEADER_WIDTH);
+            line        = g_strnfill(ML_HEADER_WIDTH, '=');
+        } else { /* tabular */
+            table_width = NM_MAX(table_width, header_width);
+            line        = g_strnfill(table_width, '=');
+        }
+
+        width1 = strlen(header_name);
+        width2 = nmc_string_screen_width(header_name, NULL);
+        g_print("%s\n", line);
+        g_print("%*s\n", (table_width + width2) / 2 + width1 - width2, header_name);
+        g_print("%s\n", line);
+    }
+
+    if (main_header_only)
+        return;
+
+    /* No field headers are printed in terse mode nor for multiline output */
+    if ((nmc_config->print_output == NMC_PRINT_TERSE || nmc_config->multiline_output)
+        && field_names)
+        return;
+
+    /* Don't replace empty strings in terse mode */
+    not_set_str = nmc_config->print_output == NMC_PRINT_TERSE ? "" : "--";
+
+    if (nmc_config->multiline_output) {
+        for (i = 0; i < indices->len; i++) {
+            int      idx      = g_array_index(indices, int, i);
+            gboolean is_array = field_values[idx].value_is_array;
+
+            /* section prefix can't be an array */
+            g_assert(!is_array || !section_prefix || idx != 0);
+
+            if (section_prefix && idx == 0) /* The first field is section prefix */
+                continue;
+
+            if (is_array) {
+                gs_free char *val_to_free = NULL;
+                const char ** p, *val, *print_val;
+                int           j;
+
+                /* value is a null-terminated string array */
+
+                for (p = (const char **) field_values[idx].value, j = 1; p && *p; p++, j++) {
+                    gs_free char *tmp = NULL;
+
+                    val = *p ?: not_set_str;
+                    print_val =
+                        colorize_string(nmc_config, field_values[idx].color, val, &val_to_free);
+                    tmp = g_strdup_printf(
+                        "%s%s%s[%d]:",
+                        section_prefix ? (const char *) field_values[0].value : "",
+                        section_prefix ? "." : "",
+                        nm_meta_abstract_info_get_name(field_values[idx].info, FALSE),
+                        j);
+                    width1 = strlen(tmp);
+                    width2 = nmc_string_screen_width(tmp, NULL);
+                    g_print("%-*s%s\n",
+                            (int) (nmc_config->print_output == NMC_PRINT_TERSE
+                                       ? 0
+                                       : ML_VALUE_INDENT + width1 - width2),
+                            tmp,
+                            print_val);
+                }
+            } else {
+                gs_free char *val_to_free = NULL;
+                gs_free char *tmp         = NULL;
+                const char *  hdr_name    = (const char *) field_values[0].value;
+                const char *  val         = (const char *) field_values[idx].value;
+                const char *  print_val;
+
+                /* value is a string */
+
+                val       = val && *val ? val : not_set_str;
+                print_val = colorize_string(nmc_config, field_values[idx].color, val, &val_to_free);
+                tmp =
+                    g_strdup_printf("%s%s%s:",
+                                    section_prefix ? hdr_name : "",
+                                    section_prefix ? "." : "",
+                                    nm_meta_abstract_info_get_name(field_values[idx].info, FALSE));
+                width1 = strlen(tmp);
+                width2 = nmc_string_screen_width(tmp, NULL);
+                g_print("%-*s%s\n",
+                        (int) (nmc_config->print_output == NMC_PRINT_TERSE
+                                   ? 0
+                                   : ML_VALUE_INDENT + width1 - width2),
+                        tmp,
+                        print_val);
+            }
+        }
+        if (nmc_config->print_output == NMC_PRINT_PRETTY) {
+            gs_free char *line = NULL;
+
+            g_print("%s\n", (line = g_strnfill(ML_HEADER_WIDTH, '-')));
+        }
+
+        return;
+    }
+
+    /* --- Tabular mode: each line = one object --- */
+
+    str = g_string_new(NULL);
+
+    for (i = 0; i < indices->len; i++) {
+        gs_free char *val_to_free = NULL;
+        int           idx;
+        const char *  value;
+
+        idx = g_array_index(indices, int, i);
+
+        value = get_value_to_print(nmc_config,
+                                   (NmcOutputField *) field_values + idx,
+                                   field_names,
+                                   not_set_str,
+                                   &val_to_free);
+
+        if (nmc_config->print_output == NMC_PRINT_TERSE) {
+            if (nmc_config->escape_values) {
+                const char *p = value;
+                while (*p) {
+                    if (*p == ':' || *p == '\\')
+                        g_string_append_c(str, '\\'); /* Escaping by '\' */
+                    g_string_append_c(str, *p);
+                    p++;
+                }
+            } else
+                g_string_append_printf(str, "%s", value);
+            g_string_append_c(str, ':'); /* Column separator */
+        } else {
+            width1 = strlen(value);
+            width2 =
+                nmc_string_screen_width(value, NULL); /* Width of the string (in screen columns) */
+            g_string_append_printf(str,
+                                   "%-*s",
+                                   field_values[idx].width + width1 - width2,
+                                   strlen(value) > 0 ? value : not_set_str);
+            g_string_append_c(str, ' '); /* Column separator */
+            table_width += field_values[idx].width + width1 - width2 + 1;
+        }
+    }
+
+    /* Print actual values */
+    if (str->len > 0) {
+        g_string_truncate(str, str->len - 1); /* Chop off last column separator */
+        if (indent > 0) {
+            gs_free char *indent_str = NULL;
+
+            g_string_prepend(str, (indent_str = g_strnfill(indent, ' ')));
+        }
+
+        g_print("%s\n", str->str);
+
+        /* Print horizontal separator */
+        if (nmc_config->print_output == NMC_PRINT_PRETTY && field_names) {
+            gs_free char *line = NULL;
+
+            g_print("%s\n", (line = g_strnfill(table_width, '-')));
+        }
+    }
 }
 
 void
-print_data_prepare_width (GPtrArray *output_data)
+print_data_prepare_width(GPtrArray *output_data)
 {
-	int i, j;
-	size_t len;
-	NmcOutputField *row;
-	int num_fields = 0;
-
-	if (!output_data || output_data->len < 1)
-		return;
-
-	/* How many fields? */
-	row = g_ptr_array_index (output_data, 0);
-	while (row->info) {
-		num_fields++;
-		row++;
-	}
-
-	/* Find out maximal string lengths */
-	for (i = 0; i < num_fields; i++) {
-		size_t max_width = 0;
-		for (j = 0; j < output_data->len; j++) {
-			gboolean field_names;
-			gs_free char * val_to_free = NULL;
-			const char *value;
-
-			row = g_ptr_array_index (output_data, j);
-			field_names = row[0].flags & NMC_OF_FLAG_FIELD_NAMES;
-			value = get_value_to_print (NULL, row+i, field_names, "--", &val_to_free);
-			len = nmc_string_screen_width (value, NULL);
-			max_width = len > max_width ? len : max_width;
-		}
-		for (j = 0; j < output_data->len; j++) {
-			row = g_ptr_array_index (output_data, j);
-			row[i].width = max_width + 1;
-		}
-	}
+    int             i, j;
+    size_t          len;
+    NmcOutputField *row;
+    int             num_fields = 0;
+
+    if (!output_data || output_data->len < 1)
+        return;
+
+    /* How many fields? */
+    row = g_ptr_array_index(output_data, 0);
+    while (row->info) {
+        num_fields++;
+        row++;
+    }
+
+    /* Find out maximal string lengths */
+    for (i = 0; i < num_fields; i++) {
+        size_t max_width = 0;
+        for (j = 0; j < output_data->len; j++) {
+            gboolean      field_names;
+            gs_free char *val_to_free = NULL;
+            const char *  value;
+
+            row         = g_ptr_array_index(output_data, j);
+            field_names = row[0].flags & NMC_OF_FLAG_FIELD_NAMES;
+            value       = get_value_to_print(NULL, row + i, field_names, "--", &val_to_free);
+            len         = nmc_string_screen_width(value, NULL);
+            max_width   = len > max_width ? len : max_width;
+        }
+        for (j = 0; j < output_data->len; j++) {
+            row          = g_ptr_array_index(output_data, j);
+            row[i].width = max_width + 1;
+        }
+    }
 }
 
 void
-print_data (const NmcConfig *nmc_config,
-            NmcPagerData *pager_data,
-            const GArray *indices,
-            const char *header_name,
-            int indent,
-            const NmcOutputData *out)
+print_data(const NmcConfig *    nmc_config,
+           NmcPagerData *       pager_data,
+           const GArray *       indices,
+           const char *         header_name,
+           int                  indent,
+           const NmcOutputData *out)
 {
-	guint i;
-
-	for (i = 0; i < out->output_data->len; i++) {
-		const NmcOutputField *field_values = g_ptr_array_index (out->output_data, i);
-
-		print_required_fields (nmc_config,
-		                       pager_data,
-		                       field_values[0].flags,
-		                       indices,
-		                       header_name,
-		                       indent,
-		                       field_values);
-	}
+    guint i;
+
+    for (i = 0; i < out->output_data->len; i++) {
+        const NmcOutputField *field_values = g_ptr_array_index(out->output_data, i);
+
+        print_required_fields(nmc_config,
+                              pager_data,
+                              field_values[0].flags,
+                              indices,
+                              header_name,
+                              indent,
+                              field_values);
+    }
 }
-