diff --git a/src/frontend/ibusfrontend/ibusfrontend.cpp b/src/frontend/ibusfrontend/ibusfrontend.cpp index 8765457e..22bc4335 100644 --- a/src/frontend/ibusfrontend/ibusfrontend.cpp +++ b/src/frontend/ibusfrontend/ibusfrontend.cpp @@ -10,20 +10,45 @@ #include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include "fcitx-config/iniparser.h" +#include "fcitx-config/rawconfig.h" +#include "fcitx-utils/capabilityflags.h" +#include "fcitx-utils/dbus/bus.h" #include "fcitx-utils/dbus/message.h" #include "fcitx-utils/dbus/objectvtable.h" #include "fcitx-utils/dbus/servicewatcher.h" #include "fcitx-utils/dbus/variant.h" +#include "fcitx-utils/event.h" +#include "fcitx-utils/flags.h" +#include "fcitx-utils/handlertable.h" +#include "fcitx-utils/key.h" #include "fcitx-utils/log.h" -#include "fcitx-utils/metastring.h" +#include "fcitx-utils/macros.h" +#include "fcitx-utils/misc.h" +#include "fcitx-utils/rect.h" #include "fcitx-utils/standardpath.h" #include "fcitx-utils/stringutils.h" +#include "fcitx-utils/textformatflags.h" #include "fcitx-utils/utf8.h" #include "fcitx-utils/uuid_p.h" #include "fcitx/addonfactory.h" +#include "fcitx/addoninstance.h" +#include "fcitx/event.h" #include "fcitx/inputcontext.h" #include "fcitx/inputpanel.h" #include "fcitx/instance.h" @@ -634,8 +659,8 @@ std::set allSocketPaths(const StandardPath &standardPath) { if (isInFlatpak()) { // Flatpak always use DISPLAY=:99, which means we will need to guess // what files are available. - auto map = standardPath.multiOpenFilter( - StandardPath::Type::Config, "ibus/bus", O_RDONLY, + auto map = standardPath.locateWithFilter( + StandardPath::Type::Config, "ibus/bus", [](const std::string &path, const std::string &, bool user) { if (!user) { return false; @@ -644,7 +669,7 @@ std::set allSocketPaths(const StandardPath &standardPath) { }); for (const auto &item : map) { - paths.insert(item.second.path()); + paths.insert(item.second); } // Make the guess that display is 0, it is the most common value that diff --git a/src/lib/fcitx-config/configuration.h b/src/lib/fcitx-config/configuration.h index f4c2e051..ac2509b3 100644 --- a/src/lib/fcitx-config/configuration.h +++ b/src/lib/fcitx-config/configuration.h @@ -7,12 +7,15 @@ #ifndef _FCITX_CONFIG_CONFIGURATION_H_ #define _FCITX_CONFIG_CONFIGURATION_H_ +#include +#include +#include #include +#include +#include #include #include "fcitxconfig_export.h" -#include - #define FCITX_CONFIGURATION_EXTEND(NAME, SUBCLASS, ...) \ class NAME; \ FCITX_SPECIALIZE_TYPENAME(NAME, #NAME) \ diff --git a/src/lib/fcitx-config/iniparser.cpp b/src/lib/fcitx-config/iniparser.cpp index f8b306dd..849eb4c6 100644 --- a/src/lib/fcitx-config/iniparser.cpp +++ b/src/lib/fcitx-config/iniparser.cpp @@ -7,7 +7,13 @@ #include "iniparser.h" #include #include +#include +#include +#include +#include "fcitx-config/rawconfig.h" #include "fcitx-utils/fs.h" +#include "fcitx-utils/macros.h" +#include "fcitx-utils/misc.h" #include "fcitx-utils/standardpath.h" #include "fcitx-utils/stringutils.h" #include "fcitx-utils/unixfd.h" @@ -54,8 +60,6 @@ void readFromIni(RawConfig &config, FILE *fin) { continue; } - std::string::size_type equalPos; - if (lineBuf.front() == '[' && lineBuf.back() == ']') { currentGroup = lineBuf.substr(1, lineBuf.size() - 2); config.visitItemsOnPath( @@ -65,8 +69,8 @@ void readFromIni(RawConfig &config, FILE *fin) { } }, currentGroup); - } else if ((equalPos = lineBuf.find_first_of('=')) != - std::string::npos) { + } else if (std::string::size_type equalPos = lineBuf.find_first_of('='); + equalPos != std::string::npos) { auto name = lineBuf.substr(0, equalPos); auto valueStart = equalPos + 1; @@ -91,7 +95,7 @@ void readFromIni(RawConfig &config, FILE *fin) { } } -bool writeAsIni(const RawConfig &root, FILE *fout) { +bool writeAsIni(const RawConfig &config, FILE *fout) { std::function callback; callback = [fout, &callback](const RawConfig &config, @@ -131,7 +135,7 @@ bool writeAsIni(const RawConfig &root, FILE *fout) { return true; }; - return callback(root, ""); + return callback(config, ""); } void readAsIni(RawConfig &rawConfig, const std::string &path) { diff --git a/src/lib/fcitx-config/iniparser.h b/src/lib/fcitx-config/iniparser.h index e88deb30..6c67d5d5 100644 --- a/src/lib/fcitx-config/iniparser.h +++ b/src/lib/fcitx-config/iniparser.h @@ -7,6 +7,8 @@ #ifndef _FCITX_CONFIG_INIPARSER_H_ #define _FCITX_CONFIG_INIPARSER_H_ +#include +#include #include #include #include "fcitxconfig_export.h" @@ -17,22 +19,25 @@ FCITXCONFIG_EXPORT void readFromIni(RawConfig &config, int fd); FCITXCONFIG_EXPORT bool writeAsIni(const RawConfig &config, int fd); FCITXCONFIG_EXPORT void readFromIni(RawConfig &config, FILE *fin); FCITXCONFIG_EXPORT bool writeAsIni(const RawConfig &config, FILE *fout); -FCITXCONFIG_EXPORT void readAsIni(Configuration &, const std::string &name); -FCITXCONFIG_EXPORT void readAsIni(RawConfig &, const std::string &name); -FCITXCONFIG_EXPORT void readAsIni(Configuration &, StandardPath::Type type, - const std::string &name); -FCITXCONFIG_EXPORT void readAsIni(RawConfig &, StandardPath::Type type, - const std::string &name); -FCITXCONFIG_EXPORT bool safeSaveAsIni(const Configuration &, - const std::string &name); -FCITXCONFIG_EXPORT bool safeSaveAsIni(const RawConfig &, - const std::string &name); -FCITXCONFIG_EXPORT bool safeSaveAsIni(const Configuration &, +FCITXCONFIG_EXPORT void readAsIni(Configuration &configuration, + const std::string &path); +FCITXCONFIG_EXPORT void readAsIni(RawConfig &rawConfig, + const std::string &path); +FCITXCONFIG_EXPORT void readAsIni(Configuration &configuration, + StandardPath::Type type, + const std::string &path); +FCITXCONFIG_EXPORT void readAsIni(RawConfig &rawConfig, StandardPath::Type type, + const std::string &path); +FCITXCONFIG_EXPORT bool safeSaveAsIni(const Configuration &configuration, + const std::string &path); +FCITXCONFIG_EXPORT bool safeSaveAsIni(const RawConfig &rawConfig, + const std::string &path); +FCITXCONFIG_EXPORT bool safeSaveAsIni(const Configuration &configuration, StandardPath::Type type, - const std::string &name); -FCITXCONFIG_EXPORT bool safeSaveAsIni(const RawConfig &, + const std::string &path); +FCITXCONFIG_EXPORT bool safeSaveAsIni(const RawConfig &rawConfig, StandardPath::Type type, - const std::string &name); + const std::string &path); } // namespace fcitx #endif // _FCITX_CONFIG_INIPARSER_H_ diff --git a/src/lib/fcitx-config/optiontypename.h b/src/lib/fcitx-config/optiontypename.h index 921de628..317d32fe 100644 --- a/src/lib/fcitx-config/optiontypename.h +++ b/src/lib/fcitx-config/optiontypename.h @@ -8,9 +8,12 @@ #define _FCITX_CONFIG_TYPENAME_H_ #include +#include +#include #include #include #include +#include #include namespace fcitx { @@ -42,8 +45,7 @@ struct OptionTypeName> { }; template -struct OptionTypeName::value>::type> { +struct OptionTypeName>> { static std::string get() { return "Enum"; } }; } // namespace fcitx diff --git a/src/lib/fcitx-utils/standardpath.cpp b/src/lib/fcitx-utils/standardpath.cpp index 799d4c5e..76030c8a 100644 --- a/src/lib/fcitx-utils/standardpath.cpp +++ b/src/lib/fcitx-utils/standardpath.cpp @@ -9,16 +9,30 @@ #include #include #include +#include #include #include #include +#include +#include +#include #include +#include +#include +#include +#include #include +#include +#include +#include #include #include +#include #include #include "config.h" #include "fs.h" +#include "macros.h" +#include "misc.h" #include "misc_p.h" #include "stringutils.h" @@ -594,10 +608,11 @@ StandardPath::openUserTemp(Type type, const std::string &pathOrig) const { fullPathOrig = constructPath(dirPath, pathOrig); } if (fs::makePath(fs::dirName(fullPath))) { - auto cPath = makeUniqueCPtr(strdup(fullPath.c_str())); - int fd = mkstemp(cPath.get()); + std::vector cPath(fullPath.data(), + fullPath.data() + fullPath.size() + 1); + int fd = mkstemp(cPath.data()); if (fd >= 0) { - return {fd, fullPathOrig, cPath.get()}; + return {fd, fullPathOrig, cPath.data()}; } } return {}; @@ -623,6 +638,27 @@ bool StandardPath::safeSave(Type type, const std::string &pathOrig, return false; } +std::map StandardPath::locateWithFilter( + Type type, const std::string &path, + std::function + filter) const { + std::map result; + scanFiles(type, path, + [&result, &filter](const std::string &path, + const std::string &dir, bool isUser) { + if (!result.count(path) && filter(path, dir, isUser)) { + auto fullPath = constructPath(dir, path); + if (fs::isreg(fullPath)) { + result.emplace(path, std::move(fullPath)); + } + } + return true; + }); + + return result; +} + StandardPathFileMap StandardPath::multiOpenFilter( Type type, const std::string &path, int flags, std::function #include #include #include #include +#include #include +#include #include #include #include @@ -40,7 +43,8 @@ class Chainer; template <> class Chainer<> { public: - bool operator()(const std::string &, const std::string &, bool) { + bool operator()(const std::string & /*unused*/, + const std::string & /*unused*/, bool /*unused*/) { return true; } }; @@ -86,7 +90,8 @@ NotFilter Not(T t) { /// \brief Filter class that filters based on user file. struct FCITXUTILS_EXPORT User { - bool operator()(const std::string &, const std::string &, bool isUser) { + bool operator()(const std::string & /*unused*/, + const std::string & /*unused*/, bool isUser) { return isUser; } }; @@ -95,7 +100,8 @@ struct FCITXUTILS_EXPORT User { struct FCITXUTILS_EXPORT Prefix { Prefix(const std::string &prefix_) : prefix(prefix_) {} - bool operator()(const std::string &path, const std::string &, bool) const { + bool operator()(const std::string &path, const std::string & /*unused*/, + bool /*unused*/) const { return stringutils::startsWith(path, prefix); } @@ -106,7 +112,8 @@ struct FCITXUTILS_EXPORT Prefix { struct FCITXUTILS_EXPORT Suffix { Suffix(const std::string &suffix_) : suffix(suffix_) {} - bool operator()(const std::string &path, const std::string &, bool) const { + bool operator()(const std::string &path, const std::string & /*unused*/, + bool /*unused*/) const { return stringutils::endsWith(path, suffix); } @@ -297,9 +304,41 @@ class FCITXUTILS_EXPORT StandardPath { bool safeSave(Type type, const std::string &pathOrig, const std::function &callback) const; + /** + * \brief Locate all files match the filter under first [directory]/[path]. + * + * Prefer this function over multiOpenFilter, if there could be too many + * files that exceeds the systems file descriptor limit. + * @since 5.1.10 + * @see multiOpenFilter + */ + std::map + locateWithFilter(Type type, const std::string &path, + std::function + filter) const; + + /** + * \brief Locate all files match the filter under first [directory]/[path]. + * + * You may pass multiple filter to it. + * Prefer this function over multiOpen, if there could be too many + * files that exceeds the systems file descriptor limit. + * @since 5.1.10 + * @see multiOpen + */ + template + std::map + locate(Type type, const std::string &path, Arg1 arg1, Args... args) const { + return locateWithFilter(type, path, + filter::Chainer( + std::move(arg1), std::move(args)...)); + } + /// \brief Open all files match the first [directory]/[path]. std::vector openAll(Type type, const std::string &path, int flags) const; + /// \brief Open all files match the filter under first [directory]/[path]. StandardPathFileMap multiOpenFilter(Type type, const std::string &path, int flags, diff --git a/src/lib/fcitx/addoninfo.cpp b/src/lib/fcitx/addoninfo.cpp index cb171a67..49d8c6e4 100644 --- a/src/lib/fcitx/addoninfo.cpp +++ b/src/lib/fcitx/addoninfo.cpp @@ -6,7 +6,19 @@ */ #include "addoninfo.h" + +#include +#include +#include +#include +#include #include "fcitx-config/configuration.h" +#include "fcitx-config/option.h" +#include "fcitx-config/rawconfig.h" +#include "fcitx-utils/i18nstring.h" +#include "fcitx-utils/macros.h" +#include "fcitx-utils/semver.h" +#include "fcitx-utils/stringutils.h" namespace fcitx { FCITX_CONFIGURATION( @@ -57,7 +69,7 @@ void parseDependencies(const std::vector &data, class AddonInfoPrivate : public AddonConfig { public: - AddonInfoPrivate(const std::string &name) : uniqueName_(name) {} + AddonInfoPrivate(std::string name) : uniqueName_(std::move(name)) {} bool valid_ = false; std::string uniqueName_; diff --git a/src/lib/fcitx/addoninfo.h b/src/lib/fcitx/addoninfo.h index 86428ea8..55704851 100644 --- a/src/lib/fcitx/addoninfo.h +++ b/src/lib/fcitx/addoninfo.h @@ -8,8 +8,11 @@ #define _FCITX_ADDON_H_ #include +#include +#include #include #include +#include #include #include #include diff --git a/src/lib/fcitx/addonmanager.cpp b/src/lib/fcitx/addonmanager.cpp index 872f9156..55269f33 100644 --- a/src/lib/fcitx/addonmanager.cpp +++ b/src/lib/fcitx/addonmanager.cpp @@ -7,15 +7,28 @@ #include "addonmanager.h" #include +#include +#include +#include +#include #include #include +#include +#include #include "fcitx-config/iniparser.h" +#include "fcitx-config/rawconfig.h" #include "fcitx-utils/log.h" +#include "fcitx-utils/macros.h" #include "fcitx-utils/misc_p.h" -#include "fcitx/addoninstance.h" +#include "fcitx-utils/semver.h" +#include "fcitx-utils/standardpath.h" +#include "fcitx-utils/unixfd.h" +#include "addoninfo.h" +#include "addoninstance.h" #include "addoninstance_p.h" #include "addonloader.h" #include "addonloader_p.h" +#include "config.h" #include "instance.h" namespace fcitx { @@ -60,7 +73,7 @@ enum class DependencyCheckStatus { class AddonManagerPrivate { public: - AddonManagerPrivate() : instance_(nullptr) {} + AddonManagerPrivate() {} Addon *addon(const std::string &name) const { auto iter = addons_.find(name); @@ -76,9 +89,8 @@ class AddonManagerPrivate { if (dependency == "core") { if (depVersion <= version_) { continue; - } else { - return DependencyCheckStatus::Failed; } + return DependencyCheckStatus::Failed; } Addon *dep = addon(dependency); if (!dep || !dep->isLoadable()) { @@ -250,12 +262,11 @@ void AddonManager::load(const std::unordered_set &enabled, const auto &path = StandardPath::global(); d->timestamp_ = path.timestamp(StandardPath::Type::PkgData, d->addonConfigDir_); - auto fileMap = - path.multiOpen(StandardPath::Type::PkgData, d->addonConfigDir_, - O_RDONLY, filter::Suffix(".conf")); + auto fileNames = path.locate(StandardPath::Type::PkgData, + d->addonConfigDir_, filter::Suffix(".conf")); bool enableAll = enabled.count("all"); bool disableAll = disabled.count("all"); - for (const auto &[fileName, file] : fileMap) { + for (const auto &[fileName, fullName] : fileNames) { // remove .conf std::string name = fileName.substr(0, fileName.size() - 5); if (name == "core") { @@ -267,7 +278,8 @@ void AddonManager::load(const std::unordered_set &enabled, } RawConfig config; - readFromIni(config, file.fd()); + UnixFD fd = UnixFD::own(open(fullName.c_str(), O_RDONLY)); + readFromIni(config, fd.fd()); // override configuration auto addon = std::make_unique(name, config); @@ -403,7 +415,7 @@ void AddonManager::setAddonOptions( std::vector AddonManager::addonOptions(const std::string &name) { FCITX_D(); - if (auto options = findValue(d->options_, name)) { + if (auto *options = findValue(d->options_, name)) { return *options; } return {}; diff --git a/src/lib/fcitx/inputmethodmanager.cpp b/src/lib/fcitx/inputmethodmanager.cpp index 03906cff..35675a1b 100644 --- a/src/lib/fcitx/inputmethodmanager.cpp +++ b/src/lib/fcitx/inputmethodmanager.cpp @@ -7,19 +7,35 @@ #include "inputmethodmanager.h" #include +#include #include +#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include #include "fcitx-config/iniparser.h" #include "fcitx-config/rawconfig.h" +#include "fcitx-utils/connectableobject.h" +#include "fcitx-utils/handlertable.h" #include "fcitx-utils/i18n.h" #include "fcitx-utils/log.h" +#include "fcitx-utils/macros.h" +#include "fcitx-utils/misc_p.h" #include "fcitx-utils/standardpath.h" +#include "fcitx-utils/unixfd.h" +#include "addoninfo.h" #include "addonmanager.h" #include "inputmethodconfig_p.h" #include "inputmethodengine.h" +#include "inputmethodgroup.h" #include "instance.h" -#include "misc_p.h" namespace fcitx { @@ -151,15 +167,16 @@ void InputMethodManagerPrivate::loadStaticEntries( const std::unordered_set &addonNames) { const auto &path = StandardPath::global(); timestamp_ = path.timestamp(StandardPath::Type::PkgData, "inputmethod"); - auto filesMap = path.multiOpen(StandardPath::Type::PkgData, "inputmethod", - O_RDONLY, filter::Suffix(".conf")); - for (const auto &[fileName, file] : filesMap) { + auto filesMap = path.locate(StandardPath::Type::PkgData, "inputmethod", + filter::Suffix(".conf")); + for (const auto &[fileName, fullName] : filesMap) { std::string name = fileName.substr(0, fileName.size() - 5); if (entries_.count(name) != 0) { continue; } RawConfig config; - readFromIni(config, file.fd()); + UnixFD fd = UnixFD::own(open(fullName.c_str(), O_RDONLY)); + readFromIni(config, fd.fd()); InputMethodInfo imInfo; imInfo.load(config); diff --git a/src/modules/quickphrase/quickphraseprovider.cpp b/src/modules/quickphrase/quickphraseprovider.cpp index 2d2611f2..3eba6ad3 100644 --- a/src/modules/quickphrase/quickphraseprovider.cpp +++ b/src/modules/quickphrase/quickphraseprovider.cpp @@ -6,12 +6,20 @@ */ #include "quickphraseprovider.h" #include +#include +#include +#include +#include #include #include #include "fcitx-utils/fs.h" +#include "fcitx-utils/macros.h" +#include "fcitx-utils/misc.h" #include "fcitx-utils/standardpath.h" #include "fcitx-utils/stringutils.h" +#include "fcitx/inputcontext.h" #include "quickphrase.h" +#include "quickphrase_public.h" #include "spell_public.h" namespace fcitx { @@ -36,28 +44,28 @@ bool BuiltInQuickPhraseProvider::populate( void BuiltInQuickPhraseProvider::reloadConfig() { map_.clear(); - auto file = StandardPath::global().open(StandardPath::Type::PkgData, - "data/QuickPhrase.mb", O_RDONLY); - auto files = StandardPath::global().multiOpen( - StandardPath::Type::PkgData, "data/quickphrase.d/", O_RDONLY, - filter::Suffix(".mb")); - auto disableFiles = StandardPath::global().multiOpen( - StandardPath::Type::PkgData, "data/quickphrase.d/", O_RDONLY, - filter::Suffix(".mb.disable")); - if (file.fd() >= 0) { - load(file); + if (auto file = StandardPath::global().open( + StandardPath::Type::PkgData, "data/QuickPhrase.mb", O_RDONLY); + file.fd() >= 0) { + load(fs::openFD(file, "rb")); } + auto files = StandardPath::global().locate(StandardPath::Type::PkgData, + "data/quickphrase.d/", + filter::Suffix(".mb")); + auto disableFiles = StandardPath::global().locate( + StandardPath::Type::PkgData, "data/quickphrase.d/", + filter::Suffix(".mb.disable")); for (auto &p : files) { if (disableFiles.count(stringutils::concat(p.first, ".disable"))) { continue; } - load(p.second); + UnixFD fd = UnixFD::own(open(p.second.c_str(), O_RDONLY)); + load(fs::openFD(fd, "rb")); } } -void BuiltInQuickPhraseProvider::load(StandardPathFile &file) { - UniqueFilePtr fp = fs::openFD(file, "rb"); +void BuiltInQuickPhraseProvider::load(UniqueFilePtr fp) { if (!fp) { return; } @@ -93,8 +101,8 @@ void BuiltInQuickPhraseProvider::load(StandardPathFile &file) { } } -SpellQuickPhraseProvider::SpellQuickPhraseProvider(QuickPhrase *quickPhrase) - : parent_(quickPhrase), instance_(parent_->instance()) {} +SpellQuickPhraseProvider::SpellQuickPhraseProvider(QuickPhrase *parent) + : parent_(parent), instance_(parent_->instance()) {} bool SpellQuickPhraseProvider::populate( InputContext *ic, const std::string &userInput, @@ -102,12 +110,12 @@ bool SpellQuickPhraseProvider::populate( if (!*parent_->config().enableSpell) { return true; } - auto spell = this->spell(); + auto *spell = this->spell(); if (!spell) { return true; } std::string lang = *parent_->config().fallbackSpellLanguage; - if (auto entry = instance_->inputMethodEntry(ic)) { + if (const auto *entry = instance_->inputMethodEntry(ic)) { if (spell->call(entry->languageCode())) { lang = entry->languageCode(); } else if (!spell->call(lang)) { diff --git a/src/modules/quickphrase/quickphraseprovider.h b/src/modules/quickphrase/quickphraseprovider.h index 05211935..31e61d0e 100644 --- a/src/modules/quickphrase/quickphraseprovider.h +++ b/src/modules/quickphrase/quickphraseprovider.h @@ -8,8 +8,13 @@ #define _FCITX5_MODULES_QUICKPHRASE_QUICKPHRASEPROVIDER_H_ #include +#include #include +#include #include "fcitx-utils/connectableobject.h" +#include "fcitx-utils/handlertable.h" +#include "fcitx-utils/misc.h" +#include "fcitx/addoninstance.h" #include "fcitx/addonmanager.h" #include "fcitx/instance.h" #include "quickphrase_public.h" @@ -33,7 +38,7 @@ class BuiltInQuickPhraseProvider : public QuickPhraseProvider { void reloadConfig(); private: - void load(StandardPathFile &file); + void load(UniqueFilePtr fp); std::multimap map_; }; diff --git a/test/teststandardpath.cpp b/test/teststandardpath.cpp index 21069b3e..e3b14034 100644 --- a/test/teststandardpath.cpp +++ b/test/teststandardpath.cpp @@ -6,7 +6,10 @@ */ #include +#include #include +#include +#include #include "fcitx-utils/fs.h" #include "fcitx-utils/log.h" #include "fcitx-utils/standardpath.h" @@ -34,8 +37,9 @@ void test_basic() { auto result = standardPath.multiOpen( StandardPath::Type::PkgData, "addon", O_RDONLY, filter::Not(filter::User()), filter::Suffix(".conf")); - std::set names, - expect_names = {"testim.conf", "testfrontend.conf"}; + std::set names; + std::set expect_names = {"testim.conf", + "testfrontend.conf"}; for (auto &p : result) { names.insert(p.first); FCITX_ASSERT(p.second.fd() >= 0); @@ -44,11 +48,26 @@ void test_basic() { FCITX_ASSERT(names == expect_names); } + { + auto result = standardPath.locate(StandardPath::Type::PkgData, "addon", + filter::Not(filter::User()), + filter::Suffix(".conf")); + std::set names; + std::set expect_names = {"testim.conf", + "testfrontend.conf"}; + for (auto &p : result) { + names.insert(p.first); + } + + FCITX_ASSERT(names == expect_names); + } + { auto result = standardPath.multiOpen( StandardPath::Type::PkgData, "addon", O_RDONLY, filter::Not(filter::User()), filter::Suffix("im.conf")); - std::set names, expect_names = {"testim.conf"}; + std::set names; + std::set expect_names = {"testim.conf"}; for (auto &p : result) { names.insert(p.first); FCITX_ASSERT(p.second.fd() >= 0); @@ -82,8 +101,9 @@ void test_nouser() { auto result = standardPath.multiOpen( StandardPath::Type::PkgData, "addon", O_RDONLY, filter::Not(filter::User()), filter::Suffix(".conf")); - std::set names, - expect_names = {"testim.conf", "testfrontend.conf"}; + std::set names; + std::set expect_names = {"testim.conf", + "testfrontend.conf"}; for (auto &p : result) { names.insert(p.first); FCITX_ASSERT(p.second.fd() >= 0); @@ -96,7 +116,8 @@ void test_nouser() { auto result = standardPath.multiOpen( StandardPath::Type::PkgData, "addon", O_RDONLY, filter::Not(filter::User()), filter::Suffix("im.conf")); - std::set names, expect_names = {"testim.conf"}; + std::set names; + std::set expect_names = {"testim.conf"}; for (auto &p : result) { names.insert(p.first); FCITX_ASSERT(p.second.fd() >= 0);