X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fappcore-i18n.c;h=94289e60ac4621955e4df71ce308228c431425d9;hb=refs%2Fchanges%2F28%2F113328%2F10;hp=3cbefcc19ee6998ebbab8170738fcf9435868930;hpb=5ce24250be4c50783b93221e76fe58411e5f3dcd;p=platform%2Fcore%2Fappfw%2Fapp-core.git diff --git a/src/appcore-i18n.c b/src/appcore-i18n.c index 3cbefcc..94289e6 100644 --- a/src/appcore-i18n.c +++ b/src/appcore-i18n.c @@ -24,23 +24,266 @@ #include #include #include - +#include +#include +#include +#include +#include #include #include "appcore-internal.h" static int _set; +static char locale_dir[PATH_MAX]; + +static void __free_children_langs(gpointer data) +{ + GList *list = (GList *)data; + + if (list == NULL) + return; + + g_list_free_full(list, (GDestroyNotify)free); +} + +static gint __compare_langs(gconstpointer a, gconstpointer b) +{ + return strcmp(a, b); +} + +static GHashTable *__get_lang_table(void) +{ + GHashTable *table; + DIR *dp; + struct dirent *dentry; + char buf[PATH_MAX]; + struct stat stat_buf; + int ret; + char *dup_lang; + char *token; + GList *list; + + if (locale_dir[0] == 0 || locale_dir[0] == '\0') + return NULL; + + table = g_hash_table_new_full(g_str_hash, g_str_equal, + free, __free_children_langs); + if (table == NULL) { + _ERR("Out of memory"); + return NULL; + } + + dp = opendir(locale_dir); + if (dp == NULL) { + g_hash_table_destroy(table); + return NULL; + } + + while ((dentry = readdir(dp)) != NULL) { + if (!strcmp(dentry->d_name, ".") || + !strcmp(dentry->d_name, "..")) + continue; + + snprintf(buf, sizeof(buf), "%s/%s", locale_dir, dentry->d_name); + ret = stat(buf, &stat_buf); + if (ret != 0 || !S_ISDIR(stat_buf.st_mode)) + continue; + + dup_lang = strdup(dentry->d_name); + if (dup_lang == NULL) { + _ERR("Out of memory"); + break; + } + + token = strtok(dup_lang, "_"); + if (token == NULL) { + free(dup_lang); + continue; + } + + list = (GList *)g_hash_table_lookup(table, token); + if (list == NULL) { + list = g_list_append(list, strdup(dentry->d_name)); + g_hash_table_insert(table, strdup(token), list); + } else { + list = g_list_append(list, strdup(dentry->d_name)); + } + free(dup_lang); + } + closedir(dp); + + return table; +} + +static GList *__append_langs(const char *lang, GList *list, GHashTable *table) +{ + GList *child_list; + GList *child_iter; + GList *found; + char *child_lang; + char *dup_lang; + char *token; + + if (lang == NULL) + return list; + + found = g_list_find_custom(g_list_first(list), lang, + __compare_langs); + if (found) { + list = g_list_remove_link(list, found); + free(found->data); + g_list_free(found); + list = g_list_append(list, strdup(lang)); + return list; + } + + dup_lang = strdup(lang); + if (dup_lang == NULL) + return list; + + token = strtok(dup_lang, "_"); + if (token == NULL) { + free(dup_lang); + return list; + } + + child_list = g_hash_table_lookup(table, token); + if (child_list == NULL) { + free(dup_lang); + return list; + } + + found = g_list_find_custom(g_list_first(child_list), + lang, __compare_langs); + if (found) { + list = g_list_append(list, strdup(lang)); + child_list = g_list_remove_link(child_list, found); + free(found->data); + g_list_free(found); + free(dup_lang); + return list; + } + + found = g_list_find_custom(g_list_first(child_list), + token, __compare_langs); + if (found) { + list = g_list_append(list, strdup(token)); + child_list = g_list_remove_link(child_list, found); + free(found->data); + g_list_free(found); + free(dup_lang); + return list; + } + free(dup_lang); + + child_iter = g_list_first(child_list); + while (child_iter) { + child_lang = (char *)child_iter->data; + child_iter = g_list_next(child_iter); + if (child_lang) { + list = g_list_append(list, strdup(child_lang)); + child_list = g_list_remove(child_list, child_lang); + free(child_lang); + break; + } + } + + return list; +} + +static GList *__split_language(const char *lang) +{ + GList *list = NULL; + char *dup_lang; + char *token; + + dup_lang = strdup(lang); + if (dup_lang == NULL) { + _ERR("Out of memory"); + return NULL; + } + + token = strtok(dup_lang, ":"); + while (token != NULL) { + list = g_list_append(list, strdup(token)); + token = strtok(NULL, ":"); + } + free(dup_lang); + + return list; +} + +static char *__get_language(const char *lang) +{ + GHashTable *table; + GList *list; + GList *lang_list = NULL; + GList *iter; + char *language; + char buf[LINE_MAX] = {'\0'}; + size_t n; + + list = __split_language(lang); + if (list == NULL) + return NULL; + + table = __get_lang_table(); + if (table == NULL) { + g_list_free_full(list, free); + return NULL; + } + + iter = g_list_first(list); + while (iter) { + language = (char *)iter->data; + lang_list = __append_langs(language, lang_list, table); + iter = g_list_next(iter); + } + g_list_free_full(list, free); + g_hash_table_destroy(table); + + iter = g_list_first(lang_list); + while (iter) { + language = (char *)iter->data; + if (language) { + if (buf[0] == '\0') { + snprintf(buf, sizeof(buf), "%s", language); + } else { + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, ":", n); + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, language, n); + } + } + iter = g_list_next(iter); + } + g_list_free_full(lang_list, free); + + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, ":", n); + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, "en_US:en_GB:en", n); + + return strdup(buf); +} void update_lang(void) { - char language[32]; + char *language; char *lang; char *r; lang = vconf_get_str(VCONFKEY_LANGSET); if (lang) { - snprintf(language, sizeof(language), "%s:en_US:en_GB:en", lang); - setenv("LANGUAGE", language, 1); + /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */ + language = __get_language(lang); + if (language) { + _DBG("*****language(%s)", language); + setenv("LANGUAGE", language, 1); + free(language); + } else { + setenv("LANGUAGE", lang, 1); + } setenv("LANG", lang, 1); setenv("LC_MESSAGES", lang, 1); r = setlocale(LC_ALL, ""); @@ -113,10 +356,19 @@ static int __set_i18n(const char *domain, const char *dir) return 0; } +static void __set_locale_dir(const char *dirname) +{ + if (dirname == NULL) + return; + + snprintf(locale_dir, sizeof(locale_dir), "%s", dirname); +} + EXPORT_API int appcore_set_i18n(const char *domainname, const char *dirname) { int r; + __set_locale_dir(dirname); update_lang(); update_region(); @@ -131,6 +383,7 @@ int set_i18n(const char *domainname, const char *dirname) { _retv_if(_set, 0); + __set_locale_dir(dirname); update_lang(); update_region();