GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
guile-util.c
1 /********************************************************************\
2  * guile-util.c -- utility functions for using guile for GnuCash *
3  * Copyright (C) 1999 Linas Vepstas *
4  * Copyright (C) 2000 Dave Peticolas *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, write to the Free Software *
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 \********************************************************************/
20 
21 #include "config.h"
22 
23 #include <glib.h>
24 #include <glib/gi18n.h>
25 #include <string.h>
26 #include "swig-runtime.h"
27 #include <libguile.h>
28 #include <errno.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #else
32 # include <io.h>
33 # define close _close
34 #endif
35 #ifndef HAVE_STRPTIME
36 # include "strptime.h"
37 #endif
38 
39 #include "qof.h"
40 #include "engine-helpers-guile.h"
41 #include "glib-helpers.h"
42 #include "gnc-glib-utils.h"
43 #include "gnc-guile-utils.h"
44 #include "gnc-prefs.h"
45 #include "guile-util.h"
46 #include "guile-mappings.h"
47 
48 /* This static indicates the debugging module this .o belongs to. */
49 static QofLogModule log_module = GNC_MOD_GUILE;
50 
51 
52 struct _setters
53 {
54  SCM split_scm_account_guid;
55  SCM split_scm_memo;
56  SCM split_scm_action;
57  SCM split_scm_reconcile_state;
58  SCM split_scm_amount;
59  SCM split_scm_value;
60 
61  SCM trans_scm_date;
62  SCM trans_scm_num;
63  SCM trans_scm_description;
64  SCM trans_scm_notes;
65  SCM trans_scm_append_split_scm;
66 } setters;
67 
68 struct _getters
69 {
70  SCM split_scm_memo;
71  SCM split_scm_action;
72  SCM split_scm_amount;
73  SCM split_scm_value;
74 
75  SCM trans_scm_split_scms;
76  SCM trans_scm_split_scm;
77  SCM trans_scm_other_split_scm;
78 
79  SCM debit_string;
80  SCM credit_string;
81 } getters;
82 
84 {
85  SCM is_split_scm;
86  SCM is_trans_scm;
87 } predicates;
88 
89 struct _Process
90 {
91  GPid pid;
92  gint fd_stdin;
93  gint fd_stdout;
94  gint fd_stderr;
95  gboolean dead;
96  gboolean detached;
97 };
98 
99 
100 static void
101 initialize_scm_functions()
102 {
103  static gboolean scm_funcs_inited = FALSE;
104 
105  if (scm_funcs_inited)
106  return;
107 
108  setters.split_scm_account_guid =
109  scm_c_eval_string("gnc:split-scm-set-account-guid");
110  setters.split_scm_memo = scm_c_eval_string("gnc:split-scm-set-memo");
111  setters.split_scm_action = scm_c_eval_string("gnc:split-scm-set-action");
112  setters.split_scm_reconcile_state =
113  scm_c_eval_string("gnc:split-scm-set-reconcile-state");
114  setters.split_scm_amount = scm_c_eval_string("gnc:split-scm-set-amount");
115  setters.split_scm_value = scm_c_eval_string("gnc:split-scm-set-value");
116 
117  setters.trans_scm_date = scm_c_eval_string("gnc:transaction-scm-set-date-posted");
118  setters.trans_scm_num = scm_c_eval_string("gnc:transaction-scm-set-num");
119  setters.trans_scm_description =
120  scm_c_eval_string("gnc:transaction-scm-set-description");
121  setters.trans_scm_notes = scm_c_eval_string("gnc:transaction-scm-set-notes");
122  setters.trans_scm_append_split_scm =
123  scm_c_eval_string("gnc:transaction-scm-append-split-scm");
124 
125  getters.split_scm_memo = scm_c_eval_string("gnc:split-scm-get-memo");
126  getters.split_scm_action = scm_c_eval_string("gnc:split-scm-get-action");
127  getters.split_scm_amount = scm_c_eval_string("gnc:split-scm-get-amount");
128  getters.split_scm_value = scm_c_eval_string("gnc:split-scm-get-value");
129 
130  getters.trans_scm_split_scms =
131  scm_c_eval_string("gnc:transaction-scm-get-split-scms");
132  getters.trans_scm_split_scm =
133  scm_c_eval_string("gnc:transaction-scm-get-split-scm");
134  getters.trans_scm_other_split_scm =
135  scm_c_eval_string("gnc:transaction-scm-get-other-split-scm");
136 
137  getters.debit_string = scm_c_eval_string("gnc:get-debit-string");
138  getters.credit_string = scm_c_eval_string("gnc:get-credit-string");
139 
140  predicates.is_split_scm = scm_c_eval_string("gnc:split-scm?");
141  predicates.is_trans_scm = scm_c_eval_string("gnc:transaction-scm?");
142 
143  scm_funcs_inited = TRUE;
144 }
145 
146 
147 /********************************************************************\
148  gnc_scm_lookup
149 
150  returns the SCM binding associated with the given symbol function,
151  or SCM_UNDEFINED if it couldn't be retrieved.
152 
153  Don't use this to get hold of symbols that are considered private
154  to a given module unless the C code you're writing is considered
155  part of that module.
156 
157  Args:
158 
159  module - where to lookup the symbol, something like "ice-9 debug"
160  symbol - what to look up.
161 
162  Returns: value bound to the symbol, if any.
163 \********************************************************************/
164 
165 #if 0
166 
167 ************ NOT TESTED YET **************
168 
169 SCM
170 gnc_scm_lookup(const char *module, const char *symbol)
171 {
172  SCM scm_module = scm_c_resolve_module(module);
173  SCM value = scm_c_module_lookup(scm_module, symbol);
174  return value;
175 }
176 
177 #endif
178 
179 /********************************************************************\
180  * gnc_copy_split *
181  * returns a scheme representation of a split. If the split is *
182  * NULL, SCM_UNDEFINED is returned. *
183  * *
184  * Args: split - the split to copy *
185  * use_cut_semantics - if TRUE, copy is for a 'cut' operation *
186  * Returns: SCM representation of split or SCM_UNDEFINED *
187 \********************************************************************/
188 SCM
189 gnc_copy_split(Split *split, gboolean use_cut_semantics)
190 {
191  static swig_type_info *split_type = NULL;
192  SCM func;
193  SCM arg;
194 
195  if (split == NULL)
196  return SCM_UNDEFINED;
197 
198  func = scm_c_eval_string("gnc:split->split-scm");
199  if (!scm_is_procedure(func))
200  return SCM_UNDEFINED;
201 
202  if (!split_type)
203  split_type = SWIG_TypeQuery("_p_Split");
204 
205  arg = SWIG_NewPointerObj(split, split_type, 0);
206 
207  return scm_call_2(func, arg, SCM_BOOL(use_cut_semantics));
208 }
209 
210 
211 /********************************************************************\
212  * gnc_copy_split_scm_onto_split *
213  * copies a scheme representation of a split onto an actual split.*
214  * *
215  * Args: split_scm - the scheme representation of a split *
216  * split - the split to copy onto *
217  * Returns: Nothing *
218 \********************************************************************/
219 void
220 gnc_copy_split_scm_onto_split(SCM split_scm, Split *split,
221  QofBook * book)
222 {
223  static swig_type_info *split_type = NULL;
224  SCM result;
225  SCM func;
226  SCM arg;
227 
228  if (split_scm == SCM_UNDEFINED)
229  return;
230 
231  if (split == NULL)
232  return;
233 
234  g_return_if_fail (book);
235 
236  func = scm_c_eval_string("gnc:split-scm?");
237  if (!scm_is_procedure(func))
238  return;
239 
240  result = scm_call_1(func, split_scm);
241  if (!scm_is_true(result))
242  return;
243 
244  func = scm_c_eval_string("gnc:split-scm-onto-split");
245  if (!scm_is_procedure(func))
246  return;
247 
248  if (!split_type)
249  split_type = SWIG_TypeQuery("_p_Split");
250 
251  arg = SWIG_NewPointerObj(split, split_type, 0);
252 
253  scm_call_3(func, split_scm, arg, gnc_book_to_scm (book));
254 }
255 
256 
257 /********************************************************************\
258  * gnc_is_split_scm *
259  * returns true if the scm object is a scheme split *
260  * *
261  * Args: scm - a scheme object *
262  * Returns: true if scm is a scheme split *
263 \********************************************************************/
264 gboolean
265 gnc_is_split_scm(SCM scm)
266 {
267  initialize_scm_functions();
268 
269  return scm_is_true(scm_call_1(predicates.is_split_scm, scm));
270 }
271 
272 
273 /********************************************************************\
274  * gnc_is_trans_scm *
275  * returns true if the scm object is a scheme transaction *
276  * *
277  * Args: scm - a scheme object *
278  * Returns: true if scm is a scheme transaction *
279 \********************************************************************/
280 gboolean
281 gnc_is_trans_scm(SCM scm)
282 {
283  initialize_scm_functions();
284 
285  return scm_is_true(scm_call_1(predicates.is_trans_scm, scm));
286 }
287 
288 
289 /********************************************************************\
290  * gnc_split_scm_set_account *
291  * set the account of a scheme representation of a split. *
292  * *
293  * Args: split_scm - the scheme split *
294  * account - the account to set *
295  * Returns: Nothing *
296 \********************************************************************/
297 void
298 gnc_split_scm_set_account(SCM split_scm, Account *account)
299 {
300  gchar guid_string[GUID_ENCODING_LENGTH+1];
301  SCM arg;
302 
303  initialize_scm_functions();
304 
305  if (!gnc_is_split_scm(split_scm))
306  return;
307  if (account == NULL)
308  return;
309 
310  guid_to_string_buff(xaccAccountGetGUID(account), guid_string);
311  if (strlen(guid_string) == 0)
312  return;
313 
314  arg = scm_from_utf8_string(guid_string);
315 
316  scm_call_2(setters.split_scm_account_guid, split_scm, arg);
317 }
318 
319 
320 /********************************************************************\
321  * gnc_split_scm_set_memo *
322  * set the memo of a scheme representation of a split. *
323  * *
324  * Args: split_scm - the scheme split *
325  * memo - the memo to set *
326  * Returns: Nothing *
327 \********************************************************************/
328 void
329 gnc_split_scm_set_memo(SCM split_scm, const char *memo)
330 {
331  SCM arg;
332 
333  initialize_scm_functions();
334 
335  if (!gnc_is_split_scm(split_scm))
336  return;
337  if (memo == NULL)
338  return;
339 
340  arg = scm_from_utf8_string(memo);
341 
342  scm_call_2(setters.split_scm_memo, split_scm, arg);
343 }
344 
345 
346 /********************************************************************\
347  * gnc_split_scm_set_action *
348  * set the action of a scheme representation of a split. *
349  * *
350  * Args: split_scm - the scheme split *
351  * action - the action to set *
352  * Returns: Nothing *
353 \********************************************************************/
354 void
355 gnc_split_scm_set_action(SCM split_scm, const char *action)
356 {
357  SCM arg;
358 
359  initialize_scm_functions();
360 
361  if (!gnc_is_split_scm(split_scm))
362  return;
363  if (action == NULL)
364  return;
365 
366  arg = scm_from_utf8_string(action);
367 
368  scm_call_2(setters.split_scm_action, split_scm, arg);
369 }
370 
371 
372 /********************************************************************\
373  * gnc_split_scm_set_reconcile_state *
374  * set the reconcile state of a scheme split. *
375  * *
376  * Args: split_scm - the scheme split *
377  * reconcile_state - the reconcile state to set *
378  * Returns: Nothing *
379 \********************************************************************/
380 void
381 gnc_split_scm_set_reconcile_state(SCM split_scm, char reconcile_state)
382 {
383  SCM arg;
384 
385  initialize_scm_functions();
386 
387  if (!gnc_is_split_scm(split_scm))
388  return;
389 
390  arg = SCM_MAKE_CHAR(reconcile_state);
391 
392  scm_call_2(setters.split_scm_reconcile_state, split_scm, arg);
393 }
394 
395 
396 /********************************************************************\
397  * gnc_split_scm_set_amount *
398  * set the amount of a scheme split *
399  * *
400  * Args: split_scm - the scheme split *
401  * amount - the amount to set *
402  * Returns: Nothing *
403 \********************************************************************/
404 void
405 gnc_split_scm_set_amount(SCM split_scm, gnc_numeric amount)
406 {
407  SCM arg;
408 
409  initialize_scm_functions();
410 
411  if (!gnc_is_split_scm(split_scm))
412  return;
413 
414  arg = gnc_numeric_to_scm(amount);
415  scm_call_2(setters.split_scm_amount, split_scm, arg);
416 }
417 
418 
419 /********************************************************************\
420  * gnc_split_scm_set_value *
421  * set the value of a scheme split *
422  * *
423  * Args: split_scm - the scheme split *
424  * value - the value to set *
425  * Returns: Nothing *
426 \********************************************************************/
427 void
428 gnc_split_scm_set_value(SCM split_scm, gnc_numeric value)
429 {
430  SCM arg;
431 
432  initialize_scm_functions();
433 
434  if (!gnc_is_split_scm(split_scm))
435  return;
436 
437  arg = gnc_numeric_to_scm(value);
438  scm_call_2(setters.split_scm_value, split_scm, arg);
439 }
440 
441 
442 /********************************************************************\
443  * gnc_split_scm_get_memo *
444  * return the newly allocated memo of a scheme split, or NULL. *
445  * *
446  * Args: split_scm - the scheme split *
447  * Returns: newly allocated memo string, must be freed with g_free *
448 \********************************************************************/
449 char *
450 gnc_split_scm_get_memo(SCM split_scm)
451 {
452  SCM result;
453 
454  initialize_scm_functions();
455 
456  if (!gnc_is_split_scm(split_scm))
457  return NULL;
458 
459  result = scm_call_1(getters.split_scm_memo, split_scm);
460  if (!scm_is_string(result))
461  return NULL;
462 
463  return gnc_scm_to_utf8_string(result);
464 }
465 
466 
467 /**********************************************************************\
468  * gnc_split_scm_get_action *
469  * return the newly allocated action of a scheme split, or NULL. *
470  * *
471  * Args: split_scm - the scheme split *
472  * Returns: newly allocated action string, must be freed with g_free *
473 \**********************************************************************/
474 char *
475 gnc_split_scm_get_action(SCM split_scm)
476 {
477  SCM result;
478 
479  initialize_scm_functions();
480 
481  if (!gnc_is_split_scm(split_scm))
482  return NULL;
483 
484  result = scm_call_1(getters.split_scm_action, split_scm);
485  if (!scm_is_string(result))
486  return NULL;
487 
488  return gnc_scm_to_utf8_string(result);
489 }
490 
491 
492 /********************************************************************\
493  * gnc_split_scm_get_amount *
494  * return the amount of a scheme split *
495  * *
496  * Args: split_scm - the scheme split *
497  * Returns: amount of scheme split *
498 \********************************************************************/
500 gnc_split_scm_get_amount(SCM split_scm)
501 {
502  SCM result;
503 
504  initialize_scm_functions();
505 
506  if (!gnc_is_split_scm(split_scm))
507  return gnc_numeric_zero ();
508 
509  result = scm_call_1(getters.split_scm_amount, split_scm);
510  if (!gnc_numeric_p(result))
511  return gnc_numeric_zero ();
512 
513  return gnc_scm_to_numeric(result);
514 }
515 
516 
517 /********************************************************************\
518  * gnc_split_scm_get_value *
519  * return the value of a scheme split *
520  * *
521  * Args: split_scm - the scheme split *
522  * Returns: value of scheme split *
523 \********************************************************************/
525 gnc_split_scm_get_value(SCM split_scm)
526 {
527  SCM result;
528 
529  initialize_scm_functions();
530 
531  if (!gnc_is_split_scm(split_scm))
532  return gnc_numeric_zero ();
533 
534  result = scm_call_1(getters.split_scm_value, split_scm);
535  if (!gnc_numeric_p(result))
536  return gnc_numeric_zero ();
537 
538  return gnc_scm_to_numeric(result);
539 }
540 
541 
542 /********************************************************************\
543  * gnc_copy_trans *
544  * returns a scheme representation of a transaction. If the *
545  * transaction is NULL, SCM_UNDEFINED is returned. *
546  * *
547  * Args: trans - the transaction to copy *
548  * use_cut_semantics - if TRUE, copy is for a 'cut' operation *
549  * Returns: SCM representation of transaction or SCM_UNDEFINED *
550 \********************************************************************/
551 SCM
552 gnc_copy_trans(Transaction *trans, gboolean use_cut_semantics)
553 {
554  static swig_type_info *trans_type = NULL;
555  SCM func;
556  SCM arg;
557 
558  if (trans == NULL)
559  return SCM_UNDEFINED;
560 
561  func = scm_c_eval_string("gnc:transaction->transaction-scm");
562  if (!scm_is_procedure(func))
563  return SCM_UNDEFINED;
564 
565  if (!trans_type)
566  trans_type = SWIG_TypeQuery("_p_Transaction");
567 
568  arg = SWIG_NewPointerObj(trans, trans_type, 0);
569 
570  return scm_call_2(func, arg, SCM_BOOL(use_cut_semantics));
571 }
572 
573 
574 /********************************************************************\
575  * gnc_copy_trans_scm_onto_trans *
576  * copies a scheme representation of a transaction onto *
577  * an actual transaction. *
578  * *
579  * Args: trans_scm - the scheme representation of a transaction *
580  * trans - the transaction to copy onto *
581  * Returns: Nothing *
582 \********************************************************************/
583 void
584 gnc_copy_trans_scm_onto_trans(SCM trans_scm, Transaction *trans,
585  gboolean do_commit, QofBook *book)
586 {
587  gnc_copy_trans_scm_onto_trans_swap_accounts(trans_scm, trans, NULL, NULL,
588  do_commit, book);
589 }
590 
591 
592 /********************************************************************\
593  * gnc_copy_trans_scm_onto_trans_swap_accounts *
594  * copies a scheme representation of a transaction onto *
595  * an actual transaction. If guid_1 and guid_2 are not NULL, *
596  * the account guids of the splits are swapped accordingly. *
597  * *
598  * Args: trans_scm - the scheme representation of a transaction *
599  * trans - the transaction to copy onto *
600  * guid_1 - account guid to swap with guid_2 *
601  * guid_2 - account guid to swap with guid_1 *
602  * do_commit - whether to commit the edits *
603  * Returns: Nothing *
604 \********************************************************************/
605 void
606 gnc_copy_trans_scm_onto_trans_swap_accounts(SCM trans_scm,
607  Transaction *trans,
608  const GncGUID *guid_1,
609  const GncGUID *guid_2,
610  gboolean do_commit,
611  QofBook *book)
612 {
613  static swig_type_info *trans_type = NULL;
614  SCM result;
615  SCM func;
616  SCM arg;
617 
618  if (trans_scm == SCM_UNDEFINED)
619  return;
620 
621  if (trans == NULL)
622  return;
623 
624  g_return_if_fail (book);
625 
626  func = scm_c_eval_string("gnc:transaction-scm?");
627  if (!scm_is_procedure(func))
628  return;
629 
630  result = scm_call_1(func, trans_scm);
631  if (!scm_is_true(result))
632  return;
633 
634  func = scm_c_eval_string("gnc:transaction-scm-onto-transaction");
635  if (!scm_is_procedure(func))
636  return;
637 
638  if (!trans_type)
639  trans_type = SWIG_TypeQuery("_p_Transaction");
640 
641  arg = SWIG_NewPointerObj(trans, trans_type, 0);
642 
643  if ((guid_1 == NULL) || (guid_2 == NULL))
644  {
645  SCM args = SCM_EOL;
646  SCM commit;
647 
648  commit = SCM_BOOL(do_commit);
649 
650  args = scm_cons(gnc_book_to_scm (book), args);
651  args = scm_cons(commit, args);
652  args = scm_cons(SCM_EOL, args);
653  args = scm_cons(arg, args);
654  args = scm_cons(trans_scm, args);
655 
656  scm_apply(func, args, SCM_EOL);
657  }
658  else
659  {
660  gchar guidstr[GUID_ENCODING_LENGTH+1];
661  SCM from, to;
662  SCM map = SCM_EOL;
663  SCM args = SCM_EOL;
664  SCM commit;
665 
666  args = scm_cons(gnc_book_to_scm (book), args);
667 
668  commit = SCM_BOOL(do_commit);
669 
670  args = scm_cons(commit, args);
671 
672  guid_to_string_buff(guid_1, guidstr);
673  from = scm_from_utf8_string(guidstr);
674  guid_to_string_buff(guid_2, guidstr);
675  to = scm_from_utf8_string(guidstr);
676 
677  map = scm_cons(scm_cons(from, to), map);
678  map = scm_cons(scm_cons(to, from), map);
679 
680  args = scm_cons(map, args);
681  args = scm_cons(arg, args);
682  args = scm_cons(trans_scm, args);
683 
684  scm_apply(func, args, SCM_EOL);
685  }
686 }
687 
688 /********************************************************************\
689  * gnc_trans_scm_set_date *
690  * set the date of a scheme transaction. *
691  * *
692  * Args: trans_scm - the scheme transaction *
693  * ts - the time to set *
694  * Returns: Nothing *
695 \********************************************************************/
696 void
697 gnc_trans_scm_set_date(SCM trans_scm, Timespec *ts)
698 {
699  SCM arg;
700 
701  initialize_scm_functions();
702 
703  if (!gnc_is_trans_scm(trans_scm))
704  return;
705  if (ts == NULL)
706  return;
707 
708  arg = gnc_timespec2timepair(*ts);
709 
710  scm_call_2(setters.trans_scm_date, trans_scm, arg);
711 }
712 
713 
714 /********************************************************************\
715  * gnc_trans_scm_set_num *
716  * set the num of a scheme transaction. *
717  * *
718  * Args: trans_scm - the scheme transaction *
719  * num - the num to set *
720  * Returns: Nothing *
721 \********************************************************************/
722 void
723 gnc_trans_scm_set_num(SCM trans_scm, const char *num)
724 {
725  SCM arg;
726 
727  initialize_scm_functions();
728 
729  if (!gnc_is_trans_scm(trans_scm))
730  return;
731  if (num == NULL)
732  return;
733 
734  arg = scm_from_utf8_string(num);
735 
736  scm_call_2(setters.trans_scm_num, trans_scm, arg);
737 }
738 
739 
740 /********************************************************************\
741  * gnc_trans_scm_set_description *
742  * set the description of a scheme transaction. *
743  * *
744  * Args: trans_scm - the scheme transaction *
745  * description - the description to set *
746  * Returns: Nothing *
747 \********************************************************************/
748 void
749 gnc_trans_scm_set_description(SCM trans_scm, const char *description)
750 {
751  SCM arg;
752 
753  initialize_scm_functions();
754 
755  if (!gnc_is_trans_scm(trans_scm))
756  return;
757  if (description == NULL)
758  return;
759 
760  arg = scm_from_utf8_string(description);
761 
762  scm_call_2(setters.trans_scm_description, trans_scm, arg);
763 }
764 
765 
766 /********************************************************************\
767  * gnc_trans_scm_set_notes *
768  * set the notes of a scheme transaction. *
769  * *
770  * Args: trans_scm - the scheme transaction *
771  * notes - the notes to set *
772  * Returns: Nothing *
773 \********************************************************************/
774 void
775 gnc_trans_scm_set_notes(SCM trans_scm, const char *notes)
776 {
777  SCM arg;
778 
779  initialize_scm_functions();
780 
781  if (!gnc_is_trans_scm(trans_scm))
782  return;
783  if (notes == NULL)
784  return;
785 
786  arg = scm_from_utf8_string(notes);
787 
788  scm_call_2(setters.trans_scm_notes, trans_scm, arg);
789 }
790 
791 
792 /********************************************************************\
793  * gnc_trans_scm_append_split_scm *
794  * append the scheme split onto the scheme transaction *
795  * *
796  * Args: trans_scm - the scheme transaction *
797  * split_scm - the scheme split to append *
798  * Returns: Nothing *
799 \********************************************************************/
800 void
801 gnc_trans_scm_append_split_scm(SCM trans_scm, SCM split_scm)
802 {
803  initialize_scm_functions();
804 
805  if (!gnc_is_trans_scm(trans_scm))
806  return;
807  if (!gnc_is_split_scm(split_scm))
808  return;
809 
810  scm_call_2(setters.trans_scm_append_split_scm, trans_scm, split_scm);
811 }
812 
813 
814 /********************************************************************\
815  * gnc_trans_scm_get_split_scm *
816  * get the indexth scheme split of a scheme transaction. *
817  * *
818  * Args: trans_scm - the scheme transaction *
819  * index - the index of the split to get *
820  * Returns: scheme split to get, or SCM_UNDEFINED if none *
821 \********************************************************************/
822 SCM
823 gnc_trans_scm_get_split_scm(SCM trans_scm, int index)
824 {
825  SCM arg;
826 
827  initialize_scm_functions();
828 
829  if (!gnc_is_trans_scm(trans_scm))
830  return SCM_UNDEFINED;
831 
832  arg = scm_from_int (index);
833 
834  return scm_call_2(getters.trans_scm_split_scm, trans_scm, arg);
835 }
836 
837 
838 /********************************************************************\
839  * gnc_trans_scm_get_other_split_scm *
840  * get the other scheme split of a scheme transaction. *
841  * *
842  * Args: trans_scm - the scheme transaction *
843  * split_scm - the split not to get *
844  * Returns: other scheme split, or SCM_UNDEFINED if none *
845 \********************************************************************/
846 SCM
847 gnc_trans_scm_get_other_split_scm(SCM trans_scm, SCM split_scm)
848 {
849  SCM result;
850 
851  initialize_scm_functions();
852 
853  if (!gnc_is_trans_scm(trans_scm))
854  return SCM_UNDEFINED;
855  if (!gnc_is_split_scm(split_scm))
856  return SCM_UNDEFINED;
857 
858  result = scm_call_2(getters.trans_scm_other_split_scm, trans_scm, split_scm);
859 
860  if (!gnc_is_split_scm(result))
861  return SCM_UNDEFINED;
862 
863  return result;
864 }
865 
866 
867 /********************************************************************\
868  * gnc_trans_scm_get_num_splits *
869  * get the number of scheme splits in a scheme transaction. *
870  * *
871  * Args: trans_scm - the scheme transaction *
872  * Returns: number of scheme splits in the transaction *
873 \********************************************************************/
874 int
875 gnc_trans_scm_get_num_splits(SCM trans_scm)
876 {
877  SCM result;
878 
879  initialize_scm_functions();
880 
881  if (!gnc_is_trans_scm(trans_scm))
882  return 0;
883 
884  result = scm_call_1(getters.trans_scm_split_scms, trans_scm);
885 
886  if (!scm_is_list(result))
887  return 0;
888 
889  return scm_to_int(scm_length(result));
890 }
891 
892 
893 /********************************************************************\
894  * gnc_get_debit_string *
895  * return a debit string for a given account type *
896  * *
897  * Args: account_type - type of account to get debit string for *
898  * Return: g_malloc'd debit string or NULL *
899 \********************************************************************/
900 char *
901 gnc_get_debit_string(GNCAccountType account_type)
902 {
903  SCM result;
904  SCM arg;
905 
906  initialize_scm_functions();
907 
908  if (gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_ACCOUNTING_LABELS))
909  return g_strdup(_("Debit"));
910 
911  if ((account_type < ACCT_TYPE_NONE) || (account_type >= NUM_ACCOUNT_TYPES))
912  account_type = ACCT_TYPE_NONE;
913 
914  arg = scm_from_long (account_type);
915 
916  result = scm_call_1(getters.debit_string, arg);
917  if (!scm_is_string(result))
918  return NULL;
919 
920  return scm_to_utf8_string(result);
921 }
922 
923 
924 /************************************************************************\
925  * gnc_get_credit_string *
926  * return a credit string for a given account type *
927  * *
928  * Args: account_type - type of account to get credit string for *
929  * Return: g_malloc'd credit string or NULL, must be freed with g_free *
930 \************************************************************************/
931 char *
932 gnc_get_credit_string(GNCAccountType account_type)
933 {
934  SCM result;
935  SCM arg;
936 
937  initialize_scm_functions();
938 
939  if (gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_ACCOUNTING_LABELS))
940  return g_strdup(_("Credit"));
941 
942  if ((account_type < ACCT_TYPE_NONE) || (account_type >= NUM_ACCOUNT_TYPES))
943  account_type = ACCT_TYPE_NONE;
944 
945  arg = scm_from_long (account_type);
946 
947  result = scm_call_1(getters.credit_string, arg);
948  if (!scm_is_string(result))
949  return NULL;
950 
951  return gnc_scm_to_utf8_string(result);
952 }
953 
954 
955 static void
956 on_child_exit (GPid pid, gint status, gpointer data)
957 {
958  Process *proc = data;
959  g_return_if_fail (proc && proc->pid == pid);
960 
961  g_spawn_close_pid (proc->pid);
962 
963  /* free if the process is both dead and detached */
964  if (!proc->detached)
965  proc->dead = TRUE;
966  else
967  g_free (proc);
968 }
969 
970 Process *
971 gnc_spawn_process_async (GList *argl, const gboolean search_path)
972 {
973  gboolean retval;
974  Process *proc;
975  GList *l_iter;
976  guint argc;
977  gchar **argv, **v_iter;
978  GSpawnFlags flags;
979  GError *error = NULL;
980 
981  proc = g_new0 (Process, 1);
982 
983  argc = g_list_length (argl);
984  argv = g_malloc ((argc + 1) * sizeof(gchar*));
985 
986  for (l_iter = argl, v_iter = argv; l_iter; l_iter = l_iter->next, v_iter++)
987  {
988  *v_iter = (gchar*) l_iter->data;
989  }
990  *v_iter = NULL;
991  g_list_free (argl);
992 
993  flags = G_SPAWN_DO_NOT_REAP_CHILD;
994  if (search_path)
995  flags |= G_SPAWN_SEARCH_PATH;
996 
997  retval = g_spawn_async_with_pipes (
998  NULL, argv, NULL, flags, NULL, NULL, &proc->pid,
999  &proc->fd_stdin, &proc->fd_stdout, &proc->fd_stderr, &error);
1000 
1001  if (retval)
1002  {
1003  g_child_watch_add (proc->pid, on_child_exit, proc);
1004  }
1005  else
1006  {
1007  g_warning ("Could not spawn %s: %s", *argv ? *argv : "(null)",
1008  error->message ? error->message : "(null)");
1009  g_free (proc);
1010  proc = NULL;
1011  }
1012  g_strfreev (argv);
1013 
1014  return proc;
1015 }
1016 
1017 gint
1018 gnc_process_get_fd (const Process *proc, const gint std_fd)
1019 {
1020  const gint *retptr = NULL;
1021  g_return_val_if_fail (proc, -1);
1022 
1023  if (std_fd == 0)
1024  retptr = &proc->fd_stdin;
1025  else if (std_fd == 1)
1026  retptr = &proc->fd_stdout;
1027  else if (std_fd == 2)
1028  retptr = &proc->fd_stderr;
1029  else
1030  g_return_val_if_reached (-1);
1031 
1032  if (*retptr == -1)
1033  g_warning ("Pipe to childs file descriptor %d is -1", std_fd);
1034  return *retptr;
1035 }
1036 
1037 void
1038 gnc_detach_process (Process *proc, const gboolean kill_it)
1039 {
1040  g_return_if_fail (proc && proc->pid);
1041 
1042  errno = 0;
1043  close (proc->fd_stdin);
1044  if (errno)
1045  {
1046  g_message ("Close of childs stdin (%d) failed: %s", proc->fd_stdin,
1047  g_strerror (errno));
1048  errno = 0;
1049  }
1050  close (proc->fd_stdout);
1051  if (errno)
1052  {
1053  g_message ("Close of childs stdout (%d) failed: %s", proc->fd_stdout,
1054  g_strerror(errno));
1055  errno = 0;
1056  }
1057  close (proc->fd_stderr);
1058  if (errno)
1059  {
1060  g_message ("Close of childs stderr (%d) failed: %s", proc->fd_stderr,
1061  g_strerror(errno));
1062  errno = 0;
1063  }
1064 
1065  if (kill_it && !proc->dead)
1066  {
1067  /* give it a chance to die */
1068  while (g_main_context_iteration (NULL, FALSE) && !proc->dead)
1069  ;
1070  if (!proc->dead)
1071  gnc_gpid_kill (proc->pid);
1072  }
1073 
1074  /* free if the process is both dead and detached */
1075  if (!proc->dead)
1076  proc->detached = TRUE;
1077  else
1078  g_free (proc);
1079 }
1080 
1081 
1082 time64
1083 gnc_parse_time_to_time64 (const gchar *s, const gchar *format)
1084 {
1085  struct tm tm;
1086 
1087  g_return_val_if_fail(s && format, -1);
1088 
1089  if (!strptime(s, format, &tm))
1090  return -1;
1091 
1092  return gnc_mktime(&tm);
1093 }
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
Definition: guid.h:65
#define xaccAccountGetGUID(X)
Definition: Account.h:239
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
GNCAccountType
Definition: Account.h:96
GLib helper routines.
Generic api to store and retrieve preferences.
void gnc_gpid_kill(GPid pid)
Definition: SplitP.h:71
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
gint64 time64
Definition: gnc-date.h:83
const gchar * QofLogModule
Definition: qofid.h:89