FD.io VPP  v16.06
Vector Packet Processing
unformat.c
Go to the documentation of this file.
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 #include <vppinfra/format.h>
39 
40 /* Call user's function to fill input buffer. */
41 uword _unformat_fill_input (unformat_input_t * i)
42 {
43  uword l, first_mark;
44 
45  if (i->index == UNFORMAT_END_OF_INPUT)
46  return i->index;
47 
48  first_mark = l = vec_len (i->buffer);
49  if (vec_len (i->buffer_marks) > 0)
50  first_mark = i->buffer_marks[0];
51 
52  /* Re-use buffer when no marks. */
53  if (first_mark > 0)
54  vec_delete (i->buffer, first_mark, 0);
55 
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;
59 
60  /* Call user's function to fill the buffer. */
61  if (i->fill_buffer)
62  i->index = i->fill_buffer (i);
63 
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;
68 
69  return i->index;
70 }
71 
74 {
75  switch (c)
76  {
77  case ' ': case '\t':
78  case '\n': case '\r':
79  return 1;
80 
81  default:
82  return 0;
83  }
84 }
85 
86 /* Format function for dumping input stream. */
87 u8 * format_unformat_error (u8 * s, va_list * va)
88 {
89  unformat_input_t * i = va_arg (*va, unformat_input_t *);
90  uword l = vec_len (i->buffer);
91 
92  /* Only show so much of the input buffer (it could be really large). */
93  uword n_max = 30;
94 
95  if (i->index < l)
96  {
97  uword n = l - i->index;
98  u8 * p, * p_end;
99 
100  p = i->buffer + i->index;
101  p_end = p + (n > n_max ? n_max : n);
102 
103  /* Skip white space at end. */
104  if (n <= n_max)
105  {
106  while (p_end > p && is_white_space (p_end[-1]))
107  p_end--;
108  }
109 
110  while (p < p_end)
111  {
112  switch (*p)
113  {
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;
118  }
119  p++;
120  }
121 
122  if (n > n_max)
123  vec_add (s, "...", 3);
124  }
125 
126  return s;
127 }
128 
129 /* Print everything: not just error context. */
131  va_list * va)
132 {
133  unformat_input_t * i = va_arg (*va, unformat_input_t *);
134  uword l, n;
135 
136  if (i->index == UNFORMAT_END_OF_INPUT)
137  s = format (s, "{END_OF_INPUT}");
138  else
139  {
140  l = vec_len (i->buffer);
141  n = l - i->index;
142  if (n > 0)
143  vec_add (s, i->buffer + i->index, n);
144  }
145 
146  return s;
147 }
148 
149 #if CLIB_DEBUG > 0
151 { fformat (stderr, "%U\n", format_unformat_input, i); }
152 #endif
153 
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. */
157 static uword
159  uword delimiter_character,
160  uword format_character,
161  va_list * va)
162 {
163  u8 ** string_return = va_arg (*va, u8 **);
164  u8 * s = 0;
165  word paren = 0;
166  word is_paren_delimited = 0;
167  word backslash = 0;
168  uword c;
169 
170  switch (delimiter_character)
171  {
172  case '%':
173  case ' ':
174  case '\t':
175  delimiter_character = 0;
176  break;
177  }
178 
179  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
180  {
181  word add_to_vector;
182 
183  /* Null return string means to skip over delimited input. */
184  add_to_vector = string_return != 0;
185 
186  if (backslash)
187  backslash = 0;
188  else
189  switch (c)
190  {
191  case '\\':
192  backslash = 1;
193  add_to_vector = 0;
194  break;
195 
196  case '{':
197  if (paren == 0 && vec_len (s) == 0)
198  {
199  is_paren_delimited = 1;
200  add_to_vector = 0;
201  }
202  paren++;
203  break;
204 
205  case '}':
206  paren--;
207  if (is_paren_delimited && paren == 0)
208  goto done;
209  break;
210 
211  case ' ':
212  case '\t':
213  case '\n':
214  case '\r':
215  if (! is_paren_delimited)
216  {
217  unformat_put_input (input);
218  goto done;
219  }
220  break;
221 
222  default:
223  if (! is_paren_delimited && c == delimiter_character)
224  {
225  unformat_put_input (input);
226  goto done;
227  }
228  }
229 
230  if (add_to_vector)
231  vec_add1 (s, c);
232  }
233 
234  done:
235  if (string_return)
236  {
237  /* Match the string { END-OF-INPUT as a single brace. */
238  if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0 && paren == 1)
239  vec_add1 (s, '{');
240 
241  /* Don't match null string. */
242  if (c == UNFORMAT_END_OF_INPUT && vec_len (s) == 0)
243  return 0;
244 
245  /* Null terminate C string. */
246  if (format_character == 's')
247  vec_add1 (s, 0);
248 
249  *string_return = s;
250  }
251  else
252  vec_free (s); /* just to make sure */
253 
254  return 1;
255 }
256 
257 uword
259  va_list * va)
260 {
261  u8 ** hexstring_return = va_arg (*va, u8 **);
262  u8 * s;
263  uword n, d, c;
264 
265  n = 0;
266  d = 0;
267  s = 0;
268  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269  {
270  if (c >= '0' && c <= '9')
271  d = 16*d + c - '0';
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';
276  else
277  {
278  unformat_put_input (input);
279  break;
280  }
281  n++;
282 
283  if (n == 2)
284  {
285  vec_add1 (s, d);
286  n = d = 0;
287  }
288  }
289 
290  /* Hex string must have even number of digits. */
291  if (n % 2)
292  {
293  vec_free (s);
294  return 0;
295  }
296 
297  *hexstring_return = s;
298  return 1;
299 }
300 
301 /* unformat (input "foo%U", unformat_eof) matches terminal foo only */
302 uword
303 unformat_eof (unformat_input_t * input, va_list * va)
304 {
306 }
307 
308 /* Parse a token containing given set of characters. */
309 uword
311  va_list * va)
312 {
313  u8 * token_chars = va_arg (*va, u8 *);
314  u8 ** string_return = va_arg (*va, u8 **);
315  u8 * s, map[256];
316  uword i, c;
317 
318  if (! token_chars)
319  token_chars = (u8 *) "a-zA-Z0-9_";
320 
321  memset (map, 0, sizeof (map));
322  for (s = token_chars; *s; )
323  {
324  /* Parse range. */
325  if (s[0] < s[2] && s[1] == '-')
326  {
327  for (i = s[0]; i <= s[2]; i++)
328  map[i] = 1;
329  s = s + 3;
330  }
331  else
332  {
333  map[s[0]] = 1;
334  s = s + 1;
335  }
336  }
337 
338  s = 0;
339  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
340  {
341  if (! map[c])
342  {
343  unformat_put_input (input);
344  break;
345  }
346 
347  vec_add1 (s, c);
348  }
349 
350  if (vec_len (s) == 0)
351  return 0;
352 
353  *string_return = s;
354  return 1;
355 }
356 
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)
360 {
361  unformat_input_t * sub_input = va_arg (*args, unformat_input_t *);
362  u8 * s;
363 
364  if (unformat (i, "%v", &s))
365  {
366  unformat_init_vector (sub_input, s);
367  return 1;
368  }
369 
370  return 0;
371 }
372 
373 /* Parse a line ending with \n and return it. */
375 {
376  u8 * line = 0, ** result = va_arg (*va, u8 **);
377  uword c;
378 
379  while ((c = unformat_get_input (i)) != '\n'
380  && c != UNFORMAT_END_OF_INPUT)
381  {
382  vec_add1 (line, c);
383  }
384 
385  *result = line;
386  return 1;
387 }
388 
389 /* Parse a line ending with \n and return it as an unformat_input_t. */
391 {
392  unformat_input_t * result = va_arg (*va, unformat_input_t *);
393  u8 * line;
394  unformat_user (i, unformat_line, &line);
395  unformat_init_vector (result, line);
396  return 1;
397 }
398 
399 /* Values for is_signed. */
400 #define UNFORMAT_INTEGER_SIGNED 1
401 #define UNFORMAT_INTEGER_UNSIGNED 0
402 
403 static uword
405  va_list * va,
406  uword base,
407  uword is_signed,
408  uword data_bytes)
409 {
410  uword c, digit;
411  uword value = 0;
412  uword n_digits = 0;
413  uword n_input = 0;
414  uword sign = 0;
415 
416  /* We only support bases <= 64. */
417  if (base < 2 || base > 64)
418  goto error;
419 
420  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
421  {
422  switch (c)
423  {
424  case '-':
425  if (n_input == 0)
426  {
427  if (is_signed)
428  {
429  sign = 1;
430  goto next_digit;
431  }
432  else
433  /* Leading sign for unsigned number. */
434  goto error;
435  }
436  /* Sign after input (e.g. 100-200). */
437  goto put_input_done;
438 
439  case '+':
440  if (n_input > 0)
441  goto put_input_done;
442  sign = 0;
443  goto next_digit;
444 
445  case '0' ... '9':
446  digit = c - '0';
447  break;
448 
449  case 'a' ... 'z':
450  digit = 10 + (c - 'a');
451  break;
452 
453  case 'A' ... 'Z':
454  digit = 10 + (base >= 36 ? 26 : 0) + (c - 'A');
455  break;
456 
457  case '/':
458  digit = 62;
459  break;
460 
461  case '?':
462  digit = 63;
463  break;
464 
465  default:
466  goto put_input_done;
467  }
468 
469  if (digit >= base)
470  {
471  put_input_done:
472  unformat_put_input (input);
473  goto done;
474  }
475 
476  {
477  uword new_value = base*value + digit;
478 
479  /* Check for overflow. */
480  if (new_value < value)
481  goto error;
482  value = new_value;
483  }
484  n_digits += 1;
485 
486  next_digit:
487  n_input++;
488  }
489 
490  done:
491  if (sign)
492  value = -value;
493 
494  if (n_digits > 0)
495  {
496  void * v = va_arg (*va, void *);
497 
498  if (data_bytes == ~0)
499  data_bytes = sizeof (int);
500 
501  switch (data_bytes)
502  {
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;
507  default:
508  goto error;
509  }
510 
511  return 1;
512  }
513 
514  error:
515  return 0;
516 }
517 
518 /* Return x 10^n */
519 static f64 times_power_of_ten (f64 x, int n)
520 {
521  if (n >= 0)
522  {
523  static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
524  while (n >= 8)
525  {
526  x *= 1e+8;
527  n -= 8;
528  }
529  return x * t[n];
530  }
531  else
532  {
533  static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
534  while (n <= -8)
535  {
536  x *= 1e-8;
537  n += 8;
538  }
539  return x * t[-n];
540  }
541 
542 }
543 
544 static uword
546  va_list * va)
547 {
548  uword c;
549  u64 values[3];
550  uword n_digits[3], value_index = 0;
551  uword signs[2], sign_index = 0;
552  uword n_input = 0;
553 
554  memset (values, 0, sizeof (values));
555  memset (n_digits, 0, sizeof (n_digits));
556  memset (signs, 0, sizeof (signs));
557 
558  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
559  {
560  switch (c)
561  {
562  case '-':
563  if (value_index == 2 && n_digits[2] == 0)
564  /* sign of exponent: it's ok. */;
565 
566  else if (value_index < 2 && n_digits[0] > 0)
567  {
568  /* 123- */
569  unformat_put_input (input);
570  goto done;
571  }
572 
573  else if (n_input > 0)
574  goto error;
575 
576  signs[sign_index++] = 1;
577  goto next_digit;
578 
579  case '+':
580  if (value_index == 2 && n_digits[2] == 0)
581  /* sign of exponent: it's ok. */;
582 
583  else if (value_index < 2 && n_digits[0] > 0)
584  {
585  /* 123+ */
586  unformat_put_input (input);
587  goto done;
588  }
589 
590  else if (n_input > 0)
591  goto error;
592  signs[sign_index++] = 0;
593  goto next_digit;
594 
595  case 'e':
596  case 'E':
597  if (n_input == 0)
598  goto error;
599  value_index = 2;
600  sign_index = 1;
601  break;
602 
603  case '.':
604  if (value_index > 0)
605  goto error;
606  value_index = 1;
607  break;
608 
609  case '0' ... '9':
610  {
611  u64 tmp;
612 
613  tmp = values[value_index] * 10 + c - '0';
614 
615  /* Check for overflow. */
616  if (tmp < values[value_index])
617  goto error;
618  values[value_index] = tmp;
619  n_digits[value_index] += 1;
620  }
621  break;
622 
623  default:
624  unformat_put_input (input);
625  goto done;
626  }
627 
628  next_digit:
629  n_input++;
630  }
631 
632  done:
633  {
634  f64 f_values[2], * value_return;
635  word expon;
636 
637  /* Must have either whole or fraction digits. */
638  if (n_digits[0] + n_digits[1] <= 0)
639  goto error;
640 
641  f_values[0] = values[0];
642  if (signs[0])
643  f_values[0] = -f_values[0];
644 
645  f_values[1] = values[1];
646  f_values[1] = times_power_of_ten (f_values[1], -n_digits[1]);
647 
648  f_values[0] += f_values[1];
649 
650  expon = values[2];
651  if (signs[1])
652  expon = -expon;
653 
654  f_values[0] = times_power_of_ten (f_values[0], expon);
655 
656  value_return = va_arg (*va, f64 *);
657  *value_return = f_values[0];
658  return 1;
659  }
660 
661  error:
662  return 0;
663 }
664 
665 static char * match_input_with_format (unformat_input_t * input, char * f)
666 {
667  uword cf, ci;
668 
669  ASSERT (*f != 0);
670 
671  while (1)
672  {
673  cf = *f;
674  if (cf == 0 || cf == '%' || cf == ' ')
675  break;
676  f++;
677 
678  ci = unformat_get_input (input);
679 
680  if (cf != ci)
681  return 0;
682  }
683  return f;
684 }
685 
686 static char * do_percent (unformat_input_t * input, va_list * va, char * f)
687 {
688  uword cf, n, data_bytes = ~0;
689 
690  cf = *f++;
691 
692  switch (cf)
693  {
694  default:
695  break;
696 
697  case 'w':
698  /* Word types. */
699  cf = *f++;
700  data_bytes = sizeof (uword);
701  break;
702 
703  case 'l':
704  cf = *f++;
705  if (cf == 'l')
706  {
707  cf = *f++;
708  data_bytes = sizeof (long long);
709  }
710  else
711  {
712  data_bytes = sizeof (long);
713  }
714  break;
715 
716  case 'L':
717  cf = *f++;
718  data_bytes = sizeof (long long);
719  break;
720  }
721 
722  n = 0;
723  switch (cf)
724  {
725  case 'D':
726  data_bytes = va_arg (*va, int);
727  case 'd':
728  n = unformat_integer (input, va, 10,
729  UNFORMAT_INTEGER_SIGNED, data_bytes);
730  break;
731 
732  case 'u':
733  n = unformat_integer (input, va, 10,
734  UNFORMAT_INTEGER_UNSIGNED, data_bytes);
735  break;
736 
737  case 'b':
738  n = unformat_integer (input, va, 2,
739  UNFORMAT_INTEGER_UNSIGNED, data_bytes);
740  break;
741 
742  case 'o':
743  n = unformat_integer (input, va, 8,
744  UNFORMAT_INTEGER_UNSIGNED, data_bytes);
745  break;
746 
747  case 'X':
748  data_bytes = va_arg (*va, int);
749  case 'x':
750  n = unformat_integer (input, va, 16,
751  UNFORMAT_INTEGER_UNSIGNED, data_bytes);
752  break;
753 
754  case 'f':
755  n = unformat_float (input, va);
756  break;
757 
758  case 's':
759  case 'v':
760  n = unformat_string (input, f[0], cf, va);
761  break;
762 
763  case 'U':
764  {
765  unformat_function_t * f = va_arg (*va, unformat_function_t *);
766  n = f (input, va);
767  }
768  break;
769 
770  case '=':
771  case '|':
772  {
773  int * var = va_arg (*va, int *);
774  uword val = va_arg (*va, int);
775 
776  if (cf == '|')
777  val |= *var;
778  *var = val;
779  n = 1;
780  }
781  break;
782  }
783 
784  return n ? f : 0;
785 }
786 
788 {
789  uword n = 0;
790  uword c;
791 
792  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
793  {
794  if (! is_white_space (c))
795  {
796  unformat_put_input (input);
797  break;
798  }
799  n++;
800  }
801  return n;
802 }
803 
804 uword
805 va_unformat (unformat_input_t * input, char * fmt, va_list * va)
806 {
807  char * f;
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;
813 
814  vec_add1_aligned (input->buffer_marks, input->index, sizeof (input->buffer_marks[0]));
815 
816  f = fmt;
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;
821 
822  while (1)
823  {
824  char cf;
825  uword is_percent, skip_input_white_space;
826 
827  cf = *f;
828  is_percent = 0;
829 
830  /* Always skip input white space at start of format string.
831  Otherwise use default skip value which can be changed by %_
832  (see below). */
833  skip_input_white_space = f == fmt || default_skip_input_white_space;
834 
835  /* Spaces in format request skipping input white space. */
836  if (is_white_space (cf))
837  {
838  skip_input_white_space = 1;
839 
840  /* Multiple format spaces are equivalent to a single white
841  space. */
842  while (is_white_space (*++f))
843  ;
844  }
845  else if (cf == '%')
846  {
847  /* %_ toggles whether or not to skip input white space. */
848  switch (*++f)
849  {
850  case '_':
851  default_skip_input_white_space = !default_skip_input_white_space;
852  f++;
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%_"
856  input "1.2 -> 3.4"
857  Without this the space after -> does not get skipped. */
858  if (! default_skip_input_white_space
859  && ! (f == fmt + 2 || *f == 0))
861  continue;
862 
863  /* %% means match % */
864  case '%':
865  break;
866 
867  /* % at end of format string. */
868  case 0:
869  goto parse_fail;
870 
871  default:
872  is_percent = 1;
873  break;
874  }
875  }
876 
877  n_input_white_space_skipped = 0;
878  if (skip_input_white_space)
879  n_input_white_space_skipped = unformat_skip_white_space (input);
880 
881  /* End of format string. */
882  if (cf == 0)
883  {
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)
894  goto parse_fail;
895  break;
896  }
897 
898  last_non_white_space_match_percent = is_percent;
899  last_non_white_space_match_format = 0;
900 
901  /* Explicit spaces in format must match input white space. */
902  if (cf == ' ' && !default_skip_input_white_space)
903  {
904  if (n_input_white_space_skipped == 0)
905  goto parse_fail;
906  }
907 
908  else if (is_percent)
909  {
910  if (! (f = do_percent (input, va, f)))
911  goto parse_fail;
912  }
913 
914  else
915  {
916  char * g = match_input_with_format (input, f);
917  if (! g)
918  goto parse_fail;
919  last_non_white_space_match_format = g > f;
920  f = g;
921  }
922  }
923 
924  input_matches_format = 1;
925  parse_fail:
926 
927  /* Rewind buffer marks. */
928  {
929  uword l = vec_len (input->buffer_marks);
930 
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];
934 
935  _vec_len (input->buffer_marks) = l - 1;
936  }
937 
938  return input_matches_format;
939 }
940 
941 uword
942 unformat (unformat_input_t * input, char * fmt, ...)
943 {
944  va_list va;
945  uword result;
946  va_start (va, fmt);
947  result = va_unformat (input, fmt, &va);
948  va_end (va);
949  return result;
950 }
951 
952 uword
954 {
955  va_list va;
956  uword result, l;
957 
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]));
961 
962  va_start (va, func);
963  result = func (input, &va);
964  va_end (va);
965 
966  if (! result)
967  input->index = input->buffer_marks[l];
968 
969  _vec_len (input->buffer_marks) = l;
970 
971  return result;
972 }
973 
974 /* Setup for unformat of Unix style command line. */
976  char * argv[])
977 {
978  uword i;
979 
980  unformat_init (input, 0, 0);
981 
982  /* Concatenate argument strings with space in between. */
983  for (i = 1; argv[i]; i++)
984  {
985  vec_add (input->buffer, argv[i], strlen (argv[i]));
986  if (argv[i + 1])
987  vec_add1 (input->buffer, ' ');
988  }
989 }
990 
992  char * string,
993  int string_len)
994 {
995  unformat_init (input, 0, 0);
996  if (string_len > 0)
997  vec_add (input->buffer, string, string_len);
998 }
999 
1001  u8 * vector_string)
1002 {
1003  unformat_init (input, 0, 0);
1004  input->buffer = vector_string;
1005 }
1006 
1007 #ifdef CLIB_UNIX
1008 
1010 {
1011  int fd = pointer_to_uword (input->fill_buffer_arg);
1012  uword l, n;
1013 
1014  l = vec_len (input->buffer);
1015  vec_resize (input->buffer, 4096);
1016  n = read (fd, input->buffer + l, 4096);
1017  if (n > 0)
1018  _vec_len (input->buffer) = l + n;
1019 
1020  if (n <= 0)
1021  return UNFORMAT_END_OF_INPUT;
1022  else
1023  return input->index;
1024 }
1025 
1027  int file_descriptor)
1028 {
1030  uword_to_pointer (file_descriptor, void *));
1031 }
1032 
1033 /* Take input from Unix environment variable. */
1035 {
1036  char * val = getenv (var);
1037  if (val)
1038  unformat_init_string (input, val, strlen (val));
1039  return val != 0;
1040 }
1041 
1042 #endif /* CLIB_UNIX */
1043 
void unformat_init_unix_file(unformat_input_t *input, int file_descriptor)
Definition: unformat.c:1026
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword( unformat_function_t)(unformat_input_t *input, va_list *args)
Definition: format.h:229
static char * do_percent(unformat_input_t *input, va_list *va, char *f)
Definition: unformat.c:686
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1000
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
static uword unformat_float(unformat_input_t *input, va_list *va)
Definition: unformat.c:545
static char * match_input_with_format(unformat_input_t *input, char *f)
Definition: unformat.c:665
uword unformat_line(unformat_input_t *i, va_list *va)
Definition: unformat.c:374
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
uword unformat_hex_string(unformat_input_t *input, va_list *va)
Definition: unformat.c:258
uword va_unformat(unformat_input_t *input, char *fmt, va_list *va)
Definition: unformat.c:805
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:557
#define UNFORMAT_INTEGER_UNSIGNED
Definition: unformat.c:401
static uword unformat_integer(unformat_input_t *input, va_list *va, uword base, uword is_signed, uword data_bytes)
Definition: unformat.c:404
#define vec_add1_aligned(V, E, A)
Add 1 element to end of vector (alignment specified).
Definition: vec.h:490
#define always_inline
Definition: clib.h:84
uword unformat_token(unformat_input_t *input, va_list *va)
Definition: unformat.c:310
void di(unformat_input_t *i)
Definition: unformat.c:150
unsigned long u64
Definition: types.h:89
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:199
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:953
static uword pointer_to_uword(const void *p)
Definition: types.h:131
void unformat_init_command_line(unformat_input_t *input, char *argv[])
Definition: unformat.c:975
uword unformat_skip_white_space(unformat_input_t *input)
Definition: unformat.c:787
uword unformat(unformat_input_t *input, char *fmt,...)
Definition: unformat.c:942
#define uword_to_pointer(u, type)
Definition: types.h:134
uword unformat_input(unformat_input_t *i, va_list *args)
Definition: unformat.c:359
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
static f64 times_power_of_ten(f64 x, int n)
Definition: unformat.c:519
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:743
static uword unix_file_fill_buffer(unformat_input_t *input)
Definition: unformat.c:1009
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
always_inline uword unformat_get_input(unformat_input_t *input)
Definition: format.h:190
#define UNFORMAT_INTEGER_SIGNED
Definition: unformat.c:400
always_inline uword is_white_space(uword c)
Definition: unformat.c:73
uword unformat_line_input(unformat_input_t *i, va_list *va)
Definition: unformat.c:390
u64 uword
Definition: types.h:112
unsigned short u16
Definition: types.h:57
always_inline void unformat_init(unformat_input_t *i, uword(*fill_buffer)(unformat_input_t *), void *fill_buffer_arg)
Definition: format.h:150
i64 word
Definition: types.h:111
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:140
u8 * format_unformat_input(u8 *s, va_list *va)
Definition: unformat.c:130
unsigned char u8
Definition: types.h:56
word fformat(FILE *f, char *fmt,...)
Definition: format.c:437
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
uword unformat_init_unix_env(unformat_input_t *input, char *var)
Definition: unformat.c:1034
always_inline void unformat_put_input(unformat_input_t *input)
Definition: format.h:203
struct _unformat_input_t unformat_input_t
uword unformat_eof(unformat_input_t *input, va_list *va)
Definition: unformat.c:303
void unformat_init_string(unformat_input_t *input, char *string, int string_len)
Definition: unformat.c:991
static uword unformat_string(unformat_input_t *input, uword delimiter_character, uword format_character, va_list *va)
Definition: unformat.c:158