diff --git a/libmuguile/mu-guile-msg.c b/libmuguile/mu-guile-msg.c index bc691dce..9db5e219 100644 --- a/libmuguile/mu-guile-msg.c +++ b/libmuguile/mu-guile-msg.c @@ -488,11 +488,39 @@ define_symbols (void) } +gboolean +mu_guile_msg_load_current (const char *path) +{ + MuMsg *msg; + GError *err; + SCM msgsmob; + + err = NULL; + msg = mu_msg_new_from_file (path, NULL, &err); + + if (!msg) { + g_printerr ("error creating message for '%s'", path); + if (err) { + g_printerr (": %s", err->message); + g_error_free (err); + } + g_printerr ("\n"); + return FALSE; + } + + msgsmob = mu_guile_msg_to_scm (msg); + scm_c_define ("mu:current", msgsmob); + + return TRUE; +} + + void* mu_guile_msg_init (void *data) { + MSG_TAG = scm_make_smob_type ("msg", sizeof(MuMsgWrapper)); - + scm_set_smob_mark (MSG_TAG, msg_mark); scm_set_smob_free (MSG_TAG, msg_free); scm_set_smob_print (MSG_TAG, msg_print); diff --git a/libmuguile/mu-guile-msg.h b/libmuguile/mu-guile-msg.h index 856fa627..e69b095d 100644 --- a/libmuguile/mu-guile-msg.h +++ b/libmuguile/mu-guile-msg.h @@ -27,15 +27,28 @@ extern "C" { #endif /*__cplusplus*/ -/** +typedef void* MuGuileFunc (void*); + +/** * register MuMsg-related functions/smobs with guile; use with * scm_with_guile - * + * + * @param data */ void *mu_guile_msg_init (void *data); -/** +/** + * set 'mu:msg:current in the guile env + * + * @param path path to a message + * + * @return TRUE if it worked, FALSE otherwise + */ +gboolean mu_guile_msg_load_current (const char *path); + + +/** * create an SCM for the MuMsg* * * @param msg a MuMsg instance diff --git a/toys/muile/muile.cc b/toys/muile/muile.cc index 880651ef..f9bd33d3 100644 --- a/toys/muile/muile.cc +++ b/toys/muile/muile.cc @@ -21,29 +21,106 @@ #endif /*HAVE_CONFIG_H*/ #include +#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:msg:current)", 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=] [msgfile]\n"); +} + int main (int argc, char *argv[]) { + MuileConfig *opts; + + g_type_init (); #ifdef HAVE_PRE2_GUILE g_warning ("Note: muile will not function correctly unless you have a " "UTF-8 locale."); #endif /* HAVE_PRE2_GUILE */ + + opts = muile_config_new (&argc, &argv); + if (!opts) { + usage (); + goto error; + } - mu_runtime_init (mu_util_guess_mu_homedir()); - + if (!mu_runtime_init (opts->muhome /* NULL is okay */)) { + usage (); + goto error; + } + scm_with_guile (&mu_guile_msg_init, NULL); scm_with_guile (&mu_guile_store_init, NULL); + 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; + }