From eaf8b1cba58e0b9657b089520ad82799669942c5 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sat, 28 Nov 2009 14:06:21 +0200 Subject: [PATCH] * overhaul the configuration system (part 1) --- src/mu-config.c | 120 +++++++++++++++++++++++++++++++++ src/mu-config.h | 92 +++++++++++++++++++++++++ src/mu-index.c | 41 ++---------- src/mu-query.c | 175 +++++++++++++++++------------------------------- src/mu-query.h | 5 +- src/mu.c | 44 ++++++------ 6 files changed, 299 insertions(+), 178 deletions(-) create mode 100644 src/mu-config.c create mode 100644 src/mu-config.h diff --git a/src/mu-config.c b/src/mu-config.c new file mode 100644 index 00000000..6c3954d2 --- /dev/null +++ b/src/mu-config.c @@ -0,0 +1,120 @@ +/* +** Copyright (C) 2008, 2009 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 +#include /* memset */ +#include "mu-config.h" + + +GOptionGroup* +mu_config_options_group_mu (MuConfigOptions *opts) +{ + GOptionGroup *og; + GOptionEntry entries[] = { + { "debug", 'd', 0, G_OPTION_ARG_NONE, &opts->debug, + "print debug output to standard-error", NULL }, + { "quiet", 'q', 0, G_OPTION_ARG_NONE, &opts->quiet, + "don't give any progress information", NULL }, + { NULL } + }; + + og = g_option_group_new ("mu", + "general mu options", + "", NULL, NULL); + g_option_group_add_entries (og, entries); + + return og; +} + + + +GOptionGroup* +mu_config_options_group_index (MuConfigOptions *opts) +{ + GOptionGroup *og; + GOptionEntry entries[] = { + {"maildir", 'm', 0, G_OPTION_ARG_FILENAME, &opts->maildir, + "top of the maildir", NULL}, + + /* FIXME: implement this */ + {"reindex", 'r', 0, G_OPTION_ARG_NONE, &opts->reindex, + "re-index already indexed messages ", NULL}, + {NULL} + }; + + og = g_option_group_new ("index", + "options for the 'index' command", + "", NULL, NULL); + g_option_group_add_entries (og, entries); + + return og; +} + +GOptionGroup* +mu_config_options_group_query (MuConfigOptions *opts) +{ + GOptionGroup *og; + GOptionEntry entries[] = { + {"print", 'p', 0, G_OPTION_ARG_NONE, &opts->print, + "print matching messages to screen (default)", NULL}, + {"xquery", 'x', 0, G_OPTION_ARG_NONE, &opts->xquery, + "print a string representation of the Xapian query", NULL}, + {"fields", 'f', 0, G_OPTION_ARG_STRING, &opts->fields, + "fields to display in output", NULL}, + {"sortfield", 's', 0, G_OPTION_ARG_STRING, &opts->sortfield_str, + "field to sort on", NULL}, + {"ascending", 'a', 0, G_OPTION_ARG_NONE, &opts->ascending_flag, + "sort ascending", NULL}, + {"descending", 'c', 0, G_OPTION_ARG_NONE, &opts->descending_flag, + "sort ascending", NULL}, + {NULL} + }; + + og = g_option_group_new ("querying", + "options for the 'query' command", + "", NULL, NULL); + g_option_group_add_entries (og, entries); + + return og; +} + + + +void +mu_config_set_defaults (MuConfigOptions *opts) +{ + g_return_if_fail (opts); + + /* start from zero */ + memset (opts, 0, sizeof(MuConfigOptions)); + + /* general */ + opts->quiet = FALSE; + opts->debug = FALSE; + + /* indexing */ + opts->maildir = "/home/djcb/Maildir"; + opts->cleanup = FALSE; + opts->reindex = FALSE; + + /* querying */ + opts->print = TRUE; + opts->xquery = FALSE; + opts->fields = "d f s"; +} diff --git a/src/mu-config.h b/src/mu-config.h new file mode 100644 index 00000000..c1542879 --- /dev/null +++ b/src/mu-config.h @@ -0,0 +1,92 @@ +/* +** Copyright (C) 2008, 2009 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_CONFIG_H__ +#define __MU_CONFIG_H__ + +#include +#include "mu-msg-fields.h" + +/* struct with all configuration options for mu; it will be filled + * from the config file, and/or command line arguments */ + +struct _MuConfigOptions { + + /* general options */ + gboolean quiet; /* don't give any output */ + gboolean debug; /* spew out debug info */ + + /* options for indexing */ + const char *maildir; /* where the mails are */ + gboolean cleanup; /* cleanup deleted mails form db */ + gboolean reindex; /* re-index existing mails */ + + /* options for querying */ + gboolean print; /* do output */ + gboolean xquery; /* give the Xapian query (for debuging)*/ + char *fields; /* fields to show in output */ + + char* sortfield_str; /* fields to sort by */ + const MuMsgField* sortfield; + + /* FIXME: clean up this mess */ + gboolean sortdir_descending ; /* sort descending? */ + gboolean sortdir_ascending; + gboolean ascending_flag, descending_flag; +}; +typedef struct _MuConfigOptions MuConfigOptions; + + +/** + * set default values for the configuration options + * + * @param opts + */ +void mu_config_set_defaults (MuConfigOptions *opts); + + +/** + * get the general options option group + * + * @param opts the MuConfigOptions to fill from this option group + * + * @return a new option group; *DON'T* unref when added to an optioncontext + */ +GOptionGroup* mu_config_options_group_mu (MuConfigOptions *opts); + +/** + * get the index-options option group + * + * @param opts the MuConfigOptions to fill from this option group + * + * @return a new option group; *DON'T* unref when added to an optioncontext + */ +GOptionGroup* mu_config_options_group_index (MuConfigOptions *opts); + +/** + * get the query-options option group + * + * @param opts the MuConfigOptions to fill from this option group + * + * @return a new option group; *DON'T* unref when added to an optioncontext + */ +GOptionGroup* mu_config_options_group_query (MuConfigOptions *opts); + + +#endif /*__MU_CONFIG_H__*/ diff --git a/src/mu-index.c b/src/mu-index.c index 993a3c7e..cbe81a8b 100644 --- a/src/mu-index.c +++ b/src/mu-index.c @@ -32,39 +32,6 @@ #include "mu-index.h" #include "mu-store-xapian.h" -struct _IndexOptions { - gboolean quiet; - gboolean cleanup; - gboolean reindex; - const char *maildir; -}; -typedef struct _IndexOptions IndexOptions; - -static IndexOptions INDEX_OPTIONS; -static GOptionEntry INDEX_ENTRIES[] = { - {"maildir", 'm', 0, G_OPTION_ARG_FILENAME, &INDEX_OPTIONS.maildir, - "top of the maildir", NULL}, - - /* FIXME: implement this */ - {"reindex", 'r', 0, G_OPTION_ARG_NONE, &INDEX_OPTIONS.reindex, - "re-index already indexed messages ", NULL}, - {NULL} -}; - - -GOptionGroup* -mu_index_option_group (void) -{ - GOptionGroup *og; - - og = g_option_group_new ("index", - "options for indexing your maildirs", - "", NULL, NULL); - - g_option_group_add_entries (og, INDEX_ENTRIES); - - return og; -} struct _MuIndex { @@ -112,7 +79,7 @@ struct _MuIndexCallbackData { MuStoreXapian* _xapian; void* _user_data; MuIndexStats* _stats; - gboolean _force; + gboolean _reindex; time_t _dirstamp; }; typedef struct _MuIndexCallbackData MuIndexCallbackData; @@ -126,7 +93,7 @@ insert_or_update_maybe (const char* fullpath, time_t filestamp, *updated = FALSE; if ((size_t)filestamp <= (size_t)data->_dirstamp) { - if (!data->_force) + if (!data->_reindex) return MU_OK; } @@ -239,7 +206,7 @@ check_path (const char* path) MuResult mu_index_run (MuIndex *index, const char* path, - gboolean force, MuIndexStats *stats, + gboolean reindex, MuIndexStats *stats, MuIndexMsgCallback msg_cb, MuIndexDirCallback dir_cb, void *user_data) { @@ -254,7 +221,7 @@ mu_index_run (MuIndex *index, const char* path, cb_data._user_data = user_data; cb_data._xapian = index->_xapian; cb_data._stats = stats; - cb_data._force = force; + cb_data._reindex = reindex; cb_data._dirstamp = 0; diff --git a/src/mu-query.c b/src/mu-query.c index 85febe37..ca7b88c8 100644 --- a/src/mu-query.c +++ b/src/mu-query.c @@ -27,109 +27,7 @@ #include "mu-msg-str.h" #include "mu-msg-flags.h" #include "mu-query-xapian.h" - -struct _FindOptions { - gboolean _print; - gboolean _xquery; - char* _fields; - - char* _sortfield_str; - const MuMsgField* _sortfield; - - gboolean _ascending_flag, _descending_flag; - gboolean _sortdir_ascending; - -}; -typedef struct _FindOptions FindOptions; - -static FindOptions FIND_OPTIONS; -static GOptionEntry OPTION_ENTRIES[] = { - {"print", 'p', 0, G_OPTION_ARG_NONE, &FIND_OPTIONS._print, - "print matching messages to screen (default)", NULL}, - {"xquery", 'x', 0, G_OPTION_ARG_NONE, &FIND_OPTIONS._xquery, - "print a string representation of the Xapian query", NULL}, - {"fields", 'f', 0, G_OPTION_ARG_STRING, &FIND_OPTIONS._fields, - "fields to display in output", NULL}, - {"sortfield", 's', 0, G_OPTION_ARG_STRING, &FIND_OPTIONS._sortfield_str, - "field to sort on", NULL}, - {"ascending", 'a', 0, G_OPTION_ARG_NONE, &FIND_OPTIONS._ascending_flag, - "sort ascending", NULL}, - {"descending", 'c', 0, G_OPTION_ARG_NONE, &FIND_OPTIONS._descending_flag, - "sort ascending", NULL}, - {NULL} -}; - -GOptionGroup* -mu_query_option_group (void) -{ - GOptionGroup *og; - - og = g_option_group_new ("query", - "options for quering the e-mail database", - "", NULL, NULL); - g_option_group_add_entries (og, OPTION_ENTRIES); - - return og; -} - - -static gboolean -handle_options_sort_field_dir (void) -{ - const MuMsgField *field; - - if (FIND_OPTIONS._sortfield_str) { - field = mu_msg_field_from_name (FIND_OPTIONS._sortfield_str); - if (!field && strlen(FIND_OPTIONS._sortfield_str) == 1) - field = mu_msg_field_from_shortcut - (FIND_OPTIONS._sortfield_str[0]); - if (!field) { - g_warning ("not a valid sort field: '%s'", - FIND_OPTIONS._sortfield_str); - return FALSE; - } - FIND_OPTIONS._sortfield = field; - } - - if (FIND_OPTIONS._ascending_flag && FIND_OPTIONS._descending_flag) { - g_warning ("ignoring option '--descending'"); - FIND_OPTIONS._sortdir_ascending = TRUE; - } else if (!FIND_OPTIONS._descending_flag) - FIND_OPTIONS._sortdir_ascending = !FIND_OPTIONS._descending_flag; - - return TRUE; -} - - -static gboolean -handle_options (void) -{ - //GError *err = NULL; - /* if (!mu_conf_handle_options (mu_app_conf(),OPTION_ENTRIES, argcp, argvp, */ - /* &err)) { */ - /* g_printerr ("option parsing failed: %s\n", */ - /* (err && err->message) ? err->message : "?" ); */ - /* if (err) */ - /* g_error_free (err); */ - /* return FALSE; */ - /* } */ - - /* if nothing specified, or fields are specified use print */ - if ((!FIND_OPTIONS._xquery)||FIND_OPTIONS._fields) - FIND_OPTIONS._print = TRUE; - - /* if no fields are specified, use 'd f s' */ - if (FIND_OPTIONS._print && !FIND_OPTIONS._fields) { - FIND_OPTIONS._fields = "d f s"; /* default: date-from-subject.. */ - if (!FIND_OPTIONS._ascending_flag) /* ... and sort descending */ - FIND_OPTIONS._sortdir_ascending = FALSE; - } - - if (!handle_options_sort_field_dir ()) - return FALSE; - - return TRUE; -} +#include "mu-query.h" static gboolean print_query (MuQueryXapian *xapian, const gchar *query) @@ -178,19 +76,68 @@ display_field (MuMsgXapian *row, const MuMsgField* field) static gboolean -print_rows (MuQueryXapian *xapian, const gchar *query, FindOptions *opts) +handle_options_sort_field_dir (MuConfigOptions *opts) +{ + const MuMsgField *field; + + if (opts->sortfield_str) { + field = mu_msg_field_from_name (opts->sortfield_str); + if (!field && strlen(opts->sortfield_str) == 1) + field = mu_msg_field_from_shortcut + (opts->sortfield_str[0]); + if (!field) { + g_printerr ("not a valid sort field: '%s'\n", + opts->sortfield_str); + return FALSE; + } + opts->sortfield = field; + } + + if (opts->ascending_flag && opts->descending_flag) { + g_printerr ("ignoring option '--descending'\n"); + opts->sortdir_ascending = TRUE; + } else if (!opts->descending_flag) + opts->sortdir_ascending = !opts->descending_flag; + + return TRUE; +} + +static gboolean +handle_options (MuConfigOptions *opts) +{ + /* if nothing specified, or fields are specified use print */ + if ((!opts->xquery)||opts->fields) + opts->print = TRUE; + + /* if no fields are specified, use 'd f s' */ + if (opts->print && !opts->fields) { + opts->fields = "d f s"; /* default: date-from-subject.. */ + if (!opts->ascending_flag) /* ... and sort descending */ + opts->sortdir_ascending = FALSE; + } + + if (!handle_options_sort_field_dir (opts)) + return FALSE; + + return TRUE; +} + + +static gboolean +print_rows (MuQueryXapian *xapian, const gchar *query, MuConfigOptions *opts) { MuMsgXapian *row; row = mu_query_xapian_run (xapian, query, - opts->_sortfield, opts->_sortdir_ascending); + opts->sortfield, + opts->sortdir_ascending); if (!row) { g_printerr ("error: running query failed\n"); return FALSE; } while (!mu_msg_xapian_is_done (row)) { - const char* fields = opts->_fields; + const char* fields = opts->fields; int printlen = 0; while (*fields) { const MuMsgField* field = @@ -198,8 +145,8 @@ print_rows (MuQueryXapian *xapian, const gchar *query, FindOptions *opts) if (!field) printlen += printf ("%c", *fields); else - printlen += printf ("%s", display_field(row, - field)); + printlen += printf ("%s", + display_field(row, field)); ++fields; } @@ -215,16 +162,16 @@ print_rows (MuQueryXapian *xapian, const gchar *query, FindOptions *opts) static gboolean -do_output (MuQueryXapian *xapian, GSList *args, FindOptions* opts) +do_output (MuQueryXapian *xapian, GSList *args, MuConfigOptions* opts) { gchar *query; gboolean retval = TRUE; query = mu_query_xapian_combine (args, FALSE); - if (opts->_xquery) + if (opts->xquery) retval = print_query (xapian, query); - if (retval && opts->_print) + if (retval && opts->print) retval = print_rows (xapian, query, opts); g_free (query); @@ -234,7 +181,7 @@ do_output (MuQueryXapian *xapian, GSList *args, FindOptions* opts) MuResult -mu_query_run (GSList *args) +mu_query_run (MuConfigOptions *opts, GSList *args) { GError *err = 0; MuQueryXapian *xapian; @@ -242,7 +189,7 @@ mu_query_run (GSList *args) rv = MU_OK; - handle_options (); + handle_options (opts); xapian = mu_query_xapian_new ("/home/djcb/.mu", &err); if (!xapian) { @@ -253,7 +200,7 @@ mu_query_run (GSList *args) return MU_ERROR; } - rv = do_output (xapian, args, &FIND_OPTIONS) ? 0 : 1; + rv = do_output (xapian, args, opts) ? 0 : 1; mu_query_xapian_destroy (xapian); return rv; diff --git a/src/mu-query.h b/src/mu-query.h index 1e4cb7ab..65ab686d 100644 --- a/src/mu-query.h +++ b/src/mu-query.h @@ -1,8 +1,9 @@ #ifndef __MU_QUERY_H__ #define __MU_QUERY_H__ -MuResult mu_query_run (GSList *args); -GOptionGroup* mu_query_option_group (void); +#include "mu-config.h" + +MuResult mu_query_run (MuConfigOptions *opts, GSList *args); #endif /*__MU_QUERY_H__*/ diff --git a/src/mu.c b/src/mu.c index a9d63832..c6bfc84f 100644 --- a/src/mu.c +++ b/src/mu.c @@ -24,10 +24,10 @@ #include "mu-index.h" #include "mu-query.h" #include "mu-util.h" +#include "mu-config.h" #include "mu-msg-gmime.h" - enum _MuCmd { MU_CMD_INDEX, MU_CMD_QUERY, @@ -37,6 +37,7 @@ enum _MuCmd { typedef enum _MuCmd MuCmd; + MuCmd parse_cmd (const char* cmd) { @@ -99,37 +100,27 @@ show_usage (gboolean noerror) return noerror ? 0 : 1; } - - - - -static gboolean opt_debug; -static gboolean opt_quiet; - -static GOptionEntry entries[] = { - { "debug", 'd', 0, G_OPTION_ARG_NONE, &opt_debug, - "print debug output to standard-error", NULL }, - { "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, - "don't give any progress information", NULL }, - { NULL } -}; - - int main (int argc, char *argv[]) { GError *error = NULL; GOptionContext *context; + MuConfigOptions config; MuResult rv; MuCmd cmd; g_type_init (); context = g_option_context_new ("- search your e-mail"); - g_option_context_add_main_entries (context, entries, "mu"); + + g_option_context_set_main_group (context, + mu_config_options_group_mu(&config)); + g_option_context_add_group (context, + mu_config_options_group_index(&config)); + g_option_context_add_group (context, + mu_config_options_group_query(&config)); - g_option_context_add_group (context, mu_query_option_group()); - g_option_context_add_group (context, mu_index_option_group()); + mu_config_set_defaults (&config); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("error in options: %s\n", @@ -150,16 +141,19 @@ main (int argc, char *argv[]) mu_msg_gmime_init (); rv = MU_OK; - - + if (cmd == MU_CMD_INDEX) { MuIndex *midx; MuIndexStats stats; midx = mu_index_new ("/home/djcb/.mu"); rv = mu_index_run (midx, - "/home/djcb/Maildir", - FALSE, &stats, msg_cb, NULL, NULL); + config.maildir, + config.reindex, + &stats, + msg_cb, + NULL, + NULL); mu_index_destroy (midx); @@ -171,7 +165,7 @@ main (int argc, char *argv[]) rv = 1; } else { args = mu_util_strlist_from_args (argc-2, argv+2); - rv = mu_query_run (args); + rv = mu_query_run (&config, args); mu_util_strlist_free (args); } }