From d1d4129202059a05ee1b64ebbfb235451112109d Mon Sep 17 00:00:00 2001 From: claudio Date: Sat, 15 Apr 2023 10:36:59 +0000 Subject: [PATCH] Introduce an ANYTOKEN token which can be used instead of NOTOKEN to allow to fall back to another table if no other element in the current table matched. ANYTOKEN needs to be the last element in a table. With this 'bgpctl show rib 192.0.2.1 detail' works. OK tb@ --- usr.sbin/bgpctl/parser.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/usr.sbin/bgpctl/parser.c b/usr.sbin/bgpctl/parser.c index c81476c4dcc..86079fc2fea 100644 --- a/usr.sbin/bgpctl/parser.c +++ b/usr.sbin/bgpctl/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.124 2023/04/13 11:52:43 claudio Exp $ */ +/* $OpenBSD: parser.c,v 1.125 2023/04/15 10:36:59 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -34,8 +34,9 @@ #include "parser.h" enum token_type { - NOTOKEN, ENDTOKEN, + NOTOKEN, + ANYTOKEN, KEYWORD, ADDRESS, PEERADDRESS, @@ -72,6 +73,8 @@ struct token { const struct token *next; }; +static const struct token *prevtable; + static const struct token t_main[]; static const struct token t_show[]; static const struct token t_show_summary[]; @@ -320,11 +323,11 @@ static const struct token t_show_mrt_as[] = { }; static const struct token t_show_prefix[] = { - { NOTOKEN, "", NONE, NULL}, - { FLAG, "all", F_LONGER, NULL}, - { FLAG, "longer-prefixes", F_LONGER, NULL}, - { FLAG, "or-longer", F_LONGER, NULL}, - { FLAG, "or-shorter", F_SHORTER, NULL}, + { FLAG, "all", F_LONGER, t_show_rib}, + { FLAG, "longer-prefixes", F_LONGER, t_show_rib}, + { FLAG, "or-longer", F_LONGER, t_show_rib}, + { FLAG, "or-shorter", F_SHORTER, t_show_rib}, + { ANYTOKEN, "", NONE, t_show_rib}, { ENDTOKEN, "", NONE, NULL} }; @@ -533,6 +536,12 @@ parse(int argc, char *argv[]) show_valid_args(table); return (NULL); } + if (match->type == ANYTOKEN) { + if (prevtable == NULL) + prevtable = table; + table = match->next; + continue; + } argc--; argv++; @@ -571,6 +580,13 @@ match_token(int *argc, char **argv[], const struct token table[]) t = &table[i]; } break; + case ANYTOKEN: + /* match anything if nothing else matched before */ + if (match == 0) { + match++; + t = &table[i]; + } + break; case KEYWORD: if (word != NULL && strncmp(word, table[i].keyword, wordlen) == 0) { @@ -842,11 +858,20 @@ show_valid_args(const struct token table[]) { int i; + if (prevtable != NULL) { + const struct token *t = prevtable; + prevtable = NULL; + show_valid_args(t); + fprintf(stderr, "or any of\n"); + } + for (i = 0; table[i].type != ENDTOKEN; i++) { switch (table[i].type) { case NOTOKEN: fprintf(stderr, " \n"); break; + case ANYTOKEN: + break; case KEYWORD: case FLAG: case ASTYPE: -- 2.20.1