util/cutils: Add STR_ARRAY_ELEM_OR_NULL() for string table lookups

Many functions map an enum or exception number to a name, either
with a switch statement or by indexing a string table after an
open-coded bounds check. Add STR_ARRAY_ELEM_OR_NULL(array, index),
which returns array[index], or NULL when index is out of bounds,
so such code can use a static table and a single call.

The array is passed as 'const char *const *', so only arrays of
strings are accepted; hence the STR_ prefix rather than a generic
name.

Misuse is caught at build time:
- pointer instead of array: "negative width in bit-field" error,
  plus -Wsizeof-pointer-div (GCC);
- array of non-strings (int[], char[][N], int *[]):
  -Wincompatible-pointer-types;
- array of non-const 'char *': -Wincompatible-pointer-types (GCC),
  -Wincompatible-pointer-types-discards-qualifiers (clang);
- pointer as index: -Wint-conversion.

Suggested-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Message-ID: <20261022215115.19680-3-philmd@oss.qualcomm.com>
This commit is contained in:
Philippe Mathieu-Daudé committed 2026-10-24 11:48:29 +02:00
1 parent 3aa02c7b6f
commit c4c07cac75
3 files changed
+26

No files matched your search

+17
View File
@@ -19,6 +19,23 @@ const char *si_prefix(unsigned int exp10);
*/
const char *iec_binary_prefix(unsigned int exp2);
const char *str_array_elem_or_null(const char *const *array,
size_t nelem, uint64_t index);
/**
* STR_ARRAY_ELEM_OR_NULL() - Return a string array element, or NULL if
* out of bounds
* @array: array of strings to index
* @index: index of the element to return
*
* Return @array[@index] if @index is a valid index, otherwise return
* NULL. @index is converted to uint64_t, so negative values of signed
* types are out of bounds and also yield NULL. Useful to look up entries
* in enum-indexed string tables without a prior bounds check.
*/
#define STR_ARRAY_ELEM_OR_NULL(array, index) \
str_array_elem_or_null(array, ARRAY_SIZE(array), index)
/**
* pstrcpy:
* @buf: buffer to copy string into
+3
View File
@@ -532,6 +532,9 @@ void QEMU_ERROR("code path is reachable")
* ARRAY_SIZE() - Return the number of elements of an array
* @x: the array
*
* For bounds-checked lookups in arrays of strings, see
* STR_ARRAY_ELEM_OR_NULL() in "qemu/cutils.h".
*
* Note: fails to build if @x is a pointer.
*/
#ifndef ARRAY_SIZE
+6
View File
@@ -954,6 +954,12 @@ const char *iec_binary_prefix(unsigned int exp2)
return prefixes[exp2 / 10];
}
const char *str_array_elem_or_null(const char *const *array,
size_t nelem, uint64_t index)
{
return index >= nelem ? NULL : array[index];
}
/*
* Return human readable string for size @val.
* @val can be anything that uint64_t allows (no more than "16 EiB").