1cb9cadadSEd Warnicke/*
2cb9cadadSEd Warnicke * Copyright (c) 2015 Cisco and/or its affiliates.
3cb9cadadSEd Warnicke * Licensed under the Apache License, Version 2.0 (the "License");
4cb9cadadSEd Warnicke * you may not use this file except in compliance with the License.
5cb9cadadSEd Warnicke * You may obtain a copy of the License at:
6cb9cadadSEd Warnicke *
7cb9cadadSEd Warnicke *     http://www.apache.org/licenses/LICENSE-2.0
8cb9cadadSEd Warnicke *
9cb9cadadSEd Warnicke * Unless required by applicable law or agreed to in writing, software
10cb9cadadSEd Warnicke * distributed under the License is distributed on an "AS IS" BASIS,
11cb9cadadSEd Warnicke * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cb9cadadSEd Warnicke * See the License for the specific language governing permissions and
13cb9cadadSEd Warnicke * limitations under the License.
14cb9cadadSEd Warnicke */
15cb9cadadSEd Warnicke/*
16cb9cadadSEd Warnicke  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17cb9cadadSEd Warnicke
18cb9cadadSEd Warnicke  Permission is hereby granted, free of charge, to any person obtaining
19cb9cadadSEd Warnicke  a copy of this software and associated documentation files (the
20cb9cadadSEd Warnicke  "Software"), to deal in the Software without restriction, including
21cb9cadadSEd Warnicke  without limitation the rights to use, copy, modify, merge, publish,
22cb9cadadSEd Warnicke  distribute, sublicense, and/or sell copies of the Software, and to
23cb9cadadSEd Warnicke  permit persons to whom the Software is furnished to do so, subject to
24cb9cadadSEd Warnicke  the following conditions:
25cb9cadadSEd Warnicke
26cb9cadadSEd Warnicke  The above copyright notice and this permission notice shall be
27cb9cadadSEd Warnicke  included in all copies or substantial portions of the Software.
28cb9cadadSEd Warnicke
29cb9cadadSEd Warnicke  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30cb9cadadSEd Warnicke  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31cb9cadadSEd Warnicke  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32cb9cadadSEd Warnicke  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33cb9cadadSEd Warnicke  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34cb9cadadSEd Warnicke  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35cb9cadadSEd Warnicke  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36cb9cadadSEd Warnicke*/
37cb9cadadSEd Warnicke
38cb9cadadSEd Warnicke#ifndef included_format_h
39cb9cadadSEd Warnicke#define included_format_h
40cb9cadadSEd Warnicke
41cb9cadadSEd Warnicke#include <stdarg.h>
42cb9cadadSEd Warnicke
43c3799996SDave Barach#include <vppinfra/clib.h>	/* for CLIB_UNIX, etc. */
44cb9cadadSEd Warnicke#include <vppinfra/vec.h>
45c3799996SDave Barach#include <vppinfra/error.h>	/* for ASSERT */
46cb9cadadSEd Warnicke#include <vppinfra/string.h>
47cb9cadadSEd Warnicke
48c3799996SDave Barachtypedef u8 *(format_function_t) (u8 * s, va_list * args);
49cb9cadadSEd Warnicke
500bfe5d8cSNeale Rannsu8 *va_format (u8 * s, const char *format, va_list * args);
510bfe5d8cSNeale Rannsu8 *format (u8 * s, const char *format, ...);
52cb9cadadSEd Warnicke
53cb9cadadSEd Warnicke#ifdef CLIB_UNIX
54cb9cadadSEd Warnicke
55cb9cadadSEd Warnicke#include <stdio.h>
56cb9cadadSEd Warnicke
57cb9cadadSEd Warnicke#else /* ! CLIB_UNIX */
58cb9cadadSEd Warnicke
59cb9cadadSEd Warnicke/* We're not Unix and have not stdio.h */
60cb9cadadSEd Warnicke#define FILE void
61cb9cadadSEd Warnicke#define stdin ((FILE *) 0)
62cb9cadadSEd Warnicke#define stdout ((FILE *) 1)
63cb9cadadSEd Warnicke#define stderr ((FILE *) 2)
64cb9cadadSEd Warnicke
65cb9cadadSEd Warnicke#endif
66cb9cadadSEd Warnicke
67c3799996SDave Barachword va_fformat (FILE * f, char *fmt, va_list * va);
68c3799996SDave Barachword fformat (FILE * f, char *fmt, ...);
69c3799996SDave Barachword fdformat (int fd, char *fmt, ...);
70cb9cadadSEd Warnicke
71d3c008d1SChristophe Fontainealways_inline u32
72cb9cadadSEd Warnickeformat_get_indent (u8 * s)
73cb9cadadSEd Warnicke{
74d3c008d1SChristophe Fontaine  u32 indent = 0;
75c3799996SDave Barach  u8 *nl;
76cb9cadadSEd Warnicke
77c3799996SDave Barach  if (!s)
78cb9cadadSEd Warnicke    return indent;
79cb9cadadSEd Warnicke
80cb9cadadSEd Warnicke  nl = vec_end (s) - 1;
81cb9cadadSEd Warnicke  while (nl >= s)
82cb9cadadSEd Warnicke    {
83cb9cadadSEd Warnicke      if (*nl-- == '\n')
84cb9cadadSEd Warnicke	break;
85cb9cadadSEd Warnicke      indent++;
86cb9cadadSEd Warnicke    }
87cb9cadadSEd Warnicke  return indent;
88cb9cadadSEd Warnicke}
89cb9cadadSEd Warnicke
90cb9cadadSEd Warnicke#define _(f) u8 * f (u8 * s, va_list * va)
91cb9cadadSEd Warnicke
92cb9cadadSEd Warnicke/* Standard user-defined formats. */
93c3799996SDave Barach_(format_vec32);
94c3799996SDave Barach_(format_vec_uword);
95c3799996SDave Barach_(format_ascii_bytes);
96c3799996SDave Barach_(format_hex_bytes);
973860a77eSDamjan Marion_(format_hex_bytes_no_wrap);
98c3799996SDave Barach_(format_white_space);
99c3799996SDave Barach_(format_f64);
100c3799996SDave Barach_(format_time_interval);
101cb9cadadSEd Warnicke
102cb9cadadSEd Warnicke#ifdef CLIB_UNIX
103cb9cadadSEd Warnicke/* Unix specific formats. */
104c3799996SDave Barach_(format_address_family);
105c3799996SDave Barach_(format_unix_arphrd);
106c3799996SDave Barach_(format_unix_interface_flags);
107c3799996SDave Barach_(format_network_address);
108c3799996SDave Barach_(format_network_protocol);
109c3799996SDave Barach_(format_network_port);
110c3799996SDave Barach_(format_sockaddr);
111c3799996SDave Barach_(format_ip4_tos_byte);
112c3799996SDave Barach_(format_ip4_packet);
113c3799996SDave Barach_(format_icmp4_type_and_code);
114c3799996SDave Barach_(format_ethernet_packet);
115c3799996SDave Barach_(format_hostname);
116c3799996SDave Barach_(format_timeval);
117c3799996SDave Barach_(format_time_float);
118c3799996SDave Barach_(format_signal);
119c3799996SDave Barach_(format_ucontext_pc);
120926b564dSDamjan Marion_(format_page_map);
121cb9cadadSEd Warnicke#endif
122cb9cadadSEd Warnicke
123cb9cadadSEd Warnicke#undef _
124cb9cadadSEd Warnicke
125cb9cadadSEd Warnicke/* Unformat. */
126cb9cadadSEd Warnicke
127c3799996SDave Barachtypedef struct _unformat_input_t
128c3799996SDave Barach{
129cb9cadadSEd Warnicke  /* Input buffer (vector). */
130c3799996SDave Barach  u8 *buffer;
131cb9cadadSEd Warnicke
132cb9cadadSEd Warnicke  /* Current index in input buffer. */
133cb9cadadSEd Warnicke  uword index;
134cb9cadadSEd Warnicke
135cb9cadadSEd Warnicke  /* Vector of buffer marks.  Used to delineate pieces of the buffer
136cb9cadadSEd Warnicke     for error reporting and for parse recovery. */
137c3799996SDave Barach  uword *buffer_marks;
138cb9cadadSEd Warnicke
139cb9cadadSEd Warnicke  /* User's function to fill the buffer when its empty
140cb9cadadSEd Warnicke     (and argument). */
141c3799996SDave Barach    uword (*fill_buffer) (struct _unformat_input_t * i);
142cb9cadadSEd Warnicke
143cb9cadadSEd Warnicke  /* Return values for fill buffer function which indicate whether not
144cb9cadadSEd Warnicke     input has been exhausted. */
145cb9cadadSEd Warnicke#define UNFORMAT_END_OF_INPUT (~0)
146cb9cadadSEd Warnicke#define UNFORMAT_MORE_INPUT   0
147cb9cadadSEd Warnicke
148cb9cadadSEd Warnicke  /* User controlled argument to fill buffer function. */
149c3799996SDave Barach  void *fill_buffer_arg;
150cb9cadadSEd Warnicke} unformat_input_t;
151cb9cadadSEd Warnicke
152cb9cadadSEd Warnickealways_inline void
153cb9cadadSEd Warnickeunformat_init (unformat_input_t * i,
154c3799996SDave Barach	       uword (*fill_buffer) (unformat_input_t *),
155c3799996SDave Barach	       void *fill_buffer_arg)
156cb9cadadSEd Warnicke{
157b7b92993SDave Barach  clib_memset (i, 0, sizeof (i[0]));
158cb9cadadSEd Warnicke  i->fill_buffer = fill_buffer;
159cb9cadadSEd Warnicke  i->fill_buffer_arg = fill_buffer_arg;
160cb9cadadSEd Warnicke}
161cb9cadadSEd Warnicke
162cb9cadadSEd Warnickealways_inline void
163cb9cadadSEd Warnickeunformat_free (unformat_input_t * i)
164cb9cadadSEd Warnicke{
165cb9cadadSEd Warnicke  vec_free (i->buffer);
166cb9cadadSEd Warnicke  vec_free (i->buffer_marks);
167b7b92993SDave Barach  clib_memset (i, 0, sizeof (i[0]));
168cb9cadadSEd Warnicke}
169cb9cadadSEd Warnicke
170cb9cadadSEd Warnickealways_inline uword
171cb9cadadSEd Warnickeunformat_check_input (unformat_input_t * i)
172cb9cadadSEd Warnicke{
173cb9cadadSEd Warnicke  /* Low level fill input function. */
174cb9cadadSEd Warnicke  extern uword _unformat_fill_input (unformat_input_t * i);
175cb9cadadSEd Warnicke
176c3799996SDave Barach  if (i->index >= vec_len (i->buffer) && i->index != UNFORMAT_END_OF_INPUT)
177cb9cadadSEd Warnicke    _unformat_fill_input (i);
178cb9cadadSEd Warnicke
179cb9cadadSEd Warnicke  return i->index;
180cb9cadadSEd Warnicke}
181cb9cadadSEd Warnicke
182cb9cadadSEd Warnicke/* Return true if input is exhausted */
183cb9cadadSEd Warnickealways_inline uword
184cb9cadadSEd Warnickeunformat_is_eof (unformat_input_t * input)
185cb9cadadSEd Warnicke{
186cb9cadadSEd Warnicke  return unformat_check_input (input) == UNFORMAT_END_OF_INPUT;
187cb9cadadSEd Warnicke}
188cb9cadadSEd Warnicke
189cb9cadadSEd Warnicke/* Return next element in input vector,
190cb9cadadSEd Warnicke   possibly calling fill input to get more. */
191cb9cadadSEd Warnickealways_inline uword
192cb9cadadSEd Warnickeunformat_get_input (unformat_input_t * input)
193cb9cadadSEd Warnicke{
194cb9cadadSEd Warnicke  uword i = unformat_check_input (input);
195cb9cadadSEd Warnicke  if (i < vec_len (input->buffer))
196cb9cadadSEd Warnicke    {
197cb9cadadSEd Warnicke      input->index = i + 1;
198cb9cadadSEd Warnicke      i = input->buffer[i];
199cb9cadadSEd Warnicke    }
200cb9cadadSEd Warnicke  return i;
201cb9cadadSEd Warnicke}
202cb9cadadSEd Warnicke
203cb9cadadSEd Warnicke/* Back up input pointer by one. */
204cb9cadadSEd Warnickealways_inline void
205cb9cadadSEd Warnickeunformat_put_input (unformat_input_t * input)
206c3799996SDave Barach{
207c3799996SDave Barach  input->index -= 1;
208c3799996SDave Barach}
209cb9cadadSEd Warnicke
210cb9cadadSEd Warnicke/* Peek current input character without advancing. */
211cb9cadadSEd Warnickealways_inline uword
212cb9cadadSEd Warnickeunformat_peek_input (unformat_input_t * input)
213cb9cadadSEd Warnicke{
214cb9cadadSEd Warnicke  uword c = unformat_get_input (input);
215cb9cadadSEd Warnicke  if (c != UNFORMAT_END_OF_INPUT)
216cb9cadadSEd Warnicke    unformat_put_input (input);
217cb9cadadSEd Warnicke  return c;
218cb9cadadSEd Warnicke}
219cb9cadadSEd Warnicke
220cb9cadadSEd Warnicke/* Skip current input line. */
221c3799996SDave Barachalways_inline void
222c3799996SDave Barachunformat_skip_line (unformat_input_t * i)
223cb9cadadSEd Warnicke{
224cb9cadadSEd Warnicke  uword c;
225cb9cadadSEd Warnicke
226c3799996SDave Barach  while ((c = unformat_get_input (i)) != UNFORMAT_END_OF_INPUT && c != '\n')
227cb9cadadSEd Warnicke    ;
228cb9cadadSEd Warnicke}
229cb9cadadSEd Warnicke
230cb9cadadSEd Warnickeuword unformat_skip_white_space (unformat_input_t * input);
231cb9cadadSEd Warnicke
232cb9cadadSEd Warnicke/* Unformat function. */
233c3799996SDave Barachtypedef uword (unformat_function_t) (unformat_input_t * input,
234c3799996SDave Barach				     va_list * args);
235cb9cadadSEd Warnicke
236cb9cadadSEd Warnicke/* External functions. */
237cb9cadadSEd Warnicke
238cb9cadadSEd Warnicke/* General unformatting function with programmable input stream. */
23932e1c010SNeale Rannsuword unformat (unformat_input_t * i, const char *fmt, ...);
240cb9cadadSEd Warnicke
241cb9cadadSEd Warnicke/* Call user defined parse function.
242cb9cadadSEd Warnicke   unformat_user (i, f, ...) is equivalent to unformat (i, "%U", f, ...) */
243c3799996SDave Barachuword unformat_user (unformat_input_t * input, unformat_function_t * func,
244c3799996SDave Barach		     ...);
245cb9cadadSEd Warnicke
246cb9cadadSEd Warnicke/* Alternate version which allows for extensions. */
24732e1c010SNeale Rannsuword va_unformat (unformat_input_t * i, const char *fmt, va_list * args);
248cb9cadadSEd Warnicke
249cb9cadadSEd Warnicke/* Setup for unformat of Unix style command line. */
250c3799996SDave Barachvoid unformat_init_command_line (unformat_input_t * input, char *argv[]);
251cb9cadadSEd Warnicke
252cb9cadadSEd Warnicke/* Setup for unformat of given string. */
253cb9cadadSEd Warnickevoid unformat_init_string (unformat_input_t * input,
254c3799996SDave Barach			   char *string, int string_len);
255cb9cadadSEd Warnicke
256cb9cadadSEd Warnickealways_inline void
257c3799996SDave Barachunformat_init_cstring (unformat_input_t * input, char *string)
258c3799996SDave Barach{
259c3799996SDave Barach  unformat_init_string (input, string, strlen (string));
260c3799996SDave Barach}
261cb9cadadSEd Warnicke
262cb9cadadSEd Warnicke/* Setup for unformat of given vector string; vector will be freed by unformat_string. */
263c3799996SDave Barachvoid unformat_init_vector (unformat_input_t * input, u8 * vector_string);
264cb9cadadSEd Warnicke
265cb9cadadSEd Warnicke/* Format function for unformat input usable when an unformat error
266cb9cadadSEd Warnicke   has occurred. */
267c3799996SDave Barachu8 *format_unformat_error (u8 * s, va_list * va);
268cb9cadadSEd Warnicke
269cb9cadadSEd Warnicke#define unformat_parse_error(input)						\
270cb9cadadSEd Warnicke  clib_error_return (0, "parse error `%U'", format_unformat_error, input)
271cb9cadadSEd Warnicke
272cb9cadadSEd Warnicke/* Print all input: not just error context. */
273c3799996SDave Barachu8 *format_unformat_input (u8 * s, va_list * va);
274cb9cadadSEd Warnicke
275cb9cadadSEd Warnicke/* Unformat (parse) function which reads a %s string and converts it
276cb9cadadSEd Warnicke   to and unformat_input_t. */
277cb9cadadSEd Warnickeunformat_function_t unformat_input;
278cb9cadadSEd Warnicke
279cb9cadadSEd Warnicke/* Parse a line ending with \n and return it. */
280cb9cadadSEd Warnickeunformat_function_t unformat_line;
281cb9cadadSEd Warnicke
282cb9cadadSEd Warnicke/* Parse a line ending with \n and return it as an unformat_input_t. */
283cb9cadadSEd Warnickeunformat_function_t unformat_line_input;
284cb9cadadSEd Warnicke
285cb9cadadSEd Warnicke/* Parse a token containing given set of characters. */
286cb9cadadSEd Warnickeunformat_function_t unformat_token;
287cb9cadadSEd Warnicke
288cb9cadadSEd Warnicke/* Parses a hexstring into a vector of bytes. */
289cb9cadadSEd Warnickeunformat_function_t unformat_hex_string;
290cb9cadadSEd Warnicke
291cb9cadadSEd Warnicke/* Returns non-zero match if input is exhausted.
292cb9cadadSEd Warnicke   Useful to ensure that the entire input matches with no trailing junk. */
293cb9cadadSEd Warnickeunformat_function_t unformat_eof;
294cb9cadadSEd Warnicke
295cb9cadadSEd Warnicke/* Parse memory size e.g. 100, 100k, 100m, 100g. */
296cb9cadadSEd Warnickeunformat_function_t unformat_memory_size;
297cb9cadadSEd Warnicke
298cb9cadadSEd Warnicke/* Unparse memory size e.g. 100, 100k, 100m, 100g. */
299c3799996SDave Barachu8 *format_memory_size (u8 * s, va_list * va);
300cb9cadadSEd Warnicke
301cb9cadadSEd Warnicke/* Format c identifier: e.g. a_name -> "a name". */
302c3799996SDave Barachu8 *format_c_identifier (u8 * s, va_list * va);
303cb9cadadSEd Warnicke
304a7e83ceeSDamjan Marion/* Format hexdump with both hex and printable chars - compatible with text2pcap */
305c3799996SDave Barachu8 *format_hexdump (u8 * s, va_list * va);
306a7e83ceeSDamjan Marion
307cb9cadadSEd Warnicke/* Unix specific formats. */
308cb9cadadSEd Warnicke#ifdef CLIB_UNIX
309cb9cadadSEd Warnicke/* Setup input from Unix file. */
31059b2565cSDave Barachvoid unformat_init_clib_file (unformat_input_t * input, int file_descriptor);
311cb9cadadSEd Warnicke
312cb9cadadSEd Warnicke/* Take input from Unix environment variable; returns
313cb9cadadSEd Warnicke   1 if variable exists zero otherwise. */
314c3799996SDave Barachuword unformat_init_unix_env (unformat_input_t * input, char *var);
315a54230d4SDamjan Marion
316a54230d4SDamjan Marion/* Unformat unix group id (gid) specified as integer or string */
317a54230d4SDamjan Marionunformat_function_t unformat_unix_gid;
318cb9cadadSEd Warnicke#endif /* CLIB_UNIX */
319cb9cadadSEd Warnicke
320579b1650SMathiasRaouluword unformat_data_size (unformat_input_t * input, va_list * args);
321579b1650SMathiasRaoul
322cb9cadadSEd Warnicke/* Test code. */
323cb9cadadSEd Warnickeint test_format_main (unformat_input_t * input);
324cb9cadadSEd Warnickeint test_unformat_main (unformat_input_t * input);
325cb9cadadSEd Warnicke
326c3799996SDave Barach/* This is not the right place for this, but putting it in vec.h
327cb9cadadSEd Warnickecreated circular dependency problems. */
328cb9cadadSEd Warnickeint test_vec_main (unformat_input_t * input);
329cb9cadadSEd Warnicke
330cb9cadadSEd Warnicke#endif /* included_format_h */
331c3799996SDave Barach
332c3799996SDave Barach/*
333c3799996SDave Barach * fd.io coding-style-patch-verification: ON
334c3799996SDave Barach *
335c3799996SDave Barach * Local Variables:
336c3799996SDave Barach * eval: (c-set-style "gnu")
337c3799996SDave Barach * End:
338c3799996SDave Barach */
339