dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / vppinfra / 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   uword 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 /* Add variable number of spaces. */
112 u8 *
113 format_white_space (u8 * s, va_list * va)
114 {
115   uword n = va_arg (*va, uword);
116   while (n-- > 0)
117     vec_add1 (s, ' ');
118   return s;
119 }
120
121 u8 *
122 format_time_interval (u8 * s, va_list * args)
123 {
124   u8 *fmt = va_arg (*args, u8 *);
125   f64 t = va_arg (*args, f64);
126   u8 *f;
127
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;
132
133   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
145   msecs = 1e3 * t;
146   usecs = 1e6 * t;
147
148   for (f = fmt; *f; f++)
149     {
150       uword what, c;
151       char *what_fmt = "%d";
152
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. */
192 u8 *
193 format_memory_size (u8 * s, va_list * va)
194 {
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. */
221 uword
222 unformat_memory_size (unformat_input_t * input, va_list * va)
223 {
224   uword amount, shift, c;
225   uword *result = va_arg (*va, uword *);
226
227   if (!unformat (input, "%wd%_", &amount))
228     return 0;
229
230   c = unformat_get_input (input);
231   switch (c)
232     {
233     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;
245     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. */
257 u8 *
258 format_c_identifier (u8 * s, va_list * va)
259 {
260   u8 *id = va_arg (*va, u8 *);
261   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 }
279
280 u8 *
281 format_hexdump (u8 * s, va_list * args)
282 {
283   u8 *data = va_arg (*args, u8 *);
284   uword len = va_arg (*args, uword);
285   int i, index = 0;
286   const int line_len = 16;
287   u8 *line_hex = 0;
288   u8 *line_str = 0;
289   uword indent = format_get_indent (s);
290
291   if (!len)
292     return s;
293
294   for (i = 0; i < len; i++)
295     {
296       line_hex = format (line_hex, "%02x ", data[i]);
297       line_str = format (line_str, "%c", isprint (data[i]) ? data[i] : '.');
298       if (!((i + 1) % line_len))
299         {
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;
306           vec_reset_length (line_hex);
307           vec_reset_length (line_str);
308         }
309     }
310
311   while (i++ % line_len)
312     line_hex = format (line_hex, "   ");
313
314   if (vec_len (line_hex))
315     s = format (s, "%U%05x: %v[%v]",
316                 format_white_space, indent, index, line_hex, line_str);
317
318   vec_free (line_hex);
319   vec_free (line_str);
320
321   return s;
322 }
323
324 /*
325  * fd.io coding-style-patch-verification: ON
326  *
327  * Local Variables:
328  * eval: (c-set-style "gnu")
329  * End:
330  */