GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnucash-bin.c
1 /*
2  * gnucash-bin.c -- The program entry point for GnuCash
3  *
4  * Copyright (C) 2006 Chris Shoemaker <[email protected]>
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, contact:
18  *
19  * Free Software Foundation Voice: +1-617-542-5942
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21  * Boston, MA 02110-1301, USA [email protected]
22  */
23 #include "config.h"
24 
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <libguile.h>
29 #include <gtk/gtk.h>
30 #include <glib/gi18n.h>
31 #include "glib.h"
32 #include "gnc-module.h"
33 #include "gnc-path.h"
34 #include "binreloc.h"
35 #include "gnc-locale-utils.h"
36 #include "core-utils/gnc-version.h"
37 #include "gnc-engine.h"
38 #include "gnc-environment.h"
39 #include "gnc-filepath-utils.h"
40 #include "gnc-ui-util.h"
41 #include "gnc-file.h"
42 #include "gnc-hooks.h"
43 #include "top-level.h"
44 #include "gfec.h"
45 #include "gnc-commodity.h"
46 #include "gnc-prefs.h"
47 #include "gnc-prefs-utils.h"
48 #include "gnc-gsettings.h"
49 #include "gnc-report.h"
50 #include "gnc-main-window.h"
51 #include "gnc-splash.h"
52 #include "gnc-gnome-utils.h"
54 #include "dialog-new-user.h"
55 #include "gnc-session.h"
56 #include "engine-helpers-guile.h"
57 #include "swig-runtime.h"
58 
59 /* This static indicates the debugging module that this .o belongs to. */
60 static QofLogModule log_module = GNC_MOD_GUI;
61 
62 #ifdef HAVE_GETTEXT
63 # include <libintl.h>
64 # include <locale.h>
65 #endif
66 
67 #ifdef MAC_INTEGRATION
68 # include <Foundation/Foundation.h>
69 #endif
70 
71 /* GNUCASH_SCM is defined whenever we're building from an svn/svk/git/bzr tree */
72 #ifdef GNUCASH_SCM
73 static int is_development_version = TRUE;
74 #else
75 static int is_development_version = FALSE;
76 #define GNUCASH_SCM ""
77 #endif
78 
79 /* Command-line option variables */
80 static int gnucash_show_version = 0;
81 static int debugging = 0;
82 static int extra = 0;
83 static gchar **log_flags = NULL;
84 static gchar *log_to_filename = NULL;
85 static int nofile = 0;
86 static const gchar *gsettings_prefix = NULL;
87 static const char *add_quotes_file = NULL;
88 static char *namespace_regexp = NULL;
89 static const char *file_to_load = NULL;
90 static gchar **args_remaining = NULL;
91 
92 static GOptionEntry options[] =
93 {
94  {
95  "version", 'v', 0, G_OPTION_ARG_NONE, &gnucash_show_version,
96  N_("Show GnuCash version"), NULL
97  },
98 
99  {
100  "debug", '\0', 0, G_OPTION_ARG_NONE, &debugging,
101  N_("Enable debugging mode: increasing logging to provide deep detail."), NULL
102  },
103 
104  {
105  "extra", '\0', 0, G_OPTION_ARG_NONE, &extra,
106  N_("Enable extra/development/debugging features."), NULL
107  },
108 
109  {
110  "log", '\0', 0, G_OPTION_ARG_STRING_ARRAY, &log_flags,
111  N_("Log level overrides, of the form \"log.ger.path={debug,info,warn,crit,error}\""),
112  NULL
113  },
114 
115  {
116  "logto", '\0', 0, G_OPTION_ARG_STRING, &log_to_filename,
117  N_("File to log into; defaults to \"/tmp/gnucash.trace\"; can be \"stderr\" or \"stdout\"."),
118  NULL
119  },
120 
121  {
122  "nofile", '\0', 0, G_OPTION_ARG_NONE, &nofile,
123  N_("Do not load the last file opened"), NULL
124  },
125  {
126  "gsettings-prefix", '\0', 0, G_OPTION_ARG_STRING, &gsettings_prefix,
127  N_("Set the prefix for gsettings schemas for gsettings queries. This can be useful to have a different settings tree while debugging."),
128  /* Translators: Argument description for autohelp; see
129  http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
130  N_("GSETTINGSPREFIX")
131  },
132  {
133  "add-price-quotes", '\0', 0, G_OPTION_ARG_STRING, &add_quotes_file,
134  N_("Add price quotes to given GnuCash datafile"),
135  /* Translators: Argument description for autohelp; see
136  http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
137  N_("FILE")
138  },
139  {
140  "namespace", '\0', 0, G_OPTION_ARG_STRING, &namespace_regexp,
141  N_("Regular expression determining which namespace commodities will be retrieved"),
142  /* Translators: Argument description for autohelp; see
143  http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
144  N_("REGEXP")
145  },
146  {
147  G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, N_("[datafile]") },
148  { NULL }
149 };
150 
151 static void
152 gnc_print_unstable_message(void)
153 {
154  if (!is_development_version) return;
155 
156  g_print("\n\n%s\n%s\n%s\n%s\n",
157  _("This is a development version. It may or may not work."),
158  _("Report bugs and other problems to [email protected]"),
159  _("You can also lookup and file bug reports at http://bugzilla.gnome.org"),
160  _("To find the last stable version, please refer to http://www.gnucash.org"));
161 }
162 
163 #ifdef MAC_INTEGRATION
164 static void
165 set_mac_locale()
166 {
167  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
168  NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
169  NSArray *languages = [defs objectForKey: @"AppleLanguages"];
170  const gchar *langs = NULL;
171  NSLocale *locale = [NSLocale currentLocale];
172  NSString *locale_str;
173  @try
174  {
175  locale_str = [[[locale objectForKey: NSLocaleLanguageCode]
176  stringByAppendingString: @"_"]
177  stringByAppendingString:
178  [locale objectForKey: NSLocaleCountryCode]];
179  }
180  @catch (NSException *err)
181  {
182  PWARN("Locale detection raised error %s: %s. "
183  "Check that your locale settings in "
184  "System Preferences>Languages & Text are set correctly.",
185  [[err name] UTF8String], [[err reason] UTF8String]);
186  locale_str = @"_";
187  }
188 /* If we didn't get a valid current locale, the string will be just "_" */
189  if ([locale_str isEqualToString: @"_"])
190  locale_str = @"en_US";
191 
192  if (!setlocale(LC_ALL, [locale_str UTF8String]))
193  {
194  NSArray *all_locales = [NSLocale availableLocaleIdentifiers];
195  NSEnumerator *locale_iter = [all_locales objectEnumerator];
196  NSString *this_locale, *new_locale = nil;
197  NSString *lang = [locale objectForKey: NSLocaleLanguageCode];
198  PWARN("Apple Locale is set to a value %s not supported"
199  " by the C runtime", [locale_str UTF8String]);
200  while ((this_locale = (NSString*)[locale_iter nextObject]))
201  if ([[[NSLocale componentsFromLocaleIdentifier: this_locale]
202  objectForKey: NSLocaleLanguageCode]
203  isEqualToString: lang] &&
204  setlocale (LC_ALL, [this_locale UTF8String]))
205  {
206  new_locale = this_locale;
207  break;
208  }
209  if (new_locale)
210  locale_str = new_locale;
211  else
212  {
213  locale_str = @"en_US";
214  setlocale(LC_ALL, [locale_str UTF8String]);
215  }
216  PWARN("Using %s instead.", [locale_str UTF8String]);
217  }
218  if (g_getenv("LANG") == NULL)
219  g_setenv("LANG", [locale_str UTF8String], TRUE);
220 /* If the currency doesn't match the base locale, we need to find a locale that does match, because setlocale won't know what to do with just a currency identifier. */
221  if (![[locale objectForKey: NSLocaleCurrencyCode] isEqualToString:
222  [[[NSLocale alloc] initWithLocaleIdentifier: locale_str] objectForKey: NSLocaleCurrencyCode]]) {
223  NSArray *all_locales = [NSLocale availableLocaleIdentifiers];
224  NSEnumerator *locale_iter = [all_locales objectEnumerator];
225  NSString *this_locale;
226  NSString *currency = [locale objectForKey: NSLocaleCurrencyCode];
227  NSString *money_locale = nil;
228  while ((this_locale = (NSString*)[locale_iter nextObject]))
229  {
230  NSLocale *templocale = [[NSLocale alloc]
231  initWithLocaleIdentifier: this_locale];
232  if ([[templocale objectForKey: NSLocaleCurrencyCode]
233  isEqualToString: currency])
234  {
235  money_locale = this_locale;
236  [templocale release];
237  break;
238  }
239  [templocale release];
240  }
241  if (money_locale)
242  setlocale(LC_MONETARY, [money_locale UTF8String]);
243  }
244 /* Now call gnc_localeconv() to force creation of the app locale
245  * before another call to setlocale messes it up. */
246  gnc_localeconv ();
247 /* Process the language list.
248  *
249  * Language subgroups (e.g., US English) are reported in the form
250  * "ll-SS" (e.g. again, "en-US"), not what gettext wants. We convert
251  * those to old-style locales, which is easy for most cases. There are
252  * two where it isn't, though: Simplified Chinese (zh-Hans) and
253  * traditional Chinese (zh-Hant), which are normally assigned the
254  * locales zh_CN and zh_TW, respectively. Those are handled
255  * specially.*/
256  if ([languages count] > 0) {
257  NSEnumerator *lang_iter = [languages objectEnumerator];
258  NSString *this_lang;
259  NSArray *elements;
260  NSArray *new_languages = [NSArray array];
261  while ((this_lang = [lang_iter nextObject])) {
262  this_lang = [this_lang stringByTrimmingCharactersInSet:
263  [NSCharacterSet characterSetWithCharactersInString:
264  @"\""]];
265  elements = [this_lang componentsSeparatedByString: @"-"];
266  if ([elements count] > 1) {
267  if ([[elements objectAtIndex: 0] isEqualToString: @"zh"]) {
268  if ([[elements objectAtIndex: 1] isEqualToString: @"Hans"])
269  this_lang = @"zh_CN";
270  else
271  this_lang = @"zh_TW";
272  }
273  else
274  this_lang = [elements componentsJoinedByString: @"_"];
275  }
276  new_languages = [new_languages arrayByAddingObject: this_lang];
277 /* If it's an English language, add the "C" locale after it so that
278  * any messages can default to it */
279  if ( [[elements objectAtIndex: 0] isEqualToString: @"en"])
280  new_languages = [new_languages arrayByAddingObject: @"C"];
281 
282  }
283  langs = [[new_languages componentsJoinedByString:@":"] UTF8String];
284  }
285  if (langs && strlen(langs) > 0)
286  g_setenv("LANGUAGE", langs, TRUE);
287  [pool drain];
288 }
289 #endif /* MAC_INTEGRATION */
290 
291 static gboolean
292 try_load_config_array(const gchar *fns[])
293 {
294  gchar *filename;
295  int i;
296 
297  for (i = 0; fns[i]; i++)
298  {
299  filename = gnc_build_dotgnucash_path(fns[i]);
300  if (gfec_try_load(filename))
301  {
302  g_free(filename);
303  return TRUE;
304  }
305  g_free(filename);
306  }
307  return FALSE;
308 }
309 
310 static void
311 update_message(const gchar *msg)
312 {
313  gnc_update_splash_screen(msg, GNC_SPLASH_PERCENTAGE_UNKNOWN);
314  g_message("%s", msg);
315 }
316 
317 static void
318 load_system_config(void)
319 {
320  static int is_system_config_loaded = FALSE;
321  gchar *system_config_dir;
322  gchar *system_config;
323 
324  if (is_system_config_loaded) return;
325 
326  update_message("loading system configuration");
327  system_config_dir = gnc_path_get_pkgsysconfdir();
328  system_config = g_build_filename(system_config_dir, "config", NULL);
329  is_system_config_loaded = gfec_try_load(system_config);
330  g_free(system_config_dir);
331  g_free(system_config);
332 }
333 
334 static void
335 load_user_config(void)
336 {
337  /* Don't continue adding to this list. When 2.0 rolls around bump
338  the 1.4 (unnumbered) files off the list. */
339  static const gchar *user_config_files[] =
340  {
341  "config-2.0.user", "config-1.8.user", "config-1.6.user",
342  "config.user", NULL
343  };
344  static const gchar *auto_config_files[] =
345  {
346  "config-2.0.auto", "config-1.8.auto", "config-1.6.auto",
347  "config.auto", NULL
348  };
349  static const gchar *saved_report_files[] =
350  {
351  SAVED_REPORTS_FILE, SAVED_REPORTS_FILE_OLD_REV, NULL
352  };
353  static const gchar *stylesheet_files[] = { "stylesheets-2.0", NULL};
354  static int is_user_config_loaded = FALSE;
355 
356  if (is_user_config_loaded)
357  return;
358  else is_user_config_loaded = TRUE;
359 
360  update_message("loading user configuration");
361  try_load_config_array(user_config_files);
362  update_message("loading auto configuration");
363  try_load_config_array(auto_config_files);
364  update_message("loading saved reports");
365  try_load_config_array(saved_report_files);
366  update_message("loading stylesheets");
367  try_load_config_array(stylesheet_files);
368 }
369 
370 /* Parse command line options, using GOption interface.
371  * We can't let gtk_init_with_args do it because it fails
372  * before parsing any arguments if the GUI can't be initialized.
373  */
374 static void
375 gnc_parse_command_line(int *argc, char ***argv)
376 {
377 
378  GError *error = NULL;
379  GOptionContext *context = g_option_context_new (_("- GnuCash personal and small business finance management"));
380 
381  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
382  g_option_context_add_group (context, gtk_get_option_group(FALSE));
383  if (!g_option_context_parse (context, argc, argv, &error))
384  {
385  g_printerr (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
386  error->message, *argv[0]);
387  g_error_free (error);
388  exit (1);
389  }
390  g_option_context_free (context);
391 
392  if (gnucash_show_version)
393  {
394  gchar *fixed_message;
395 
396  if (is_development_version)
397  {
398  fixed_message = g_strdup_printf(_("GnuCash %s development version"), VERSION);
399 
400  /* Translators: 1st %s is a fixed message, which is translated independently;
401  2nd %s is the scm type (svn/svk/git/bzr);
402  3rd %s is the scm revision number;
403  4th %s is the build date */
404  g_print ( _("%s\nThis copy was built from %s rev %s on %s."),
405  fixed_message, GNUCASH_SCM, GNUCASH_SCM_REV,
406  GNUCASH_BUILD_DATE );
407  }
408  else
409  {
410  fixed_message = g_strdup_printf(_("GnuCash %s"), VERSION);
411 
412  /* Translators: 1st %s is a fixed message, which is translated independently;
413  2nd %s is the scm (svn/svk/git/bzr) revision number;
414  3rd %s is the build date */
415  g_print ( _("%s\nThis copy was built from rev %s on %s."),
416  fixed_message, GNUCASH_SCM_REV, GNUCASH_BUILD_DATE );
417  }
418  g_print("\n");
419  g_free (fixed_message);
420  exit(0);
421  }
422 
423  gnc_prefs_set_debugging(debugging);
424  gnc_prefs_set_extra(extra);
425 
426  if (gsettings_prefix)
427  gnc_gsettings_set_prefix(g_strdup(gsettings_prefix));
428 
429  if (namespace_regexp)
430  gnc_prefs_set_namespace_regexp(namespace_regexp);
431 
432  if (args_remaining)
433  file_to_load = args_remaining[0];
434 }
435 
436 static void
437 load_gnucash_modules()
438 {
439  int i, len;
440  struct
441  {
442  gchar * name;
443  int version;
444  gboolean optional;
445  } modules[] =
446  {
447  { "gnucash/app-utils", 0, FALSE },
448  { "gnucash/engine", 0, FALSE },
449  { "gnucash/register/ledger-core", 0, FALSE },
450  { "gnucash/register/register-core", 0, FALSE },
451  { "gnucash/register/register-gnome", 0, FALSE },
452  { "gnucash/import-export/qif-import", 0, FALSE },
453  { "gnucash/import-export/ofx", 0, TRUE },
454  { "gnucash/import-export/csv-import", 0, TRUE },
455  { "gnucash/import-export/csv-export", 0, TRUE },
456  { "gnucash/import-export/log-replay", 0, TRUE },
457  { "gnucash/import-export/aqbanking", 0, TRUE },
458  { "gnucash/report/report-system", 0, FALSE },
459  { "gnucash/report/stylesheets", 0, FALSE },
460  { "gnucash/report/standard-reports", 0, FALSE },
461  { "gnucash/report/utility-reports", 0, FALSE },
462  { "gnucash/report/locale-specific/us", 0, FALSE },
463  { "gnucash/report/report-gnome", 0, FALSE },
464  { "gnucash/business-gnome", 0, TRUE },
465  { "gnucash/gtkmm", 0, TRUE },
466  { "gnucash/python", 0, TRUE },
467  { "gnucash/plugins/bi_import", 0, TRUE},
468  { "gnucash/plugins/customer_import", 0, TRUE},
469  };
470 
471  /* module initializations go here */
472  len = sizeof(modules) / sizeof(*modules);
473  for (i = 0; i < len; i++)
474  {
475  DEBUG("Loading module %s started", modules[i].name);
476  gnc_update_splash_screen(modules[i].name, GNC_SPLASH_PERCENTAGE_UNKNOWN);
477  if (modules[i].optional)
478  gnc_module_load_optional(modules[i].name, modules[i].version);
479  else
480  gnc_module_load(modules[i].name, modules[i].version);
481  DEBUG("Loading module %s finished", modules[i].name);
482  }
483  if (!gnc_engine_is_initialized())
484  {
485  /* On Windows this check used to fail anyway, see
486  * https://lists.gnucash.org/pipermail/gnucash-devel/2006-September/018529.html
487  * but more recently it seems to work as expected
488  * again. 2006-12-20, cstim. */
489  g_warning("GnuCash engine failed to initialize. Exiting.\n");
490  exit(1);
491  }
492 }
493 
494 static void
495 inner_main_add_price_quotes(void *closure, int argc, char **argv)
496 {
497  SCM mod, add_quotes, scm_book, scm_result = SCM_BOOL_F;
498  QofSession *session = NULL;
499 
500  scm_c_eval_string("(debug-set! stack 200000)");
501 
502  mod = scm_c_resolve_module("gnucash price-quotes");
503  scm_set_current_module(mod);
504 
505  /* Don't load the modules since the stylesheet module crashes if the
506  GUI is not initialized */
507 #ifdef PRICE_QUOTES_NEED_MODULES
508  load_gnucash_modules();
509 #endif
510  gnc_prefs_init ();
511  qof_event_suspend();
512  scm_c_eval_string("(gnc:price-quotes-install-sources)");
513 
514  if (!gnc_quote_source_fq_installed())
515  {
516  g_print("%s", _("No quotes retrieved. Finance::Quote isn't "
517  "installed properly.\n"));
518  goto fail;
519  }
520 
521  add_quotes = scm_c_eval_string("gnc:book-add-quotes");
522  session = gnc_get_current_session();
523  if (!session) goto fail;
524 
525  qof_session_begin(session, add_quotes_file, FALSE, FALSE, FALSE);
526  if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
527 
528  qof_session_load(session, NULL);
529  if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
530 
531  scm_book = gnc_book_to_scm(qof_session_get_book(session));
532  scm_result = scm_call_2(add_quotes, SCM_BOOL_F, scm_book);
533 
534  qof_session_save(session, NULL);
535  if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
536 
537  qof_session_destroy(session);
538  if (!scm_is_true(scm_result))
539  {
540  g_warning("Failed to add quotes to %s.", add_quotes_file);
541  goto fail;
542  }
543 
544  qof_event_resume();
545  gnc_shutdown(0);
546  return;
547 fail:
548  if (session && qof_session_get_error(session) != ERR_BACKEND_NO_ERR)
549  g_warning("Session Error: %s", qof_session_get_error_message(session));
550  qof_event_resume();
551  gnc_shutdown(1);
552 }
553 
554 static char *
555 get_file_to_load()
556 {
557  if (file_to_load)
558  return g_strdup(file_to_load);
559  else
560  return gnc_history_get_last();
561 }
562 
563 static void
564 inner_main (void *closure, int argc, char **argv)
565 {
566  SCM main_mod;
567  char* fn;
568  GError *error = NULL;
569 
570  scm_c_eval_string("(debug-set! stack 200000)");
571 
572  main_mod = scm_c_resolve_module("gnucash main");
573  scm_set_current_module(main_mod);
574 
575  /* GnuCash switched to gsettings to store its preferences in version 2.5.6
576  * Migrate the user's preferences from gconf if needed */
577  gnc_gsettings_migrate_from_gconf();
578 
579  load_gnucash_modules();
580 
581  /* Load the config before starting up the gui. This insures that
582  * custom reports have been read into memory before the Reports
583  * menu is created. */
584  load_system_config();
585  load_user_config();
586 
587  /* Setting-up the report menu must come after the module
588  loading but before the gui initialization. */
589  scm_c_use_module("gnucash report report-gnome");
590  scm_c_eval_string("(gnc:report-menu-setup)");
591 
592  /* TODO: After some more guile-extraction, this should happen even
593  before booting guile. */
594  gnc_main_gui_init();
595 
596  gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL);
597 
598  /* Install Price Quote Sources */
599  gnc_update_splash_screen(_("Checking Finance::Quote..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
600  scm_c_use_module("gnucash price-quotes");
601  scm_c_eval_string("(gnc:price-quotes-install-sources)");
602 
603  gnc_hook_run(HOOK_STARTUP, NULL);
604 
605  if (!nofile && (fn = get_file_to_load()))
606  {
607  gnc_update_splash_screen(_("Loading data..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
608  gnc_file_open_file(fn, /*open_readonly*/ FALSE);
609  g_free(fn);
610  }
611  else if (gnc_prefs_get_bool(GNC_PREFS_GROUP_NEW_USER, GNC_PREF_FIRST_STARTUP))
612  {
613  gnc_destroy_splash_screen();
614  gnc_ui_new_user_dialog();
615  }
616 
617  gnc_destroy_splash_screen();
619 
620  gnc_hook_run(HOOK_UI_POST_STARTUP, NULL);
621  gnc_ui_start_event_loop();
622  gnc_hook_remove_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit);
623 
624  gnc_shutdown(0);
625  return;
626 }
627 
628 static void
629 gnc_log_init()
630 {
631  if (log_to_filename != NULL)
632  {
633  qof_log_init_filename_special(log_to_filename);
634  }
635  else
636  {
637  /* initialize logging to our file. */
638  gchar *tracefilename;
639  tracefilename = g_build_filename(g_get_tmp_dir(), "gnucash.trace",
640  (gchar *)NULL);
641  qof_log_init_filename(tracefilename);
642  g_free(tracefilename);
643  }
644 
645  // set a reasonable default.
646  qof_log_set_default(QOF_LOG_WARNING);
647 
648  gnc_log_default();
649 
650  if (gnc_prefs_is_debugging_enabled())
651  {
652  qof_log_set_level("", QOF_LOG_INFO);
653  qof_log_set_level("qof", QOF_LOG_INFO);
654  qof_log_set_level("gnc", QOF_LOG_INFO);
655  }
656 
657  {
658  gchar *log_config_filename;
659  log_config_filename = gnc_build_dotgnucash_path("log.conf");
660  if (g_file_test(log_config_filename, G_FILE_TEST_EXISTS))
661  qof_log_parse_log_config(log_config_filename);
662  g_free(log_config_filename);
663  }
664 
665  if (log_flags != NULL)
666  {
667  int i = 0;
668  for (; log_flags[i] != NULL; i++)
669  {
670  QofLogLevel level;
671  gchar **parts = NULL;
672 
673  gchar *log_opt = log_flags[i];
674  parts = g_strsplit(log_opt, "=", 2);
675  if (parts == NULL || parts[0] == NULL || parts[1] == NULL)
676  {
677  g_warning("string [%s] not parseable", log_opt);
678  continue;
679  }
680 
681  level = qof_log_level_from_string(parts[1]);
682  qof_log_set_level(parts[0], level);
683  g_strfreev(parts);
684  }
685  }
686 }
687 
688 int
689 main(int argc, char ** argv)
690 {
691  gchar *sys_locale = NULL;
692 #if !defined(G_THREADS_ENABLED) || defined(G_THREADS_IMPL_NONE)
693 # error "No GLib thread implementation available!"
694 #endif
695 #ifndef HAVE_GLIB_2_32 /* Automatic after GLib 2-32 */
696  g_thread_init(NULL);
697 #endif
698 #ifdef ENABLE_BINRELOC
699  {
700  GError *binreloc_error = NULL;
701  if (!gnc_gbr_init(&binreloc_error))
702  {
703  g_print("main: Error on gnc_gbr_init: %s\n", binreloc_error->message);
704  g_error_free(binreloc_error);
705  }
706  }
707 #endif
708 
709  /* This should be called before gettext is initialized
710  * The user may have configured a different language via
711  * the environment file.
712  */
713 #ifdef MAC_INTEGRATION
714  set_mac_locale();
715 #endif
717 #ifndef MAC_INTEGRATION /* setlocale already done */
718  sys_locale = g_strdup (setlocale (LC_ALL, ""));
719  if (!sys_locale)
720  {
721  g_print ("The locale defined in the environment isn't supported. "
722  "Falling back to the 'C' (US English) locale\n");
723  g_setenv ("LC_ALL", "C", TRUE);
724  setlocale (LC_ALL, "C");
725  }
726 #endif
727 #ifdef HAVE_GETTEXT
728  {
729  gchar *localedir = gnc_path_get_localedir();
730  bindtextdomain(GETTEXT_PACKAGE, localedir);
731  textdomain(GETTEXT_PACKAGE);
732  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
733  g_free(localedir);
734  }
735 #endif
736 
737  gnc_parse_command_line(&argc, &argv);
738  gnc_print_unstable_message();
739 
740  gnc_log_init();
741 
742 #ifndef MAC_INTEGRATION
743  /* Write some locale details to the log to simplify debugging
744  * To be on the safe side, only do this if not on OS X,
745  * to avoid unintentionally messing up the locale settings */
746  PINFO ("System locale returned %s", sys_locale ? sys_locale : "(null)");
747  PINFO ("Effective locale set to %s.", setlocale (LC_ALL, ""));
748  g_free (sys_locale);
749 #endif
750 
751  /* If asked via a command line parameter, fetch quotes only */
752  if (add_quotes_file)
753  {
754  /* First initialize the module system, even though gtk hasn't been initialized. */
755  gnc_module_system_init();
756  scm_boot_guile(argc, argv, inner_main_add_price_quotes, 0);
757  exit(0); /* never reached */
758  }
759 
760  /* We need to initialize gtk before looking up all modules */
762  if(!gtk_init_check (&argc, &argv))
763  {
764  g_printerr(_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
765  _("Error: could not initialize graphical user interface and option add-price-quotes was not set.\n"
766  " Perhaps you need to set the $DISPLAY environment variable ?"),
767  argv[0]);
768  return 1;
769  }
770 
771  /* Now the module files are looked up, which might cause some library
772  initialization to be run, hence gtk must be initialized beforehand. */
773  gnc_module_system_init();
774 
775  gnc_gui_init();
776  scm_boot_guile(argc, argv, inner_main, 0);
777  exit(0); /* never reached */
778 }
void qof_log_set_level(QofLogModule module, QofLogLevel level)
utility functions for the GnuCash UI
#define PINFO(format, args...)
Definition: qoflog.h:249
void qof_log_set_default(QofLogLevel log_level)
void gnc_shutdown(int exit_status)
gchar * gnc_build_dotgnucash_path(const gchar *filename)
Make a path to filename in the user's configuration directory.
void gnc_main_window_show_all_windows(void)
Functions for adding content to a window.
#define PWARN(format, args...)
Definition: qoflog.h:243
void qof_log_init_filename_special(const char *log_to_filename)
void qof_log_init_filename(const gchar *logfilename)
void gnc_log_default(void)
Definition: gnc-engine.c:189
Functions providing the file history menu.
code to set up the environment for proper gnucash functioning.
Preferences initialization function.
void gnc_environment_setup(void)
Gnome specific utility functions.
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.
void gnc_gtk_add_rc_file(void)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
GncMainWindow * gnc_gui_init(void)
File path resolution utility functions.
GSettings helper routines.
Commodity handling public routines.
void qof_log_parse_log_config(const char *filename)
const gchar * QofLogModule
Definition: qofid.h:89