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>
41 /* Call user's function to fill input buffer. */
43 _unformat_fill_input (unformat_input_t * i)
47 if (i->index == UNFORMAT_END_OF_INPUT)
50 first_mark = l = vec_len (i->buffer);
51 if (vec_len (i->buffer_marks) > 0)
52 first_mark = i->buffer_marks[0];
54 /* Re-use buffer when no marks. */
56 vec_delete (i->buffer, first_mark, 0);
58 i->index = vec_len (i->buffer);
59 for (l = 0; l < vec_len (i->buffer_marks); l++)
60 i->buffer_marks[l] -= first_mark;
62 /* Call user's function to fill the buffer. */
64 i->index = i->fill_buffer (i);
66 /* If input pointer is still beyond end of buffer even after
67 fill then we've run out of input. */
68 if (i->index >= vec_len (i->buffer))
69 i->index = UNFORMAT_END_OF_INPUT;
74 /* Format function for dumping input stream. */
76 format_unformat_error (u8 * s, va_list * va)
78 unformat_input_t *i = va_arg (*va, unformat_input_t *);
79 uword l = vec_len (i->buffer);
81 /* Only show so much of the input buffer (it could be really large). */
86 uword n = l - i->index;
89 p = i->buffer + i->index;
90 p_end = p + (n > n_max ? n_max : n);
92 /* Skip white space at end. */
95 while (p_end > p && is_white_space (p_end[-1]))
104 vec_add (s, "\\r", 2);
107 vec_add (s, "\\n", 2);
110 vec_add (s, "\\t", 2);
120 vec_add (s, "...", 3);
126 /* Print everything: not just error context. */
128 format_unformat_input (u8 * s, va_list * va)
130 unformat_input_t *i = va_arg (*va, unformat_input_t *);
133 if (i->index == UNFORMAT_END_OF_INPUT)
134 s = format (s, "{END_OF_INPUT}");
137 l = vec_len (i->buffer);
140 vec_add (s, i->buffer + i->index, n);
148 di (unformat_input_t * i)
150 fformat (stderr, "%U\n", format_unformat_input, i);
154 /* Parse delimited vector string. If string starts with { then string
155 is delimited by balanced parenthesis. Other string is delimited by
156 white space. {} were chosen since they are special to the shell. */
158 unformat_string (unformat_input_t * input,
159 uword delimiter_character,
160 uword format_character, va_list * va)
162 u8 **string_return = va_arg (*va, u8 **);
165 word is_paren_delimited = 0;
169 switch (delimiter_character)
174 delimiter_character = 0;
178 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
182 /* Null return string means to skip over delimited input. */
183 add_to_vector = string_return != 0;
196 if (paren == 0 && vec_len (s) == 0)
198 is_paren_delimited = 1;
206 if (is_paren_delimited && paren == 0)
214 if (!is_paren_delimited)
216 unformat_put_input (input);
222 if (!is_paren_delimited && c == delimiter_character)
224 unformat_put_input (input);
236 /* Match the string { END-OF-INPUT as a single brace. */
237 if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0 && paren == 1)
240 /* Don't match null string. */
241 if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0)
244 /* Null terminate C string. */
245 if (format_character == 's')
251 vec_free (s); /* just to make sure */
257 unformat_hex_string (unformat_input_t * input, va_list * va)
259 u8 **hexstring_return = va_arg (*va, u8 **);
266 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
268 if (c >= '0' && c <= '9')
269 d = 16 * d + c - '0';
270 else if (c >= 'a' && c <= 'f')
271 d = 16 * d + 10 + c - 'a';
272 else if (c >= 'A' && c <= 'F')
273 d = 16 * d + 10 + c - 'A';
276 unformat_put_input (input);
288 /* Hex string must have even number of digits. */
294 /* Make sure something was processed. */
300 *hexstring_return = s;
304 /* unformat (input "foo%U", unformat_eof) matches terminal foo only */
306 unformat_eof (unformat_input_t * input, va_list * va)
308 return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
311 /* Parse a token containing given set of characters. */
313 unformat_token (unformat_input_t * input, va_list * va)
315 u8 *token_chars = va_arg (*va, u8 *);
316 u8 **string_return = va_arg (*va, u8 **);
321 token_chars = (u8 *) "a-zA-Z0-9_";
323 clib_memset (map, 0, sizeof (map));
324 for (s = token_chars; *s;)
328 * The test order is important: s[1] is valid because s[0] != '\0' but
329 * s[2] might not if s[1] == '\0'
330 * Also, if s[1] == '-' but s[2] == '\0' the test s[0] < s[2] will
333 if (s[1] == '-' && s[0] < s[2])
335 for (i = s[0]; i <= s[2]; i++)
347 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
351 unformat_put_input (input);
358 if (vec_len (s) == 0)
365 /* Unformat (parse) function which reads a %s string and converts it
366 to and unformat_input_t. */
368 unformat_input (unformat_input_t * i, va_list * args)
370 unformat_input_t *sub_input = va_arg (*args, unformat_input_t *);
373 if (unformat (i, "%v", &s))
375 unformat_init_vector (sub_input, s);
382 /* Parse a line ending with \n and return it. */
384 unformat_line (unformat_input_t * i, va_list * va)
386 u8 *line = 0, **result = va_arg (*va, u8 **);
389 while ((c = unformat_get_input (i)) != '\n' && c != UNFORMAT_END_OF_INPUT)
395 return vec_len (line);
398 /* Parse a line ending with \n and return it as an unformat_input_t. */
400 unformat_line_input (unformat_input_t * i, va_list * va)
402 unformat_input_t *result = va_arg (*va, unformat_input_t *);
404 if (!unformat_user (i, unformat_line, &line))
406 unformat_init_vector (result, line);
410 /* Values for is_signed. */
411 #define UNFORMAT_INTEGER_SIGNED 1
412 #define UNFORMAT_INTEGER_UNSIGNED 0
415 unformat_integer (unformat_input_t * input,
416 va_list * va, uword base, uword is_signed, uword data_bytes)
424 /* We only support bases <= 64. */
425 if (base < 2 || base > 64)
428 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
441 /* Leading sign for unsigned number. */
444 /* Sign after input (e.g. 100-200). */
458 digit = 10 + (c - 'a');
462 digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
480 unformat_put_input (input);
485 uword new_value = base * value + digit;
487 /* Check for overflow. */
488 if (new_value < value)
504 void *v = va_arg (*va, void *);
506 if (data_bytes == ~0)
507 data_bytes = sizeof (int);
536 times_power_of_ten (f64 x, int n)
540 static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
550 static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
562 unformat_float (unformat_input_t * input, va_list * va)
566 uword n_digits[3], value_index = 0;
567 uword signs[2], sign_index = 0;
570 clib_memset (values, 0, sizeof (values));
571 clib_memset (n_digits, 0, sizeof (n_digits));
572 clib_memset (signs, 0, sizeof (signs));
574 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
579 if (value_index == 2 && n_digits[2] == 0)
580 /* sign of exponent: it's ok. */ ;
582 else if (value_index < 2 && n_digits[0] > 0)
585 unformat_put_input (input);
589 else if (n_input > 0)
592 signs[sign_index++] = 1;
596 if (value_index == 2 && n_digits[2] == 0)
597 /* sign of exponent: it's ok. */ ;
599 else if (value_index < 2 && n_digits[0] > 0)
602 unformat_put_input (input);
606 else if (n_input > 0)
608 signs[sign_index++] = 0;
629 tmp = values[value_index] * 10 + c - '0';
631 /* Check for overflow. */
632 if (tmp < values[value_index])
634 values[value_index] = tmp;
635 n_digits[value_index] += 1;
640 unformat_put_input (input);
650 f64 f_values[2], *value_return;
653 /* Must have either whole or fraction digits. */
654 if (n_digits[0] + n_digits[1] <= 0)
657 f_values[0] = values[0];
659 f_values[0] = -f_values[0];
661 f_values[1] = values[1];
662 f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
664 f_values[0] += f_values[1];
670 f_values[0] = times_power_of_ten (f_values[0], expon);
672 value_return = va_arg (*va, f64 *);
673 *value_return = f_values[0];
682 match_input_with_format (unformat_input_t * input, const char *f)
691 if (cf == 0 || cf == '%' || cf == ' ')
695 ci = unformat_get_input (input);
704 do_percent (unformat_input_t * input, va_list * va, const char *f)
706 uword cf, n, data_bytes = ~0;
718 data_bytes = sizeof (uword);
726 data_bytes = sizeof (long long);
730 data_bytes = sizeof (long);
736 data_bytes = sizeof (long long);
744 data_bytes = va_arg (*va, int);
746 n = unformat_integer (input, va, 10,
747 UNFORMAT_INTEGER_SIGNED, data_bytes);
751 n = unformat_integer (input, va, 10,
752 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
756 n = unformat_integer (input, va, 2,
757 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
761 n = unformat_integer (input, va, 8,
762 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
766 data_bytes = va_arg (*va, int);
768 n = unformat_integer (input, va, 16,
769 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
773 n = unformat_float (input, va);
778 n = unformat_string (input, f[0], cf, va);
783 unformat_function_t *f = va_arg (*va, unformat_function_t *);
791 int *var = va_arg (*va, int *);
792 uword val = va_arg (*va, int);
806 unformat_skip_white_space (unformat_input_t * input)
811 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
813 if (!is_white_space (c))
815 unformat_put_input (input);
824 va_unformat (unformat_input_t * input, const char *fmt, va_list * va)
827 uword input_matches_format;
828 uword default_skip_input_white_space;
829 uword n_input_white_space_skipped;
830 uword last_non_white_space_match_percent;
831 uword last_non_white_space_match_format;
833 vec_add1_aligned (input->buffer_marks, input->index,
834 sizeof (input->buffer_marks[0]));
837 default_skip_input_white_space = 1;
838 input_matches_format = 0;
839 last_non_white_space_match_percent = 0;
840 last_non_white_space_match_format = 0;
845 uword is_percent, skip_input_white_space;
850 /* Always skip input white space at start of format string.
851 Otherwise use default skip value which can be changed by %_
853 skip_input_white_space = f == fmt || default_skip_input_white_space;
855 /* Spaces in format request skipping input white space. */
856 if (is_white_space (cf))
858 skip_input_white_space = 1;
860 /* Multiple format spaces are equivalent to a single white
862 while (is_white_space (*++f))
867 /* %_ toggles whether or not to skip input white space. */
871 default_skip_input_white_space =
872 !default_skip_input_white_space;
874 /* For transition from skip to no-skip in middle of format
875 string, skip input white space. For example, the following matches:
876 fmt = "%_%d.%d%_->%_%d.%d%_"
878 Without this the space after -> does not get skipped. */
879 if (!default_skip_input_white_space
880 && !(f == fmt + 2 || *f == 0))
881 unformat_skip_white_space (input);
884 /* %% means match % */
888 /* % at end of format string. */
898 n_input_white_space_skipped = 0;
899 if (skip_input_white_space)
900 n_input_white_space_skipped = unformat_skip_white_space (input);
902 /* End of format string. */
905 /* Force parse error when format string ends and input is
906 not white or at end. As an example, this is to prevent
907 format "foo" from matching input "food".
908 The last_non_white_space_match_percent is to make
909 "foo %d" match input "foo 10,bletch" with %d matching 10. */
910 if (skip_input_white_space
911 && !last_non_white_space_match_percent
912 && !last_non_white_space_match_format
913 && n_input_white_space_skipped == 0
914 && input->index != UNFORMAT_END_OF_INPUT)
919 last_non_white_space_match_percent = is_percent;
920 last_non_white_space_match_format = 0;
922 /* Explicit spaces in format must match input white space. */
923 if (cf == ' ' && !default_skip_input_white_space)
925 if (n_input_white_space_skipped == 0)
931 if (!(f = do_percent (input, va, f)))
937 const char *g = match_input_with_format (input, f);
940 last_non_white_space_match_format = g > f;
945 input_matches_format = 1;
948 /* Rewind buffer marks. */
950 uword l = vec_len (input->buffer_marks);
952 /* If we did not match back up buffer to last mark. */
953 if (!input_matches_format)
954 input->index = input->buffer_marks[l - 1];
956 vec_set_len (input->buffer_marks, l - 1);
959 return input_matches_format;
963 unformat (unformat_input_t * input, const char *fmt, ...)
968 result = va_unformat (input, fmt, &va);
974 unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
979 /* Save place in input buffer in case parse fails. */
980 l = vec_len (input->buffer_marks);
981 vec_add1_aligned (input->buffer_marks, input->index,
982 sizeof (input->buffer_marks[0]));
985 result = func (input, &va);
988 if (!result && input->index != UNFORMAT_END_OF_INPUT)
989 input->index = input->buffer_marks[l];
991 vec_set_len (input->buffer_marks, l);
996 /* Setup for unformat of Unix style command line. */
998 unformat_init_command_line (unformat_input_t * input, char *argv[])
1002 unformat_init (input, 0, 0);
1004 /* Concatenate argument strings with space in between. */
1005 for (i = 1; argv[i]; i++)
1007 vec_add (input->buffer, argv[i], strlen (argv[i]));
1009 vec_add1 (input->buffer, ' ');
1014 unformat_init_string (unformat_input_t *input, const char *string,
1017 unformat_init (input, 0, 0);
1019 vec_add (input->buffer, string, string_len);
1023 unformat_init_vector (unformat_input_t * input, u8 * vector_string)
1025 unformat_init (input, 0, 0);
1026 input->buffer = vector_string;
1032 clib_file_fill_buffer (unformat_input_t * input)
1034 int fd = pointer_to_uword (input->fill_buffer_arg);
1037 l = vec_len (input->buffer);
1038 vec_resize (input->buffer, 4096);
1039 n = read (fd, input->buffer + l, 4096);
1041 vec_set_len (input->buffer, l + n);
1044 return UNFORMAT_END_OF_INPUT;
1046 return input->index;
1050 unformat_close_fd (unformat_input_t *input)
1052 int fd = pointer_to_uword (input->fill_buffer_arg);
1057 unformat_init_clib_file (unformat_input_t * input, int file_descriptor)
1059 unformat_init (input, clib_file_fill_buffer,
1060 uword_to_pointer (file_descriptor, void *));
1064 unformat_init_file (unformat_input_t *input, char *fmt, ...)
1071 path = va_format (0, fmt, &va);
1075 fd = open ((char *) path, 0);
1080 unformat_init (input, clib_file_fill_buffer,
1081 uword_to_pointer (fd, void *));
1082 input->free = unformat_close_fd;
1088 /* Take input from Unix environment variable. */
1090 unformat_init_unix_env (unformat_input_t * input, char *var)
1092 char *val = getenv (var);
1094 unformat_init_string (input, val, strlen (val));
1099 unformat_data_size (unformat_input_t * input, va_list * args)
1102 u64 *a = va_arg (*args, u64 *);
1103 if (unformat (input, "%lluGb", &_a))
1105 else if (unformat (input, "%lluG", &_a))
1107 else if (unformat (input, "%lluMb", &_a))
1109 else if (unformat (input, "%lluM", &_a))
1111 else if (unformat (input, "%lluKb", &_a))
1113 else if (unformat (input, "%lluK", &_a))
1115 else if (unformat (input, "%llu", a))
1123 unformat_c_string_array (unformat_input_t *input, va_list *va)
1125 char *str = va_arg (*va, char *);
1126 u32 array_len = va_arg (*va, u32);
1130 if (unformat (input, "%v", &s) == 0)
1135 if (c > 0 && c < array_len)
1137 clib_memcpy (str, s, c);
1147 __unformat_quoted_string (unformat_input_t *input, u8 **sp, char quote)
1152 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
1153 if (!is_white_space (c))
1159 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
1161 if (c == quote && p != '\\')
1175 unformat_single_quoted_string (unformat_input_t *input, va_list *va)
1177 return __unformat_quoted_string (input, va_arg (*va, u8 **), '\'');
1181 unformat_double_quoted_string (unformat_input_t *input, va_list *va)
1183 return __unformat_quoted_string (input, va_arg (*va, u8 **), '"');
1186 #endif /* CLIB_UNIX */
1190 * fd.io coding-style-patch-verification: ON
1193 * eval: (c-set-style "gnu")