static void fxaddon_load_numbered_entries(UT_array *ret, FcitxDesktopGroup *grp, const char *prefix, boolean stop_at_empty) { utarray_init(ret, fcitx_ptr_icd); size_t prefix_len = strlen(prefix); char *buff = malloc(prefix_len + FCITX_INT_LEN + 1); memcpy(buff, prefix, prefix_len); char *num_start = buff + prefix_len; int i; FcitxDesktopEntry *tmp_ety; for (i = 0;;i++) { sprintf(num_start, "%d", i); tmp_ety = fcitx_desktop_group_find_entry(grp, buff); if (!tmp_ety) break; if (!(tmp_ety->value && *tmp_ety->value)) { if (stop_at_empty) { break; } else { continue; } } utarray_push_back(ret, &tmp_ety->value); } free(buff); }
/** * Load uint16 array. * @param[in] option Configuration option. * @param[in,out] array Resulting array. * @return <0 - error. 0 - success. >0 - not found. */ static int zcfg_load_uint16_array(const config_setting_t *option, UT_array *array) { utarray_init(array, &ut_uint16_icd); if (!option) { return 1; } if (CONFIG_TYPE_ARRAY != option->type) { return -1; } int count = config_setting_length(option); for (int i = 0; i < count; i++) { int item = config_setting_get_int_elem(option, i); if ((item < 0) || (item > UINT16_MAX)) { ZLOG(LOG_ERR, "config:%s:%s: invalid port: %d", option->parent->name, option->name, item); utarray_done(array); return -1; } uint16_t port = (uint16_t) item; utarray_push_back(array, &port); } if (utarray_len(array)) { utarray_sort(array, uint16_cmp); } return 0; }
void MergeRules(FcitxXkbRules* rules, FcitxXkbRules* rulesextra) { utarray_concat(rules->modelInfos, rulesextra->modelInfos); utarray_concat(rules->optionGroupInfos, rulesextra->optionGroupInfos); FcitxXkbLayoutInfo* layoutInfo; UT_array toAdd; utarray_init(&toAdd, fcitx_ptr_icd); for (layoutInfo = (FcitxXkbLayoutInfo*) utarray_front(rulesextra->layoutInfos); layoutInfo != NULL; layoutInfo = (FcitxXkbLayoutInfo*) utarray_next(rulesextra->layoutInfos, layoutInfo)) { FcitxXkbLayoutInfo* l = FindByName(rules, layoutInfo->name); if (l) { utarray_concat(l->languages, layoutInfo->languages); utarray_concat(l->variantInfos, layoutInfo->variantInfos); } else utarray_push_back(&toAdd, &layoutInfo); } unsigned int i; for(i = 0;i < utarray_len(&toAdd);i++) { FcitxXkbLayoutInfo* p = *(FcitxXkbLayoutInfo**)utarray_eltptr(&toAdd, i); utarray_push_back(rules->layoutInfos, p); } utarray_done(&toAdd); FcitxXkbRulesFree(rulesextra); }
void* X11Create(FcitxInstance* instance) { FcitxX11 *x11priv = fcitx_utils_new(FcitxX11); x11priv->dpy = XOpenDisplay(NULL); if (x11priv->dpy == NULL) return NULL; x11priv->owner = instance; x11priv->iScreen = DefaultScreen(x11priv->dpy); x11priv->rootWindow = DefaultRootWindow(x11priv->dpy); x11priv->eventWindow = XCreateWindow(x11priv->dpy, x11priv->rootWindow, 0, 0, 1, 1, 0, 0, InputOnly, CopyFromParent, 0, NULL); X11InitAtoms(x11priv); utarray_init(&x11priv->handlers, &handler_icd); utarray_init(&x11priv->comphandlers, &comphandler_icd); FcitxX11AddFunctions(instance); #ifdef HAVE_XFIXES int ignore; if (XFixesQueryExtension(x11priv->dpy, &x11priv->xfixesEventBase, &ignore)) x11priv->hasXfixes = true; #endif X11InitSelection(x11priv); X11InitComposite(x11priv); X11InitScreen(x11priv); XWindowAttributes attr; XGetWindowAttributes(x11priv->dpy, x11priv->rootWindow, &attr); if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) { XSelectInput(x11priv->dpy, x11priv->rootWindow, attr.your_event_mask | StructureNotifyMask); } InitXErrorHandler(x11priv); X11DelayedCompositeTest(x11priv); FcitxInstanceAddTimeout(x11priv->owner, 5000, X11DelayedCompositeTest, x11priv); return x11priv; }
/** * @param[in] root Root section of config. * @param[in] zconf Config handle. * @return True on success. */ bool zconfig_load_sections(const config_setting_t *root, zconfig_t *zconf) { // global section config_setting_t *section = config_setting_get_member(root, ZCFG_SECTION_GLOBAL); if (!section) { ZLOG(LOG_ERR, "config: %s section not found", ZCFG_SECTION_GLOBAL); return false; } if (0 != zconfig_global_load(section, zconf)) { ZLOG(LOG_ERR, "config: failed to load %s section", ZCFG_SECTION_GLOBAL); return false; } // all other sections parse as scopes u_int sections_count = (u_int) config_setting_length(root); // global section + minimum one scope section if (sections_count < 2) { ZLOG(LOG_ERR, "config: no scopes found"); return false; } utarray_init(&zconf->scopes, &ut_ptr_icd); for (u_int i = 0; i < sections_count; i++) { section = config_setting_get_elem(root, i); if (!config_setting_is_group(section)) { continue; } if (0 == strcmp(section->name, ZCFG_SECTION_GLOBAL)) { continue; } for (size_t j = 0; j < utarray_len(&zconf->scopes); j++) { zconfig_scope_t *sc = *(zconfig_scope_t **) utarray_eltptr(&zconf->scopes, j); if (0 == strcasecmp(sc->name, section->name)) { ZLOG(LOG_ERR, "config: duplicate scope %s", section->name); return false; } } zconfig_scope_t *scope = malloc(sizeof(*scope)); if (0 == zconfig_scope_load(section, scope)) { utarray_push_back(&zconf->scopes, &scope); ZLOG(LOG_DEBUG, "config: loaded scope %s", scope->name); } else { zconfig_scope_destroy(scope); free(scope); ZLOG(LOG_ERR, "config: failed to load scope %s", section->name); return false; } } return true; }
FCITX_EXPORT_API FcitxCandidateWordList* FcitxCandidateWordNewList() { FcitxCandidateWordList* candList = fcitx_utils_malloc0(sizeof(FcitxCandidateWordList)); utarray_init(&candList->candWords, &cand_icd); utarray_reserve(&candList->candWords, 128); candList->wordPerPage = 5; /* anyway put a default value for safety */ strncpy(candList->strChoose, DIGIT_STR_CHOOSE, MAX_CAND_WORD); return candList; }
FCITX_EXPORT_API void FcitxAddonsInit(UT_array* addons) { utarray_init(addons, &addon_icd); /* * FIXME: this is a workaround since everyone is using "FcitxAddon*" everywhere, * so realloc will really do some evil things. * * We might better use UT_hash for fcitx addon in the future */ utarray_reserve(addons, 512); }
void InitSkinMenu(FcitxClassicUI* classicui) { utarray_init(&classicui->skinBuf, &ut_str_icd); FcitxMenuInit(&classicui->skinMenu); classicui->skinMenu.candStatusBind = NULL; classicui->skinMenu.name = strdup(_("Skin")); classicui->skinMenu.UpdateMenu = UpdateSkinMenu; classicui->skinMenu.MenuAction = SkinMenuAction; classicui->skinMenu.priv = classicui; classicui->skinMenu.isSubMenu = false; }
/** * Create firewall instance. * @return New instance. */ struct zfirewall *zfwall_create() { struct zfirewall *fire = malloc(sizeof(*fire)); bzero(fire, sizeof(*fire)); pthread_spin_init(&fire->lock, PTHREAD_PROCESS_PRIVATE); for (int proto = 0; proto < PROTO_MAX; proto++) { for (int rule = 0; rule < PORT_MAX; rule++) { utarray_init(&fire->rules[proto][rule], &ut_uint16_icd); } } return fire; }
/** * Load interfaces section. * @param[in] option Option name. * @param[in,out] array Resulting array. * @return <0 - error. 0 - success. >0 - not found. */ int zcfg_load_interfaces(const config_setting_t *option, UT_array *array) { utarray_init(array, &ut_zif_pair_icd); if (!option) { return 1; } if (CONFIG_TYPE_LIST != option->type) { return -1; } u_int count = (u_int) config_setting_length(option); for (u_int i = 0; i < count; i++) { zifpair_t if_pair; const char *str; config_setting_t *entry = config_setting_get_elem(option, i); if (!config_setting_lookup_string(entry, ZCFG_LAN, &str)) { ZLOG(LOG_ERR, "config:%s:%s: invalid or missing 'lan' property", option->parent->name, option->name); goto fail; } strncpy(if_pair.lan, str, sizeof(if_pair.lan)); if (!config_setting_lookup_string(entry, ZCFG_WAN, &str)) { ZLOG(LOG_ERR, "config:%s:%s: invalid or missing 'wan' property", option->parent->name, option->name); goto fail; } strncpy(if_pair.wan, str, sizeof(if_pair.wan)); int affinity = 0; if (!config_setting_lookup_int(entry, ZCFG_AFFINITY, &affinity)) { ZLOG(LOG_ERR, "config:%s:%s: invalid or missing 'affinity' property", option->parent->name, option->name); goto fail; } if ((affinity < 0) || affinity >= UINT16_MAX) { ZLOG(LOG_ERR, "config:%s:%s: invalid 'affinity' value", option->parent->name, option->name); goto fail; } if_pair.affinity = (uint16_t) affinity; utarray_push_back(array, &if_pair); } return 0; fail: utarray_done(array); return -1; }
/** * Load subnet array. * @param[in] cfg Config section. * @param[in] option Option name. * @param[in,out] array Resulting array. * @return <0 - error. 0 - success. >0 - not found. */ static int zcfg_load_subnet_list(const config_setting_t *option, zsubnet_group_t *array) { utarray_init(array, &ut_ip_range_icd); if (!option) { return 1; } if (CONFIG_TYPE_LIST != option->type) { return -1; } int count = config_setting_length(option); for (int i = 0; i < count; i++) { ip_range_t range; char ip_str[INET_ADDRSTRLEN]; const char *item = config_setting_get_string_elem(option, i); const char *cidr_pos = strchr(item, '/'); // search CIDR, and make sure, that ip part is not bigger than buffer size if (cidr_pos && (((size_t) (cidr_pos - item) < sizeof(ip_str)))) { strncpy(ip_str, item, cidr_pos - item); ip_str[cidr_pos - item] = '\0'; struct in_addr ip_addr; if (0 < inet_pton(AF_INET, ip_str, &ip_addr)) { uint8_t cidr = 0; if ((0 == str_to_u8(cidr_pos + 1, &cidr)) && (cidr <= CIDR_MAX)) { range.ip_start = ntohl(ip_addr.s_addr); range.ip_end = IP_RANGE_END(range.ip_start, cidr); utarray_push_back(array, &range); continue; } } } // error handler ZLOG(LOG_ERR, "config:%s:%s: invalid subnet: %s", option->parent->name, option->name, item); utarray_done(array); return -1; } if (count) { utarray_sort(array, ip_range_cmp); } return 0; }
/** * Load uint16 array from config. * @param[in] cfg Configuration option. * @param[in] option Option name. * @param[in,out] array Resulting array. * @return Zero on success. */ static int load_uint16_list(const config_setting_t *cfg, const char *option, UT_array *array) { config_setting_t *cfg_list = config_setting_get_member(cfg, option); if (!cfg_list) { ZERO_LOG(LOG_ERR, "config: missing %s entry", option); return 0; } if (config_setting_type(cfg_list) != CONFIG_TYPE_LIST) { ZERO_LOG(LOG_ERR, "config: invalid %s entry", option); return -1; } int count = config_setting_length(cfg_list); if (0 >= count) { return 0; } utarray_init(array, &ut_uint16_icd); for (int i = 0; i < count; i++) { int entry = config_setting_get_int_elem(cfg_list, i); if (!entry) { ZERO_LOG(LOG_ERR, "config: failed to get next %s record", option); continue; } if (entry < UINT16_MAX) { uint16_t port = entry; utarray_push_back(array, &port); continue; } // if we here, then entry is invalid ZERO_LOG(LOG_ERR, "config: invalid %s item: %d", option, entry); utarray_done(array); return -1; } utarray_sort(array, uint16_cmp); return 0; }
/** * Create new instance. * @param[in] max_bandwidth Max total bandwidth. * @return New instance. */ struct zmonitor *zmonitor_new(uint64_t max_bandwidth) { struct zmonitor *mon = malloc(sizeof(*mon)); if (unlikely(!mon)) { return NULL; } memset(mon, 0, sizeof(*mon)); if (unlikely(0 != pthread_rwlock_init(&mon->lock, NULL))) { free(mon); return NULL; } token_bucket_init(&mon->band, max_bandwidth); utarray_init(&mon->monitors, &ut_ptr_icd); return mon; }
FCITX_EXPORT_API void FcitxFrontendsInit(UT_array* frontends) { utarray_init(frontends, &frontend_icd); }
/** @加载皮肤配置文件 */ int LoadSkinConfig(FcitxSkin* sc, char** skinType) { FILE *fp; boolean isreload = False; int ret = 0; if (sc->config.configFile) { utarray_done(&sc->skinMainBar.skinPlacement); FcitxConfigFree(&sc->config); UnloadImage(sc); } memset(sc, 0, sizeof(FcitxSkin)); utarray_init(&sc->skinMainBar.skinPlacement, &place_icd); reload: if (!isreload) { char *buf; fcitx_utils_alloc_cat_str(buf, *skinType, "/fcitx_skin.conf"); fp = FcitxXDGGetFileWithPrefix("skin", buf, "r", NULL); free(buf); } else { char *path = fcitx_utils_get_fcitx_path_with_filename( "pkgdatadir", "/skin/default/fcitx_skin.conf"); fp = fopen(path, "r"); free(path); } if (fp) { FcitxConfigFile *cfile; FcitxConfigFileDesc* skinDesc = GetSkinDesc(); if (sc->config.configFile == NULL) { cfile = FcitxConfigParseConfigFileFp(fp, skinDesc); } else { cfile = sc->config.configFile; cfile = FcitxConfigParseIniFp(fp, cfile); } if (!cfile) { fclose(fp); fp = NULL; } else { FcitxSkinConfigBind(sc, cfile, skinDesc); FcitxConfigBindSync((FcitxGenericConfig*)sc); } } if (!fp) { if (isreload) { FcitxLog(FATAL, _("Can not load default skin, is installion correct?")); perror("fopen"); ret = 1; // 如果安装目录里面也没有配置文件,那就只好告诉用户,无法运行了 } else { perror("fopen"); FcitxLog(WARNING, _("Can not load skin %s, return to default"), *skinType); if (*skinType) free(*skinType); *skinType = strdup("default"); isreload = true; goto reload; } } if (fp) fclose(fp); sc->skinType = skinType; return ret; }
FCITX_EXPORT_API void FcitxMenuInit(FcitxUIMenu* menu) { memset(menu, 0, sizeof(FcitxUIMenu)); utarray_init(&menu->shell, &menuICD); }
int main(int argc, char **argv) { FILE *fout = stdout; char c; boolean alternativeOrder = false; while ((c = getopt(argc, argv, "ao:h")) != -1) { switch (c) { case 'a': alternativeOrder = true; break; case 'o': fout = fopen(optarg, "w"); if (!fout) { fprintf(stderr, "Cannot open file: %s\n", optarg); return 1; } break; case 'h': default: usage(); break; } } if (optind >= argc) { usage(); return 1; } FILE *fp = fopen(argv[optind], "r"); if (!fp) { fprintf(stderr, "Cannot open file: %s\n", argv[optind]); return 1; } char buf[BUFLEN], bufout[BUFLEN]; size_t count = fread(buf, 1, HEADER_SIZE, fp); if (count < HEADER_SIZE || memcmp(buf, header_str, HEADER_SIZE) != 0) { fprintf(stderr, "format error.\n"); fclose(fp); return 1; } conv = iconv_open("utf-8", "unicode"); if (conv == (iconv_t) -1) { fprintf(stderr, "iconv error.\n"); return 1; } fseek(fp, DESC_START, SEEK_SET); fread(buf, 1, DESC_LENGTH, fp); IconvStr in = buf; char *out = bufout; size_t inlen = DESC_LENGTH, outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(stderr, "%s\n", bufout); fread(buf, 1, LDESC_LENGTH, fp); in = buf; out = bufout; inlen = LDESC_LENGTH; outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(stderr, "%s\n", bufout); fread(buf, 1, NEXT_LENGTH, fp); in = buf; out = bufout; inlen = NEXT_LENGTH; outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(stderr, "%s\n", bufout); count = fread(buf, 1, PINYIN_SIZE, fp); if (count < PINYIN_SIZE || memcmp(buf, pinyin_str, PINYIN_SIZE) != 0) { fprintf(stderr, "format error.\n"); fclose(fp); return 1; } UT_array pys; utarray_init(&pys, &py_icd); for (; ;) { int16_t index; int16_t count; fread(&index, 1, sizeof(int16_t), fp); fread(&count, 1, sizeof(int16_t), fp); ScelPinyin py; memset(buf, 0, sizeof(buf)); memset(&py, 0, sizeof(ScelPinyin)); fread(buf, count, sizeof(char), fp); in = buf; out = py.pinyin; inlen = count * sizeof(char); outlen = 10; iconv(conv, &in, &inlen, &out, &outlen); utarray_push_back(&pys, &py); if (strcmp(py.pinyin, "zuo") == 0) break; } while (!feof(fp)) { int16_t symcount; int16_t count; int16_t wordcount; fread(&symcount, 1, sizeof(int16_t), fp); if (feof(fp)) break; fread(&count, 1, sizeof(int16_t), fp); wordcount = count / 2; int16_t* pyindex = malloc(sizeof(int16_t) * wordcount); fread(pyindex, wordcount, sizeof(int16_t), fp); int s; for (s = 0; s < symcount ; s++) { memset(buf, 0, sizeof(buf)); memset(bufout, 0, sizeof(bufout)); fread(&count, 1, sizeof(int16_t), fp); fread(buf, count, sizeof(char), fp); in = buf; out = bufout; inlen = count * sizeof(char); outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); if (alternativeOrder) { fprintf(fout, "%s ", bufout); } ScelPinyin *py = (ScelPinyin*)utarray_eltptr( &pys, (unsigned int)pyindex[0]); fprintf(fout, "%s", py->pinyin); int i; for (i = 1 ; i < wordcount ; i ++) { py = (ScelPinyin*)utarray_eltptr(&pys, (unsigned int)pyindex[i]); fprintf(fout, "\'%s", py->pinyin); } if (!alternativeOrder) { fprintf(fout, " %s", bufout); } fprintf(fout, "\n"); fread(&count, 1, sizeof(int16_t), fp); fread(buf, count, sizeof(char), fp); } free(pyindex); } iconv_close(conv); utarray_done(&pys); fclose(fout); fclose(fp); return 0; }
DBusMessage* FcitxDBusMenuGetGroupProperties(FcitxNotificationItem* notificationitem, DBusMessage* message) { /* signature aias */ DBusMessageIter args; dbus_message_iter_init(message, &args); DBusMessage* reply = NULL; do { if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) break; DBusMessageIter sub; dbus_message_iter_recurse(&args, &sub); UT_array ids; utarray_init(&ids, &ut_int32_icd); while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_INT32) { int32_t id; dbus_message_iter_get_basic(&sub, &id); utarray_push_back(&ids, &id); dbus_message_iter_next(&sub); } dbus_message_iter_next(&args); dbus_message_iter_recurse(&args, &sub); FcitxStringHashSet* properties = NULL; if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) { utarray_done(&ids); break; } while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { char* property; dbus_message_iter_get_basic(&sub, &property); if (!fcitx_utils_string_hash_set_contains(properties, property)) { properties = fcitx_utils_string_hash_set_insert(properties, property); } dbus_message_iter_next(&sub); } reply = dbus_message_new_method_return(message); /* out put is a(ia{sv}) */ DBusMessageIter iter; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ia{sv})", &sub); int i = 0; for (; i < utarray_len(&ids); i ++) { int32_t id = *(int32_t*) utarray_eltptr(&ids, i); DBusMessageIter ssub; dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &ssub); dbus_message_iter_append_basic(&ssub, DBUS_TYPE_INT32, &id); FcitxDBusMenuFillProperty(notificationitem, id, properties, &ssub); dbus_message_iter_close_container(&sub, &ssub); } dbus_message_iter_close_container(&iter, &sub); utarray_done(&ids); fcitx_utils_free_string_hash_set(properties); } while(0); if (!reply) { reply = FcitxDBusPropertyUnknownMethod(message); } return reply; }
FCITX_EXPORT_API void FcitxMenuInit(FcitxUIMenu* menu) { utarray_init(&menu->shell, &menuICD); }
/** * Load ip-mask array. * @param[in] cfg Config section. * @param[in] option Option name. * @param[in,out] array Resulting array. * @return Zero on success. */ static int load_ip_mask_list(const config_setting_t *cfg, const char *option, UT_array *array) { config_setting_t *cfg_list = config_setting_get_member(cfg, option); if (!cfg_list) { ZERO_LOG(LOG_ERR, "config: missing %s entry", option); return 0; } if (config_setting_type(cfg_list) != CONFIG_TYPE_LIST) { ZERO_LOG(LOG_ERR, "config: invalid %s entry", option); return -1; } int count = config_setting_length(cfg_list); if (0 >= count) { return 0; } utarray_init(array, &ut_ip_range_icd); for (int i = 0; i < count; i++) { struct ip_range range; const char *entry = config_setting_get_string_elem(cfg_list, i); if (!entry) { ZERO_LOG(LOG_ERR, "config: failed to get next %s record", option); continue; } char ip_str[INET_ADDRSTRLEN]; const char *cidr_pos = strchr(entry, '/'); // we search for CIDR, and make sure, that ip part is not bigger than allowed size if (cidr_pos && ((size_t)(cidr_pos - entry) < sizeof(ip_str))) { strncpy(ip_str, entry, cidr_pos - entry); ip_str[cidr_pos - entry] = '\0'; struct in_addr ip_addr; if (0 < inet_pton(AF_INET, ip_str, &ip_addr)) { u_long cidr = strtoul(cidr_pos + 1, NULL, 10); if (cidr != ULONG_MAX && cidr <= 32) { range.ip_start = ntohl(ip_addr.s_addr); range.ip_end = IP_RANGE_END(range.ip_start, cidr); utarray_push_back(array, &range); continue; } } } // if we here, then entry is invalid ZERO_LOG(LOG_ERR, "config: invalid %s item: %s", option, entry); utarray_done(array); return -1; } utarray_sort(array, ip_range_cmp); return 0; }
int main(int argc, char **argv) { FILE *fout = stdout; char c; while ((c = getopt(argc, argv, "o:h")) != -1) { switch (c) { case 'o': fout = fopen(optarg, "w"); if (!fout) fprintf(stderr, "can not open %s\n", optarg); break; case 'h': default: usage(); break; } } if (optind >= argc) usage(); FILE *fp = fopen(argv[optind], "r"); char buf[BUFLEN], bufout[BUFLEN]; size_t count = fread(buf, 1, HEADER_SIZE, fp); if (count < HEADER_SIZE || memcmp(buf, header_str, HEADER_SIZE) != 0) { fprintf(stderr, "format error.\n"); fclose(fp); return 1; } conv = iconv_open("utf-8", "unicode"); fseek(fp, DESC_START, SEEK_SET); fread(buf, 1, DESC_LENGTH, fp); IconvStr in = buf; char *out = bufout; size_t inlen = DESC_LENGTH, outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(stderr, "%s\n", bufout); fread(buf, 1, LDESC_LENGTH, fp); in = buf; out = bufout; inlen = LDESC_LENGTH; outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(stderr, "%s\n", bufout); fread(buf, 1, NEXT_LENGTH, fp); in = buf; out = bufout; inlen = NEXT_LENGTH; outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(stderr, "%s\n", bufout); count = fread(buf, 1, PINYIN_SIZE, fp); if (count < PINYIN_SIZE || memcmp(buf, pinyin_str, PINYIN_SIZE) != 0) { fprintf(stderr, "format error.\n"); fclose(fp); return 1; } UT_array* pys = malloc(sizeof(UT_array)); utarray_init(pys, &py_icd); for (; ;) { short index; short count; fread(&index, 1, sizeof(short), fp); fread(&count, 1, sizeof(short), fp); ScelPinyin py; memset(buf, 0, sizeof(buf)); memset(&py, 0, sizeof(ScelPinyin)); fread(buf, count, sizeof(char), fp); in = buf; out = py.pinyin; inlen = count * sizeof(char); outlen = 10; iconv(conv, &in, &inlen, &out, &outlen); utarray_push_back(pys, &py); if (strcmp(py.pinyin, "zuo") == 0) break; } while (!feof(fp)) { short symcount; short count; short wordcount; fread(&symcount, 1, sizeof(short), fp); if (feof(fp)) break; fread(&count, 1, sizeof(short), fp); short pyindex[10]; wordcount = count / 2; fread(pyindex, wordcount, sizeof(short), fp); int s; for (s = 0; s < symcount ; s++) { ScelPinyin *py = (ScelPinyin*) utarray_eltptr(pys, pyindex[0]); fprintf(fout, "%s", py->pinyin); int i; for (i = 1 ; i < wordcount ; i ++) { py = (ScelPinyin*) utarray_eltptr(pys, pyindex[i]); fprintf(fout, "\'%s", py->pinyin); } memset(buf, 0, sizeof(buf)); memset(bufout, 0, sizeof(bufout)); fread(&count, 1, sizeof(short), fp); fread(buf, count, sizeof(char), fp); in = buf; out = bufout; inlen = count * sizeof(char); outlen = BUFLEN; iconv(conv, &in, &inlen, &out, &outlen); fprintf(fout, " %s\n", bufout); fread(&count, 1, sizeof(short), fp); fread(buf, count, sizeof(char), fp); } } fclose(fout); fclose(fp); return 0; }
void* RunInstance(void* arg) { FcitxInstance* instance = (FcitxInstance*) arg; FcitxAddonsInit(&instance->addons); FcitxInstanceInitIM(instance); FcitxInstanceInitNoPreeditApps(instance); FcitxFrontendsInit(&instance->frontends); InitFcitxModules(&instance->modules); InitFcitxModules(&instance->eventmodules); utarray_init(&instance->uistats, &stat_icd); utarray_init(&instance->uicompstats, &compstat_icd); utarray_init(&instance->uimenus, fcitx_ptr_icd); utarray_init(&instance->timeout, &timeout_icd); utarray_init(&instance->icdata, &icdata_icd); instance->input = FcitxInputStateCreate(); instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig)); instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile)); instance->globalIMName = strdup(""); if (instance->fd >= 0) { fcntl(instance->fd, F_SETFL, O_NONBLOCK); } else { instance->fd = -1; } if (!FcitxGlobalConfigLoad(instance->config)) goto error_exit; FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord); int overrideDelay = instance->overrideDelay; if (overrideDelay < 0) overrideDelay = instance->config->iDelayStart; if (overrideDelay > 0) sleep(overrideDelay); instance->timeStart = time(NULL); instance->globalState = instance->config->defaultIMState; instance->totaltime = 0; FcitxInitThread(instance); if (!FcitxProfileLoad(instance->profile, instance)) goto error_exit; if (FcitxAddonGetConfigDesc() == NULL) goto error_exit; if (GetIMConfigDesc() == NULL) goto error_exit; FcitxAddonsLoad(&instance->addons); FcitxInstanceFillAddonOwner(instance, NULL); FcitxInstanceResolveAddonDependency(instance); FcitxInstanceInitBuiltInHotkey(instance); FcitxInstanceInitBuiltContext(instance); FcitxModuleLoad(instance); if (instance->loadingFatalError) return NULL; if (!FcitxInstanceLoadAllIM(instance)) { goto error_exit; } FcitxInstanceInitIMMenu(instance); FcitxUIRegisterMenu(instance, &instance->imMenu); FcitxUIRegisterStatus(instance, instance, "remind", instance->profile->bUseRemind ? _("Use remind") : _("No remind"), _("Toggle Remind"), ToggleRemindState, GetRemindEnabled); FcitxUISetStatusVisable(instance, "remind", false); FcitxUILoad(instance); instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName); if (instance->iIMIndex < 0) { instance->iIMIndex = 0; } FcitxInstanceSwitchIMByIndex(instance, instance->iIMIndex); if (!FcitxInstanceLoadFrontend(instance)) { goto error_exit; } /* fcitx is running in a standalone thread or not */ if (instance->sem) { sem_post(&instance->notifySem); sem_wait(&instance->startUpSem); } else { instance->initialized = true; } uint64_t curtime = 0; while (1) { FcitxAddon** pmodule; uint8_t signo = 0; if (instance->fd >= 0) { while (read(instance->fd, &signo, sizeof(char)) > 0) { if (signo == SIGINT || signo == SIGTERM || signo == SIGQUIT || signo == SIGXCPU) FcitxInstanceEnd(instance); else if (signo == SIGHUP) FcitxInstanceRestart(instance); else if (signo == SIGUSR1) FcitxInstanceReloadConfig(instance); } } do { instance->eventflag &= (~FEF_PROCESS_EVENT_MASK); for (pmodule = (FcitxAddon**) utarray_front(&instance->eventmodules); pmodule != NULL; pmodule = (FcitxAddon**) utarray_next(&instance->eventmodules, pmodule)) { FcitxModule* module = (*pmodule)->module; module->ProcessEvent((*pmodule)->addonInstance); } struct timeval current_time; gettimeofday(¤t_time, NULL); curtime = (current_time.tv_sec * 1000LL) + (current_time.tv_usec / 1000LL); unsigned int idx = 0; while(idx < utarray_len(&instance->timeout)) { TimeoutItem* ti = (TimeoutItem*) utarray_eltptr(&instance->timeout, idx); uint64_t id = ti->idx; if (ti->time + ti->milli <= curtime) { ti->callback(ti->arg); ti = (TimeoutItem*) utarray_eltptr(&instance->timeout, idx); /* faster remove */ if (ti && ti->idx == id) utarray_remove_quick(&instance->timeout, idx); else { FcitxInstanceRemoveTimeoutById(instance, id); idx = 0; } } else { idx++; } } if (instance->eventflag & FEF_UI_MOVE) FcitxUIMoveInputWindowReal(instance); if (instance->eventflag & FEF_UI_UPDATE) FcitxUIUpdateInputWindowReal(instance); } while ((instance->eventflag & FEF_PROCESS_EVENT_MASK) != FEF_NONE); setjmp(FcitxRecover); if (instance->destroy || instance->restart) { FcitxInstanceRealEnd(instance); break; } if (instance->eventflag & FEF_RELOAD_ADDON) { instance->eventflag &= ~(FEF_RELOAD_ADDON); FcitxInstanceReloadAddon(instance); } FD_ZERO(&instance->rfds); FD_ZERO(&instance->wfds); FD_ZERO(&instance->efds); instance->maxfd = 0; if (instance->fd > 0) { instance->maxfd = instance->fd; FD_SET(instance->fd, &instance->rfds); } for (pmodule = (FcitxAddon**) utarray_front(&instance->eventmodules); pmodule != NULL; pmodule = (FcitxAddon**) utarray_next(&instance->eventmodules, pmodule)) { FcitxModule* module = (*pmodule)->module; module->SetFD((*pmodule)->addonInstance); } if (instance->maxfd == 0) break; struct timeval tval; struct timeval* ptval = NULL; if (utarray_len(&instance->timeout) != 0) { unsigned long int min_time = LONG_MAX; TimeoutItem* ti; for (ti = (TimeoutItem*)utarray_front(&instance->timeout);ti; ti = (TimeoutItem*)utarray_next(&instance->timeout, ti)) { if (ti->time + ti->milli - curtime < min_time) { min_time = ti->time + ti->milli - curtime; } } tval.tv_usec = (min_time % 1000) * 1000; tval.tv_sec = min_time / 1000; ptval = &tval; } select(instance->maxfd + 1, &instance->rfds, &instance->wfds, &instance->efds, ptval); } if (instance->restart) { fcitx_utils_restart_in_place(); } return NULL; error_exit: sem_post(&instance->startUpSem); FcitxInstanceEnd(instance); return NULL; }
/** Load interfaces section. * @param[in] cfg Config section. * @param[in] option Option name. * @param[in,out] array Resulting array. * @return Zero on success. */ int load_interfaces(const config_setting_t *cfg, const char *option, UT_array *array) { config_setting_t *cfg_list = config_setting_get_member(cfg, option); if (!cfg_list) { ZERO_LOG(LOG_ERR, "config: missing %s entry", option); return -1; } if (config_setting_type(cfg_list) != CONFIG_TYPE_LIST) { ZERO_LOG(LOG_ERR, "config: invalid %s entry", option); return -1; } int count = config_setting_length(cfg_list); if (0 >= count) { ZERO_LOG(LOG_ERR, "config: empty %s entry", option); return -1; } utarray_init(array, &ut_zif_pair_icd); for (int i = 0; i < count; i++) { struct zif_pair if_pair; const char *str; config_setting_t *entry = config_setting_get_elem(cfg_list, i); if (NULL == entry) { ZERO_LOG(LOG_ERR, "config: failed to read %u-th group of %s entry", i, option); goto fail; } if (!config_setting_lookup_string(entry, ZCFG_LAN, &str)) { ZERO_LOG(LOG_ERR, "config: failed to read '%s' property of %u-th group of %s entry", ZCFG_LAN, i, option); goto fail; } strncpy(if_pair.lan, str, sizeof(if_pair.lan)); if (!config_setting_lookup_string(entry, ZCFG_WAN, &str)) { ZERO_LOG(LOG_ERR, "config: failed to read '%s' property of %u-th group of %s entry", ZCFG_WAN, i, option); goto fail; } strncpy(if_pair.wan, str, sizeof(if_pair.wan)); int affinity = 0; if (!config_setting_lookup_int(entry, ZCFG_AFFINITY, &affinity)) { ZERO_LOG(LOG_ERR, "config: failed to read '%s' property of %u-th group of %s entry", ZCFG_AFFINITY, i, option); goto fail; } if ((affinity < 0) || affinity >= UINT16_MAX) { ZERO_LOG(LOG_ERR, "config: invalid value in '%s' property of %u-th group of %s entry", ZCFG_AFFINITY, i, option); goto fail; } if_pair.affinity = (uint16_t)affinity; utarray_push_back(array, &if_pair); } return 0; fail: utarray_done(array); return -1; }
static void py_enhance_load_py(PinyinEnhance *pyenhance) { UT_array *array = &pyenhance->py_list; if (array->icd) return; utarray_init(array, fcitx_ptr_icd); FILE *fp; char *fname; fname = fcitx_utils_get_fcitx_path_with_filename( "pkgdatadir", "py-enhance/"PY_TABLE_FILE); fp = fopen(fname, "r"); free(fname); if (fp) { FcitxMemoryPool *pool = pyenhance->static_pool; char buff[UTF8_MAX_LENGTH + 1]; int buff_size = 33; int8_t *list_buff = malloc(buff_size); size_t res; int8_t word_l; int8_t count; int8_t min_size; FcitxPYEnhancePYList *py_list; int i; FcitxPYEnhancePY *py; while (true) { res = fread(&word_l, 1, 1, fp); if (!res || word_l < 0 || word_l > UTF8_MAX_LENGTH) break; res = fread(buff, word_l, 1, fp); if (!res) break; res = fread(&count, 1, 1, fp); if (!res || count < 0) break; if (count == 0) continue; min_size = count * 3; if (buff_size < min_size) { buff_size = min_size; list_buff = realloc(list_buff, buff_size); } res = fread(list_buff, min_size, 1, fp); if (!res) break; py_list = fcitx_memory_pool_alloc_align( pool, (sizeof(FcitxPYEnhancePYList) + sizeof(FcitxPYEnhancePY) * count), 1); memcpy(py_list->word, buff, word_l); py_list->word[word_l] = '\0'; py_list->count = count; for (i = 0;i < count;i++) { py = pinyin_enhance_pylist_get(py_list, i); int8_t *tmp = list_buff + i * 3; py->konsonant = tmp[0]; py->vokal = tmp[1]; py->tone = tmp[2]; } for (i = utarray_len(array) - 1;i >= 0;i--) { FcitxPYEnhancePYList *ele; ele = *(FcitxPYEnhancePYList**)_utarray_eltptr(array, i); if (strcmp(ele->word, py_list->word) < 0) { break; } } utarray_insert(array, &py_list, i + 1); } free(list_buff); fclose(fp); } }
static void py_enhance_load_py(PinyinEnhance *pyenhance) { UT_array *array = &pyenhance->py_list; if (array->icd) return; utarray_init(array, fcitx_ptr_icd); FILE *fp; char *fname; fname = fcitx_utils_get_fcitx_path_with_filename( "pkgdatadir", "py-enhance/"PY_TABLE_FILE); fp = fopen(fname, "r"); free(fname); if (fp) { FcitxMemoryPool *pool = pyenhance->static_pool; char buff[UTF8_MAX_LENGTH + 1]; int buff_size = 33; int8_t *list_buff = malloc(buff_size); size_t res; int8_t word_l; int8_t count; int8_t py_size; int i; int8_t *py_list; int8_t *tmp; /** * Format: * int8_t word_l; * char word[word_l]; * int8_t count; * int8_t py[count][3]; **/ while (true) { res = fread(&word_l, 1, 1, fp); if (!res || word_l < 0 || word_l > UTF8_MAX_LENGTH) break; res = fread(buff, word_l + 1, 1, fp); if (!res) break; count = buff[word_l]; if (count < 0) break; if (count == 0) continue; py_size = count * 3; if (buff_size < py_size) { buff_size = py_size; list_buff = realloc(list_buff, buff_size); } res = fread(list_buff, py_size, 1, fp); if (!res) break; py_list = fcitx_memory_pool_alloc(pool, word_l + py_size + 3); py_list[0] = word_l + 1; py_list++; memcpy(py_list, buff, word_l); tmp = py_list + word_l; *tmp = '\0'; tmp++; *tmp = count; memcpy(tmp + 1, list_buff, py_size); for (i = utarray_len(array) - 1;i >= 0;i--) { if (strcmp(*(char**)_utarray_eltptr(array, i), (char*)py_list) < 0) { break; } } utarray_insert(array, &py_list, i + 1); } free(list_buff); fclose(fp); } }
boolean FcitxKkcLoadDictionary(FcitxKkc* kkc) { FILE* fp = FcitxXDGGetFileWithPrefix("kkc", "dictionary_list", "r", NULL); if (!fp) { return false; } UT_array dictionaries; utarray_init(&dictionaries, &dict_icd); char *buf = NULL; size_t len = 0; char *trimmed = NULL; while (getline(&buf, &len, fp) != -1) { if (trimmed) free(trimmed); trimmed = fcitx_utils_trim(buf); UT_array* list = fcitx_utils_split_string(trimmed, ','); do { if (utarray_len(list) < 3) { break; } boolean typeFile = false; char* path = NULL; int mode = 0; utarray_foreach(item, list, char*) { char* key = *item; char* value = strchr(*item, '='); if (!value) continue; *value = '\0'; value++; if (strcmp(key, "type") == 0) { if (strcmp(value, "file") == 0) { typeFile = true; } } else if (strcmp(key, "file") == 0) { path = value; } else if (strcmp(key, "mode") == 0) { if (strcmp(value, "readonly") == 0) { mode = 1; } else if (strcmp(value, "readwrite") == 0) { mode = 2; } } } if (mode == 0 || path == NULL || !typeFile) { break; } if (mode == 1) { KkcSystemSegmentDictionary* dict = kkc_system_segment_dictionary_new(path, "EUC-JP", NULL); if (dict) { utarray_push_back(&dictionaries, &dict); } } else { char* needfree = NULL; char* realpath = NULL; if (strncmp(path, "$FCITX_CONFIG_DIR/", strlen("$FCITX_CONFIG_DIR/")) == 0) { FcitxXDGGetFileUserWithPrefix("", path + strlen("$FCITX_CONFIG_DIR/"), NULL, &needfree); realpath = needfree; } else { realpath = path; } KkcUserDictionary* userdict = kkc_user_dictionary_new(realpath, NULL); if (needfree) { free(needfree); } if (userdict) { utarray_push_back(&dictionaries, &userdict); } } } while(0); fcitx_utils_free_string_list(list); }
/** *导入所有数据。skinName变量应为到皮肤所在目录的完整路径 **/ MyLoadConfig::MyLoadConfig(const QString& skinName) { memset(&this->skin, 0, sizeof(FcitxSkin)); utarray_init(&skin.skinMainBar.skinPlacement, &place_icd); int chk=LoadSkinConfig(&this->skin, skinName); }
FCITX_EXPORT_API FcitxInstance* FcitxInstanceCreate(sem_t *sem, int argc, char* argv[]) { FcitxInstance* instance = fcitx_utils_malloc0(sizeof(FcitxInstance)); FcitxAddonsInit(&instance->addons); FcitxInstanceInitIM(instance); FcitxFrontendsInit(&instance->frontends); InitFcitxModules(&instance->eventmodules); utarray_init(&instance->uistats, &stat_icd); utarray_init(&instance->uimenus, &menup_icd); instance->input = FcitxInputStateCreate(); instance->sem = sem; instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig)); instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile)); if (!FcitxGlobalConfigLoad(instance->config)) goto error_exit; FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord); if (!ProcessOption(instance, argc, argv)) goto error_exit; instance->timeStart = time(NULL); instance->globalState = instance->config->defaultIMState; instance->totaltime = 0; FcitxInitThread(instance); if (!FcitxProfileLoad(instance->profile, instance)) goto error_exit; if (FcitxAddonGetConfigDesc() == NULL) goto error_exit; if (GetIMConfigDesc() == NULL) goto error_exit; FcitxAddonsLoad(&instance->addons); /* FIXME: a walkaround for not have instance in function FcitxModuleInvokeFunction */ FcitxAddon* addon; for (addon = (FcitxAddon *) utarray_front(&instance->addons); addon != NULL; addon = (FcitxAddon *) utarray_next(&instance->addons, addon)) { addon->owner = instance; } FcitxInstanceResolveAddonDependency(instance); FcitxInstanceInitBuiltInHotkey(instance); FcitxInstanceInitBuiltContext(instance); FcitxModuleLoad(instance); if (!FcitxInstanceLoadAllIM(instance)) { FcitxInstanceEnd(instance); return instance; } FcitxInstanceInitIMMenu(instance); FcitxUIRegisterMenu(instance, &instance->imMenu); FcitxUIRegisterStatus(instance, instance, "remind", _("Remind"), _("Remind"), ToggleRemindState, GetRemindEnabled); FcitxUILoad(instance); instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName); FcitxInstanceSwitchIM(instance, instance->iIMIndex); instance->lastIMIndex = instance->iIMIndex; if (!FcitxInstanceLoadFrontend(instance)) { FcitxInstanceEnd(instance); return instance; } if (instance->config->bFirstRun) { instance->config->bFirstRun = false; FcitxGlobalConfigSave(instance->config); const char *imname = "fcitx"; char *strTemp; asprintf(&strTemp, "@im=%s", imname); if ((getenv("XMODIFIERS") != NULL && CHECK_ENV("XMODIFIERS", strTemp, true)) || (CHECK_ENV("GTK_IM_MODULE", "xim", false) && CHECK_ENV("GTK_IM_MODULE", "fcitx", false)) || (CHECK_ENV("QT_IM_MODULE", "xim", false) && CHECK_ENV("QT_IM_MODULE", "fcitx", false))) { char *msg[12]; msg[0] = _("Please check your environment varibles."); msg[1] = _("You can use tools provided by your distribution."); msg[2] = _("Or You may need to set environment varibles below to make fcitx work correctly."); msg[3] = "export XMODIFIERS=\"@im=fcitx\""; msg[4] = "export QT_IM_MODULE=xim"; msg[5] = "export GTK_IM_MODULE=xim"; msg[6] = _("Or (Depends on you install im module or not)"); msg[7] = "export XMODIFIERS=\"@im=fcitx\""; msg[8] = "export QT_IM_MODULE=fcitx"; msg[9] = "export GTK_IM_MODULE=fcitx"; msg[10] = _("If you use login manager like gdm or kdm, put those lines in your ~/.xprofile."); msg[11] = _("If you use ~/.xinitrc and startx, put those lines in ~/.xinitrc."); FcitxUIDisplayMessage(instance, _("Setting Hint"), msg, 12); } free(strTemp); } /* make in order to use block X, query is not good here */ pthread_create(&instance->pid, NULL, RunInstance, instance); return instance; error_exit: FcitxInstanceEnd(instance); return instance; }
FCITX_EXPORT_API FcitxInstance* FcitxInstanceCreateWithFD(sem_t *sem, int argc, char* argv[], int fd) { FcitxInstance* instance = fcitx_utils_malloc0(sizeof(FcitxInstance)); FcitxAddonsInit(&instance->addons); FcitxInstanceInitIM(instance); FcitxFrontendsInit(&instance->frontends); InitFcitxModules(&instance->modules); InitFcitxModules(&instance->eventmodules); utarray_init(&instance->uistats, &stat_icd); utarray_init(&instance->uicompstats, &compstat_icd); utarray_init(&instance->uimenus, &menup_icd); utarray_init(&instance->timeout, &timeout_icd); utarray_init(&instance->icdata, &icdata_icd); instance->input = FcitxInputStateCreate(); instance->sem = sem; instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig)); instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile)); instance->globalIMName = strdup(""); if (fd > 0) { fcntl(fd, F_SETFL, O_NONBLOCK); instance->fd = fd; } if (!FcitxGlobalConfigLoad(instance->config)) goto error_exit; FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord); if (!ProcessOption(instance, argc, argv)) goto error_exit; instance->timeStart = time(NULL); instance->globalState = instance->config->defaultIMState; instance->totaltime = 0; FcitxInitThread(instance); if (!FcitxProfileLoad(instance->profile, instance)) goto error_exit; if (FcitxAddonGetConfigDesc() == NULL) goto error_exit; if (GetIMConfigDesc() == NULL) goto error_exit; FcitxAddonsLoad(&instance->addons); FcitxInstanceFillAddonOwner(instance, NULL); FcitxInstanceResolveAddonDependency(instance); FcitxInstanceInitBuiltInHotkey(instance); FcitxInstanceInitBuiltContext(instance); FcitxModuleLoad(instance); if (instance->loadingFatalError) return instance; if (!FcitxInstanceLoadAllIM(instance)) { FcitxInstanceEnd(instance); return instance; } FcitxInstanceInitIMMenu(instance); FcitxUIRegisterMenu(instance, &instance->imMenu); FcitxUIRegisterStatus(instance, instance, "remind", instance->profile->bUseRemind ? _("Use remind") : _("No remind"), _("Toggle Remind"), ToggleRemindState, GetRemindEnabled); FcitxUISetStatusVisable(instance, "remind", false); FcitxUILoad(instance); instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName); FcitxInstanceSwitchIMByIndex(instance, instance->iIMIndex); if (!FcitxInstanceLoadFrontend(instance)) { FcitxInstanceEnd(instance); return instance; } /* make in order to use block X, query is not good here */ pthread_create(&instance->pid, NULL, RunInstance, instance); return instance; error_exit: FcitxInstanceEnd(instance); return instance; }
FcitxAddon* FcitxAddonsLoadInternal(UT_array* addons, boolean reloadIM) { char **addonPath; size_t len; size_t start; if (!reloadIM) utarray_clear(addons); start = utarray_len(addons); FcitxStringHashSet* sset = FcitxXDGGetFiles("addon", NULL, ".conf"); addonPath = FcitxXDGGetPathWithPrefix(&len, "addon"); char *paths[len]; HASH_FOREACH(string, sset, FcitxStringHashSet) { // FIXME: if it will cause realloc, then it's evil for fcitx 4.2 series if (reloadIM && addons->i == addons->n) { break; } int i; for (i = len - 1; i >= 0; i--) { fcitx_utils_alloc_cat_str(paths[i], addonPath[len - i - 1], "/", string->name); FcitxLog(DEBUG, "Load Addon Config File:%s", paths[i]); } FcitxConfigFile* cfile = FcitxConfigParseMultiConfigFile(paths, len, FcitxAddonGetConfigDesc()); if (cfile) { utarray_extend_back(addons); FcitxAddon *a = (FcitxAddon*) utarray_back(addons); utarray_init(&a->functionList, fcitx_ptr_icd); FcitxAddonConfigBind(a, cfile, FcitxAddonGetConfigDesc()); FcitxConfigBindSync((FcitxGenericConfig*)a); FcitxLog(DEBUG, _("Addon Config %s is %s"), string->name, (a->bEnabled) ? "Enabled" : "Disabled"); boolean error = false; if (reloadIM) { if (a->category != AC_INPUTMETHOD) error = true; } /* if loaded, don't touch the old one */ if (FcitxAddonsGetAddonByNameInternal(addons, a->name, true) != a) error = true; if (error) utarray_pop_back(addons); else FcitxLog(INFO, _("Load Addon Config File:%s"), string->name); } for (i = len - 1;i >= 0;i--) { free(paths[i]); } } FcitxXDGFreePath(addonPath); fcitx_utils_free_string_hash_set(sset); size_t to = utarray_len(addons); utarray_sort_range(addons, AddonPriorityCmp, start, to); return (FcitxAddon*)utarray_eltptr(addons, start); }