Better support for variadic functions
This commit is contained in:
+37
-18
@@ -8,6 +8,10 @@ typedef struct {
|
||||
int len;
|
||||
} CWEB_String;
|
||||
|
||||
typedef struct {
|
||||
char data[61];
|
||||
} CWEB_PasswordHash;
|
||||
|
||||
CWEB_String cweb_trim(CWEB_String s);
|
||||
bool cweb_streq(CWEB_String a, CWEB_String b);
|
||||
|
||||
@@ -31,6 +35,7 @@ typedef enum {
|
||||
CWEB_VARG_TYPE_D,
|
||||
CWEB_VARG_TYPE_B,
|
||||
CWEB_VARG_TYPE_STR,
|
||||
CWEB_VARG_TYPE_HASH,
|
||||
CWEB_VARG_TYPE_PC,
|
||||
CWEB_VARG_TYPE_PS,
|
||||
CWEB_VARG_TYPE_PI,
|
||||
@@ -50,6 +55,7 @@ typedef enum {
|
||||
CWEB_VARG_TYPE_PD,
|
||||
CWEB_VARG_TYPE_PB,
|
||||
CWEB_VARG_TYPE_PSTR,
|
||||
CWEB_VARG_TYPE_PHASH,
|
||||
} CWEB_VArgType;
|
||||
|
||||
typedef struct {
|
||||
@@ -74,6 +80,7 @@ typedef struct {
|
||||
double d;
|
||||
bool b;
|
||||
CWEB_String str;
|
||||
CWEB_PasswordHash hash;
|
||||
char *pc;
|
||||
short *ps;
|
||||
int *pi;
|
||||
@@ -93,9 +100,15 @@ typedef struct {
|
||||
double *pd;
|
||||
bool *pb;
|
||||
CWEB_String *pstr;
|
||||
CWEB_PasswordHash *phash;
|
||||
};
|
||||
} CWEB_VArg;
|
||||
|
||||
typedef struct {
|
||||
int len;
|
||||
CWEB_VArg *ptr;
|
||||
} CWEB_VArgs;
|
||||
|
||||
CWEB_VArg cweb_varg_from_c (char c);
|
||||
CWEB_VArg cweb_varg_from_s (short s);
|
||||
CWEB_VArg cweb_varg_from_i (int i);
|
||||
@@ -115,6 +128,7 @@ CWEB_VArg cweb_varg_from_f (float f);
|
||||
CWEB_VArg cweb_varg_from_d (double d);
|
||||
CWEB_VArg cweb_varg_from_b (bool b);
|
||||
CWEB_VArg cweb_varg_from_str (CWEB_String str);
|
||||
CWEB_VArg cweb_varg_from_hash (CWEB_PasswordHash hash);
|
||||
CWEB_VArg cweb_varg_from_pc (char *pc);
|
||||
CWEB_VArg cweb_varg_from_ps (short *ps);
|
||||
CWEB_VArg cweb_varg_from_pi (int *pi);
|
||||
@@ -134,8 +148,9 @@ CWEB_VArg cweb_varg_from_pf (float *pf);
|
||||
CWEB_VArg cweb_varg_from_pd (double *pd);
|
||||
CWEB_VArg cweb_varg_from_pb (bool *pb);
|
||||
CWEB_VArg cweb_varg_from_pstr (CWEB_String *pstr);
|
||||
CWEB_VArg cweb_varg_from_phash(CWEB_PasswordHash *phash);
|
||||
|
||||
#define CWEB_VARG(X) (_Generic((X), \
|
||||
#define __CWEB_HELPER_ARG(X) (_Generic((X), \
|
||||
char : cweb_varg_from_c, \
|
||||
short : cweb_varg_from_s, \
|
||||
int : cweb_varg_from_i, \
|
||||
@@ -155,6 +170,7 @@ CWEB_VArg cweb_varg_from_pstr (CWEB_String *pstr);
|
||||
double : cweb_varg_from_d, \
|
||||
bool : cweb_varg_from_b, \
|
||||
CWEB_String : cweb_varg_from_str, \
|
||||
CWEB_PasswordHash : cweb_varg_from_hash, \
|
||||
char* : cweb_varg_from_pc, \
|
||||
short* : cweb_varg_from_ps, \
|
||||
int* : cweb_varg_from_pi, \
|
||||
@@ -173,21 +189,26 @@ CWEB_VArg cweb_varg_from_pstr (CWEB_String *pstr);
|
||||
float* : cweb_varg_from_pf, \
|
||||
double* : cweb_varg_from_pd, \
|
||||
bool* : cweb_varg_from_pb, \
|
||||
CWEB_String* : cweb_varg_from_pstr \
|
||||
CWEB_String* : cweb_varg_from_pstr, \
|
||||
CWEB_PasswordHash* : cweb_varg_from_phash \
|
||||
))(X)
|
||||
|
||||
typedef struct {
|
||||
int len;
|
||||
CWEB_VArg *ptr;
|
||||
} CWEB_VArgs;
|
||||
// Helper macros
|
||||
#define __CWEB_HELPER_DISPATCH_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
|
||||
#define __CWEB_HELPER_CONCAT_0(A, B) A ## B
|
||||
#define __CWEB_HELPER_CONCAT_1(A, B) __CWEB_HELPER_CONCAT_0(A, B)
|
||||
#define __CWEB_HELPER_ARGS_0() (CWEB_VArgs) { 0, (CWEB_VArg[]) {}}
|
||||
#define __CWEB_HELPER_ARGS_1(a) (CWEB_VArgs) { 1, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a) }}
|
||||
#define __CWEB_HELPER_ARGS_2(a, b) (CWEB_VArgs) { 2, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b) }}
|
||||
#define __CWEB_HELPER_ARGS_3(a, b, c) (CWEB_VArgs) { 3, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c) }}
|
||||
#define __CWEB_HELPER_ARGS_4(a, b, c, d) (CWEB_VArgs) { 4, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d) }}
|
||||
#define __CWEB_HELPER_ARGS_5(a, b, c, d, e) (CWEB_VArgs) { 5, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e) }}
|
||||
#define __CWEB_HELPER_ARGS_6(a, b, c, d, e, f) (CWEB_VArgs) { 6, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e), __CWEB_HELPER_ARG(f) }}
|
||||
#define __CWEB_HELPER_ARGS_7(a, b, c, d, e, f, g) (CWEB_VArgs) { 7, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e), __CWEB_HELPER_ARG(f), __CWEB_HELPER_ARG(g) }}
|
||||
#define __CWEB_HELPER_ARGS_8(a, b, c, d, e, f, g, h) (CWEB_VArgs) { 8, (CWEB_VArg[]) { __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e), __CWEB_HELPER_ARG(f), __CWEB_HELPER_ARG(g), __CWEB_HELPER_ARG(h) }}
|
||||
#define __CWEB_COUNT_ARGS(...) __CWEB_HELPER_DISPATCH_N(DUMMY, ##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
|
||||
#define CWEB_VARGS_1(a) (CWEB_VArgs) {1, (CWEB_VArg[]) { CWEB_VARG(a) } }
|
||||
#define CWEB_VARGS_2(a, b) (CWEB_VArgs) {2, (CWEB_VArg[]) { CWEB_VARG(a), CWEB_VARG(b) } }
|
||||
#define CWEB_VARGS_3(a, b, c) (CWEB_VArgs) {3, (CWEB_VArg[]) { CWEB_VARG(a), CWEB_VARG(b), CWEB_VARG(c) } }
|
||||
#define CWEB_VARGS_4(a, b, c, d) (CWEB_VArgs) {4, (CWEB_VArg[]) { CWEB_VARG(a), CWEB_VARG(b), CWEB_VARG(c), CWEB_VARG(d) } }
|
||||
#define CWEB_VARGS_5(a, b, c, d, e) (CWEB_VArgs) {5, (CWEB_VArg[]) { CWEB_VARG(a), CWEB_VARG(b), CWEB_VARG(c), CWEB_VARG(d), CWEB_VARG(e) } }
|
||||
#define CWEB_DISPATCH__(_1, _2, _3, _4, _5, NAME, ...) NAME
|
||||
#define CWEB_VARGS(...) CWEB_DISPATCH__(__VA_ARGS__, CWEB_VARGS_5, CWEB_VARGS_4, CWEB_VARGS_3, CWEB_VARGS_2, CWEB_VARGS_1)(__VA_ARGS__)
|
||||
#define CWEB_VARGS(...) __CWEB_HELPER_CONCAT_1(__CWEB_HELPER_ARGS_, __CWEB_COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
typedef struct CWEB CWEB;
|
||||
typedef struct CWEB_Request CWEB_Request;
|
||||
@@ -220,9 +241,11 @@ int cweb_get_param_i(CWEB_Request *req, CWEB_String name);
|
||||
// Response
|
||||
|
||||
void cweb_respond_basic(CWEB_Request *req, int status, CWEB_String content);
|
||||
void cweb_respond_redirect(CWEB_Request *req, CWEB_String target);
|
||||
void cweb_respond_redirect_impl(CWEB_Request *req, CWEB_String target_format, CWEB_VArgs args);
|
||||
void cweb_respond_template(CWEB_Request *req, int status, CWEB_String template_file, int resource_id);
|
||||
|
||||
#define cweb_respond_redirect(req, format, ...) cweb_respond_redirect_impl((req), (format), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////
|
||||
// Database
|
||||
|
||||
@@ -242,9 +265,5 @@ void cweb_free_query_result(CWEB_QueryResult *res);
|
||||
//////////////////////////////////////
|
||||
// Password
|
||||
|
||||
typedef struct {
|
||||
char data[61];
|
||||
} CWEB_PasswordHash;
|
||||
|
||||
int cweb_hash_password(char *pass, int passlen, int cost, CWEB_PasswordHash *hash);
|
||||
int cweb_check_password(char *pass, int passlen, CWEB_PasswordHash hash);
|
||||
|
||||
Reference in New Issue
Block a user