LCOV - code coverage report
Current view: top level - vppinfra - format.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 43 54 79.6 %
Date: 2023-10-26 01:39:38 Functions: 8 11 72.7 %

          Line data    Source code
       1             : /*
       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:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       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.
      14             :  */
      15             : /*
      16             :   Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
      17             : 
      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:
      25             : 
      26             :   The above copyright notice and this permission notice shall be
      27             :   included in all copies or substantial portions of the Software.
      28             : 
      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.
      36             : */
      37             : 
      38             : #ifndef included_format_h
      39             : #define included_format_h
      40             : 
      41             : #include <stdarg.h>
      42             : 
      43             : #include <vppinfra/clib.h>        /* for CLIB_UNIX, etc. */
      44             : #include <vppinfra/vec.h>
      45             : #include <vppinfra/error.h>       /* for ASSERT */
      46             : #include <vppinfra/string.h>
      47             : 
      48             : typedef u8 *(format_function_t) (u8 * s, va_list * args);
      49             : 
      50             : u8 *va_format (u8 * s, const char *format, va_list * args);
      51             : u8 *format (u8 * s, const char *format, ...);
      52             : 
      53             : #ifdef CLIB_UNIX
      54             : 
      55             : #include <stdio.h>
      56             : 
      57             : #else /* ! CLIB_UNIX */
      58             : 
      59             : /* We're not Unix and have not stdio.h */
      60             : #define FILE void
      61             : #define stdin ((FILE *) 0)
      62             : #define stdout ((FILE *) 1)
      63             : #define stderr ((FILE *) 2)
      64             : 
      65             : #endif
      66             : 
      67             : word va_fformat (FILE * f, char *fmt, va_list * va);
      68             : word fformat (FILE * f, char *fmt, ...);
      69             : word fdformat (int fd, char *fmt, ...);
      70             : 
      71             : always_inline u32
      72     8361523 : format_get_indent (u8 * s)
      73             : {
      74     8361523 :   u32 indent = 0;
      75             :   u8 *nl;
      76             : 
      77     8361523 :   if (!s)
      78      136430 :     return indent;
      79             : 
      80     8225093 :   nl = vec_end (s) - 1;
      81    69931587 :   while (nl >= s)
      82             :     {
      83    69903180 :       if (*nl-- == '\n')
      84     8196676 :         break;
      85    61706490 :       indent++;
      86             :     }
      87     8225093 :   return indent;
      88             : }
      89             : 
      90             : #define _(f) __clib_export u8 * f (u8 * s, va_list * va)
      91             : 
      92             : /* Standard user-defined formats. */
      93             : _(format_vec32);
      94             : _(format_vec_uword);
      95             : _(format_ascii_bytes);
      96             : _(format_hex_bytes);
      97             : _(format_hex_bytes_no_wrap);
      98             : _(format_white_space);
      99             : _(format_f64);
     100             : _(format_time_interval);
     101             : _ (format_duration);
     102             : 
     103             : #ifdef CLIB_UNIX
     104             : /* Unix specific formats. */
     105             : _(format_address_family);
     106             : _(format_network_address);
     107             : _(format_network_protocol);
     108             : _(format_network_port);
     109             : _(format_sockaddr);
     110             : _(format_timeval);
     111             : _(format_time_float);
     112             : _(format_signal);
     113             : _(format_ucontext_pc);
     114             : #endif
     115             : 
     116             : #undef _
     117             : 
     118             : /* Unformat. */
     119             : 
     120             : typedef struct _unformat_input_t
     121             : {
     122             :   /* Input buffer (vector). */
     123             :   u8 *buffer;
     124             : 
     125             :   /* Current index in input buffer. */
     126             :   uword index;
     127             : 
     128             :   /* Vector of buffer marks.  Used to delineate pieces of the buffer
     129             :      for error reporting and for parse recovery. */
     130             :   uword *buffer_marks;
     131             : 
     132             :   /* User's function to fill the buffer when its empty
     133             :      (and argument). */
     134             :     uword (*fill_buffer) (struct _unformat_input_t * i);
     135             : 
     136             :     /* User's function to be called on input_free */
     137             :     void (*free) (struct _unformat_input_t *i);
     138             : 
     139             :     /* Return values for fill buffer function which indicate whether not
     140             :        input has been exhausted. */
     141             : #define UNFORMAT_END_OF_INPUT (~0)
     142             : #define UNFORMAT_MORE_INPUT   0
     143             : 
     144             :   /* User controlled argument to fill buffer function. */
     145             :   void *fill_buffer_arg;
     146             : } unformat_input_t;
     147             : 
     148             : always_inline void
     149     1466499 : unformat_init (unformat_input_t * i,
     150             :                uword (*fill_buffer) (unformat_input_t *),
     151             :                void *fill_buffer_arg)
     152             : {
     153     1466499 :   clib_memset (i, 0, sizeof (i[0]));
     154     1466499 :   i->fill_buffer = fill_buffer;
     155     1466499 :   i->fill_buffer_arg = fill_buffer_arg;
     156     1466499 : }
     157             : 
     158             : always_inline void
     159      592183 : unformat_free (unformat_input_t * i)
     160             : {
     161      592183 :   if (i->free)
     162           0 :     i->free (i);
     163      592183 :   vec_free (i->buffer);
     164      592183 :   vec_free (i->buffer_marks);
     165      592183 :   clib_memset (i, 0, sizeof (i[0]));
     166      592183 : }
     167             : 
     168             : always_inline uword
     169    53397530 : unformat_check_input (unformat_input_t * i)
     170             : {
     171             :   /* Low level fill input function. */
     172             :   extern uword _unformat_fill_input (unformat_input_t * i);
     173             : 
     174    53397530 :   if (i->index >= vec_len (i->buffer) && i->index != UNFORMAT_END_OF_INPUT)
     175     1517473 :     _unformat_fill_input (i);
     176             : 
     177    53397530 :   return i->index;
     178             : }
     179             : 
     180             : /* Return true if input is exhausted */
     181             : always_inline uword
     182           0 : unformat_is_eof (unformat_input_t * input)
     183             : {
     184           0 :   return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
     185             : }
     186             : 
     187             : /* Return next element in input vector,
     188             :    possibly calling fill input to get more. */
     189             : always_inline uword
     190    52568080 : unformat_get_input (unformat_input_t * input)
     191             : {
     192    52568080 :   uword i = unformat_check_input (input);
     193    52568080 :   if (i < vec_len (input->buffer))
     194             :     {
     195    49463592 :       input->index = i + 1;
     196    49463592 :       i = input->buffer[i];
     197             :     }
     198    52568080 :   return i;
     199             : }
     200             : 
     201             : /* Back up input pointer by one. */
     202             : always_inline void
     203    11632844 : unformat_put_input (unformat_input_t * input)
     204             : {
     205    11632844 :   input->index -= 1;
     206    11632844 : }
     207             : 
     208             : always_inline uword
     209    22427700 : is_white_space (uword c)
     210             : {
     211    22427700 :   switch (c)
     212             :     {
     213     1533500 :     case ' ':
     214             :     case '\t':
     215             :     case '\n':
     216             :     case '\r':
     217     1533500 :       return 1;
     218             : 
     219    20894200 :     default:
     220    20894200 :       return 0;
     221             :     }
     222             : }
     223             : 
     224             : /* Peek current input character without advancing. */
     225             : always_inline uword
     226           0 : unformat_peek_input (unformat_input_t * input)
     227             : {
     228           0 :   uword c = unformat_get_input (input);
     229           0 :   if (c != UNFORMAT_END_OF_INPUT)
     230           0 :     unformat_put_input (input);
     231           0 :   return c;
     232             : }
     233             : 
     234             : /* Skip current input line. */
     235             : always_inline void
     236           0 : unformat_skip_line (unformat_input_t * i)
     237             : {
     238             :   uword c;
     239             : 
     240           0 :   while ((c = unformat_get_input (i)) != UNFORMAT_END_OF_INPUT && c != '\n')
     241             :     ;
     242           0 : }
     243             : 
     244             : uword unformat_skip_white_space (unformat_input_t * input);
     245             : 
     246             : /* Unformat function. */
     247             : typedef uword (unformat_function_t) (unformat_input_t * input,
     248             :                                      va_list * args);
     249             : 
     250             : /* External functions. */
     251             : 
     252             : /* General unformatting function with programmable input stream. */
     253             : uword unformat (unformat_input_t * i, const char *fmt, ...);
     254             : 
     255             : /* Call user defined parse function.
     256             :    unformat_user (i, f, ...) is equivalent to unformat (i, "%U", f, ...) */
     257             : uword unformat_user (unformat_input_t * input, unformat_function_t * func,
     258             :                      ...);
     259             : 
     260             : /* Alternate version which allows for extensions. */
     261             : uword va_unformat (unformat_input_t * i, const char *fmt, va_list * args);
     262             : 
     263             : /* Setup for unformat of Unix style command line. */
     264             : void unformat_init_command_line (unformat_input_t * input, char *argv[]);
     265             : 
     266             : /* Setup for unformat of given string. */
     267             : void unformat_init_string (unformat_input_t *input, const char *string,
     268             :                            int string_len);
     269             : 
     270             : always_inline void
     271          12 : unformat_init_cstring (unformat_input_t * input, char *string)
     272             : {
     273          12 :   unformat_init_string (input, string, strlen (string));
     274          12 : }
     275             : 
     276             : /* Setup for unformat of given vector string; vector will be freed by unformat_string. */
     277             : void unformat_init_vector (unformat_input_t * input, u8 * vector_string);
     278             : 
     279             : /* Format function for unformat input usable when an unformat error
     280             :    has occurred. */
     281             : u8 *format_unformat_error (u8 * s, va_list * va);
     282             : 
     283             : #define unformat_parse_error(input)                                             \
     284             :   clib_error_return (0, "parse error `%U'", format_unformat_error, input)
     285             : 
     286             : /* Print all input: not just error context. */
     287             : u8 *format_unformat_input (u8 * s, va_list * va);
     288             : 
     289             : /* Unformat (parse) function which reads a %s string and converts it
     290             :    to and unformat_input_t. */
     291             : unformat_function_t unformat_input;
     292             : 
     293             : /* Parse a line ending with \n and return it. */
     294             : unformat_function_t unformat_line;
     295             : 
     296             : /* Parse a line ending with \n and return it as an unformat_input_t. */
     297             : unformat_function_t unformat_line_input;
     298             : 
     299             : /* Parse a token containing given set of characters. */
     300             : unformat_function_t unformat_token;
     301             : 
     302             : /* Parses a hexstring into a vector of bytes. */
     303             : unformat_function_t unformat_hex_string;
     304             : 
     305             : /* Returns non-zero match if input is exhausted.
     306             :    Useful to ensure that the entire input matches with no trailing junk. */
     307             : unformat_function_t unformat_eof;
     308             : 
     309             : /* Parse memory size e.g. 100, 100k, 100m, 100g. */
     310             : unformat_function_t unformat_memory_size;
     311             : 
     312             : /* Unformat C string array, takes array length as 2nd argument */
     313             : unformat_function_t unformat_c_string_array;
     314             : 
     315             : /* Format base 10 e.g. 100, 100K, 100M, 100G */
     316             : u8 *format_base10 (u8 *s, va_list *va);
     317             : 
     318             : /* Unparse memory size e.g. 100, 100k, 100m, 100g. */
     319             : u8 *format_memory_size (u8 * s, va_list * va);
     320             : 
     321             : /* Parse memory page size e.g. 4K, 2M */
     322             : unformat_function_t unformat_log2_page_size;
     323             : 
     324             : /* Unparse memory page size e.g. 4K, 2M */
     325             : u8 *format_log2_page_size (u8 * s, va_list * va);
     326             : 
     327             : /* Format c identifier: e.g. a_name -> "a name". */
     328             : u8 *format_c_identifier (u8 * s, va_list * va);
     329             : 
     330             : /* Format hexdump with both hex and printable chars - compatible with text2pcap */
     331             : u8 *format_hexdump (u8 * s, va_list * va);
     332             : u8 *format_hexdump_u16 (u8 *s, va_list *va);
     333             : u8 *format_hexdump_u32 (u8 *s, va_list *va);
     334             : u8 *format_hexdump_u64 (u8 *s, va_list *va);
     335             : 
     336             : /* Format bitmap of array of uword numbers */
     337             : u8 *format_uword_bitmap (u8 *s, va_list *va);
     338             : 
     339             : /* Unix specific formats. */
     340             : #ifdef CLIB_UNIX
     341             : /* Setup input from Unix file. */
     342             : void unformat_init_clib_file (unformat_input_t * input, int file_descriptor);
     343             : 
     344             : /* Setup input from flesystem path. */
     345             : uword unformat_init_file (unformat_input_t *input, char *fmt, ...);
     346             : 
     347             : /* Take input from Unix environment variable; returns
     348             :    1 if variable exists zero otherwise. */
     349             : uword unformat_init_unix_env (unformat_input_t * input, char *var);
     350             : 
     351             : /* Unformat unix group id (gid) specified as integer or string */
     352             : unformat_function_t unformat_unix_gid;
     353             : #endif /* CLIB_UNIX */
     354             : 
     355             : uword unformat_data_size (unformat_input_t * input, va_list * args);
     356             : 
     357             : /* Test code. */
     358             : int test_format_main (unformat_input_t * input);
     359             : int test_unformat_main (unformat_input_t * input);
     360             : 
     361             : /* This is not the right place for this, but putting it in vec.h
     362             : created circular dependency problems. */
     363             : int test_vec_main (unformat_input_t * input);
     364             : 
     365             : #endif /* included_format_h */
     366             : 
     367             : /*
     368             :  * fd.io coding-style-patch-verification: ON
     369             :  *
     370             :  * Local Variables:
     371             :  * eval: (c-set-style "gnu")
     372             :  * End:
     373             :  */

Generated by: LCOV version 1.14