FD.io VPP  v16.06
Vector Packet Processing
std-formats.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 /* Format vectors. */
41 u8 * format_vec32 (u8 * s, va_list * va)
42 {
43  u32 * v = va_arg (*va, u32 *);
44  char * fmt = va_arg (*va, char *);
45  uword i;
46  for (i = 0; i < vec_len (v); i++)
47  {
48  if (i > 0)
49  s = format (s, ", ");
50  s = format (s, fmt, v[i]);
51  }
52  return s;
53 }
54 
55 u8 * format_vec_uword (u8 * s, va_list * va)
56 {
57  uword * v = va_arg (*va, uword *);
58  char * fmt = va_arg (*va, char *);
59  uword i;
60  for (i = 0; i < vec_len (v); i++)
61  {
62  if (i > 0)
63  s = format (s, ", ");
64  s = format (s, fmt, v[i]);
65  }
66  return s;
67 }
68 
69 /* Ascii buffer and length. */
70 u8 * format_ascii_bytes (u8 * s, va_list * va)
71 {
72  u8 * v = va_arg (*va, u8 *);
73  uword n_bytes = va_arg (*va, uword);
74  vec_add (s, v, n_bytes);
75  return s;
76 }
77 
78 /* Format hex dump. */
79 u8 * format_hex_bytes (u8 * s, va_list * va)
80 {
81  u8 * bytes = va_arg (*va, u8 *);
82  int n_bytes = va_arg (*va, int);
83  uword i;
84 
85  /* Print short or long form depending on byte count. */
86  uword short_form = n_bytes <= 32;
87  uword indent = format_get_indent (s);
88 
89  if (n_bytes == 0)
90  return s;
91 
92  for (i = 0; i < n_bytes; i++)
93  {
94  if (! short_form && (i % 32) == 0)
95  s = format (s, "%08x: ", i);
96 
97  s = format (s, "%02x", bytes[i]);
98 
99  if (! short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
100  s = format (s, "\n%U", format_white_space, indent);
101  }
102 
103  return s;
104 }
105 
106 /* Add variable number of spaces. */
107 u8 * format_white_space (u8 * s, va_list * va)
108 {
109  uword n = va_arg (*va, uword);
110  while (n-- > 0)
111  vec_add1 (s, ' ');
112  return s;
113 }
114 
115 u8 * format_time_interval (u8 * s, va_list * args)
116 {
117  u8 * fmt = va_arg (*args, u8 *);
118  f64 t = va_arg (*args, f64);
119  u8 * f;
120 
121  const f64 seconds_per_minute = 60;
122  const f64 seconds_per_hour = 60 * seconds_per_minute;
123  const f64 seconds_per_day = 24 * seconds_per_hour;
124  uword days, hours, minutes, secs, msecs, usecs;
125 
126  days = t / seconds_per_day;
127  t -= days * seconds_per_day;
128 
129  hours = t / seconds_per_hour;
130  t -= hours * seconds_per_hour;
131 
132  minutes = t / seconds_per_minute;
133  t -= minutes * seconds_per_minute;
134 
135  secs = t;
136  t -= secs;
137 
138  msecs = 1e3*t;
139  usecs = 1e6*t;
140 
141  for (f = fmt; *f; f++)
142  {
143  uword what, c;
144  char * what_fmt = "%d";
145 
146  switch (c = *f)
147  {
148  default:
149  vec_add1 (s, c);
150  continue;
151 
152  case 'd':
153  what = days;
154  what_fmt = "%d";
155  break;
156  case 'h':
157  what = hours;
158  what_fmt = "%02d";
159  break;
160  case 'm':
161  what = minutes;
162  what_fmt = "%02d";
163  break;
164  case 's':
165  what = secs;
166  what_fmt = "%02d";
167  break;
168  case 'f':
169  what = msecs;
170  what_fmt = "%03d";
171  break;
172  case 'u':
173  what = usecs;
174  what_fmt = "%06d";
175  break;
176  }
177 
178  s = format (s, what_fmt, what);
179  }
180 
181  return s;
182 }
183 
184 /* Unparse memory size e.g. 100, 100k, 100m, 100g. */
185 u8 * format_memory_size (u8 * s, va_list * va)
186 {
187  uword size = va_arg (*va, uword);
188  uword l, u, log_u;
189 
190  l = size > 0 ? min_log2 (size) : 0;
191  if (l < 10)
192  log_u = 0;
193  else if (l < 20)
194  log_u = 10;
195  else if (l < 30)
196  log_u = 20;
197  else
198  log_u = 30;
199 
200  u = (uword) 1 << log_u;
201  if (size & (u - 1))
202  s = format (s, "%.2f", (f64) size / (f64) u);
203  else
204  s = format (s, "%d", size >> log_u);
205 
206  if (log_u != 0)
207  s = format (s, "%c", " kmg"[log_u / 10]);
208 
209  return s;
210 }
211 
212 /* Parse memory size e.g. 100, 100k, 100m, 100g. */
214 {
215  uword amount, shift, c;
216  uword * result = va_arg (*va, uword *);
217 
218  if (! unformat (input, "%wd%_", &amount))
219  return 0;
220 
221  c = unformat_get_input (input);
222  switch (c)
223  {
224  case 'k': case 'K': shift = 10; break;
225  case 'm': case 'M': shift = 20; break;
226  case 'g': case 'G': shift = 30; break;
227  default:
228  shift = 0;
229  unformat_put_input (input);
230  break;
231  }
232 
233  *result = amount << shift;
234  return 1;
235 }
236 
237 /* Format c identifier: e.g. a_name -> "a name".
238  Words for both vector names and null terminated c strings. */
239 u8 * format_c_identifier (u8 * s, va_list * va)
240 {
241  u8 * id = va_arg (*va, u8 *);
242  uword i, l;
243 
244  l = ~0;
245  if (clib_mem_is_vec (id))
246  l = vec_len (id);
247 
248  if (id)
249  for (i = 0; id[i] != 0 && i < l; i++)
250  {
251  u8 c = id[i];
252 
253  if (c == '_')
254  c = ' ';
255  vec_add1 (s, c);
256  }
257 
258  return s;
259 }
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
u8 * format_ascii_bytes(u8 *s, va_list *va)
Definition: std-formats.c:70
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:557
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:107
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:79
always_inline uword clib_mem_is_vec(void *v)
Predicate function, says whether the supplied vector is a clib heap object.
Definition: vec.h:165
u8 * format_memory_size(u8 *s, va_list *va)
Definition: std-formats.c:185
u8 * format_vec32(u8 *s, va_list *va)
Definition: std-formats.c:41
unsigned int u32
Definition: types.h:88
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
always_inline uword unformat_get_input(unformat_input_t *input)
Definition: format.h:190
u32 size
Definition: vhost-user.h:74
u8 * format_c_identifier(u8 *s, va_list *va)
Definition: std-formats.c:239
always_inline uword format_get_indent(u8 *s)
Definition: format.h:72
u64 uword
Definition: types.h:112
u8 * format_vec_uword(u8 *s, va_list *va)
Definition: std-formats.c:55
uword unformat_memory_size(unformat_input_t *input, va_list *va)
Definition: std-formats.c:213
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:140
unsigned char u8
Definition: types.h:56
u8 * format_time_interval(u8 *s, va_list *args)
Definition: std-formats.c:115
always_inline void unformat_put_input(unformat_input_t *input)
Definition: format.h:203
always_inline uword min_log2(uword x)
Definition: clib.h:181
struct _unformat_input_t unformat_input_t