From 141b7298e959b838adb5fba42c8d0d1d4132be97 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sun, 14 Nov 2010 13:55:04 +0200 Subject: [PATCH] * add 'mu_runtime' for initialization, keeping global state during runtime. update many. --- mug/mug.cc | 28 +++--- src/Makefile.am | 2 + src/mu-cmd-find.c | 29 +++++-- src/mu-cmd-index.c | 22 +++-- src/mu-config.c | 39 ++++----- src/mu-config.h | 2 - src/mu-runtime.c | 207 +++++++++++++++++++++++++++++++++++++++++++++ src/mu-runtime.h | 38 +++++++++ src/mu-util.c | 34 +------- src/mu-util.h | 32 ------- src/mu.cc | 49 ++--------- 11 files changed, 317 insertions(+), 165 deletions(-) create mode 100644 src/mu-runtime.c create mode 100644 src/mu-runtime.h diff --git a/mug/mug.cc b/mug/mug.cc index 31af9ff9..f9316f69 100644 --- a/mug/mug.cc +++ b/mug/mug.cc @@ -24,9 +24,8 @@ #include #include /* for memset */ -#include "mu-config.h" -#include "mu-log.h" #include "mu-util.h" +#include "mu-runtime.h" #include "mug-msg-list-view.h" #include "mug-query-bar.h" @@ -147,13 +146,8 @@ on_shortcut_clicked (GtkWidget *w, const gchar *query, MugData *mdata) static GtkWidget* mug_shortcuts_bar (MugData *data) { - gchar* bmpath; - - bmpath = mu_util_guess_bookmark_file (data->muhome); - data->shortcuts = mug_shortcuts_new (bmpath); + data->shortcuts = mug_shortcuts_new (mu_runtime_bookmarks_file()); - g_free (bmpath); - g_signal_connect (G_OBJECT(data->shortcuts), "clicked", G_CALLBACK(on_shortcut_clicked), data); @@ -224,19 +218,15 @@ mug_query_area (MugData *mugdata) GtkWidget *paned; GtkWidget *scrolled; - gchar* xdir; - queryarea = gtk_vbox_new (FALSE, 2); - - paned = gtk_vpaned_new (); + paned = gtk_vpaned_new (); - xdir = mu_util_guess_xapian_dir (mugdata->muhome); - mugdata->mlist = mug_msg_list_view_new(xdir); - g_free (xdir); + mugdata->mlist = mug_msg_list_view_new(mu_runtime_xapian_dir()); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER(scrolled), mugdata->mlist); gtk_paned_add1 (GTK_PANED (paned), scrolled); @@ -248,7 +238,7 @@ mug_query_area (MugData *mugdata) gtk_paned_add2 (GTK_PANED (paned), mugdata->msgview); mugdata->querybar = mug_querybar(); - g_signal_connect (G_OBJECT(mugdata->querybar), "query_changed", + g_signal_connect (G_OBJECT(mugdata->querybar), "query-changed", G_CALLBACK(on_query_changed), mugdata); @@ -329,6 +319,8 @@ main (int argc, char *argv[]) g_printerr ("mug: error in options\n"); return 1; } + + mu_runtime_init (mugdata.muhome); mugshell = mug_shell (&mugdata); g_signal_connect(G_OBJECT(mugshell), "destroy", @@ -339,6 +331,8 @@ main (int argc, char *argv[]) gtk_main (); g_free (mugdata.muhome); + + mu_runtime_uninit (); return 0; } diff --git a/src/Makefile.am b/src/Makefile.am index fe13fd26..a7582ead 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -89,6 +89,8 @@ libmu_la_SOURCES= \ mu-query.cc \ mu-query.h \ mu-result.h \ + mu-runtime.c \ + mu-runtime.h \ mu-store.cc \ mu-store.h \ mu-util-db.cc \ diff --git a/src/mu-cmd-find.c b/src/mu-cmd-find.c index 62c353f6..1ee09da5 100644 --- a/src/mu-cmd-find.c +++ b/src/mu-cmd-find.c @@ -36,6 +36,8 @@ #include "mu-msg-str.h" #include "mu-bookmarks.h" +#include "mu-runtime.h" + #include "mu-util.h" #include "mu-util-db.h" #include "mu-cmd.h" @@ -164,16 +166,20 @@ run_query (MuQuery *xapian, const gchar *query, MuConfigOptions *opts) static gboolean query_params_valid (MuConfigOptions *opts) { + const gchar *xpath; + if (opts->linksdir) if (opts->xquery) { g_printerr ("Invalid option for '--linksdir'\n"); return FALSE; } - - if (mu_util_check_dir (opts->xpath, TRUE, FALSE)) - return TRUE; - g_printerr ("%s is not a readable Xapian directory\n", opts->xpath); + xpath = mu_runtime_xapian_dir(); + + if (mu_util_check_dir (xpath, TRUE, FALSE)) + return TRUE; + + g_warning ("'%s' is not a readable Xapian directory\n", xpath); g_message ("Did you run 'mu index'?"); return FALSE; @@ -184,10 +190,12 @@ resolve_bookmark (MuConfigOptions *opts) { MuBookmarks *bm; char* val; + const gchar *bmfile; - bm = mu_bookmarks_new (opts->bmpath); + bmfile = mu_runtime_bookmarks_file(); + bm = mu_bookmarks_new (bmfile); if (!bm) { - g_warning ("Failed to open bookmarks file '%s'", opts->bmpath); + g_warning ("Failed to open bookmarks file '%s'", bmfile); return FALSE; } @@ -237,6 +245,7 @@ mu_cmd_find (MuConfigOptions *opts) MuQuery *xapian; gboolean rv; gchar *query; + const gchar *xpath; g_return_val_if_fail (opts, FALSE); g_return_val_if_fail (mu_cmd_equals (opts, "find"), FALSE); @@ -244,12 +253,14 @@ mu_cmd_find (MuConfigOptions *opts) if (!query_params_valid (opts)) return FALSE; - if (mu_util_db_is_empty (opts->xpath)) { + xpath = mu_runtime_xapian_dir (); + + if (mu_util_db_is_empty (xpath)) { g_warning ("Database is empty; use 'mu index' to add messages"); return FALSE; } - if (!mu_util_db_version_up_to_date (opts->xpath)) { + if (!mu_util_db_version_up_to_date (xpath)) { update_warning (); return FALSE; } @@ -259,7 +270,7 @@ mu_cmd_find (MuConfigOptions *opts) if (!query) return FALSE; - xapian = mu_query_new (opts->xpath); + xapian = mu_query_new (xpath); if (!xapian) { g_warning ("Failed to create a Xapian query\n"); return FALSE; diff --git a/src/mu-cmd-index.c b/src/mu-cmd-index.c index c28e34b5..a6db8109 100644 --- a/src/mu-cmd-index.c +++ b/src/mu-cmd-index.c @@ -34,6 +34,7 @@ #include "mu-msg.h" #include "mu-index.h" +#include "mu-runtime.h" static gboolean MU_CAUGHT_SIGNAL; @@ -147,24 +148,28 @@ index_msg_cb (MuIndexStats* stats, void *user_data) static gboolean database_version_check_and_update (MuConfigOptions *opts) { - if (mu_util_db_is_empty (opts->xpath)) + const gchar *xpath; + + xpath = mu_runtime_xapian_dir (); + + if (mu_util_db_is_empty (xpath)) return TRUE; /* we empty the database before doing anything */ if (opts->rebuild) { opts->reindex = TRUE; - g_message ("Clearing database %s", opts->xpath); - return mu_util_clear_database (opts->xpath); + g_message ("Clearing database %s", xpath); + return mu_util_clear_database (xpath); } - if (mu_util_db_version_up_to_date (opts->xpath)) + if (mu_util_db_version_up_to_date (xpath)) return TRUE; /* ok, nothing to do */ /* ok, database is not up to date */ if (opts->autoupgrade) { opts->reindex = TRUE; g_message ("Auto-upgrade: clearing old database first"); - return mu_util_clear_database (opts->xpath); + return mu_util_clear_database (xpath); } update_warning (); @@ -191,7 +196,7 @@ cmd_cleanup (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats, MuResult rv; time_t t; - g_message ("Cleaning up messages [%s]", opts->xpath); + g_message ("Cleaning up messages [%s]", mu_runtime_xapian_dir()); t = time (NULL); rv = mu_index_cleanup (midx, stats, @@ -216,7 +221,8 @@ cmd_index (MuIndex *midx, MuConfigOptions *opts, MuIndexStats *stats, MuResult rv; time_t t; - g_message ("Indexing messages under %s [%s]", opts->maildir, opts->xpath); + g_message ("Indexing messages under %s [%s]", opts->maildir, + mu_runtime_xapian_dir()); t = time (NULL); rv = mu_index_run (midx, opts->maildir, opts->reindex, stats, @@ -261,7 +267,7 @@ cmd_index_or_cleanup (MuConfigOptions *opts) if (!check_index_params (opts) || !database_version_check_and_update(opts)) return FALSE; - if (!(midx = mu_index_new (opts->xpath))) { + if (!(midx = mu_index_new (mu_runtime_xapian_dir()))) { g_warning ("Indexing/Cleanup failed"); return FALSE; } diff --git a/src/mu-config.c b/src/mu-config.c index 4ee2a983..fcf5fa06 100644 --- a/src/mu-config.c +++ b/src/mu-config.c @@ -17,7 +17,7 @@ ** */ -#ifdef HAVE_CONFIG_H +#if HAVE_CONFIG_H #include "config.h" #endif /*HAVE_CONFIG_H*/ @@ -30,11 +30,16 @@ static void set_group_mu_defaults (MuConfigOptions *opts) { + gchar *exp; + if (!opts->muhome) opts->muhome = mu_util_guess_mu_homedir (); - /* note: xpath is is *not* settable from the cmdline */ - opts->xpath = mu_util_guess_xapian_dir (opts->muhome); + exp = mu_util_dir_expand (opts->muhome); + if (exp) { + g_free (opts->muhome); + opts->muhome = exp; + } } @@ -69,20 +74,16 @@ config_options_group_mu (MuConfigOptions *opts) static void set_group_index_defaults (MuConfigOptions *opts) { - gchar *old; - - old = opts->maildir; - if (opts->maildir) - opts->maildir = mu_util_dir_expand (opts->maildir); - else + gchar *exp; + + if (!opts->maildir) opts->maildir = mu_util_guess_maildir(); - /* note, this may be an invalid dir, but we're checking for - * validity of the dir later */ - if (!opts->maildir) - opts->maildir = old; - else - g_free (old); + exp = mu_util_dir_expand (opts->maildir); + if (exp) { + g_free (opts->maildir); + opts->maildir = exp; + } } @@ -138,9 +139,6 @@ set_group_find_defaults (MuConfigOptions *opts) /* FIXME: some warning when summary_len < 0? */ if (opts->summary_len < 1) opts->summary_len = 0; - - /* note: xpath is is *not* settable from the cmdline */ - opts->bmpath = mu_util_guess_bookmark_file (opts->muhome); } @@ -205,7 +203,8 @@ config_options_group_extract (MuConfigOptions *opts) { GOptionGroup *og; GOptionEntry entries[] = { - {"save-attachments", 'a', 0, G_OPTION_ARG_NONE, &opts->save_attachments, + {"save-attachments", 'a', 0, G_OPTION_ARG_NONE, + &opts->save_attachments, "save all attachments", NULL}, {"save-all", 0, 0, G_OPTION_ARG_NONE, &opts->save_all, "save all parts (incl. non-attachments)", NULL}, @@ -292,11 +291,9 @@ mu_config_uninit (MuConfigOptions *opts) g_return_if_fail (opts); g_free (opts->muhome); - g_free (opts->xpath); g_free (opts->maildir); g_free (opts->linksdir); g_free (opts->targetdir); - g_free (opts->bmpath); g_strfreev (opts->params); } diff --git a/src/mu-config.h b/src/mu-config.h index 9d062204..2d311749 100644 --- a/src/mu-config.h +++ b/src/mu-config.h @@ -36,7 +36,6 @@ struct _MuConfigOptions { gboolean quiet; /* don't give any output */ gboolean debug; /* spew out debug info */ char *muhome; /* the House of Mu */ - char *xpath; /* path to the Xapian dir (internal) */ gboolean version; /* request mu version */ gboolean log_stderr; /* log to stderr (not logfile) */ gchar** params; /* parameters (for querying) */ @@ -56,7 +55,6 @@ struct _MuConfigOptions { gboolean descending; /* sort descending? */ unsigned summary_len; /* max # of lines of msg in summary */ char *bookmark; /* use bookmark */ - char *bmpath; /* path to bookmark file (internal) */ /* output to a maildir with symlinks */ char *linksdir; /* maildir to output symlinks */ gboolean clearlinks; /* clear a linksdir before filling */ diff --git a/src/mu-runtime.c b/src/mu-runtime.c new file mode 100644 index 00000000..5bfcb687 --- /dev/null +++ b/src/mu-runtime.c @@ -0,0 +1,207 @@ +/* +** Copyright (C) 2010 Dirk-Jan C. Binnema +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ + +#include "mu-runtime.h" + +#include +#include /* for setlocale() */ +#include /* for fileno() */ + +#include "mu-config.h" +#include "mu-log.h" +#include "mu-util.h" + +#define MU_XAPIAN_DIRNAME "xapian" +#define MU_BOOKMARKS_FILENAME "bookmarks" + +struct _MuRuntimeData { + gchar *_muhome; + gchar *_xapian_dir; + gchar *_bookmarks_file; + + MuConfigOptions *_config; +}; +typedef struct _MuRuntimeData MuRuntimeData; + +/* static, global data for this singleton */ +static gboolean _initialized = FALSE; +static MuRuntimeData *_data = NULL; + +static void runtime_free (void); + +static gboolean +init_system (void) +{ + /* without setlocale, non-ascii cmdline params (like search + * terms) won't work */ + setlocale (LC_ALL, ""); + + /* on FreeBSD, it seems g_slice_new and friends lead to + * segfaults. So we shut if off */ +#ifdef __FreeBSD__ + if (!g_setenv ("G_SLICE", "always-malloc", TRUE)) { + g_critical ("cannot set G_SLICE"); + return FALSE; + } +#endif /*__FreeBSD__*/ + + g_type_init (); + + return TRUE; +} + + + +gboolean +mu_runtime_init (const char* muhome_arg) +{ + gchar *muhome; + + g_return_val_if_fail (!_initialized, FALSE); + + if (!init_system()) + return FALSE; + + if (muhome_arg) + muhome = g_strdup (muhome_arg); + else + muhome = mu_util_guess_mu_homedir (); + + if (!mu_log_init (muhome, TRUE, FALSE, FALSE)) { + g_free (muhome); + return FALSE; + } + + _data = g_new0 (MuRuntimeData, 1); + _data->_muhome = muhome; + + return _initialized = TRUE; +} + + +static gboolean +init_log (MuConfigOptions *opts) +{ + if (opts->log_stderr) + return mu_log_init_with_fd (fileno(stderr), FALSE, + opts->quiet, opts->debug); + else + return mu_log_init (opts->muhome, TRUE, opts->quiet, + opts->debug); +} + +gboolean +mu_runtime_init_from_cmdline (int *pargc, char ***pargv) +{ + g_return_val_if_fail (!_initialized, FALSE); + + if (!init_system()) + return FALSE; + + _data = g_new0 (MuRuntimeData, 1); + _data->_config = g_new0 (MuConfigOptions, 1); + + if (!mu_config_init (_data->_config, pargc, pargv)) { + runtime_free (); + return FALSE; + } + + if (!init_log (_data->_config)) { + runtime_free (); + return FALSE; + } + + _data->_muhome = g_strdup (_data->_config->muhome); + + return _initialized = TRUE; +} + + +static void +runtime_free (void) +{ + g_free (_data->_xapian_dir); + g_free (_data->_muhome); + + if (_data->_config) { + mu_config_uninit (_data->_config); + g_free (_data->_config); + } + + mu_log_uninit(); + + g_free (_data); +} + +void +mu_runtime_uninit (void) +{ + g_return_if_fail (_initialized); + + runtime_free (); + + _initialized = FALSE; +} + + +const char* +mu_runtime_mu_home_dir (void) +{ +g_return_val_if_fail (_initialized, NULL); + + return _data->_muhome; +} + + + +const char* +mu_runtime_xapian_dir (void) +{ + g_return_val_if_fail (_initialized, NULL); + + if (!_data->_xapian_dir) + _data->_xapian_dir = g_strdup_printf ("%s%c%s", _data->_muhome, + G_DIR_SEPARATOR, + MU_XAPIAN_DIRNAME); + return _data->_xapian_dir; +} + +const char* +mu_runtime_bookmarks_file (void) +{ + g_return_val_if_fail (_initialized, NULL); + + if (!_data->_bookmarks_file) + _data->_bookmarks_file = + g_strdup_printf ("%s%c%s", + _data->_muhome, + G_DIR_SEPARATOR, + MU_BOOKMARKS_FILENAME); + + return _data->_bookmarks_file; +} + + +MuConfigOptions* +mu_runtime_config_options (void) +{ + g_return_val_if_fail (_initialized, NULL); + + return _data->_config; +} diff --git a/src/mu-runtime.h b/src/mu-runtime.h new file mode 100644 index 00000000..1ddb42b6 --- /dev/null +++ b/src/mu-runtime.h @@ -0,0 +1,38 @@ +/* +** Copyright (C) 2010 Dirk-Jan C. Binnema +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ +#ifndef __MU_RUNTIME_H__ +#define __MU_RUNTIME_H__ + +#include +#include "mu-config.h" + +G_BEGIN_DECLS + +gboolean mu_runtime_init (const char* muhome); +gboolean mu_runtime_init_from_cmdline (int *pargc, char ***pargv); +void mu_runtime_uninit (void); + +const char* mu_runtime_mu_home_dir (void); +const char* mu_runtime_xapian_dir (void); +const char* mu_runtime_bookmarks_file (void); +MuConfigOptions* mu_runtime_config_options (void); + +G_END_DECLS + +#endif /*__MU_RUNTIME_H__*/ diff --git a/src/mu-util.c b/src/mu-util.c index d403341d..683c63bd 100644 --- a/src/mu-util.c +++ b/src/mu-util.c @@ -65,9 +65,7 @@ do_wordexp (const char *path) return NULL; } - /* if (wexp.we_wordc != 1) /\* not an *error*, we just take the first one *\/ */ - /* g_debug ("%s: expansion ambiguous for '%s'", __FUNCTION__, path); */ - + /* we just pick the first one */ dir = g_strdup (wexp.we_wordv[0]); /* strangely, below seems to lead to a crash on MacOS (BSD); @@ -194,33 +192,6 @@ mu_util_guess_mu_homedir (void) ".mu"); } -gchar* -mu_util_guess_xapian_dir (const char* muhome) -{ - gchar *homedir, *xdir; - - homedir = muhome ? g_strdup(muhome) : mu_util_guess_mu_homedir (); - xdir = g_strdup_printf ("%s%c%s", homedir, G_DIR_SEPARATOR, - MU_XAPIAN_DIR_NAME); - g_free (homedir); - - return xdir; -} - -gchar* -mu_util_guess_bookmark_file (const char* muhome) -{ - gchar *homedir, *bmpath; - - homedir = muhome ? g_strdup(muhome) : mu_util_guess_mu_homedir (); - bmpath = g_strdup_printf ("%s%c%s", homedir, G_DIR_SEPARATOR, - MU_BOOKMARK_FILENAME); - g_free (homedir); - - return bmpath; -} - - gboolean mu_util_create_dir_maybe (const gchar *path) { @@ -295,8 +266,7 @@ mu_util_create_writeable_fd (const char* filename, const char* dir, g_debug ("%s: cannot open %s for writing: %s", __FUNCTION__, fullpath, strerror(errno)); - g_free (fullpath); - + g_free (fullpath); return fd; } diff --git a/src/mu-util.h b/src/mu-util.h index 8e9ba9ab..0717016a 100644 --- a/src/mu-util.h +++ b/src/mu-util.h @@ -61,38 +61,6 @@ char* mu_util_guess_maildir (void) G_GNUC_WARN_UNUSED_RESULT; */ gchar* mu_util_guess_mu_homedir (void); - -/** - * guess the place of the xapian database (typically, - * ~/.mu/xapian/). Note, this directory does not necessarily - * exist. mu_util_check_dir can be use to check that - * - * @param muhome the mu home directory or NULL, in which the muhome - * directoy will be guessed as well - * - * @return the guessed xapian dir, which needs to be freed with g_free - * when no longer needed. - */ -gchar* mu_util_guess_xapian_dir (const gchar *muhome); - - -/** - * guess the place of the bookmark file (typically, - * ~/.mu/bookmarks). Note that this does not mean the file actually - * exists. - * - * @param muhome the mu home directory or NULL, in which the muhome - * directoy will be guessed as well - * - * @return the guessed mu bookmark file, which needs to be freed with - * g_free when no longer needed. - */ -gchar* mu_util_guess_bookmark_file (const gchar *muhome); - - - - - /** * if path exists, check that's a read/writeable dir; otherwise try to * create it (with perms 0700) diff --git a/src/mu.cc b/src/mu.cc index a23d856f..5c5d9318 100644 --- a/src/mu.cc +++ b/src/mu.cc @@ -17,60 +17,21 @@ ** */ -#if HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ - #include -#include /* for fileno() */ - -#include "mu-util.h" -#include "mu-config.h" #include "mu-cmd.h" -#include "mu-log.h" - -static gboolean -init_log (MuConfigOptions *opts) -{ - gboolean rv; - - if (opts->log_stderr) - rv = mu_log_init_with_fd (fileno(stderr), FALSE, - opts->quiet, opts->debug); - else - rv = mu_log_init (opts->muhome, TRUE, opts->quiet, - opts->debug); - - /* we use g_printerr here because g_warning does not give - * the desired result when log initialization failed */ - if (!rv) - g_printerr ("error: failed to initialize log\n"); - - return rv; -} +#include "mu-runtime.h" int main (int argc, char *argv[]) { - MuConfigOptions config; gboolean rv; - - if (!mu_util_init_system()) + + if (!mu_runtime_init_from_cmdline (&argc, &argv)) return 1; - if (!mu_config_init (&config, &argc, &argv)) - return 1; + rv = mu_cmd_execute (mu_runtime_config_options()); - if (!init_log (&config)) { - mu_config_uninit (&config); - return 1; - } - - rv = mu_cmd_execute (&config); - - mu_log_uninit(); - - mu_config_uninit (&config); + mu_runtime_uninit (); return rv ? 0 : 1; }