#include <libintl.h>
#include <stdlib.h>
#include <errno.h>
-
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <linux/limits.h>
+#include <glib.h>
#include <vconf.h>
#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, "");
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();
{
_retv_if(_set, 0);
+ __set_locale_dir(dirname);
update_lang();
update_region();
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <malloc.h>
#include <locale.h>
static GList *__events;
static GDBusConnection *__bus;
static guint __suspend_dbus_handler_initialized;
+static char *__locale_dir;
static void __invoke_callback(void *event, int type)
{
__invoke_callback(key, APPCORE_BASE_EVENT_LOW_BATTERY);
}
+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 == NULL || __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);
+}
+
static 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", language, 1);
+ }
setenv("LANG", lang, 1);
setenv("LC_MESSAGES", lang, 1);
r = setlocale(LC_ALL, "");
if (r == NULL)
_ERR("appcore: setlocale() error");
+ if (dir) {
+ if (__locale_dir)
+ free(__locale_dir);
+ __locale_dir = strdup(dir);
+ }
+
r = bindtextdomain(domain, dir);
if (r == NULL)
_ERR("appcore: bindtextdomain() error");
if (__context.ops.terminate)
__context.ops.terminate(__context.data);
+ if (__locale_dir) {
+ free(__locale_dir);
+ __locale_dir = NULL;
+ }
}
EXPORT_API int appcore_base_flush_memory(void)