From a01196499f40658cce019387e6f9a9df3f04176a Mon Sep 17 00:00:00 2001 From: djcb Date: Wed, 24 Oct 2012 23:47:47 +0300 Subject: [PATCH] * mu-cfind: some cleanups / better help --- lib/mu-contacts.c | 60 +++++++++--------- lib/mu-str.c | 96 ----------------------------- lib/mu-str.h | 39 ------------ lib/tests/test-mu-str.c | 126 +++++++++++++++++++------------------- mu/mu-cmd-cfind.c | 131 ++++++++++++++++++++++++++++++++++++++-- mu/mu-config.c | 48 ++++++++------- mu/mu-config.h | 10 +-- mu/mu-help-strings.txt | 10 ++- 8 files changed, 260 insertions(+), 260 deletions(-) diff --git a/lib/mu-contacts.c b/lib/mu-contacts.c index 93e0b1fb..149af0cf 100644 --- a/lib/mu-contacts.c +++ b/lib/mu-contacts.c @@ -55,30 +55,6 @@ struct _MuContacts { }; -/* - * we use the e-mail address to create a key in the GKeyFile, but we - * have to mutilate a bit so that it's (a) *cough* practically-unique - * and (b) valid as a GKeyFile group name (ie., valid utf8, no control - * chars, no '[' or ']') - */ -static const char* -encode_email_address (const char *addr) -{ - static char enc[254 + 1]; /* max size for an e-mail addr */ - char *cur; - - if (!addr) - return FALSE; - - /* make sure chars are with {' ' .. '~'}, and not '[' ']' */ - for (cur = strncpy(enc, addr, sizeof(enc)); *cur != '\0'; ++cur) - if (!isalnum(*cur)) { - *cur = 'A' + (*cur % ('Z' - 'A')); - } else - *cur = tolower(*cur); - - return enc; -} static GKeyFile* load_key_file (const char *path) @@ -235,31 +211,53 @@ mu_contacts_clear (MuContacts *self) } +/* + * we use the e-mail address to create a key in the GKeyFile, but we + * have to mutilate a bit so that it's (a) *cough* practically-unique + * and (b) valid as a GKeyFile group name (ie., valid utf8, no control + * chars, no '[' or ']') + */ +static const char* +encode_email_address (const char *addr) +{ + static char enc[254 + 1]; /* max size for an e-mail addr */ + char *cur; + + if (!addr) + return FALSE; + + /* make sure chars are with {' ' .. '~'}, and not '[' ']' */ + for (cur = strncpy(enc, addr, sizeof(enc)); *cur != '\0'; ++cur) + if (!isalnum(*cur)) { + *cur = 'A' + (*cur % ('Z' - 'A')); + } else + *cur = tolower(*cur); + + return enc; +} gboolean -mu_contacts_add (MuContacts *self, const char *email, const char *name, +mu_contacts_add (MuContacts *self, const char *addr, const char *name, gboolean personal, time_t tstamp) { ContactInfo *cinfo; - const char* group; + const char *group; g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (email, FALSE); + g_return_val_if_fail (addr, FALSE); /* add the info, if either there is no info for this email * yet, *OR* the new one is more recent and does not have an * empty name */ - group = encode_email_address (email); + group = encode_email_address (addr); cinfo = (ContactInfo*) g_hash_table_lookup (self->_hash, group); if (!cinfo || (cinfo->_tstamp < tstamp && !mu_str_is_empty(name))) { ContactInfo *ci; - ci = contact_info_new (g_strdup(email), + ci = contact_info_new (g_strdup(addr), name ? g_strdup(name) : NULL, personal, tstamp); - g_hash_table_insert (self->_hash, g_strdup(group), ci); - return self->_dirty = TRUE; } diff --git a/lib/mu-str.c b/lib/mu-str.c index 48422d16..23329f92 100644 --- a/lib/mu-str.c +++ b/lib/mu-str.c @@ -625,102 +625,6 @@ mu_str_convert_to_utf8 (const char* buffer, const char *charset) } - -gchar* -mu_str_guess_last_name (const char *name) -{ - const gchar *lastsp; - - if (!name) - return g_strdup (""); - - lastsp = g_strrstr (name, " "); - - return g_strdup (lastsp ? lastsp + 1 : ""); -} - - -gchar* -mu_str_guess_first_name (const char *name) -{ - const gchar *lastsp; - - if (!name) - return g_strdup (""); - - lastsp = g_strrstr (name, " "); - - if (lastsp) - return g_strndup (name, lastsp - name); - else - return g_strdup (name); -} - -static gchar* -cleanup_str (const char* str) -{ - gchar *s; - const gchar *cur; - unsigned i; - - if (mu_str_is_empty(str)) - return g_strdup (""); - - s = g_new0 (char, strlen(str) + 1); - - for (cur = str, i = 0; *cur; ++cur) { - if (ispunct(*cur) || isspace(*cur)) - continue; - else - s[i++] = *cur; - } - - return s; -} - - -gchar* -mu_str_guess_nick (const char* name) -{ - gchar *fname, *lname, *nick; - gchar initial[7]; - - fname = mu_str_guess_first_name (name); - lname = mu_str_guess_last_name (name); - - /* if there's no last name, use first name as the nick */ - if (mu_str_is_empty(fname) || mu_str_is_empty(lname)) { - g_free (lname); - nick = fname; - goto leave; - } - - memset (initial, 0, sizeof(initial)); - /* couldn't we get an initial for the last name? */ - if (g_unichar_to_utf8 (g_utf8_get_char (lname), initial) == 0) { - g_free (lname); - nick = fname; - goto leave; - } - - nick = g_strdup_printf ("%s%s", fname, initial); - g_free (fname); - g_free (lname); - -leave: - { - gchar *tmp; - tmp = cleanup_str (nick); - g_free (nick); - nick = tmp; - } - - return nick; -} - - - - gchar* mu_str_quoted_from_strv (const gchar **params) { diff --git a/lib/mu-str.h b/lib/mu-str.h index 2f59a6db..118c6f36 100644 --- a/lib/mu-str.h +++ b/lib/mu-str.h @@ -319,45 +319,6 @@ void mu_str_free_list (GSList *lst); const gchar* mu_str_subject_normalize (const gchar* str); -/** - * guess some nick name for the given name; if we can determine an - * first name, last name, the nick will be first name + the first char - * of the last name. otherwise, it's just the first name. clearly, - * this is just a rough guess for setting an initial value for nicks. - * - * @param name a name - * - * @return the guessed nick, as a newly allocated string (free with g_free) - */ -gchar* mu_str_guess_nick (const char* name) - G_GNUC_WARN_UNUSED_RESULT; - - -/** - * guess the first name for the given name; clearly, - * this is just a rough guess for setting an initial value. - * - * @param name a name - * - * @return the first name, as a newly allocated string (free with - * g_free) - */ -gchar* mu_str_guess_first_name (const char* name) - G_GNUC_WARN_UNUSED_RESULT; - -/** - * guess the last name for the given name; clearly, - * this is just a rough guess for setting an initial value. - * - * @param name a name - * - * @return the last name, as a newly allocated string (free with - * g_free) - */ -gchar* mu_str_guess_last_name (const char* name) - G_GNUC_WARN_UNUSED_RESULT; - - /** * take a list of strings, and return the concatenation of their * quoted forms diff --git a/lib/tests/test-mu-str.c b/lib/tests/test-mu-str.c index 33665b77..a231c097 100644 --- a/lib/tests/test-mu-str.c +++ b/lib/tests/test-mu-str.c @@ -368,77 +368,77 @@ test_mu_str_to_list_strip (void) -static void -test_mu_str_guess_first_name (void) -{ - int i; +/* static void */ +/* test_mu_str_guess_first_name (void) */ +/* { */ +/* int i; */ - struct { - char *src, *exp; - } tests[] = { - { "Richard M. Stallman", "Richard M." }, - { "John Rambo", "John" }, - { "Ivanhoe", "Ivanhoe" }, - { "", "" } - }; +/* struct { */ +/* char *src, *exp; */ +/* } tests[] = { */ +/* { "Richard M. Stallman", "Richard M." }, */ +/* { "John Rambo", "John" }, */ +/* { "Ivanhoe", "Ivanhoe" }, */ +/* { "", "" } */ +/* }; */ - for (i = 0; i != G_N_ELEMENTS(tests); ++i) { - gchar *s; +/* for (i = 0; i != G_N_ELEMENTS(tests); ++i) { */ +/* gchar *s; */ - s = mu_str_guess_first_name (tests[i].src); - g_assert_cmpstr (s, ==, tests[i].exp); - g_free (s); - } -} +/* s = mu_str_guess_first_name (tests[i].src); */ +/* g_assert_cmpstr (s, ==, tests[i].exp); */ +/* g_free (s); */ +/* } */ +/* } */ -static void -test_mu_str_guess_last_name (void) -{ - int i; +/* static void */ +/* test_mu_str_guess_last_name (void) */ +/* { */ +/* int i; */ - struct { - char *src, *exp; - } tests[] = { - { "Richard M. Stallman", "Stallman" }, - { "John Rambo", "Rambo" }, - { "Ivanhoe", "" }, - { "", "" } - }; +/* struct { */ +/* char *src, *exp; */ +/* } tests[] = { */ +/* { "Richard M. Stallman", "Stallman" }, */ +/* { "John Rambo", "Rambo" }, */ +/* { "Ivanhoe", "" }, */ +/* { "", "" } */ +/* }; */ - for (i = 0; i != G_N_ELEMENTS(tests); ++i) { - gchar *s; +/* for (i = 0; i != G_N_ELEMENTS(tests); ++i) { */ +/* gchar *s; */ - s = mu_str_guess_last_name (tests[i].src); - g_assert_cmpstr (s, ==, tests[i].exp); - g_free (s); - } -} +/* s = mu_str_guess_last_name (tests[i].src); */ +/* g_assert_cmpstr (s, ==, tests[i].exp); */ +/* g_free (s); */ +/* } */ +/* } */ -static void -test_mu_str_guess_nick (void) -{ - int i; +/* static void */ +/* test_mu_str_guess_nick (void) */ +/* { */ +/* int i; */ - struct { - char *src, *exp; - } tests[] = { - { "Richard M. Stallman", "RichardMS" }, - { "John Rambo", "JohnR" }, - { "Ivanhoe", "Ivanhoe" }, - { "", "" } - }; +/* struct { */ +/* char *src, *exp; */ +/* } tests[] = { */ +/* { "Richard M. Stallman", "RichardMS" }, */ +/* { "John Rambo", "JohnR" }, */ +/* { "Ivanhoe", "Ivanhoe" }, */ +/* { "", "" } */ +/* }; */ - for (i = 0; i != G_N_ELEMENTS(tests); ++i) { - gchar *s; +/* for (i = 0; i != G_N_ELEMENTS(tests); ++i) { */ +/* gchar *s; */ - s = mu_str_guess_nick (tests[i].src); - g_assert_cmpstr (s, ==, tests[i].exp); - g_free (s); - } -} +/* s = mu_str_guess_nick (tests[i].src); */ +/* g_assert_cmpstr (s, ==, tests[i].exp); */ +/* g_free (s); */ +/* } */ +/* } */ @@ -509,12 +509,12 @@ main (int argc, char *argv[]) g_test_add_func ("/mu-str/mu-str-esc-to-list", test_mu_str_esc_to_list); - g_test_add_func ("/mu-str/mu_str_guess_first_name", - test_mu_str_guess_first_name); - g_test_add_func ("/mu-str/mu_str_guess_last_name", - test_mu_str_guess_last_name); - g_test_add_func ("/mu-str/mu_str_guess_nick", - test_mu_str_guess_nick); + /* g_test_add_func ("/mu-str/mu_str_guess_first_name", */ + /* test_mu_str_guess_first_name); */ + /* g_test_add_func ("/mu-str/mu_str_guess_last_name", */ + /* test_mu_str_guess_last_name); */ + /* g_test_add_func ("/mu-str/mu_str_guess_nick", */ + /* test_mu_str_guess_nick); */ g_test_add_func ("/mu-str/mu_str_subject_normalize", test_mu_str_subject_normalize); diff --git a/mu/mu-cmd-cfind.c b/mu/mu-cmd-cfind.c index 440f4fa3..796baf8c 100644 --- a/mu/mu-cmd-cfind.c +++ b/mu/mu-cmd-cfind.c @@ -23,6 +23,8 @@ #include #include +#include +#include #include "mu-cmd.h" #include "mu-util.h" @@ -31,6 +33,127 @@ #include "mu-contacts.h" #include "mu-runtime.h" +/** + * guess the last name for the given name; clearly, + * this is just a rough guess for setting an initial value. + * + * @param name a name + * + * @return the last name, as a newly allocated string (free with + * g_free) + */ +static gchar* +guess_last_name (const char *name) +{ + const gchar *lastsp; + + if (!name) + return g_strdup (""); + + lastsp = g_strrstr (name, " "); + + return g_strdup (lastsp ? lastsp + 1 : ""); +} + +/** + * guess the first name for the given name; clearly, + * this is just a rough guess for setting an initial value. + * + * @param name a name + * + * @return the first name, as a newly allocated string (free with + * g_free) + */ +static gchar* +guess_first_name (const char *name) +{ + const gchar *lastsp; + + if (!name) + return g_strdup (""); + + lastsp = g_strrstr (name, " "); + + if (lastsp) + return g_strndup (name, lastsp - name); + else + return g_strdup (name); +} + +/** + * guess some nick name for the given name; if we can determine an + * first name, last name, the nick will be first name + the first char + * of the last name. otherwise, it's just the first name. clearly, + * this is just a rough guess for setting an initial value for nicks. + * + * @param name a name + * + * @return the guessed nick, as a newly allocated string (free with g_free) + */ +static gchar* +cleanup_str (const char* str) +{ + gchar *s; + const gchar *cur; + unsigned i; + + if (mu_str_is_empty(str)) + return g_strdup (""); + + s = g_new0 (char, strlen(str) + 1); + + for (cur = str, i = 0; *cur; ++cur) { + if (ispunct(*cur) || isspace(*cur)) + continue; + else + s[i++] = *cur; + } + + return s; +} + + +static gchar* +guess_nick (const char* name) +{ + gchar *fname, *lname, *nick; + gchar initial[7]; + + fname = guess_first_name (name); + lname = guess_last_name (name); + + /* if there's no last name, use first name as the nick */ + if (mu_str_is_empty(fname) || mu_str_is_empty(lname)) { + g_free (lname); + nick = fname; + goto leave; + } + + memset (initial, 0, sizeof(initial)); + /* couldn't we get an initial for the last name? */ + if (g_unichar_to_utf8 (g_utf8_get_char (lname), initial) == 0) { + g_free (lname); + nick = fname; + goto leave; + } + + nick = g_strdup_printf ("%s%s", fname, initial); + g_free (fname); + g_free (lname); + +leave: + { + gchar *tmp; + tmp = cleanup_str (nick); + g_free (nick); + nick = tmp; + } + + return nick; +} + + + static void print_header (MuConfigFormat format) { @@ -52,8 +175,8 @@ each_contact_bbdb (const char *email, const char *name, time_t tstamp) { char *fname, *lname, *now, *timestamp; - fname = mu_str_guess_first_name (name); - lname = mu_str_guess_last_name (name); + fname = guess_first_name (name); + lname = guess_last_name (name); now = mu_date_str ("%Y-%m-%d", time(NULL)); timestamp = mu_date_str ("%Y-%m-%d", tstamp); @@ -76,7 +199,7 @@ each_contact_mutt_alias (const char *email, const char *name) if (!name) return; - nick = mu_str_guess_nick (name); + nick = guess_nick (name); mu_util_print_encoded ("alias %s %s <%s>\n", nick, name, email); g_free (nick); @@ -92,7 +215,7 @@ each_contact_wl (const char *email, const char *name) if (!name) return; - nick = mu_str_guess_nick (name); + nick = guess_nick (name); mu_util_print_encoded ("%s \"%s\" \"%s\"\n", email, nick, name); g_free (nick); diff --git a/mu/mu-config.c b/mu/mu-config.c index fcae4f9c..aa5be628 100644 --- a/mu/mu-config.c +++ b/mu/mu-config.c @@ -273,7 +273,7 @@ config_options_group_cfind (void) GOptionGroup *og; GOptionEntry entries[] = { {"format", 'o', 0, G_OPTION_ARG_STRING, &MU_CONFIG.formatstr, - "output format ('plain'(*), 'mutt', 'wanderlust'," + "output format ('plain'(*), 'mutt', 'wl'," "'org-contact', 'csv')", ""}, {"personal", 0, 0, G_OPTION_ARG_NONE, &MU_CONFIG.personal, "whether to only get 'personal' contacts", NULL}, @@ -476,7 +476,7 @@ cmd_from_string (const char *str) static gboolean -parse_cmd (int *argcp, char ***argvp) +parse_cmd (int *argcp, char ***argvp, GError **err) { MU_CONFIG.cmd = MU_CONFIG_CMD_NONE; MU_CONFIG.cmdstr = NULL; @@ -492,6 +492,23 @@ parse_cmd (int *argcp, char ***argvp) MU_CONFIG.cmdstr = (*argvp)[1]; MU_CONFIG.cmd = cmd_from_string (MU_CONFIG.cmdstr); +#ifndef BUILD_GUILE + if (MU_CONFIG.cmd == MU_CONFIG_CMD_SCRIPT) { + mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS, + "command 'script' not supported"); + return FALSE; + } +#endif /*!BUILD_GUILE*/ + +#ifndef BUILD_CRYPTO + if (MU_CONFIG.cmd == MU_CONFIG_CMD_VERIFIY) { + mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS, + "command 'verify' not supported"); + return FALSE; + } +#endif /*!BUILD_CRYPTO */ + + return TRUE; } @@ -627,9 +644,8 @@ show_usage (void) static gboolean -parse_params (int *argcp, char ***argvp) +parse_params (int *argcp, char ***argvp, GError **err) { - GError *err; GOptionContext *context; GOptionGroup *group; gboolean rv; @@ -648,44 +664,32 @@ parse_params (int *argcp, char ***argvp) case MU_CONFIG_CMD_HELP: /* 'help' is special; sucks in the options of the * command after it */ - rv = g_option_context_parse (context, argcp, argvp, &err) && + rv = g_option_context_parse (context, argcp, argvp, err) && cmd_help (); break; - case MU_CONFIG_CMD_SCRIPT: - /* script feeds the rest of the options to the script, so - * we accept all of them */ - g_option_context_set_ignore_unknown_options (context, TRUE); - /* fall through */ default: group = get_option_group (MU_CONFIG.cmd); if (group) g_option_context_add_group(context, group); - rv = g_option_context_parse (context, argcp, argvp, &err); + rv = g_option_context_parse (context, argcp, argvp, err); } - g_option_context_free (context); - if (rv) - return TRUE; - - /* something when wrong */ - g_printerr ("mu: option error: %s\n", err ? err->message : "?"); - g_clear_error (&err); - return FALSE; + return rv ? TRUE : FALSE; } MuConfig* -mu_config_init (int *argcp, char ***argvp) +mu_config_init (int *argcp, char ***argvp, GError **err) { g_return_val_if_fail (argcp && argvp, NULL); memset (&MU_CONFIG, 0, sizeof(MU_CONFIG)); - if (!parse_cmd (argcp, argvp)) + if (!parse_cmd (argcp, argvp, err)) goto errexit; - if (!parse_params(argcp, argvp)) + if (!parse_params(argcp, argvp, err)) goto errexit; /* fill in the defaults if user did not specify */ diff --git a/mu/mu-config.h b/mu/mu-config.h index 69804d10..0bf69179 100644 --- a/mu/mu-config.h +++ b/mu/mu-config.h @@ -188,12 +188,14 @@ typedef struct _MuConfig MuConfig; * mu_config_init, you should also call mu_config_uninit when the data * is no longer needed. * - * Note that is _static_ data, ie., mu_config_init will always return - * the same pointer + * Note that this is _static_ data, ie., mu_config_init will always + * return the same pointer * - * @param opts options + * @param argcp: pointer to argc + * @param argvp: pointer to argv + * @param err: receives error information */ -MuConfig *mu_config_init (int *argcp, char ***argvp) +MuConfig *mu_config_init (int *argcp, char ***argvp, GError **err) G_GNUC_WARN_UNUSED_RESULT; /** * free the MuConfig structure diff --git a/mu/mu-help-strings.txt b/mu/mu-help-strings.txt index d6e64d8a..1342e9b3 100644 --- a/mu/mu-help-strings.txt +++ b/mu/mu-help-strings.txt @@ -27,10 +27,18 @@ files must be specified with an absolute path. #BEGIN MU_CONFIG_CMD_CFIND #STRING -mu cfind [options] [] +mu cfind [options] [--format=] [] #STRING mu cfind is the mu command to find contacts in the mu database and export them for use in other programs. + + is one of: + mutt-alias + mutt-ab + wl + csv + org-contact + bbdb #END #BEGIN MU_CONFIG_CMD_EXTRACT