QOF  0.7.5
deprecated.c
1 /* *****************************************************************\
2  * deprecated.c -- QOF deprecated function replacements *
3  * Copyright (c) 2005 Neil Williams <linux@codehelp.co.uk> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22 \********************************************************************/
23 
24 #include "config.h"
25 #ifndef QOF_DISABLE_DEPRECATED
26 
27 /* keep the deprecated functions close to the originals -
28 including use of localtime - that's why these are deprecated! */
29 #include <stdlib.h>
30 #include <ctype.h>
31 #include <sys/time.h>
32 
33 #ifdef HAVE_LANGINFO_H
34 #define HAVE_LANGINFO_D_FMT 1
35 #include <langinfo.h>
36 #endif
37 #ifdef HAVE_LANGINFO_D_FMT
38 # define QOF_D_FMT (nl_langinfo (D_FMT))
39 # define QOF_D_T_FMT (nl_langinfo (D_T_FMT))
40 # define QOF_T_FMT (nl_langinfo (T_FMT))
41 #else
42 # define QOF_D_FMT "%F"
43 # define QOF_D_T_FMT "%F %r"
44 # define QOF_T_FMT "%i"
45 #endif
46 
47 #include <glib.h>
48 #include <libintl.h>
49 #define _(String) dgettext (GETTEXT_PACKAGE, String)
50 #include "qof.h"
51 #include "qofsession-p.h"
52 #include "qoferror-p.h"
53 
54 static QofLogModule log_module = "deprecated";
55 static FILE *fout = NULL;
56 
57 /* Don't be fooled: gnc_trace_num_spaces has external linkage and
58  static storage, but can't be defined with 'extern' because it has
59  an initializer, and can't be declared with 'static' because that
60  would give it internal linkage. (this is why it is deprecated) */
61 gint __attribute__ ((unused)) gnc_trace_num_spaces = 0;
62 void
63 gnc_log_init (void)
64 {
65  qof_log_init ();
66 }
67 
68 void
69 gnc_set_log_level (QofLogModule log_module, gncLogLevel level)
70 {
71  qof_log_set_level (log_module, (QofLogLevel) level);
72 }
73 
74 void
75 gnc_set_log_level_global (gncLogLevel level)
76 {
78 }
79 
80 void
81 qof_log_set_level_global (QofLogLevel level)
82 {
84 }
85 
86 void
87 gnc_set_logfile (FILE * outfile)
88 {
89  qof_log_set_file (outfile);
90 }
91 const char *
92 gnc_log_prettify (const char *name)
93 {
94  return qof_log_prettify (name);
95 }
96 
97 void
98 gnc_start_clock (int a __attribute__ ((unused)),
99  QofLogModule b __attribute__ ((unused)),
100  gncLogLevel c __attribute__ ((unused)),
101  const char *d __attribute__ ((unused)),
102  const char *e __attribute__ ((unused)), ...)
103 {
104 }
105 void
106 gnc_report_clock (int a __attribute__ ((unused)),
107  QofLogModule b __attribute__ ((unused)),
108  gncLogLevel c __attribute__ ((unused)),
109  const char *d __attribute__ ((unused)),
110  const char *e __attribute__ ((unused)), ...)
111 {
112 }
113 void
114 gnc_report_clock_total (int a __attribute__ ((unused)),
115  QofLogModule b __attribute__ ((unused)),
116  gncLogLevel c __attribute__ ((unused)),
117  const char *d __attribute__ ((unused)),
118  const char *e __attribute__ ((unused)), ...)
119 {
120 }
121 
122 gboolean
123 gnc_should_log (QofLogModule log_module, gncLogLevel log_level)
124 {
125  return qof_log_check (log_module, log_level);
126 }
127 
128 gint
129 gnc_engine_register_event_handler (GNCEngineEventHandler handler,
130  gpointer user_data)
131 {
132  return qof_event_register_old_handler (handler, user_data);
133 }
134 
135 void
136 gnc_engine_unregister_event_handler (gint handler_id)
137 {
138  qof_event_unregister_handler (handler_id);
139 }
140 
141 void
142 gnc_engine_suspend_events (void)
143 {
145 }
146 
147 void
148 gnc_engine_resume_events (void)
149 {
150  qof_event_resume ();
151 }
152 
153 void
154 gnc_engine_gen_event (QofEntity * entity, GNCEngineEventType event_type)
155 {
156  qof_event_gen (entity, event_type, NULL);
157 }
158 
160 qof_book_mergeInit (QofBook * importBook, QofBook * targetBook)
161 {
162  return qof_book_merge_init (importBook, targetBook);
163 }
164 
166 qof_book_mergeUpdateResult (QofBookMergeData * mergeData,
167  QofBookMergeResult tag)
168 {
169  return qof_book_merge_update_result (mergeData, tag);
170 }
171 
172 gint
173 qof_book_mergeCommit (QofBookMergeData * mergeData)
174 {
175  return qof_book_merge_commit (mergeData);
176 }
177 
178 void
179 qof_book_mergeRuleForeach (QofBookMergeData * mergeData,
181 {
182  qof_book_merge_rule_foreach (mergeData, cb, mergeResult);
183 }
184 
185 gpointer
186 gnc_string_cache_insert (gconstpointer key)
187 {
188  return qof_util_string_cache_insert (key);
189 }
190 
191 gchar *
192 gnc_stpcpy (gchar * dest, const gchar * src)
193 {
194  return g_stpcpy (dest, src);
195 }
196 
197 GCache *
198 gnc_engine_get_string_cache (void)
199 {
200  return qof_util_get_string_cache ();
201 }
202 
203 void
204 gnc_engine_string_cache_destroy (void)
205 {
207 }
208 
209 void
210 gnc_string_cache_remove (gconstpointer key)
211 {
213 }
214 
215 gboolean
216 gnc_date_string_to_dateformat (const gchar * format_string,
217  QofDateFormat * format)
218 {
219  QofDateFormat df;
220 
221  df = qof_date_format_from_name (format_string);
222  if (df < 0)
223  return TRUE;
224  *format = df;
225  return FALSE;
226 }
227 
228 gboolean
229 gnc_date_string_to_monthformat (const gchar * format_string,
230  GNCDateMonthFormat * format)
231 {
232  if (!format_string)
233  return TRUE;
234 
235  if (!strcmp (format_string, "number"))
236  *format = GNCDATE_MONTH_NUMBER;
237  else if (!strcmp (format_string, "abbrev"))
238  *format = GNCDATE_MONTH_ABBREV;
239  else if (!strcmp (format_string, "name"))
240  *format = GNCDATE_MONTH_NAME;
241  else
242  return TRUE;
243 
244  return FALSE;
245 }
246 static inline QofTime *
247 timespecToQofTime (Timespec ts)
248 {
249  QofTime *time;
250 
251  time = qof_time_new ();
252  qof_time_set_secs (time, ts.tv_sec);
253  qof_time_set_nanosecs (time, ts.tv_nsec);
254  return time;
255 }
256 static inline Timespec
257 qof_time_to_Timespec (QofTime * time)
258 {
259  Timespec ts;
260 
261  ts.tv_sec = qof_time_get_secs (time);
262  ts.tv_nsec = qof_time_get_nanosecs (time);
263  return ts;
264 }
265 static inline Timespec
266 null_timespec (void)
267 {
268  Timespec ts;
269 
270  ts.tv_sec = 0;
271  ts.tv_nsec = 0;
272  return ts;
273 }
274 
275 gboolean
276 timespec_equal (const Timespec * ta, const Timespec * tb)
277 {
278  QofTime *qta, *qtb;
279  gboolean retval;
280 
281  qta = timespecToQofTime (*ta);
282  qtb = timespecToQofTime (*tb);
283  retval = qof_time_equal (qta, qtb);
284  qof_time_free (qta);
285  qof_time_free (qtb);
286  return retval;
287 }
288 
289 gint
290 timespec_cmp (const Timespec * ta, const Timespec * tb)
291 {
292  QofTime *qta, *qtb;
293  gint retval;
294 
295  qta = timespecToQofTime (*ta);
296  qtb = timespecToQofTime (*tb);
297  retval = qof_time_cmp (qta, qtb);
298  qof_time_free (qta);
299  qof_time_free (qtb);
300  return retval;
301 }
302 
303 void
304 timespecFromTime_t (Timespec * ts, time_t t)
305 {
306  QofTime *time;
307 
308  time = qof_time_new ();
309  time = qof_time_from_time_t (t, 0);
310  *ts = qof_time_to_Timespec (time);
311  qof_time_free (time);
312 }
313 
314 time_t
315 timespecToTime_t (Timespec ts)
316 {
317  return ts.tv_sec;
318 }
319 
320 Timespec
321 timespec_diff (const Timespec * ta, const Timespec * tb)
322 {
323  Timespec ts;
324  QofTime *qta, *qtb, *qt;
325 
326  qta = timespecToQofTime (*ta);
327  qtb = timespecToQofTime (*tb);
328  qt = qof_time_diff (qta, qtb);
329  ts = qof_time_to_Timespec (qt);
330  qof_time_free (qta);
331  qof_time_free (qtb);
332  qof_time_free (qt);
333  return ts;
334 }
335 
336 Timespec
337 timespec_abs (const Timespec * t)
338 {
339  Timespec ts;
340  QofTime *qt = timespecToQofTime (*t);
341  qof_time_abs (qt);
342  ts = qof_time_to_Timespec (qt);
343  qof_time_free (qt);
344  return ts;
345 }
346 
347 Timespec
348 timespecCanonicalDayTime (Timespec t)
349 {
350  struct tm tm, *result;
351  Timespec retval;
352 
353  time_t t_secs = t.tv_sec + (t.tv_nsec / QOF_NSECS);
354  result = localtime(&t_secs);
355  tm = *result;
356  gnc_tm_set_day_middle(&tm);
357  retval.tv_sec = mktime(&tm);
358  retval.tv_nsec = 0;
359  return retval;
360 }
361 
362 time_t
363 qof_date_dmy_to_sec (gint day, gint month, gint year)
364 {
365  QofTime *qt;
366  QofDate *qd;
367  time_t retval;
368 
369  qd = qof_date_new ();
370  qd->qd_mday = day;
371  qd->qd_mon = month;
372  qd->qd_year = year;
373  qt = qof_date_to_qtime (qd);
374  retval = qof_time_get_secs (qt);
375  qof_time_free (qt);
376  qof_date_free (qd);
377  return retval;
378 }
379 
380 size_t
381 qof_print_hours_elapsed_buff (char *buff, size_t len, int secs,
382  gboolean show_secs)
383 {
384  size_t flen;
385  if (0 <= secs)
386  {
387  if (show_secs)
388  {
389  flen = g_snprintf (buff, len,
390  "%02d:%02d:%02d", (int) (secs / 3600),
391  (int) ((secs % 3600) / 60), (int) (secs % 60));
392  }
393  else
394  {
395  flen = g_snprintf (buff, len,
396  "%02d:%02d", (int) (secs / 3600),
397  (int) ((secs % 3600) / 60));
398  }
399  }
400  else
401  {
402  if (show_secs)
403  {
404  flen = g_snprintf (buff, len,
405  "-%02d:%02d:%02d", (int) (-secs / 3600),
406  (int) ((-secs % 3600) / 60), (int) (-secs % 60));
407  }
408  else
409  {
410  flen = g_snprintf (buff, len,
411  "-%02d:%02d", (int) (-secs / 3600),
412  (int) ((-secs % 3600) / 60));
413  }
414  }
415  return flen;
416 }
417 
418 size_t
419 qof_print_minutes_elapsed_buff (char *buff, size_t len, int secs,
420  gboolean show_secs)
421 {
422  size_t flen;
423  if (0 <= secs)
424  {
425  if (show_secs)
426  {
427  flen = g_snprintf (buff, len,
428  "%02d:%02d", (int) (secs / 60), (int) (secs % 60));
429  }
430  else
431  {
432  flen = g_snprintf (buff, len, "%02d", (int) (secs / 60));
433  }
434  }
435  else
436  {
437  if (show_secs)
438  {
439  flen = g_snprintf (buff, len,
440  "-%02d:%02d", (int) (-secs / 60), (int) (-secs % 60));
441  }
442  else
443  {
444  flen = g_snprintf (buff, len, "-%02d", (int) (-secs / 60));
445  }
446  }
447  return flen;
448 }
449 
450 size_t
451 qof_print_date_time_buff (char *buff, size_t len, time_t secs)
452 {
453  int flen;
454  int day, month, year, hour, min, sec;
455  struct tm ltm, gtm;
456 
457  if (!buff)
458  return 0;
459  ltm = *localtime (&secs);
460  day = ltm.tm_mday;
461  month = ltm.tm_mon + 1;
462  year = ltm.tm_year + 1900;
463  hour = ltm.tm_hour;
464  min = ltm.tm_min;
465  sec = ltm.tm_sec;
466  switch (qof_date_format_get_current ())
467  {
468  case QOF_DATE_FORMAT_UK:
469  flen =
470  g_snprintf (buff, len, "%2d/%2d/%-4d %2d:%02d", day, month,
471  year, hour, min);
472  break;
473  case QOF_DATE_FORMAT_CE:
474  flen =
475  g_snprintf (buff, len, "%2d.%2d.%-4d %2d:%02d", day, month,
476  year, hour, min);
477  break;
478  case QOF_DATE_FORMAT_ISO:
479  flen =
480  g_snprintf (buff, len, "%04d-%02d-%02d %02d:%02d", year, month,
481  day, hour, min);
482  break;
483  case QOF_DATE_FORMAT_UTC:
484  {
485  gtm = *gmtime (&secs);
486  flen = strftime (buff, len, QOF_UTC_DATE_FORMAT, &gtm);
487  break;
488  }
490  {
491  flen = strftime (buff, len, QOF_D_T_FMT, &ltm);
492  }
493  break;
494 
495  case QOF_DATE_FORMAT_US:
496  default:
497  flen =
498  g_snprintf (buff, len, "%2d/%2d/%-4d %2d:%02d", month, day,
499  year, hour, min);
500  break;
501  }
502  return flen;
503 }
504 
505 size_t
506 qof_print_time_buff (gchar * buff, size_t len, time_t secs)
507 {
508  gint flen;
509  struct tm ltm, gtm;
510 
511  if (!buff)
512  return 0;
514  {
515  gtm = *gmtime (&secs);
516  flen = strftime (buff, len, QOF_UTC_DATE_FORMAT, &gtm);
517  return flen;
518  }
519  ltm = *localtime (&secs);
520  flen = strftime (buff, len, QOF_T_FMT, &ltm);
521 
522  return flen;
523 }
524 
525 gboolean
526 qof_is_same_day (time_t ta, time_t tb)
527 {
528  struct tm lta, ltb;
529  lta = *localtime (&ta);
530  ltb = *localtime (&tb);
531  if (lta.tm_year == ltb.tm_year)
532  {
533  return (ltb.tm_yday - lta.tm_yday);
534  }
535  return (ltb.tm_year - lta.tm_year)*365; /* very approximate */
536 }
537 
538 void
539 gnc_tm_set_day_start (struct tm *tm)
540 {
541  tm->tm_hour = 0;
542  tm->tm_min = 0;
543  tm->tm_sec = 0;
544  tm->tm_isdst = -1;
545 }
546 
547 void
548 gnc_tm_get_day_start (struct tm *tm, time_t time_val)
549 {
550  tm = localtime_r (&time_val, tm);
551  gnc_tm_set_day_start (tm);
552 }
553 
554 void
555 gnc_tm_set_day_middle (struct tm *tm)
556 {
557  tm->tm_hour = 12;
558  tm->tm_min = 0;
559  tm->tm_sec = 0;
560  tm->tm_isdst = -1;
561 }
562 
563 void
564 gnc_tm_set_day_end (struct tm *tm)
565 {
566  tm->tm_hour = 23;
567  tm->tm_min = 59;
568  tm->tm_sec = 59;
569  tm->tm_isdst = -1;
570 }
571 
572 void
573 gnc_tm_get_day_end (struct tm *tm, time_t time_val)
574 {
575  tm = localtime_r (&time_val, tm);
576  gnc_tm_set_day_end (tm);
577 }
578 
579 time_t
580 gnc_timet_get_day_start (time_t time_val)
581 {
582  struct tm tm;
583 
584  gnc_tm_get_day_start (&tm, time_val);
585  return mktime (&tm);
586 }
587 
588 time_t
589 gnc_timet_get_day_end (time_t time_val)
590 {
591  struct tm tm;
592 
593  gnc_tm_get_day_end (&tm, time_val);
594  return mktime (&tm);
595 }
596 
597 #ifndef GNUCASH_MAJOR_VERSION
598 time_t
599 gnc_timet_get_day_start_gdate (GDate * date)
600 {
601  struct tm stm;
602  time_t secs;
603 
604  stm.tm_year = g_date_get_year (date) - 1900;
605  stm.tm_mon = g_date_get_month (date) - 1;
606  stm.tm_mday = g_date_get_day (date);
607  gnc_tm_set_day_start (&stm);
608  secs = mktime (&stm);
609  return secs;
610 }
611 
612 time_t
613 gnc_timet_get_day_end_gdate (GDate * date)
614 {
615  struct tm stm;
616  time_t secs;
617 
618  stm.tm_year = g_date_get_year (date) - 1900;
619  stm.tm_mon = g_date_get_month (date) - 1;
620  stm.tm_mday = g_date_get_day (date);
621  gnc_tm_set_day_end (&stm);
622  secs = mktime (&stm);
623  return secs;
624 }
625 #endif
626 int
627 gnc_date_my_last_mday (int month, int year)
628 {
629  return g_date_get_days_in_month (month, year);
630 }
631 
632 int
633 date_get_last_mday (struct tm *tm)
634 {
635  return g_date_get_days_in_month (tm->tm_mon + 1, tm->tm_year + 1900);
636 }
637 
638 gboolean
639 date_is_last_mday (struct tm * tm)
640 {
641  return (tm->tm_mday ==
642  g_date_get_days_in_month (tm->tm_mon + 1, tm->tm_year + 1900));
643 }
644 
645 int
646 gnc_timespec_last_mday (Timespec t)
647 {
648  /* Replacement code should not use localtime */
649  struct tm *result;
650  time_t t_secs = t.tv_sec + (t.tv_nsec / QOF_NSECS);
651  result = localtime (&t_secs);
652  return date_get_last_mday (result);
653 }
654 
655 void
656 gnc_tm_get_today_start (struct tm *tm)
657 {
658  gnc_tm_get_day_start (tm, time (NULL));
659 }
660 
661 void
662 gnc_tm_get_today_end (struct tm *tm)
663 {
664  gnc_tm_get_day_end (tm, time (NULL));
665 }
666 
667 time_t
668 gnc_timet_get_today_start (void)
669 {
670  struct tm tm;
671 
672  gnc_tm_get_day_start (&tm, time (NULL));
673  return mktime (&tm);
674 }
675 
676 time_t
677 gnc_timet_get_today_end (void)
678 {
679  struct tm tm;
680 
681  gnc_tm_get_day_end (&tm, time (NULL));
682  return mktime (&tm);
683 }
684 
685 char *
686 xaccDateUtilGetStamp (time_t thyme)
687 {
688  struct tm *stm;
689 
690  stm = localtime (&thyme);
691  return g_strdup_printf ("%04d%02d%02d%02d%02d%02d",
692  (stm->tm_year + 1900),
693  (stm->tm_mon + 1),
694  stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec);
695 }
696 
697 size_t
698 qof_print_date_dmy_buff (char *buff, size_t len, int day, int month,
699  int year)
700 {
701  int flen;
702  if (!buff)
703  return 0;
704  switch (qof_date_format_get_current ())
705  {
706  case QOF_DATE_FORMAT_UK:
707  flen = g_snprintf (buff, len, "%2d/%2d/%-4d", day, month, year);
708  break;
709  case QOF_DATE_FORMAT_CE:
710  flen = g_snprintf (buff, len, "%2d.%2d.%-4d", day, month, year);
711  break;
713  {
714  struct tm tm_str;
715  time_t t;
716  tm_str.tm_mday = day;
717  tm_str.tm_mon = month - 1;
718  tm_str.tm_year = year - 1900;
719  gnc_tm_set_day_start (&tm_str);
720  t = mktime (&tm_str);
721  localtime_r (&t, &tm_str);
722  flen = strftime (buff, len, QOF_D_FMT, &tm_str);
723  if (flen != 0)
724  break;
725  }
726  case QOF_DATE_FORMAT_ISO:
727  case QOF_DATE_FORMAT_UTC:
728  flen = g_snprintf (buff, len, "%04d-%02d-%02d", year, month, day);
729  break;
730  case QOF_DATE_FORMAT_US:
731  default:
732  flen = g_snprintf (buff, len, "%2d/%2d/%-4d", month, day, year);
733  break;
734  }
735  return flen;
736 }
737 
738 size_t
739 qof_print_date_buff (char *buff, size_t len, time_t t)
740 {
741  struct tm *theTime;
742  if (!buff)
743  return 0;
744  theTime = localtime (&t);
745  return qof_print_date_dmy_buff (buff, len,
746  theTime->tm_mday, theTime->tm_mon + 1, theTime->tm_year + 1900);
747 }
748 
749 size_t
750 qof_print_gdate (gchar * buf, size_t len __attribute__ ((unused)),
751  GDate * gd)
752 {
753  QofDateFormat df;
754  QofDate *qd;
755  gchar *str;
756 
758  qd = qof_date_from_gdate (gd);
759  str = qof_date_print (qd, df);
760  qof_date_free (qd);
761  g_stpcpy (buf, str);
762  g_free (str);
763  return strlen (buf);
764 }
765 
766 gchar *
767 qof_print_date (time_t t)
768 {
769  QofDateFormat df;
770  QofTime *time;
771  gchar *str;
772 
774  time = qof_time_from_time_t (t, 0);
775  str = qof_date_print (qof_date_from_qtime (time), df);
776  qof_time_free (time);
777  return str;
778 }
779 const gchar *
780 gnc_print_date (Timespec ts)
781 {
782  static gchar buff[MAX_DATE_LENGTH];
783  QofDateFormat df;
784  QofTime *time;
785  gchar *str;
786 
788  ENTER (" using date format %d", df);
789  time = timespecToQofTime (ts);
790  str = qof_date_print (qof_date_from_qtime (time), df);
791  qof_time_free (time);
792  g_stpcpy (buff, str);
793  g_free (str);
794  LEAVE (" printing %s", buff);
795  return buff;
796 }
797 
798 /* This is now user configured through the gnome options system() */
799 static QofDateFormat dateFormat = QOF_DATE_FORMAT_LOCALE;
800 static QofDateFormat prevQofDateFormat = QOF_DATE_FORMAT_LOCALE;
801 
802 static gboolean
803 qof_scan_date_internal (const char *buff, int *day, int *month, int *year,
804  QofDateFormat which_format)
805 {
806  char *dupe, *tmp, *first_field, *second_field, *third_field;
807  int iday, imonth, iyear;
808  struct tm *now, utc;
809  time_t secs;
810 
811  if (!buff) return(FALSE);
812 
813  if(which_format == QOF_DATE_FORMAT_UTC)
814  {
815  if(strptime(buff, QOF_UTC_DATE_FORMAT, &utc)) {
816  *day = utc.tm_mday;
817  *month = utc.tm_mon + 1;
818  *year = utc.tm_year + 1900;
819  return TRUE;
820  }
821  else { return FALSE; }
822  }
823  dupe = g_strdup (buff);
824 
825  tmp = dupe;
826  first_field = NULL;
827  second_field = NULL;
828  third_field = NULL;
829 
830  /* Use strtok to find delimiters */
831  if (tmp) {
832  static char *delims = ".,-+/\\() ";
833 
834  first_field = strtok (tmp, delims);
835  if (first_field) {
836  second_field = strtok (NULL, delims);
837  if (second_field) {
838  third_field = strtok (NULL, delims);
839  }
840  }
841  }
842 
843  /* If any fields appear to be blank, use today's date */
844  time (&secs);
845  now = localtime (&secs);
846  iday = now->tm_mday;
847  imonth = now->tm_mon+1;
848  iyear = now->tm_year+1900;
849 
850  /* get numeric values */
851  switch (which_format)
852  {
854  if (buff[0] != '\0')
855  {
856  struct tm thetime;
857 
858  /* Parse time string. */
859  memset(&thetime, -1, sizeof(struct tm));
860  strptime (buff, QOF_D_FMT, &thetime);
861 
862  if (third_field) {
863  /* Easy. All three values were parsed. */
864  iyear = thetime.tm_year + 1900;
865  iday = thetime.tm_mday;
866  imonth = thetime.tm_mon + 1;
867  } else if (second_field) {
868  /* Hard. Two values parsed. Figure out the ordering. */
869  if (thetime.tm_year == -1) {
870  /* %m-%d or %d-%m. Don't care. Already parsed correctly. */
871  iday = thetime.tm_mday;
872  imonth = thetime.tm_mon + 1;
873  } else if (thetime.tm_mon != -1) {
874  /* Must be %Y-%m-%d. Reparse as %m-%d.*/
875  imonth = atoi(first_field);
876  iday = atoi(second_field);
877  } else {
878  /* Must be %Y-%d-%m. Reparse as %d-%m. */
879  iday = atoi(first_field);
880  imonth = atoi(second_field);
881  }
882  } else if (first_field) {
883  iday = atoi(first_field);
884  }
885  }
886  break;
887  case QOF_DATE_FORMAT_UK:
888  case QOF_DATE_FORMAT_CE:
889  if (third_field) {
890  iday = atoi(first_field);
891  imonth = atoi(second_field);
892  iyear = atoi(third_field);
893  } else if (second_field) {
894  iday = atoi(first_field);
895  imonth = atoi(second_field);
896  } else if (first_field) {
897  iday = atoi(first_field);
898  }
899  break;
900  case QOF_DATE_FORMAT_ISO:
901  if (third_field) {
902  iyear = atoi(first_field);
903  imonth = atoi(second_field);
904  iday = atoi(third_field);
905  } else if (second_field) {
906  imonth = atoi(first_field);
907  iday = atoi(second_field);
908  } else if (first_field) {
909  iday = atoi(first_field);
910  }
911  break;
912  case QOF_DATE_FORMAT_US:
913  default:
914  if (third_field) {
915  imonth = atoi(first_field);
916  iday = atoi(second_field);
917  iyear = atoi(third_field);
918  } else if (second_field) {
919  imonth = atoi(first_field);
920  iday = atoi(second_field);
921  } else if (first_field) {
922  iday = atoi(first_field);
923  }
924  break;
925  }
926 
927  g_free (dupe);
928 
929  if ((12 < imonth) || (31 < iday))
930  {
931  /*
932  * Ack! Thppfft! Someone just fed this routine a string in the
933  * wrong date format. This is known to happen if a register
934  * window is open when changing the date format. Try the
935  * previous date format. If that doesn't work, see if we can
936  * exchange month and day. If that still doesn't work,
937  * bail and give the caller what they asked for (garbage)
938  * parsed in the new format.
939  *
940  * Note: This test cannot detect any format change that only
941  * swaps month and day field, if the day is 12 or less. This is
942  * deemed acceptable given the obscurity of this bug.
943  */
944  if ((which_format != prevQofDateFormat) &&
945  qof_scan_date_internal(buff, day, month, year, prevQofDateFormat))
946  {
947  return(TRUE);
948  }
949  if ((12 < imonth) && (12 >= iday))
950  {
951  int tmp = imonth; imonth = iday; iday = tmp;
952  }
953  else
954  {
955  return FALSE;
956  }
957  }
958 
959  /* If the year entered is smaller than 100, assume we mean the current
960  century (and are not revising some roman emperor's books) */
961  if (iyear < 100)
962  iyear += ((int) ((now->tm_year+1950-iyear)/100)) * 100;
963 
964  if (year) *year=iyear;
965  if (month) *month=imonth;
966  if (day) *day=iday;
967  return(TRUE);
968 }
969 
970 gboolean
971 qof_scan_date (const char *buff, int *day, int *month, int *year)
972 {
973  return qof_scan_date_internal(buff, day, month, year, dateFormat);
974 }
975 
976 gboolean
977 qof_scan_date_secs (const gchar * buff, time_t * secs)
978 {
979  gboolean rc;
980  int day, month, year;
981 
982  rc = qof_scan_date_internal(buff, &day, &month, &year, dateFormat);
983  if (secs) *secs = xaccDMYToSec (day, month, year);
984 
985  return rc;
986 }
987 
988 Timespec
989 gnc_dmy2timespec (gint day, gint month, gint year)
990 {
991  Timespec ts;
992  QofTime *qt;
993  QofDate *qd;
994 
995  if (!g_date_valid_dmy (day, month, year))
996  return null_timespec ();
997  qd = qof_date_new ();
998  qd->qd_mday = day;
999  qd->qd_mon = month;
1000  qd->qd_year = year;
1001  qof_date_valid (qd);
1002  qt = qof_date_to_qtime (qd);
1003  ts = qof_time_to_Timespec (qt);
1004  qof_time_free (qt);
1005  qof_date_free (qd);
1006  return ts;
1007 }
1008 
1009 Timespec
1010 gnc_dmy2timespec_end (gint day, gint month, gint year)
1011 {
1012  Timespec ts;
1013  QofTime *qt;
1014  QofDate *qd;
1015 
1016  if (!g_date_valid_dmy (day, month, year))
1017  return null_timespec ();
1018  qd = qof_date_new ();
1019  qd->qd_mday = day;
1020  qd->qd_mon = month;
1021  qd->qd_year = year;
1022  qof_date_set_day_end (qd);
1023  qt = qof_date_to_qtime (qd);
1024  ts = qof_time_to_Timespec (qt);
1025  qof_time_free (qt);
1026  qof_date_free (qd);
1027  return ts;
1028 }
1029 
1030 Timespec
1031 gnc_iso8601_to_timespec_gmt (const gchar * str)
1032 {
1033  gchar buf[4];
1034  gchar *dupe;
1035  Timespec ts;
1036  struct tm stm;
1037  glong nsec = 0;
1038 
1039  ts.tv_sec = 0;
1040  ts.tv_nsec = 0;
1041  if (!str)
1042  return ts;
1043  dupe = g_strdup (str);
1044  stm.tm_year = atoi (str) - 1900;
1045  str = strchr (str, '-');
1046  if (str)
1047  {
1048  str++;
1049  }
1050  else
1051  {
1052  return ts;
1053  }
1054  stm.tm_mon = atoi (str) - 1;
1055  str = strchr (str, '-');
1056  if (str)
1057  {
1058  str++;
1059  }
1060  else
1061  {
1062  return ts;
1063  }
1064  stm.tm_mday = atoi (str);
1065 
1066  str = strchr (str, ' ');
1067  if (str)
1068  {
1069  str++;
1070  }
1071  else
1072  {
1073  return ts;
1074  }
1075  stm.tm_hour = atoi (str);
1076  str = strchr (str, ':');
1077  if (str)
1078  {
1079  str++;
1080  }
1081  else
1082  {
1083  return ts;
1084  }
1085  stm.tm_min = atoi (str);
1086  str = strchr (str, ':');
1087  if (str)
1088  {
1089  str++;
1090  }
1091  else
1092  {
1093  return ts;
1094  }
1095  stm.tm_sec = atoi (str);
1096 
1097  if (strchr (str, '.'))
1098  {
1099  gint decimals, i, multiplier = 1000000000;
1100  str = strchr (str, '.') + 1;
1101  decimals = strcspn (str, "+- ");
1102  for (i = 0; i < decimals; i++)
1103  multiplier /= 10;
1104  nsec = atoi (str) * multiplier;
1105  }
1106  stm.tm_isdst = -1;
1107 
1108  str += strcspn (str, "+-");
1109  if (str)
1110  {
1111  buf[0] = str[0];
1112  buf[1] = str[1];
1113  buf[2] = str[2];
1114  buf[3] = 0;
1115  stm.tm_hour -= atoi (buf);
1116 
1117  str += 3;
1118  if ('.' == *str)
1119  str++;
1120  if (isdigit ((guchar) * str) && isdigit ((guchar) * (str + 1)))
1121  {
1122  gint cyn;
1123  if ('+' == buf[0])
1124  {
1125  cyn = -1;
1126  }
1127  else
1128  {
1129  cyn = +1;
1130  }
1131  buf[0] = str[0];
1132  buf[1] = str[1];
1133  buf[2] = str[2];
1134  buf[3] = 0;
1135  stm.tm_min += cyn * atoi (buf);
1136  }
1137  }
1138 
1139  {
1140  struct tm tmp_tm;
1141  struct tm tm;
1142  glong tz;
1143  gint tz_hour;
1144  time_t secs;
1145 
1146  tmp_tm = stm;
1147  tmp_tm.tm_isdst = -1;
1148 
1149  secs = mktime (&tmp_tm);
1150 
1151  if (secs < 0)
1152  {
1153  PWARN (" mktime failed to handle daylight saving: "
1154  "tm_hour=%d tm_year=%d tm_min=%d tm_sec=%d tm_isdst=%d for string=%s",
1155  stm.tm_hour, stm.tm_year, stm.tm_min,
1156  stm.tm_sec, stm.tm_isdst, dupe);
1157  tmp_tm.tm_hour++;
1158  secs = mktime (&tmp_tm);
1159  if (secs < 0)
1160  {
1161  tmp_tm.tm_hour -= 2;
1162  secs = mktime (&tmp_tm);
1163  }
1164  if (secs < 0)
1165  {
1166  PERR (" unable to recover from buggy mktime ");
1167  g_free (dupe);
1168  return ts;
1169  }
1170  }
1171 
1172  tm = *localtime_r (&secs, &tm);
1173 
1174  tz = gnc_timezone (&tmp_tm);
1175 
1176  tz_hour = tz / 3600;
1177  stm.tm_hour -= tz_hour;
1178  stm.tm_min -= (tz % 3600) / 60;
1179  stm.tm_isdst = tmp_tm.tm_isdst;
1180  ts.tv_sec = mktime (&stm);
1181  /* unreachable code */
1182 /* if (ts.tv_sec < 0)
1183  {
1184  PWARN (" mktime failed to adjust calculated time:"
1185  " tm_hour=%d tm_year=%d tm_min=%d tm_sec=%d tm_isdst=%d",
1186  stm.tm_hour, stm.tm_year, stm.tm_min,
1187  stm.tm_sec, stm.tm_isdst);
1188  ts.tv_sec = secs - tz;
1189  }*/
1190  ts.tv_nsec = nsec;
1191  }
1192  g_free (dupe);
1193  return ts;
1194 }
1195 
1196 gchar *
1197 gnc_timespec_to_iso8601_buff (Timespec ts, gchar * buff)
1198 {
1199  gint len, tz_hour, tz_min;
1200  glong secs;
1201  gchar cyn;
1202  time_t tmp;
1203  struct tm parsed;
1204 
1205  tmp = ts.tv_sec;
1206  localtime_r (&tmp, &parsed);
1207 
1208  secs = gnc_timezone (&parsed);
1209  tz_hour = secs / 3600;
1210  tz_min = (secs % 3600) / 60;
1211 
1212  cyn = '-';
1213  if (0 > tz_hour)
1214  {
1215  cyn = '+';
1216  tz_hour = -tz_hour;
1217  }
1218 
1219  len = sprintf (buff, "%4d-%02d-%02d %02d:%02d:%02d.%06ld %c%02d%02d",
1220  parsed.tm_year + 1900,
1221  parsed.tm_mon + 1,
1222  parsed.tm_mday,
1223  parsed.tm_hour,
1224  parsed.tm_min,
1225  parsed.tm_sec, ts.tv_nsec / 1000, cyn, tz_hour, tz_min);
1226 
1227  buff += len;
1228  return buff;
1229 }
1230 
1231 void
1232 gnc_timespec2dmy (Timespec ts, gint * day, gint * month, gint * year)
1233 {
1234  QofTime *time;
1235  QofDate *qd;
1236 
1237  time = timespecToQofTime (ts);
1238  qd = qof_date_from_qtime (time);
1239  qof_time_free (time);
1240  if (day)
1241  *day = qd->qd_mday;
1242  if (month)
1243  *month = qd->qd_mon;
1244  if ((year) && (qd->qd_year < 0) && (qd->qd_year > G_MAXINT))
1245  *year = (gint)qd->qd_year;
1246 }
1247 
1248 glong
1249 gnc_timezone (struct tm *tm)
1250 {
1251  g_return_val_if_fail (tm != NULL, 0);
1252 
1253  return -(tm->tm_gmtoff);
1254 }
1255 
1256 Timespec
1257 qof_instance_get_last_update (QofInstance * inst)
1258 {
1259  Timespec ts;
1260  ts = inst->last_update;
1261  inst->update_time = timespecToQofTime (ts);
1262  return ts;
1263 }
1264 
1265 void
1266 qof_instance_set_last_update (QofInstance * inst, Timespec ts)
1267 {
1268  QofTime *time;
1269  g_return_if_fail (inst);
1270  inst->last_update = ts;
1271  time = timespecToQofTime (ts);
1272  qof_instance_set_update_time (inst, time);
1273 }
1274 time_t
1275 xaccDMYToSec (int day, int month, int year)
1276 {
1277  struct tm stm;
1278  time_t secs;
1279 
1280  stm.tm_year = year - 1900;
1281  stm.tm_mon = month - 1;
1282  stm.tm_mday = day;
1283  gnc_tm_set_day_start(&stm);
1284 
1285  secs = mktime (&stm);
1286 
1287  return secs;
1288 }
1289 void date_add_months (struct tm *tm, int months, gboolean track_last_day)
1290 {
1291  gboolean was_last_day;
1292  int new_last_mday;
1293 
1294  was_last_day = date_is_last_mday(tm);
1295 
1296  tm->tm_mon += months;
1297  while (tm->tm_mon > 11) {
1298  tm->tm_mon -= 12;
1299  tm->tm_year++;
1300  }
1301 
1302  if (!track_last_day)
1303  return;
1304 
1305  new_last_mday = date_get_last_mday(tm);
1306  if (was_last_day || (tm->tm_mday > new_last_mday))
1307  tm->tm_mday = new_last_mday;
1308 }
1309 char dateSeparator (void)
1310 {
1312 }
1313 
1314 const char*
1315 gnc_date_dateformat_to_string(QofDateFormat format)
1316 {
1317  switch (format) {
1318  case QOF_DATE_FORMAT_US:
1319  return "us";
1320  case QOF_DATE_FORMAT_UK:
1321  return "uk";
1322  case QOF_DATE_FORMAT_CE:
1323  return "ce";
1324  case QOF_DATE_FORMAT_ISO:
1325  return "iso";
1326  case QOF_DATE_FORMAT_UTC:
1327  return "utc";
1329  return "locale";
1331  return "custom";
1332  default:
1333  return NULL;
1334  }
1335 }
1336 const char*
1337 gnc_date_monthformat_to_string(GNCDateMonthFormat format)
1338 {
1339  switch (format) {
1340  case GNCDATE_MONTH_NUMBER:
1341  return "number";
1342  case GNCDATE_MONTH_ABBREV:
1343  return "abbrev";
1344  case GNCDATE_MONTH_NAME:
1345  return "name";
1346  default:
1347  return NULL;
1348  }
1349 }
1350 gboolean
1351 qof_date_add_days(Timespec *ts, gint days)
1352 {
1353  struct tm tm;
1354  time_t tt;
1355 
1356  g_return_val_if_fail(ts, FALSE);
1357  tt = timespecToTime_t(*ts);
1358 #ifdef HAVE_GMTIME_R
1359  tm = *gmtime_r(&tt, &tm);
1360 #else
1361  tm = *gmtime(&tt);
1362 #endif
1363  tm.tm_mday += days;
1364  tt = mktime(&tm);
1365  if(tt < 0) { return FALSE; }
1366  timespecFromTime_t(ts, tt);
1367  return TRUE;
1368 }
1369 
1370 gboolean
1371 qof_date_add_months(Timespec *ts, gint months, gboolean track_last_day)
1372 {
1373  struct tm tm;
1374  time_t tt;
1375  gint new_last_mday;
1376  gboolean was_last_day;
1377 
1378  g_return_val_if_fail(ts, FALSE);
1379  tt = timespecToTime_t(*ts);
1380 #ifdef HAVE_GMTIME_R
1381  tm = *gmtime_r(&tt, &tm);
1382 #else
1383  tm = *gmtime(&tt);
1384 #endif
1385  was_last_day = date_is_last_mday(&tm);
1386  tm.tm_mon += months;
1387  while (tm.tm_mon > 11) {
1388  tm.tm_mon -= 12;
1389  tm.tm_year++;
1390  }
1391  if (track_last_day) {
1392  new_last_mday = date_get_last_mday(&tm);
1393  if (was_last_day || (tm.tm_mday > new_last_mday)) {
1394  tm.tm_mday = new_last_mday;
1395  }
1396  }
1397  tt = mktime(&tm);
1398  if(tt < 0) { return FALSE; }
1399  timespecFromTime_t(ts, tt);
1400  return TRUE;
1401 }
1402 
1403 QofDateFormat qof_date_format_get (void)
1404 {
1405  return qof_date_format_get_current ();
1406 }
1407 
1408 const gchar *qof_date_format_get_string(QofDateFormat df)
1409 {
1410  switch(df) {
1411  case QOF_DATE_FORMAT_US:
1412  return "%m/%d/%y";
1413  case QOF_DATE_FORMAT_UK:
1414  return "%d/%m/%y";
1415  case QOF_DATE_FORMAT_CE:
1416  return "%d.%m.%y";
1417  case QOF_DATE_FORMAT_UTC:
1418  return "%Y-%m-%dT%H:%M:%SZ";
1419  case QOF_DATE_FORMAT_ISO:
1420  return "%y-%m-%d";
1422  default:
1423  return QOF_D_FMT;
1424  };
1425 }
1426 
1427 void qof_date_format_set(QofDateFormat df)
1428 {
1429  if(!qof_date_format_set_current (df))
1430  PERR (" unable to set current format, %d", df);
1431 }
1432 
1433 const gchar *qof_date_text_format_get_string(QofDateFormat df)
1434 {
1435  return qof_date_format_get_format (df);
1436 }
1437 
1438 char *
1439 xaccDateUtilGetStampNow (void)
1440 {
1441  return qof_time_stamp_now ();
1442 }
1443 
1444 void
1445 kvp_frame_set_timespec (KvpFrame * frame, const char *path, Timespec ts)
1446 {
1447  KvpValue *value;
1448  value = kvp_value_new_timespec (ts);
1449  frame = kvp_frame_set_value_nc (frame, path, value);
1450  if (!frame)
1451  kvp_value_delete (value);
1452 }
1453 
1454 void
1455 kvp_frame_add_timespec (KvpFrame * frame, const char *path, Timespec ts)
1456 {
1457  KvpValue *value;
1458  value = kvp_value_new_timespec (ts);
1459  frame = kvp_frame_add_value_nc (frame, path, value);
1460  if (!frame)
1461  kvp_value_delete (value);
1462 }
1463 
1464 Timespec
1465 kvp_frame_get_timespec (const KvpFrame * frame,
1466  const char *path __attribute__ ((unused)))
1467 {
1468  QofTime *qt;
1469  Timespec ts;
1470  char *key;
1471 
1472  key = NULL;
1473  ts.tv_sec = 0;
1474  ts.tv_nsec = 0;
1475  qt = kvp_value_get_time (kvp_frame_get_slot (frame, key));
1476  if(!qt)
1477  return ts;
1478  return qof_time_to_Timespec (qt);
1479 }
1480 
1481 KvpValue *
1482 kvp_value_new_timespec (Timespec value)
1483 {
1484  QofTime *qt;
1485  KvpValue *retval;
1486 
1487  qt = timespecToQofTime (value);
1488  retval = kvp_value_new_time (qt);
1489  return retval;
1490 }
1491 
1492 Timespec
1493 kvp_value_get_timespec (const KvpValue * value)
1494 {
1495  Timespec ts;
1496  QofTime *qt;
1497  ts.tv_sec = 0;
1498  ts.tv_nsec = 0;
1499  if (!value)
1500  return ts;
1501  qt = kvp_value_get_time (value);
1502  ts = qof_time_to_Timespec (qt);
1503  return ts;
1504 }
1505 #define NUM_CLOCKS 10
1506 static struct timeval qof_clock[NUM_CLOCKS] = {
1507  {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
1508  {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
1509 };
1510 
1511 static struct timeval qof_clock_total[NUM_CLOCKS] = {
1512  {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
1513  {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
1514 };
1515 
1516 void
1517 qof_start_clock (gint clockno,
1518  QofLogModule log_module __attribute__ ((unused)),
1519  QofLogLevel log_level __attribute__ ((unused)),
1520  const gchar * function_name, const gchar * format, ...)
1521 {
1522  va_list ap;
1523 
1524  if ((0 > clockno) || (NUM_CLOCKS <= clockno))
1525  return;
1526 #ifdef HAVE_GETTIMEOFDAY
1527  gettimeofday (&qof_clock[clockno], NULL);
1528 #else
1529  time (&(qof_clock[clockno].tv_sec));
1530  qof_clock[clockno].tv_usec = 0;
1531 #endif
1532 
1533  if (!fout)
1534  qof_log_init ();
1535 
1536  fprintf (fout, "Clock %d Start: %s: ",
1537  clockno, qof_log_prettify (function_name));
1538 
1539  va_start (ap, format);
1540 
1541  vfprintf (fout, format, ap);
1542 
1543  va_end (ap);
1544 
1545  fprintf (fout, "\n");
1546  fflush (fout);
1547 }
1548 
1549 void
1550 qof_report_clock (gint clockno,
1551  QofLogModule log_module __attribute__ ((unused)),
1552  QofLogLevel log_level __attribute__ ((unused)),
1553  const gchar * function_name, const gchar * format, ...)
1554 {
1555  struct timeval now;
1556  va_list ap;
1557 
1558  if ((0 > clockno) || (NUM_CLOCKS <= clockno))
1559  return;
1560 #ifdef HAVE_GETTIMEOFDAY
1561  gettimeofday (&now, NULL);
1562 #else
1563  time (&(now.tv_sec));
1564  now.tv_usec = 0;
1565 #endif
1566 
1567  if (now.tv_usec < qof_clock[clockno].tv_usec)
1568  {
1569  now.tv_sec--;
1570  now.tv_usec += 1000000;
1571  }
1572  now.tv_sec -= qof_clock[clockno].tv_sec;
1573  now.tv_usec -= qof_clock[clockno].tv_usec;
1574 
1575  qof_clock_total[clockno].tv_sec += now.tv_sec;
1576  qof_clock_total[clockno].tv_usec += now.tv_usec;
1577 
1578  if (!fout)
1579  qof_log_init ();
1580 
1581  fprintf (fout, "Clock %d Elapsed: %ld.%06lds %s: ",
1582  clockno, (long int) now.tv_sec, (long int) now.tv_usec,
1583  qof_log_prettify (function_name));
1584 
1585  va_start (ap, format);
1586 
1587  vfprintf (fout, format, ap);
1588 
1589  va_end (ap);
1590 
1591  fprintf (fout, "\n");
1592  fflush (fout);
1593 }
1594 
1595 void
1596 qof_report_clock_total (gint clockno,
1597  QofLogModule log_module __attribute__ ((unused)),
1598  QofLogLevel log_level __attribute__ ((unused)),
1599  const gchar * function_name, const gchar * format, ...)
1600 {
1601  va_list ap;
1602 
1603  if ((0 > clockno) || (NUM_CLOCKS <= clockno))
1604  return;
1605 
1606  while (qof_clock_total[clockno].tv_usec >= 1000000)
1607  {
1608  qof_clock_total[clockno].tv_sec++;
1609  qof_clock_total[clockno].tv_usec -= 1000000;
1610  }
1611 
1612  if (!fout)
1613  qof_log_init ();
1614 
1615  fprintf (fout, "Clock %d Total Elapsed: %ld.%06lds %s: ",
1616  clockno,
1617  (long int) qof_clock_total[clockno].tv_sec,
1618  (long int) qof_clock_total[clockno].tv_usec,
1619  qof_log_prettify (function_name));
1620 
1621  va_start (ap, format);
1622 
1623  vfprintf (fout, format, ap);
1624 
1625  va_end (ap);
1626 
1627  fprintf (fout, "\n");
1628  fflush (fout);
1629 }
1630 static QofSession *current_session = NULL;
1631 
1632 QofSession *
1633 qof_session_get_current_session (void)
1634 {
1635  if (!current_session)
1636  {
1637  qof_event_suspend ();
1638  current_session = qof_session_new ();
1639  qof_event_resume ();
1640  }
1641 
1642  return current_session;
1643 }
1644 
1645 void
1646 qof_session_set_current_session (QofSession * session)
1647 {
1648  current_session = session;
1649 }
1650 
1651 void
1652 qof_session_clear_current_session (void)
1653 {
1654  current_session = NULL;
1655 }
1656 
1657 gboolean
1658 gnc_strisnum (const guchar * s)
1659 {
1660  return qof_util_string_isnum (s);
1661 }
1662 
1663 KvpFrame *
1664 gnc_kvp_bag_add (KvpFrame * pwd, const char *path,
1665  time_t secs, const char *first_name, ...)
1666 {
1667  QofTime *qt;
1668  KvpFrame *cwd;
1669  va_list ap;
1670 
1671  qt = qof_time_from_time_t (secs, 0);
1672  va_start (ap, first_name);
1673  cwd = qof_kvp_bag_add(pwd, path, qt, first_name, ap);
1674  va_end (ap);
1675  return cwd;
1676 }
1677 
1678 KvpFrame *
1679 gnc_kvp_bag_find_by_guid (KvpFrame * root, const gchar *path,
1680  const gchar *guid_name, GUID * desired_guid)
1681 {
1682  return qof_kvp_bag_find_by_guid (root, path,
1683  guid_name, desired_guid);
1684 }
1685 
1686 void
1687 gnc_kvp_bag_remove_frame (KvpFrame * root, const char *path,
1688  KvpFrame * fr)
1689 {
1690  qof_kvp_bag_remove_frame (root, path, fr);
1691 }
1692 
1693 void
1694 gnc_kvp_bag_merge (KvpFrame * kvp_into, const char *intopath,
1695  KvpFrame * kvp_from, const char *frompath)
1696 {
1697  qof_kvp_bag_merge (kvp_into, intopath, kvp_from, frompath);
1698 }
1699 
1700 static gboolean param_flag = TRUE;
1701 static void
1702 param_edit_cb (QofParam * param, gpointer user_data)
1703 {
1704  QofInstance * inst = (QofInstance*)user_data;
1705  param_flag = qof_util_param_edit (inst, param);
1706  if (!param_flag)
1707  return;
1708 }
1709 
1710 static void
1711 param_commit_cb (QofParam * param, gpointer user_data)
1712 {
1713  QofInstance * inst = (QofInstance*)user_data;
1714  param_flag = qof_util_param_commit (inst, param);
1715  if (!param_flag)
1716  return;
1717 }
1718 gboolean qof_begin_edit (QofInstance * inst)
1719 {
1720  QofIdTypeConst type;
1721  QofEntity * ent;
1722 
1723  param_flag = TRUE;
1724  ent = &inst->entity;
1725  type = ent->e_type;
1726  qof_class_param_foreach (type, param_edit_cb, inst);
1727  return param_flag;
1728 }
1729 gboolean
1730 qof_commit_edit (QofInstance * inst)
1731 {
1732  QofIdTypeConst type;
1733  QofEntity * ent;
1734 
1735  param_flag = TRUE;
1736  ent = &inst->entity;
1737  type = ent->e_type;
1738  qof_class_param_foreach (type, param_commit_cb, inst);
1739  return param_flag;
1740 }
1741 gboolean
1742 qof_commit_edit_part2 (QofInstance * inst,
1743  void (*on_error) (QofInstance *, QofBackendError),
1744  void (*on_done) (QofInstance *), void (*on_free) (QofInstance *))
1745 {
1746  QofBackend *be;
1747 
1748  ENTER (" ");
1749  /* See if there's a backend. If there is, invoke it. */
1750  be = qof_book_get_backend (inst->book);
1751  if (be && qof_backend_commit_exists(be))
1752  {
1753  QofBackendError errcode;
1754  do {
1755  errcode = qof_backend_get_error (be);
1756  } while (ERR_BACKEND_NO_ERR != errcode);
1757  qof_backend_run_commit(be, inst);
1758  errcode = qof_backend_get_error (be);
1759  if (ERR_BACKEND_NO_ERR != errcode)
1760  {
1761  inst->do_free = FALSE;
1762 
1763  qof_backend_set_error (be, errcode);
1764  if (on_error)
1765  on_error (inst, errcode);
1766  LEAVE (" errcode=%d", errcode);
1767  return FALSE;
1768  }
1769  inst->dirty = FALSE;
1770  }
1771  if (inst->do_free) {
1772  LEAVE (" do_free");
1773  if (on_free)
1774  on_free(inst);
1775  return TRUE;
1776  }
1777  if (on_done)
1778  on_done(inst);
1779  LEAVE (" done");
1780  return TRUE;
1781 }
1782 gchar *
1783 qof_util_param_as_string (QofEntity * ent, QofParam * param)
1784 {
1785  return qof_util_param_to_string (ent, param);
1786 }
1787 gnc_numeric
1788 double_to_gnc_numeric (double in, gint64 denom, gint how)
1789 {
1790  return qof_numeric_from_double (in, denom, how);
1791 }
1792 gboolean
1793 string_to_gnc_numeric (const gchar * str, gnc_numeric * n)
1794 {
1795  return qof_numeric_from_string (str, n);
1796 }
1797 gnc_numeric
1798 gnc_numeric_error (GNCNumericErrorCode error_code)
1799 {
1800  return qof_numeric_error (error_code);
1801 }
1802 gdouble
1803 gnc_numeric_to_double (gnc_numeric in)
1804 {
1805  return qof_numeric_to_double (in);
1806 }
1807 gchar *
1808 gnc_numeric_to_string (gnc_numeric n)
1809 {
1810  return qof_numeric_to_string (n);
1811 }
1812 gchar *
1813 gnc_num_dbg_to_string (gnc_numeric n)
1814 {
1815  return qof_numeric_dbg_to_string (n);
1816 }
1818 gnc_numeric_check (gnc_numeric a)
1819 {
1820  return qof_numeric_check (a);
1821 }
1822 gint
1823 gnc_numeric_compare (gnc_numeric a, gnc_numeric b)
1824 {
1825  return qof_numeric_compare (a, b);
1826 }
1827 gboolean
1828 gnc_numeric_zero_p (gnc_numeric a)
1829 {
1830  return qof_numeric_zero_p (a);
1831 }
1832 gboolean
1833 gnc_numeric_negative_p (gnc_numeric a)
1834 {
1835  return qof_numeric_negative_p (a);
1836 }
1837 gboolean
1838 gnc_numeric_positive_p (gnc_numeric a)
1839 {
1840  return qof_numeric_positive_p (a);
1841 }
1842 gboolean
1843 gnc_numeric_eq (gnc_numeric a, gnc_numeric b)
1844 {
1845  return qof_numeric_eq (a, b);
1846 }
1847 gboolean
1848 gnc_numeric_equal (gnc_numeric a, gnc_numeric b)
1849 {
1850  return qof_numeric_equal (a, b);
1851 }
1852 gint
1853 gnc_numeric_same (gnc_numeric a, gnc_numeric b,
1854  gint64 denom, gint how)
1855 {
1856  return qof_numeric_same (a, b, denom, how);
1857 }
1858 gnc_numeric
1859 gnc_numeric_add (gnc_numeric a, gnc_numeric b,
1860  gint64 denom, gint how)
1861 {
1862  return qof_numeric_add (a, b, denom, how);
1863 }
1864 gnc_numeric
1865 gnc_numeric_sub (gnc_numeric a, gnc_numeric b,
1866  gint64 denom, gint how)
1867 {
1868  return qof_numeric_sub (a, b, denom, how);
1869 }
1870 gnc_numeric
1871 gnc_numeric_mul (gnc_numeric a, gnc_numeric b,
1872  gint64 denom, gint how)
1873 {
1874  return qof_numeric_mul (a, b, denom, how);
1875 }
1876 gnc_numeric
1877 gnc_numeric_div (gnc_numeric x, gnc_numeric y,
1878  gint64 denom, gint how)
1879 {
1880  return qof_numeric_div (x, y, denom, how);
1881 }
1882 gnc_numeric gnc_numeric_neg (gnc_numeric a)
1883 {
1884  return qof_numeric_neg (a);
1885 }
1886 gnc_numeric gnc_numeric_abs (gnc_numeric a)
1887 {
1888  return qof_numeric_abs (a);
1889 }
1890 gnc_numeric
1891 gnc_numeric_add_with_error (gnc_numeric a, gnc_numeric b,
1892  gint64 denom, gint how,
1893  gnc_numeric * error)
1894 {
1895  return qof_numeric_add_with_error (a, b, denom, how, error);
1896 }
1897 gnc_numeric
1898 gnc_numeric_sub_with_error (gnc_numeric a, gnc_numeric b,
1899  gint64 denom, gint how,
1900  gnc_numeric * error)
1901 {
1902  return qof_numeric_sub_with_error (a, b, denom, how, error);
1903 }
1904 gnc_numeric
1905 gnc_numeric_mul_with_error (gnc_numeric a, gnc_numeric b,
1906  gint64 denom, gint how,
1907  gnc_numeric * error)
1908 {
1909  return qof_numeric_mul_with_error (a, b, denom, how, error);
1910 }
1911 gnc_numeric
1912 gnc_numeric_div_with_error (gnc_numeric a, gnc_numeric b,
1913  gint64 denom, gint how,
1914  gnc_numeric * error)
1915 {
1916  return qof_numeric_div_with_error (a, b, denom, how, error);
1917 }
1918 
1919 gnc_numeric
1920 gnc_numeric_convert (gnc_numeric in, gint64 denom, gint how)
1921 {
1922  return qof_numeric_convert (in, denom, how);
1923 }
1924 
1925 gnc_numeric gnc_numeric_reduce (gnc_numeric in)
1926 {
1927  return qof_numeric_reduce (in);
1928 }
1929 void
1930 qof_session_push_error (QofSession * session, QofBackendError err,
1931  const gchar *message)
1932 {
1933  if (!session)
1934  return;
1935  qof_error_set (session, qof_error_register (message, FALSE));
1936 }
1937 const gchar *
1938 qof_session_get_error_message (QofSession * session)
1939 {
1940  if (!session)
1941  return "";
1942  if (!session->error_message)
1943  return "";
1944  return session->error_message;
1945 }
1946 QofErrorId
1947 qof_session_pop_error (QofSession * session)
1948 {
1949  if (!session)
1950  return QOF_FATAL;
1951  return qof_error_get_id (session);
1952 }
1953 QofErrorId
1954 qof_session_get_error (QofSession * session)
1955 {
1956  QofErrorId err;
1957 
1958  if (!session)
1959  return ERR_BACKEND_NO_BACKEND;
1960 
1961  /* if we have a local error, return that. */
1962  if (ERR_BACKEND_NO_ERR != session->last_err)
1963  {
1964  return session->last_err;
1965  }
1966 
1967  /* maybe we should return a no-backend error ??? */
1968  if (!session->backend)
1969  return ERR_BACKEND_NO_ERR;
1970 
1971  err = qof_backend_get_error (session->backend);
1972  session->last_err = err;
1973  return err;
1974 }
1975 void
1976 qof_backend_set_error (QofBackend * be, QofErrorId err)
1977 {
1978  if (!be)
1979  return;
1980  qof_error_set_be (be, err);
1981 }
1982 QofErrorId
1983 qof_backend_get_error (QofBackend * be)
1984 {
1985  QofErrorId err;
1986  if (!be)
1987  return ERR_BACKEND_NO_BACKEND;
1988 
1989  /* use 'stack-pop' semantics */
1990  err = be->last_err;
1991  be->last_err = ERR_BACKEND_NO_ERR;
1992  return err;
1993 }
1994 void
1995 qof_backend_set_message (QofBackend * be, const gchar * format, ...)
1996 {
1997  va_list args;
1998  gchar *buffer;
1999 
2000  if (!be)
2001  return;
2002 
2003  /* If there's already something here, free it */
2004  if (be->error_msg)
2005  g_free (be->error_msg);
2006 
2007  if (!format)
2008  {
2009  be->error_msg = NULL;
2010  return;
2011  }
2012 
2013  va_start (args, format);
2014  buffer = (gchar *) g_strdup_vprintf (format, args);
2015  va_end (args);
2016 
2017  be->error_msg = buffer;
2018 }
2019 gchar *
2020 qof_backend_get_message (QofBackend * be)
2021 {
2022  if (!be)
2023  return g_strdup ("ERR_BACKEND_NO_BACKEND");
2024  if (!be->error_msg)
2025  return NULL;
2026 
2027  return g_strdup(qof_error_get_message_be (be));
2028 }
2029 
2030 /* qof_backend_set_error with old values but no strings.
2031 */
2032 
2033 AS_STRING_FUNC(QofBackendError, ENUM_LIST_DEP)
2034 
2035 void
2036 set_deprecated_errors (void)
2037 {
2038  QofErrorId err;
2039 
2040  for (err = 0;err < ERR_LAST; err++)
2041  {
2042  switch (err)
2043  {
2044  case ERR_BACKEND_NO_ERR:
2045  {
2046  break;
2047  }
2048  case ERR_BACKEND_NO_HANDLER:
2049  case ERR_BACKEND_NO_BACKEND:
2050  case ERR_BACKEND_BAD_URL:
2051  case ERR_BACKEND_CANT_CONNECT:
2052  case ERR_BACKEND_CONN_LOST:
2053  case ERR_BACKEND_TOO_NEW:
2054  case ERR_BACKEND_NO_SUCH_DB:
2055  case ERR_BACKEND_LOCKED:
2056  case ERR_BACKEND_READONLY:
2057  case ERR_BACKEND_DATA_CORRUPT:
2058  case ERR_BACKEND_SERVER_ERR:
2059  case ERR_BACKEND_PERM:
2060  case ERR_BACKEND_MISC:
2061  case ERR_QSF_INVALID_OBJ:
2062  case ERR_QSF_INVALID_MAP:
2063  case ERR_QSF_BAD_QOF_VERSION:
2064  case ERR_QSF_BAD_MAP:
2065  case ERR_QSF_BAD_OBJ_GUID:
2066  case ERR_QSF_NO_MAP:
2067  case ERR_QSF_WRONG_MAP:
2068  case ERR_QSF_MAP_NOT_OBJ:
2069  case ERR_QSF_OVERFLOW:
2070  case ERR_QSF_OPEN_NOT_MERGE:
2071  case ERR_FILEIO_FILE_BAD_READ:
2072  case ERR_FILEIO_PARSE_ERROR:
2073  case ERR_FILEIO_FILE_EMPTY:
2074  case ERR_FILEIO_FILE_NOT_FOUND:
2075  case ERR_FILEIO_FILE_TOO_OLD:
2076  case ERR_FILEIO_UNKNOWN_FILE_TYPE:
2077  case ERR_FILEIO_BACKUP_ERROR:
2078  case ERR_FILEIO_WRITE_ERROR:
2079  case ERR_SQL_DB_TOO_OLD:
2080  case ERR_SQL_DB_BUSY:
2081  {
2082  deprecated_support (err, QofBackendErrorasString(err));
2083  break;
2084  }
2085  default:
2086  break;
2087  }
2088  }
2090 
2091 gint double_compare (gdouble d1, gdouble d2)
2092 {
2093  return qof_util_double_compare (d1, d2);
2094 }
2095 
2096 /* ==================================================================== */
2097 #endif /* QOF_DISABLE_DEPRECATED */