void find_top_level_structs(FcitxConfiguration* config, FcitxDescription* desc) { FCITX_UNUSED(config); desc->topLevelStructs = fcitx_string_hashset_clone(desc->structs); fcitx_dict_foreach(desc->structs, structs_foreach, desc); }
void _fcitx_configuration_foreach(FcitxConfiguration* config, const char* path, bool recursive, FcitxConfigurationForeachCallback callback, void* userData) { if (config->subitems) { fcitx_configuration_foreach_context context; context.path = path; context.pathLen = strlen(path); context.pathBuf = NULL; context.pathBufLen = 0; context.recursive = recursive; context.callback = callback; context.userData = userData; fcitx_dict_foreach(config->subitems, _fcitx_configuration_subitems_foreach, &context); free(context.pathBuf); } }
FCITX_EXPORT_API void fcitx_addon_manager_load(FcitxAddonManager* manager) { // list all metadata FcitxStandardPathFilter filter; filter.flag = FSPFT_Suffix | FSPFT_Sort; filter.suffix = ".conf"; FcitxDict* fileDict = fcitx_standard_path_match(manager->standardPath, FSPT_Data, "fcitx/addon", &filter); fcitx_dict_foreach(fileDict, _fcitx_addon_load_metadata, manager); fcitx_dict_free(fileDict); // topo sort doesn't work here, since bool update; do { update = false; for (FcitxDictData* data = fcitx_dict_first(manager->addons); data != NULL; data = fcitx_dict_data_next(data)) { FcitxAddon* addon = data->data; if (!addon->config->addon.enabled) { continue; } FcitxDictData* dependency = NULL; bool allDependenciesLoaded = true; for (dependency = fcitx_dict_first(addon->dependencies); dependency != NULL; dependency = fcitx_dict_data_next(dependency)) { FcitxAddon* dependAddon; if (!fcitx_dict_lookup_by_str(manager->addons, dependency->key, &dependAddon)) { break; } if (!dependAddon->loaded) { allDependenciesLoaded = false; } } if (dependency) { addon->config->addon.enabled = false; update = true; } else if (allDependenciesLoaded) { _fcitx_addon_manager_load_addon(manager, addon); } } } while(update); manager->loaded = true; }