blob: 832dbb557f70b058645d7095d96ec722ab10d400 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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>
Damjan Mariona7e83ce2016-06-09 12:38:22 +020039#include <ctype.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070040
41/* Format vectors. */
Dave Barachc3799992016-08-15 11:12:27 -040042u8 *
43format_vec32 (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070044{
Dave Barachc3799992016-08-15 11:12:27 -040045 u32 *v = va_arg (*va, u32 *);
46 char *fmt = va_arg (*va, char *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070047 uword i;
48 for (i = 0; i < vec_len (v); i++)
49 {
50 if (i > 0)
51 s = format (s, ", ");
52 s = format (s, fmt, v[i]);
53 }
54 return s;
55}
56
Dave Barachc3799992016-08-15 11:12:27 -040057u8 *
58format_vec_uword (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070059{
Dave Barachc3799992016-08-15 11:12:27 -040060 uword *v = va_arg (*va, uword *);
61 char *fmt = va_arg (*va, char *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070062 uword i;
63 for (i = 0; i < vec_len (v); i++)
64 {
65 if (i > 0)
66 s = format (s, ", ");
67 s = format (s, fmt, v[i]);
68 }
69 return s;
70}
71
72/* Ascii buffer and length. */
Dave Barachc3799992016-08-15 11:12:27 -040073u8 *
74format_ascii_bytes (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070075{
Dave Barachc3799992016-08-15 11:12:27 -040076 u8 *v = va_arg (*va, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070077 uword n_bytes = va_arg (*va, uword);
78 vec_add (s, v, n_bytes);
79 return s;
80}
81
82/* Format hex dump. */
Dave Barachc3799992016-08-15 11:12:27 -040083u8 *
84format_hex_bytes (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070085{
Dave Barachc3799992016-08-15 11:12:27 -040086 u8 *bytes = va_arg (*va, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070087 int n_bytes = va_arg (*va, int);
88 uword i;
89
90 /* Print short or long form depending on byte count. */
91 uword short_form = n_bytes <= 32;
Christophe Fontained3c008d2017-10-02 18:10:54 +020092 u32 indent = format_get_indent (s);
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
94 if (n_bytes == 0)
95 return s;
96
97 for (i = 0; i < n_bytes; i++)
98 {
Dave Barachc3799992016-08-15 11:12:27 -040099 if (!short_form && (i % 32) == 0)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700100 s = format (s, "%08x: ", i);
101
102 s = format (s, "%02x", bytes[i]);
103
Dave Barachc3799992016-08-15 11:12:27 -0400104 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700105 s = format (s, "\n%U", format_white_space, indent);
106 }
107
108 return s;
109}
110
111/* Add variable number of spaces. */
Dave Barachc3799992016-08-15 11:12:27 -0400112u8 *
113format_white_space (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700114{
Gabriel Gannee3ea7972017-10-12 10:53:31 +0200115 u32 n = va_arg (*va, u32);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116 while (n-- > 0)
117 vec_add1 (s, ' ');
118 return s;
119}
120
Dave Barachc3799992016-08-15 11:12:27 -0400121u8 *
122format_time_interval (u8 * s, va_list * args)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700123{
Dave Barachc3799992016-08-15 11:12:27 -0400124 u8 *fmt = va_arg (*args, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700125 f64 t = va_arg (*args, f64);
Dave Barachc3799992016-08-15 11:12:27 -0400126 u8 *f;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127
128 const f64 seconds_per_minute = 60;
129 const f64 seconds_per_hour = 60 * seconds_per_minute;
130 const f64 seconds_per_day = 24 * seconds_per_hour;
131 uword days, hours, minutes, secs, msecs, usecs;
Dave Barachc3799992016-08-15 11:12:27 -0400132
Ed Warnickecb9cada2015-12-08 15:45:58 -0700133 days = t / seconds_per_day;
134 t -= days * seconds_per_day;
135
136 hours = t / seconds_per_hour;
137 t -= hours * seconds_per_hour;
138
139 minutes = t / seconds_per_minute;
140 t -= minutes * seconds_per_minute;
141
142 secs = t;
143 t -= secs;
144
Dave Barachc3799992016-08-15 11:12:27 -0400145 msecs = 1e3 * t;
146 usecs = 1e6 * t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700147
148 for (f = fmt; *f; f++)
149 {
150 uword what, c;
Dave Barachc3799992016-08-15 11:12:27 -0400151 char *what_fmt = "%d";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700152
153 switch (c = *f)
154 {
155 default:
156 vec_add1 (s, c);
157 continue;
158
159 case 'd':
160 what = days;
161 what_fmt = "%d";
162 break;
163 case 'h':
164 what = hours;
165 what_fmt = "%02d";
166 break;
167 case 'm':
168 what = minutes;
169 what_fmt = "%02d";
170 break;
171 case 's':
172 what = secs;
173 what_fmt = "%02d";
174 break;
175 case 'f':
176 what = msecs;
177 what_fmt = "%03d";
178 break;
179 case 'u':
180 what = usecs;
181 what_fmt = "%06d";
182 break;
183 }
184
185 s = format (s, what_fmt, what);
186 }
187
188 return s;
189}
190
191/* Unparse memory size e.g. 100, 100k, 100m, 100g. */
Dave Barachc3799992016-08-15 11:12:27 -0400192u8 *
193format_memory_size (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700194{
195 uword size = va_arg (*va, uword);
196 uword l, u, log_u;
197
198 l = size > 0 ? min_log2 (size) : 0;
199 if (l < 10)
200 log_u = 0;
201 else if (l < 20)
202 log_u = 10;
203 else if (l < 30)
204 log_u = 20;
205 else
206 log_u = 30;
207
208 u = (uword) 1 << log_u;
209 if (size & (u - 1))
210 s = format (s, "%.2f", (f64) size / (f64) u);
211 else
212 s = format (s, "%d", size >> log_u);
213
214 if (log_u != 0)
215 s = format (s, "%c", " kmg"[log_u / 10]);
216
217 return s;
218}
219
220/* Parse memory size e.g. 100, 100k, 100m, 100g. */
Dave Barachc3799992016-08-15 11:12:27 -0400221uword
222unformat_memory_size (unformat_input_t * input, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700223{
224 uword amount, shift, c;
Dave Barachc3799992016-08-15 11:12:27 -0400225 uword *result = va_arg (*va, uword *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700226
Dave Barachc3799992016-08-15 11:12:27 -0400227 if (!unformat (input, "%wd%_", &amount))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700228 return 0;
229
230 c = unformat_get_input (input);
231 switch (c)
232 {
Dave Barachc3799992016-08-15 11:12:27 -0400233 case 'k':
234 case 'K':
235 shift = 10;
236 break;
237 case 'm':
238 case 'M':
239 shift = 20;
240 break;
241 case 'g':
242 case 'G':
243 shift = 30;
244 break;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700245 default:
246 shift = 0;
247 unformat_put_input (input);
248 break;
249 }
250
251 *result = amount << shift;
252 return 1;
253}
254
255/* Format c identifier: e.g. a_name -> "a name".
256 Words for both vector names and null terminated c strings. */
Dave Barachc3799992016-08-15 11:12:27 -0400257u8 *
258format_c_identifier (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700259{
Dave Barachc3799992016-08-15 11:12:27 -0400260 u8 *id = va_arg (*va, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700261 uword i, l;
262
263 l = ~0;
264 if (clib_mem_is_vec (id))
265 l = vec_len (id);
266
267 if (id)
268 for (i = 0; id[i] != 0 && i < l; i++)
269 {
270 u8 c = id[i];
271
272 if (c == '_')
273 c = ' ';
274 vec_add1 (s, c);
275 }
276
277 return s;
278}
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200279
280u8 *
281format_hexdump (u8 * s, va_list * args)
282{
Dave Barachc3799992016-08-15 11:12:27 -0400283 u8 *data = va_arg (*args, u8 *);
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200284 uword len = va_arg (*args, uword);
Dave Barachc3799992016-08-15 11:12:27 -0400285 int i, index = 0;
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200286 const int line_len = 16;
Dave Barachc3799992016-08-15 11:12:27 -0400287 u8 *line_hex = 0;
288 u8 *line_str = 0;
Christophe Fontained3c008d2017-10-02 18:10:54 +0200289 u32 indent = format_get_indent (s);
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200290
291 if (!len)
292 return s;
293
Dave Barachc3799992016-08-15 11:12:27 -0400294 for (i = 0; i < len; i++)
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200295 {
Dave Barachc3799992016-08-15 11:12:27 -0400296 line_hex = format (line_hex, "%02x ", data[i]);
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200297 line_str = format (line_str, "%c", isprint (data[i]) ? data[i] : '.');
Dave Barachc3799992016-08-15 11:12:27 -0400298 if (!((i + 1) % line_len))
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200299 {
300 s = format (s, "%U%05x: %v[%v]",
301 format_white_space, index ? indent : 0,
302 index, line_hex, line_str);
303 if (i < len - 1)
304 s = format (s, "\n");
305 index = i + 1;
Dave Barachc3799992016-08-15 11:12:27 -0400306 vec_reset_length (line_hex);
307 vec_reset_length (line_str);
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200308 }
309 }
310
311 while (i++ % line_len)
312 line_hex = format (line_hex, " ");
313
Dave Barachc3799992016-08-15 11:12:27 -0400314 if (vec_len (line_hex))
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200315 s = format (s, "%U%05x: %v[%v]",
Damjan Marion1e336632018-02-17 14:05:08 +0100316 format_white_space, index ? indent : 0,
317 index, line_hex, line_str);
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200318
Dave Barachc3799992016-08-15 11:12:27 -0400319 vec_free (line_hex);
320 vec_free (line_str);
Damjan Mariona7e83ce2016-06-09 12:38:22 +0200321
322 return s;
323}
Dave Barachc3799992016-08-15 11:12:27 -0400324
325/*
326 * fd.io coding-style-patch-verification: ON
327 *
328 * Local Variables:
329 * eval: (c-set-style "gnu")
330 * End:
331 */