0ce716b539e619a5ba162b90cfb942d31ea2f266
[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,
23                                   vec_len (pm->match_items) - 1));
24   return i->value.as_pointer;
25 }
26
27 vlib_parse_match_t
28 eof_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
29            vlib_lex_token_t * t, vlib_parse_value_t * valuep)
30 {
31   return t->token ==
32     VLIB_LEX_eof ? VLIB_PARSE_MATCH_DONE : VLIB_PARSE_MATCH_FAIL;
33 }
34
35 PARSE_TYPE_INIT (eof, eof_match, 0 /* cleanup value */ ,
36                  0 /* format value */ );
37
38 vlib_parse_match_t
39 rule_eof_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
40                 vlib_lex_token_t * t, vlib_parse_value_t * valuep)
41 {
42   vlib_parse_match_function_t *fp = parse_last_match_value (pm);
43   pm->current_token_index--;
44   return fp ? fp (pm, type, t, valuep) : VLIB_PARSE_MATCH_RULE;
45 }
46
47 PARSE_TYPE_INIT (rule_eof, rule_eof_match, 0, 0);
48
49 vlib_parse_match_t
50 word_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
51             vlib_lex_token_t * t, vlib_parse_value_t * valuep)
52 {
53   u8 *tv, *iv;
54   int i;
55
56   if (t->token != VLIB_LEX_word)
57     return VLIB_PARSE_MATCH_FAIL;
58
59   tv = t->value.as_pointer;
60   iv = parse_last_match_value (pm);
61
62   for (i = 0; tv[i]; i++)
63     {
64       if (tv[i] != iv[i])
65         return VLIB_PARSE_MATCH_FAIL;
66     }
67
68   return iv[i] == 0 ? VLIB_PARSE_MATCH_FULL : VLIB_PARSE_MATCH_PARTIAL;
69 }
70
71 PARSE_TYPE_INIT (word, word_match, 0 /* clnup value */ ,
72                  0 /* format value */ );
73
74 vlib_parse_match_t
75 number_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
76               vlib_lex_token_t * t, vlib_parse_value_t * valuep)
77 {
78   if (t->token == VLIB_LEX_number)
79     {
80       valuep->value.as_uword = t->value.as_uword;
81       return VLIB_PARSE_MATCH_VALUE;
82     }
83   return VLIB_PARSE_MATCH_FAIL;
84 }
85
86 static u8 *
87 format_value_number (u8 * s, va_list * args)
88 {
89   vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *);
90   uword a = v->value.as_uword;
91
92   if (BITS (uword) == 64)
93     s = format (s, "%lld(0x%llx)", a, a);
94   else
95     s = format (s, "%ld(0x%lx)", a, a);
96   return s;
97 }
98
99 PARSE_TYPE_INIT (number, number_match, 0 /* cln value */ ,
100                  format_value_number /* fmt value */ );
101
102
103 #define foreach_vanilla_lex_match_function      \
104     _(plus)                                     \
105     _(minus)                                    \
106     _(star)                                     \
107     _(slash)                                    \
108     _(lpar)                                     \
109     _(rpar)
110
111 #define LEX_MATCH_DEBUG 0
112
113 #define _(name)                                                 \
114 vlib_parse_match_t name##_match (vlib_parse_main_t *pm,         \
115                                  vlib_parse_type_t *type,       \
116                                  vlib_lex_token_t *t,           \
117                                  vlib_parse_value_t *valuep)    \
118 {                                                               \
119   if (LEX_MATCH_DEBUG > 0)                                      \
120     clib_warning ("against %U returns %s",                      \
121                   format_vlib_lex_token, pm->lex_main, t,       \
122                   (t->token == VLIB_LEX_##name)                 \
123                   ? "VLIB_PARSE_MATCH_FULL" :                   \
124                   "VLIB_PARSE_MATCH_FAIL");                     \
125   if (t->token == VLIB_LEX_##name)                              \
126     return VLIB_PARSE_MATCH_FULL;                               \
127   return VLIB_PARSE_MATCH_FAIL;                                 \
128 }                                                               \
129                                                                 \
130 PARSE_TYPE_INIT (name, name##_match, 0 /* cln value */,         \
131                  0 /* fmt val */);
132
133 foreach_vanilla_lex_match_function
134 #undef _
135 /* So we're linked in. */
136 static clib_error_t *
137 parse_builtin_init (vlib_main_t * vm)
138 {
139   return 0;
140 }
141
142 VLIB_INIT_FUNCTION (parse_builtin_init);
143
144 /*
145  * fd.io coding-style-patch-verification: ON
146  *
147  * Local Variables:
148  * eval: (c-set-style "gnu")
149  * End:
150  */