27 vlib_parse_value_t *v;
50 #define _(a) case VLIB_PARSE_##a: t = #a; break; 53 default: t = 0;
break;
57 return format (s,
"%s", t);
59 return format (s,
"unknown 0x%x", m);
85 if (type->rule_index == node - pm->parse_graph)
86 s = format (s,
"\n<%s>\n", type->name);
90 s =
format (s,
"\n<root>\n");
98 s =
format (s,
"peer nil ");
103 s =
format (s,
"deeper nil ");
116 fformat(stdout,
"%U\n", format_vlib_parse_graph, pm, node);
131 vlib_parse_value_t *pv;
142 _vec_len (pm->
tokens) = 0;
157 for (i =
vec_len(help_input)-1; i >= 0; i--)
158 if (help_input[i] ==
'?')
161 _vec_len(help_input) =
i;
165 for (i =
vec_len(help_input)-1; i >= 0; i--)
167 if (help_input[i] !=
' ' && help_input[i] !=
'\t')
172 _vec_len(help_input) = i+1;
174 while (index != (
u32)~0)
197 vlib_parse_value_t value, *pv;
199 u32 *partial_matches = 0;
201 u32 save_token_index=(
u32)~0, save_match_items=0;
205 return VLIB_PARSE_MATCH_FAIL;
215 return VLIB_PARSE_MATCH_DONE;
219 while (index != (
u32)~0)
246 case VLIB_PARSE_MATCH_VALUE:
251 value.type = item->
type;
256 case VLIB_PARSE_MATCH_FULL:
257 unambiguous_partial_match:
265 if (rv == VLIB_PARSE_MATCH_FAIL)
282 case VLIB_PARSE_MATCH_PARTIAL:
288 case VLIB_PARSE_MATCH_FAIL:
294 case VLIB_PARSE_MATCH_DONE:
311 case VLIB_PARSE_MATCH_AMBIGUOUS:
312 case VLIB_PARSE_MATCH_EVAL_FAIL:
313 case VLIB_PARSE_MATCH_RULE:
323 if (
vec_len (partial_matches) == 1)
325 index = partial_matches[0];
328 goto unambiguous_partial_match;
332 rv = VLIB_PARSE_MATCH_FAIL;
335 if (
vec_len (partial_matches) > 1)
338 rv = VLIB_PARSE_MATCH_AMBIGUOUS;
347 vlib_parse_value_t *valuep)
350 static int recursion_level;
353 clib_warning (
"[%d]: try to match type %s graph index %d",
362 if (rv == VLIB_PARSE_MATCH_RULE)
367 return VLIB_PARSE_MATCH_FULL;
388 }
while (t->
token != VLIB_LEX_eof);
455 memset (&type, 0,
sizeof (type));
457 #define foreach_token_type \ 469 #define _(a) a##_type_index = parse_type_find_by_name (pm, #a); 473 memset (&item, 0,
sizeof (item));
481 memset (g, 0xff,
sizeof (*g));
500 }
while (t->
token != VLIB_LEX_eof);
510 && t[0].
token == VLIB_LEX_lt
511 && t[1].
token == VLIB_LEX_word
512 && t[2].
token == VLIB_LEX_gt
513 && t[3].
token == VLIB_LEX_equals)
523 u32 *token_increment)
526 if (t->
token == VLIB_LEX_eof)
530 if (t->
token == VLIB_LEX_word)
539 *token_increment = 1;
543 if (t->
token == VLIB_LEX_lt)
545 u16 token_type_index;
548 if (t[1].token != VLIB_LEX_word ||
549 t[2].token != VLIB_LEX_gt)
556 if (token_type_index == (
u16)~0)
563 if (item->
type != token_type_index)
566 *token_increment = 3;
575 u32 *new_subgraph_depth,
581 u32 rv = (
u32)~0, new_item_index, last_index = (
u32)~0;
582 u16 token_type_index;
587 memset (&new_item, 0,
sizeof (new_item));
589 if (t->
token == VLIB_LEX_word)
596 else if (t->
token == VLIB_LEX_lt)
598 if (t[1].token != VLIB_LEX_word ||
599 t[2].token != VLIB_LEX_gt)
606 if (token_type_index == (
u16)~0)
612 new_item.
type = token_type_index;
617 else if (t->
token == VLIB_LEX_eof)
634 memset (g, 0xff,
sizeof (*g));
635 g->
item = new_item_index;
649 *new_subgraph_depth = depth;
660 if (index == (
u32)~0)
669 while (index != (
u32)~0)
682 u32 last_matching_index,
683 u32 graph_root_index,
684 u32 new_subgraph_index,
685 u32 new_subgraph_depth)
688 int new_subgraph_longest = 1;
689 u32 current_peer_index;
699 if (last_matching_index == (
u32)~0)
701 u32 index = graph_root_index;
705 if (current_depth < new_subgraph_depth
706 || current_peer->
peer == (
u32)~0)
708 index = current_peer->
peer;
710 new_subgraph_node->
peer = current_peer->
peer;
711 current_peer->
peer = new_subgraph_index;
716 current_peer_index = parent_node->
deeper;
718 while (current_peer_index != (
u32)~0)
722 if (current_depth < new_subgraph_depth)
724 new_subgraph_longest = 0;
725 current_peer_index = current_peer->
peer;
730 if (new_subgraph_longest)
732 new_subgraph_node->
peer = parent_node->
deeper;
733 parent_node->
deeper = new_subgraph_index;
737 new_subgraph_node->
peer = current_peer->
peer;
738 current_peer->
peer = new_subgraph_index;
745 u32 graph_root_index;
746 u16 subgraph_type_index = (
u16)~0;
750 u32 node_index, last_index, token_increment, new_subgraph_index;
751 u32 new_subgraph_depth, last_matching_index;
755 int use_main_graph = 1;
765 if (subgraph_type_index == (
u16)~0)
781 last_matching_index = (
u32)~0;
782 last_index = node_index = graph_root_index;
790 last_index = node_index;
794 t += token_increment;
795 last_matching_index = node_index;
796 node_index = node->
deeper;
799 node_index = node->
peer;
807 if (graph_root_index == (
u32)~0)
812 subgraph_type->
rule_index = new_subgraph_index;
830 for (pr = lo; pr <
hi; pr = vlib_elf_section_data_next (pr, 0))
852 for (ptr = lo; ptr <
hi; ptr = vlib_elf_section_data_next (ptr, 0)) {
918 vlib_elf_section_bounds_t * b, * bounds;
944 _vec_len (pm->
tokens) = 0;
948 bounds = vlib_get_elf_section_bounds (vm,
"parse_type_registrations");
959 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 void(BVT(clib_bihash)*h, BVT(clib_bihash_value)*v)
static int compute_rule_length(parse_registration_t *r)
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
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
always_inline uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
#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)
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)
#define VLIB_INIT_FUNCTION(x)
vlib_parse_type_t * parse_types
vlib_parse_item_t * parse_items
always_inline void parse_cleanup_value(vlib_parse_main_t *pm, vlib_parse_value_t *pv)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static u8 * format_vlib_parse_item(u8 *s, va_list *args)
clib_error_t * vlib_stdlex_init(vlib_main_t *vm)
#define clib_warning(format, args...)
void dump_parse_graph(void)
#define vlib_call_init_function(vm, x)
static void tokenize(vlib_parse_main_t *pm, parse_registration_t *pr)
#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)
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)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
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).
vlib_parse_value_cleanup_function_t * value_cleanup_function
static int rule_length_compare(parse_registration_t *r1, parse_registration_t *r2)
void vlib_lex_reset(vlib_lex_main_t *lm, u8 *input_vector)
union vlib_lex_token_t::@31 value
union vlib_parse_item_t::@35 value
parse_registration_t ** parse_registrations
format_function_t * format_value
uword * parse_type_by_name_hash
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)
#define clib_error_return(e, args...)
always_inline void vlib_lex_cleanup_token(vlib_lex_token_t *t)
always_inline uword * mhash_get(mhash_t *h, void *key)