Initial commit of vpp code.
[vpp.git] / vlib / vlib / parse_builtin.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vlib/parse.h>
16
17 always_inline void *
18 parse_last_match_value (vlib_parse_main_t * pm)
19 {
20   vlib_parse_item_t * i;
21   i = pool_elt_at_index (pm->parse_items,
22                          vec_elt (pm->match_items, vec_len (pm->match_items) - 1));
23   return i->value.as_pointer;
24 }
25
26 vlib_parse_match_t eof_match (vlib_parse_main_t *pm, vlib_parse_type_t *type, 
27                               vlib_lex_token_t *t, vlib_parse_value_t *valuep)
28 { return t->token == VLIB_LEX_eof ? VLIB_PARSE_MATCH_DONE : VLIB_PARSE_MATCH_FAIL; }
29
30 PARSE_TYPE_INIT (eof, eof_match, 0 /* cleanup value */, 0 /* format value */);
31
32 vlib_parse_match_t rule_eof_match (vlib_parse_main_t *pm, vlib_parse_type_t *type, 
33                               vlib_lex_token_t *t, vlib_parse_value_t *valuep)
34 {
35   vlib_parse_match_function_t * fp = parse_last_match_value (pm);
36   pm->current_token_index--;
37   return fp ? fp (pm, type, t, valuep) : VLIB_PARSE_MATCH_RULE;
38 }
39
40 PARSE_TYPE_INIT (rule_eof, rule_eof_match, 0, 0);
41
42 vlib_parse_match_t word_match (vlib_parse_main_t *pm, vlib_parse_type_t *type, 
43                           vlib_lex_token_t *t, vlib_parse_value_t *valuep)
44 {
45   u8 * tv, * iv;
46   int i;
47
48   if (t->token != VLIB_LEX_word)
49     return VLIB_PARSE_MATCH_FAIL;
50
51   tv = t->value.as_pointer;
52   iv = parse_last_match_value (pm);
53
54   for (i = 0; tv[i]; i++)
55     {
56       if (tv[i] != iv[i])
57         return VLIB_PARSE_MATCH_FAIL;
58     }
59
60   return iv[i] == 0 ? VLIB_PARSE_MATCH_FULL : VLIB_PARSE_MATCH_PARTIAL;
61 }
62
63 PARSE_TYPE_INIT (word, word_match, 0 /* clnup value */, 0 /* format value */);
64
65 vlib_parse_match_t number_match (vlib_parse_main_t *pm, vlib_parse_type_t *type, 
66                                  vlib_lex_token_t *t, vlib_parse_value_t *valuep)
67 {
68   if (t->token == VLIB_LEX_number)
69     {
70       valuep->value.as_uword = t->value.as_uword;
71       return VLIB_PARSE_MATCH_VALUE;
72     }
73   return VLIB_PARSE_MATCH_FAIL;
74 }
75
76 static u8 * format_value_number (u8 * s, va_list * args)
77 {
78   vlib_parse_value_t * v = va_arg (*args, vlib_parse_value_t *);
79   uword a = v->value.as_uword;
80
81   if (BITS(uword) == 64) 
82     s = format (s, "%lld(0x%llx)", a, a);
83   else 
84     s = format (s, "%ld(0x%lx)", a, a);
85   return s;
86 }
87
88 PARSE_TYPE_INIT (number, number_match, 0 /* cln value */, 
89                  format_value_number /* fmt value */);
90
91
92 #define foreach_vanilla_lex_match_function      \
93     _(plus)                                     \
94     _(minus)                                    \
95     _(star)                                     \
96     _(slash)                                    \
97     _(lpar)                                     \
98     _(rpar)
99
100 #define LEX_MATCH_DEBUG 0
101
102 #define _(name)                                                 \
103 vlib_parse_match_t name##_match (vlib_parse_main_t *pm,         \
104                                  vlib_parse_type_t *type,       \
105                                  vlib_lex_token_t *t,           \
106                                  vlib_parse_value_t *valuep)    \
107 {                                                               \
108   if (LEX_MATCH_DEBUG > 0)                                      \
109     clib_warning ("against %U returns %s",                      \
110                   format_vlib_lex_token, pm->lex_main, t,       \
111                   (t->token == VLIB_LEX_##name)                 \
112                   ? "VLIB_PARSE_MATCH_FULL" :                   \
113                   "VLIB_PARSE_MATCH_FAIL");                     \
114   if (t->token == VLIB_LEX_##name)                              \
115     return VLIB_PARSE_MATCH_FULL;                               \
116   return VLIB_PARSE_MATCH_FAIL;                                 \
117 }                                                               \
118                                                                 \
119 PARSE_TYPE_INIT (name, name##_match, 0 /* cln value */,         \
120                  0 /* fmt val */);
121
122 foreach_vanilla_lex_match_function
123 #undef _
124
125 /* So we're linked in. */
126 static clib_error_t *
127 parse_builtin_init (vlib_main_t * vm)
128 {
129   return 0;
130 }
131
132 VLIB_INIT_FUNCTION (parse_builtin_init);