1 /********************************************************************\
2  * qof-util.h -- QOF utility functions                              *
3  *                                                                  *
4  * This program is free software; you can redistribute it and/or    *
5  * modify it under the terms of the GNU General Public License as   *
6  * published by the Free Software Foundation; either version 2 of   *
7  * the License, or (at your option) any later version.              *
8  *                                                                  *
9  * This program is distributed in the hope that it will be useful,  *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
12  * GNU General Public License for more details.                     *
13  *                                                                  *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact:                        *
16  *                                                                  *
17  * Free Software Foundation           Voice:  +1-617-542-5942       *
18  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
19  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
20 \********************************************************************/
21 
22 /** @addtogroup Utilities
23     @{ */
24 /** @file qofutil.h
25     @brief QOF utility functions
26     @author Copyright (C) 1997 Robin D. Clark <rclark@cs.hmc.edu>
27     @author Copyright (C) 2000 Bill Gribble <grib@billgribble.com>
28     @author Copyright (C) 1997-2002,2004 Linas Vepstas <linas@linas.org>
29     @author Copyright 2006  Neil Williams  <linux@codehelp.co.uk>
30 */
31 
32 #ifndef QOF_UTIL_H
33 #define QOF_UTIL_H
34 
35 #ifdef __cplusplus
36 extern "C"
37 {
38 #endif
39 
40 #include <stddef.h>
41 #include "qof.h"
42 #include "qoflog.h"
43 #include "qofutil.h"
44 #include "qofbackend.h"
45 #include "qofclass.h"
46 #include "qofbook.h"
47 #include "qofinstance.h"
48 
49 /** Do not use these for printf, only scanf */
50 #if HAVE_SCANF_LLD
51 # define QOF_SCANF_LLD "%lld"
52 #else
53 # if HAVE_SCANF_QD
54 #  define QOF_SCANF_LLD "%qd"
55 # else
56 #  if HAVE_SCANF_I64D
57 #   define QOF_SCANF_LLD "%I64d"
58 #  else
59 #   error "No scanf format string is known for LLD. Fix your ./configure so that the correct one is detected!"
60 #  endif
61 # endif
62 #endif
63 
64 #define QOF_MOD_UTIL "qof.utilities"
65 
66 /** \name typedef enum as string macros
67 @{
68 */
69 #define ENUM_BODY(name, value)           \
70     name value,
71 
72 #define AS_STRING_CASE(name, value)      \
73     case name: { return #name; }
74 
75 #define FROM_STRING_CASE(name, value)    \
76     if (strcmp(str, #name) == 0) {       \
77         return name;  }
78 
79 #define DEFINE_ENUM(name, list)          \
80     typedef enum {                       \
81         list(ENUM_BODY)                  \
82     }name;
83 
84 #define AS_STRING_DEC(name, list)        \
85     const gchar* name##asString(name n);
86 
87 #define AS_STRING_FUNC(name, list)        \
88     const gchar* name##asString(name n) { \
89         switch (n) {                      \
90             list(AS_STRING_CASE)          \
91             default: return "";  } }
92 
93 #define FROM_STRING_DEC(name, list)      \
94     name name##fromString                \
95     (const gchar* str);
96 
97 #define FROM_STRING_FUNC(name, list)     \
98     name name##fromString                \
99     (const gchar* str) {                 \
100     if(str == NULL) { return 0; }        \
101         list(FROM_STRING_CASE)           \
102         return 0;  }
103 
104 /** @} */
105 
106 /** \name enum as string with no typedef
107 @{
108 
109   Similar but used when the enum is NOT a typedef
110   Make sure you use the DEFINE_ENUM_NON_TYPEDEF macro.
111 
112  You can precede the FROM_STRING_FUNC_NON_TYPEDEF
113  and AS_STRING_FUNC_NON_TYPEDEF macros with the
114  keyword static if appropriate.
115 
116  ENUM_BODY is used in both types.
117  */
118 
119 #define DEFINE_ENUM_NON_TYPEDEF(name, list)   \
120     enum name {                               \
121         list(ENUM_BODY)                       \
122     };
123 
124 #define FROM_STRING_DEC_NON_TYPEDEF(name, list)   \
125    void name##fromString                          \
126    (const gchar* str, enum name *type);
127 
128 #define FROM_STRING_CASE_NON_TYPEDEF(name, value) \
129    if (strcmp(str, #name) == 0) { *type = name; }
130 
131 #define FROM_STRING_FUNC_NON_TYPEDEF(name, list)  \
132    void name##fromString                          \
133    (const gchar* str, enum name *type) {          \
134    if(str == NULL) { return; }                    \
135     list(FROM_STRING_CASE_NON_TYPEDEF) }
136 
137 #define AS_STRING_DEC_NON_TYPEDEF(name, list)     \
138    const gchar* name##asString(enum name n);
139 
140 #define AS_STRING_FUNC_NON_TYPEDEF(name, list)    \
141    const gchar* name##asString(enum name n) {     \
142        switch (n) {                               \
143            list(AS_STRING_CASE_NON_TYPEDEF)       \
144            default: return ""; } }
145 
146 #define AS_STRING_CASE_NON_TYPEDEF(name, value)   \
147    case name: { return #name; }
148 
149 /** @} */
150 
151 /** @name Convenience wrappers
152    @{
153 */
154 
155 /** \brief Initialise the Query Object Framework
156 
157 Use in place of separate init functions (like qof_query_init(),
158 etc.) to protect against future changes.
159 */
160 void qof_init (void);
161 
162 /** \brief Safely close down the Query Object Framework
163 
164 Use in place of separate close / shutdown functions
165 (like qof_query_shutdown(), etc.) to protect
166 against future changes.
167 */
168 void qof_close (void);
169 
170 /** @} */
171 
172 /* **** Prototypes *********************************************/
173 
174 /** Calls the given function for each of the key/value pairs in the
175  *  GHashTable in an order determined by the GCompareFunc applied to
176  *  the keys. The function is passed the key and value of each pair,
177  *  and the given user_data parameter. */
178 void g_hash_table_foreach_sorted(GHashTable *hash_table, GHFunc func, gpointer user_data, GCompareFunc compare_func);
179 
180 /** Search for an occurrence of the substring needle in the string
181  * haystack, ignoring case. Return TRUE if one is found or FALSE
182  * otherwise. */
183 gboolean qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle);
184 
185 /** case sensitive comparison of strings da and db - either
186 may be NULL. A non-NULL string is greater than a NULL string.
187 
188  @param da string 1.
189  @param db string 2.
190 
191  @return If da == NULL && db != NULL, returns -1.
192          If da != NULL && db == NULL, returns +1.
193          If da != NULL && db != NULL, returns the result of
194                    strcmp(da, db).
195          If da == NULL && db == NULL, returns 0.
196 */
197 gint safe_strcasecmp (const gchar * da, const gchar * db);
198 
199 /** The null_strcmp compares strings a and b the same way that strcmp()
200  * does, except that either may be null.  This routine assumes that
201  * a null string is equal to the empty string.
202  */
203 gint null_strcmp (const gchar * da, const gchar * db);
204 
205 /** The ultostr() subroutine is the inverse of strtoul(). It accepts a
206  * number and prints it in the indicated base.  The returned string
207  * should be g_freed when done.  */
208 gchar * ultostr (gulong val, gint base);
209 
210 /** Returns true if string s is a number, possibly surrounded by
211  * whitespace. */
212 gboolean gnc_strisnum(const gchar *s);
213 
214 #ifndef HAVE_STPCPY
215 #define stpcpy g_stpcpy
216 #endif
217 
218 /** begin_edit
219  *
220  * @param  inst: an instance of QofInstance
221  *
222  * The caller should use this macro first and then perform any other operations.
223  */
224 gboolean qof_begin_edit(QofInstance *inst);
225 
226 /**
227  * commit_edit helpers
228  *
229  * The caller should call PART1 as the first thing, then
230  * perform any local operations prior to calling the backend.
231  * Then call PART2.
232  */
233 
234 /**
235  * part1 -- deal with the editlevel
236  *
237  * @param inst: an instance of QofInstance
238  */
239 gboolean qof_commit_edit(QofInstance *inst);
240 
241 /**
242  * part2 -- deal with the backend
243  *
244  * @param inst: an instance of QofInstance
245  * @param on_error: a function called if there is a backend error.
246  *                void (*on_error)(inst, QofBackendError)
247  * @param on_done: a function called after the commit is completed
248  *                successfully for an object which remained valid.
249  *                void (*on_done)(inst)
250  * @param on_free: a function called if the commit succeeded and the instance
251  *                 is to be freed.
252  *                void (*on_free)(inst)
253  *
254  * Note that only *one* callback will be called (or zero, if that
255  * callback is NULL).  In particular, 'on_done' will not be called for
256  * an object which is to be freed.
257  *
258  * Returns TRUE, if the commit succeeded, FALSE otherwise.
259  */
260 gboolean
261 qof_commit_edit_part2(QofInstance *inst,
262                       void (*on_error)(QofInstance *, QofBackendError),
263                       void (*on_done)(QofInstance *),
264                       void (*on_free)(QofInstance *));
265 
266 #ifdef __cplusplus
267 }
268 #endif
269 
270 #endif /* QOF_UTIL_H */
271 /** @} */
272