static void fcitx_config_widget_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec) { FcitxConfigWidget* config_widget = FCITX_CONFIG_WIDGET(gobject); switch (prop_id) { case PROP_CONFIG_DESC: config_widget->cfdesc = g_value_get_pointer(value); break; case PROP_PREFIX: if (config_widget->prefix) g_free(config_widget->prefix); config_widget->prefix = g_strdup(g_value_get_string(value)); break; case PROP_NAME: if (config_widget->name) g_free(config_widget->name); config_widget->name = g_strdup(g_value_get_string(value)); break; case PROP_SUBCONFIG: if (config_widget->parser) sub_config_parser_free(config_widget->parser); config_widget->parser = sub_config_parser_new(g_value_get_string(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); break; } }
FcitxSubConfigParser* sub_config_parser_new(const gchar* subconfig) { if (subconfig == NULL) return NULL; FcitxSubConfigParser* parser = g_malloc0(sizeof(FcitxSubConfigParser)); parser->subconfigs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, sub_config_pattern_free); gchar** strv = g_strsplit(subconfig, ",", 0); gchar** str; for (str = &strv[0]; *str != NULL; str++) { if (strchr(*str, ':') == NULL) continue; gchar** items = g_strsplit(*str, ":", 0); if (g_strv_length(items) < 2) goto end; if (strlen(items[0]) == 0) goto end; if (strcmp(items[1], "domain") == 0) { parser->domain = g_strdup(items[0]); goto end; } SubConfigType type = parse_type(items[1]); if (type == SC_None) goto end; if (g_hash_table_lookup(parser->subconfigs, items[0]) != NULL) continue; if (type == SC_ConfigFile) { if (g_strv_length(items) != 4) goto end; if (strlen(items[2]) == 0 || items[2][0] == '/') goto end; } else if (type == SC_NativeFile) { if (g_strv_length(items) != 3) goto end; if (strchr(items[2], '*') != NULL) goto end; } gchar** paths = g_strsplit(items[2], "/", 0); if (paths[0] == 0) { g_strfreev(paths); goto end; } gchar** path; for (path = &paths[0]; *path != NULL; path++) { if (strlen(*path) == 0) break; if (strcmp(*path, ".") == 0) break; if (strcmp(*path, "..") == 0) break; } if (*path != NULL) { g_strfreev(paths); goto end; } FcitxSubConfigPattern* pattern = g_malloc0(sizeof(FcitxSubConfigPattern)); pattern->type = type; pattern->patternlist = paths; if (type == SC_ConfigFile) pattern->configdesc = g_strdup(items[3]); else if (type == SC_NativeFile) pattern->nativepath = g_strdup(items[2]); g_hash_table_insert(parser->subconfigs, g_strdup(items[0]), pattern); end: g_strfreev(items); } g_strfreev(strv); if (g_hash_table_size(parser->subconfigs) == 0 || parser->domain == NULL) { sub_config_parser_free(parser); parser = NULL; } return parser; }