mirror of https://gerrit.osmocom.org/libosmocore
vty: enable optional-multi-choice syntax: [(one|two)]
Since very recently we sensibly handle commands like cmd ([one]|[two]|[three]) as optional multi-choice arguments. In addition, support the more obvious syntax of cmd [(one|two|three)] Internally, the tokens are mangled to [one] [two] and [three], which is how the rest of the code detects optional args, and makes sense in terms of UI: > cmd ? [one] [two] [three] (i.e. optional arguments are always shown in braces in '?' listings) Before this patch, commands defined with a syntax like [(one|two)], would lead to an assertion (shows as "multiple") during program startup. Change-Id: I952b3c00f97e2447f2308b0ec6f5f1714692b5b2
This commit is contained in:
parent
c197809deb
commit
b55f4d2df2
|
@ -380,6 +380,7 @@ static char *cmd_desc_str(const char **string)
|
|||
static vector cmd_make_descvec(const char *string, const char *descstr)
|
||||
{
|
||||
int multiple = 0;
|
||||
int optional_brace = 0;
|
||||
const char *sp;
|
||||
char *token;
|
||||
int len;
|
||||
|
@ -401,6 +402,12 @@ static vector cmd_make_descvec(const char *string, const char *descstr)
|
|||
while (isspace((int)*cp) && *cp != '\0')
|
||||
cp++;
|
||||
|
||||
/* Explicitly detect optional multi-choice braces like [(one|two)]. */
|
||||
if (cp[0] == '[' && cp[1] == '(') {
|
||||
optional_brace = 1;
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (*cp == '(') {
|
||||
multiple = 1;
|
||||
cp++;
|
||||
|
@ -408,6 +415,9 @@ static vector cmd_make_descvec(const char *string, const char *descstr)
|
|||
if (*cp == ')') {
|
||||
multiple = 0;
|
||||
cp++;
|
||||
if (*cp == ']')
|
||||
cp++;
|
||||
optional_brace = 0;
|
||||
}
|
||||
if (*cp == '|') {
|
||||
OSMO_ASSERT(multiple);
|
||||
|
@ -434,9 +444,17 @@ static vector cmd_make_descvec(const char *string, const char *descstr)
|
|||
|
||||
len = cp - sp;
|
||||
|
||||
token = _talloc_zero(tall_vty_cmd_ctx, len + 1, "cmd_make_descvec");
|
||||
memcpy(token, sp, len);
|
||||
*(token + len) = '\0';
|
||||
token = _talloc_zero(tall_vty_cmd_ctx, len + (optional_brace? 2 : 0) + 1, "cmd_make_descvec");
|
||||
if (optional_brace) {
|
||||
/* Place each individual multi-choice token in its own square braces */
|
||||
token[0] = '[';
|
||||
memcpy(token + 1, sp, len);
|
||||
token[1 + len] = ']';
|
||||
token[2 + len] = '\0';
|
||||
} else {
|
||||
memcpy(token, sp, len);
|
||||
*(token + len) = '\0';
|
||||
}
|
||||
|
||||
desc = talloc_zero(tall_vty_cmd_ctx, struct desc);
|
||||
desc->cmd = token;
|
||||
|
|
|
@ -170,10 +170,19 @@ DEFUN(multi1, multi1_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(multi2, multi2_cmd,
|
||||
"multi2 [(one|two|three)]",
|
||||
"multi2 test command\n" "1\n2\n3\n")
|
||||
{
|
||||
vty_out(vty, "ok argc=%d%s%s%s", argc, argc ? " " : "", argc ? argv[0] : "", VTY_NEWLINE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void init_vty_cmds()
|
||||
{
|
||||
install_element_ve(&multi0_cmd);
|
||||
install_element_ve(&multi1_cmd);
|
||||
install_element_ve(&multi2_cmd);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
@ -2,6 +2,7 @@ vty_transcript_test> list
|
|||
...
|
||||
multi0 (one|two|three)
|
||||
multi1 ([one]|[two]|[three])
|
||||
multi2 [(one|two|three)]
|
||||
|
||||
vty_transcript_test> multi0 ?
|
||||
one 1
|
||||
|
@ -51,3 +52,17 @@ ok argc=0
|
|||
|
||||
vty_transcript_test> multi1 [one]
|
||||
% Unknown command.
|
||||
|
||||
vty_transcript_test> multi2 ?
|
||||
[one] 1
|
||||
[two] 2
|
||||
[three] 3
|
||||
|
||||
vty_transcript_test> multi2 one
|
||||
ok argc=1 one
|
||||
|
||||
vty_transcript_test> multi2 two
|
||||
ok argc=1 two
|
||||
|
||||
vty_transcript_test> multi2
|
||||
ok argc=0
|
||||
|
|
Loading…
Reference in New Issue