diff --git a/src/mu-str.c b/src/mu-str.c index 5afcca86..98b51e99 100644 --- a/src/mu-str.c +++ b/src/mu-str.c @@ -425,3 +425,95 @@ mu_str_escape_c_literal (const gchar* str) return g_string_free (tmp, FALSE); } + +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); + +leave: + { + gchar *tmp; + tmp = cleanup_str (nick); + g_free (nick); + nick = tmp; + } + + return nick; +} + diff --git a/src/mu-str.h b/src/mu-str.h index 97ba53a5..ad8894c0 100644 --- a/src/mu-str.h +++ b/src/mu-str.h @@ -261,6 +261,48 @@ char* mu_str_escape_c_literal (const gchar* str) */ #define mu_str_is_empty(S) ((!(S)||!(S)[0])?TRUE:FALSE) + + +/** + * 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; + G_END_DECLS #endif /*__MU_STR_H__*/ diff --git a/src/tests/test-mu-str.c b/src/tests/test-mu-str.c index 31d90db7..208ba568 100644 --- a/src/tests/test-mu-str.c +++ b/src/tests/test-mu-str.c @@ -251,6 +251,82 @@ test_mu_str_date_parse_hdwmy (void) } +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" }, + { "", "" } + }; + + 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); + } +} + + +static void +test_mu_str_guess_last_name (void) +{ + int i; + + struct { + char *src, *exp; + } tests[] = { + { "Richard M. Stallman", "Stallman" }, + { "John Rambo", "Rambo" }, + { "Ivanhoe", "" }, + { "", "" } + }; + + 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); + } +} + + + +static void +test_mu_str_guess_nick (void) +{ + int i; + + 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; + + s = mu_str_guess_nick (tests[i].src); + g_assert_cmpstr (s, ==, tests[i].exp); + g_free (s); + } +} + + + + + int main (int argc, char *argv[]) @@ -289,6 +365,12 @@ main (int argc, char *argv[]) g_test_add_func ("/mu-str/mu-str_date_parse_hdwmy", test_mu_str_date_parse_hdwmy); + 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); /* FIXME: add tests for mu_str_flags; but note the * function simply calls mu_msg_field_str */