Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2015, 2016 Nicira, Inc.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <config.h>
18 : : #include <ctype.h>
19 : : #include <errno.h>
20 : : #include <stdarg.h>
21 : : #include "openvswitch/dynamic-string.h"
22 : : #include "openvswitch/json.h"
23 : : #include "ovn/lex.h"
24 : : #include "packets.h"
25 : : #include "util.h"
26 : :
27 : : /* Returns a string that represents 'format'. */
28 : : const char *
29 : 0 : lex_format_to_string(enum lex_format format)
30 : : {
31 [ # # # # : 0 : switch (format) {
# # ]
32 : : case LEX_F_DECIMAL:
33 : 0 : return "decimal";
34 : : case LEX_F_HEXADECIMAL:
35 : 0 : return "hexadecimal";
36 : : case LEX_F_IPV4:
37 : 0 : return "IPv4";
38 : : case LEX_F_IPV6:
39 : 0 : return "IPv6";
40 : : case LEX_F_ETHERNET:
41 : 0 : return "Ethernet";
42 : : default:
43 : 0 : abort();
44 : : }
45 : : }
46 : :
47 : : /* Initializes 'token'. */
48 : : void
49 : 43727517 : lex_token_init(struct lex_token *token)
50 : : {
51 : 43727517 : token->type = LEX_T_END;
52 : 43727517 : token->s = NULL;
53 : 43727517 : }
54 : :
55 : : /* Frees memory owned by 'token'. */
56 : : void
57 : 48875094 : lex_token_destroy(struct lex_token *token)
58 : : {
59 [ + + ]: 48875094 : if (token->s != token->buffer) {
60 : 39326251 : free(token->s);
61 : : }
62 : 48875094 : token->s = NULL;
63 : 48875094 : }
64 : :
65 : : /* Exchanges 'a' and 'b'. */
66 : : void
67 : 1 : lex_token_swap(struct lex_token *a, struct lex_token *b)
68 : : {
69 : 1 : struct lex_token tmp = *a;
70 : 1 : *a = *b;
71 : 1 : *b = tmp;
72 : :
73 : : /* Before swap, if 's' was pointed to 'buffer', its value shall be changed
74 : : * to point to the 'buffer' with the copied value. */
75 [ - + ]: 1 : if (a->s == b->buffer) {
76 : 0 : a->s = a->buffer;
77 : : }
78 [ + - ]: 1 : if (b->s == a->buffer) {
79 : 1 : b->s = b->buffer;
80 : : }
81 : 1 : }
82 : :
83 : : /* The string 's' need not be null-terminated at 'length'. */
84 : : void
85 : 9548819 : lex_token_strcpy(struct lex_token *token, const char *s, size_t length)
86 : : {
87 : 9548819 : lex_token_destroy(token);
88 : 19097638 : token->s = (length + 1 <= sizeof token->buffer
89 : : ? token->buffer
90 [ + - ]: 9548819 : : xmalloc(length + 1));
91 : 9548819 : memcpy(token->s, s, length);
92 : 9548819 : token->buffer[length] = '\0';
93 : 9548819 : }
94 : :
95 : : void
96 : 350725 : lex_token_strset(struct lex_token *token, char *s)
97 : : {
98 : 350725 : lex_token_destroy(token);
99 : 350725 : token->s = s;
100 : 350725 : }
101 : :
102 : : void
103 : 24 : lex_token_vsprintf(struct lex_token *token, const char *format, va_list args)
104 : : {
105 : 24 : lex_token_destroy(token);
106 : :
107 : : va_list args2;
108 : 24 : va_copy(args2, args);
109 : 48 : token->s = (vsnprintf(token->buffer, sizeof token->buffer, format, args)
110 : 24 : < sizeof token->buffer
111 : : ? token->buffer
112 [ + - ]: 24 : : xvasprintf(format, args2));
113 : 24 : va_end(args2);
114 : 24 : }
115 : :
116 : : /* lex_token_format(). */
117 : :
118 : : static size_t
119 : 121 : lex_token_n_zeros(enum lex_format format)
120 : : {
121 [ + + + + : 121 : switch (format) {
+ - ]
122 : 33 : case LEX_F_DECIMAL: return offsetof(union mf_subvalue, integer);
123 : 11 : case LEX_F_HEXADECIMAL: return 0;
124 : 43 : case LEX_F_IPV4: return offsetof(union mf_subvalue, ipv4);
125 : 19 : case LEX_F_IPV6: return offsetof(union mf_subvalue, ipv6);
126 : 15 : case LEX_F_ETHERNET: return offsetof(union mf_subvalue, mac);
127 : 0 : default: OVS_NOT_REACHED();
128 : : }
129 : : }
130 : :
131 : : /* Returns the effective format for 'token', that is, the format in which it
132 : : * should actually be printed. This is ordinarily the same as 'token->format',
133 : : * but it's always possible that someone sets up a token with a format that
134 : : * won't work for a value, e.g. 'token->value' is wider than 32 bits but the
135 : : * format is LEX_F_IPV4. (The lexer itself won't do that; this is an attempt
136 : : * to avoid confusion in the future.) */
137 : : static enum lex_format
138 : 121 : lex_token_get_format(const struct lex_token *token)
139 : : {
140 : 121 : size_t n_zeros = lex_token_n_zeros(token->format);
141 [ + - ]: 242 : return (is_all_zeros(&token->value, n_zeros)
142 [ + + ]: 121 : && (token->type != LEX_T_MASKED_INTEGER
143 [ + - ]: 28 : || is_all_zeros(&token->mask, n_zeros))
144 : : ? token->format
145 : : : LEX_F_HEXADECIMAL);
146 : : }
147 : :
148 : : static void
149 : 134 : lex_token_format_value(const union mf_subvalue *value,
150 : : enum lex_format format, struct ds *s)
151 : : {
152 [ + + + + : 134 : switch (format) {
+ - ]
153 : : case LEX_F_DECIMAL:
154 : 38 : ds_put_format(s, "%"PRIu64, ntohll(value->integer));
155 : 38 : break;
156 : :
157 : : case LEX_F_HEXADECIMAL:
158 : 14 : mf_format_subvalue(value, s);
159 : 14 : break;
160 : :
161 : : case LEX_F_IPV4:
162 : 44 : ds_put_format(s, IP_FMT, IP_ARGS(value->ipv4));
163 : 44 : break;
164 : :
165 : : case LEX_F_IPV6:
166 : 20 : ipv6_format_addr(&value->ipv6, s);
167 : 20 : break;
168 : :
169 : : case LEX_F_ETHERNET:
170 : 18 : ds_put_format(s, ETH_ADDR_FMT, ETH_ADDR_ARGS(value->mac));
171 : 18 : break;
172 : :
173 : : default:
174 : 0 : OVS_NOT_REACHED();
175 : : }
176 : :
177 : 134 : }
178 : :
179 : : static void
180 : 28 : lex_token_format_masked_integer(const struct lex_token *token, struct ds *s)
181 : : {
182 : 28 : enum lex_format format = lex_token_get_format(token);
183 : :
184 : 28 : lex_token_format_value(&token->value, format, s);
185 : 28 : ds_put_char(s, '/');
186 : :
187 : 28 : const union mf_subvalue *mask = &token->mask;
188 [ + + ][ + + ]: 28 : if (format == LEX_F_IPV4 && ip_is_cidr(mask->ipv4)) {
189 : 11 : ds_put_format(s, "%d", ip_count_cidr_bits(mask->ipv4));
190 [ + + ][ + + ]: 17 : } else if (token->format == LEX_F_IPV6 && ipv6_is_cidr(&mask->ipv6)) {
191 : 4 : ds_put_format(s, "%d", ipv6_count_cidr_bits(&mask->ipv6));
192 : : } else {
193 : 13 : lex_token_format_value(&token->mask, format, s);
194 : : }
195 : 28 : }
196 : :
197 : : /* Appends a string representation of 'token' to 's', in a format that can be
198 : : * losslessly parsed back by the lexer. (LEX_T_END and LEX_T_ERROR can't be
199 : : * parsed back.) */
200 : : void
201 : 251 : lex_token_format(const struct lex_token *token, struct ds *s)
202 : : {
203 [ - + + + : 251 : switch (token->type) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
- ]
204 : : case LEX_T_END:
205 : 0 : ds_put_cstr(s, "$");
206 : 0 : break;
207 : :
208 : : case LEX_T_ID:
209 : 17 : ds_put_cstr(s, token->s);
210 : 17 : break;
211 : :
212 : : case LEX_T_ERROR:
213 : 23 : ds_put_cstr(s, "error(");
214 : 23 : json_string_escape(token->s, s);
215 : 23 : ds_put_char(s, ')');
216 : 23 : break;
217 : :
218 : : case LEX_T_STRING:
219 : 1 : json_string_escape(token->s, s);
220 : 1 : break;
221 : :
222 : : case LEX_T_INTEGER:
223 : 93 : lex_token_format_value(&token->value, lex_token_get_format(token), s);
224 : 93 : break;
225 : :
226 : : case LEX_T_MASKED_INTEGER:
227 : 28 : lex_token_format_masked_integer(token, s);
228 : 28 : break;
229 : :
230 : : case LEX_T_MACRO:
231 : 7 : ds_put_format(s, "$%s", token->s);
232 : 7 : break;
233 : :
234 : : case LEX_T_LPAREN:
235 : 3 : ds_put_cstr(s, "(");
236 : 3 : break;
237 : : case LEX_T_RPAREN:
238 : 9 : ds_put_cstr(s, ")");
239 : 9 : break;
240 : : case LEX_T_LCURLY:
241 : 1 : ds_put_cstr(s, "{");
242 : 1 : break;
243 : : case LEX_T_RCURLY:
244 : 1 : ds_put_cstr(s, "}");
245 : 1 : break;
246 : : case LEX_T_LSQUARE:
247 : 1 : ds_put_cstr(s, "[");
248 : 1 : break;
249 : : case LEX_T_RSQUARE:
250 : 2 : ds_put_cstr(s, "]");
251 : 2 : break;
252 : : case LEX_T_EQ:
253 : 1 : ds_put_cstr(s, "==");
254 : 1 : break;
255 : : case LEX_T_NE:
256 : 1 : ds_put_cstr(s, "!=");
257 : 1 : break;
258 : : case LEX_T_LT:
259 : 1 : ds_put_cstr(s, "<");
260 : 1 : break;
261 : : case LEX_T_LE:
262 : 1 : ds_put_cstr(s, "<=");
263 : 1 : break;
264 : : case LEX_T_GT:
265 : 1 : ds_put_cstr(s, ">");
266 : 1 : break;
267 : : case LEX_T_GE:
268 : 1 : ds_put_cstr(s, ">=");
269 : 1 : break;
270 : : case LEX_T_LOG_NOT:
271 : 1 : ds_put_cstr(s, "!");
272 : 1 : break;
273 : : case LEX_T_LOG_AND:
274 : 1 : ds_put_cstr(s, "&&");
275 : 1 : break;
276 : : case LEX_T_LOG_OR:
277 : 1 : ds_put_cstr(s, "||");
278 : 1 : break;
279 : : case LEX_T_ELLIPSIS:
280 : 1 : ds_put_cstr(s, "..");
281 : 1 : break;
282 : : case LEX_T_COMMA:
283 : 9 : ds_put_cstr(s, ",");
284 : 9 : break;
285 : : case LEX_T_SEMICOLON:
286 : 40 : ds_put_cstr(s, ";");
287 : 40 : break;
288 : : case LEX_T_EQUALS:
289 : 1 : ds_put_cstr(s, "=");
290 : 1 : break;
291 : : case LEX_T_EXCHANGE:
292 : 1 : ds_put_cstr(s, "<->");
293 : 1 : break;
294 : : case LEX_T_DECREMENT:
295 : 2 : ds_put_cstr(s, "--");
296 : 2 : break;
297 : : case LEX_T_COLON:
298 : 2 : ds_put_char(s, ':');
299 : 2 : break;
300 : : default:
301 : 0 : OVS_NOT_REACHED();
302 : : }
303 : :
304 : 251 : }
305 : :
306 : : /* lex_token_parse(). */
307 : :
308 : : static void OVS_PRINTF_FORMAT(2, 3)
309 : 24 : lex_error(struct lex_token *token, const char *message, ...)
310 : : {
311 [ - + ]: 24 : ovs_assert(!token->s);
312 : 24 : token->type = LEX_T_ERROR;
313 : :
314 : : va_list args;
315 : 24 : va_start(args, message);
316 : 24 : lex_token_vsprintf(token, message, args);
317 : 24 : va_end(args);
318 : 24 : }
319 : :
320 : : static void
321 : 2474031 : lex_parse_hex_integer(const char *start, size_t len, struct lex_token *token)
322 : : {
323 : 2474031 : const char *in = start + (len - 1);
324 : 2474031 : uint8_t *out = token->value.u8 + (sizeof token->value.u8 - 1);
325 : :
326 [ + + ]: 10916807 : for (int i = 0; i < len; i++) {
327 : 8442777 : int hexit = hexit_value(in[-i]);
328 [ + + ]: 8442777 : if (hexit < 0) {
329 : 1 : lex_error(token, "Invalid syntax in hexadecimal constant.");
330 : 1 : return;
331 : : }
332 [ + + ][ - + ]: 8442776 : if (hexit && i / 2 >= sizeof token->value.u8) {
333 : 0 : lex_error(token, "Hexadecimal constant requires more than "
334 : : "%"PRIuSIZE" bits.", 8 * sizeof token->value.u8);
335 : 0 : return;
336 : : }
337 [ + + ]: 8442776 : out[-(i / 2)] |= i % 2 ? hexit << 4 : hexit;
338 : : }
339 : 2474030 : token->format = LEX_F_HEXADECIMAL;
340 : : }
341 : :
342 : : static const char *
343 : 4800784 : lex_parse_integer__(const char *p, struct lex_token *token)
344 : : {
345 : 4800784 : lex_token_init(token);
346 : 4800784 : token->type = LEX_T_INTEGER;
347 : 4800784 : memset(&token->value, 0, sizeof token->value);
348 : :
349 : : /* Find the extent of an "integer" token, which can be in decimal or
350 : : * hexadecimal, or an Ethernet address or IPv4 or IPv6 address, as 'start'
351 : : * through 'end'.
352 : : *
353 : : * Special cases we handle here are:
354 : : *
355 : : * - The ellipsis token "..", used as e.g. 123..456. A doubled dot
356 : : * is never valid syntax as part of an "integer", so we stop if
357 : : * we encounter two dots in a row.
358 : : *
359 : : * - Syntax like 1.2.3.4:1234 to indicate an IPv4 address followed by a
360 : : * port number should be considered three tokens: 1.2.3.4 : 1234.
361 : : * The obvious approach is to allow just dots or just colons within a
362 : : * given integer, but that would disallow IPv4-mapped IPv6 addresses,
363 : : * e.g. ::ffff:192.0.2.128. However, even in those addresses, a
364 : : * colon never follows a dot, so we stop if we encounter a colon
365 : : * after a dot.
366 : : *
367 : : * (There is no corresponding way to parse an IPv6 address followed
368 : : * by a port number: ::1:2:3:4:1234 is unavoidably ambiguous.)
369 : : */
370 : 4800784 : const char *start = p;
371 : 4800784 : const char *end = start;
372 : 4800784 : bool saw_dot = false;
373 [ + + ]: 32265806 : while (isalnum((unsigned char) *end)
374 [ + + ][ + + ]: 7819497 : || (*end == ':' && !saw_dot)
375 [ + + ][ + + ]: 5514290 : || (*end == '.' && end[1] != '.')) {
376 [ + + ]: 27465022 : if (*end == '.') {
377 : 713506 : saw_dot = true;
378 : : }
379 : 27465022 : end++;
380 : : }
381 : 4800784 : size_t len = end - start;
382 : :
383 : : int n;
384 : : struct eth_addr mac;
385 : :
386 [ + + ]: 4800784 : if (!len) {
387 : 1 : lex_error(token, "Integer constant expected.");
388 [ + + ]: 4800783 : } else if (len == 17
389 [ + + ]: 327492 : && ovs_scan(start, ETH_ADDR_SCAN_FMT"%n",
390 : : ETH_ADDR_SCAN_ARGS(mac), &n)
391 [ + - ]: 317192 : && n == len) {
392 : 317192 : token->value.mac = mac;
393 : 317192 : token->format = LEX_F_ETHERNET;
394 [ + + ]: 4483591 : } else if (start + strspn(start, "0123456789") == end) {
395 [ + + ][ + + ]: 1616604 : if (p[0] == '0' && len > 1) {
396 : 1 : lex_error(token, "Decimal constants must not have leading zeros.");
397 : : } else {
398 : : unsigned long long int integer;
399 : : char *tail;
400 : :
401 : 1616603 : errno = 0;
402 : 1616603 : integer = strtoull(p, &tail, 10);
403 [ + - ][ + + ]: 1616603 : if (tail != end || errno == ERANGE) {
404 : 3 : lex_error(token, "Decimal constants must be less than 2**64.");
405 : : } else {
406 : 1616600 : token->value.integer = htonll(integer);
407 : 1616604 : token->format = LEX_F_DECIMAL;
408 : : }
409 : : }
410 [ + + ][ + + ]: 2866987 : } else if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
[ + + ]
411 [ + + ]: 4948066 : if (len > 2) {
412 : 2474031 : lex_parse_hex_integer(start + 2, len - 2, token);
413 : : } else {
414 : 2 : lex_error(token, "Hex digits expected following 0%c.", p[1]);
415 : : }
416 [ + - ]: 392954 : } else if (len < INET6_ADDRSTRLEN) {
417 : : char copy[INET6_ADDRSTRLEN];
418 : 392954 : memcpy(copy, p, len);
419 : 392954 : copy[len] = '\0';
420 : :
421 [ + + ]: 392954 : if (ip_parse(copy, &token->value.ipv4)) {
422 : 237830 : token->format = LEX_F_IPV4;
423 [ + + ]: 155124 : } else if (ipv6_parse(copy, &token->value.ipv6)) {
424 : 155121 : token->format = LEX_F_IPV6;
425 : : } else {
426 : 392954 : lex_error(token, "Invalid numeric constant.");
427 : : }
428 : : } else {
429 : 0 : lex_error(token, "Invalid numeric constant.");
430 : : }
431 : :
432 [ + + ][ - + ]: 4800784 : ovs_assert(token->type == LEX_T_INTEGER || token->type == LEX_T_ERROR);
433 : 4800784 : return end;
434 : : }
435 : :
436 : : static const char *
437 : 48794 : lex_parse_mask(const char *p, struct lex_token *token)
438 : : {
439 : : struct lex_token mask;
440 : :
441 : : /* Parse just past the '/' as a second integer. Handle errors. */
442 : 48794 : p = lex_parse_integer__(p + 1, &mask);
443 [ + + ]: 48794 : if (mask.type == LEX_T_ERROR) {
444 : 1 : lex_token_swap(&mask, token);
445 : 1 : lex_token_destroy(&mask);
446 : 1 : return p;
447 : : }
448 [ - + ]: 48793 : ovs_assert(mask.type == LEX_T_INTEGER);
449 : :
450 : : /* Now convert the value and mask into a masked integer token.
451 : : * We have a few special cases. */
452 : 48793 : token->type = LEX_T_MASKED_INTEGER;
453 : 48793 : memset(&token->mask, 0, sizeof token->mask);
454 : 48793 : uint32_t prefix_bits = ntohll(mask.value.integer);
455 [ + + ]: 48793 : if (token->format == mask.format) {
456 : : /* Same format value and mask is always OK. */
457 : 11974 : token->mask = mask.value;
458 [ + + ]: 36819 : } else if (token->format == LEX_F_IPV4
459 [ + - ]: 23524 : && mask.format == LEX_F_DECIMAL
460 [ + - ]: 23524 : && prefix_bits <= 32) {
461 : : /* IPv4 address with decimal mask is a CIDR prefix. */
462 : 23524 : token->mask.integer = htonll(ntohl(be32_prefix_mask(prefix_bits)));
463 [ + + ]: 13295 : } else if (token->format == LEX_F_IPV6
464 [ + - ]: 13285 : && mask.format == LEX_F_DECIMAL
465 [ + - ]: 13285 : && prefix_bits <= 128) {
466 : : /* IPv6 address with decimal mask is a CIDR prefix. */
467 : 13285 : token->mask.ipv6 = ipv6_create_mask(prefix_bits);
468 [ + - ]: 10 : } else if (token->format == LEX_F_DECIMAL
469 [ + - ]: 10 : && mask.format == LEX_F_HEXADECIMAL
470 [ + + ]: 10 : && token->value.integer == 0) {
471 : : /* Special case for e.g. 0/0x1234. */
472 : 9 : token->format = LEX_F_HEXADECIMAL;
473 : 9 : token->mask = mask.value;
474 : : } else {
475 : 1 : lex_error(token, "Value and mask have incompatible formats.");
476 : 1 : return p;
477 : : }
478 : :
479 : : /* Check invariant that a 1-bit in the value corresponds to a 1-bit in the
480 : : * mask. */
481 [ + + ]: 1610131 : for (int i = 0; i < ARRAY_SIZE(token->mask.be32); i++) {
482 : 1561343 : ovs_be32 v = token->value.be32[i];
483 : 1561343 : ovs_be32 m = token->mask.be32[i];
484 : :
485 [ + + ]: 1561343 : if (v & ~m) {
486 : 4 : lex_error(token, "Value contains unmasked 1-bits.");
487 : 4 : break;
488 : : }
489 : : }
490 : :
491 : : /* Done! */
492 : 48792 : lex_token_destroy(&mask);
493 : 48794 : return p;
494 : : }
495 : :
496 : : static const char *
497 : 4751990 : lex_parse_integer(const char *p, struct lex_token *token)
498 : : {
499 : 4751990 : p = lex_parse_integer__(p, token);
500 [ + + ][ + + ]: 4751990 : if (token->type == LEX_T_INTEGER && *p == '/') {
501 : 48794 : p = lex_parse_mask(p, token);
502 : : }
503 : 4751990 : return p;
504 : : }
505 : :
506 : : static const char *
507 : 350726 : lex_parse_string(const char *p, struct lex_token *token)
508 : : {
509 : 350726 : const char *start = ++p;
510 : 350726 : char * s = NULL;
511 : : for (;;) {
512 [ + + + + ]: 2455996 : switch (*p) {
513 : : case '\0':
514 : 1 : lex_error(token, "Input ends inside quoted string.");
515 : 1 : return p;
516 : :
517 : : case '"':
518 [ + - ]: 350725 : token->type = (json_string_unescape(start, p - start, &s)
519 : : ? LEX_T_STRING : LEX_T_ERROR);
520 : 350725 : lex_token_strset(token, s);
521 : 350725 : return p + 1;
522 : :
523 : : case '\\':
524 : 1 : p++;
525 [ + - ]: 1 : if (*p) {
526 : 1 : p++;
527 : : }
528 : 1 : break;
529 : :
530 : : default:
531 : 2105269 : p++;
532 : 2105269 : break;
533 : : }
534 : 2455996 : }
535 : : }
536 : :
537 : : static bool
538 : 59796347 : lex_is_id1(unsigned char c)
539 : : {
540 [ + + ][ + + ]: 119592694 : return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
[ + - ]
541 [ + + ][ + + ]: 119592694 : || c == '_' || c == '.');
[ + + ]
542 : : }
543 : :
544 : : static bool
545 : 54107117 : lex_is_idn(unsigned char c)
546 : : {
547 [ + + ][ + + ]: 54107117 : return lex_is_id1(c) || (c >= '0' && c <= '9');
[ + + ]
548 : : }
549 : :
550 : : static const char *
551 : 9548819 : lex_parse_id(const char *p, enum lex_type type, struct lex_token *token)
552 : : {
553 : 9548819 : const char *start = p;
554 : :
555 : : do {
556 : 54107117 : p++;
557 [ + + ]: 54107117 : } while (lex_is_idn(*p));
558 : :
559 : 9548819 : token->type = type;
560 : 9548819 : lex_token_strcpy(token, start, p - start);
561 : 9548819 : return p;
562 : : }
563 : :
564 : : static const char *
565 : 132 : lex_parse_macro(const char *p, struct lex_token *token)
566 : : {
567 : 132 : p++;
568 [ + + ]: 132 : if (!lex_is_id1(*p)) {
569 : 1 : lex_error(token, "`$' must be followed by a valid identifier.");
570 : 1 : return p;
571 : : }
572 : :
573 : 131 : return lex_parse_id(p, LEX_T_MACRO, token);
574 : : }
575 : :
576 : : /* Initializes 'token' and parses the first token from the beginning of
577 : : * null-terminated string 'p' into 'token'. Stores a pointer to the start of
578 : : * the token (after skipping white space and comments, if any) into '*startp'.
579 : : * Returns the character position at which to begin parsing the next token. */
580 : : const char *
581 : 32212745 : lex_token_parse(struct lex_token *token, const char *p, const char **startp)
582 : : {
583 : 32212745 : lex_token_init(token);
584 : :
585 : : next:
586 : 47357042 : *startp = p;
587 [ + + + + : 47357042 : switch (*p) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ ]
588 : : case '\0':
589 : 6713317 : token->type = LEX_T_END;
590 : 6713317 : return p;
591 : :
592 : : case ' ': case '\t': case '\n': case '\r':
593 : 15099516 : p++;
594 : 15099516 : goto next;
595 : :
596 : : case '/':
597 : 44783 : p++;
598 [ + + ]: 44783 : if (*p == '/') {
599 : : do {
600 : 4 : p++;
601 [ + + ][ + - ]: 4 : } while (*p != '\0' && *p != '\n');
602 : 1 : goto next;
603 [ + + ]: 44782 : } else if (*p == '*') {
604 : 44781 : p++;
605 : : for (;;) {
606 [ + + ][ + + ]: 537349 : if (*p == '*' && p[1] == '/') {
607 : 44780 : p += 2;
608 : 44780 : goto next;
609 [ + + ][ - + ]: 492569 : } else if (*p == '\0' || *p == '\n') {
610 : 1 : lex_error(token, "`/*' without matching `*/'.");
611 : 1 : return p;
612 : : } else {
613 : 492568 : p++;
614 : : }
615 : 492568 : }
616 : : goto next;
617 : : } else {
618 : 1 : lex_error(token,
619 : : "`/' is only valid as part of `//' or `/*'.");
620 : : }
621 : 1 : break;
622 : :
623 : : case '(':
624 : 147102 : token->type = LEX_T_LPAREN;
625 : 147102 : p++;
626 : 147102 : break;
627 : :
628 : : case ')':
629 : 108027 : token->type = LEX_T_RPAREN;
630 : 108027 : p++;
631 : 108027 : break;
632 : :
633 : : case '{':
634 : 117488 : token->type = LEX_T_LCURLY;
635 : 117488 : p++;
636 : 117488 : break;
637 : :
638 : : case '}':
639 : 101621 : token->type = LEX_T_RCURLY;
640 : 101621 : p++;
641 : 101621 : break;
642 : :
643 : : case '[':
644 : 238614 : token->type = LEX_T_LSQUARE;
645 : 238614 : p++;
646 : 238614 : break;
647 : :
648 : : case ']':
649 : 238296 : token->type = LEX_T_RSQUARE;
650 : 238296 : p++;
651 : 238296 : break;
652 : :
653 : : case '=':
654 : 5555509 : p++;
655 [ + + ]: 5555509 : if (*p == '=') {
656 : 3878636 : token->type = LEX_T_EQ;
657 : 3878636 : p++;
658 : : } else {
659 : 1676873 : token->type = LEX_T_EQUALS;
660 : : }
661 : 5555509 : break;
662 : :
663 : : case '!':
664 : 83180 : p++;
665 [ + + ]: 83180 : if (*p == '=') {
666 : 9944 : token->type = LEX_T_NE;
667 : 9944 : p++;
668 : : } else {
669 : 73236 : token->type = LEX_T_LOG_NOT;
670 : : }
671 : 83180 : break;
672 : :
673 : : case '&':
674 : 946866 : p++;
675 [ + + ]: 946866 : if (*p == '&') {
676 : 946865 : token->type = LEX_T_LOG_AND;
677 : 946865 : p++;
678 : : } else {
679 : 1 : lex_error(token, "`&' is only valid as part of `&&'.");
680 : : }
681 : 946866 : break;
682 : :
683 : : case '|':
684 : 767592 : p++;
685 [ + + ]: 767592 : if (*p == '|') {
686 : 767591 : token->type = LEX_T_LOG_OR;
687 : 767591 : p++;
688 : : } else {
689 : 1 : lex_error(token, "`|' is only valid as part of `||'.");
690 : : }
691 : 767592 : break;
692 : :
693 : : case '<':
694 : 89402 : p++;
695 [ + + ]: 89402 : if (*p == '=') {
696 : 19730 : token->type = LEX_T_LE;
697 : 19730 : p++;
698 [ + + ][ + - ]: 69672 : } else if (*p == '-' && p[1] == '>') {
699 : 49946 : token->type = LEX_T_EXCHANGE;
700 : 49946 : p += 2;
701 : : } else {
702 : 19726 : token->type = LEX_T_LT;
703 : : }
704 : 89402 : break;
705 : :
706 : : case '>':
707 : 39457 : p++;
708 [ + + ]: 39457 : if (*p == '=') {
709 : 19726 : token->type = LEX_T_GE;
710 : 19726 : p++;
711 : : } else {
712 : 19731 : token->type = LEX_T_GT;
713 : : }
714 : 39457 : break;
715 : :
716 : : case '.':
717 : 62687 : p++;
718 [ + - ]: 62687 : if (*p == '.') {
719 : 62687 : token->type = LEX_T_ELLIPSIS;
720 : 62687 : p++;
721 : : } else {
722 : 0 : lex_error(token, "`.' is only valid as part of `..' or a number.");
723 : : }
724 : 62687 : break;
725 : :
726 : : case ',':
727 : 114985 : p++;
728 : 114985 : token->type = LEX_T_COMMA;
729 : 114985 : break;
730 : :
731 : : case ';':
732 : 2185375 : p++;
733 : 2185375 : token->type = LEX_T_SEMICOLON;
734 : 2185375 : break;
735 : :
736 : : case '-':
737 : 51629 : p++;
738 [ + + ]: 51629 : if (*p == '-') {
739 : 51628 : token->type = LEX_T_DECREMENT;
740 : 51628 : p++;
741 : : } else {
742 : 1 : lex_error(token, "`-' is only valid as part of `--'.");
743 : : }
744 : 51629 : break;
745 : :
746 : : case '$':
747 : 132 : p = lex_parse_macro(p, token);
748 : 132 : break;
749 : :
750 : : case ':':
751 [ + + ]: 543 : if (p[1] != ':') {
752 : 59 : token->type = LEX_T_COLON;
753 : 59 : p++;
754 : 59 : break;
755 : : }
756 : : /* IPv6 address beginning with "::". Fall through. */
757 : : case '0': case '1': case '2': case '3': case '4':
758 : : case '5': case '6': case '7': case '8': case '9':
759 : 4433637 : p = lex_parse_integer(p, token);
760 : 4433637 : break;
761 : :
762 : : case '"':
763 : 350726 : p = lex_parse_string(p, token);
764 : 350726 : break;
765 : :
766 : : case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
767 : : case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
768 : : /* We need to distinguish an Ethernet address or IPv6 address from an
769 : : * identifier. Fortunately, Ethernet addresses and IPv6 addresses that
770 : : * are ambiguous based on the first character, always start with hex
771 : : * digits followed by a colon, but identifiers never do. */
772 : 8355888 : p = (p[strspn(p, "0123456789abcdefABCDEF")] == ':'
773 : : ? lex_parse_integer(p, token)
774 [ + + ]: 4177944 : : lex_parse_id(p, LEX_T_ID, token));
775 : 4177944 : break;
776 : :
777 : : default:
778 [ + + ]: 5689098 : if (lex_is_id1(*p)) {
779 : 5689097 : p = lex_parse_id(p, LEX_T_ID, token);
780 : : } else {
781 [ + - ]: 1 : if (isprint((unsigned char) *p)) {
782 : 1 : lex_error(token, "Invalid character `%c' in input.", *p);
783 : : } else {
784 : 0 : lex_error(token, "Invalid byte 0x%d in input.", *p);
785 : : }
786 : 1 : p++;
787 : : }
788 : 5689098 : break;
789 : : }
790 : :
791 : 25499427 : return p;
792 : : }
793 : :
794 : : /* Initializes 'lexer' for parsing 'input'.
795 : : *
796 : : * While the lexer is in use, 'input' must remain available, but the caller
797 : : * otherwise retains ownership of 'input'.
798 : : *
799 : : * The caller must call lexer_get() to obtain the first token. */
800 : : void
801 : 6713988 : lexer_init(struct lexer *lexer, const char *input)
802 : : {
803 : 6713988 : lexer->input = input;
804 : 6713988 : lexer->start = NULL;
805 : 6713988 : lex_token_init(&lexer->token);
806 : 6713988 : lexer->error = NULL;
807 : 6713988 : }
808 : :
809 : : /* Frees storage associated with 'lexer'. */
810 : : void
811 : 6713988 : lexer_destroy(struct lexer *lexer)
812 : : {
813 : 6713988 : lex_token_destroy(&lexer->token);
814 : 6713988 : free(lexer->error);
815 : 6713988 : }
816 : :
817 : : /* Obtains the next token from 'lexer' into 'lexer->token', and returns the
818 : : * token's type. The caller may examine 'lexer->token' directly to obtain full
819 : : * information about the token. */
820 : : enum lex_type
821 : 30650936 : lexer_get(struct lexer *lexer)
822 : : {
823 : 30650936 : lex_token_destroy(&lexer->token);
824 : 30650936 : lexer->input = lex_token_parse(&lexer->token, lexer->input, &lexer->start);
825 : 30650936 : return lexer->token.type;
826 : : }
827 : :
828 : : /* Returns the type of the next token that will be fetched by lexer_get(),
829 : : * without advancing 'lexer->token' to that token. */
830 : : enum lex_type
831 : 1561809 : lexer_lookahead(const struct lexer *lexer)
832 : : {
833 : : struct lex_token next;
834 : : enum lex_type type;
835 : : const char *start;
836 : :
837 : 1561809 : lex_token_parse(&next, lexer->input, &start);
838 : 1561809 : type = next.type;
839 : 1561809 : lex_token_destroy(&next);
840 : 1561809 : return type;
841 : : }
842 : :
843 : : /* If 'lexer''s current token has the given 'type', advances 'lexer' to the
844 : : * next token and returns true. Otherwise returns false. */
845 : : bool
846 : 35074058 : lexer_match(struct lexer *lexer, enum lex_type type)
847 : : {
848 [ + + ]: 35074058 : if (lexer->token.type == type) {
849 : 3752209 : lexer_get(lexer);
850 : 3752209 : return true;
851 : : } else {
852 : 31321849 : return false;
853 : : }
854 : : }
855 : :
856 : : bool
857 : 1946712 : lexer_force_match(struct lexer *lexer, enum lex_type t)
858 : : {
859 [ + + ]: 1946712 : if (lexer_match(lexer, t)) {
860 : 1946653 : return true;
861 : : } else {
862 : 59 : struct lex_token token = { .type = t };
863 : 59 : struct ds s = DS_EMPTY_INITIALIZER;
864 : 59 : lex_token_format(&token, &s);
865 : :
866 : 59 : lexer_syntax_error(lexer, "expecting `%s'", ds_cstr(&s));
867 : :
868 : 59 : ds_destroy(&s);
869 : :
870 : 59 : return false;
871 : : }
872 : : }
873 : :
874 : : /* If 'lexer''s current token is the identifier given in 'id', advances 'lexer'
875 : : * to the next token and returns true. Otherwise returns false. */
876 : : bool
877 : 1529181 : lexer_match_id(struct lexer *lexer, const char *id)
878 : : {
879 [ + - ][ + + ]: 1529181 : if (lexer->token.type == LEX_T_ID && !strcmp(lexer->token.s, id)) {
880 : 639628 : lexer_get(lexer);
881 : 639628 : return true;
882 : : } else {
883 : 889553 : return false;
884 : : }
885 : : }
886 : :
887 : : bool
888 : 301049 : lexer_is_int(const struct lexer *lexer)
889 : : {
890 : 301049 : return (lexer->token.type == LEX_T_INTEGER
891 [ + + ]: 301046 : && lexer->token.format == LEX_F_DECIMAL
892 [ + + ][ + + ]: 602095 : && ntohll(lexer->token.value.integer) <= INT_MAX);
893 : : }
894 : :
895 : : bool
896 : 300994 : lexer_get_int(struct lexer *lexer, int *value)
897 : : {
898 [ + + ]: 300994 : if (lexer_is_int(lexer)) {
899 : 300990 : *value = ntohll(lexer->token.value.integer);
900 : 300990 : lexer_get(lexer);
901 : 300990 : return true;
902 : : } else {
903 : 4 : *value = 0;
904 : 4 : return false;
905 : : }
906 : : }
907 : :
908 : : bool
909 : 300994 : lexer_force_int(struct lexer *lexer, int *value)
910 : : {
911 : 300994 : bool ok = lexer_get_int(lexer, value);
912 [ + + ]: 300994 : if (!ok) {
913 : 4 : lexer_syntax_error(lexer, "expecting small integer");
914 : : }
915 : 300994 : return ok;
916 : : }
917 : :
918 : : void
919 : 6158723 : lexer_force_end(struct lexer *lexer)
920 : : {
921 [ + + ]: 6158723 : if (lexer->token.type != LEX_T_END) {
922 : 24 : lexer_syntax_error(lexer, "expecting end of input");
923 : : }
924 : 6158723 : }
925 : :
926 : : static bool
927 : 191 : lexer_error_handle_common(struct lexer *lexer)
928 : : {
929 [ + + ]: 191 : if (lexer->error) {
930 : : /* Already have an error, suppress this one since the cascade seems
931 : : * unlikely to be useful. */
932 : 74 : return true;
933 [ + + ]: 117 : } else if (lexer->token.type == LEX_T_ERROR) {
934 : : /* The lexer signaled an error. Nothing at a higher level accepts an
935 : : * error token, so we'll inevitably end up here with some meaningless
936 : : * parse error. Report the lexical error instead. */
937 : 1 : lexer->error = xstrdup(lexer->token.s);
938 : 1 : return true;
939 : : } else {
940 : 116 : return false;
941 : : }
942 : : }
943 : :
944 : : void OVS_PRINTF_FORMAT(2, 3)
945 : 55 : lexer_error(struct lexer *lexer, const char *message, ...)
946 : : {
947 [ - + ]: 55 : if (lexer_error_handle_common(lexer)) {
948 : 0 : return;
949 : : }
950 : :
951 : : va_list args;
952 : 55 : va_start(args, message);
953 : 55 : lexer->error = xvasprintf(message, args);
954 : 55 : va_end(args);
955 : : }
956 : :
957 : : void OVS_PRINTF_FORMAT(2, 3)
958 : 136 : lexer_syntax_error(struct lexer *lexer, const char *message, ...)
959 : : {
960 [ + + ]: 136 : if (lexer_error_handle_common(lexer)) {
961 : 75 : return;
962 : : }
963 : :
964 : : struct ds s;
965 : :
966 : 61 : ds_init(&s);
967 : 61 : ds_put_cstr(&s, "Syntax error");
968 [ + + ]: 61 : if (lexer->token.type == LEX_T_END) {
969 : 3 : ds_put_cstr(&s, " at end of input");
970 [ + - ]: 58 : } else if (lexer->start) {
971 : 58 : ds_put_format(&s, " at `%.*s'",
972 : 58 : (int) (lexer->input - lexer->start),
973 : : lexer->start);
974 : : }
975 : :
976 [ + + ]: 61 : if (message) {
977 : 57 : ds_put_char(&s, ' ');
978 : :
979 : : va_list args;
980 : 57 : va_start(args, message);
981 : 57 : ds_put_format_valist(&s, message, args);
982 : 57 : va_end(args);
983 : : }
984 : 61 : ds_put_char(&s, '.');
985 : :
986 : 61 : lexer->error = ds_steal_cstr(&s);
987 : : }
988 : :
989 : : char *
990 : 6713256 : lexer_steal_error(struct lexer *lexer)
991 : : {
992 : 6713256 : char *error = lexer->error;
993 : 6713256 : lexer->error = NULL;
994 : 6713256 : return error;
995 : : }
|