diff --git a/libmuguile/mu-guile-common.c b/libmuguile/mu-guile-common.c deleted file mode 100644 index fef177d4..00000000 --- a/libmuguile/mu-guile-common.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -** Copyright (C) 2011 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. -** -*/ -#if HAVE_CONFIG_H -#include "config.h" -#endif /*HAVE_CONFIG_H*/ - -#include "mu-guile-common.h" -#include "mu-guile-store.h" -#include "mu-guile-msg.h" -#include "mu-guile-log.h" - -void -mu_guile_error (const char *func_name, int status, - const char *fmt, SCM args) -{ - scm_error_scm (scm_from_locale_symbol ("MuError"), - scm_from_utf8_string (func_name ? func_name : ""), - scm_from_utf8_string (fmt), args, - scm_list_1 (scm_from_int (status))); -} - -void -mu_guile_g_error (const char *func_name, GError *err) -{ - scm_error_scm (scm_from_locale_symbol ("MuError"), - scm_from_utf8_string (func_name), - scm_from_utf8_string (err ? err->message : "error"), - SCM_UNDEFINED, SCM_UNDEFINED); -} - - -void -mu_guile_init (void) -{ - scm_with_guile (&mu_guile_msg_init, NULL); - scm_with_guile (&mu_guile_store_init, NULL); - scm_with_guile (&mu_guile_log_init, NULL); -} - - -/* - * backward compat for pre-2.x guile - note, this will fail miserably - * if you don't use a UTF8 locale - */ -#if HAVE_PRE2_GUILE - -SCM -scm_from_utf8_string (const char* str) -{ - return scm_from_locale_string (str); -} - -char* -scm_to_utf8_string (SCM scm) -{ - return scm_to_locale_string (scm); -} - -#endif /*HAVE_PRE2_GUILE*/ diff --git a/libmuguile/Makefile.am b/src/guile/Makefile.am similarity index 67% rename from libmuguile/Makefile.am rename to src/guile/Makefile.am index 4964e4b6..17b778df 100644 --- a/libmuguile/Makefile.am +++ b/src/guile/Makefile.am @@ -2,7 +2,7 @@ ## ## 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 -## t he Free Software Foundation; either version 3 of the License, or +## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, @@ -16,38 +16,50 @@ include $(top_srcdir)/gtest.mk +# don't use -Werror, as it might break on other compilers +# use -Wno-unused-parameters, because some callbacks may not +# really need all the params they get +AM_CFLAGS=-Wall -Wextra -Wno-unused-parameter -Wdeclaration-after-statement +AM_CXXFLAGS=-Wall -Wextra -Wno-unused-parameter + # note, we need top_builddir for snarfing with 'make distcheck' (ie., # with separate builddir) -SUBDIRS= . -INCLUDES=-I. -I${top_builddir} -I${top_srcdir}/src -I${top_srcdir}/libmuguile ${GUILE_CFLAGS} ${GLIB_CFLAGS} +SUBDIRS= . mu +INCLUDES=-I. -I${top_builddir} -I${top_srcdir}/src ${GUILE_CFLAGS} ${GLIB_CFLAGS} # don't use -Werror, as it might break on other compilers # use -Wno-unused-parameters, because some callbacks may not # really need all the params they get -AM_CFLAGS=-Wall -Wextra -Wno-unused-parameter -Wdeclaration-after-statement -Wno-missing-braces \ - -Wno-missing-field-initializers -noinst_LTLIBRARIES= \ - libmuguile.la +lib_LTLIBRARIES= \ + libguile-mu.la -libmuguile_la_SOURCES= \ +libguile_mu_la_SOURCES= \ + mu-guile.c \ + mu-guile.h \ mu-guile-msg.c \ mu-guile-msg.h \ mu-guile-store.c \ mu-guile-store.h \ mu-guile-log.c \ mu-guile-log.h \ - mu-guile-common.c \ - mu-guile-common.h + mu-guile-util.c \ + mu-guile-util.h -libmuguile_la_LIBADD= \ +libguile_mu_la_LIBADD= \ ${top_builddir}/src/libmu.la \ ${GUILE_LIBS} XFILES= \ mu-guile-msg.x \ mu-guile-store.x \ - mu-guile-log.x + mu-guile-log.x \ + mu-guile.x + +moduledir=$(GUILE_SITEDIR) + +module_DATA= \ + mu.scm BUILT_SOURCES=$(XFILES) @@ -59,5 +71,7 @@ SUFFIXES = .x .doc ## Add -MG to make the .x magic work with auto-dep code. MKDEP = $(CC) -M -MG $(snarfcppopts) - DISTCLEANFILES=$(XFILES) + +EXTRA_DIST= \ + mu.scm diff --git a/libmuguile/mu-guile-log.c b/src/guile/mu-guile-log.c similarity index 88% rename from libmuguile/mu-guile-log.c rename to src/guile/mu-guile-log.c index 4aefade9..d985c62c 100644 --- a/libmuguile/mu-guile-log.c +++ b/src/guile/mu-guile-log.c @@ -17,7 +17,7 @@ ** */ -#include "mu-guile-common.h" +#include "mu-guile-util.h" #include "mu-guile-log.h" enum _LogType { @@ -33,17 +33,17 @@ write_log (LogType logtype, SCM FRM, SCM ARGS) #define FUNC_NAME __FUNCTION__ { SCM str; - + SCM_ASSERT (scm_is_string(FRM), FRM, SCM_ARG1, ""); SCM_VALIDATE_REST_ARGUMENT(ARGS); - + str = scm_simple_format (SCM_BOOL_F, FRM, ARGS); - + if (scm_is_string (str)) { gchar *output; output = scm_to_utf8_string (str); - + switch (logtype) { case LOG_INFO: g_message ("%s", output); break; case LOG_WARNING: g_warning ("%s", output); break; @@ -57,7 +57,7 @@ write_log (LogType logtype, SCM FRM, SCM ARGS) } -SCM_DEFINE (log_info, "mu:log:info", 1, 0, 1, (SCM FRM, SCM ARGS), +SCM_DEFINE_PUBLIC (log_info, "mu:log:info", 1, 0, 1, (SCM FRM, SCM ARGS), "log some message using a list of ARGS applied to FRM " "(in 'simple-format' notation).\n") #define FUNC_NAME s_info @@ -66,7 +66,7 @@ SCM_DEFINE (log_info, "mu:log:info", 1, 0, 1, (SCM FRM, SCM ARGS), } #undef FUNC_NAME -SCM_DEFINE (log_warning, "mu:log:warning", 1, 0, 1, (SCM FRM, SCM ARGS), +SCM_DEFINE_PUBLIC (log_warning, "mu:log:warning", 1, 0, 1, (SCM FRM, SCM ARGS), "log some warning using a list of ARGS applied to FRM (in 'simple-format' " "notation).\n") #define FUNC_NAME s_warning @@ -75,7 +75,7 @@ SCM_DEFINE (log_warning, "mu:log:warning", 1, 0, 1, (SCM FRM, SCM ARGS), } #undef FUNC_NAME -SCM_DEFINE (log_critical, "mu:log:critical", 1, 0, 1, (SCM FRM, SCM ARGS), +SCM_DEFINE_PUBLIC (log_critical, "mu:log:critical", 1, 0, 1, (SCM FRM, SCM ARGS), "log some critical message using a list of ARGS applied to FRM " "(in 'simple-format' notation).\n") #define FUNC_NAME s_critical @@ -87,10 +87,8 @@ SCM_DEFINE (log_critical, "mu:log:critical", 1, 0, 1, (SCM FRM, SCM ARGS), void* mu_guile_log_init (void *data) -{ +{ #include "mu-guile-log.x" return NULL; } - - diff --git a/libmuguile/mu-guile-log.h b/src/guile/mu-guile-log.h similarity index 100% rename from libmuguile/mu-guile-log.h rename to src/guile/mu-guile-log.h diff --git a/libmuguile/mu-guile-msg.c b/src/guile/mu-guile-msg.c similarity index 91% rename from libmuguile/mu-guile-msg.c rename to src/guile/mu-guile-msg.c index 2101aa6f..0065c0d2 100644 --- a/libmuguile/mu-guile-msg.c +++ b/src/guile/mu-guile-msg.c @@ -22,7 +22,7 @@ #include #include "mu-guile-msg.h" -#include "mu-guile-common.h" +#include "mu-guile-util.h" struct _MuMsgWrapper { MuMsg *_msg; @@ -38,7 +38,6 @@ mu_guile_scm_is_msg (SCM scm) return SCM_NIMP(scm) && (long)SCM_CAR(scm) == MSG_TAG; } - SCM mu_guile_msg_to_scm (MuMsg *msg) { @@ -53,7 +52,7 @@ mu_guile_msg_to_scm (MuMsg *msg) SCM_RETURN_NEWSMOB (MSG_TAG, msgwrap); } -SCM_DEFINE (msg_make_from_file, "mu:msg:make-from-file", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_make_from_file, "mu:msg:make-from-file", 1, 0, 0, (SCM PATH), "Create a message object based on the message in PATH.\n") #define FUNC_NAME s_msg_make_from_file @@ -67,7 +66,7 @@ SCM_DEFINE (msg_make_from_file, "mu:msg:make-from-file", 1, 0, 0, msg = mu_msg_new_from_file (scm_to_utf8_string (PATH), NULL, &err); if (err) { - mu_guile_g_error (FUNC_NAME, err); + mu_guile_util_g_error (FUNC_NAME, err); g_error_free (err); } @@ -76,7 +75,7 @@ SCM_DEFINE (msg_make_from_file, "mu:msg:make-from-file", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_move, "mu:msg:move-to-maildir", 2, 0, 0, +SCM_DEFINE_PUBLIC (msg_move, "mu:msg:move-to-maildir", 2, 0, 0, (SCM MSG, SCM TARGETMDIR), "Move message to another maildir TARGETMDIR. Note that this the " "base-level Maildir, ie. /home/user/Maildir/archive, and must" @@ -102,7 +101,7 @@ SCM_DEFINE (msg_move, "mu:msg:move-to-maildir", 2, 0, 0, scm_to_utf8_string (TARGETMDIR), flags, FALSE, &err); if (!rv && err) { - mu_guile_g_error (FUNC_NAME, err); + mu_guile_util_g_error (FUNC_NAME, err); g_error_free (err); } @@ -141,7 +140,7 @@ msg_num_field (SCM msg_smob, MuMsgFieldId mfid) } -SCM_DEFINE (msg_date, "mu:msg:date", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_date, "mu:msg:date", 1, 0, 0, (SCM MSG), "Get the date (time in seconds since epoch) for MSG.\n") #define FUNC_NAME s_msg_date @@ -155,7 +154,7 @@ SCM_DEFINE (msg_date, "mu:msg:date", 1, 0, 0, -SCM_DEFINE (msg_size, "mu:msg:size", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_size, "mu:msg:size", 1, 0, 0, (SCM MSG), "Get the size in bytes for MSG.\n") #define FUNC_NAME s_msg_size @@ -169,7 +168,7 @@ SCM_DEFINE (msg_size, "mu:msg:size", 1, 0, 0, -SCM_DEFINE (msg_prio, "mu:msg:priority", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_prio, "mu:msg:priority", 1, 0, 0, (SCM MSG), "Get the priority of MSG (low, normal or high).\n") #define FUNC_NAME s_msg_prio @@ -216,7 +215,7 @@ check_flag (MuFlags flag, FlagData *fdata) } -SCM_DEFINE (msg_flags, "mu:msg:flags", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_flags, "mu:msg:flags", 1, 0, 0, (SCM MSG), "Get the flags for MSG (one or or more of new, passed, replied, " "seen, trashed, draft, flagged, unread, signed, encrypted, " @@ -239,7 +238,7 @@ SCM_DEFINE (msg_flags, "mu:msg:flags", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_subject, "mu:msg:subject", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_subject, "mu:msg:subject", 1, 0, 0, (SCM MSG), "Get the subject of MSG.\n") #define FUNC_NAME s_msg_subject { @@ -250,7 +249,7 @@ SCM_DEFINE (msg_subject, "mu:msg:subject", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_from, "mu:msg:from", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_from, "mu:msg:from", 1, 0, 0, (SCM MSG), "Get the sender of MSG.\n") #define FUNC_NAME s_msg_from { @@ -309,7 +308,7 @@ contact_list_field (SCM msg_smob, MuMsgFieldId mfid) } -SCM_DEFINE (msg_to, "mu:msg:to", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_to, "mu:msg:to", 1, 0, 0, (SCM MSG), "Get the list of To:-recipients of MSG.\n") #define FUNC_NAME s_msg_to { @@ -321,7 +320,7 @@ SCM_DEFINE (msg_to, "mu:msg:to", 1, 0, 0, -SCM_DEFINE (msg_cc, "mu:msg:cc", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_cc, "mu:msg:cc", 1, 0, 0, (SCM MSG), "Get the list of Cc:-recipients of MSG.\n") #define FUNC_NAME s_msg_cc { @@ -332,7 +331,7 @@ SCM_DEFINE (msg_cc, "mu:msg:cc", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_bcc, "mu:msg:bcc", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_bcc, "mu:msg:bcc", 1, 0, 0, (SCM MSG), "Get the list of Bcc:-recipients of MSG.\n") #define FUNC_NAME s_msg_bcc { @@ -343,7 +342,7 @@ SCM_DEFINE (msg_bcc, "mu:msg:bcc", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_path, "mu:msg:path", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_path, "mu:msg:path", 1, 0, 0, (SCM MSG), "Get the filesystem path for MSG.\n") #define FUNC_NAME s_msg_path { @@ -354,7 +353,7 @@ SCM_DEFINE (msg_path, "mu:msg:path", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_maildir, "mu:msg:maildir", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_maildir, "mu:msg:maildir", 1, 0, 0, (SCM MSG), "Get the maildir where MSG lives.\n") #define FUNC_NAME s_msg_maildir { @@ -366,7 +365,7 @@ SCM_DEFINE (msg_maildir, "mu:msg:maildir", 1, 0, 0, -SCM_DEFINE (msg_msgid, "mu:msg:message-id", 1, 0, 0, +SCM_DEFINE_PUBLIC (msg_msgid, "mu:msg:message-id", 1, 0, 0, (SCM MSG), "Get the MSG's message-id.\n") #define FUNC_NAME s_msg_msgid { @@ -375,7 +374,7 @@ SCM_DEFINE (msg_msgid, "mu:msg:message-id", 1, 0, 0, #undef FUNC_NAME -SCM_DEFINE (msg_body, "mu:msg:body", 1, 1, 0, +SCM_DEFINE_PUBLIC (msg_body, "mu:msg:body", 1, 1, 0, (SCM MSG, SCM HTML), "Get the MSG's body. If HTML is #t, " "prefer the html-version, otherwise prefer plain text.\n") #define FUNC_NAME s_msg_body @@ -399,7 +398,7 @@ SCM_DEFINE (msg_body, "mu:msg:body", 1, 1, 0, #undef FUNC_NAME -SCM_DEFINE (msg_header, "mu:msg:header", 1, 1, 0, +SCM_DEFINE_PUBLIC (msg_header, "mu:msg:header", 1, 1, 0, (SCM MSG, SCM HEADER), "Get an arbitary HEADER from MSG.\n") #define FUNC_NAME s_msg_header { @@ -408,7 +407,8 @@ SCM_DEFINE (msg_header, "mu:msg:header", 1, 1, 0, const char *val; SCM_ASSERT (mu_guile_scm_is_msg(MSG), MSG, SCM_ARG1, FUNC_NAME); - SCM_ASSERT (scm_is_string (HEADER), HEADER, SCM_ARG2, FUNC_NAME); + SCM_ASSERT (scm_is_string (HEADER)||HEADER==SCM_UNDEFINED, + HEADER, SCM_ARG2, FUNC_NAME); msgwrap = (MuMsgWrapper*) SCM_CDR(MSG); header = scm_to_utf8_string (HEADER); @@ -440,7 +440,7 @@ msg_string_list_field (SCM msg_smob, MuMsgFieldId mfid) } -SCM_DEFINE (msg_tags, "mu:msg:tags", 1, 1, 0, +SCM_DEFINE_PUBLIC (msg_tags, "mu:msg:tags", 1, 0, 0, (SCM MSG), "Get the list of tags (contents of the " "X-Label:-header) for MSG.\n") #define FUNC_NAME s_msg_tags @@ -453,7 +453,7 @@ SCM_DEFINE (msg_tags, "mu:msg:tags", 1, 1, 0, -SCM_DEFINE (msg_refs, "mu:msg:references", 1, 1, 0, +SCM_DEFINE_PUBLIC (msg_refs, "mu:msg:references", 1, 0, 0, (SCM MSG), "Get the list of referenced message-ids " "(contents of the References: and Reply-To: headers).\n") #define FUNC_NAME s_msg_refs @@ -564,7 +564,6 @@ mu_guile_msg_load_current (const char *path) void* mu_guile_msg_init (void *data) { - MSG_TAG = scm_make_smob_type ("msg", sizeof(MuMsgWrapper)); scm_set_smob_mark (MSG_TAG, msg_mark); @@ -577,5 +576,3 @@ mu_guile_msg_init (void *data) return NULL; } - - diff --git a/libmuguile/mu-guile-msg.h b/src/guile/mu-guile-msg.h similarity index 100% rename from libmuguile/mu-guile-msg.h rename to src/guile/mu-guile-msg.h diff --git a/libmuguile/mu-guile-store.c b/src/guile/mu-guile-store.c similarity index 91% rename from libmuguile/mu-guile-store.c rename to src/guile/mu-guile-store.c index d4a508d4..e409bbb9 100644 --- a/libmuguile/mu-guile-store.c +++ b/src/guile/mu-guile-store.c @@ -23,7 +23,7 @@ #include "mu-guile-msg.h" #include "mu-guile-store.h" -#include "mu-guile-common.h" +#include "mu-guile-util.h" static MuQuery* get_query (void) @@ -41,7 +41,7 @@ get_query (void) mu_store_unref (store); if (!query) { - mu_guile_g_error ("", err); + mu_guile_util_g_error ("", err); g_clear_error (&err); } @@ -59,7 +59,7 @@ get_query_iter (MuQuery *query, const char* expr) iter = mu_query_run (query, expr, FALSE, MU_MSG_FIELD_ID_NONE, TRUE, &err); if (!iter) { - mu_guile_g_error ("", err); + mu_guile_util_g_error ("", err); g_clear_error (&err); } @@ -81,7 +81,7 @@ call_func (SCM FUNC, MuMsgIter *iter, const char* func_name) } -SCM_DEFINE (store_foreach, "mu:store:for-each", 1, 1, 0, +SCM_DEFINE_PUBLIC (store_foreach, "mu:store:for-each", 1, 1, 0, (SCM FUNC, SCM EXPR), "Call FUNC for each message in the store, or, if EXPR is specified, " "for each message matching EXPR.\n") @@ -93,7 +93,7 @@ SCM_DEFINE (store_foreach, "mu:store:for-each", 1, 1, 0, const char* expr; SCM_ASSERT (scm_procedure_p (FUNC), FUNC, SCM_ARG1, FUNC_NAME); - SCM_ASSERT (scm_is_string (EXPR) || EXPR == SCM_UNSPECIFIED, + SCM_ASSERT (scm_is_string (EXPR) || EXPR == SCM_UNDEFINED, EXPR, SCM_ARG2, FUNC_NAME); query = get_query (); @@ -125,5 +125,3 @@ mu_guile_store_init (void *data) return NULL; } - - diff --git a/libmuguile/mu-guile-store.h b/src/guile/mu-guile-store.h similarity index 100% rename from libmuguile/mu-guile-store.h rename to src/guile/mu-guile-store.h diff --git a/src/guile/mu-guile-util.c b/src/guile/mu-guile-util.c new file mode 100644 index 00000000..50b2fdae --- /dev/null +++ b/src/guile/mu-guile-util.c @@ -0,0 +1,155 @@ +/* +** Copyright (C) 2011 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-guile-util.h" + +SCM +mu_guile_util_error (const char *func_name, int status, + const char *fmt, SCM args) +{ + scm_error_scm (scm_from_locale_symbol ("MuError"), + scm_from_utf8_string (func_name ? func_name : ""), + scm_from_utf8_string (fmt), args, + scm_list_1 (scm_from_int (status))); + + return SCM_UNSPECIFIED; +} + +SCM +mu_guile_util_g_error (const char *func_name, GError *err) +{ + scm_error_scm (scm_from_locale_symbol ("MuError"), + scm_from_utf8_string (func_name), + scm_from_utf8_string (err ? err->message : "error"), + SCM_UNDEFINED, SCM_UNDEFINED); + + return SCM_UNSPECIFIED; +} + + + +#include +#include + +#include "mu-guile-util.h" +#include "mu-guile-msg.h" + +struct _GuileConfig { + const char *muhome; + char *msgpath; +}; +typedef struct _GuileConfig GuileConfig; + + +static GuileConfig* +guile_config_new (int *argcp, char ***argvp) +{ + GOptionContext *octx; + GuileConfig *opts = g_new0 (GuileConfig, 1); + GOptionEntry entries[] = { + {"muhome", 0, 0, G_OPTION_ARG_FILENAME, &opts->muhome, + "specify an alternative mu directory", NULL}, + {"msg", 0, 0, G_OPTION_ARG_FILENAME, &opts->msgpath, + "specify path to a message to load as mu:current-msg)", NULL}, + {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}/* sentinel */ + }; + + octx = g_option_context_new ("- mu guile options"); + g_option_context_add_main_entries (octx, entries, "mu guile"); + + if (!g_option_context_parse (octx, argcp, argvp, NULL)) { + g_option_context_free (octx); + g_printerr ("mu guile: error in options\n"); + return NULL; + } + + if (opts->msgpath) + opts->msgpath = mu_util_dir_expand (opts->msgpath); + + g_option_context_free (octx); + + return opts; +} + +static void +guile_config_destroy (GuileConfig *conf) +{ + g_free (conf->msgpath); + g_free (conf); +} + + + +gboolean +mu_guile_util_run (int *argcp, char **argvp[]) +{ + GuileConfig *opts; + +#ifdef HAVE_PRE2_GUILE + g_warning ("Note: mu guile will not function properly unless you are using a" + "UTF-8 locale."); +#endif /* HAVE_PRE2_GUILE */ + + opts = guile_config_new (argcp, argvp); + if (!opts) + goto error; + + if (!mu_runtime_init (opts->muhome /* NULL is okay */, + "mu-guile")) + goto error; + + /* FIXME: mu_guile_init (); /\* initialize mu guile modules *\/ */ + + if (opts->msgpath) { + if (!(gboolean)scm_with_guile + ((MuGuileFunc*)&mu_guile_msg_load_current, + opts->msgpath)) + goto error; + } + + scm_shell (*argcp, *argvp); + + mu_runtime_uninit (); + guile_config_destroy (opts); + + return TRUE; +error: + guile_config_destroy (opts); + return FALSE; +} + + + +/* + * backward compat for pre-2.x guile - note, this will fail miserably + * if you don't use a UTF8 locale + */ +#if HAVE_PRE2_GUILE + +SCM +scm_from_utf8_string (const char* str) +{ + return scm_from_locale_string (str); +} + +char* +scm_to_utf8_string (SCM scm) +{ + return scm_to_locale_string (scm); +} +#endif /*HAVE_PRE2_GUILE*/ diff --git a/libmuguile/mu-guile-common.h b/src/guile/mu-guile-util.h similarity index 61% rename from libmuguile/mu-guile-common.h rename to src/guile/mu-guile-util.h index 8bfde07f..00a230b4 100644 --- a/libmuguile/mu-guile-common.h +++ b/src/guile/mu-guile-util.h @@ -17,8 +17,8 @@ ** */ -#ifndef __MU_GUILE_COMMON_H__ -#define __MU_GUILE_COMMON_H__ +#ifndef __MU_GUILE_UTIL_H__ +#define __MU_GUILE_UTIL_H__ #include @@ -30,41 +30,44 @@ G_BEGIN_DECLS -/** - * output an error - * - * @param func_name - * @param status - * @param fmt - * @param args - */ -void mu_guile_error (const char *func_name, int status, - const char *fmt, SCM args); +/** + * start a guile shell with the mu modules loaded. function does not return + * + * @param argcp pointer to argc + * @param argvp pointer to argv + * + * @return FALSE in case of error, otherwise, the function will not return + */ +gboolean mu_guile_util_run (int *argcp, char **argvp[]); + + +/** + * output an error + * + * @param func_name + * @param status + * @param fmt + * @param args + */ +SCM mu_guile_util_error (const char *func_name, int status, + const char *fmt, SCM args); /** * display a GError as a Guile error - * + * * @param func_name function name * @param err Gerror */ -void mu_guile_g_error (const char *func_name, GError *err); +SCM mu_guile_util_g_error (const char *func_name, GError *err); -/** - * initialize the mu guile modules - * - */ -void mu_guile_init (void); - - -/* compatibility functions for old guile */ +/* compatibility functions for guile 1.8 */ #if HAVE_PRE2_GUILE SCM scm_from_utf8_string (const char* str); -char* scm_to_utf8_string (SCM scm); +char* scm_to_utf8_string (SCM scm); #endif /*HAVE_PRE2_GUILE*/ G_END_DECLS -#endif /*__MU_GUILE_COMMON_H__*/ - +#endif /*__MU_GUILE_UTIL_H__*/ diff --git a/src/guile/mu-guile.c b/src/guile/mu-guile.c new file mode 100644 index 00000000..e0530efa --- /dev/null +++ b/src/guile/mu-guile.c @@ -0,0 +1,83 @@ +/* +** Copyright (C) 2011 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. +** +*/ + +#if HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ + +#include +#include "mu-guile-util.h" + + +static gboolean initialized = FALSE; + +SCM_DEFINE_PUBLIC (init_mu, "mu:init", 0, 1, 0, + (SCM MUHOME), + "Initialize mu - needed before you call any of the other " + "functions. Optionally, you can provide MUHOME which " + "should be an absolute path to your mu home directory " + "(typically, the default, ~/.mu, should be just fine).\n") +#define FUNC_NAME s_init_mu +{ + const char *muhome; + static gboolean initialized = FALSE; + + SCM_ASSERT (scm_is_string (MUHOME) || SCM_UNBNDP(MUHOME), + MUHOME, SCM_ARG1, FUNC_NAME); + + if (initialized) + return mu_guile_util_error (FUNC_NAME, 0, "Already initialized", + SCM_UNSPECIFIED); + + muhome = SCM_UNBNDP(MUHOME) ? NULL : scm_to_utf8_string (MUHOME); + + if (!mu_runtime_init (muhome, "mu-guile")) + return mu_guile_util_error (FUNC_NAME, 0, "Failed to initialize mu", + SCM_UNSPECIFIED); + initialized = TRUE; + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + + +SCM_DEFINE_PUBLIC (init_p, "mu:init?", 0, 0, 0, + (void), "Whether mu is initialized or not.\n") +#define FUNC_NAME s_init_p +{ + return initialized ? SCM_BOOL_T : SCM_BOOL_F; +} +#undef FUNC_NAME + + +/* C function so we can cheaply check from other C-based code */ +gboolean +mu_guile_initialized (void) +{ + return initialized; +} + + +void* +mu_guile_init (void *data) +{ +#include "mu-guile.x" + + return NULL; +} diff --git a/src/guile/mu-guile.h b/src/guile/mu-guile.h new file mode 100644 index 00000000..59438f11 --- /dev/null +++ b/src/guile/mu-guile.h @@ -0,0 +1,48 @@ +/* +** Copyright (C) 2011 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_GUILE_H__ +#define __MU_GUILE_H__ + +#include + +G_BEGIN_DECLS + +/** + * Whether or not mu/guile has been initialized + * + * + * @return TRUE if it has been initialized, FALSE otherwise + */ +gboolean mu_guile_initialized (void); + + +/** + * Initialize this mu guile module. + * + * @param data + * + * @return + */ +void* mu_guile_init (void *data); + + +G_END_DECLS + +#endif /*__MU_GUILE_H__*/ diff --git a/src/guile/mu.scm b/src/guile/mu.scm new file mode 100644 index 00000000..4caf37c7 --- /dev/null +++ b/src/guile/mu.scm @@ -0,0 +1,25 @@ +;; +;; Copyright (C) 2011 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. + +(define-module (mu) + :use-module (mu log) + :use-module (mu msg) + :use-module (mu store)) + +;; mu_guile_init will actually initialize the msg/store/log as well +(load-extension "libguile-mu" "mu_guile_init") diff --git a/src/guile/mu/Makefile.am b/src/guile/mu/Makefile.am new file mode 100644 index 00000000..42c3b0e0 --- /dev/null +++ b/src/guile/mu/Makefile.am @@ -0,0 +1,28 @@ +## Copyright (C) 2008-2011 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 of the License, 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 $(top_srcdir)/gtest.mk + +moduledir=$(GUILE_SITEDIR)/mu + +module_DATA= \ + msg.scm \ + log.scm \ + store.scm \ + stats.scm + +EXTRA_DIST= \ + README diff --git a/toys/muile/README b/src/guile/mu/README similarity index 100% rename from toys/muile/README rename to src/guile/mu/README diff --git a/src/guile/mu/log.scm b/src/guile/mu/log.scm new file mode 100644 index 00000000..42f787eb --- /dev/null +++ b/src/guile/mu/log.scm @@ -0,0 +1,20 @@ +;; +;; Copyright (C) 2011 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. +(define-module (mu log)) + +(load-extension "libguile-mu" "mu_guile_log_init") diff --git a/src/guile/mu/msg.scm b/src/guile/mu/msg.scm new file mode 100644 index 00000000..87abda40 --- /dev/null +++ b/src/guile/mu/msg.scm @@ -0,0 +1,22 @@ +;; +;; Copyright (C) 2011 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. + +(define-module (mu msg) + :use-module (mu log)) + +(load-extension "libguile-mu" "mu_guile_msg_init") diff --git a/toys/muile/mu-stats.scm b/src/guile/mu/stats.scm similarity index 100% rename from toys/muile/mu-stats.scm rename to src/guile/mu/stats.scm diff --git a/toys/Makefile.am b/toys/Makefile.am index 2107b41f..c247c21a 100644 --- a/toys/Makefile.am +++ b/toys/Makefile.am @@ -27,17 +27,3 @@ endif if BUILD_WIDGETS SUBDIRS += mug2 endif - -# for muile, we need guile -if HAVE_GUILE -SUBDIRS += muile -endif - -# for procmule, we need guile and gio -if HAVE_GUILE -if HAVE_GIO -SUBDIRS += procmule -endif -endif - - diff --git a/toys/muile/Makefile.am b/toys/muile/Makefile.am deleted file mode 100644 index 64f0fc4a..00000000 --- a/toys/muile/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -## Copyright (C) 2011 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 -## t he Free Software Foundation; either version 3 of the License, 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 $(top_srcdir)/gtest.mk - -# enforce compiling this dir first before decending into tests/ -INCLUDES=-I${top_srcdir} -I${top_srcdir}/src ${GUILE_CFLAGS} ${GLIB_CFLAGS} - -# don't use -Werror, as it might break on other compilers -# use -Wno-unused-parameters, because some callbacks may not -# really need all the params they get -AM_CFLAGS=-Wall -Wextra -Wno-unused-parameter -Wdeclaration-after-statement -AM_CXXFLAGS=-Wall -Wextra -Wno-unused-parameter - -noinst_PROGRAMS= \ - muile - -muile_SOURCES= \ - muile.c \ - dummy.cc - -# we need to use dummy.cc to enforce c++ linking... -BUILT_SOURCES= \ - dummy.cc - -dummy.cc: - touch dummy.cc - -DISTCLEANFILES= \ - $(BUILT_SOURCES) - - - -muile_LDFLAGS= \ - ${top_builddir}/libmuguile/libmuguile.la diff --git a/toys/muile/muile.c b/toys/muile/muile.c deleted file mode 100644 index 6a2a5825..00000000 --- a/toys/muile/muile.c +++ /dev/null @@ -1,125 +0,0 @@ -/* -** Copyright (C) 2011 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. -** -*/ -#if HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ - -#include -#include - -#include -#include - -struct _MuileConfig { - const char *muhome; - char *msgpath; -}; -typedef struct _MuileConfig MuileConfig; - - -static MuileConfig * -muile_config_new (int *argcp, char ***argvp) -{ - GOptionContext *octx; - MuileConfig *opts = g_new0 (MuileConfig, 1); - GOptionEntry entries[] = { - {"muhome", 0, 0, G_OPTION_ARG_FILENAME, &opts->muhome, - "specify an alternative mu directory", NULL}, - {"msg", 0, 0, G_OPTION_ARG_FILENAME, &opts->msgpath, - "specify path to a message to load as mu:current-msg)", NULL}, - {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}/* sentinel */ - }; - - octx = g_option_context_new ("- muile options"); - g_option_context_add_main_entries (octx, entries, "Muile"); - - if (!g_option_context_parse (octx, argcp, argvp, NULL)) { - g_option_context_free (octx); - g_printerr ("muile: error in options\n"); - return NULL; - } - - if (opts->msgpath) - opts->msgpath = mu_util_dir_expand (opts->msgpath); - - g_option_context_free (octx); - - return opts; -} - -static void -muile_config_destroy (MuileConfig *conf) -{ - g_free (conf->msgpath); - g_free (conf); -} - - -static void -usage (void) -{ - g_print ("usage: muile [--muhome ] [--msg ]\n"); -} - - -int -main (int argc, char *argv[]) -{ - MuileConfig *opts; - - g_type_init (); - -#ifdef HAVE_PRE2_GUILE - g_warning ("Note: muile will not function properly unless you are using a" - "UTF-8 locale."); -#endif /* HAVE_PRE2_GUILE */ - - opts = muile_config_new (&argc, &argv); - if (!opts) { - usage (); - goto error; - } - - if (!mu_runtime_init (opts->muhome /* NULL is okay */, - "muile")) { - usage (); - goto error; - } - - mu_guile_init (); /* initialize mu guile modules */ - - if (opts->msgpath) { - if (!(gboolean)scm_with_guile - ((MuGuileFunc*)&mu_guile_msg_load_current, opts->msgpath)) - goto error; - } - - - scm_shell (argc, argv); - - mu_runtime_uninit (); - muile_config_destroy (opts); - - return 0; - -error: - muile_config_destroy (opts); - return 1; - -} diff --git a/toys/procmule/Makefile.am b/toys/procmule/Makefile.am deleted file mode 100644 index 7543376f..00000000 --- a/toys/procmule/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -## Copyright (C) 2011 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 -## t he Free Software Foundation; either version 3 of the License, 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 $(top_srcdir)/gtest.mk - -INCLUDES=-I${top_srcdir} -I${top_srcdir}/src ${GUILE_CFLAGS} ${GLIB_CFLAGS} - -# don't use -Werror, as it might break on other compilers -# use -Wno-unused-parameters, because some callbacks may not -# really need all the params they get -AM_CFLAGS=-Wall -Wextra -Wno-unused-parameter -Wdeclaration-after-statement -AM_CXXFLAGS=-Wall -Wextra -Wno-unused-parameter - -noinst_PROGRAMS= \ - procmule - -procmule_SOURCES= \ - procmule.c \ - dummy.cc - -# we need to use dummy.cc to enforce c++ linking... -BUILT_SOURCES= \ - dummy.cc - -dummy.cc: - touch dummy.cc - -# is this needed? -DISTCLEANFILES= \ - $(BUILT_SOURCES) - -procmule_LDFLAGS= \ - ${top_builddir}/libmuguile/libmuguile.la \ - ${top_builddir}/src/libmu.la \ - ${GIO_LIBS} - diff --git a/toys/procmule/README b/toys/procmule/README deleted file mode 100644 index 69d9165d..00000000 --- a/toys/procmule/README +++ /dev/null @@ -1,32 +0,0 @@ -* README - - The toy here is called 'procmule', which tries to offer procmail[1]-like - functionality from mu, with the procmailrc configuration language replaced - with guile and the mu-guile-bindings. - - Of course, I'm not arrogant enough to claim that I can replace a time-tested, - classical Unix tool so easily. On the other hand, I'm gluing existing tools - together. - - Now, the big difference with procmail is that procmail is an MDA - a mail - delivery agent. In practice, it typically reads a new e-mail message from - standard input (it's called from the local mail daemon), and then decides what - to do with it. - - In contrast, procmule watches a directory (or series of directories) for - changes - as soon as a new message appears in one of these directories, - procmule evaluates a Guile/Scheme program (typically, ~/.mu/procmule.scm) with - the message available as 'mu:current-msg'. - - - - -[1] http://www.procmail.org/ - -# Local Variables: -# mode: org; org-startup-folded: nil -# End: - - - - diff --git a/toys/procmule/procmule.c b/toys/procmule/procmule.c deleted file mode 100644 index 5e437685..00000000 --- a/toys/procmule/procmule.c +++ /dev/null @@ -1,295 +0,0 @@ -/* -** Copyright (C) 2011 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 -#include -#include - -#include "mu-runtime.h" -#include "mu-util.h" - -struct _ChildData { - char **shell_argv; - int shell_argc; -}; -typedef struct _ChildData ChildData; - -static ChildData * -child_data_new (const char *muhome) -{ - ChildData *data; - - data = g_new0 (ChildData, 1); - - data->shell_argv = g_new0 (char*,3); - data->shell_argc = 0; - - data->shell_argv[data->shell_argc++] = g_strdup ("procmule"); - data->shell_argv[data->shell_argc++] = g_strdup ("-s"); - data->shell_argv[data->shell_argc++] = - g_strdup_printf ("%s%cprocmule.scm", muhome, G_DIR_SEPARATOR); - - return data; -} - -static void -child_data_destroy (ChildData *data) -{ - if (!data) - return; - - g_strfreev (data->shell_argv); - g_free (data); -} - -static void -on_dir_change (GFileMonitor *mon, GFile *file, GFile *other_file, - GFileMonitorEvent event_type, ChildData *data) -{ - gchar *path; - - path = g_file_get_path (file); - - /* ignore all except create events */ - if (event_type != G_FILE_MONITOR_EVENT_CREATED) - return; - - if (fork() == 0) { /* run guile in child */ - - mu_guile_init (); /* initialize mu guile modules */ - - if (!(gboolean)scm_with_guile - ((MuGuileFunc*)&mu_guile_msg_load_current, path)) { - g_warning ("failed to set message in guile env"); - return; - } - scm_shell (data->shell_argc, data->shell_argv); /* never returns */ - } - - g_free (path); -} - -static GFileMonitor* -create_monitor (const char *path, ChildData *data) -{ - GFile *dir; - GFileMonitor *dirmon; - GError *err; - - if (!mu_util_check_dir (path, TRUE, FALSE)) { - g_warning ("must be a readable dir: '%s'", path); - return NULL; - } - - dir = g_file_new_for_path (path); - - err = NULL; - dirmon = g_file_monitor_directory (dir, G_FILE_MONITOR_NONE, - NULL, &err); - if (!dirmon) { - g_warning ("error adding monitor: %s", err->message); - g_error_free (err); - } - - g_object_unref (dir); - - if (dirmon) - g_signal_connect (dirmon, "changed", - G_CALLBACK(on_dir_change), data); - - return dirmon; -} - -static void -destroy_watchlist (GSList *lst) -{ - g_slist_foreach (lst, (GFunc)g_object_unref, NULL); - g_slist_free (lst); -} - - -GSList* -create_watchlist (char **dirs, ChildData *data) -{ - GSList *watchlist; - char **cur; - - /* TODO: check for dups */ - for (watchlist = NULL, cur = dirs; cur && *cur; ++cur) { - GFileMonitor *dirmon; - dirmon = create_monitor (*cur, data); - if (!dirmon) { - destroy_watchlist (watchlist); - return NULL; - } - watchlist = g_slist_prepend (watchlist, dirmon); - } - - return watchlist; -} - - -struct _PMConfig { - char *muhome; - char **watchdirs; - -}; -typedef struct _PMConfig PMConfig; - - -static void -expand_paths (PMConfig *opts) -{ - char **cur; - - for (cur = opts->watchdirs; cur && *cur; ++cur) - *cur = mu_util_dir_expand (*cur); - - if (opts->muhome) - opts->muhome = mu_util_dir_expand (opts->muhome); -} - - -static PMConfig * -pm_config_new (int *argcp, char ***argvp) -{ - GOptionContext *octx; - - PMConfig *opts = g_new0 (PMConfig, 1); - GOptionEntry entries[] = { - {"muhome", 0, 0, G_OPTION_ARG_FILENAME, &opts->muhome, - "specify an alternative mu directory", NULL}, - {"watch", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opts->watchdirs, - "directory to watch (may be specified multiple times)", NULL}, - {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}/* sentinel */ - }; - - octx = g_option_context_new ("- procmule options"); - g_option_context_add_main_entries (octx, entries, "Procmule"); - - if (!g_option_context_parse (octx, argcp, argvp, NULL)) { - g_printerr ("error in options\n"); - goto error; - } - - if (!opts->watchdirs) { - g_printerr ("specify at least one --watch=\n"); - goto error; - } - - expand_paths (opts); - - g_option_context_free (octx); - return opts; - -error: - if (octx) - g_option_context_free (octx); - g_free (opts); - return NULL; -} - -static void -pm_config_destroy (PMConfig *conf) -{ - if (!conf) - return; - - g_free (conf->muhome); - g_strfreev (conf->watchdirs); - - g_free (conf); -} - - -static void -usage (void) -{ - g_print ("usage: procmule [--muhome=] [--watch=]\n"); - g_print ("also, see toys/procmule/README\n"); -} - - -static gboolean -watch_dirs (char **watchdirs) -{ - ChildData *child_data; - GSList *watchlist; - GMainLoop *loop; - - child_data = child_data_new - (mu_runtime_path(MU_RUNTIME_PATH_MUHOME)); - - watchlist = create_watchlist (watchdirs, child_data); - if (!watchlist) - goto error; - - loop = g_main_loop_new (NULL, TRUE); - - g_main_loop_run (loop); - g_main_loop_unref (loop); - - destroy_watchlist (watchlist); - - return TRUE; - -error: - child_data_destroy (child_data); - return FALSE; - -} - - -int -main (int argc, char *argv[]) -{ - PMConfig *opts; - - g_type_init (); - g_thread_init (NULL); - -#ifdef HAVE_PRE2_GUILE - g_warning ("Note: pre-2.x version of guile: procmule will not function " - "correctly unless you're using UTF-8 locale."); -#endif /* HAVE_PRE2_GUILE */ - - opts = pm_config_new (&argc, &argv); - if (!opts) { - usage (); - goto error; - } - - if (!mu_runtime_init (opts->muhome, "procmule")) { - usage (); - goto error; - } - - watch_dirs (opts->watchdirs); /* do it! */ - mu_runtime_uninit (); - - pm_config_destroy (opts); - - return 0; - -error: - pm_config_destroy (opts); - return 1; - -}