crypto-native: fix build error on Arm using clang-13
[vpp.git] / src / vppinfra / std-formats.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 #include <ctype.h>
40
41 /* Format vectors. */
42 u8 *
43 format_vec32 (u8 * s, va_list * va)
44 {
45   u32 *v = va_arg (*va, u32 *);
46   char *fmt = va_arg (*va, char *);
47   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
57 u8 *
58 format_vec_uword (u8 * s, va_list * va)
59 {
60   uword *v = va_arg (*va, uword *);
61   char *fmt = va_arg (*va, char *);
62   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. */
73 u8 *
74 format_ascii_bytes (u8 * s, va_list * va)
75 {
76   u8 *v = va_arg (*va, u8 *);
77   uword n_bytes = va_arg (*va, uword);
78   vec_add (s, v, n_bytes);
79   return s;
80 }
81
82 /* Format hex dump. */
83 u8 *
84 format_hex_bytes (u8 * s, va_list * va)
85 {
86   u8 *bytes = va_arg (*va, u8 *);
87   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;
92   u32 indent = format_get_indent (s);
93
94   if (n_bytes == 0)
95     return s;
96
97   for (i = 0; i < n_bytes; i++)
98     {
99       if (!short_form && (i % 32) == 0)
100         s = format (s, "%08x: ", i);
101
102       s = format (s, "%02x", bytes[i]);
103
104       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
105         s = format (s, "\n%U", format_white_space, indent);
106     }
107
108   return s;
109 }
110
111 u8 *
112 format_hex_bytes_no_wrap (u8 * s, va_list * va)
113 {
114   u8 *bytes = va_arg (*va, u8 *);
115   int n_bytes = va_arg (*va, int);
116   uword i;
117
118   if (n_bytes == 0)
119     return s;
120
121   for (i = 0; i < n_bytes; i++)
122     s = format (s, "%02x", bytes[i]);
123
124   return s;
125 }
126
127 /* Add variable number of spaces. */
128 u8 *
129 format_white_space (u8 * s, va_list * va)
130 {
131   u32 n = va_arg (*va, u32);
132   while (n-- > 0)
133     vec_add1 (s, ' ');
134   return s;
135 }
136
137 u8 *
138 format_time_interval (u8 * s, va_list * args)
139 {
140   u8 *fmt = va_arg (*args, u8 *);
141   f64 t = va_arg (*args, f64);
142   u8 *f;
143
144   const f64 seconds_per_minute = 60;
145   const f64 seconds_per_hour = 60 * seconds_per_minute;
146   const f64 seconds_per_day = 24 * seconds_per_hour;
147   uword days, hours, minutes, secs, msecs, usecs;
148
149   days = t / seconds_per_day;
150   t -= days * seconds_per_day;
151
152   hours = t / seconds_per_hour;
153   t -= hours * seconds_per_hour;
154
155   minutes = t / seconds_per_minute;
156   t -= minutes * seconds_per_minute;
157
158   secs = t;
159   t -= secs;
160
161   msecs = 1e3 * t;
162   usecs = 1e6 * t;
163
164   for (f = fmt; *f; f++)
165     {
166       uword what, c;
167       char *what_fmt = "%d";
168
169       switch (c = *f)
170         {
171         default:
172           vec_add1 (s, c);
173           continue;
174
175         case 'd':
176           what = days;
177           what_fmt = "%d";
178           break;
179         case 'h':
180           what = hours;
181           what_fmt = "%02d";
182           break;
183         case 'm':
184           what = minutes;
185           what_fmt = "%02d";
186           break;
187         case 's':
188           what = secs;
189           what_fmt = "%02d";
190           break;
191         case 'f':
192           what = msecs;
193           what_fmt = "%03d";
194           break;
195         case 'u':
196           what = usecs;
197           what_fmt = "%06d";
198           break;
199         }
200
201       s = format (s, what_fmt, what);
202     }
203
204   return s;
205 }
206
207 /* Unparse memory size e.g. 100, 100k, 100m, 100g. */
208 __clib_export u8 *
209 format_memory_size (u8 * s, va_list * va)
210 {
211   uword size = va_arg (*va, uword);
212   uword l, u, log_u;
213
214   l = size > 0 ? min_log2 (size) : 0;
215   if (l < 10)
216     log_u = 0;
217   else if (l < 20)
218     log_u = 10;
219   else if (l < 30)
220     log_u = 20;
221   else
222     log_u = 30;
223
224   u = (uword) 1 << log_u;
225   if (size & (u - 1))
226     s = format (s, "%.2f", (f64) size / (f64) u);
227   else
228     s = format (s, "%d", size >> log_u);
229
230   if (log_u != 0)
231     s = format (s, "%c", " kmg"[log_u / 10]);
232
233   return s;
234 }
235
236 /* Parse memory size e.g. 100, 100k, 100m, 100g. */
237 __clib_export uword
238 unformat_memory_size (unformat_input_t * input, va_list * va)
239 {
240   uword amount, shift, c;
241   uword *result = va_arg (*va, uword *);
242
243   if (!unformat (input, "%wd%_", &amount))
244     return 0;
245
246   c = unformat_get_input (input);
247   switch (c)
248     {
249     case 'k':
250     case 'K':
251       shift = 10;
252       break;
253     case 'm':
254     case 'M':
255       shift = 20;
256       break;
257     case 'g':
258     case 'G':
259       shift = 30;
260       break;
261     default:
262       shift = 0;
263       unformat_put_input (input);
264       break;
265     }
266
267   *result = amount << shift;
268   return 1;
269 }
270
271 /* Unparse memory page size e.g. 4K, 2M */
272 __clib_export u8 *
273 format_log2_page_size (u8 * s, va_list * va)
274 {
275   clib_mem_page_sz_t log2_page_sz = va_arg (*va, clib_mem_page_sz_t);
276
277   if (log2_page_sz == CLIB_MEM_PAGE_SZ_UNKNOWN)
278     return format (s, "unknown");
279
280   if (log2_page_sz == CLIB_MEM_PAGE_SZ_DEFAULT)
281     return format (s, "default");
282
283   if (log2_page_sz == CLIB_MEM_PAGE_SZ_DEFAULT_HUGE)
284     return format (s, "default-hugepage");
285
286   if (log2_page_sz >= 30)
287     return format (s, "%uG", 1 << (log2_page_sz - 30));
288
289   if (log2_page_sz >= 20)
290     return format (s, "%uM", 1 << (log2_page_sz - 20));
291
292   if (log2_page_sz >= 10)
293     return format (s, "%uK", 1 << (log2_page_sz - 10));
294
295   return format (s, "%u", 1 << log2_page_sz);
296 }
297
298 /* Parse memory page size e.g. 4K, 2M */
299 __clib_export uword
300 unformat_log2_page_size (unformat_input_t * input, va_list * va)
301 {
302   uword amount;
303   clib_mem_page_sz_t *result = va_arg (*va, clib_mem_page_sz_t *);
304
305   if (unformat (input, "default-hugepage"))
306     *result = CLIB_MEM_PAGE_SZ_DEFAULT_HUGE;
307   else if (unformat (input, "default"))
308     *result = CLIB_MEM_PAGE_SZ_DEFAULT;
309   else if (unformat (input, "%wdk", &amount))
310     *result = min_log2 (amount) + 10;
311   else if (unformat (input, "%wdK", &amount))
312     *result = min_log2 (amount) + 10;
313   else if (unformat (input, "%wdm", &amount))
314     *result = min_log2 (amount) + 20;
315   else if (unformat (input, "%wdM", &amount))
316     *result = min_log2 (amount) + 20;
317   else if (unformat (input, "%wdg", &amount))
318     *result = min_log2 (amount) + 30;
319   else if (unformat (input, "%wdG", &amount))
320     *result = min_log2 (amount) + 30;
321   else
322     return 0;
323   return 1;
324 }
325
326 /* Format c identifier: e.g. a_name -> "a name".
327    Works for both vector names and null terminated c strings. */
328 __clib_export u8 *
329 format_c_identifier (u8 * s, va_list * va)
330 {
331   u8 *id = va_arg (*va, u8 *);
332   uword i, l;
333
334   l = ~0;
335   if (clib_mem_is_vec (id))
336     l = vec_len (id);
337
338   if (id)
339     for (i = 0; i < l && id[i] != 0; i++)
340       {
341         u8 c = id[i];
342
343         if (c == '_')
344           c = ' ';
345         vec_add1 (s, c);
346       }
347
348   return s;
349 }
350
351 __clib_export u8 *
352 format_hexdump (u8 * s, va_list * args)
353 {
354   u8 *data = va_arg (*args, u8 *);
355   uword len = va_arg (*args, uword);
356   int i, index = 0;
357   const int line_len = 16;
358   u8 *line_hex = 0;
359   u8 *line_str = 0;
360   u32 indent = format_get_indent (s);
361
362   if (!len)
363     return s;
364
365   for (i = 0; i < len; i++)
366     {
367       line_hex = format (line_hex, "%02x ", data[i]);
368       line_str = format (line_str, "%c", isprint (data[i]) ? data[i] : '.');
369       if (!((i + 1) % line_len))
370         {
371           s = format (s, "%U%05x: %v[%v]",
372                       format_white_space, index ? indent : 0,
373                       index, line_hex, line_str);
374           if (i < len - 1)
375             s = format (s, "\n");
376           index = i + 1;
377           vec_reset_length (line_hex);
378           vec_reset_length (line_str);
379         }
380     }
381
382   while (i++ % line_len)
383     line_hex = format (line_hex, "   ");
384
385   if (vec_len (line_hex))
386     s = format (s, "%U%05x: %v[%v]",
387                 format_white_space, index ? indent : 0,
388                 index, line_hex, line_str);
389
390   vec_free (line_hex);
391   vec_free (line_str);
392
393   return s;
394 }
395
396 /*
397  * fd.io coding-style-patch-verification: ON
398  *
399  * Local Variables:
400  * eval: (c-set-style "gnu")
401  * End:
402  */