qofutil.h

Go to the documentation of this file.
00001 /********************************************************************\
00002  * qofutil.h -- QOF utility functions                              *
00003  *                                                                  *
00004  * This program is free software; you can redistribute it and/or    *
00005  * modify it under the terms of the GNU General Public License as   *
00006  * published by the Free Software Foundation; either version 2 of   *
00007  * the License, or (at your option) any later version.              *
00008  *                                                                  *
00009  * This program is distributed in the hope that it will be useful,  *
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00012  * GNU General Public License for more details.                     *
00013  *                                                                  *
00014  * You should have received a copy of the GNU General Public License*
00015  * along with this program; if not, contact:                        *
00016  *                                                                  *
00017  * Free Software Foundation           Voice:  +1-617-542-5942       *
00018  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00019  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
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 /* **** Prototypes *********************************************/
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 /* Replace cached string currently in 'dst' with string in 'src'.
00279  * Typical usage:
00280  *     void foo_set_name(Foo *f, const char *str) {
00281  *        CACHE_REPLACE(f->name, str);
00282  *     }
00283  * It avoids unnecessary ejection by doing INSERT before REMOVE.
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   /* See if there's a backend.  If there is, invoke it. */          \
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       /* We tried and failed to start transaction! */               \
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   /* The pricedb suffers from delayed update...     */          \
00357   /* This may be setting a bad precedent for other types, I fear. */ \
00358   /* Other types probably really should handle begin like this. */ \
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   /* See if there's a backend.  If there is, invoke it. */       \
00417   be = qof_book_get_backend ((inst)->book);                      \
00418   if (be && qof_backend_commit_exists(be))                       \
00419   {                                                              \
00420     QofBackendError errcode;                                     \
00421                                                                  \
00422     /* clear errors */                                           \
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       /* XXX Should perform a rollback here */                   \
00432       (inst)->do_free = FALSE;                                   \
00433                                                                  \
00434       /* Push error back onto the stack */                       \
00435       qof_backend_set_error (be, errcode);                       \
00436       (on_error)((inst), errcode);                               \
00437     }                                                            \
00438     /* XXX the backend commit code should clear dirty!! */       \
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 /* QOF_UTIL_H */
00452 

Generated on Fri Sep 1 15:10:40 2006 for QOF by  doxygen 1.4.7