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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 #include <vppinfra/format.h>
40 /* Call user's function to fill input buffer. */
42 _unformat_fill_input (unformat_input_t * i)
46 if (i->index == UNFORMAT_END_OF_INPUT)
49 first_mark = l = vec_len (i->buffer);
50 if (vec_len (i->buffer_marks) > 0)
51 first_mark = i->buffer_marks[0];
53 /* Re-use buffer when no marks. */
55 vec_delete (i->buffer, first_mark, 0);
57 i->index = vec_len (i->buffer);
58 for (l = 0; l < vec_len (i->buffer_marks); l++)
59 i->buffer_marks[l] -= first_mark;
61 /* Call user's function to fill the buffer. */
63 i->index = i->fill_buffer (i);
65 /* If input pointer is still beyond end of buffer even after
66 fill then we've run out of input. */
67 if (i->index >= vec_len (i->buffer))
68 i->index = UNFORMAT_END_OF_INPUT;
74 is_white_space (uword c)
89 /* Format function for dumping input stream. */
91 format_unformat_error (u8 * s, va_list * va)
93 unformat_input_t *i = va_arg (*va, unformat_input_t *);
94 uword l = vec_len (i->buffer);
96 /* Only show so much of the input buffer (it could be really large). */
101 uword n = l - i->index;
104 p = i->buffer + i->index;
105 p_end = p + (n > n_max ? n_max : n);
107 /* Skip white space at end. */
110 while (p_end > p && is_white_space (p_end[-1]))
119 vec_add (s, "\\r", 2);
122 vec_add (s, "\\n", 2);
125 vec_add (s, "\\t", 2);
135 vec_add (s, "...", 3);
141 /* Print everything: not just error context. */
143 format_unformat_input (u8 * s, va_list * va)
145 unformat_input_t *i = va_arg (*va, unformat_input_t *);
148 if (i->index == UNFORMAT_END_OF_INPUT)
149 s = format (s, "{END_OF_INPUT}");
152 l = vec_len (i->buffer);
155 vec_add (s, i->buffer + i->index, n);
163 di (unformat_input_t * i)
165 fformat (stderr, "%U\n", format_unformat_input, i);
169 /* Parse delimited vector string. If string starts with { then string
170 is delimited by balenced parenthesis. Other string is delimited by
171 white space. {} were chosen since they are special to the shell. */
173 unformat_string (unformat_input_t * input,
174 uword delimiter_character,
175 uword format_character, va_list * va)
177 u8 **string_return = va_arg (*va, u8 **);
180 word is_paren_delimited = 0;
184 switch (delimiter_character)
189 delimiter_character = 0;
193 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
197 /* Null return string means to skip over delimited input. */
198 add_to_vector = string_return != 0;
211 if (paren == 0 && vec_len (s) == 0)
213 is_paren_delimited = 1;
221 if (is_paren_delimited && paren == 0)
229 if (!is_paren_delimited)
231 unformat_put_input (input);
237 if (!is_paren_delimited && c == delimiter_character)
239 unformat_put_input (input);
251 /* Match the string { END-OF-INPUT as a single brace. */
252 if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0 && paren == 1)
255 /* Don't match null string. */
256 if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0)
259 /* Null terminate C string. */
260 if (format_character == 's')
266 vec_free (s); /* just to make sure */
272 unformat_hex_string (unformat_input_t * input, va_list * va)
274 u8 **hexstring_return = va_arg (*va, u8 **);
281 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
283 if (c >= '0' && c <= '9')
284 d = 16 * d + c - '0';
285 else if (c >= 'a' && c <= 'f')
286 d = 16 * d + 10 + c - 'a';
287 else if (c >= 'A' && c <= 'F')
288 d = 16 * d + 10 + c - 'A';
291 unformat_put_input (input);
303 /* Hex string must have even number of digits. */
309 /* Make sure something was processed. */
315 *hexstring_return = s;
319 /* unformat (input "foo%U", unformat_eof) matches terminal foo only */
321 unformat_eof (unformat_input_t * input, va_list * va)
323 return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
326 /* Parse a token containing given set of characters. */
328 unformat_token (unformat_input_t * input, va_list * va)
330 u8 *token_chars = va_arg (*va, u8 *);
331 u8 **string_return = va_arg (*va, u8 **);
336 token_chars = (u8 *) "a-zA-Z0-9_";
338 memset (map, 0, sizeof (map));
339 for (s = token_chars; *s;)
342 if (s[0] < s[2] && s[1] == '-')
344 for (i = s[0]; i <= s[2]; i++)
356 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
360 unformat_put_input (input);
367 if (vec_len (s) == 0)
374 /* Unformat (parse) function which reads a %s string and converts it
375 to and unformat_input_t. */
377 unformat_input (unformat_input_t * i, va_list * args)
379 unformat_input_t *sub_input = va_arg (*args, unformat_input_t *);
382 if (unformat (i, "%v", &s))
384 unformat_init_vector (sub_input, s);
391 /* Parse a line ending with \n and return it. */
393 unformat_line (unformat_input_t * i, va_list * va)
395 u8 *line = 0, **result = va_arg (*va, u8 **);
398 while ((c = unformat_get_input (i)) != '\n' && c != UNFORMAT_END_OF_INPUT)
404 return vec_len (line);
407 /* Parse a line ending with \n and return it as an unformat_input_t. */
409 unformat_line_input (unformat_input_t * i, va_list * va)
411 unformat_input_t *result = va_arg (*va, unformat_input_t *);
413 if (!unformat_user (i, unformat_line, &line))
415 unformat_init_vector (result, line);
419 /* Values for is_signed. */
420 #define UNFORMAT_INTEGER_SIGNED 1
421 #define UNFORMAT_INTEGER_UNSIGNED 0
424 unformat_integer (unformat_input_t * input,
425 va_list * va, uword base, uword is_signed, uword data_bytes)
433 /* We only support bases <= 64. */
434 if (base < 2 || base > 64)
437 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
450 /* Leading sign for unsigned number. */
453 /* Sign after input (e.g. 100-200). */
467 digit = 10 + (c - 'a');
471 digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
489 unformat_put_input (input);
494 uword new_value = base * value + digit;
496 /* Check for overflow. */
497 if (new_value < value)
513 void *v = va_arg (*va, void *);
515 if (data_bytes == ~0)
516 data_bytes = sizeof (int);
545 times_power_of_ten (f64 x, int n)
549 static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
559 static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
571 unformat_float (unformat_input_t * input, va_list * va)
575 uword n_digits[3], value_index = 0;
576 uword signs[2], sign_index = 0;
579 memset (values, 0, sizeof (values));
580 memset (n_digits, 0, sizeof (n_digits));
581 memset (signs, 0, sizeof (signs));
583 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
588 if (value_index == 2 && n_digits[2] == 0)
589 /* sign of exponent: it's ok. */ ;
591 else if (value_index < 2 && n_digits[0] > 0)
594 unformat_put_input (input);
598 else if (n_input > 0)
601 signs[sign_index++] = 1;
605 if (value_index == 2 && n_digits[2] == 0)
606 /* sign of exponent: it's ok. */ ;
608 else if (value_index < 2 && n_digits[0] > 0)
611 unformat_put_input (input);
615 else if (n_input > 0)
617 signs[sign_index++] = 0;
638 tmp = values[value_index] * 10 + c - '0';
640 /* Check for overflow. */
641 if (tmp < values[value_index])
643 values[value_index] = tmp;
644 n_digits[value_index] += 1;
649 unformat_put_input (input);
659 f64 f_values[2], *value_return;
662 /* Must have either whole or fraction digits. */
663 if (n_digits[0] + n_digits[1] <= 0)
666 f_values[0] = values[0];
668 f_values[0] = -f_values[0];
670 f_values[1] = values[1];
671 f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
673 f_values[0] += f_values[1];
679 f_values[0] = times_power_of_ten (f_values[0], expon);
681 value_return = va_arg (*va, f64 *);
682 *value_return = f_values[0];
691 match_input_with_format (unformat_input_t * input, const char *f)
700 if (cf == 0 || cf == '%' || cf == ' ')
704 ci = unformat_get_input (input);
713 do_percent (unformat_input_t * input, va_list * va, const char *f)
715 uword cf, n, data_bytes = ~0;
727 data_bytes = sizeof (uword);
735 data_bytes = sizeof (long long);
739 data_bytes = sizeof (long);
745 data_bytes = sizeof (long long);
753 data_bytes = va_arg (*va, int);
755 n = unformat_integer (input, va, 10,
756 UNFORMAT_INTEGER_SIGNED, data_bytes);
760 n = unformat_integer (input, va, 10,
761 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
765 n = unformat_integer (input, va, 2,
766 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
770 n = unformat_integer (input, va, 8,
771 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
775 data_bytes = va_arg (*va, int);
777 n = unformat_integer (input, va, 16,
778 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
782 n = unformat_float (input, va);
787 n = unformat_string (input, f[0], cf, va);
792 unformat_function_t *f = va_arg (*va, unformat_function_t *);
800 int *var = va_arg (*va, int *);
801 uword val = va_arg (*va, int);
815 unformat_skip_white_space (unformat_input_t * input)
820 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
822 if (!is_white_space (c))
824 unformat_put_input (input);
833 va_unformat (unformat_input_t * input, const char *fmt, va_list * va)
836 uword input_matches_format;
837 uword default_skip_input_white_space;
838 uword n_input_white_space_skipped;
839 uword last_non_white_space_match_percent;
840 uword last_non_white_space_match_format;
842 vec_add1_aligned (input->buffer_marks, input->index,
843 sizeof (input->buffer_marks[0]));
846 default_skip_input_white_space = 1;
847 input_matches_format = 0;
848 last_non_white_space_match_percent = 0;
849 last_non_white_space_match_format = 0;
854 uword is_percent, skip_input_white_space;
859 /* Always skip input white space at start of format string.
860 Otherwise use default skip value which can be changed by %_
862 skip_input_white_space = f == fmt || default_skip_input_white_space;
864 /* Spaces in format request skipping input white space. */
865 if (is_white_space (cf))
867 skip_input_white_space = 1;
869 /* Multiple format spaces are equivalent to a single white
871 while (is_white_space (*++f))
876 /* %_ toggles whether or not to skip input white space. */
880 default_skip_input_white_space =
881 !default_skip_input_white_space;
883 /* For transition from skip to no-skip in middle of format
884 string, skip input white space. For example, the following matches:
885 fmt = "%_%d.%d%_->%_%d.%d%_"
887 Without this the space after -> does not get skipped. */
888 if (!default_skip_input_white_space
889 && !(f == fmt + 2 || *f == 0))
890 unformat_skip_white_space (input);
893 /* %% means match % */
897 /* % at end of format string. */
907 n_input_white_space_skipped = 0;
908 if (skip_input_white_space)
909 n_input_white_space_skipped = unformat_skip_white_space (input);
911 /* End of format string. */
914 /* Force parse error when format string ends and input is
915 not white or at end. As an example, this is to prevent
916 format "foo" from matching input "food".
917 The last_non_white_space_match_percent is to make
918 "foo %d" match input "foo 10,bletch" with %d matching 10. */
919 if (skip_input_white_space
920 && !last_non_white_space_match_percent
921 && !last_non_white_space_match_format
922 && n_input_white_space_skipped == 0
923 && input->index != UNFORMAT_END_OF_INPUT)
928 last_non_white_space_match_percent = is_percent;
929 last_non_white_space_match_format = 0;
931 /* Explicit spaces in format must match input white space. */
932 if (cf == ' ' && !default_skip_input_white_space)
934 if (n_input_white_space_skipped == 0)
940 if (!(f = do_percent (input, va, f)))
946 const char *g = match_input_with_format (input, f);
949 last_non_white_space_match_format = g > f;
954 input_matches_format = 1;
957 /* Rewind buffer marks. */
959 uword l = vec_len (input->buffer_marks);
961 /* If we did not match back up buffer to last mark. */
962 if (!input_matches_format)
963 input->index = input->buffer_marks[l - 1];
965 _vec_len (input->buffer_marks) = l - 1;
968 return input_matches_format;
972 unformat (unformat_input_t * input, const char *fmt, ...)
977 result = va_unformat (input, fmt, &va);
983 unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
988 /* Save place in input buffer in case parse fails. */
989 l = vec_len (input->buffer_marks);
990 vec_add1_aligned (input->buffer_marks, input->index,
991 sizeof (input->buffer_marks[0]));
994 result = func (input, &va);
997 if (!result && input->index != UNFORMAT_END_OF_INPUT)
998 input->index = input->buffer_marks[l];
1000 _vec_len (input->buffer_marks) = l;
1005 /* Setup for unformat of Unix style command line. */
1007 unformat_init_command_line (unformat_input_t * input, char *argv[])
1011 unformat_init (input, 0, 0);
1013 /* Concatenate argument strings with space in between. */
1014 for (i = 1; argv[i]; i++)
1016 vec_add (input->buffer, argv[i], strlen (argv[i]));
1018 vec_add1 (input->buffer, ' ');
1023 unformat_init_string (unformat_input_t * input, char *string, int string_len)
1025 unformat_init (input, 0, 0);
1027 vec_add (input->buffer, string, string_len);
1031 unformat_init_vector (unformat_input_t * input, u8 * vector_string)
1033 unformat_init (input, 0, 0);
1034 input->buffer = vector_string;
1040 unix_file_fill_buffer (unformat_input_t * input)
1042 int fd = pointer_to_uword (input->fill_buffer_arg);
1045 l = vec_len (input->buffer);
1046 vec_resize (input->buffer, 4096);
1047 n = read (fd, input->buffer + l, 4096);
1049 _vec_len (input->buffer) = l + n;
1052 return UNFORMAT_END_OF_INPUT;
1054 return input->index;
1058 unformat_init_unix_file (unformat_input_t * input, int file_descriptor)
1060 unformat_init (input, unix_file_fill_buffer,
1061 uword_to_pointer (file_descriptor, void *));
1064 /* Take input from Unix environment variable. */
1066 unformat_init_unix_env (unformat_input_t * input, char *var)
1068 char *val = getenv (var);
1070 unformat_init_string (input, val, strlen (val));
1074 #endif /* CLIB_UNIX */
1078 * fd.io coding-style-patch-verification: ON
1081 * eval: (c-set-style "gnu")