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)
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 unformat_user (i, unformat_line, &line);
414 unformat_init_vector (result, line);
418 /* Values for is_signed. */
419 #define UNFORMAT_INTEGER_SIGNED 1
420 #define UNFORMAT_INTEGER_UNSIGNED 0
423 unformat_integer (unformat_input_t * input,
424 va_list * va, uword base, uword is_signed, uword data_bytes)
432 /* We only support bases <= 64. */
433 if (base < 2 || base > 64)
436 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
449 /* Leading sign for unsigned number. */
452 /* Sign after input (e.g. 100-200). */
466 digit = 10 + (c - 'a');
470 digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
488 unformat_put_input (input);
493 uword new_value = base * value + digit;
495 /* Check for overflow. */
496 if (new_value < value)
512 void *v = va_arg (*va, void *);
514 if (data_bytes == ~0)
515 data_bytes = sizeof (int);
544 times_power_of_ten (f64 x, int n)
548 static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
558 static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
570 unformat_float (unformat_input_t * input, va_list * va)
574 uword n_digits[3], value_index = 0;
575 uword signs[2], sign_index = 0;
578 memset (values, 0, sizeof (values));
579 memset (n_digits, 0, sizeof (n_digits));
580 memset (signs, 0, sizeof (signs));
582 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
587 if (value_index == 2 && n_digits[2] == 0)
588 /* sign of exponent: it's ok. */ ;
590 else if (value_index < 2 && n_digits[0] > 0)
593 unformat_put_input (input);
597 else if (n_input > 0)
600 signs[sign_index++] = 1;
604 if (value_index == 2 && n_digits[2] == 0)
605 /* sign of exponent: it's ok. */ ;
607 else if (value_index < 2 && n_digits[0] > 0)
610 unformat_put_input (input);
614 else if (n_input > 0)
616 signs[sign_index++] = 0;
637 tmp = values[value_index] * 10 + c - '0';
639 /* Check for overflow. */
640 if (tmp < values[value_index])
642 values[value_index] = tmp;
643 n_digits[value_index] += 1;
648 unformat_put_input (input);
658 f64 f_values[2], *value_return;
661 /* Must have either whole or fraction digits. */
662 if (n_digits[0] + n_digits[1] <= 0)
665 f_values[0] = values[0];
667 f_values[0] = -f_values[0];
669 f_values[1] = values[1];
670 f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
672 f_values[0] += f_values[1];
678 f_values[0] = times_power_of_ten (f_values[0], expon);
680 value_return = va_arg (*va, f64 *);
681 *value_return = f_values[0];
690 match_input_with_format (unformat_input_t * input, const char *f)
699 if (cf == 0 || cf == '%' || cf == ' ')
703 ci = unformat_get_input (input);
712 do_percent (unformat_input_t * input, va_list * va, const char *f)
714 uword cf, n, data_bytes = ~0;
726 data_bytes = sizeof (uword);
734 data_bytes = sizeof (long long);
738 data_bytes = sizeof (long);
744 data_bytes = sizeof (long long);
752 data_bytes = va_arg (*va, int);
754 n = unformat_integer (input, va, 10,
755 UNFORMAT_INTEGER_SIGNED, data_bytes);
759 n = unformat_integer (input, va, 10,
760 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
764 n = unformat_integer (input, va, 2,
765 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
769 n = unformat_integer (input, va, 8,
770 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
774 data_bytes = va_arg (*va, int);
776 n = unformat_integer (input, va, 16,
777 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
781 n = unformat_float (input, va);
786 n = unformat_string (input, f[0], cf, va);
791 unformat_function_t *f = va_arg (*va, unformat_function_t *);
799 int *var = va_arg (*va, int *);
800 uword val = va_arg (*va, int);
814 unformat_skip_white_space (unformat_input_t * input)
819 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
821 if (!is_white_space (c))
823 unformat_put_input (input);
832 va_unformat (unformat_input_t * input, const char *fmt, va_list * va)
835 uword input_matches_format;
836 uword default_skip_input_white_space;
837 uword n_input_white_space_skipped;
838 uword last_non_white_space_match_percent;
839 uword last_non_white_space_match_format;
841 vec_add1_aligned (input->buffer_marks, input->index,
842 sizeof (input->buffer_marks[0]));
845 default_skip_input_white_space = 1;
846 input_matches_format = 0;
847 last_non_white_space_match_percent = 0;
848 last_non_white_space_match_format = 0;
853 uword is_percent, skip_input_white_space;
858 /* Always skip input white space at start of format string.
859 Otherwise use default skip value which can be changed by %_
861 skip_input_white_space = f == fmt || default_skip_input_white_space;
863 /* Spaces in format request skipping input white space. */
864 if (is_white_space (cf))
866 skip_input_white_space = 1;
868 /* Multiple format spaces are equivalent to a single white
870 while (is_white_space (*++f))
875 /* %_ toggles whether or not to skip input white space. */
879 default_skip_input_white_space =
880 !default_skip_input_white_space;
882 /* For transition from skip to no-skip in middle of format
883 string, skip input white space. For example, the following matches:
884 fmt = "%_%d.%d%_->%_%d.%d%_"
886 Without this the space after -> does not get skipped. */
887 if (!default_skip_input_white_space
888 && !(f == fmt + 2 || *f == 0))
889 unformat_skip_white_space (input);
892 /* %% means match % */
896 /* % at end of format string. */
906 n_input_white_space_skipped = 0;
907 if (skip_input_white_space)
908 n_input_white_space_skipped = unformat_skip_white_space (input);
910 /* End of format string. */
913 /* Force parse error when format string ends and input is
914 not white or at end. As an example, this is to prevent
915 format "foo" from matching input "food".
916 The last_non_white_space_match_percent is to make
917 "foo %d" match input "foo 10,bletch" with %d matching 10. */
918 if (skip_input_white_space
919 && !last_non_white_space_match_percent
920 && !last_non_white_space_match_format
921 && n_input_white_space_skipped == 0
922 && input->index != UNFORMAT_END_OF_INPUT)
927 last_non_white_space_match_percent = is_percent;
928 last_non_white_space_match_format = 0;
930 /* Explicit spaces in format must match input white space. */
931 if (cf == ' ' && !default_skip_input_white_space)
933 if (n_input_white_space_skipped == 0)
939 if (!(f = do_percent (input, va, f)))
945 const char *g = match_input_with_format (input, f);
948 last_non_white_space_match_format = g > f;
953 input_matches_format = 1;
956 /* Rewind buffer marks. */
958 uword l = vec_len (input->buffer_marks);
960 /* If we did not match back up buffer to last mark. */
961 if (!input_matches_format)
962 input->index = input->buffer_marks[l - 1];
964 _vec_len (input->buffer_marks) = l - 1;
967 return input_matches_format;
971 unformat (unformat_input_t * input, const char *fmt, ...)
976 result = va_unformat (input, fmt, &va);
982 unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
987 /* Save place in input buffer in case parse fails. */
988 l = vec_len (input->buffer_marks);
989 vec_add1_aligned (input->buffer_marks, input->index,
990 sizeof (input->buffer_marks[0]));
993 result = func (input, &va);
996 if (!result && input->index != UNFORMAT_END_OF_INPUT)
997 input->index = input->buffer_marks[l];
999 _vec_len (input->buffer_marks) = l;
1004 /* Setup for unformat of Unix style command line. */
1006 unformat_init_command_line (unformat_input_t * input, char *argv[])
1010 unformat_init (input, 0, 0);
1012 /* Concatenate argument strings with space in between. */
1013 for (i = 1; argv[i]; i++)
1015 vec_add (input->buffer, argv[i], strlen (argv[i]));
1017 vec_add1 (input->buffer, ' ');
1022 unformat_init_string (unformat_input_t * input, char *string, int string_len)
1024 unformat_init (input, 0, 0);
1026 vec_add (input->buffer, string, string_len);
1030 unformat_init_vector (unformat_input_t * input, u8 * vector_string)
1032 unformat_init (input, 0, 0);
1033 input->buffer = vector_string;
1039 unix_file_fill_buffer (unformat_input_t * input)
1041 int fd = pointer_to_uword (input->fill_buffer_arg);
1044 l = vec_len (input->buffer);
1045 vec_resize (input->buffer, 4096);
1046 n = read (fd, input->buffer + l, 4096);
1048 _vec_len (input->buffer) = l + n;
1051 return UNFORMAT_END_OF_INPUT;
1053 return input->index;
1057 unformat_init_unix_file (unformat_input_t * input, int file_descriptor)
1059 unformat_init (input, unix_file_fill_buffer,
1060 uword_to_pointer (file_descriptor, void *));
1063 /* Take input from Unix environment variable. */
1065 unformat_init_unix_env (unformat_input_t * input, char *var)
1067 char *val = getenv (var);
1069 unformat_init_string (input, val, strlen (val));
1073 #endif /* CLIB_UNIX */
1077 * fd.io coding-style-patch-verification: ON
1080 * eval: (c-set-style "gnu")