| /* SPDX-License-Identifier: Apache-2.0 |
| * Copyright(c) 2021 Cisco Systems, Inc. |
| */ |
| |
| #include <vppinfra/vec.h> |
| #include <vppinfra/bitmap.h> |
| |
| /** unformat an any sized hexadecimal bitmask into a bitmap |
| |
| uword * bitmap; |
| rv = unformat ("%U", unformat_bitmap_mask, &bitmap); |
| |
| Standard unformat_function_t arguments |
| |
| @param input - pointer an unformat_input_t |
| @param va - varargs list comprising a single uword ** |
| @returns 1 on success, 0 on failure |
| */ |
| __clib_export uword |
| unformat_bitmap_mask (unformat_input_t *input, va_list *va) |
| { |
| u8 *v = 0; /* hexadecimal vector */ |
| uword **bitmap_return = va_arg (*va, uword **); |
| uword *bitmap = 0; |
| |
| if (unformat (input, "%U", unformat_hex_string, &v)) |
| { |
| int i, s = vec_len (v) - 1; /* 's' for significance or shift */ |
| |
| /* v[0] holds the most significant byte */ |
| for (i = 0; s >= 0; i++, s--) |
| bitmap = clib_bitmap_set_multiple (bitmap, s * BITS (v[i]), v[i], |
| BITS (v[i])); |
| |
| vec_free (v); |
| *bitmap_return = bitmap; |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| /** unformat a list of bit ranges into a bitmap (eg "0-3,5-7,11" ) |
| |
| uword * bitmap; |
| rv = unformat ("%U", unformat_bitmap_list, &bitmap); |
| |
| Standard unformat_function_t arguments |
| |
| @param input - pointer an unformat_input_t |
| @param va - varargs list comprising a single uword ** |
| @returns 1 on success, 0 on failure |
| */ |
| __clib_export uword |
| unformat_bitmap_list (unformat_input_t *input, va_list *va) |
| { |
| uword **bitmap_return = va_arg (*va, uword **); |
| uword *bitmap = 0; |
| |
| u32 a, b; |
| |
| while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) |
| { |
| int i; |
| if (unformat (input, "%u-%u,", &a, &b)) |
| ; |
| else if (unformat (input, "%u,", &a)) |
| b = a; |
| else if (unformat (input, "%u-%u", &a, &b)) |
| ; |
| else if (unformat (input, "%u", &a)) |
| b = a; |
| else if (bitmap) |
| { |
| unformat_put_input (input); |
| break; |
| } |
| else |
| goto error; |
| |
| if (b < a) |
| goto error; |
| |
| for (i = a; i <= b; i++) |
| bitmap = clib_bitmap_set (bitmap, i, 1); |
| } |
| *bitmap_return = bitmap; |
| return 1; |
| error: |
| clib_bitmap_free (bitmap); |
| return 0; |
| } |
| |
| /** Format a bitmap as a string of hex bytes |
| |
| uword * bitmap; |
| s = format ("%U", format_bitmap_hex, bitmap); |
| |
| Standard format_function_t arguments |
| |
| @param s - string under construction |
| @param args - varargs list comprising a single uword * |
| @returns string under construction |
| */ |
| |
| __clib_export u8 * |
| format_bitmap_hex (u8 *s, va_list *args) |
| { |
| uword *bitmap = va_arg (*args, uword *); |
| int i, is_trailing_zero = 1; |
| |
| if (!bitmap) |
| return format (s, "0"); |
| |
| i = vec_bytes (bitmap) * 2; |
| |
| while (i > 0) |
| { |
| u8 x = clib_bitmap_get_multiple (bitmap, --i * 4, 4); |
| |
| if (x && is_trailing_zero) |
| is_trailing_zero = 0; |
| |
| if (x || !is_trailing_zero) |
| s = format (s, "%x", x); |
| } |
| return s; |
| } |
| |
| /** Format a bitmap as a list |
| |
| uword * bitmap; |
| s = format ("%U", format_bitmap_list, bitmap); |
| |
| Standard format_function_t arguments |
| |
| @param s - string under construction |
| @param args - varargs list comprising a single uword * |
| @returns string under construction |
| */ |
| |
| __clib_export u8 * |
| format_bitmap_list (u8 *s, va_list *args) |
| { |
| uword *bitmap = va_arg (*args, uword *); |
| uword fs, fc; |
| |
| if (!bitmap) |
| return s; |
| |
| fs = clib_bitmap_first_set (bitmap); |
| if (fs == ~0) |
| return s; |
| |
| while (1) |
| { |
| fc = clib_bitmap_next_clear (bitmap, fs + 1); |
| if (fc > fs + 1) |
| s = format (s, "%lu-%lu", fs, fc - 1); |
| else |
| s = format (s, "%lu", fs); |
| |
| if ((fs = clib_bitmap_next_set (bitmap, fc)) == ~0) |
| return s; |
| s = format (s, ", "); |
| } |
| } |