LCOV - code coverage report
Current view: top level - vppinfra - format.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 42 52 80.8 %
Date: 2023-07-05 22:20:52 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     7748387 : format_get_indent (u8 * s)
      73             : {
      74     7748387 :   u32 indent = 0;
      75             :   u8 *nl;
      76             : 
      77     7748387 :   if (!s)
      78      134366 :     return indent;
      79             : 
      80     7614021 :   nl = vec_end (s) - 1;
      81    64678777 :   while (nl >= s)
      82             :     {
      83    64651690 :       if (*nl-- == '\n')
      84     7586914 :         break;
      85    57064713 :       indent++;
      86             :     }
      87     7614021 :   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             :   /* Return values for fill buffer function which indicate whether not
     137             :      input has been exhausted. */
     138             : #define UNFORMAT_END_OF_INPUT (~0)
     139             : #define UNFORMAT_MORE_INPUT   0
     140             : 
     141             :   /* User controlled argument to fill buffer function. */
     142             :   void *fill_buffer_arg;
     143             : } unformat_input_t;
     144             : 
     145             : always_inline void
     146     1457419 : unformat_init (unformat_input_t * i,
     147             :                uword (*fill_buffer) (unformat_input_t *),
     148             :                void *fill_buffer_arg)
     149             : {
     150     1457419 :   clib_memset (i, 0, sizeof (i[0]));
     151     1457419 :   i->fill_buffer = fill_buffer;
     152     1457419 :   i->fill_buffer_arg = fill_buffer_arg;
     153     1457419 : }
     154             : 
     155             : always_inline void
     156      773456 : unformat_free (unformat_input_t * i)
     157             : {
     158      773456 :   vec_free (i->buffer);
     159      773456 :   vec_free (i->buffer_marks);
     160      773456 :   clib_memset (i, 0, sizeof (i[0]));
     161      773456 : }
     162             : 
     163             : always_inline uword
     164    50982589 : unformat_check_input (unformat_input_t * i)
     165             : {
     166             :   /* Low level fill input function. */
     167             :   extern uword _unformat_fill_input (unformat_input_t * i);
     168             : 
     169    50982589 :   if (i->index >= vec_len (i->buffer) && i->index != UNFORMAT_END_OF_INPUT)
     170     1505916 :     _unformat_fill_input (i);
     171             : 
     172    50982589 :   return i->index;
     173             : }
     174             : 
     175             : /* Return true if input is exhausted */
     176             : always_inline uword
     177           0 : unformat_is_eof (unformat_input_t * input)
     178             : {
     179           0 :   return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
     180             : }
     181             : 
     182             : /* Return next element in input vector,
     183             :    possibly calling fill input to get more. */
     184             : always_inline uword
     185    50187689 : unformat_get_input (unformat_input_t * input)
     186             : {
     187    50187689 :   uword i = unformat_check_input (input);
     188    50187689 :   if (i < vec_len (input->buffer))
     189             :     {
     190    46949725 :       input->index = i + 1;
     191    46949725 :       i = input->buffer[i];
     192             :     }
     193    50187689 :   return i;
     194             : }
     195             : 
     196             : /* Back up input pointer by one. */
     197             : always_inline void
     198    10907118 : unformat_put_input (unformat_input_t * input)
     199             : {
     200    10907118 :   input->index -= 1;
     201    10907118 : }
     202             : 
     203             : always_inline uword
     204    21205300 : is_white_space (uword c)
     205             : {
     206    21205300 :   switch (c)
     207             :     {
     208     1315220 :     case ' ':
     209             :     case '\t':
     210             :     case '\n':
     211             :     case '\r':
     212     1315220 :       return 1;
     213             : 
     214    19890100 :     default:
     215    19890100 :       return 0;
     216             :     }
     217             : }
     218             : 
     219             : /* Peek current input character without advancing. */
     220             : always_inline uword
     221           0 : unformat_peek_input (unformat_input_t * input)
     222             : {
     223           0 :   uword c = unformat_get_input (input);
     224           0 :   if (c != UNFORMAT_END_OF_INPUT)
     225           0 :     unformat_put_input (input);
     226           0 :   return c;
     227             : }
     228             : 
     229             : /* Skip current input line. */
     230             : always_inline void
     231           0 : unformat_skip_line (unformat_input_t * i)
     232             : {
     233             :   uword c;
     234             : 
     235           0 :   while ((c = unformat_get_input (i)) != UNFORMAT_END_OF_INPUT && c != '\n')
     236             :     ;
     237           0 : }
     238             : 
     239             : uword unformat_skip_white_space (unformat_input_t * input);
     240             : 
     241             : /* Unformat function. */
     242             : typedef uword (unformat_function_t) (unformat_input_t * input,
     243             :                                      va_list * args);
     244             : 
     245             : /* External functions. */
     246             : 
     247             : /* General unformatting function with programmable input stream. */
     248             : uword unformat (unformat_input_t * i, const char *fmt, ...);
     249             : 
     250             : /* Call user defined parse function.
     251             :    unformat_user (i, f, ...) is equivalent to unformat (i, "%U", f, ...) */
     252             : uword unformat_user (unformat_input_t * input, unformat_function_t * func,
     253             :                      ...);
     254             : 
     255             : /* Alternate version which allows for extensions. */
     256             : uword va_unformat (unformat_input_t * i, const char *fmt, va_list * args);
     257             : 
     258             : /* Setup for unformat of Unix style command line. */
     259             : void unformat_init_command_line (unformat_input_t * input, char *argv[]);
     260             : 
     261             : /* Setup for unformat of given string. */
     262             : void unformat_init_string (unformat_input_t *input, const char *string,
     263             :                            int string_len);
     264             : 
     265             : always_inline void
     266          12 : unformat_init_cstring (unformat_input_t * input, char *string)
     267             : {
     268          12 :   unformat_init_string (input, string, strlen (string));
     269          12 : }
     270             : 
     271             : /* Setup for unformat of given vector string; vector will be freed by unformat_string. */
     272             : void unformat_init_vector (unformat_input_t * input, u8 * vector_string);
     273             : 
     274             : /* Format function for unformat input usable when an unformat error
     275             :    has occurred. */
     276             : u8 *format_unformat_error (u8 * s, va_list * va);
     277             : 
     278             : #define unformat_parse_error(input)                                             \
     279             :   clib_error_return (0, "parse error `%U'", format_unformat_error, input)
     280             : 
     281             : /* Print all input: not just error context. */
     282             : u8 *format_unformat_input (u8 * s, va_list * va);
     283             : 
     284             : /* Unformat (parse) function which reads a %s string and converts it
     285             :    to and unformat_input_t. */
     286             : unformat_function_t unformat_input;
     287             : 
     288             : /* Parse a line ending with \n and return it. */
     289             : unformat_function_t unformat_line;
     290             : 
     291             : /* Parse a line ending with \n and return it as an unformat_input_t. */
     292             : unformat_function_t unformat_line_input;
     293             : 
     294             : /* Parse a token containing given set of characters. */
     295             : unformat_function_t unformat_token;
     296             : 
     297             : /* Parses a hexstring into a vector of bytes. */
     298             : unformat_function_t unformat_hex_string;
     299             : 
     300             : /* Returns non-zero match if input is exhausted.
     301             :    Useful to ensure that the entire input matches with no trailing junk. */
     302             : unformat_function_t unformat_eof;
     303             : 
     304             : /* Parse memory size e.g. 100, 100k, 100m, 100g. */
     305             : unformat_function_t unformat_memory_size;
     306             : 
     307             : /* Format base 10 e.g. 100, 100K, 100M, 100G */
     308             : u8 *format_base10 (u8 *s, va_list *va);
     309             : 
     310             : /* Unparse memory size e.g. 100, 100k, 100m, 100g. */
     311             : u8 *format_memory_size (u8 * s, va_list * va);
     312             : 
     313             : /* Parse memory page size e.g. 4K, 2M */
     314             : unformat_function_t unformat_log2_page_size;
     315             : 
     316             : /* Unparse memory page size e.g. 4K, 2M */
     317             : u8 *format_log2_page_size (u8 * s, va_list * va);
     318             : 
     319             : /* Format c identifier: e.g. a_name -> "a name". */
     320             : u8 *format_c_identifier (u8 * s, va_list * va);
     321             : 
     322             : /* Format hexdump with both hex and printable chars - compatible with text2pcap */
     323             : u8 *format_hexdump (u8 * s, va_list * va);
     324             : u8 *format_hexdump_u16 (u8 *s, va_list *va);
     325             : u8 *format_hexdump_u32 (u8 *s, va_list *va);
     326             : u8 *format_hexdump_u64 (u8 *s, va_list *va);
     327             : 
     328             : /* Format bitmap of array of uword numbers */
     329             : u8 *format_uword_bitmap (u8 *s, va_list *va);
     330             : 
     331             : /* Unix specific formats. */
     332             : #ifdef CLIB_UNIX
     333             : /* Setup input from Unix file. */
     334             : void unformat_init_clib_file (unformat_input_t * input, int file_descriptor);
     335             : 
     336             : /* Take input from Unix environment variable; returns
     337             :    1 if variable exists zero otherwise. */
     338             : uword unformat_init_unix_env (unformat_input_t * input, char *var);
     339             : 
     340             : /* Unformat unix group id (gid) specified as integer or string */
     341             : unformat_function_t unformat_unix_gid;
     342             : #endif /* CLIB_UNIX */
     343             : 
     344             : uword unformat_data_size (unformat_input_t * input, va_list * args);
     345             : 
     346             : /* Test code. */
     347             : int test_format_main (unformat_input_t * input);
     348             : int test_unformat_main (unformat_input_t * input);
     349             : 
     350             : /* This is not the right place for this, but putting it in vec.h
     351             : created circular dependency problems. */
     352             : int test_vec_main (unformat_input_t * input);
     353             : 
     354             : #endif /* included_format_h */
     355             : 
     356             : /*
     357             :  * fd.io coding-style-patch-verification: ON
     358             :  *
     359             :  * Local Variables:
     360             :  * eval: (c-set-style "gnu")
     361             :  * End:
     362             :  */

Generated by: LCOV version 1.14