Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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> |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 39 | #include <ctype.h> |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 40 | |
| 41 | /* Format vectors. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 42 | u8 * |
| 43 | format_vec32 (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 44 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 45 | u32 *v = va_arg (*va, u32 *); |
| 46 | char *fmt = va_arg (*va, char *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 57 | u8 * |
| 58 | format_vec_uword (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 59 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 60 | uword *v = va_arg (*va, uword *); |
| 61 | char *fmt = va_arg (*va, char *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 73 | u8 * |
| 74 | format_ascii_bytes (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 75 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 76 | u8 *v = va_arg (*va, u8 *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 77 | uword n_bytes = va_arg (*va, uword); |
| 78 | vec_add (s, v, n_bytes); |
| 79 | return s; |
| 80 | } |
| 81 | |
| 82 | /* Format hex dump. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 83 | u8 * |
| 84 | format_hex_bytes (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 85 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 86 | u8 *bytes = va_arg (*va, u8 *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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; |
Christophe Fontaine | d3c008d | 2017-10-02 18:10:54 +0200 | [diff] [blame] | 92 | u32 indent = format_get_indent (s); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 93 | |
| 94 | if (n_bytes == 0) |
| 95 | return s; |
| 96 | |
| 97 | for (i = 0; i < n_bytes; i++) |
| 98 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 99 | if (!short_form && (i % 32) == 0) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 100 | s = format (s, "%08x: ", i); |
| 101 | |
| 102 | s = format (s, "%02x", bytes[i]); |
| 103 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 104 | if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 105 | s = format (s, "\n%U", format_white_space, indent); |
| 106 | } |
| 107 | |
| 108 | return s; |
| 109 | } |
| 110 | |
Damjan Marion | 3860a77 | 2019-06-17 23:20:27 +0200 | [diff] [blame] | 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 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 127 | /* Add variable number of spaces. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 128 | u8 * |
| 129 | format_white_space (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 130 | { |
Gabriel Ganne | e3ea797 | 2017-10-12 10:53:31 +0200 | [diff] [blame] | 131 | u32 n = va_arg (*va, u32); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 132 | while (n-- > 0) |
| 133 | vec_add1 (s, ' '); |
| 134 | return s; |
| 135 | } |
| 136 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 137 | u8 * |
Nathan Skrzypczak | 6de58f5 | 2022-01-24 17:10:41 +0100 | [diff] [blame^] | 138 | format_duration (u8 *s, va_list *args) |
| 139 | { |
| 140 | f64 t = va_arg (*args, f64); |
| 141 | s = format (s, ""); |
| 142 | |
| 143 | const f64 seconds_per_minute = 60; |
| 144 | const f64 seconds_per_hour = 60 * seconds_per_minute; |
| 145 | const f64 seconds_per_day = 24 * seconds_per_hour; |
| 146 | uword days, hours, minutes, secs, msecs, usecs; |
| 147 | |
| 148 | days = t / seconds_per_day; |
| 149 | t -= days * seconds_per_day; |
| 150 | |
| 151 | hours = t / seconds_per_hour; |
| 152 | t -= hours * seconds_per_hour; |
| 153 | |
| 154 | minutes = t / seconds_per_minute; |
| 155 | t -= minutes * seconds_per_minute; |
| 156 | |
| 157 | secs = t; |
| 158 | t -= secs; |
| 159 | |
| 160 | msecs = 1e3 * t; |
| 161 | |
| 162 | usecs = 1e6 * t; |
| 163 | usecs = usecs % 1000; |
| 164 | |
| 165 | if (t == 0.) |
| 166 | s = format (s, "0"); |
| 167 | if (days) |
| 168 | s = format (s, "%ddays ", days); |
| 169 | if (hours) |
| 170 | s = format (s, "%dh ", hours); |
| 171 | if (minutes) |
| 172 | s = format (s, "%dmin ", minutes); |
| 173 | if (secs) |
| 174 | s = format (s, "%ds ", secs); |
| 175 | if (msecs) |
| 176 | s = format (s, "%dms ", msecs); |
| 177 | if (usecs) |
| 178 | s = format (s, "%dus", usecs); |
| 179 | |
| 180 | return (s); |
| 181 | } |
| 182 | |
| 183 | u8 * |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 184 | format_time_interval (u8 * s, va_list * args) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 185 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 186 | u8 *fmt = va_arg (*args, u8 *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 187 | f64 t = va_arg (*args, f64); |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 188 | u8 *f; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 189 | |
| 190 | const f64 seconds_per_minute = 60; |
| 191 | const f64 seconds_per_hour = 60 * seconds_per_minute; |
| 192 | const f64 seconds_per_day = 24 * seconds_per_hour; |
| 193 | uword days, hours, minutes, secs, msecs, usecs; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 194 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 195 | days = t / seconds_per_day; |
| 196 | t -= days * seconds_per_day; |
| 197 | |
| 198 | hours = t / seconds_per_hour; |
| 199 | t -= hours * seconds_per_hour; |
| 200 | |
| 201 | minutes = t / seconds_per_minute; |
| 202 | t -= minutes * seconds_per_minute; |
| 203 | |
| 204 | secs = t; |
| 205 | t -= secs; |
| 206 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 207 | msecs = 1e3 * t; |
| 208 | usecs = 1e6 * t; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 209 | |
| 210 | for (f = fmt; *f; f++) |
| 211 | { |
| 212 | uword what, c; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 213 | char *what_fmt = "%d"; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 214 | |
| 215 | switch (c = *f) |
| 216 | { |
| 217 | default: |
| 218 | vec_add1 (s, c); |
| 219 | continue; |
| 220 | |
| 221 | case 'd': |
| 222 | what = days; |
| 223 | what_fmt = "%d"; |
| 224 | break; |
| 225 | case 'h': |
| 226 | what = hours; |
| 227 | what_fmt = "%02d"; |
| 228 | break; |
| 229 | case 'm': |
| 230 | what = minutes; |
| 231 | what_fmt = "%02d"; |
| 232 | break; |
| 233 | case 's': |
| 234 | what = secs; |
| 235 | what_fmt = "%02d"; |
| 236 | break; |
| 237 | case 'f': |
| 238 | what = msecs; |
| 239 | what_fmt = "%03d"; |
| 240 | break; |
| 241 | case 'u': |
| 242 | what = usecs; |
| 243 | what_fmt = "%06d"; |
| 244 | break; |
| 245 | } |
| 246 | |
| 247 | s = format (s, what_fmt, what); |
| 248 | } |
| 249 | |
| 250 | return s; |
| 251 | } |
| 252 | |
Nathan Skrzypczak | 162ff5e | 2021-11-09 18:18:21 +0100 | [diff] [blame] | 253 | /* Format base 10 e.g. 100, 100K, 100M, 100G */ |
| 254 | __clib_export u8 * |
| 255 | format_base10 (u8 *s, va_list *va) |
| 256 | { |
| 257 | uword size = va_arg (*va, uword); |
| 258 | |
| 259 | if (size < 1000) |
| 260 | s = format (s, "%d", size); |
| 261 | else if (size < 1000000) |
| 262 | s = format (s, "%.2fK", (f64) size / 1000.); |
| 263 | else if (size < 1000000000) |
| 264 | s = format (s, "%.2fM", (f64) size / 1000000.); |
| 265 | else |
| 266 | s = format (s, "%.2fG", (f64) size / 1000000000.); |
| 267 | |
| 268 | return s; |
| 269 | } |
| 270 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 271 | /* Unparse memory size e.g. 100, 100k, 100m, 100g. */ |
Damjan Marion | dae1c7e | 2020-10-17 13:32:25 +0200 | [diff] [blame] | 272 | __clib_export u8 * |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 273 | format_memory_size (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 274 | { |
| 275 | uword size = va_arg (*va, uword); |
| 276 | uword l, u, log_u; |
| 277 | |
| 278 | l = size > 0 ? min_log2 (size) : 0; |
| 279 | if (l < 10) |
| 280 | log_u = 0; |
| 281 | else if (l < 20) |
| 282 | log_u = 10; |
| 283 | else if (l < 30) |
| 284 | log_u = 20; |
| 285 | else |
| 286 | log_u = 30; |
| 287 | |
| 288 | u = (uword) 1 << log_u; |
| 289 | if (size & (u - 1)) |
| 290 | s = format (s, "%.2f", (f64) size / (f64) u); |
| 291 | else |
| 292 | s = format (s, "%d", size >> log_u); |
| 293 | |
| 294 | if (log_u != 0) |
| 295 | s = format (s, "%c", " kmg"[log_u / 10]); |
| 296 | |
| 297 | return s; |
| 298 | } |
| 299 | |
| 300 | /* Parse memory size e.g. 100, 100k, 100m, 100g. */ |
Damjan Marion | dae1c7e | 2020-10-17 13:32:25 +0200 | [diff] [blame] | 301 | __clib_export uword |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 302 | unformat_memory_size (unformat_input_t * input, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 303 | { |
| 304 | uword amount, shift, c; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 305 | uword *result = va_arg (*va, uword *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 306 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 307 | if (!unformat (input, "%wd%_", &amount)) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 308 | return 0; |
| 309 | |
| 310 | c = unformat_get_input (input); |
| 311 | switch (c) |
| 312 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 313 | case 'k': |
| 314 | case 'K': |
| 315 | shift = 10; |
| 316 | break; |
| 317 | case 'm': |
| 318 | case 'M': |
| 319 | shift = 20; |
| 320 | break; |
| 321 | case 'g': |
| 322 | case 'G': |
| 323 | shift = 30; |
| 324 | break; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 325 | default: |
| 326 | shift = 0; |
| 327 | unformat_put_input (input); |
| 328 | break; |
| 329 | } |
| 330 | |
| 331 | *result = amount << shift; |
| 332 | return 1; |
| 333 | } |
| 334 | |
Damjan Marion | b509504 | 2020-09-11 22:13:46 +0200 | [diff] [blame] | 335 | /* Unparse memory page size e.g. 4K, 2M */ |
Damjan Marion | dae1c7e | 2020-10-17 13:32:25 +0200 | [diff] [blame] | 336 | __clib_export u8 * |
Damjan Marion | b509504 | 2020-09-11 22:13:46 +0200 | [diff] [blame] | 337 | format_log2_page_size (u8 * s, va_list * va) |
| 338 | { |
| 339 | clib_mem_page_sz_t log2_page_sz = va_arg (*va, clib_mem_page_sz_t); |
| 340 | |
| 341 | if (log2_page_sz == CLIB_MEM_PAGE_SZ_UNKNOWN) |
| 342 | return format (s, "unknown"); |
| 343 | |
| 344 | if (log2_page_sz == CLIB_MEM_PAGE_SZ_DEFAULT) |
| 345 | return format (s, "default"); |
| 346 | |
| 347 | if (log2_page_sz == CLIB_MEM_PAGE_SZ_DEFAULT_HUGE) |
| 348 | return format (s, "default-hugepage"); |
| 349 | |
| 350 | if (log2_page_sz >= 30) |
| 351 | return format (s, "%uG", 1 << (log2_page_sz - 30)); |
| 352 | |
| 353 | if (log2_page_sz >= 20) |
| 354 | return format (s, "%uM", 1 << (log2_page_sz - 20)); |
| 355 | |
| 356 | if (log2_page_sz >= 10) |
| 357 | return format (s, "%uK", 1 << (log2_page_sz - 10)); |
| 358 | |
| 359 | return format (s, "%u", 1 << log2_page_sz); |
| 360 | } |
| 361 | |
| 362 | /* Parse memory page size e.g. 4K, 2M */ |
Damjan Marion | dae1c7e | 2020-10-17 13:32:25 +0200 | [diff] [blame] | 363 | __clib_export uword |
Damjan Marion | b509504 | 2020-09-11 22:13:46 +0200 | [diff] [blame] | 364 | unformat_log2_page_size (unformat_input_t * input, va_list * va) |
| 365 | { |
Nathan Skrzypczak | 6155902 | 2020-11-23 16:25:21 +0100 | [diff] [blame] | 366 | uword amount; |
Damjan Marion | b509504 | 2020-09-11 22:13:46 +0200 | [diff] [blame] | 367 | clib_mem_page_sz_t *result = va_arg (*va, clib_mem_page_sz_t *); |
| 368 | |
Damjan Marion | b509504 | 2020-09-11 22:13:46 +0200 | [diff] [blame] | 369 | if (unformat (input, "default-hugepage")) |
Nathan Skrzypczak | 6155902 | 2020-11-23 16:25:21 +0100 | [diff] [blame] | 370 | *result = CLIB_MEM_PAGE_SZ_DEFAULT_HUGE; |
| 371 | else if (unformat (input, "default")) |
| 372 | *result = CLIB_MEM_PAGE_SZ_DEFAULT; |
| 373 | else if (unformat (input, "%wdk", &amount)) |
| 374 | *result = min_log2 (amount) + 10; |
| 375 | else if (unformat (input, "%wdK", &amount)) |
| 376 | *result = min_log2 (amount) + 10; |
| 377 | else if (unformat (input, "%wdm", &amount)) |
| 378 | *result = min_log2 (amount) + 20; |
| 379 | else if (unformat (input, "%wdM", &amount)) |
| 380 | *result = min_log2 (amount) + 20; |
| 381 | else if (unformat (input, "%wdg", &amount)) |
| 382 | *result = min_log2 (amount) + 30; |
| 383 | else if (unformat (input, "%wdG", &amount)) |
| 384 | *result = min_log2 (amount) + 30; |
| 385 | else |
| 386 | return 0; |
Damjan Marion | b509504 | 2020-09-11 22:13:46 +0200 | [diff] [blame] | 387 | return 1; |
| 388 | } |
| 389 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 390 | /* Format c identifier: e.g. a_name -> "a name". |
Klement Sekera | ea84130 | 2018-05-11 12:59:05 +0200 | [diff] [blame] | 391 | Works for both vector names and null terminated c strings. */ |
Damjan Marion | dae1c7e | 2020-10-17 13:32:25 +0200 | [diff] [blame] | 392 | __clib_export u8 * |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 393 | format_c_identifier (u8 * s, va_list * va) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 394 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 395 | u8 *id = va_arg (*va, u8 *); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 396 | uword i, l; |
| 397 | |
| 398 | l = ~0; |
| 399 | if (clib_mem_is_vec (id)) |
| 400 | l = vec_len (id); |
| 401 | |
| 402 | if (id) |
BenoƮt Ganne | 1bd6f61 | 2020-07-16 12:03:35 +0200 | [diff] [blame] | 403 | for (i = 0; i < l && id[i] != 0; i++) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 404 | { |
| 405 | u8 c = id[i]; |
| 406 | |
| 407 | if (c == '_') |
| 408 | c = ' '; |
| 409 | vec_add1 (s, c); |
| 410 | } |
| 411 | |
| 412 | return s; |
| 413 | } |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 414 | |
Damjan Marion | dae1c7e | 2020-10-17 13:32:25 +0200 | [diff] [blame] | 415 | __clib_export u8 * |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 416 | format_hexdump (u8 * s, va_list * args) |
| 417 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 418 | u8 *data = va_arg (*args, u8 *); |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 419 | uword len = va_arg (*args, uword); |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 420 | int i, index = 0; |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 421 | const int line_len = 16; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 422 | u8 *line_hex = 0; |
| 423 | u8 *line_str = 0; |
Christophe Fontaine | d3c008d | 2017-10-02 18:10:54 +0200 | [diff] [blame] | 424 | u32 indent = format_get_indent (s); |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 425 | |
| 426 | if (!len) |
| 427 | return s; |
| 428 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 429 | for (i = 0; i < len; i++) |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 430 | { |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 431 | line_hex = format (line_hex, "%02x ", data[i]); |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 432 | line_str = format (line_str, "%c", isprint (data[i]) ? data[i] : '.'); |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 433 | if (!((i + 1) % line_len)) |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 434 | { |
| 435 | s = format (s, "%U%05x: %v[%v]", |
| 436 | format_white_space, index ? indent : 0, |
| 437 | index, line_hex, line_str); |
| 438 | if (i < len - 1) |
| 439 | s = format (s, "\n"); |
| 440 | index = i + 1; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 441 | vec_reset_length (line_hex); |
| 442 | vec_reset_length (line_str); |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 443 | } |
| 444 | } |
| 445 | |
| 446 | while (i++ % line_len) |
| 447 | line_hex = format (line_hex, " "); |
| 448 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 449 | if (vec_len (line_hex)) |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 450 | s = format (s, "%U%05x: %v[%v]", |
Damjan Marion | 1e33663 | 2018-02-17 14:05:08 +0100 | [diff] [blame] | 451 | format_white_space, index ? indent : 0, |
| 452 | index, line_hex, line_str); |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 453 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 454 | vec_free (line_hex); |
| 455 | vec_free (line_str); |
Damjan Marion | a7e83ce | 2016-06-09 12:38:22 +0200 | [diff] [blame] | 456 | |
| 457 | return s; |
| 458 | } |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 459 | |
Damjan Marion | e6387b2 | 2021-12-22 21:58:54 +0100 | [diff] [blame] | 460 | __clib_export u8 * |
| 461 | format_u64_bitmap (u8 *s, va_list *args) |
| 462 | { |
| 463 | u64 *bitmap = va_arg (*args, u64 *); |
| 464 | int n_uword = va_arg (*args, int); |
| 465 | u32 indent = format_get_indent (s); |
| 466 | |
| 467 | s = format (s, "%6s", ""); |
| 468 | |
| 469 | for (int i = 60; i >= 0; i -= 4) |
| 470 | s = format (s, "%5d", i); |
| 471 | |
| 472 | vec_add1 (s, '\n'); |
| 473 | |
| 474 | for (int j = n_uword - 1; j >= 0; j--) |
| 475 | { |
| 476 | s = format (s, "%U0x%04x ", format_white_space, indent, j * 8); |
| 477 | for (int i = 63; i >= 0; i--) |
| 478 | { |
| 479 | vec_add1 (s, (1ULL << i) & bitmap[j] ? '1' : '.'); |
| 480 | if (i % 4 == 0) |
| 481 | vec_add1 (s, ' '); |
| 482 | } |
| 483 | s = format (s, "0x%016lx", bitmap[j]); |
| 484 | if (j) |
| 485 | vec_add1 (s, '\n'); |
| 486 | } |
| 487 | |
| 488 | return s; |
| 489 | } |
| 490 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 491 | /* |
| 492 | * fd.io coding-style-patch-verification: ON |
| 493 | * |
| 494 | * Local Variables: |
| 495 | * eval: (c-set-style "gnu") |
| 496 | * End: |
| 497 | */ |