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 balanced 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 clib_memset (map, 0, sizeof (map));
339 for (s = token_chars; *s;)
343 * The test order is important: s[1] is valid because s[0] != '\0' but
344 * s[2] might not if s[1] == '\0'
345 * Also, if s[1] == '-' but s[2] == '\0' the test s[0] < s[2] will
348 if (s[1] == '-' && s[0] < s[2])
350 for (i = s[0]; i <= s[2]; i++)
362 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
366 unformat_put_input (input);
373 if (vec_len (s) == 0)
380 /* Unformat (parse) function which reads a %s string and converts it
381 to and unformat_input_t. */
383 unformat_input (unformat_input_t * i, va_list * args)
385 unformat_input_t *sub_input = va_arg (*args, unformat_input_t *);
388 if (unformat (i, "%v", &s))
390 unformat_init_vector (sub_input, s);
397 /* Parse a line ending with \n and return it. */
399 unformat_line (unformat_input_t * i, va_list * va)
401 u8 *line = 0, **result = va_arg (*va, u8 **);
404 while ((c = unformat_get_input (i)) != '\n' && c != UNFORMAT_END_OF_INPUT)
410 return vec_len (line);
413 /* Parse a line ending with \n and return it as an unformat_input_t. */
415 unformat_line_input (unformat_input_t * i, va_list * va)
417 unformat_input_t *result = va_arg (*va, unformat_input_t *);
419 if (!unformat_user (i, unformat_line, &line))
421 unformat_init_vector (result, line);
425 /* Values for is_signed. */
426 #define UNFORMAT_INTEGER_SIGNED 1
427 #define UNFORMAT_INTEGER_UNSIGNED 0
430 unformat_integer (unformat_input_t * input,
431 va_list * va, uword base, uword is_signed, uword data_bytes)
439 /* We only support bases <= 64. */
440 if (base < 2 || base > 64)
443 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
456 /* Leading sign for unsigned number. */
459 /* Sign after input (e.g. 100-200). */
473 digit = 10 + (c - 'a');
477 digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
495 unformat_put_input (input);
500 uword new_value = base * value + digit;
502 /* Check for overflow. */
503 if (new_value < value)
519 void *v = va_arg (*va, void *);
521 if (data_bytes == ~0)
522 data_bytes = sizeof (int);
551 times_power_of_ten (f64 x, int n)
555 static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
565 static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
577 unformat_float (unformat_input_t * input, va_list * va)
581 uword n_digits[3], value_index = 0;
582 uword signs[2], sign_index = 0;
585 clib_memset (values, 0, sizeof (values));
586 clib_memset (n_digits, 0, sizeof (n_digits));
587 clib_memset (signs, 0, sizeof (signs));
589 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
594 if (value_index == 2 && n_digits[2] == 0)
595 /* sign of exponent: it's ok. */ ;
597 else if (value_index < 2 && n_digits[0] > 0)
600 unformat_put_input (input);
604 else if (n_input > 0)
607 signs[sign_index++] = 1;
611 if (value_index == 2 && n_digits[2] == 0)
612 /* sign of exponent: it's ok. */ ;
614 else if (value_index < 2 && n_digits[0] > 0)
617 unformat_put_input (input);
621 else if (n_input > 0)
623 signs[sign_index++] = 0;
644 tmp = values[value_index] * 10 + c - '0';
646 /* Check for overflow. */
647 if (tmp < values[value_index])
649 values[value_index] = tmp;
650 n_digits[value_index] += 1;
655 unformat_put_input (input);
665 f64 f_values[2], *value_return;
668 /* Must have either whole or fraction digits. */
669 if (n_digits[0] + n_digits[1] <= 0)
672 f_values[0] = values[0];
674 f_values[0] = -f_values[0];
676 f_values[1] = values[1];
677 f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
679 f_values[0] += f_values[1];
685 f_values[0] = times_power_of_ten (f_values[0], expon);
687 value_return = va_arg (*va, f64 *);
688 *value_return = f_values[0];
697 match_input_with_format (unformat_input_t * input, const char *f)
706 if (cf == 0 || cf == '%' || cf == ' ')
710 ci = unformat_get_input (input);
719 do_percent (unformat_input_t * input, va_list * va, const char *f)
721 uword cf, n, data_bytes = ~0;
733 data_bytes = sizeof (uword);
741 data_bytes = sizeof (long long);
745 data_bytes = sizeof (long);
751 data_bytes = sizeof (long long);
759 data_bytes = va_arg (*va, int);
761 n = unformat_integer (input, va, 10,
762 UNFORMAT_INTEGER_SIGNED, data_bytes);
766 n = unformat_integer (input, va, 10,
767 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
771 n = unformat_integer (input, va, 2,
772 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
776 n = unformat_integer (input, va, 8,
777 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
781 data_bytes = va_arg (*va, int);
783 n = unformat_integer (input, va, 16,
784 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
788 n = unformat_float (input, va);
793 n = unformat_string (input, f[0], cf, va);
798 unformat_function_t *f = va_arg (*va, unformat_function_t *);
806 int *var = va_arg (*va, int *);
807 uword val = va_arg (*va, int);
821 unformat_skip_white_space (unformat_input_t * input)
826 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
828 if (!is_white_space (c))
830 unformat_put_input (input);
839 va_unformat (unformat_input_t * input, const char *fmt, va_list * va)
842 uword input_matches_format;
843 uword default_skip_input_white_space;
844 uword n_input_white_space_skipped;
845 uword last_non_white_space_match_percent;
846 uword last_non_white_space_match_format;
848 vec_add1_aligned (input->buffer_marks, input->index,
849 sizeof (input->buffer_marks[0]));
852 default_skip_input_white_space = 1;
853 input_matches_format = 0;
854 last_non_white_space_match_percent = 0;
855 last_non_white_space_match_format = 0;
860 uword is_percent, skip_input_white_space;
865 /* Always skip input white space at start of format string.
866 Otherwise use default skip value which can be changed by %_
868 skip_input_white_space = f == fmt || default_skip_input_white_space;
870 /* Spaces in format request skipping input white space. */
871 if (is_white_space (cf))
873 skip_input_white_space = 1;
875 /* Multiple format spaces are equivalent to a single white
877 while (is_white_space (*++f))
882 /* %_ toggles whether or not to skip input white space. */
886 default_skip_input_white_space =
887 !default_skip_input_white_space;
889 /* For transition from skip to no-skip in middle of format
890 string, skip input white space. For example, the following matches:
891 fmt = "%_%d.%d%_->%_%d.%d%_"
893 Without this the space after -> does not get skipped. */
894 if (!default_skip_input_white_space
895 && !(f == fmt + 2 || *f == 0))
896 unformat_skip_white_space (input);
899 /* %% means match % */
903 /* % at end of format string. */
913 n_input_white_space_skipped = 0;
914 if (skip_input_white_space)
915 n_input_white_space_skipped = unformat_skip_white_space (input);
917 /* End of format string. */
920 /* Force parse error when format string ends and input is
921 not white or at end. As an example, this is to prevent
922 format "foo" from matching input "food".
923 The last_non_white_space_match_percent is to make
924 "foo %d" match input "foo 10,bletch" with %d matching 10. */
925 if (skip_input_white_space
926 && !last_non_white_space_match_percent
927 && !last_non_white_space_match_format
928 && n_input_white_space_skipped == 0
929 && input->index != UNFORMAT_END_OF_INPUT)
934 last_non_white_space_match_percent = is_percent;
935 last_non_white_space_match_format = 0;
937 /* Explicit spaces in format must match input white space. */
938 if (cf == ' ' && !default_skip_input_white_space)
940 if (n_input_white_space_skipped == 0)
946 if (!(f = do_percent (input, va, f)))
952 const char *g = match_input_with_format (input, f);
955 last_non_white_space_match_format = g > f;
960 input_matches_format = 1;
963 /* Rewind buffer marks. */
965 uword l = vec_len (input->buffer_marks);
967 /* If we did not match back up buffer to last mark. */
968 if (!input_matches_format)
969 input->index = input->buffer_marks[l - 1];
971 _vec_len (input->buffer_marks) = l - 1;
974 return input_matches_format;
978 unformat (unformat_input_t * input, const char *fmt, ...)
983 result = va_unformat (input, fmt, &va);
989 unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
994 /* Save place in input buffer in case parse fails. */
995 l = vec_len (input->buffer_marks);
996 vec_add1_aligned (input->buffer_marks, input->index,
997 sizeof (input->buffer_marks[0]));
1000 result = func (input, &va);
1003 if (!result && input->index != UNFORMAT_END_OF_INPUT)
1004 input->index = input->buffer_marks[l];
1006 _vec_len (input->buffer_marks) = l;
1011 /* Setup for unformat of Unix style command line. */
1013 unformat_init_command_line (unformat_input_t * input, char *argv[])
1017 unformat_init (input, 0, 0);
1019 /* Concatenate argument strings with space in between. */
1020 for (i = 1; argv[i]; i++)
1022 vec_add (input->buffer, argv[i], strlen (argv[i]));
1024 vec_add1 (input->buffer, ' ');
1029 unformat_init_string (unformat_input_t * input, char *string, int string_len)
1031 unformat_init (input, 0, 0);
1033 vec_add (input->buffer, string, string_len);
1037 unformat_init_vector (unformat_input_t * input, u8 * vector_string)
1039 unformat_init (input, 0, 0);
1040 input->buffer = vector_string;
1046 clib_file_fill_buffer (unformat_input_t * input)
1048 int fd = pointer_to_uword (input->fill_buffer_arg);
1051 l = vec_len (input->buffer);
1052 vec_resize (input->buffer, 4096);
1053 n = read (fd, input->buffer + l, 4096);
1055 _vec_len (input->buffer) = l + n;
1058 return UNFORMAT_END_OF_INPUT;
1060 return input->index;
1064 unformat_init_clib_file (unformat_input_t * input, int file_descriptor)
1066 unformat_init (input, clib_file_fill_buffer,
1067 uword_to_pointer (file_descriptor, void *));
1070 /* Take input from Unix environment variable. */
1072 unformat_init_unix_env (unformat_input_t * input, char *var)
1074 char *val = getenv (var);
1076 unformat_init_string (input, val, strlen (val));
1080 #endif /* CLIB_UNIX */
1084 * fd.io coding-style-patch-verification: ON
1087 * eval: (c-set-style "gnu")