Add macro M_CSTR

This commit is contained in:
Patrick Pelissier committed 2021-01-10 09:26:27 +01:00
1 parent ffc2ec8c4b
commit 3df2408ffb
3 files changed
+93 -2

No files matched your search

+11
View File
@@ -5700,6 +5700,17 @@ If it cannot, the compilation failed.
Assuming 'ptr' is a pointer to a fieldType object that is stored within a structure of type 'type'
at the position 'field', it returns a pointer to the structure.
##### M\_CSTR(format, ...)
Return a constant string constructed based on the printf-liked formated string
and its arguments.
The string is constructed at run time and uses a temporary space on the stack.
If the constructed string is longer than M\_USE\_CSTR\_ALLOC (default 256),
the string is truncated. Example:
strcmp( M_CSTR("Len=%d", 17) , "Len=17" ) == 0
#### HASH Functions
+71 -2
View File
@@ -29,7 +29,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <limits.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
@@ -1971,7 +1971,7 @@ M_PARSE_DEFAULT_TYPE_DEF(m_core_parse_ldouble, long double, strtold, )
* a null pointer constant, the returned type depends if the **other**
* expression is itself a null pointer constant or not.
*/
#define M_CONDITIONAL(cond, true_expr, false_expr) \
#define M_CONDITIONAL(cond, true_expr, false_expr) \
_Generic(1 ? (float *) 0 : (void *)(intptr_t) (cond), float *: false_expr, void *: true_expr)
/* Return the minimum between x and y (computed in compile time) */
@@ -2054,6 +2054,75 @@ M_PARSE_DEFAULT_TYPE_DEF(m_core_parse_ldouble, long double, strtold, )
#endif
/* Define the allocation of the temporary string used by M_CSTR
Default is 256 bytes (so 255 characters excluding the final null char).
It can be overriden by users if needed.
*/
#ifndef M_USE_CSTR_ALLOC
#define M_USE_CSTR_ALLOC 256
#endif
/* Define M_CSTR for C++ & C */
#if defined(__cplusplus)
namespace m_lib {
template <unsigned int N>
struct m_char_array {
char str[N];
inline m_char_array(const char *format, ...)
{
va_list args;
va_start (args, format);
int ret = vsnprintf(str, N, format, args);
(void) ret;
va_end (args);
}
inline const char *m_get(void)
{
return str;
}
};
}
/* Return a constant string constructed based on the printf-liked formated string
and its arguments.
The string is constructed at run time and uses a temporary space on the stack.
If the constructed string is longer than M_USE_CSTR_ALLOC (default 256),
the string is truncated.
Example:
strlen( M_CSTR("Len=%d", 17) ) == 6
NOTE: C++ definition using template as C++ doesn't support compound litteral.
*/
#define M_CSTR(...) \
(const m_lib::m_char_array<M_USE_CSTR_ALLOC>(__VA_ARGS__)).m_get()
#else
// Encapsulate snprintf to return the input buffer as argument (needed for M_CSTR)
static inline const char *
m_core_snprintf(char *str, size_t size, const char *format, ...)
{
va_list args;
va_start (args, format);
int ret = vsnprintf(str, size, format, args);
(void) ret;
va_end (args);
return str;
}
/* Return a constant string constructed based on the printf-liked formated string
and its arguments.
The string is constructed at run time and uses a temporary space on the stack.
If the constructed string is longer than M_USE_CSTR_ALLOC (default 256),
the string is truncated.
Example:
strlen( M_CSTR("Len=%d", 17) ) == 6
NOTE: C definition using compound litteral.
*/
#define M_CSTR(...) \
m_core_snprintf( (char [M_USE_CSTR_ALLOC]){}, M_USE_CSTR_ALLOC, __VA_ARGS__)
#endif
/************************************************************/
/********************* HASH selection ***********************/
+11
View File
@@ -606,6 +606,16 @@ static void test_str_hash(void)
assert (M_CALL_HASH(M_CSTR_OPLIST, str3) != 0);
}
static void test_M_CSTR(void)
{
assert ( strcmp(M_CSTR("Len=%d", 17), "Len=17") == 0);
assert ( strcmp(M_CSTR("Hello %s %c", "World", '!'), "Hello World !") == 0);
// Reduce allocation to test truncation
#undef M_USE_CSTR_ALLOC
#define M_USE_CSTR_ALLOC 8
assert ( strcmp(M_CSTR("Hello %s %c", "World", '!'), "Hello W") == 0);
}
int main(void)
{
test_cat();
@@ -629,5 +639,6 @@ int main(void)
test_move_default();
test_builtin();
test_str_hash();
test_M_CSTR();
exit(0);
}