diff options
-rw-r--r-- | clients/cli/common.c | 32 | ||||
-rw-r--r-- | clients/cli/common.h | 1 | ||||
-rw-r--r-- | clients/cli/connections.c | 69 | ||||
-rw-r--r-- | clients/cli/nmcli.h | 2 | ||||
-rw-r--r-- | clients/common/nm-meta-setting-desc.c | 34 | ||||
-rw-r--r-- | clients/common/nm-meta-setting-desc.h | 2 |
6 files changed, 90 insertions, 50 deletions
diff --git a/clients/cli/common.c b/clients/cli/common.c index 8738cef7b6..e37d9d8c8b 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -1126,6 +1126,38 @@ nmc_rl_gen_func_basic (const char *text, int state, const char *const*words) return NULL; } +static struct { + bool initialized; + guint idx; + char **values; +} _rl_compentry_func_wrap = { 0 }; + +static char * +_rl_compentry_func_wrap_fcn (const char *text, int state) +{ + g_return_val_if_fail (_rl_compentry_func_wrap.initialized, NULL); + + if ( !_rl_compentry_func_wrap.values + || !_rl_compentry_func_wrap.values[_rl_compentry_func_wrap.idx]) { + g_strfreev (_rl_compentry_func_wrap.values); + _rl_compentry_func_wrap.values = NULL; + _rl_compentry_func_wrap.initialized = FALSE; + return NULL; + } + + return g_strdup (_rl_compentry_func_wrap.values[_rl_compentry_func_wrap.idx++]); +} + +NmcCompEntryFunc +nmc_rl_compentry_func_wrap (const char *const*values) +{ + g_strfreev (_rl_compentry_func_wrap.values); + _rl_compentry_func_wrap.values = g_strdupv ((char **) values); + _rl_compentry_func_wrap.idx = 0; + _rl_compentry_func_wrap.initialized = TRUE; + return _rl_compentry_func_wrap_fcn; +} + char * nmc_rl_gen_func_ifnames (const char *text, int state) { diff --git a/clients/cli/common.h b/clients/cli/common.h index 4f0f1b1ddb..b7057e462f 100644 --- a/clients/cli/common.h +++ b/clients/cli/common.h @@ -53,6 +53,7 @@ char *nmc_unique_connection_name (const GPtrArray *connections, void nmc_cleanup_readline (void); char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2); char *nmc_readline_echo (gboolean echo_on, const char *prompt_fmt, ...) G_GNUC_PRINTF (2, 3); +NmcCompEntryFunc nmc_rl_compentry_func_wrap (const char *const*values); char *nmc_rl_gen_func_basic (const char *text, int state, const char *const*words); char *nmc_rl_gen_func_ifnames (const char *text, int state); gboolean nmc_get_in_readline (void); diff --git a/clients/cli/connections.c b/clients/cli/connections.c index cf1a750805..dd7cfc5261 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -184,8 +184,6 @@ typedef struct { } TabCompletionInfo; static TabCompletionInfo nmc_tab_completion = {NULL, NULL, NULL, NULL}; -static char *gen_connection_types (const char *text, int state); - static void usage (void) { @@ -2771,7 +2769,7 @@ finish: return nmc->return_value; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ /* * Return the most appropriate name for the connection of a type 'name' possibly with given 'slave_type' @@ -3097,7 +3095,7 @@ is_setting_mandatory (NMConnection *connection, NMSetting *setting) return FALSE; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static const char * _strip_master_prefix (const char *master, const char *(**func)(NMConnection *)) @@ -3685,7 +3683,7 @@ ensure_settings (NMConnection *connection, const NMMetaSettingValidPartItem *con } } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static char * gen_func_bool_values_l10n (const char *text, int state) @@ -3721,7 +3719,7 @@ gen_func_bond_lacp_rate (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static gboolean set_connection_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error) @@ -4002,7 +4000,7 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info) .check_and_set = check_and_set_, \ .generator_func = generator_func_, \ } - OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types), + OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, NULL), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, NULL), OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, NULL), OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type), @@ -4053,7 +4051,7 @@ option_relevant (NMConnection *connection, const NMMetaAbstractInfo *abstract_in return TRUE; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static void complete_property_name (NmCli *nmc, NMConnection *connection, @@ -4173,15 +4171,12 @@ complete_property (const gchar *setting_name, const gchar *property, const gchar return; } - if (strcmp (setting_name, NM_SETTING_CONNECTION_SETTING_NAME) == 0) { - if (strcmp (property, NM_SETTING_CONNECTION_TYPE) == 0) - run_rl_generator (gen_connection_types, prefix); - } else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 + if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 && strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0) run_rl_generator (gen_func_bt_type, prefix); } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static gboolean get_value (const char **value, int *argc, char ***argv, const char *option, GError **error) @@ -4481,9 +4476,7 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) } next: - if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE)) - generator_func = gen_connection_types; - else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) + if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE)) generator_func = gen_func_bt_type; else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MODE)) generator_func = gen_func_bond_mode; @@ -4841,7 +4834,7 @@ finish: return nmc->return_value; } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ /* Functions for readline TAB completion in editor */ static void @@ -4961,36 +4954,14 @@ gen_cmd_save (const char *text, int state) return nmc_rl_gen_func_basic (text, state, words); } -static char * -gen_connection_types (const char *text, int state) +static rl_compentry_func_t * +gen_connection_types (const char *text) { - static int list_idx, len; - static int had_name; + gs_strfreev char **values = NULL; - if (!state) { - list_idx = 0; - len = strlen (text); - had_name = FALSE; - } - - for (; list_idx < _NM_META_SETTING_TYPE_NUM; ) { - const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[list_idx]; - - if (!had_name) { - had_name = TRUE; - if (!text || strncmp (text, setting_info->general->setting_name, len) == 0) - return g_strdup (setting_info->general->setting_name); - } - - had_name = FALSE; - list_idx++; - if (setting_info->alias) { - if (!text || strncmp (text, setting_info->alias, len) == 0) - return g_strdup (setting_info->alias); - } - } - - return NULL; + values = _meta_abstract_complete ((const NMMetaAbstractInfo *) nm_meta_property_info_connection_type, + text); + return nmc_rl_compentry_func_wrap ((const char *const*) values); } static char * @@ -5586,7 +5557,7 @@ nmcli_editor_tab_completion (const char *text, int start, int end) /* Choose the right generator function */ if (strcmp (prompt_tmp, EDITOR_PROMPT_CON_TYPE) == 0) - generator_func = gen_connection_types; + generator_func = gen_connection_types (text); else if (strcmp (prompt_tmp, EDITOR_PROMPT_SETTING) == 0) generator_func = gen_setting_names; else if (strcmp (prompt_tmp, EDITOR_PROMPT_PROPERTY) == 0) @@ -5772,7 +5743,7 @@ save_history_cmds (const char *uuid) } } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static void editor_show_connection (NMConnection *connection, NmCli *nmc) @@ -6125,7 +6096,7 @@ editor_sub_usage (const char *command) } } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ typedef struct { NMDevice *device; @@ -6250,7 +6221,7 @@ activate_connection_editor_cb (GObject *client, g_clear_error (&error); } -/*----------------------------------------------------------------------------*/ +/*****************************************************************************/ static void print_property_description (NMSetting *setting, const char *prop_name) diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 7203b21c8e..839a49bbc0 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -32,6 +32,8 @@ typedef gpointer NMPolkitListener; #endif +typedef char *(*NmcCompEntryFunc) (const char *, int); + /* nmcli exit codes */ typedef enum { /* Indicates successful execution */ diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 402566bfcf..ddcce8c04e 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2272,6 +2272,37 @@ _set_fcn_connection_type (ARGS_SET_FCN) return TRUE; } +static const char *const* +_complete_fcn_connection_type (ARGS_COMPLETE_FCN) +{ + guint i, j; + char **result; + gsize text_len; + + result = g_new (char *, _NM_META_SETTING_TYPE_NUM * 2 + 1); + + text_len = text ? strlen (text) : 0; + + for (i = 0, j = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[i]; + const char *v; + + v = setting_info->alias; + if (v) { + if (!text || strncmp (text, v, text_len) == 0) + result[j++] = g_strdup (v); + } + if (!text || !*text || !v) { + v = setting_info->general->setting_name; + if (!text || strncmp (text, v, text_len) == 0) + result[j++] = g_strdup (v); + } + } + result[j++] = NULL; + + return (const char *const*) (*out_to_free = result); +} + /* define from libnm-core/nm-setting-connection.c */ #define PERM_USER_PREFIX "user:" @@ -5451,7 +5482,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { .complete_fcn = _complete_fcn_gobject_devices, ), }, - { + [_NM_META_PROPERTY_TYPE_CONNECTION_TYPE] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_TYPE), .is_cli_option = TRUE, .property_alias = "type", @@ -5460,6 +5491,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = { .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_connection_type, + .complete_fcn = _complete_fcn_connection_type, ), }, { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 6a750d5c8a..859f453d2f 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -252,8 +252,10 @@ typedef enum { enum { _NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE = 0, + _NM_META_PROPERTY_TYPE_CONNECTION_TYPE = 4, }; +#define nm_meta_property_info_connection_type (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_CONNECTION].properties[_NM_META_PROPERTY_TYPE_CONNECTION_TYPE]) #define nm_meta_property_info_vpn_service_type (&nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_VPN].properties[_NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE]) struct _NMMetaPropertyInfo { |