diff options
author | Alejandro Colomar <alx@kernel.org> | 2024-04-16 17:47:12 +0200 |
---|---|---|
committer | Alejandro Colomar <alx@kernel.org> | 2024-04-16 20:28:41 +0200 |
commit | 1420e41a0d100add7bf4e3aedcafdecf886a036d (patch) | |
tree | f86805e757461c6ee41ff2059cc3f48137bc8846 | |
parent | 605d8d66f6e1aea0a03191b86bcd6e713895071b (diff) | |
download | liba2i-1420e41a0d100add7bf4e3aedcafdecf886a036d.tar.gz |
include/a2i/a2i*: Add const-generic macros
Signed-off-by: Alejandro Colomar <alx@kernel.org>
-rw-r--r-- | include/a2i/a2i.h | 140 | ||||
-rw-r--r-- | include/a2i/a2i_func.h | 180 | ||||
-rw-r--r-- | lib/src/a2i/a2i_func.c | 53 |
3 files changed, 313 insertions, 60 deletions
diff --git a/include/a2i/a2i.h b/include/a2i/a2i.h index 34be7fa..426f2d4 100644 --- a/include/a2i/a2i.h +++ b/include/a2i/a2i.h @@ -12,21 +12,40 @@ #include <a2i/typetraits.h> -#define a2i(TYPE, ...) \ +#define a2i(TYPE, n, s, endp, ...) \ ( \ - _Generic((TYPE) 0, \ - signed char: a2shh, \ - short: a2sh, \ - int: a2si, \ - long: a2sl, \ - long long: a2sll, \ - \ - unsigned char: a2uhh, \ - unsigned short: a2uh, \ - unsigned int: a2ui, \ - unsigned long: a2ul, \ - unsigned long long: a2ull \ - )(__VA_ARGS__) \ + _Generic((void (*)(TYPE, typeof(endp))) 0, \ + void (*)(signed char, const char **): a2shh_c, \ + void (*)(signed char, char **): a2shh_nc, \ + void (*)(signed char, void *): a2shh_nc, \ + void (*)(short, const char **): a2sh_c, \ + void (*)(short, char **): a2sh_nc, \ + void (*)(short, void *): a2sh_nc, \ + void (*)(int, const char **): a2si_c, \ + void (*)(int, char **): a2si_nc, \ + void (*)(int, void *): a2si_nc, \ + void (*)(long, const char **): a2sl_c, \ + void (*)(long, char **): a2sl_nc, \ + void (*)(long, void *): a2sl_nc, \ + void (*)(long long, const char **): a2sll_c, \ + void (*)(long long, char **): a2sll_nc, \ + void (*)(long long, void *): a2sll_nc, \ + void (*)(unsigned char, const char **): a2uhh_c, \ + void (*)(unsigned char, char **): a2uhh_nc, \ + void (*)(unsigned char, void *): a2uhh_nc, \ + void (*)(unsigned short, const char **): a2uh_c, \ + void (*)(unsigned short, char **): a2uh_nc, \ + void (*)(unsigned short, void *): a2uh_nc, \ + void (*)(unsigned int, const char **): a2ui_c, \ + void (*)(unsigned int, char **): a2ui_nc, \ + void (*)(unsigned int, void *): a2ui_nc, \ + void (*)(unsigned long, const char **): a2ul_c, \ + void (*)(unsigned long, char **): a2ul_nc, \ + void (*)(unsigned long, void *): a2ul_nc, \ + void (*)(unsigned long long, const char **): a2ull_c, \ + void (*)(unsigned long long, char **): a2ull_nc, \ + void (*)(unsigned long long, void *): a2ull_nc \ + )(n, s, endp, __VA_ARGS__) \ ) @@ -36,7 +55,6 @@ a2i(TYPE, __VA_ARGS__); \ }) - #define a2u(TYPE, ...) \ ({ \ static_assert(a2i_is_unsigned(TYPE), ""); \ @@ -44,4 +62,96 @@ }) +#define a2shh(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2shh_c, \ + char **: a2shh_nc, \ + void *: a2shh_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2sh(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2sh_c, \ + char **: a2sh_nc, \ + void *: a2sh_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2si(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2si_c, \ + char **: a2si_nc, \ + void *: a2si_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2sl(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2sl_c, \ + char **: a2sl_nc, \ + void *: a2sl_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2sll(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2sll_c, \ + char **: a2sll_nc, \ + void *: a2sll_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + + +#define a2uhh(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2uhh_c, \ + char **: a2uhh_nc, \ + void *: a2uhh_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2uh(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2uh_c, \ + char **: a2uh_nc, \ + void *: a2uh_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2ui(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2ui_c, \ + char **: a2ui_nc, \ + void *: a2ui_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2ul(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2ul_c, \ + char **: a2ul_nc, \ + void *: a2ul_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + +#define a2ull(n, s, endp, ...) \ +( \ + _Generic(endp, \ + const char **: a2ull_c, \ + char **: a2ull_nc, \ + void *: a2ull_nc \ + )(n, s, endp, __VA_ARGS__) \ +) + + #endif // include guard diff --git a/include/a2i/a2i_func.h b/include/a2i/a2i_func.h index 30f3f18..448b361 100644 --- a/include/a2i/a2i_func.h +++ b/include/a2i/a2i_func.h @@ -16,7 +16,24 @@ #include <a2i/strtoi.h> -#define a2i_a2S(n, s, endp, base, min, max) \ +#define a2i_a2S_c(n, s, endp, ...) \ +({ \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\""); \ + a2i_a2S_nc(n, s, (char **a2i_nullable) endp, __VA_ARGS__); \ + _Pragma("GCC diagnostic pop"); \ +}) + +#define a2i_a2U_c(n, s, endp, ...) \ +({ \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\""); \ + a2i_a2U_nc(n, s, (char **a2i_nullable) endp, __VA_ARGS__); \ + _Pragma("GCC diagnostic pop"); \ +}) + + +#define a2i_a2S_nc(n, s, endp, base, min, max) \ ({ \ int status_; \ intmax_t n_; \ @@ -30,8 +47,7 @@ -!!status_; \ }) - -#define a2i_a2U(n, s, endp, base, min, max) \ +#define a2i_a2U_nc(n, s, endp, base, min, max) \ ({ \ int status_; \ uintmax_t n_; \ @@ -46,118 +62,212 @@ }) -#define A2I_A2I_PROTOTYPE(name, TYPE) \ +#define A2I_A2I_PROTOTYPE(name, TYPE, TYPE2) \ A2I_ATTR_ACCESS(write_only, 1) \ A2I_ATTR_ACCESS(read_only, 2) \ A2I_ATTR_ACCESS(write_only, 3) \ A2I_ATTR_STRING(2) \ a2i_inline int name(TYPE *restrict n, const char *s, \ - char **a2i_nullable restrict endp, int base, TYPE min, TYPE max) + TYPE2 a2i_nullable restrict endp, int base, TYPE min, TYPE max) + +#define A2I_A2I_PROTOTYPES(name, TYPE) \ + A2I_A2I_PROTOTYPE(name ## _c, TYPE, const char **); \ + A2I_A2I_PROTOTYPE(name ## _nc, TYPE, char **) #if defined(__clang__) # pragma clang assume_nonnull begin #endif -A2I_A2I_PROTOTYPE(a2shh, signed char); -A2I_A2I_PROTOTYPE(a2sh, short); -A2I_A2I_PROTOTYPE(a2si, int); -A2I_A2I_PROTOTYPE(a2sl, long); -A2I_A2I_PROTOTYPE(a2sll, long long); +A2I_A2I_PROTOTYPES(a2shh, signed char); +A2I_A2I_PROTOTYPES(a2sh, short); +A2I_A2I_PROTOTYPES(a2si, int); +A2I_A2I_PROTOTYPES(a2sl, long); +A2I_A2I_PROTOTYPES(a2sll, long long); + +A2I_A2I_PROTOTYPES(a2uhh, unsigned char); +A2I_A2I_PROTOTYPES(a2uh, unsigned short); +A2I_A2I_PROTOTYPES(a2ui, unsigned int); +A2I_A2I_PROTOTYPES(a2ul, unsigned long); +A2I_A2I_PROTOTYPES(a2ull, unsigned long long); + + +a2i_inline int +a2shh_c(signed char *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + signed char min, signed char max) +{ + return a2i_a2S_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2sh_c(short *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + short min, short max) +{ + return a2i_a2S_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2si_c(int *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + int min, int max) +{ + return a2i_a2S_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2sl_c(long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + long min, long max) +{ + return a2i_a2S_c(n, s, endp, base, min, max); +} + -A2I_A2I_PROTOTYPE(a2uhh, unsigned char); -A2I_A2I_PROTOTYPE(a2uh, unsigned short); -A2I_A2I_PROTOTYPE(a2ui, unsigned int); -A2I_A2I_PROTOTYPE(a2ul, unsigned long); -A2I_A2I_PROTOTYPE(a2ull, unsigned long long); +a2i_inline int +a2sll_c(long long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + long long min, long long max) +{ + return a2i_a2S_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2uhh_c(unsigned char *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned char min, unsigned char max) +{ + return a2i_a2U_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2uh_c(unsigned short *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned short min, unsigned short max) +{ + return a2i_a2U_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2ui_c(unsigned int *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned int min, unsigned int max) +{ + return a2i_a2U_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2ul_c(unsigned long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned long min, unsigned long max) +{ + return a2i_a2U_c(n, s, endp, base, min, max); +} + + +a2i_inline int +a2ull_c(unsigned long long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned long long min, unsigned long long max) +{ + return a2i_a2U_c(n, s, endp, base, min, max); +} a2i_inline int -a2shh(signed char *restrict n, const char *s, +a2shh_nc(signed char *restrict n, const char *s, char **a2i_nullable restrict endp, int base, signed char min, signed char max) { - return a2i_a2S(n, s, endp, base, min, max); + return a2i_a2S_nc(n, s, endp, base, min, max); } a2i_inline int -a2sh(short *restrict n, const char *s, +a2sh_nc(short *restrict n, const char *s, char **a2i_nullable restrict endp, int base, short min, short max) { - return a2i_a2S(n, s, endp, base, min, max); + return a2i_a2S_nc(n, s, endp, base, min, max); } a2i_inline int -a2si(int *restrict n, const char *s, +a2si_nc(int *restrict n, const char *s, char **a2i_nullable restrict endp, int base, int min, int max) { - return a2i_a2S(n, s, endp, base, min, max); + return a2i_a2S_nc(n, s, endp, base, min, max); } a2i_inline int -a2sl(long *restrict n, const char *s, +a2sl_nc(long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, long min, long max) { - return a2i_a2S(n, s, endp, base, min, max); + return a2i_a2S_nc(n, s, endp, base, min, max); } a2i_inline int -a2sll(long long *restrict n, const char *s, +a2sll_nc(long long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, long long min, long long max) { - return a2i_a2S(n, s, endp, base, min, max); + return a2i_a2S_nc(n, s, endp, base, min, max); } a2i_inline int -a2uhh(unsigned char *restrict n, const char *s, +a2uhh_nc(unsigned char *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned char min, unsigned char max) { - return a2i_a2U(n, s, endp, base, min, max); + return a2i_a2U_nc(n, s, endp, base, min, max); } a2i_inline int -a2uh(unsigned short *restrict n, const char *s, +a2uh_nc(unsigned short *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned short min, unsigned short max) { - return a2i_a2U(n, s, endp, base, min, max); + return a2i_a2U_nc(n, s, endp, base, min, max); } a2i_inline int -a2ui(unsigned int *restrict n, const char *s, +a2ui_nc(unsigned int *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned int min, unsigned int max) { - return a2i_a2U(n, s, endp, base, min, max); + return a2i_a2U_nc(n, s, endp, base, min, max); } a2i_inline int -a2ul(unsigned long *restrict n, const char *s, +a2ul_nc(unsigned long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned long min, unsigned long max) { - return a2i_a2U(n, s, endp, base, min, max); + return a2i_a2U_nc(n, s, endp, base, min, max); } a2i_inline int -a2ull(unsigned long long *restrict n, const char *s, +a2ull_nc(unsigned long long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned long long min, unsigned long long max) { - return a2i_a2U(n, s, endp, base, min, max); + return a2i_a2U_nc(n, s, endp, base, min, max); } #if defined(__clang__) # pragma clang assume_nonnull end diff --git a/lib/src/a2i/a2i_func.c b/lib/src/a2i/a2i_func.c index 4ae9a20..a11e93e 100644 --- a/lib/src/a2i/a2i_func.c +++ b/lib/src/a2i/a2i_func.c @@ -8,35 +8,68 @@ #pragma clang assume_nonnull begin -extern inline int a2shh(signed char *restrict n, const char *s, +extern inline int a2shh_c(signed char *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + signed char min, signed char max); +extern inline int a2sh_c(short *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + short min, short max); +extern inline int a2si_c(int *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + int min, int max); +extern inline int a2sl_c(long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + long min, long max); +extern inline int a2sll_c(long long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + long long min, long long max); + +extern inline int a2uhh_c(unsigned char *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned char min, unsigned char max); +extern inline int a2uh_c(unsigned short *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned short min, unsigned short max); +extern inline int a2ui_c(unsigned int *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned int min, unsigned int max); +extern inline int a2ul_c(unsigned long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned long min, unsigned long max); +extern inline int a2ull_c(unsigned long long *restrict n, const char *s, + const char **a2i_nullable restrict endp, int base, + unsigned long long min, unsigned long long max); + + +extern inline int a2shh_nc(signed char *restrict n, const char *s, char **a2i_nullable restrict endp, int base, signed char min, signed char max); -extern inline int a2sh(short *restrict n, const char *s, +extern inline int a2sh_nc(short *restrict n, const char *s, char **a2i_nullable restrict endp, int base, short min, short max); -extern inline int a2si(int *restrict n, const char *s, +extern inline int a2si_nc(int *restrict n, const char *s, char **a2i_nullable restrict endp, int base, int min, int max); -extern inline int a2sl(long *restrict n, const char *s, +extern inline int a2sl_nc(long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, long min, long max); -extern inline int a2sll(long long *restrict n, const char *s, +extern inline int a2sll_nc(long long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, long long min, long long max); -extern inline int a2uhh(unsigned char *restrict n, const char *s, +extern inline int a2uhh_nc(unsigned char *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned char min, unsigned char max); -extern inline int a2uh(unsigned short *restrict n, const char *s, +extern inline int a2uh_nc(unsigned short *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned short min, unsigned short max); -extern inline int a2ui(unsigned int *restrict n, const char *s, +extern inline int a2ui_nc(unsigned int *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned int min, unsigned int max); -extern inline int a2ul(unsigned long *restrict n, const char *s, +extern inline int a2ul_nc(unsigned long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned long min, unsigned long max); -extern inline int a2ull(unsigned long long *restrict n, const char *s, +extern inline int a2ull_nc(unsigned long long *restrict n, const char *s, char **a2i_nullable restrict endp, int base, unsigned long long min, unsigned long long max); #pragma clang assume_nonnull end |