diff --git a/TODO b/TODO index 84364bf1..d4c93106 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ TODO * implement mmap for w32 * implement sdb_ainc/sdb_adec * implement io filters for load/save databases (io wrap) -* create string pool for a list of sizes +* create string pool for a list of sizes newpool (sizeof (char), 10, 100, 1000); * Add api to store serialized in memory * Add api for raw bytes @@ -19,7 +19,7 @@ TODO * Add support for socket file for memcached api * add api to create db without caching it before -Syncronization +Synchronization -------------- - each key/value have a timestamp of creation/modification - sdb_diff() must check both databases and look for removed entries diff --git a/include/sdb/asserts.h b/include/sdb/asserts.h new file mode 100644 index 00000000..79c52902 --- /dev/null +++ b/include/sdb/asserts.h @@ -0,0 +1,92 @@ +#ifndef SDB_ASSERTS_H +#define SDB_ASSERTS_H + +#if defined (__cplusplus) +extern "C" { +#endif + +#if defined (__GNUC__) && defined (__cplusplus) +#define SDB_FUNCTION ((const char*) (__PRETTY_FUNCTION__)) +#elif defined(__STDC__) && defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define SDB_FUNCTION ((const char*) (__func__)) +#elif defined (__GNUC__) || (defined(_MSC_VER) && (_MSC_VER > 1300)) +#define SDB_FUNCTION ((const char*) (__FUNCTION__)) +#else +#warning Do not know how to get function name in this setup +#define SDB_FUNCTION ((const char*) ("???")) +#endif + +/* + * SDB_CHECKS_LEVEL determines the behaviour of the sdb_return_* set of functions. + * + * 0: completely disable every function and make them like no-operation + * 1: silently enable checks. Check expressions and do return, but do not log anything + * 2: enable checks and logging (DEFAULT) + * 3: transform them into real assertion + */ +#ifndef SDB_CHECKS_LEVEL +#define SDB_CHECKS_LEVEL 2 +#endif + +#if SDB_CHECKS_LEVEL == 0 + +#define sdb_return_if_fail(expr) do { ; } while(0) +#define sdb_return_val_if_fail(expr, val) do { ; } while(0) + +#elif SDB_CHECKS_LEVEL == 1 || SDB_CHECKS_LEVEL == 2 // SDB_CHECKS_LEVEL + +#if SDB_CHECKS_LEVEL == 1 +#define H_LOG_(loglevel, fmt, ...) +#else +#define H_LOG_(loglevel, fmt, ...) eprintf (fmt, __VA_ARGS__) +#endif + +/** + * sdb_return_if_fail: + * @expr: the expression to check + * + * Verifies that the expression @expr, usually representing a precondition, + * evaluates to `true`. If the function returns a value, use + * sdb_return_val_if_fail() instead. + * + * If @expr evaluates to %FALSE, the current function should be considered to + * have undefined behaviour (a programmer error). The only correct solution + * to such an error is to change the module that is calling the current + * function, so that it avoids this incorrect call. + * + * To make this undefined behaviour visible, if @expr evaluates to %FALSE, + * the result is usually that a critical message is logged and the current + * function returns. + */ +#define sdb_return_if_fail(expr) \ + do { \ + if (!(expr)) { \ + H_LOG_ ("%s: assertion '%s' failed (line %d)", SDB_FUNCTION, #expr, __LINE__); \ + return; \ + } \ + } while (0) + +#define sdb_return_val_if_fail(expr, val) \ + do { \ + if (!(expr)) { \ + H_LOG_ ("%s: assertion '%s' failed (line %d)", SDB_FUNCTION, #expr, __LINE__); \ + return (val); \ + } \ + } while (0) + +#else // SDB_CHECKS_LEVEL + +#include + +#define sdb_return_if_fail(expr) do { assert (expr); } while(0) +#define sdb_return_val_if_fail(expr, val) do { assert (expr); } while(0) +#define sdb_return_if_reached() do { assert (false); } while(0) +#define sdb_return_val_if_reached(val) do { assert (false); } while(0) + +#endif // SDB_CHECKS_LEVEL + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sdb/sdb.h b/include/sdb/sdb.h index f9f74e7e..5249f820 100644 --- a/include/sdb/sdb.h +++ b/include/sdb/sdb.h @@ -10,6 +10,7 @@ extern "C" { #endif +#include "asserts.h" #include "types.h" #include "ht.h" #include "ls.h" @@ -192,7 +193,7 @@ SDB_API int sdb_diff_format(char *str, int size, const SdbDiff *diff); typedef void (*SdbDiffCallback)(const SdbDiff *diff, void *user); // Returns true iff the contents of a and b are equal including contained namespaces -// If cb is non-null, it will be called subsequently with differences. +// If cb is non-null, it will be called subsequently with differences. SDB_API bool sdb_diff(Sdb *a, Sdb *b, SdbDiffCallback cb, void *cb_user); // Gets a pointer to the value associated with `key`.