X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Funformat.c;h=fe1a46e4a1269fd41fa80d8a76c731c6d88bb9ff;hb=8ae63db02066a2b5ac18a89fd63dc0dd2a811ab3;hp=f626f05e3553b51fb42b765ebd5891e574dd489c;hpb=205e934ee7530dac475be14d9054183625171ccc;p=vpp.git diff --git a/src/vppinfra/unformat.c b/src/vppinfra/unformat.c index f626f05e355..fe1a46e4a12 100644 --- a/src/vppinfra/unformat.c +++ b/src/vppinfra/unformat.c @@ -36,9 +36,10 @@ */ #include +#include /* Call user's function to fill input buffer. */ -uword +__clib_export uword _unformat_fill_input (unformat_input_t * i) { uword l, first_mark; @@ -70,24 +71,8 @@ _unformat_fill_input (unformat_input_t * i) return i->index; } -always_inline uword -is_white_space (uword c) -{ - switch (c) - { - case ' ': - case '\t': - case '\n': - case '\r': - return 1; - - default: - return 0; - } -} - /* Format function for dumping input stream. */ -u8 * +__clib_export u8 * format_unformat_error (u8 * s, va_list * va) { unformat_input_t *i = va_arg (*va, unformat_input_t *); @@ -139,7 +124,7 @@ format_unformat_error (u8 * s, va_list * va) } /* Print everything: not just error context. */ -u8 * +__clib_export u8 * format_unformat_input (u8 * s, va_list * va) { unformat_input_t *i = va_arg (*va, unformat_input_t *); @@ -167,7 +152,7 @@ di (unformat_input_t * i) #endif /* Parse delimited vector string. If string starts with { then string - is delimited by balenced parenthesis. Other string is delimited by + is delimited by balanced parenthesis. Other string is delimited by white space. {} were chosen since they are special to the shell. */ static uword unformat_string (unformat_input_t * input, @@ -268,7 +253,7 @@ done: return 1; } -uword +__clib_export uword unformat_hex_string (unformat_input_t * input, va_list * va) { u8 **hexstring_return = va_arg (*va, u8 **); @@ -317,14 +302,14 @@ unformat_hex_string (unformat_input_t * input, va_list * va) } /* unformat (input "foo%U", unformat_eof) matches terminal foo only */ -uword +__clib_export uword unformat_eof (unformat_input_t * input, va_list * va) { return unformat_check_input (input) == UNFORMAT_END_OF_INPUT; } /* Parse a token containing given set of characters. */ -uword +__clib_export uword unformat_token (unformat_input_t * input, va_list * va) { u8 *token_chars = va_arg (*va, u8 *); @@ -335,11 +320,17 @@ unformat_token (unformat_input_t * input, va_list * va) if (!token_chars) token_chars = (u8 *) "a-zA-Z0-9_"; - memset (map, 0, sizeof (map)); + clib_memset (map, 0, sizeof (map)); for (s = token_chars; *s;) { - /* Parse range. */ - if (s[0] < s[2] && s[1] == '-') + /* + * Parse range. + * The test order is important: s[1] is valid because s[0] != '\0' but + * s[2] might not if s[1] == '\0' + * Also, if s[1] == '-' but s[2] == '\0' the test s[0] < s[2] will + * (correctly) fail + */ + if (s[1] == '-' && s[0] < s[2]) { for (i = s[0]; i <= s[2]; i++) map[i] = 1; @@ -373,7 +364,7 @@ unformat_token (unformat_input_t * input, va_list * va) /* Unformat (parse) function which reads a %s string and converts it to and unformat_input_t. */ -uword +__clib_export uword unformat_input (unformat_input_t * i, va_list * args) { unformat_input_t *sub_input = va_arg (*args, unformat_input_t *); @@ -389,7 +380,7 @@ unformat_input (unformat_input_t * i, va_list * args) } /* Parse a line ending with \n and return it. */ -uword +__clib_export uword unformat_line (unformat_input_t * i, va_list * va) { u8 *line = 0, **result = va_arg (*va, u8 **); @@ -401,16 +392,17 @@ unformat_line (unformat_input_t * i, va_list * va) } *result = line; - return 1; + return vec_len (line); } /* Parse a line ending with \n and return it as an unformat_input_t. */ -uword +__clib_export uword unformat_line_input (unformat_input_t * i, va_list * va) { unformat_input_t *result = va_arg (*va, unformat_input_t *); u8 *line; - unformat_user (i, unformat_line, &line); + if (!unformat_user (i, unformat_line, &line)) + return 0; unformat_init_vector (result, line); return 1; } @@ -575,9 +567,9 @@ unformat_float (unformat_input_t * input, va_list * va) uword signs[2], sign_index = 0; uword n_input = 0; - memset (values, 0, sizeof (values)); - memset (n_digits, 0, sizeof (n_digits)); - memset (signs, 0, sizeof (signs)); + clib_memset (values, 0, sizeof (values)); + clib_memset (n_digits, 0, sizeof (n_digits)); + clib_memset (signs, 0, sizeof (signs)); while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT) { @@ -810,7 +802,7 @@ do_percent (unformat_input_t * input, va_list * va, const char *f) return n ? f : 0; } -uword +__clib_export uword unformat_skip_white_space (unformat_input_t * input) { uword n = 0; @@ -828,7 +820,7 @@ unformat_skip_white_space (unformat_input_t * input) return n; } -uword +__clib_export uword va_unformat (unformat_input_t * input, const char *fmt, va_list * va) { const char *f; @@ -961,13 +953,13 @@ parse_fail: if (!input_matches_format) input->index = input->buffer_marks[l - 1]; - _vec_len (input->buffer_marks) = l - 1; + vec_set_len (input->buffer_marks, l - 1); } return input_matches_format; } -uword +__clib_export uword unformat (unformat_input_t * input, const char *fmt, ...) { va_list va; @@ -978,7 +970,7 @@ unformat (unformat_input_t * input, const char *fmt, ...) return result; } -uword +__clib_export uword unformat_user (unformat_input_t * input, unformat_function_t * func, ...) { va_list va; @@ -996,13 +988,13 @@ unformat_user (unformat_input_t * input, unformat_function_t * func, ...) if (!result && input->index != UNFORMAT_END_OF_INPUT) input->index = input->buffer_marks[l]; - _vec_len (input->buffer_marks) = l; + vec_set_len (input->buffer_marks, l); return result; } /* Setup for unformat of Unix style command line. */ -void +__clib_export void unformat_init_command_line (unformat_input_t * input, char *argv[]) { uword i; @@ -1018,15 +1010,16 @@ unformat_init_command_line (unformat_input_t * input, char *argv[]) } } -void -unformat_init_string (unformat_input_t * input, char *string, int string_len) +__clib_export void +unformat_init_string (unformat_input_t *input, const char *string, + int string_len) { unformat_init (input, 0, 0); if (string_len > 0) vec_add (input->buffer, string, string_len); } -void +__clib_export void unformat_init_vector (unformat_input_t * input, u8 * vector_string) { unformat_init (input, 0, 0); @@ -1036,7 +1029,7 @@ unformat_init_vector (unformat_input_t * input, u8 * vector_string) #ifdef CLIB_UNIX static uword -unix_file_fill_buffer (unformat_input_t * input) +clib_file_fill_buffer (unformat_input_t * input) { int fd = pointer_to_uword (input->fill_buffer_arg); uword l, n; @@ -1045,7 +1038,7 @@ unix_file_fill_buffer (unformat_input_t * input) vec_resize (input->buffer, 4096); n = read (fd, input->buffer + l, 4096); if (n > 0) - _vec_len (input->buffer) = l + n; + vec_set_len (input->buffer, l + n); if (n <= 0) return UNFORMAT_END_OF_INPUT; @@ -1053,13 +1046,45 @@ unix_file_fill_buffer (unformat_input_t * input) return input->index; } -void -unformat_init_unix_file (unformat_input_t * input, int file_descriptor) +static void +unformat_close_fd (unformat_input_t *input) { - unformat_init (input, unix_file_fill_buffer, + int fd = pointer_to_uword (input->fill_buffer_arg); + close (fd); +} + +__clib_export void +unformat_init_clib_file (unformat_input_t * input, int file_descriptor) +{ + unformat_init (input, clib_file_fill_buffer, uword_to_pointer (file_descriptor, void *)); } +__clib_export uword +unformat_init_file (unformat_input_t *input, char *fmt, ...) +{ + va_list va; + u8 *path; + int fd; + + va_start (va, fmt); + path = va_format (0, fmt, &va); + va_end (va); + vec_add1 (path, 0); + + fd = open ((char *) path, 0); + vec_free (path); + + if (fd >= 0) + { + unformat_init (input, clib_file_fill_buffer, + uword_to_pointer (fd, void *)); + input->free = unformat_close_fd; + return 1; + } + return 0; +} + /* Take input from Unix environment variable. */ uword unformat_init_unix_env (unformat_input_t * input, char *var) @@ -1070,6 +1095,94 @@ unformat_init_unix_env (unformat_input_t * input, char *var) return val != 0; } +__clib_export uword +unformat_data_size (unformat_input_t * input, va_list * args) +{ + u64 _a; + u64 *a = va_arg (*args, u64 *); + if (unformat (input, "%lluGb", &_a)) + *a = _a << 30; + else if (unformat (input, "%lluG", &_a)) + *a = _a << 30; + else if (unformat (input, "%lluMb", &_a)) + *a = _a << 20; + else if (unformat (input, "%lluM", &_a)) + *a = _a << 20; + else if (unformat (input, "%lluKb", &_a)) + *a = _a << 10; + else if (unformat (input, "%lluK", &_a)) + *a = _a << 10; + else if (unformat (input, "%llu", a)) + ; + else + return 0; + return 1; +} + +__clib_export uword +unformat_c_string_array (unformat_input_t *input, va_list *va) +{ + char *str = va_arg (*va, char *); + u32 array_len = va_arg (*va, u32); + uword c, rv = 0; + u8 *s = 0; + + if (unformat (input, "%v", &s) == 0) + return 0; + + c = vec_len (s); + + if (c > 0 && c < array_len) + { + clib_memcpy (str, s, c); + str[c] = 0; + rv = 1; + } + + vec_free (s); + return rv; +} + +static uword +__unformat_quoted_string (unformat_input_t *input, u8 **sp, char quote) +{ + u8 *s = 0; + uword c, p = 0; + + while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT) + if (!is_white_space (c)) + break; + + if (c != quote) + return 0; + + while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT) + { + if (c == quote && p != '\\') + { + *sp = s; + return 1; + } + vec_add1 (s, c); + p = c; + } + vec_free (s); + + return 0; +} + +__clib_export uword +unformat_single_quoted_string (unformat_input_t *input, va_list *va) +{ + return __unformat_quoted_string (input, va_arg (*va, u8 **), '\''); +} + +__clib_export uword +unformat_double_quoted_string (unformat_input_t *input, va_list *va) +{ + return __unformat_quoted_string (input, va_arg (*va, u8 **), '"'); +} + #endif /* CLIB_UNIX */