Initial commit of vpp code.
[vpp.git] / vppinfra / vppinfra / test_format.c
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 static int verbose;
41 static u8 * test_vec;
42
43 static u8 * format_test1 (u8 * s, va_list * va)
44 {
45   uword x = va_arg (*va, uword);
46   f64 y = va_arg (*va, f64);
47   return format (s, "%12d %12f%12.4e", x, y, y);
48 }
49
50 static int expectation (const char * exp, char * fmt, ...)
51 {
52   int ret = 0;
53
54   va_list va;
55   va_start (va, fmt);
56   test_vec = va_format (test_vec, fmt, &va);
57   va_end (va);
58
59   vec_add1(test_vec, 0);
60   if (strcmp(exp, (char *) test_vec))
61     {
62       fformat (stdout, "FAIL: %s (expected vs. result)\n\"%s\"\n\"%v\"\n",
63                fmt, exp, test_vec);
64       ret = 1;
65     }
66   else if (verbose)
67     fformat (stdout, "PASS: %s\n", fmt);
68   vec_delete (test_vec, vec_len(test_vec), 0);
69   return ret;
70 }
71
72 int test_format_main (unformat_input_t * input)
73 {
74   int ret = 0;
75   u8 * food = format (0, "food");
76
77   ret |= expectation ("foo", "foo");
78   ret |= expectation ("foo", "%s", "foo");
79   ret |= expectation ("9876", "%d", 9876);
80   ret |= expectation ("-9876", "%wd", (word) -9876);
81   ret |= expectation ("98765432", "%u", 98765432);
82   ret |= expectation ("1200ffee", "%x", 0x1200ffee);
83   ret |= expectation ("BABEBABE", "%X", 0xbabebabe);
84   ret |= expectation ("10%a", "%d%%%c", 10, 'a');
85   ret |= expectation ("123456789abcdef0", "%016Lx", 0x123456789abcdef0LL);
86   ret |= expectation ("00000123", "%08x", 0x123);
87   ret |= expectation ("             23           23    2.3037e1",
88                       "%40U", format_test1, 23, 23.0367);
89   ret |= expectation ("left      ", "%-10s", "left");
90   ret |= expectation ("  center  ", "%=10s", "center");
91   ret |= expectation ("     right", "%+10s", "right");
92   ret |= expectation ("123456", "%.0f", 123456.);
93   ret |= expectation ("1234567.0", "%.1f", 1234567.);
94   ret |= expectation ("foo", "%.*s", 3, "food");
95   ret |= expectation ("food      ", "%.*s", 10, "food          ");
96   ret |= expectation ("(nil)", "%.*s", 3, (void *) 0);
97   ret |= expectation ("foo", "%.*v", 3, food);
98   ret |= expectation ("foobar", "%.*v%s", 3, food, "bar");
99   ret |= expectation ("foo bar", "%S", "foo_bar");
100   vec_free (food);
101   vec_free (test_vec);
102   return ret;
103 }
104
105 typedef struct {
106   int a, b;
107 } foo_t;
108
109 static u8 * format_foo (u8 * s, va_list * va)
110 {
111   foo_t * foo = va_arg (*va, foo_t *);
112   return format (s, "{a %d, b %d}", foo->a, foo->b);
113 }
114
115 static uword unformat_foo (unformat_input_t * i, va_list * va)
116 {
117   foo_t * foo = va_arg (*va, foo_t *);
118   return unformat (i, "{%D,%D}",
119                    sizeof (foo->a), &foo->a,
120                    sizeof (foo->b), &foo->b);
121 }
122
123 int test_unformat_main (unformat_input_t * input)
124 {
125   u32 v[8];
126   long l;
127   long long ll;
128   f64 f;
129   u8 * s;
130   foo_t foo = {.a = ~0, .b = ~0};
131
132   v[0] = v[1] = 0;
133
134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
135     {
136       if (unformat (input, "01 %d %d", &v[0], &v[1]))
137         fformat (stdout, "got 01 %d %d\n", v[0], v[1]);
138       else if (unformat (input, "d %d", &v[0]))
139         fformat (stdout, "got it d %d\n", v[0]);
140       else if (unformat (input, "ld %ld", &l))
141         fformat (stdout, "got it ld %ld\n", l);
142       else if (unformat (input, "lld %lld", &ll))
143         fformat (stdout, "got it lld %lld\n", ll);
144       else if (unformat (input, "string %s", &s))
145         fformat (stdout, "got string `%s'\n", s);
146       else if (unformat (input, "float %f", &f))
147         fformat (stdout, "got float `%.4f'\n", f);
148       else if (unformat (input, "foo %U", unformat_foo, &foo))
149         fformat (stdout, "got a foo `%U'\n", format_foo, &foo);
150       else if (unformat (input, "ignore-me1"))
151         fformat (stdout, "got an `ignore-me1'\n");
152       else if (unformat (input, "ignore-me2"))
153         fformat (stdout, "got an `ignore-me2'\n");
154       else if (unformat (input, "gi%d_%d@-", &v[0], &v[1]))
155         fformat (stdout, "got `gi%d_%d@-'\n", v[0], v[1]);
156       else if (unformat (input, "%_%d.%d.%d.%d%_->%_%d.%d.%d.%d%_",
157                          &v[0], &v[1], &v[2], &v[3],
158                          &v[4], &v[5], &v[6], &v[7]))
159         fformat (stdout, "got %d.%d.%d.%d -> %d.%d.%d.%d",
160                  v[0], v[1], v[2], v[3],
161                  v[4], v[5], v[6], v[7]);
162       else
163         {
164           clib_warning ("unknown input `%U'\n",
165                         format_unformat_error, input);
166           return 1;
167         }
168     }
169
170   return 0;
171 }
172
173 #ifdef CLIB_UNIX
174 int main (int argc, char * argv [])
175 {
176   unformat_input_t i;
177
178   verbose = (argc > 1);
179   unformat_init_command_line (&i, argv);
180
181   if (unformat (&i, "unformat"))
182     return test_unformat_main (&i);
183   else
184     return test_format_main (&i);
185 }
186 #endif