From 36499bb35be221fee1153b57115b67684bee7271 Mon Sep 17 00:00:00 2001 From: devi Date: Mon, 22 Jun 2026 16:06:56 +0530 Subject: [PATCH 1/2] Skip variable validation during last-token expansion --- cligen_match.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/cligen_match.c b/cligen_match.c index a92e590..a9ff095 100644 --- a/cligen_match.c +++ b/cligen_match.c @@ -145,24 +145,26 @@ match_variable(cligen_handle h, /*! Given a string and one cligen object, return if the string matches * - * @param[in] h CLIgen handle - * @param[in] str0 Input string to match (NULL is match) - * @param[in] co cligen object - * @param[in] best Only return best match (for command evaluation) instead of all possible options - * @param[out] exact 1 if match is exact (CO_COMMANDS). VARS is 0. - * @param[out] reason if not match and co type is 0, reason points to a (malloced) - * string containing an error explanation string. If reason is - * NULL no such string will be malloced. This string needs to - * be freed. - * @retval 1 Match - * @retval 0 Not match - * @retval -1 Error + * @param[in] h CLIgen handle + * @param[in] str0 Input string to match (NULL is match) + * @param[in] co cligen object + * @param[in] best Only return best match (for command evaluation) instead of all possible options + * @param[in] lasttoken Set to True if this is the final token being matched + * @param[out] exact 1 if match is exact (CO_COMMANDS). VARS is 0. + * @param[out] reason if not match and co type is 0, reason points to a (malloced) + * string containing an error explanation string. If reason is + * NULL no such string will be malloced. This string needs to + * be freed. + * @retval 1 Match + * @retval 0 Not match + * @retval -1 Error */ static int match_object(cligen_handle h, const char *str0, cg_obj *co, int best, + int lasttoken, int *exact, char **reason) { @@ -207,9 +209,17 @@ match_object(cligen_handle h, else match++; } - else - if ((match = match_variable(h, co, str0, reason)) < 0) - return -1; + else { + /* During expansion of the last token, do not reject candidates + * based on variable validation failures. + */ + if (!best && lasttoken) { + match++; + } else { + if ((match = match_variable(h, co, str0, reason)) < 0) + return -1; + } + } break; case CO_REFERENCE: /* This should never match, it is an abstract object that is expanded */ if (reason){ @@ -406,7 +416,7 @@ match_vec(cligen_handle h, tmpreason = NULL; if ((match = match_object(h, ISREST(co)?resttokens:token, - co, best, &exact, + co, best, lasttoken, &exact, &tmpreason /* if match == 0 */ )) < 0) goto done; From 3c3367fac4746ab756df08cda78fbc813af2b13b Mon Sep 17 00:00:00 2001 From: devi Date: Mon, 22 Jun 2026 16:09:16 +0530 Subject: [PATCH 2/2] Preserve partial command matches over variable errors --- cligen_match.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cligen_match.c b/cligen_match.c index a9ff095..5f5d91c 100644 --- a/cligen_match.c +++ b/cligen_match.c @@ -522,10 +522,20 @@ match_vec(cligen_handle h, if (mr_pref_get(mr) == COV_PREF_COMMAND_PARTIAL && mr_reason_get(mr) != NULL && pref_lower > COV_PREF_COMMAND_PARTIAL){ - /* Partial command match with a validation error from a variable: - * remove the partial match and keep the validation reason + /* + * Keep partial matches originating from commands/keywords, + * but discard partial matches originating from expanded + * variable values. This preserves command completion and + * execution while still reporting genuine variable + * validation failures. */ - mr_pt_reset(mr); + co = mr_pt_i_get(mr, 0); + if (co && + co->co_ref && + co->co_ref->co_type == CO_VARIABLE) { + /* Partial match came from an expanded variable value. */ + mr_pt_reset(mr); + } } else mr_reason_set(mr, NULL);