From 3d5e6cb859f0942abe629adf4396715d6d955a48 Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Thu, 2 Jul 2026 00:02:21 -0700 Subject: [PATCH 1/4] Import darts-clone 0.32h from BCR with OpenCC patch Replace local_path_override with the BCR module and a single_version_override patch that captures the three local modifications: BUILD filegroup target, rules_cc 0.2.20, and the darts.h changes (uint32_t id_type, copy_array, validate). --- MODULE.bazel | 8 ++- MODULE.bazel.lock | 38 +++++++++++ patches/darts-clone-opencc.patch | 106 +++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 patches/darts-clone-opencc.patch diff --git a/MODULE.bazel b/MODULE.bazel index 44cecfa1c..a83316024 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,7 +7,7 @@ module( bazel_dep(name = "aspect_bazel_lib", version = "2.22.5") bazel_dep(name = "aspect_rules_js", version = "3.2.2") -bazel_dep(name = "darts-clone", version = "0.32") +bazel_dep(name = "darts-clone", version = "0.32h") bazel_dep(name = "googletest", version = "1.17.0.bcr.2", dev_dependency = True) bazel_dep(name = "marisa-trie", version = "0.3.1.bcr.2") bazel_dep(name = "node_addon_api", version = "8.9.0") @@ -30,9 +30,11 @@ single_version_override( version = "2.0.3", ) -local_path_override( +single_version_override( module_name = "darts-clone", - path = "deps/darts-clone-0.32h", + patches = ["//patches:darts-clone-opencc.patch"], + patch_strip = 1, + version = "0.32h", ) # Windows x64 node.lib import library for Zig/MinGW addon linking. node-addon-api diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6965d38a5..c7969595d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -75,6 +75,8 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/source.json": "7ad77c1e8c1b84222d9b3f3cae016a76639435744c19330b0b37c0a3c9da7dc0", "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/darts-clone/0.32h/MODULE.bazel": "ba209b6cfb1a70f4fad4c9c0aa5204ae4b1dcc3c0bcc95a7bf93ec3df0546296", + "https://bcr.bazel.build/modules/darts-clone/0.32h/source.json": "49b56b7949dd1efe3c99b4d08a739683bba35299f1c103be0dd76b21b30a8913", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/MODULE.bazel": "f1b7bb2dd53e8f2ef984b39485ec8a44e9076dda5c4b8efd2fb4c6a6e856a31d", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/source.json": "ebe931bfe362e4b41e59ee00a528db6074157ff2ced92eb9e970acab2e1089c9", @@ -252,6 +254,24 @@ }, "selectedYankedVersions": {}, "moduleExtensions": { + "//node:deps.bzl%node_deps": { + "general": { + "bzlTransitiveDigest": "WzrR1cSo+6UM9ltfJLYa5sdnpCU7lQ1Dpo1vc0XPWVM=", + "usagesDigest": "MjFCpVGEw42P09a/hETvnWn+qpOM2D6Z/Fh8bK8GhYE=", + "recordedInputs": [ + "REPO_MAPPING:,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "node_win_x64_lib": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "url": "https://nodejs.org/dist/v20.20.2/win-x64/node.lib", + "sha256": "c4a794e993d9304238523230885e9ec00ca052c73b9558471858eef14916d91f" + } + } + } + } + }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", @@ -330,6 +350,24 @@ } } }, + "@@rules_node_addon+//node_addon:windows.bzl%node_addon_windows": { + "general": { + "bzlTransitiveDigest": "mSDCSku6ucwsexmDIvrQtQ+UDGdJisPoQ9c0eScU5dA=", + "usagesDigest": "8m6U7FypO9pMDljalXdBD/Bt8SVdQapq+cH/dWp9OM4=", + "recordedInputs": [], + "generatedRepoSpecs": { + "windows_node_api": { + "repoRuleId": "@@rules_node_addon+//node_addon:windows.bzl%_node_api_repo", + "attributes": { + "headers_sha256": "87d1a7d80599ce330de0f0832f6b85c7d93c5be7b6a203725afa016405227988", + "node_version": "24.14.0", + "win_arm64_node_lib_sha256": "59f1c42e5962e9333bb1673c21125b7a7ce9a6908299aee8f7673803c2e24212", + "win_x64_node_lib_sha256": "35fcdd35d3d22e283c0e2e095cc43ef676301bb85f950c344a73d59231bd7e61" + } + } + } + } + }, "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "oZFClfRhTTwsYzpxVPkOpOt/r0+OzEfEV37au0jFZ0s=", diff --git a/patches/darts-clone-opencc.patch b/patches/darts-clone-opencc.patch new file mode 100644 index 000000000..750b2224e --- /dev/null +++ b/patches/darts-clone-opencc.patch @@ -0,0 +1,106 @@ +diff --git a/BUILD.bazel b/BUILD.bazel +--- a/BUILD.bazel ++++ b/BUILD.bazel +@@ -1,5 +1,11 @@ + load("@rules_cc//cc:defs.bzl", "cc_library") + ++filegroup( ++ name = "all_files", ++ srcs = glob(["**"]), ++ visibility = ["//visibility:public"], ++) ++ + cc_library( + name = "darts-clone", + hdrs = glob(["include/*.h"]), +diff --git a/MODULE.bazel b/MODULE.bazel +--- a/MODULE.bazel ++++ b/MODULE.bazel +@@ -1,4 +1,4 @@ +-"""Darts-clone is a clone of Darts (Double-ARray Trie System) which is a C++ header library for a static double-array trie structure.""" ++"""Darts-clone is a clone of Darts (Double-ARray Trie System).""" + + module( + name = "darts-clone", +@@ -6,4 +6,4 @@ + compatibility_level = 0, + ) + +-bazel_dep(name = "rules_cc", version = "0.2.17") ++bazel_dep(name = "rules_cc", version = "0.2.20") +diff --git a/include/darts.h b/include/darts.h +--- a/include/darts.h ++++ b/include/darts.h +@@ -1,7 +1,9 @@ + #ifndef DARTS_H_ + #define DARTS_H_ + ++#include + #include ++#include + #include + #include + +@@ -36,7 +38,7 @@ + + // The main structure of Darts-clone is an array of s, and the + // unit type is actually a wrapper of . +-typedef unsigned int id_type; ++typedef uint32_t id_type; + + // is the type of callback functions for reporting the + // progress of building a dictionary. See also build() of . +@@ -172,6 +174,14 @@ + clear(); + array_ = static_cast(ptr); + size_ = size; ++ } ++ void copy_array(const void* ptr, std::size_t num_bytes) { ++ clear(); ++ const std::size_t extra_padding = num_bytes % unit_size() == 0 ? 0 : 1; ++ size_ = num_bytes / unit_size() + extra_padding; ++ buf_ = new unit_type[size_]; ++ std::memcpy(buf_, ptr, num_bytes); ++ array_ = buf_; + } + // array() returns a pointer to the array of units. + const void *array() const { +@@ -314,6 +324,8 @@ + // updates `node_pos' and `key_pos' after each transition. + inline value_type traverse(const key_type *key, std::size_t &node_pos, + std::size_t &key_pos, std::size_t length = 0) const; ++ ++ bool validate(value_type max_value_limit = -1) const; + + private: + typedef Details::uchar_type uchar_type; +@@ -454,6 +466,29 @@ + } + + template ++bool DoubleArrayImpl::validate(value_type max_value_limit) const { ++ if (size_ == 0 || array_ == NULL) { ++ return false; ++ } ++ if (array_[0].label() != '\0' || array_[0].has_leaf() || ++ array_[0].offset() == 0 || ((0 ^ array_[0].offset()) | 0xFF) >= size_) { ++ return false; ++ } ++ for (std::size_t i = 1; i < size_; ++i) { ++ if (array_[i].label() <= 0xFF) { ++ if (((i ^ array_[i].offset()) | 0xFF) >= size_) { ++ return false; ++ } ++ } else if (max_value_limit >= 0) { ++ if (array_[i].value() >= max_value_limit) { ++ return false; ++ } ++ } ++ } ++ return true; ++} ++ ++template + template + inline U DoubleArrayImpl::exactMatchSearch(const key_type *key, + std::size_t length, std::size_t node_pos) const { From c6ee08b10bdfd1b9bb63519e05ae7f2590ca14c5 Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Thu, 2 Jul 2026 00:15:15 -0700 Subject: [PATCH 2/4] Simplify darts-clone patch - Keep unsigned int id_type unsigned int is 32-bit on every supported target, so matching upstream exactly avoids a gratuitous divergence. Also drop the MODULE.bazel docstring change that added no functional value. - Drop docstring edit - Drop unused all_files filegroup from darts-clone patch --- deps/darts-clone-0.32h/BUILD.bazel | 6 --- deps/darts-clone-0.32h/MODULE.bazel | 2 +- deps/darts-clone-0.32h/include/darts.h | 3 +- patches/darts-clone-opencc.patch | 70 +++++++------------------- 4 files changed, 21 insertions(+), 60 deletions(-) diff --git a/deps/darts-clone-0.32h/BUILD.bazel b/deps/darts-clone-0.32h/BUILD.bazel index 4ed61e082..0ddd906c1 100644 --- a/deps/darts-clone-0.32h/BUILD.bazel +++ b/deps/darts-clone-0.32h/BUILD.bazel @@ -1,11 +1,5 @@ load("@rules_cc//cc:defs.bzl", "cc_library") -filegroup( - name = "all_files", - srcs = glob(["**"]), - visibility = ["//visibility:public"], -) - cc_library( name = "darts-clone", hdrs = glob(["include/*.h"]), diff --git a/deps/darts-clone-0.32h/MODULE.bazel b/deps/darts-clone-0.32h/MODULE.bazel index 3ddf9b0fc..70ed8bfb7 100644 --- a/deps/darts-clone-0.32h/MODULE.bazel +++ b/deps/darts-clone-0.32h/MODULE.bazel @@ -1,4 +1,4 @@ -"""Darts-clone is a clone of Darts (Double-ARray Trie System).""" +"""Darts-clone is a clone of Darts (Double-ARray Trie System) which is a C++ header library for a static double-array trie structure.""" module( name = "darts-clone", diff --git a/deps/darts-clone-0.32h/include/darts.h b/deps/darts-clone-0.32h/include/darts.h index c38654af7..ef31795ab 100644 --- a/deps/darts-clone-0.32h/include/darts.h +++ b/deps/darts-clone-0.32h/include/darts.h @@ -1,7 +1,6 @@ #ifndef DARTS_H_ #define DARTS_H_ -#include #include #include #include @@ -38,7 +37,7 @@ typedef int value_type; // The main structure of Darts-clone is an array of s, and the // unit type is actually a wrapper of . -typedef uint32_t id_type; +typedef unsigned int id_type; // is the type of callback functions for reporting the // progress of building a dictionary. See also build() of . diff --git a/patches/darts-clone-opencc.patch b/patches/darts-clone-opencc.patch index 750b2224e..09ea4cbf9 100644 --- a/patches/darts-clone-opencc.patch +++ b/patches/darts-clone-opencc.patch @@ -1,27 +1,6 @@ -diff --git a/BUILD.bazel b/BUILD.bazel ---- a/BUILD.bazel -+++ b/BUILD.bazel -@@ -1,5 +1,11 @@ - load("@rules_cc//cc:defs.bzl", "cc_library") - -+filegroup( -+ name = "all_files", -+ srcs = glob(["**"]), -+ visibility = ["//visibility:public"], -+) -+ - cc_library( - name = "darts-clone", - hdrs = glob(["include/*.h"]), diff --git a/MODULE.bazel b/MODULE.bazel --- a/MODULE.bazel +++ b/MODULE.bazel -@@ -1,4 +1,4 @@ --"""Darts-clone is a clone of Darts (Double-ARray Trie System) which is a C++ header library for a static double-array trie structure.""" -+"""Darts-clone is a clone of Darts (Double-ARray Trie System).""" - - module( - name = "darts-clone", @@ -6,4 +6,4 @@ compatibility_level = 0, ) @@ -31,30 +10,18 @@ diff --git a/MODULE.bazel b/MODULE.bazel diff --git a/include/darts.h b/include/darts.h --- a/include/darts.h +++ b/include/darts.h -@@ -1,7 +1,9 @@ - #ifndef DARTS_H_ +@@ -2,6 +2,7 @@ #define DARTS_H_ -+#include #include +#include #include #include -@@ -36,7 +38,7 @@ - - // The main structure of Darts-clone is an array of s, and the - // unit type is actually a wrapper of . --typedef unsigned int id_type; -+typedef uint32_t id_type; - - // is the type of callback functions for reporting the - // progress of building a dictionary. See also build() of . -@@ -172,6 +174,14 @@ - clear(); +@@ -173,6 +174,14 @@ array_ = static_cast(ptr); size_ = size; -+ } + } + void copy_array(const void* ptr, std::size_t num_bytes) { + clear(); + const std::size_t extra_padding = num_bytes % unit_size() == 0 ? 0 : 1; @@ -62,22 +29,26 @@ diff --git a/include/darts.h b/include/darts.h + buf_ = new unit_type[size_]; + std::memcpy(buf_, ptr, num_bytes); + array_ = buf_; - } ++ } // array() returns a pointer to the array of units. const void *array() const { -@@ -314,6 +324,8 @@ - // updates `node_pos' and `key_pos' after each transition. + return array_; +@@ -315,6 +324,8 @@ inline value_type traverse(const key_type *key, std::size_t &node_pos, std::size_t &key_pos, std::size_t length = 0) const; -+ -+ bool validate(value_type max_value_limit = -1) const; ++ bool validate(value_type max_value_limit = -1) const; ++ private: typedef Details::uchar_type uchar_type; -@@ -454,6 +466,29 @@ - } - - template + typedef Details::id_type id_type; +@@ -451,6 +462,29 @@ + } + std::fclose(file); + return 0; ++} ++ ++template +bool DoubleArrayImpl::validate(value_type max_value_limit) const { + if (size_ == 0 || array_ == NULL) { + return false; @@ -98,9 +69,6 @@ diff --git a/include/darts.h b/include/darts.h + } + } + return true; -+} -+ -+template - template - inline U DoubleArrayImpl::exactMatchSearch(const key_type *key, - std::size_t length, std::size_t node_pos) const { + } + + template From e53ce6a425c2556145605f46e80b86c5803377dd Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Thu, 2 Jul 2026 07:06:51 -0700 Subject: [PATCH 3/4] Restore all_files filegroup in deps/darts-clone-0.32h local package --- deps/darts-clone-0.32h/BUILD.bazel | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/deps/darts-clone-0.32h/BUILD.bazel b/deps/darts-clone-0.32h/BUILD.bazel index 0ddd906c1..4ed61e082 100644 --- a/deps/darts-clone-0.32h/BUILD.bazel +++ b/deps/darts-clone-0.32h/BUILD.bazel @@ -1,5 +1,11 @@ load("@rules_cc//cc:defs.bzl", "cc_library") +filegroup( + name = "all_files", + srcs = glob(["**"]), + visibility = ["//visibility:public"], +) + cc_library( name = "darts-clone", hdrs = glob(["include/*.h"]), From 68cf68ab52eddbb96094909213075bd3b6a38ecd Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Thu, 2 Jul 2026 07:38:06 -0700 Subject: [PATCH 4/4] Fix MSVC C4267: add static_cast at size_t-to-id_type narrowing points in darts.h --- deps/darts-clone-0.32h/include/darts.h | 18 +++--- patches/darts-clone-opencc.patch | 76 ++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/deps/darts-clone-0.32h/include/darts.h b/deps/darts-clone-0.32h/include/darts.h index ef31795ab..f9c623dd2 100644 --- a/deps/darts-clone-0.32h/include/darts.h +++ b/deps/darts-clone-0.32h/include/darts.h @@ -944,7 +944,7 @@ inline void BitVector::build() { num_ones_ = 0; for (std::size_t i = 0; i < units_.size(); ++i) { - ranks_[i] = num_ones_; + ranks_[i] = static_cast(num_ones_); num_ones_ += pop_count(units_[i]); } } @@ -1866,7 +1866,7 @@ id_type DoubleArrayBuilder::arrange_from_keyset(const Keyset &keyset, inline id_type DoubleArrayBuilder::find_valid_offset(id_type id) const { if (extras_head_ >= units_.size()) { - return units_.size() | (id & LOWER_MASK); + return static_cast(units_.size()) | (id & LOWER_MASK); } id_type unfixed_id = extras_head_; @@ -1878,7 +1878,7 @@ inline id_type DoubleArrayBuilder::find_valid_offset(id_type id) const { unfixed_id = extras(unfixed_id).next(); } while (unfixed_id != extras_head_); - return units_.size() | (id & LOWER_MASK); + return static_cast(units_.size()) | (id & LOWER_MASK); } inline bool DoubleArrayBuilder::is_valid_offset(id_type id, @@ -1909,7 +1909,7 @@ inline void DoubleArrayBuilder::reserve_id(id_type id) { if (id == extras_head_) { extras_head_ = extras(id).next(); if (extras_head_ == id) { - extras_head_ = units_.size(); + extras_head_ = static_cast(units_.size()); } } extras(extras(id).prev()).set_next(extras(id).next()); @@ -1918,8 +1918,8 @@ inline void DoubleArrayBuilder::reserve_id(id_type id) { } inline void DoubleArrayBuilder::expand_units() { - id_type src_num_units = units_.size(); - id_type src_num_blocks = num_blocks(); + id_type src_num_units = static_cast(units_.size()); + id_type src_num_blocks = static_cast(num_blocks()); id_type dest_num_units = src_num_units + BLOCK_SIZE; id_type dest_num_blocks = src_num_blocks + 1; @@ -1931,7 +1931,7 @@ inline void DoubleArrayBuilder::expand_units() { units_.resize(dest_num_units); if (dest_num_blocks > NUM_EXTRA_BLOCKS) { - for (std::size_t id = src_num_units; id < dest_num_units; ++id) { + for (id_type id = src_num_units; id < dest_num_units; ++id) { extras(id).set_is_used(false); extras(id).set_is_fixed(false); } @@ -1955,9 +1955,9 @@ inline void DoubleArrayBuilder::expand_units() { inline void DoubleArrayBuilder::fix_all_blocks() { id_type begin = 0; if (num_blocks() > NUM_EXTRA_BLOCKS) { - begin = num_blocks() - NUM_EXTRA_BLOCKS; + begin = static_cast(num_blocks()) - NUM_EXTRA_BLOCKS; } - id_type end = num_blocks(); + id_type end = static_cast(num_blocks()); for (id_type block_id = begin; block_id != end; ++block_id) { fix_block(block_id); diff --git a/patches/darts-clone-opencc.patch b/patches/darts-clone-opencc.patch index 09ea4cbf9..7dfc87fe2 100644 --- a/patches/darts-clone-opencc.patch +++ b/patches/darts-clone-opencc.patch @@ -33,15 +33,15 @@ diff --git a/include/darts.h b/include/darts.h // array() returns a pointer to the array of units. const void *array() const { return array_; -@@ -315,6 +324,8 @@ +@@ -314,6 +323,8 @@ + // updates `node_pos' and `key_pos' after each transition. inline value_type traverse(const key_type *key, std::size_t &node_pos, std::size_t &key_pos, std::size_t length = 0) const; - -+ bool validate(value_type max_value_limit = -1) const; + ++ bool validate(value_type max_value_limit = -1) const; + private: typedef Details::uchar_type uchar_type; - typedef Details::id_type id_type; @@ -451,6 +462,29 @@ } std::fclose(file); @@ -72,3 +72,71 @@ diff --git a/include/darts.h b/include/darts.h } template +@@ -910,7 +944,7 @@ + + num_ones_ = 0; + for (std::size_t i = 0; i < units_.size(); ++i) { +- ranks_[i] = num_ones_; ++ ranks_[i] = static_cast(num_ones_); + num_ones_ += pop_count(units_[i]); + } + } +@@ -1832,7 +1866,7 @@ + + inline id_type DoubleArrayBuilder::find_valid_offset(id_type id) const { + if (extras_head_ >= units_.size()) { +- return units_.size() | (id & LOWER_MASK); ++ return static_cast(units_.size()) | (id & LOWER_MASK); + } + + id_type unfixed_id = extras_head_; +@@ -1844,7 +1878,7 @@ + unfixed_id = extras(unfixed_id).next(); + } while (unfixed_id != extras_head_); + +- return units_.size() | (id & LOWER_MASK); ++ return static_cast(units_.size()) | (id & LOWER_MASK); + } + + inline bool DoubleArrayBuilder::is_valid_offset(id_type id, +@@ -1875,7 +1909,7 @@ + if (id == extras_head_) { + extras_head_ = extras(id).next(); + if (extras_head_ == id) { +- extras_head_ = units_.size(); ++ extras_head_ = static_cast(units_.size()); + } + } + extras(extras(id).prev()).set_next(extras(id).next()); +@@ -1884,8 +1918,8 @@ + } + + inline void DoubleArrayBuilder::expand_units() { +- id_type src_num_units = units_.size(); +- id_type src_num_blocks = num_blocks(); ++ id_type src_num_units = static_cast(units_.size()); ++ id_type src_num_blocks = static_cast(num_blocks()); + + id_type dest_num_units = src_num_units + BLOCK_SIZE; + id_type dest_num_blocks = src_num_blocks + 1; +@@ -1897,7 +1931,7 @@ + units_.resize(dest_num_units); + + if (dest_num_blocks > NUM_EXTRA_BLOCKS) { +- for (std::size_t id = src_num_units; id < dest_num_units; ++id) { ++ for (id_type id = src_num_units; id < dest_num_units; ++id) { + extras(id).set_is_used(false); + extras(id).set_is_fixed(false); + } +@@ -1921,9 +1955,9 @@ + inline void DoubleArrayBuilder::fix_all_blocks() { + id_type begin = 0; + if (num_blocks() > NUM_EXTRA_BLOCKS) { +- begin = num_blocks() - NUM_EXTRA_BLOCKS; ++ begin = static_cast(num_blocks()) - NUM_EXTRA_BLOCKS; + } +- id_type end = num_blocks(); ++ id_type end = static_cast(num_blocks()); + + for (id_type block_id = begin; block_id != end; ++block_id) { + fix_block(block_id);