QOF  0.7.5
qoferror.c
1 /*****************************************************************
2  * qoferror.c
3  *
4  * Sun Sep 10 19:55:08 2006
5  * Copyright 2006 Neil Williams
6  * linux@codehelp.co.uk
7  ****************************************************************/
8 /*
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 #include "config.h"
25 #include "qof.h"
26 #include "qoferror-p.h"
27 #include "qofsession-p.h"
28 
29 struct QofError_s
30 {
31  QofErrorId id;
32  gchar * message;
33  const gchar * filename;
34  gboolean use_file;
35  QofTime * qt;
36 };
37 
38 /* All registered errors - hashed only once per session. */
39 static GHashTable * error_table = NULL;
40 static gint32 count = 0;
41 static QofLogModule log_module = QOF_MOD_ERROR;
42 
43 void
44 qof_error_init (void)
45 {
46  error_table = g_hash_table_new (g_direct_hash, g_direct_equal);
47 #ifndef QOF_DISABLE_DEPRECATED
48  set_deprecated_errors ();
49 #endif
50 }
51 
52 static void
53 qof_error_free (QofError * error)
54 {
55  if (error->qt)
56  qof_time_free (error->qt);
57  g_free (error->message);
58  g_free (error);
59 }
60 
61 /* clear the table of registered error values */
62 static void
63 clear_table (gpointer key, gpointer value, gpointer user_data)
64 {
65  qof_error_free ((QofError*)value);
66 }
67 
68 void
69 qof_error_close (void)
70 {
71  g_hash_table_foreach (error_table, clear_table, NULL);
72  g_hash_table_destroy (error_table);
73 }
74 
75 #ifndef QOF_DISABLE_DEPRECATED
76 void
77 deprecated_support (QofErrorId id, const gchar * err_message)
78 {
79  QofError * qerr;
80 
81  if (id >= ERR_LAST)
82  return;
83  qerr = g_new0 (QofError, 1);
84  qerr->id = id;
85  qerr->message = g_strdup (err_message);
86  g_hash_table_insert (error_table, GINT_TO_POINTER(id), qerr);
87 }
88 #endif
89 
91 qof_error_register (const gchar * err_message, gboolean use_file)
92 {
93  QofError * qerr;
94 
95  ENTER (" ");
96  qerr = g_new0 (QofError, 1);
97  count++;
98 #ifndef QOF_DISABLE_DEPRECATED
99  count += ERR_LAST;
100 #endif
101  qerr->id = count;
102  if (use_file)
103  {
104  gchar * spec;
105 
106  spec = g_strrstr (err_message, "%s");
107  use_file = (spec) ? TRUE : FALSE;
108  }
109  qerr->use_file = use_file;
110  qerr->message = g_strdup (err_message);
111  g_hash_table_insert (error_table, GINT_TO_POINTER(qerr->id), qerr);
112  LEAVE (" ");
113  return qerr->id;
114 }
115 
116 void
118 {
119  QofError * qerr;
120  gboolean result;
121 
122  ENTER (" ");
123  qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(id));
124  qof_error_free (qerr);
125  result = g_hash_table_remove (error_table,
126  GINT_TO_POINTER(id));
127  if (!result)
128  LEAVE ("unable to remove registered error.");
129  LEAVE (" ok.");
130 }
131 
132 void
134 {
135  QofError * qerr, * set;
136 
137  g_return_if_fail (session);
138  if (error == QOF_SUCCESS)
139  {
140  DEBUG (" passed success, not error.");
141  return;
142  }
143  qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(error));
144  if (!qerr)
145  {
146  DEBUG (" failed hash table lookup");
147  return;
148  }
149  session->last_err = error;
150  if (session->error_message)
151  g_free (session->error_message);
152  if (qerr->use_file)
153  session->error_message = g_strdup_printf (qerr->message,
154  qof_session_get_url (session));
155  else
156  session->error_message = g_strdup (qerr->message);
157  if (!session->backend)
158  return;
159  /* create a new error for the list */
160  set = g_new0 (QofError, 1);
161  if (qerr->use_file)
162  set->message = g_strdup_printf (qerr->message,
163  qof_session_get_file_path (session));
164  else
165  set->message = g_strdup (qerr->message);
166  set->id = error;
167  set->qt = qof_time_get_current ();
168  session->backend->error_stack =
169  g_list_prepend (session->backend->error_stack, set);
170 #ifndef QOF_DISABLE_DEPRECATED
171  session->backend->last_err = error;
172 #endif
173 }
174 
175 void
176 qof_error_set_be (QofBackend * be, QofErrorId error)
177 {
178  QofError * qerr, * set;
179 
180  g_return_if_fail (be);
181  if (error == QOF_SUCCESS)
182  return;
183  qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(error));
184  if (!qerr)
185  return;
186  /* create a new error for the list */
187  set = g_new0 (QofError, 1);
188  if (qerr->use_file)
189  set->message = g_strdup_printf (qerr->message, be->fullpath);
190  else
191  set->message = g_strdup (qerr->message);
192  set->id = error;
193  set->qt = qof_time_get_current ();
194  be->error_stack = g_list_prepend (be->error_stack,
195  set);
196 #ifndef QOF_DISABLE_DEPRECATED
197  be->last_err = error;
198 #endif
199 }
200 
201 /* clear the list of actual errors */
202 static void
203 clear_list (gpointer value, gpointer user_data)
204 {
205  qof_error_free ((QofError*)value);
206 }
207 
208 void
210 {
211  g_return_if_fail (session);
212  if (!session->backend)
213  return;
214  g_list_foreach (session->backend->error_stack, clear_list, NULL);
215  g_list_free (session->backend->error_stack);
216  session->backend->error_stack = NULL;
217  if (session->error_message)
218  g_free (session->error_message);
219  session->error_message = NULL;
220  session->last_err = QOF_SUCCESS;
221 #ifndef QOF_DISABLE_DEPRECATED
222  session->backend->last_err = QOF_SUCCESS;
223 #endif
224 }
225 
228 {
229  g_return_val_if_fail (session, QOF_FATAL);
230  return qof_error_check_be (session->backend);
231 }
232 
235 {
236  QofError * qerr;
237  GList * first;
238 
239  if (!be)
240  return QOF_FATAL;
241  if (g_list_length (be->error_stack) == 0)
242  return QOF_SUCCESS;
243  first = g_list_first (be->error_stack);
244  qerr = (QofError*)first->data;
245  if (!qerr)
246  return QOF_FATAL;
247  return qerr->id;
248 }
249 
250 QofTime *
252 {
253  QofError * qerr;
254  GList * first;
255 
256  if (g_list_length(be->error_stack) == 0)
257  return NULL;
258  first = g_list_first (be->error_stack);
259  qerr = (QofError*)first->data;
260  return qerr->qt;
261 }
262 
263 QofTime *
265 {
266  return qof_error_get_time_be (session->backend);
267 }
268 
269 #ifndef QOF_DISABLE_DEPRECATED
270 static void
271 set_previous_error (QofBackend * be)
272 {
273  QofError * qerr;
274  GList * pop;
275 
276  if (!be)
277  return;
278  if (g_list_length(be->error_stack) == 0)
279  return;
280  pop = g_list_last (be->error_stack);
281  qerr = (QofError*)pop->data;
282  be->last_err = qerr->id;
283  be->error_msg = qerr->message;
284 }
285 #endif
286 
289 {
290  QofErrorId id;
291 
292  g_return_val_if_fail (session, QOF_FATAL);
293  id = QOF_SUCCESS;
294  id = qof_error_get_id_be (session->backend);
295  {
296  QofError * qerr;
297 
298  qerr = g_hash_table_lookup (error_table,
299  GINT_TO_POINTER(id));
300  if (!qerr)
301  {
302  DEBUG (" empty QofError value");
303  return QOF_FATAL;
304  }
305  if (session->error_message)
306  g_free (session->error_message);
307  session->error_message = qerr->message;
308  session->last_err = id;
309  }
310  return id;
311 }
312 
315 {
316  QofError * qerr;
317  GList * first;
318 
319  if (!be)
320  return QOF_FATAL;
321  if (g_list_length (be->error_stack) == 0)
322  return QOF_SUCCESS;
323  first = g_list_first (be->error_stack);
324  qerr = (QofError*)first->data;
325  if (!qerr)
326  return QOF_FATAL;
327  be->error_stack =
328  g_list_remove (be->error_stack, qerr);
329 #ifndef QOF_DISABLE_DEPRECATED
330  set_previous_error (be);
331 #endif
332  return qerr->id;
333 }
334 
335 const gchar *
337 {
338  const gchar * msg;
339 
340  g_return_val_if_fail (session, NULL);
341  if (!session->backend)
342  return session->error_message;
343  msg = qof_error_get_message_be (session->backend);
344  DEBUG (" msg_1=%s", msg);
345 #ifndef QOF_DISABLE_DEPRECATED
346  {
347  QofError * qerr;
348 
349  qerr = g_hash_table_lookup (error_table,
350  GINT_TO_POINTER(session->backend->last_err));
351  if (qerr)
352  {
353  if (session->error_message)
354  g_free (session->error_message);
355  session->error_message = g_strdup(msg);
356  session->last_err = qerr->id;
357  }
358  }
359 #endif
360  return msg;
361 }
362 
363 const gchar *
365 {
366  QofError * qerr;
367  GList * first;
368 
369  g_return_val_if_fail (be, NULL);
370  if (g_list_length (be->error_stack) == 0)
371  {
372  DEBUG (" empty error stack");
373  return NULL;
374  }
375  first = g_list_first (be->error_stack);
376  qerr = (QofError*)first->data;
377  if (!qerr)
378  {
379  DEBUG (" empty QofError value");
380  return NULL;
381  }
382  DEBUG (" qerr->message=%s", qerr->message);
383  be->error_stack =
384  g_list_remove (be->error_stack, qerr);
385 #ifndef QOF_DISABLE_DEPRECATED
386  be->error_msg = qerr->message;
387  set_previous_error (be);
388 #endif
389  return qerr->message;
390 }