/*!
* \note this function will returns allocated(heap) string
*/
-static inline char *get_i18n_name(const char *lang, int id)
+static inline int get_i18n_name(const char *lang, int id, char **name, char **icon)
{
sqlite3_stmt *stmt;
- static const char *query = "SELECT name FROM shortcut_name WHERE id = ? AND lang = ? COLLATE NOCASE";
- const unsigned char *name;
- char *ret;
+ static const char *query = "SELECT name, icon FROM shortcut_name WHERE id = ? AND lang = ? COLLATE NOCASE";
+ const unsigned char *_name;
+ const unsigned char *_icon;
+ int ret;
int status;
status = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
if (status != SQLITE_OK) {
ErrPrint("Failed to prepare stmt: %s\n", sqlite3_errmsg(s_info.handle));
- return NULL;
+ return -EFAULT;
}
status = sqlite3_bind_int(stmt, 1, id);
if (status != SQLITE_OK) {
ErrPrint("Failed to bind id: %s\n", sqlite3_errmsg(s_info.handle));
- ret = NULL;
+ ret = -EFAULT;
goto out;
}
status = sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT);
if (status != SQLITE_OK) {
ErrPrint("Failed to bind lang: %s\n", sqlite3_errmsg(s_info.handle));
- ret = NULL;
+ ret = -EFAULT;
goto out;
}
DbgPrint("id: %d, lang: %s\n", id, lang);
if (SQLITE_ROW != sqlite3_step(stmt)) {
ErrPrint("Failed to do step: %s\n", sqlite3_errmsg(s_info.handle));
- ret = NULL;
+ ret = -ENOENT;
goto out;
}
- name = sqlite3_column_text(stmt, 0);
- ret = name ? strdup((const char *)name) : NULL;
+ _name = sqlite3_column_text(stmt, 0);
+ if (name) {
+ if (_name && strlen((const char *)_name)) {
+ *name = strdup((const char *)_name);
+ if (!*name) {
+ ErrPrint("strdup: %s\n", strerror(errno));
+ }
+ } else {
+ *name = NULL;
+ }
+ }
+
+ _icon = sqlite3_column_text(stmt, 1);
+ if (icon) {
+ if (_icon && strlen((const char *)_icon)) {
+ *icon = strdup((const char *)_icon);
+ if (!*icon) {
+ ErrPrint("strdup: %s\n", strerror(errno));
+ }
+ } else {
+ *icon = NULL;
+ }
+ }
out:
sqlite3_reset(stmt);
sqlite3_stmt *stmt;
const char *query;
const unsigned char *name;
- char *i18n_name;
+ char *i18n_name = NULL;
+ char *i18n_icon = NULL;
const unsigned char *extra_data;
const unsigned char *extra_key;
const unsigned char *icon;
* \todo
* Implement the "GET LOCALE" code
*/
- i18n_name = get_i18n_name(language, id);
+ if (get_i18n_name(language, id, &i18n_name, &i18n_icon) < 0) {
+ /* Okay, we can't manage this. just use the fallback string */
+ }
cnt++;
- if (cb(appid, (char *)icon, (i18n_name != NULL ? i18n_name : (char *)name), (char *)extra_key, (char *)extra_data, data) < 0) {
+ if (cb(appid, (i18n_icon != NULL ? i18n_icon : (char *)icon), (i18n_name != NULL ? i18n_name : (char *)name), (char *)extra_key, (char *)extra_data, data) < 0) {
free(i18n_name);
break;
}
free(i18n_name);
+ free(i18n_icon);
}
sqlite3_reset(stmt);
* | id | - | - | - | - | - | - |
* +----+-------+-------+------+---------+-----------+------------+
*
- * +----+-------+------+------+
- * | fk | pkgid | lang | name |
- * +----+-------+------+------+
- * | id | - | - | |
- * +----+-------+------+------+
+ * +----+-------+------+------+------+
+ * | fk | pkgid | lang | name | icon |
+ * +----+-------+------+------+------+
+ * | id | - | - | | - |
+ * +----+-------+------+------+------+
*/
#if !defined(LIBXML_TREE_ENABLED)
int errno;
+struct i18n_name {
+ xmlChar *icon;
+ xmlChar *name;
+ xmlChar *lang;
+};
+
static struct {
const char *dbfile;
sqlite3 *handle;
ErrPrint("No changes to DB\n");
}
- ddl = "CREATE TABLE shortcut_name (id INTEGER, pkgid TEXT, lang TEXT, name TEXT)";
+ ddl = "CREATE TABLE shortcut_name (id INTEGER, pkgid TEXT, lang TEXT, name TEXT, icon TEXT)";
if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
ErrPrint("Failed to execute the DDL (%s)\n", err);
return;
db_create_version();
}
+static void alter_shortcut_icon(void)
+{
+ char *err;
+ static const char *ddl = "ALTER TABLE shortcut_name ADD icon TEXT";
+
+ if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
+ ErrPrint("Failed to execute the DDL (%s)\n", err);
+ return;
+ }
+
+ if (sqlite3_changes(s_info.handle) == 0) {
+ ErrPrint("No changes to DB\n");
+ }
+}
+
static void alter_shortcut_name(void)
{
char *err;
alter_shortcut_name();
alter_shortcut_service();
case 1:
+ alter_shortcut_icon();
+ if (update_version(2) < 0) {
+ ErrPrint("Failed to update version\n");
+ }
+ case 2:
break;
default:
/* Need to update version */
DbgPrint("Old version: %d\n", version);
- if (update_version(1) < 0) {
+ if (update_version(2) < 0) {
ErrPrint("Failed to update version\n");
}
alter_shortcut_name();
alter_shortcut_service();
+ /* 2 */
+ alter_shortcut_icon();
break;
}
}
return ret;
}
-static int db_insert_name(int id, const char *pkgid, const char *lang, const char *name)
+static int db_insert_name(int id, const char *pkgid, const char *lang, const char *name, const char *icon)
{
- static const char *dml = "INSERT INTO shortcut_name (id, pkgid, lang, name) VALUES (?, ?, ?, ?)";
+ static const char *dml = "INSERT INTO shortcut_name (id, pkgid, lang, name) VALUES (?, ?, ?, ?, ?)";
sqlite3_stmt *stmt;
int ret;
- if (id < 0 || !lang || !name) {
+ if (id < 0 || !lang) {
ErrPrint("Invalid parameters\n");
return -EINVAL;
}
+ if (!name) {
+ name = "";
+ }
+
+ if (!icon) {
+ icon = "";
+ }
+
ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
if (ret != SQLITE_OK) {
ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
goto out;
}
+ if (sqlite3_bind_text(stmt, 5, icon, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+ ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
+ ret = -EIO;
+ goto out;
+ }
+
ret = 0;
if (sqlite3_step(stmt) != SQLITE_DONE) {
ErrPrint("Failed to execute the DML for %d %s %s\n", id, lang, name);
return 0;
}
+static inline struct i18n_name *find_i18n_name(struct dlist *i18n_list, xmlChar *lang)
+{
+ struct dlist *l;
+ struct i18n_name *i18n;
+
+ dlist_foreach(i18n_list, l, i18n) {
+ if (!xmlStrcasecmp(i18n->lang, lang)) {
+ return i18n;
+ }
+ }
+
+ return NULL;
+}
+
+static inline struct i18n_name *create_i18n_name(xmlChar *lang, xmlChar *name, xmlChar *icon)
+{
+ struct i18n_name *i18n;
+
+ i18n = malloc(sizeof(*i18n));
+ if (!i18n) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ i18n->lang = lang;
+ i18n->name = name;
+ i18n->icon = icon;
+
+ return i18n;
+}
+
+static inline void destroy_i18n_name(struct i18n_name *i18n)
+{
+ xmlFree(i18n->lang);
+ xmlFree(i18n->name);
+ xmlFree(i18n->icon);
+ free(i18n);
+}
+
static int do_install(xmlDocPtr docPtr, const char *appid)
{
xmlNodePtr node = NULL;
xmlChar *data;
xmlChar *name;
xmlChar *icon;
+ xmlChar *lang;
xmlChar *shortcut_appid;
xmlNodePtr root;
- struct i18n_name {
- xmlChar *name;
- xmlChar *lang;
- } *i18n;
+ struct i18n_name *i18n;
struct dlist *i18n_list = NULL;
struct dlist *l;
struct dlist *n;
name = NULL;
for (child = node->children; child; child = child->next) {
if (!xmlStrcasecmp(child->name, (const xmlChar *)"icon")) {
- if (icon) {
- DbgPrint("Icon is duplicated\n");
+ lang = xmlNodeGetLang(child);
+ if (!lang) {
+ if (icon) {
+ DbgPrint("Default icon is duplicated\n");
+ } else {
+ icon = xmlNodeGetContent(child);
+ DbgPrint("Default icon is %s\n", icon);
+ }
+
continue;
}
- icon = xmlNodeGetContent(child);
+ i18n = find_i18n_name(i18n_list, lang);
+ if (i18n) {
+ xmlFree(lang);
+
+ if (i18n->icon) {
+ DbgPrint("%s is duplicated\n", i18n->icon);
+ continue;
+ }
+
+ i18n->icon = xmlNodeGetContent(child);
+ } else {
+ i18n = create_i18n_name(lang, NULL, xmlNodeGetContent(child));
+ if (!i18n) {
+ ErrPrint("Failed to create a new i18n_name\n");
+ continue;
+ }
+ i18n_list = dlist_append(i18n_list, i18n);
+ }
+
continue;
}
if (!xmlStrcasecmp(child->name, (const xmlChar *)"label")) {
- xmlChar *lang;
lang = xmlNodeGetLang(child);
if (!lang) {
if (name) {
continue;
}
- i18n = malloc(sizeof(*i18n));
- if (!i18n) {
- ErrPrint("Heap: %s\n", strerror(errno));
- break;
+ i18n = find_i18n_name(i18n_list, lang);
+ if (i18n) {
+ xmlFree(lang);
+
+ if (i18n->name) {
+ DbgPrint("%s is duplicated\n", i18n->name);
+ continue;
+ }
+
+ i18n->name = xmlNodeGetContent(child);
+ } else {
+ i18n = create_i18n_name(lang, xmlNodeGetContent(child), NULL);
+ if (!i18n) {
+ ErrPrint("Failed to create a new i18n_name\n");
+ continue;
+ }
+ i18n_list = dlist_append(i18n_list, i18n);
}
- i18n->lang = lang;
- i18n->name = xmlNodeGetContent(child);
- i18n_list = dlist_append(i18n_list, i18n);
continue;
}
}
dlist_foreach_safe(i18n_list, l, n, i18n) {
i18n_list = dlist_remove(i18n_list, l);
- xmlFree(i18n->lang);
- xmlFree(i18n->name);
- free(i18n);
+ destroy_i18n_name(i18n);
}
} else {
id = db_get_id((char *)appid, (char *)shortcut_appid, (char *)key, (char *)data);
dlist_foreach_safe(i18n_list, l, n, i18n) {
i18n_list = dlist_remove(i18n_list, l);
- xmlFree(i18n->lang);
- xmlFree(i18n->name);
- free(i18n);
+ destroy_i18n_name(i18n);
}
} else {
dlist_foreach_safe(i18n_list, l, n, i18n) {
i18n_list = dlist_remove(i18n_list, l);
- if (db_insert_name(id, appid, (char *)i18n->lang, (char *)i18n->name) < 0) {
+ if (db_insert_name(id, appid, (char *)i18n->lang, (char *)i18n->name, (char *)i18n->icon) < 0) {
ErrPrint("Failed to add i18n name: %s(%s)\n", i18n->name, i18n->lang);
}
- xmlFree(i18n->lang);
- xmlFree(i18n->name);
- free(i18n);
+ destroy_i18n_name(i18n);
}
commit_transaction();
}