Add macro M_CSTR
This commit is contained in:
1 parent
ffc2ec8c4b
commit
3df2408ffb
3 files changed
+93
-2
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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 ***********************/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user