00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00032 #ifndef QOF_UTIL_H
00033 #define QOF_UTIL_H
00034
00035 #include <stddef.h>
00036 #include "qof.h"
00037 #include "qoflog.h"
00038 #include "qofdate.h"
00039 #include "qofutil.h"
00040 #include "qofbackend-p.h"
00041 #include "qofbook.h"
00042 #include "qofinstance.h"
00043
00045 #if HAVE_SCANF_LLD
00046 # define QOF_SCANF_LLD "%lld"
00047 #else
00048 # define QOF_SCANF_LLD "%qd"
00049 #endif
00050
00051 #define QOF_MOD_UTIL "qof-utilities"
00052
00056 #define ENUM_BODY(name, value) \
00057 name value,
00058
00059 #define AS_STRING_CASE(name, value) \
00060 case name: { return #name; }
00061
00062 #define FROM_STRING_CASE(name, value) \
00063 if (strcmp(str, #name) == 0) { \
00064 return name; }
00065
00066 #define DEFINE_ENUM(name, list) \
00067 typedef enum { \
00068 list(ENUM_BODY) \
00069 }name;
00070
00071 #define AS_STRING_DEC(name, list) \
00072 const gchar* name##asString(name n);
00073
00074 #define AS_STRING_FUNC(name, list) \
00075 const gchar* name##asString(name n) { \
00076 switch (n) { \
00077 list(AS_STRING_CASE) \
00078 default: return ""; } }
00079
00080 #define FROM_STRING_DEC(name, list) \
00081 name name##fromString \
00082 (const gchar* str);
00083
00084 #define FROM_STRING_FUNC(name, list) \
00085 name name##fromString \
00086 (const gchar* str) { \
00087 if(str == NULL) { return 0; } \
00088 list(FROM_STRING_CASE) \
00089 return 0; }
00090
00106 #define DEFINE_ENUM_NON_TYPEDEF(name, list) \
00107 enum name { \
00108 list(ENUM_BODY) \
00109 };
00110
00111 #define FROM_STRING_DEC_NON_TYPEDEF(name, list) \
00112 void name##fromString \
00113 (const gchar* str, enum name *type);
00114
00115 #define FROM_STRING_CASE_NON_TYPEDEF(name, value) \
00116 if (strcmp(str, #name) == 0) { *type = name; }
00117
00118 #define FROM_STRING_FUNC_NON_TYPEDEF(name, list) \
00119 void name##fromString \
00120 (const gchar* str, enum name *type) { \
00121 if(str == NULL) { return; } \
00122 list(FROM_STRING_CASE_NON_TYPEDEF) }
00123
00124 #define AS_STRING_DEC_NON_TYPEDEF(name, list) \
00125 const gchar* name##asString(enum name n);
00126
00127 #define AS_STRING_FUNC_NON_TYPEDEF(name, list) \
00128 const gchar* name##asString(enum name n) { \
00129 switch (n) { \
00130 list(AS_STRING_CASE_NON_TYPEDEF) \
00131 default: return ""; } }
00132
00133 #define AS_STRING_CASE_NON_TYPEDEF(name, value) \
00134 case name: { return #name; }
00135
00147 void qof_init (void);
00148
00155 void qof_close (void);
00156
00159
00160
00174 gint safe_strcmp (const gchar * da, const gchar * db);
00175
00188 gint safe_strcasecmp (const gchar * da, const gchar * db);
00189
00194 gint null_strcmp (const gchar * da, const gchar * db);
00195
00199 extern gchar *strncasestr (const guchar * str1, const guchar * str2,
00200 size_t len);
00201
00202 extern gchar *strcasestr (const gchar * str1, const gchar * str2);
00203
00207 gchar *ultostr (gulong val, gint base);
00208
00211 gboolean qof_util_string_isnum (const guchar * s);
00212
00213 #ifndef HAVE_STPCPY
00214 #define stpcpy g_stpcpy
00215 #endif
00216
00220 const gchar *qof_util_whitespace_filter (const gchar * val);
00221
00225 gint qof_util_bool_to_int (const gchar * val);
00226
00231 gchar *qof_util_param_as_string (QofEntity * ent, QofParam * param);
00232
00263 void qof_util_string_cache_destroy (void);
00264
00268 void qof_util_string_cache_remove (gconstpointer key);
00269
00273 gpointer qof_util_string_cache_insert (gconstpointer key);
00274
00275 #define CACHE_INSERT(str) qof_util_string_cache_insert((gconstpointer)(str))
00276 #define CACHE_REMOVE(str) qof_util_string_cache_remove((str))
00277
00278
00279
00280
00281
00282
00283
00284
00285 #define CACHE_REPLACE(dst, src) do { \
00286 gpointer tmp = CACHE_INSERT((src)); \
00287 CACHE_REMOVE((dst)); \
00288 (dst) = tmp; \
00289 } while (0)
00290
00291 #define QOF_CACHE_NEW(void) qof_util_string_cache_insert("")
00292
00303 #define QOF_BEGIN_EDIT(inst) \
00304 if (!(inst)) return; \
00305 \
00306 (inst)->editlevel++; \
00307 if (1 < (inst)->editlevel) return; \
00308 \
00309 if (0 >= (inst)->editlevel) \
00310 { \
00311 PERR ("unbalanced call - resetting (was %d)", (inst)->editlevel); \
00312 (inst)->editlevel = 1; \
00313 } \
00314 ENTER ("(inst=%p)", (inst)); \
00315 \
00316 \
00317 { \
00318 QofBackend * be; \
00319 be = qof_book_get_backend ((inst)->book); \
00320 if (be && qof_backend_begin_exists(be)) { \
00321 qof_backend_run_begin(be, (inst)); \
00322 } else { \
00323 \
00324 (inst)->dirty = TRUE; \
00325 } \
00326 } \
00327 LEAVE (" ");
00328
00334 gboolean qof_begin_edit (QofInstance * inst);
00335
00350 #define QOF_COMMIT_EDIT_PART1(inst) { \
00351 if (!(inst)) return; \
00352 \
00353 (inst)->editlevel--; \
00354 if (0 < (inst)->editlevel) return; \
00355 \
00356 \
00357 \
00358 \
00359 if ((-1 == (inst)->editlevel) && (inst)->dirty) \
00360 { \
00361 QofBackend * be; \
00362 be = qof_book_get_backend ((inst)->book); \
00363 if (be && qof_backend_begin_exists(be)) { \
00364 qof_backend_run_begin(be, (inst)); \
00365 } \
00366 (inst)->editlevel = 0; \
00367 } \
00368 if (0 > (inst)->editlevel) \
00369 { \
00370 PERR ("unbalanced call - resetting (was %d)", (inst)->editlevel); \
00371 (inst)->editlevel = 0; \
00372 } \
00373 ENTER ("(inst=%p) dirty=%d do-free=%d", \
00374 (inst), (inst)->dirty, (inst)->do_free); \
00375 }
00376
00382 gboolean qof_commit_edit (QofInstance * inst);
00383
00403 gboolean
00404 qof_commit_edit_part2 (QofInstance * inst,
00405 void (*on_error) (QofInstance *, QofBackendError),
00406 void (*on_done) (QofInstance *),
00407 void (*on_free) (QofInstance *));
00408
00413 #define QOF_COMMIT_EDIT_PART2(inst,on_error,on_done,on_free) { \
00414 QofBackend * be; \
00415 \
00416 \
00417 be = qof_book_get_backend ((inst)->book); \
00418 if (be && qof_backend_commit_exists(be)) \
00419 { \
00420 QofBackendError errcode; \
00421 \
00422 \
00423 do { \
00424 errcode = qof_backend_get_error (be); \
00425 } while (ERR_BACKEND_NO_ERR != errcode); \
00426 \
00427 qof_backend_run_commit(be, (inst)); \
00428 errcode = qof_backend_get_error (be); \
00429 if (ERR_BACKEND_NO_ERR != errcode) \
00430 { \
00431 \
00432 (inst)->do_free = FALSE; \
00433 \
00434 \
00435 qof_backend_set_error (be, errcode); \
00436 (on_error)((inst), errcode); \
00437 } \
00438 \
00439 (inst)->dirty = FALSE; \
00440 } \
00441 (on_done)(inst); \
00442 \
00443 LEAVE ("inst=%p, dirty=%d do-free=%d", \
00444 (inst), (inst)->dirty, (inst)->do_free); \
00445 if ((inst)->do_free) { \
00446 (on_free)(inst); \
00447 return; \
00448 } \
00449 }
00450
00451 #endif
00452