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. */
310 *hexstring_return = s;
314 /* unformat (input "foo%U", unformat_eof) matches terminal foo only */
316 unformat_eof (unformat_input_t * input, va_list * va)
318 return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
321 /* Parse a token containing given set of characters. */
323 unformat_token (unformat_input_t * input, va_list * va)
325 u8 *token_chars = va_arg (*va, u8 *);
326 u8 **string_return = va_arg (*va, u8 **);
331 token_chars = (u8 *) "a-zA-Z0-9_";
333 memset (map, 0, sizeof (map));
334 for (s = token_chars; *s;)
337 if (s[0] < s[2] && s[1] == '-')
339 for (i = s[0]; i <= s[2]; i++)
351 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
355 unformat_put_input (input);
362 if (vec_len (s) == 0)
369 /* Unformat (parse) function which reads a %s string and converts it
370 to and unformat_input_t. */
372 unformat_input (unformat_input_t * i, va_list * args)
374 unformat_input_t *sub_input = va_arg (*args, unformat_input_t *);
377 if (unformat (i, "%v", &s))
379 unformat_init_vector (sub_input, s);
386 /* Parse a line ending with \n and return it. */
388 unformat_line (unformat_input_t * i, va_list * va)
390 u8 *line = 0, **result = va_arg (*va, u8 **);
393 while ((c = unformat_get_input (i)) != '\n' && c != UNFORMAT_END_OF_INPUT)
402 /* Parse a line ending with \n and return it as an unformat_input_t. */
404 unformat_line_input (unformat_input_t * i, va_list * va)
406 unformat_input_t *result = va_arg (*va, unformat_input_t *);
408 unformat_user (i, unformat_line, &line);
409 unformat_init_vector (result, line);
413 /* Values for is_signed. */
414 #define UNFORMAT_INTEGER_SIGNED 1
415 #define UNFORMAT_INTEGER_UNSIGNED 0
418 unformat_integer (unformat_input_t * input,
419 va_list * va, uword base, uword is_signed, uword data_bytes)
427 /* We only support bases <= 64. */
428 if (base < 2 || base > 64)
431 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
444 /* Leading sign for unsigned number. */
447 /* Sign after input (e.g. 100-200). */
461 digit = 10 + (c - 'a');
465 digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
483 unformat_put_input (input);
488 uword new_value = base * value + digit;
490 /* Check for overflow. */
491 if (new_value < value)
507 void *v = va_arg (*va, void *);
509 if (data_bytes == ~0)
510 data_bytes = sizeof (int);
539 times_power_of_ten (f64 x, int n)
543 static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
553 static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
565 unformat_float (unformat_input_t * input, va_list * va)
569 uword n_digits[3], value_index = 0;
570 uword signs[2], sign_index = 0;
573 memset (values, 0, sizeof (values));
574 memset (n_digits, 0, sizeof (n_digits));
575 memset (signs, 0, sizeof (signs));
577 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
582 if (value_index == 2 && n_digits[2] == 0)
583 /* sign of exponent: it's ok. */ ;
585 else if (value_index < 2 && n_digits[0] > 0)
588 unformat_put_input (input);
592 else if (n_input > 0)
595 signs[sign_index++] = 1;
599 if (value_index == 2 && n_digits[2] == 0)
600 /* sign of exponent: it's ok. */ ;
602 else if (value_index < 2 && n_digits[0] > 0)
605 unformat_put_input (input);
609 else if (n_input > 0)
611 signs[sign_index++] = 0;
632 tmp = values[value_index] * 10 + c - '0';
634 /* Check for overflow. */
635 if (tmp < values[value_index])
637 values[value_index] = tmp;
638 n_digits[value_index] += 1;
643 unformat_put_input (input);
653 f64 f_values[2], *value_return;
656 /* Must have either whole or fraction digits. */
657 if (n_digits[0] + n_digits[1] <= 0)
660 f_values[0] = values[0];
662 f_values[0] = -f_values[0];
664 f_values[1] = values[1];
665 f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
667 f_values[0] += f_values[1];
673 f_values[0] = times_power_of_ten (f_values[0], expon);
675 value_return = va_arg (*va, f64 *);
676 *value_return = f_values[0];
685 match_input_with_format (unformat_input_t * input, char *f)
694 if (cf == 0 || cf == '%' || cf == ' ')
698 ci = unformat_get_input (input);
707 do_percent (unformat_input_t * input, va_list * va, char *f)
709 uword cf, n, data_bytes = ~0;
721 data_bytes = sizeof (uword);
729 data_bytes = sizeof (long long);
733 data_bytes = sizeof (long);
739 data_bytes = sizeof (long long);
747 data_bytes = va_arg (*va, int);
749 n = unformat_integer (input, va, 10,
750 UNFORMAT_INTEGER_SIGNED, data_bytes);
754 n = unformat_integer (input, va, 10,
755 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
759 n = unformat_integer (input, va, 2,
760 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
764 n = unformat_integer (input, va, 8,
765 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
769 data_bytes = va_arg (*va, int);
771 n = unformat_integer (input, va, 16,
772 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
776 n = unformat_float (input, va);
781 n = unformat_string (input, f[0], cf, va);
786 unformat_function_t *f = va_arg (*va, unformat_function_t *);
794 int *var = va_arg (*va, int *);
795 uword val = va_arg (*va, int);
809 unformat_skip_white_space (unformat_input_t * input)
814 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
816 if (!is_white_space (c))
818 unformat_put_input (input);
827 va_unformat (unformat_input_t * input, char *fmt, va_list * va)
830 uword input_matches_format;
831 uword default_skip_input_white_space;
832 uword n_input_white_space_skipped;
833 uword last_non_white_space_match_percent;
834 uword last_non_white_space_match_format;
836 vec_add1_aligned (input->buffer_marks, input->index,
837 sizeof (input->buffer_marks[0]));
840 default_skip_input_white_space = 1;
841 input_matches_format = 0;
842 last_non_white_space_match_percent = 0;
843 last_non_white_space_match_format = 0;
848 uword is_percent, skip_input_white_space;
853 /* Always skip input white space at start of format string.
854 Otherwise use default skip value which can be changed by %_
856 skip_input_white_space = f == fmt || default_skip_input_white_space;
858 /* Spaces in format request skipping input white space. */
859 if (is_white_space (cf))
861 skip_input_white_space = 1;
863 /* Multiple format spaces are equivalent to a single white
865 while (is_white_space (*++f))
870 /* %_ toggles whether or not to skip input white space. */
874 default_skip_input_white_space =
875 !default_skip_input_white_space;
877 /* For transition from skip to no-skip in middle of format
878 string, skip input white space. For example, the following matches:
879 fmt = "%_%d.%d%_->%_%d.%d%_"
881 Without this the space after -> does not get skipped. */
882 if (!default_skip_input_white_space
883 && !(f == fmt + 2 || *f == 0))
884 unformat_skip_white_space (input);
887 /* %% means match % */
891 /* % at end of format string. */
901 n_input_white_space_skipped = 0;
902 if (skip_input_white_space)
903 n_input_white_space_skipped = unformat_skip_white_space (input);
905 /* End of format string. */
908 /* Force parse error when format string ends and input is
909 not white or at end. As an example, this is to prevent
910 format "foo" from matching input "food".
911 The last_non_white_space_match_percent is to make
912 "foo %d" match input "foo 10,bletch" with %d matching 10. */
913 if (skip_input_white_space
914 && !last_non_white_space_match_percent
915 && !last_non_white_space_match_format
916 && n_input_white_space_skipped == 0
917 && input->index != UNFORMAT_END_OF_INPUT)
922 last_non_white_space_match_percent = is_percent;
923 last_non_white_space_match_format = 0;
925 /* Explicit spaces in format must match input white space. */
926 if (cf == ' ' && !default_skip_input_white_space)
928 if (n_input_white_space_skipped == 0)
934 if (!(f = do_percent (input, va, f)))
940 char *g = match_input_with_format (input, f);
943 last_non_white_space_match_format = g > f;
948 input_matches_format = 1;
951 /* Rewind buffer marks. */
953 uword l = vec_len (input->buffer_marks);
955 /* If we did not match back up buffer to last mark. */
956 if (!input_matches_format)
957 input->index = input->buffer_marks[l - 1];
959 _vec_len (input->buffer_marks) = l - 1;
962 return input_matches_format;
966 unformat (unformat_input_t * input, char *fmt, ...)
971 result = va_unformat (input, fmt, &va);
977 unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
982 /* Save place in input buffer in case parse fails. */
983 l = vec_len (input->buffer_marks);
984 vec_add1_aligned (input->buffer_marks, input->index,
985 sizeof (input->buffer_marks[0]));
988 result = func (input, &va);
991 if (!result && input->index != UNFORMAT_END_OF_INPUT)
992 input->index = input->buffer_marks[l];
994 _vec_len (input->buffer_marks) = l;
999 /* Setup for unformat of Unix style command line. */
1001 unformat_init_command_line (unformat_input_t * input, char *argv[])
1005 unformat_init (input, 0, 0);
1007 /* Concatenate argument strings with space in between. */
1008 for (i = 1; argv[i]; i++)
1010 vec_add (input->buffer, argv[i], strlen (argv[i]));
1012 vec_add1 (input->buffer, ' ');
1017 unformat_init_string (unformat_input_t * input, char *string, int string_len)
1019 unformat_init (input, 0, 0);
1021 vec_add (input->buffer, string, string_len);
1025 unformat_init_vector (unformat_input_t * input, u8 * vector_string)
1027 unformat_init (input, 0, 0);
1028 input->buffer = vector_string;
1034 unix_file_fill_buffer (unformat_input_t * input)
1036 int fd = pointer_to_uword (input->fill_buffer_arg);
1039 l = vec_len (input->buffer);
1040 vec_resize (input->buffer, 4096);
1041 n = read (fd, input->buffer + l, 4096);
1043 _vec_len (input->buffer) = l + n;
1046 return UNFORMAT_END_OF_INPUT;
1048 return input->index;
1052 unformat_init_unix_file (unformat_input_t * input, int file_descriptor)
1054 unformat_init (input, unix_file_fill_buffer,
1055 uword_to_pointer (file_descriptor, void *));
1058 /* Take input from Unix environment variable. */
1060 unformat_init_unix_env (unformat_input_t * input, char *var)
1062 char *val = getenv (var);
1064 unformat_init_string (input, val, strlen (val));
1068 #endif /* CLIB_UNIX */
1072 * fd.io coding-style-patch-verification: ON
1075 * eval: (c-set-style "gnu")