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