diff options
| -rw-r--r-- | src/vty/command.c | 51 | ||||
| -rw-r--r-- | tests/tdef/tdef_vty_test_config_root.vty | 11 | ||||
| -rw-r--r-- | tests/vty/vty_transcript_test.vty | 12 | 
3 files changed, 56 insertions, 18 deletions
| diff --git a/src/vty/command.c b/src/vty/command.c index 17d28fe6..3c91bfd3 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -2217,7 +2217,7 @@ static int  cmd_execute_command_real(vector vline, struct vty *vty,  			 struct cmd_element **cmd)  { -	unsigned int i; +	unsigned int i, j;  	unsigned int index;  	vector cmd_vector;  	struct cmd_element *cmd_element; @@ -2228,6 +2228,10 @@ cmd_execute_command_real(vector vline, struct vty *vty,  	enum match_type match = 0;  	int varflag;  	char *command; +	int rc; +	/* Used for temporary storage of cmd_deopt() allocated arguments during +	   argv[] generation */ +	void *cmd_deopt_ctx = NULL;  	/* Make copy of command elements. */  	cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node)); @@ -2293,9 +2297,13 @@ cmd_execute_command_real(vector vline, struct vty *vty,  	varflag = 0;  	argc = 0; +	cmd_deopt_ctx = talloc_named_const(tall_vty_cmd_ctx, 0, __func__); +  	for (i = 0; i < vector_active(vline); i++) { -		if (argc == CMD_ARGC_MAX) -			return CMD_ERR_EXEED_ARGC_MAX; +		if (argc == CMD_ARGC_MAX) { +			rc = CMD_ERR_EXEED_ARGC_MAX; +			goto rc_free_deopt_ctx; +		}  		if (varflag) {  			argv[argc++] = vector_slot(vline, i);  			continue; @@ -2313,7 +2321,32 @@ cmd_execute_command_real(vector vline, struct vty *vty,  			    || CMD_OPTION(desc->cmd))  				argv[argc++] = vector_slot(vline, i);  		} else { -			argv[argc++] = vector_slot(vline, i); +			/* multi choice argument. look up which choice +			   the user meant (can only be one after +			   filtering and checking for ambigous). For instance, +			   if user typed "th" for "(two|three)" arg, we +			   want to pass "three" in argv[]. */ +			for (j = 0; j < vector_active(descvec); j++) { +				struct desc *desc = vector_slot(descvec, j); +				const char *tmp_cmd; +				if (!desc) +					continue; +				if (cmd_match(desc->cmd, vector_slot(vline, i), ANY_MATCH, true) == NO_MATCH) +					continue; +				if (CMD_OPTION(desc->cmd)) { +					/* we need to first remove the [] chars, then check to see what's inside (var or token) */ +					tmp_cmd = cmd_deopt(cmd_deopt_ctx, desc->cmd); +				} else { +					tmp_cmd = desc->cmd; +				} + +				if(CMD_VARIABLE(tmp_cmd)) { +					argv[argc++] = vector_slot(vline, i); +				} else { +					argv[argc++] = tmp_cmd; +				} +				break; +			}  		}  	} @@ -2322,10 +2355,14 @@ cmd_execute_command_real(vector vline, struct vty *vty,  		*cmd = matched_element;  	if (matched_element->daemon) -		return CMD_SUCCESS_DAEMON; +		rc = CMD_SUCCESS_DAEMON; +	else	/* Execute matched command. */ +		rc = (*matched_element->func) (matched_element, vty, argc, argv); -	/* Execute matched command. */ -	return (*matched_element->func) (matched_element, vty, argc, argv); +rc_free_deopt_ctx: +	/* Now after we called the command func, we can free temporary strings */ +	talloc_free(cmd_deopt_ctx); +	return rc;  }  int diff --git a/tests/tdef/tdef_vty_test_config_root.vty b/tests/tdef/tdef_vty_test_config_root.vty index 8613ff36..f3aba0f9 100644 --- a/tests/tdef/tdef_vty_test_config_root.vty +++ b/tests/tdef/tdef_vty_test_config_root.vty @@ -163,7 +163,6 @@ tdef_vty_test(config)# timer te T2  tdef_vty_test(config)# timer test T2 100  tdef_vty_test(config)# timer tes T2 100 -% Error: no timers found  tdef_vty_test(config)# timer te T2 100  % Ambiguous command. @@ -219,7 +218,6 @@ tdef_vty_test(config)# timer softw T3  software: T3 = 480 m	Fix bugs (default: 480 m)  tdef_vty_test(config)# timer softw T3 23 -% Error: no timers found  tdef_vty_test(config)# timer  tea: T1 = 50 s	Water Boiling Timeout (default: 50 s) @@ -234,7 +232,7 @@ test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)  test: X23 = 239471 s	Negative T number (default: 239471 s)  software: T1 = 13 m	Write code (default: 30 m)  software: T2 = 0 ms	Hit segfault (default: 20 ms) -software: T3 = 480 m	Fix bugs (default: 480 m) +software: T3 = 23 m	Fix bugs (default: 480 m)  tdef_vty_test(config)# do show timer  tea: T1 = 50 s	Water Boiling Timeout (default: 50 s) @@ -249,13 +247,14 @@ test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)  test: X23 = 239471 s	Negative T number (default: 239471 s)  software: T1 = 13 m	Write code (default: 30 m)  software: T2 = 0 ms	Hit segfault (default: 20 ms) -software: T3 = 480 m	Fix bugs (default: 480 m) +software: T3 = 23 m	Fix bugs (default: 480 m)  tdef_vty_test(config)# show running-config  ... !timer  timer tea T3 32  timer software T1 13  timer software T2 0 +timer software T3 23  ... !timer  tdef_vty_test(config)# timer tea T3 default @@ -263,10 +262,12 @@ tdef_vty_test(config)# timer software T1 default  tdef_vty_test(config)# show running-config  ... !timer  timer software T2 0 +timer software T3 23  ... !timer  tdef_vty_test(config)# timer softw 2 default -% Error: no timers found  tdef_vty_test(config)# timer software 2 default  tdef_vty_test(config)# show running-config  ... !timer +timer software T3 23 +... !timer diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty index 15577446..f2dbacbf 100644 --- a/tests/vty/vty_transcript_test.vty +++ b/tests/vty/vty_transcript_test.vty @@ -16,13 +16,13 @@ vty_transcript_test> multi0 two  ok argc=1 two  vty_transcript_test> multi0 o -ok argc=1 o +ok argc=1 one  vty_transcript_test> multi0 t  % Ambiguous command.  vty_transcript_test> multi0 th -ok argc=1 th +ok argc=1 three  vty_transcript_test> multi0  % Command incomplete. @@ -39,13 +39,13 @@ vty_transcript_test> multi1 two  ok argc=1 two  vty_transcript_test> multi1 o -ok argc=1 o +ok argc=1 one  vty_transcript_test> multi1 t  % Ambiguous command.  vty_transcript_test> multi1 th -ok argc=1 th +ok argc=1 three  vty_transcript_test> multi1  ok argc=0 @@ -68,10 +68,10 @@ vty_transcript_test> multi2  ok argc=0  vty_transcript_test> multi0 thr -ok argc=1 thr +ok argc=1 three  vty_transcript_test> multi1 on -ok argc=1 on +ok argc=1 one  vty_transcript_test> multi2 t  % Ambiguous command. | 
