28 vlib_parse_value_t *
v;
52 #define _(a) case VLIB_PARSE_##a: t = #a; break; 61 return format (s,
"%s", t);
63 return format (s,
"unknown 0x%x", m);
92 if (type->rule_index == node - pm->parse_graph)
93 s = format (s,
"\n<%s>\n", type->name);
98 s =
format (s,
"\n<root>\n");
106 s =
format (s,
"peer nil ");
111 s =
format (s,
"deeper nil ");
126 fformat(stdout,
"%U\n", format_vlib_parse_graph, pm, node);
143 vlib_parse_value_t *pv;
152 _vec_len (pm->
tokens) = 0;
168 for (i =
vec_len (help_input) - 1; i >= 0; i--)
169 if (help_input[i] ==
'?')
172 _vec_len (help_input) =
i;
176 for (i =
vec_len (help_input) - 1; i >= 0; i--)
178 if (help_input[i] !=
' ' && help_input[i] !=
'\t')
183 _vec_len (help_input) = i + 1;
185 while (index != (
u32) ~ 0)
208 vlib_parse_value_t value, *pv;
210 u32 *partial_matches = 0;
212 u32 save_token_index = (
u32) ~ 0, save_match_items = 0;
216 return VLIB_PARSE_MATCH_FAIL;
226 return VLIB_PARSE_MATCH_DONE;
230 while (index != (
u32) ~ 0)
257 case VLIB_PARSE_MATCH_VALUE:
262 value.type = item->
type;
267 case VLIB_PARSE_MATCH_FULL:
268 unambiguous_partial_match:
276 if (rv == VLIB_PARSE_MATCH_FAIL)
293 case VLIB_PARSE_MATCH_PARTIAL:
299 case VLIB_PARSE_MATCH_FAIL:
305 case VLIB_PARSE_MATCH_DONE:
321 case VLIB_PARSE_MATCH_AMBIGUOUS:
322 case VLIB_PARSE_MATCH_EVAL_FAIL:
323 case VLIB_PARSE_MATCH_RULE:
333 if (
vec_len (partial_matches) == 1)
335 index = partial_matches[0];
338 goto unambiguous_partial_match;
342 rv = VLIB_PARSE_MATCH_FAIL;
345 if (
vec_len (partial_matches) > 1)
348 rv = VLIB_PARSE_MATCH_AMBIGUOUS;
360 static int recursion_level;
363 clib_warning (
"[%d]: try to match type %s graph index %d",
370 if (rv == VLIB_PARSE_MATCH_RULE)
375 return VLIB_PARSE_MATCH_FULL;
399 while (t->
token != VLIB_LEX_eof);
470 memset (&type, 0,
sizeof (type));
472 #define foreach_token_type \ 484 #define _(a) a##_type_index = parse_type_find_by_name (pm, #a); 487 memset (&item, 0,
sizeof (item));
495 memset (g, 0xff,
sizeof (*g));
517 while (t->
token != VLIB_LEX_eof);
528 && t[0].
token == VLIB_LEX_lt
529 && t[1].
token == VLIB_LEX_word
530 && t[2].
token == VLIB_LEX_gt && t[3].
token == VLIB_LEX_equals)
543 if (t->
token == VLIB_LEX_eof)
547 if (t->
token == VLIB_LEX_word)
556 *token_increment = 1;
560 if (t->
token == VLIB_LEX_lt)
562 u16 token_type_index;
565 if (t[1].token != VLIB_LEX_word || t[2].token != VLIB_LEX_gt)
572 if (token_type_index == (
u16) ~ 0)
579 if (item->
type != token_type_index)
582 *token_increment = 3;
592 u32 * new_subgraph_depth,
597 u32 rv = (
u32) ~ 0, new_item_index, last_index = (
u32) ~ 0;
598 u16 token_type_index;
603 memset (&new_item, 0,
sizeof (new_item));
605 if (t->
token == VLIB_LEX_word)
612 else if (t->
token == VLIB_LEX_lt)
614 if (t[1].token != VLIB_LEX_word || t[2].token != VLIB_LEX_gt)
621 if (token_type_index == (
u16) ~ 0)
627 new_item.
type = token_type_index;
632 else if (t->
token == VLIB_LEX_eof)
649 memset (g, 0xff,
sizeof (*g));
650 g->
item = new_item_index;
664 *new_subgraph_depth = depth;
676 if (index == (
u32) ~ 0)
685 while (index != (
u32) ~ 0)
699 u32 last_matching_index,
700 u32 graph_root_index,
701 u32 new_subgraph_index,
u32 new_subgraph_depth)
704 int new_subgraph_longest = 1;
705 u32 current_peer_index;
715 if (last_matching_index == (
u32) ~ 0)
717 u32 index = graph_root_index;
722 if (current_depth < new_subgraph_depth
723 || current_peer->
peer == (
u32) ~ 0)
725 index = current_peer->
peer;
727 new_subgraph_node->
peer = current_peer->
peer;
728 current_peer->
peer = new_subgraph_index;
733 current_peer_index = parent_node->
deeper;
735 while (current_peer_index != (
u32) ~ 0)
739 if (current_depth < new_subgraph_depth)
741 new_subgraph_longest = 0;
742 current_peer_index = current_peer->
peer;
747 if (new_subgraph_longest)
749 new_subgraph_node->
peer = parent_node->
deeper;
750 parent_node->
deeper = new_subgraph_index;
754 new_subgraph_node->
peer = current_peer->
peer;
755 current_peer->
peer = new_subgraph_index;
762 u32 graph_root_index;
763 u16 subgraph_type_index = (
u16) ~ 0;
767 u32 node_index, last_index, token_increment, new_subgraph_index;
768 u32 new_subgraph_depth, last_matching_index;
772 int use_main_graph = 1;
782 if (subgraph_type_index == (
u16) ~ 0)
799 last_matching_index = (
u32) ~ 0;
800 last_index = node_index = graph_root_index;
808 last_index = node_index;
811 (pm, t, node, item, type, &token_increment))
813 t += token_increment;
814 last_matching_index = node_index;
815 node_index = node->
deeper;
818 node_index = node->
peer;
826 if (graph_root_index == (
u32) ~ 0)
831 subgraph_type->
rule_index = new_subgraph_index;
836 new_subgraph_index, new_subgraph_depth);
847 for (pr = lo; pr <
hi; pr = vlib_elf_section_data_next (pr, 0))
868 for (ptr = lo; ptr <
hi; ptr = vlib_elf_section_data_next (ptr, 0))
938 vlib_elf_section_bounds_t *b, *bounds;
964 _vec_len (pm->
tokens) = 0;
968 bounds = vlib_get_elf_section_bounds (vm,
"parse_type_registrations");
979 bounds = vlib_get_elf_section_bounds (vm,
"parse_registrations");
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u16 parse_type_find_by_name(vlib_parse_main_t *pm, char *name)
u16 parse_type_find_or_create(vlib_parse_main_t *pm, vlib_parse_type_t *t)
static clib_error_t * parse_register_one(vlib_parse_main_t *pm, parse_registration_t *pr)
vlib_parse_match_t rule_match(vlib_parse_main_t *pm, vlib_parse_type_t *type, vlib_lex_token_t *t, vlib_parse_value_t *valuep)
sll srl srl sll sra u16x4 i
static vlib_parse_match_t parse_eval_internal(vlib_parse_main_t *pm, u32 index)
u8 * format_vlib_parse_value(u8 *s, va_list *args)
static int compute_rule_length(parse_registration_t *r)
union vlib_lex_token_t::@27 value
vlib_parse_main_t vlib_parse_main
static void parse_help(vlib_parse_main_t *pm, u32 index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
vlib_parse_graph_t * parse_graph
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define hash_set_mem(h, key, value)
vlib_lex_main_t * lex_main
static clib_error_t * parse_register_one_type(vlib_parse_main_t *pm, vlib_parse_type_t *rp)
static clib_error_t * parse_register(vlib_main_t *vm, parse_registration_t *lo, parse_registration_t *hi, vlib_parse_main_t *pm)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
vlib_parse_match_function_t * match_function
static int parse_eval(vlib_parse_main_t *pm, u8 *input)
vlib_parse_value_t * parse_value
u32 parse_item_find_or_create(vlib_parse_main_t *pm, vlib_parse_item_t *item)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
vlib_parse_type_t * parse_types
vlib_parse_item_t * parse_items
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
static u8 * format_vlib_parse_item(u8 *s, va_list *args)
clib_error_t * vlib_stdlex_init(vlib_main_t *vm)
void dump_parse_graph(void)
#define vlib_call_init_function(vm, x)
static void tokenize(vlib_parse_main_t *pm, parse_registration_t *pr)
static void vlib_lex_cleanup_token(vlib_lex_token_t *t)
#define hash_create_string(elts, value_bytes)
u16 vlib_lex_add_table(char *name)
static clib_error_t * parse_init(vlib_main_t *vm)
static void parse_type_and_graph_init(vlib_parse_main_t *pm)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static u8 * format_vlib_parse_graph(u8 *s, va_list *args)
u32 generate_subgraph_from_tokens(vlib_parse_main_t *pm, vlib_lex_token_t *t, u32 *new_subgraph_depth, parse_registration_t *pr, int not_a_rule)
static u8 * format_vlib_parse_match(u8 *s, va_list *args)
#define vec_dup(V)
Return copy of vector (no header, no alignment)
static foreach_vanilla_lex_match_function clib_error_t * parse_builtin_init(vlib_main_t *vm)
static void parse_reset(vlib_parse_main_t *pm, u8 *input)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
format_function_t format_vlib_lex_token
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
vlib_parse_match_t vlib_parse_eval(u8 *input)
#define foreach_token_type
static clib_error_t * parse_type_register(vlib_main_t *vm, vlib_parse_type_t *lo, vlib_parse_type_t *hi, vlib_parse_main_t *pm)
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
vlib_parse_value_cleanup_function_t * value_cleanup_function
static int rule_length_compare(parse_registration_t *r1, parse_registration_t *r2)
static uword * mhash_get(mhash_t *h, const void *key)
void vlib_lex_reset(vlib_lex_main_t *lm, u8 *input_vector)
parse_registration_t ** parse_registrations
format_function_t * format_value
uword * parse_type_by_name_hash
static void parse_cleanup_value(vlib_parse_main_t *pm, vlib_parse_value_t *pv)
vlib_lex_main_t vlib_lex_main
static int token_matches_graph_node(vlib_parse_main_t *pm, vlib_lex_token_t *t, vlib_parse_graph_t *node, vlib_parse_item_t *item, vlib_parse_type_t *type, u32 *token_increment)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
void vlib_lex_get_token(vlib_lex_main_t *lm, vlib_lex_token_t *rv)
static clib_error_t * lex_onetime_init(vlib_main_t *vm)
static u32 measure_depth(vlib_parse_main_t *pm, u32 index)
vlib_parse_match_t( vlib_parse_eval_function_t)(vlib_parse_main_t *, vlib_parse_item_t *, vlib_parse_value_t *)
static void add_subgraph_to_graph(vlib_parse_main_t *pm, u32 last_matching_index, u32 graph_root_index, u32 new_subgraph_index, u32 new_subgraph_depth)
vlib_lex_token_t * tokens
#define hash_get_mem(h, key)
#define vec_foreach(var, vec)
Vector iterator.
static int is_typed_rule(vlib_parse_main_t *pm)
union vlib_parse_item_t::@31 value
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)