diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index a48cb01dd..fd180e7fa 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -41,7 +41,7 @@ jobs: steps: - name: Install dependencies run: | - pacman -Syu --noconfirm base-devel clang cmake ninja extra-cmake-modules xcb-util xcb-util-keysyms cairo enchant iso-codes libxkbcommon-x11 pango systemd wayland xcb-util-wm libxkbfile fmt gdk-pixbuf2 wayland-protocols + pacman -Syu --noconfirm base-devel clang cmake ninja extra-cmake-modules xcb-util xcb-util-keysyms cairo enchant iso-codes libxkbcommon-x11 pango systemd wayland xcb-util-wm libxkbfile nlohmann-json gdk-pixbuf2 wayland-protocols - uses: actions/checkout@v4 with: path: xcb-imdkit diff --git a/CMakeLists.txt b/CMakeLists.txt index ebe5169c4..7209917a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,7 +149,7 @@ if (ENABLE_KEYBOARD) find_package(XKBCommon REQUIRED COMPONENTS ${REQUIRED_XKBCOMMON_COMPONENTS}) find_package(IsoCodes REQUIRED) find_package(XKeyboardConfig REQUIRED) - pkg_check_modules(JsonC REQUIRED IMPORTED_TARGET "json-c") + find_package(nlohmann_json) set(DEFAULT_XKB_RULES_FILES "${XKEYBOARDCONFIG_XKBBASE}/rules/${DEFAULT_XKB_RULES}.xml") if (NOT EXISTS "${DEFAULT_XKB_RULES_FILES}" AND NOT APPLE) diff --git a/src/im/keyboard/CMakeLists.txt b/src/im/keyboard/CMakeLists.txt index a1711200c..044496a26 100644 --- a/src/im/keyboard/CMakeLists.txt +++ b/src/im/keyboard/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(keyboard STATIC keyboard.cpp isocodes.cpp xkbrules.cpp xmlparser.cpp longpress.cpp compose.cpp) -target_link_libraries(keyboard Fcitx5::Core Expat::Expat LibIntl::LibIntl Fcitx5::Module::Spell Fcitx5::Module::Notifications XKBCommon::XKBCommon Fcitx5::Module::QuickPhrase PkgConfig::JsonC) +target_link_libraries(keyboard Fcitx5::Core Expat::Expat LibIntl::LibIntl Fcitx5::Module::Spell Fcitx5::Module::Notifications XKBCommon::XKBCommon Fcitx5::Module::QuickPhrase nlohmann_json::nlohmann_json) if (ENABLE_X11) target_link_libraries(keyboard Fcitx5::Module::XCB) endif() diff --git a/src/im/keyboard/isocodes.cpp b/src/im/keyboard/isocodes.cpp index 78886601a..3069c3b07 100644 --- a/src/im/keyboard/isocodes.cpp +++ b/src/im/keyboard/isocodes.cpp @@ -6,33 +6,37 @@ */ #include "isocodes.h" -#include +#include #include -#include +#include #include "fcitx-utils/metastring.h" -#include "fcitx-utils/misc.h" namespace fcitx { +using json = nlohmann::json; + template class IsoCodesJsonParser { public: - virtual void handle(json_object *entry) = 0; + virtual void handle(const json &entry) = 0; void parse(const std::string &filename) { - UniqueCPtr obj; - obj.reset(json_object_from_file(filename.data())); - if (!obj) { + std::ifstream fin(filename); + if (!fin.is_open()) { + return; + } + json obj; + try { + fin >> obj; + } catch (const json::parse_error &) { return; } - json_object *root = - json_object_object_get(obj.get(), RootString::data()); - if (!root || json_object_get_type(root) != json_type_array) { + auto it = obj.find(RootString::data()); + if (it == obj.end() || !it->is_array()) { return; } - for (size_t i = 0, e = json_object_array_length(root); i < e; i++) { - json_object *entry = json_object_array_get_idx(root, i); + for (const auto &entry : *it) { handle(entry); } } @@ -43,44 +47,37 @@ class IsoCodes639Parser public: IsoCodes639Parser(IsoCodes *that) : that_(that) {} - void handle(json_object *entry) override { - json_object *alpha2 = json_object_object_get(entry, "alpha_2"); - json_object *alpha3 = json_object_object_get(entry, "alpha_3"); - json_object *bibliographic = - json_object_object_get(entry, "bibliographic"); - json_object *name = json_object_object_get(entry, "name"); - if (!name || json_object_get_type(name) != json_type_string) { + void handle(const json &entry) override { + const auto it_alpha2 = entry.find("alpha_2"); + const auto it_alpha3 = entry.find("alpha_3"); + auto it_bibliographic = entry.find("bibliographic"); + const auto it_name = entry.find("name"); + if (it_name == entry.end() || !it_name->is_string()) { return; } // there must be alpha3 - if (!alpha3 || json_object_get_type(alpha3) != json_type_string) { + if (it_alpha3 == entry.end() || !it_alpha3->is_string()) { return; } // alpha2 is optional - if (alpha2 && json_object_get_type(alpha2) != json_type_string) { + if (it_alpha2 != entry.end() && !it_alpha2->is_string()) { return; } // bibliographic is optional - if (bibliographic && - json_object_get_type(bibliographic) != json_type_string) { + if (it_bibliographic == entry.end()) { + it_bibliographic = it_alpha3; + } else if (!it_bibliographic->is_string()) { return; } - if (!bibliographic) { - bibliographic = alpha3; - } IsoCodes639Entry e; - e.name.assign(json_object_get_string(name), - json_object_get_string_len(name)); - if (alpha2) { - e.iso_639_1_code.assign(json_object_get_string(alpha2), - json_object_get_string_len(alpha2)); + e.name = it_name->get(); + if (it_alpha2 != entry.end()) { + e.iso_639_1_code = it_alpha2->get(); } - e.iso_639_2B_code.assign(json_object_get_string(bibliographic), - json_object_get_string_len(bibliographic)); - e.iso_639_2T_code.assign(json_object_get_string(alpha3), - json_object_get_string_len(alpha3)); + e.iso_639_2B_code = it_bibliographic->get(); + e.iso_639_2T_code = it_alpha3->get(); if ((!e.iso_639_2B_code.empty() || !e.iso_639_2T_code.empty()) && !e.name.empty()) { that_->iso639entires.emplace_back(e); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 643d96f43..b05b1ada3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -134,7 +134,7 @@ if (ENABLE_KEYBOARD) add_executable(testisocodes testisocodes.cpp ../src/im/keyboard/isocodes.cpp) target_compile_definitions(testisocodes PRIVATE "-D_TEST_XKBRULES") target_include_directories(testisocodes PRIVATE ../src) - target_link_libraries(testisocodes Fcitx5::Core PkgConfig::JsonC) + target_link_libraries(testisocodes Fcitx5::Core nlohmann_json::nlohmann_json) add_test(NAME testisocodes COMMAND testisocodes) add_executable(testcompose testcompose.cpp)