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. */
41 uword _unformat_fill_input (unformat_input_t * i)
45 if (i->index == UNFORMAT_END_OF_INPUT)
48 first_mark = l = vec_len (i->buffer);
49 if (vec_len (i->buffer_marks) > 0)
50 first_mark = i->buffer_marks[0];
52 /* Re-use buffer when no marks. */
54 vec_delete (i->buffer, first_mark, 0);
56 i->index = vec_len (i->buffer);
57 for (l = 0; l < vec_len (i->buffer_marks); l++)
58 i->buffer_marks[l] -= first_mark;
60 /* Call user's function to fill the buffer. */
62 i->index = i->fill_buffer (i);
64 /* If input pointer is still beyond end of buffer even after
65 fill then we've run out of input. */
66 if (i->index >= vec_len (i->buffer))
67 i->index = UNFORMAT_END_OF_INPUT;
73 is_white_space (uword c)
86 /* Format function for dumping input stream. */
87 u8 * format_unformat_error (u8 * s, va_list * va)
89 unformat_input_t * i = va_arg (*va, unformat_input_t *);
90 uword l = vec_len (i->buffer);
92 /* Only show so much of the input buffer (it could be really large). */
97 uword n = l - i->index;
100 p = i->buffer + i->index;
101 p_end = p + (n > n_max ? n_max : n);
103 /* Skip white space at end. */
106 while (p_end > p && is_white_space (p_end[-1]))
114 case '\r': vec_add (s, "\\r", 2); break;
115 case '\n': vec_add (s, "\\n", 2); break;
116 case '\t': vec_add (s, "\\t", 2); break;
117 default: vec_add1 (s, *p); break;
123 vec_add (s, "...", 3);
129 /* Print everything: not just error context. */
130 u8 * format_unformat_input (u8 * s,
133 unformat_input_t * i = va_arg (*va, unformat_input_t *);
136 if (i->index == UNFORMAT_END_OF_INPUT)
137 s = format (s, "{END_OF_INPUT}");
140 l = vec_len (i->buffer);
143 vec_add (s, i->buffer + i->index, n);
150 void di (unformat_input_t * i)
151 { fformat (stderr, "%U\n", format_unformat_input, i); }
154 /* Parse delimited vector string. If string starts with { then string
155 is delimited by balenced 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,
163 u8 ** string_return = va_arg (*va, u8 **);
166 word is_paren_delimited = 0;
170 switch (delimiter_character)
175 delimiter_character = 0;
179 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
183 /* Null return string means to skip over delimited input. */
184 add_to_vector = string_return != 0;
197 if (paren == 0 && vec_len (s) == 0)
199 is_paren_delimited = 1;
207 if (is_paren_delimited && paren == 0)
215 if (! is_paren_delimited)
217 unformat_put_input (input);
223 if (! is_paren_delimited && c == delimiter_character)
225 unformat_put_input (input);
237 /* Match the string { END-OF-INPUT as a single brace. */
238 if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0 && paren == 1)
241 /* Don't match null string. */
242 if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0)
245 /* Null terminate C string. */
246 if (format_character == 's')
252 vec_free (s); /* just to make sure */
258 unformat_hex_string (unformat_input_t * input,
261 u8 ** hexstring_return = va_arg (*va, u8 **);
268 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
270 if (c >= '0' && c <= '9')
272 else if (c >= 'a' && c <= 'f')
273 d = 16*d + 10 + c - 'a';
274 else if (c >= 'A' && c <= 'F')
275 d = 16*d + 10 + c - 'A';
278 unformat_put_input (input);
290 /* Hex string must have even number of digits. */
297 *hexstring_return = s;
301 /* unformat (input "foo%U", unformat_eof) matches terminal foo only */
303 unformat_eof (unformat_input_t * input, va_list * va)
305 return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
308 /* Parse a token containing given set of characters. */
310 unformat_token (unformat_input_t * input,
313 u8 * token_chars = va_arg (*va, u8 *);
314 u8 ** string_return = va_arg (*va, u8 **);
319 token_chars = (u8 *) "a-zA-Z0-9_";
321 memset (map, 0, sizeof (map));
322 for (s = token_chars; *s; )
325 if (s[0] < s[2] && s[1] == '-')
327 for (i = s[0]; i <= s[2]; i++)
339 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
343 unformat_put_input (input);
350 if (vec_len (s) == 0)
357 /* Unformat (parse) function which reads a %s string and converts it
358 to and unformat_input_t. */
359 uword unformat_input (unformat_input_t * i, va_list * args)
361 unformat_input_t * sub_input = va_arg (*args, unformat_input_t *);
364 if (unformat (i, "%v", &s))
366 unformat_init_vector (sub_input, s);
373 /* Parse a line ending with \n and return it. */
374 uword unformat_line (unformat_input_t * i, va_list * va)
376 u8 * line = 0, ** result = va_arg (*va, u8 **);
379 while ((c = unformat_get_input (i)) != '\n'
380 && c != UNFORMAT_END_OF_INPUT)
389 /* Parse a line ending with \n and return it as an unformat_input_t. */
390 uword unformat_line_input (unformat_input_t * i, va_list * va)
392 unformat_input_t * result = va_arg (*va, unformat_input_t *);
394 unformat_user (i, unformat_line, &line);
395 unformat_init_vector (result, line);
399 /* Values for is_signed. */
400 #define UNFORMAT_INTEGER_SIGNED 1
401 #define UNFORMAT_INTEGER_UNSIGNED 0
404 unformat_integer (unformat_input_t * input,
416 /* We only support bases <= 64. */
417 if (base < 2 || base > 64)
420 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
433 /* Leading sign for unsigned number. */
436 /* Sign after input (e.g. 100-200). */
450 digit = 10 + (c - 'a');
454 digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
472 unformat_put_input (input);
477 uword new_value = base*value + digit;
479 /* Check for overflow. */
480 if (new_value < value)
496 void * v = va_arg (*va, void *);
498 if (data_bytes == ~0)
499 data_bytes = sizeof (int);
503 case 1: *(u8 *) v = value; break;
504 case 2: *(u16 *) v = value; break;
505 case 4: *(u32 *) v = value; break;
506 case 8: *(u64 *) v = value; break;
519 static f64 times_power_of_ten (f64 x, int n)
523 static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
533 static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
545 unformat_float (unformat_input_t * input,
550 uword n_digits[3], value_index = 0;
551 uword signs[2], sign_index = 0;
554 memset (values, 0, sizeof (values));
555 memset (n_digits, 0, sizeof (n_digits));
556 memset (signs, 0, sizeof (signs));
558 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
563 if (value_index == 2 && n_digits[2] == 0)
564 /* sign of exponent: it's ok. */;
566 else if (value_index < 2 && n_digits[0] > 0)
569 unformat_put_input (input);
573 else if (n_input > 0)
576 signs[sign_index++] = 1;
580 if (value_index == 2 && n_digits[2] == 0)
581 /* sign of exponent: it's ok. */;
583 else if (value_index < 2 && n_digits[0] > 0)
586 unformat_put_input (input);
590 else if (n_input > 0)
592 signs[sign_index++] = 0;
613 tmp = values[value_index] * 10 + c - '0';
615 /* Check for overflow. */
616 if (tmp < values[value_index])
618 values[value_index] = tmp;
619 n_digits[value_index] += 1;
624 unformat_put_input (input);
634 f64 f_values[2], * value_return;
637 /* Must have either whole or fraction digits. */
638 if (n_digits[0] + n_digits[1] <= 0)
641 f_values[0] = values[0];
643 f_values[0] = -f_values[0];
645 f_values[1] = values[1];
646 f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
648 f_values[0] += f_values[1];
654 f_values[0] = times_power_of_ten (f_values[0], expon);
656 value_return = va_arg (*va, f64 *);
657 *value_return = f_values[0];
665 static char * match_input_with_format (unformat_input_t * input, char * f)
674 if (cf == 0 || cf == '%' || cf == ' ')
678 ci = unformat_get_input (input);
686 static char * do_percent (unformat_input_t * input, va_list * va, char * f)
688 uword cf, n, data_bytes = ~0;
700 data_bytes = sizeof (uword);
708 data_bytes = sizeof (long long);
712 data_bytes = sizeof (long);
718 data_bytes = sizeof (long long);
726 data_bytes = va_arg (*va, int);
728 n = unformat_integer (input, va, 10,
729 UNFORMAT_INTEGER_SIGNED, data_bytes);
733 n = unformat_integer (input, va, 10,
734 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
738 n = unformat_integer (input, va, 2,
739 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
743 n = unformat_integer (input, va, 8,
744 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
748 data_bytes = va_arg (*va, int);
750 n = unformat_integer (input, va, 16,
751 UNFORMAT_INTEGER_UNSIGNED, data_bytes);
755 n = unformat_float (input, va);
760 n = unformat_string (input, f[0], cf, va);
765 unformat_function_t * f = va_arg (*va, unformat_function_t *);
773 int * var = va_arg (*va, int *);
774 uword val = va_arg (*va, int);
787 uword unformat_skip_white_space (unformat_input_t * input)
792 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
794 if (! is_white_space (c))
796 unformat_put_input (input);
805 va_unformat (unformat_input_t * input, char * fmt, va_list * va)
808 uword input_matches_format;
809 uword default_skip_input_white_space;
810 uword n_input_white_space_skipped;
811 uword last_non_white_space_match_percent;
812 uword last_non_white_space_match_format;
814 vec_add1_aligned (input->buffer_marks, input->index, sizeof (input->buffer_marks[0]));
817 default_skip_input_white_space = 1;
818 input_matches_format = 0;
819 last_non_white_space_match_percent = 0;
820 last_non_white_space_match_format = 0;
825 uword is_percent, skip_input_white_space;
830 /* Always skip input white space at start of format string.
831 Otherwise use default skip value which can be changed by %_
833 skip_input_white_space = f == fmt || default_skip_input_white_space;
835 /* Spaces in format request skipping input white space. */
836 if (is_white_space (cf))
838 skip_input_white_space = 1;
840 /* Multiple format spaces are equivalent to a single white
842 while (is_white_space (*++f))
847 /* %_ toggles whether or not to skip input white space. */
851 default_skip_input_white_space = !default_skip_input_white_space;
853 /* For transition from skip to no-skip in middle of format
854 string, skip input white space. For example, the following matches:
855 fmt = "%_%d.%d%_->%_%d.%d%_"
857 Without this the space after -> does not get skipped. */
858 if (! default_skip_input_white_space
859 && ! (f == fmt + 2 || *f == 0))
860 unformat_skip_white_space (input);
863 /* %% means match % */
867 /* % at end of format string. */
877 n_input_white_space_skipped = 0;
878 if (skip_input_white_space)
879 n_input_white_space_skipped = unformat_skip_white_space (input);
881 /* End of format string. */
884 /* Force parse error when format string ends and input is
885 not white or at end. As an example, this is to prevent
886 format "foo" from matching input "food".
887 The last_non_white_space_match_percent is to make
888 "foo %d" match input "foo 10,bletch" with %d matching 10. */
889 if (skip_input_white_space
890 && ! last_non_white_space_match_percent
891 && ! last_non_white_space_match_format
892 && n_input_white_space_skipped == 0
893 && input->index != UNFORMAT_END_OF_INPUT)
898 last_non_white_space_match_percent = is_percent;
899 last_non_white_space_match_format = 0;
901 /* Explicit spaces in format must match input white space. */
902 if (cf == ' ' && !default_skip_input_white_space)
904 if (n_input_white_space_skipped == 0)
910 if (! (f = do_percent (input, va, f)))
916 char * g = match_input_with_format (input, f);
919 last_non_white_space_match_format = g > f;
924 input_matches_format = 1;
927 /* Rewind buffer marks. */
929 uword l = vec_len (input->buffer_marks);
931 /* If we did not match back up buffer to last mark. */
932 if (! input_matches_format)
933 input->index = input->buffer_marks[l-1];
935 _vec_len (input->buffer_marks) = l - 1;
938 return input_matches_format;
942 unformat (unformat_input_t * input, char * fmt, ...)
947 result = va_unformat (input, fmt, &va);
953 unformat_user (unformat_input_t * input, unformat_function_t * func, ...)
958 /* Save place in input buffer in case parse fails. */
959 l = vec_len (input->buffer_marks);
960 vec_add1_aligned (input->buffer_marks, input->index, sizeof (input->buffer_marks[0]));
963 result = func (input, &va);
967 input->index = input->buffer_marks[l];
969 _vec_len (input->buffer_marks) = l;
974 /* Setup for unformat of Unix style command line. */
975 void unformat_init_command_line (unformat_input_t * input,
980 unformat_init (input, 0, 0);
982 /* Concatenate argument strings with space in between. */
983 for (i = 1; argv[i]; i++)
985 vec_add (input->buffer, argv[i], strlen (argv[i]));
987 vec_add1 (input->buffer, ' ');
991 void unformat_init_string (unformat_input_t * input,
995 unformat_init (input, 0, 0);
997 vec_add (input->buffer, string, string_len);
1000 void unformat_init_vector (unformat_input_t * input,
1003 unformat_init (input, 0, 0);
1004 input->buffer = vector_string;
1009 static uword unix_file_fill_buffer (unformat_input_t * input)
1011 int fd = pointer_to_uword (input->fill_buffer_arg);
1014 l = vec_len (input->buffer);
1015 vec_resize (input->buffer, 4096);
1016 n = read (fd, input->buffer + l, 4096);
1018 _vec_len (input->buffer) = l + n;
1021 return UNFORMAT_END_OF_INPUT;
1023 return input->index;
1026 void unformat_init_unix_file (unformat_input_t * input,
1027 int file_descriptor)
1029 unformat_init (input, unix_file_fill_buffer,
1030 uword_to_pointer (file_descriptor, void *));
1033 /* Take input from Unix environment variable. */
1034 uword unformat_init_unix_env (unformat_input_t * input, char * var)
1036 char * val = getenv (var);
1038 unformat_init_string (input, val, strlen (val));
1042 #endif /* CLIB_UNIX */