On Mon, Apr 17, 2023 at 12:12:47PM +0200, Theo Buehler wrote:
> On Mon, Apr 17, 2023 at 11:28:37AM +0200, Claudio Jeker wrote:
> > I want to extend the parser to support lists in a few places.
> > One of them is for communities. This is the first step towards this goal.
> > The change uses the fact that match_token() has access to argc and argv
> > and changes the community parsers to parse the next token for communities.
> > As a nice side-effect this reduces the amount of tables and removes the
> > ext-community subtype tables which are probably never in sync with the one
> > from bgpd.h.
>
> I like the direction and it looks like a good intermediate step. Go
> ahead
>
> ok
>
> > The way argv is passed to match_token() is not great, tripple pointers are
> > just strange. I plan to fix this in an upcomming diff.
>
> That would be nice.
How about this? I think this is the simplest way to handle this.
--
:wq Claudio
Index: parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.126
diff -u -p -r1.126 parser.c
--- parser.c 17 Apr 2023 10:23:32 -0000 1.126
+++ parser.c 17 Apr 2023 10:43:16 -0000
@@ -434,8 +434,8 @@ static const struct token t_show_rib_pat
static struct parse_result res;
-const struct token *match_token(int *argc, char **argv[],
- const struct token []);
+const struct token *match_token(int argc, char *argv[],
+ const struct token [], int *);
void show_valid_args(const struct token []);
int parse_addr(const char *, struct bgpd_addr *);
@@ -451,13 +451,14 @@ parse(int argc, char *argv[])
{
const struct token *table = t_main;
const struct token *match;
+ int used;
memset(&res, 0, sizeof(res));
res.rtableid = getrtable();
TAILQ_INIT(&res.set);
while (argc >= 0) {
- if ((match = match_token(&argc, &argv, table)) == NULL) {
+ if ((match = match_token(argc, argv, table, &used)) == NULL) {
fprintf(stderr, "valid commands/args:\n");
show_valid_args(table);
return (NULL);
@@ -469,12 +470,11 @@ parse(int argc, char *argv[])
continue;
}
- argc--;
- argv++;
+ argc -= used;
+ argv += used;
if (match->type == NOTOKEN || match->next == NULL)
break;
-
table = match->next;
}
@@ -487,14 +487,15 @@ parse(int argc, char *argv[])
}
const struct token *
-match_token(int *argc, char **argv[], const struct token table[])
+match_token(int argc, char *argv[], const struct token table[], int *argsused)
{
u_int i, match;
const struct token *t = NULL;
struct filter_set *fs;
- const char *word = (*argv)[0];
- size_t wordlen = 0;
+ const char *word = argv[0];
+ size_t wordlen = 0;
+ *argsused = 1;
match = 0;
if (word != NULL)
wordlen = strlen(word);
@@ -625,10 +626,9 @@ match_token(int *argc, char **argv[], co
break;
case COMMUNITY:
if (word != NULL && strncmp(word, table[i].keyword,
- wordlen) == 0 && *argc > 1) {
- parsecommunity(&res.community, (*argv)[1]);
- *argc -= 1;
- *argv += 1;
+ wordlen) == 0 && argc > 1) {
+ parsecommunity(&res.community, argv[1]);
+ *argsused += 1;
if ((fs = calloc(1, sizeof(*fs))) == NULL)
err(1, NULL);
@@ -642,10 +642,9 @@ match_token(int *argc, char **argv[], co
break;
case LRGCOMMUNITY:
if (word != NULL && strncmp(word, table[i].keyword,
- wordlen) == 0 && *argc > 1) {
- parselargecommunity(&res.community, (*argv)[1]);
- *argc -= 1;
- *argv += 1;
+ wordlen) == 0 && argc > 1) {
+ parselargecommunity(&res.community, argv[1]);
+ *argsused += 1;
if ((fs = calloc(1, sizeof(*fs))) == NULL)
err(1, NULL);
@@ -659,11 +658,10 @@ match_token(int *argc, char **argv[], co
break;
case EXTCOMMUNITY:
if (word != NULL && strncmp(word, table[i].keyword,
- wordlen) == 0 && *argc > 2) {
+ wordlen) == 0 && argc > 2) {
parseextcommunity(&res.community,
- (*argv)[1], (*argv)[2]);
- *argc -= 2;
- *argv += 2;
+ argv[1], argv[2]);
+ *argsused += 2;
if ((fs = calloc(1, sizeof(*fs))) == NULL)
err(1, NULL);