mirror of
https://github.com/openbsd/ports.git
synced 2026-06-18 07:24:23 +02:00
libime: fix build with llvm22 by backporting PR #99
This could really use an update to 1.1.14. tested by kevlo
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
COMMENT = library to support generic input method implementation
|
||||
|
||||
DISTNAME = libime-1.1.9
|
||||
REVISION = 3
|
||||
REVISION = 4
|
||||
|
||||
SHARED_LIBS += IMECore 0.2 # 0.0
|
||||
SHARED_LIBS += IMEPinyin 0.2 # 0.0
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
Avoid UB breaking the build with llvm22
|
||||
|
||||
https://github.com/fcitx/libime/pull/99
|
||||
|
||||
Index: src/libime/core/datrie.cpp
|
||||
--- src/libime/core/datrie.cpp.orig
|
||||
+++ src/libime/core/datrie.cpp
|
||||
@@ -23,7 +23,9 @@
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <istream>
|
||||
+#include <iterator>
|
||||
#include <limits>
|
||||
+#include <optional>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@@ -96,7 +98,8 @@ class DATriePrivate { (public)
|
||||
static inline const int32_t CEDAR_NO_VALUE = NanValue<V>::NO_VALUE();
|
||||
static inline const int32_t CEDAR_NO_PATH = NanValue<V>::NO_PATH();
|
||||
|
||||
- static constexpr int MAX_ALLOC_SIZE = 1 << 16; // must be divisible by 256
|
||||
+ static constexpr size_t MAX_ALLOC_SIZE = 1
|
||||
+ << 16; // must be divisible by 256
|
||||
using result_type = value_type;
|
||||
using uchar = uint8_t;
|
||||
static_assert(sizeof(value_type) <= sizeof(int32_t),
|
||||
@@ -481,10 +484,7 @@ class DATriePrivate { (public)
|
||||
if (m_tail.capacity() < m_tail.size() + needed) {
|
||||
auto quota =
|
||||
m_tail.capacity() +
|
||||
- ((needed > m_tail.size() || needed > MAX_ALLOC_SIZE)
|
||||
- ? needed
|
||||
- : (m_tail.size() >= MAX_ALLOC_SIZE ? MAX_ALLOC_SIZE
|
||||
- : m_tail.size()));
|
||||
+ std::max(needed, std::min(MAX_ALLOC_SIZE, m_tail.size()));
|
||||
m_tail.reserve(quota);
|
||||
}
|
||||
m_array[from].base = -m_tail.size();
|
||||
@@ -592,8 +592,11 @@ class DATriePrivate { (public)
|
||||
npos.offset ? -static_cast<int>(npos.offset) : m_array[from].base;
|
||||
if (base >= 0) { // on trie
|
||||
uchar c = m_ninfo[from].child;
|
||||
- if (!from && !(c = m_ninfo[base ^ c].sibling)) { // bug fix
|
||||
- return CEDAR_NO_PATH; // no entry
|
||||
+ if (!from) {
|
||||
+ c = m_ninfo[base ^ c].sibling;
|
||||
+ if (!c) { // bug fix
|
||||
+ return CEDAR_NO_PATH; // no entry
|
||||
+ }
|
||||
}
|
||||
for (; c && base >= 0; ++len) {
|
||||
from = static_cast<size_t>(base) ^ c;
|
||||
@@ -638,11 +641,13 @@ class DATriePrivate { (public)
|
||||
int _follow(uint32_t &from, const uchar label, const T &cf) {
|
||||
int to = 0;
|
||||
const int base = m_array[from].base;
|
||||
- if (base < 0 || m_array[to = base ^ label].check < 0) {
|
||||
+ if (base < 0 || m_array[base ^ label].check < 0) {
|
||||
to = _pop_enode(base, label, static_cast<int>(from));
|
||||
_push_sibling(from, to ^ label, label, base >= 0);
|
||||
- } else if (m_array[to].check != static_cast<int>(from)) {
|
||||
+ } else if (m_array[base ^ label].check != static_cast<int>(from)) {
|
||||
to = _resolve(from, base, label, cf);
|
||||
+ } else {
|
||||
+ to = base ^ label;
|
||||
}
|
||||
return to;
|
||||
}
|
||||
@@ -707,7 +712,7 @@ class DATriePrivate { (public)
|
||||
int _find_place(const uchar *const first, const uchar *const last) {
|
||||
if (auto bi = m_bheadO) {
|
||||
const auto bz = m_block[m_bheadO].prev;
|
||||
- const auto nc = static_cast<short>(last - first + 1);
|
||||
+ const auto nc = std::distance(first, last);
|
||||
while (true) { // set candidate block
|
||||
block &b = m_block[bi];
|
||||
if (b.num >= nc && nc < b.reject) { // explore configuration
|
||||
@@ -715,11 +720,13 @@ class DATriePrivate { (public)
|
||||
const int base = e ^ *first;
|
||||
for (const uchar *p = first;
|
||||
m_array[base ^ *++p].check < 0;) {
|
||||
- if (p == last) {
|
||||
- return b.ehead = e; // no conflict
|
||||
+ if (p + 1 == last) {
|
||||
+ b.ehead = e;
|
||||
+ return b.ehead; // no conflict
|
||||
}
|
||||
}
|
||||
- if ((e = -m_array[e].check) == b.ehead) {
|
||||
+ e = -m_array[e].check;
|
||||
+ if (e == b.ehead) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -892,23 +899,27 @@ class DATriePrivate { (public)
|
||||
return c_p;
|
||||
}
|
||||
// enumerate (equal to or more than one) child nodes
|
||||
- uchar *_set_child(uchar *p, const int base, uchar c, const int label = -1) {
|
||||
- --p;
|
||||
+ uchar *_set_child(uchar *p, const int base, uchar c,
|
||||
+ const std::optional<uchar> label = std::nullopt) {
|
||||
if (!c) {
|
||||
- *++p = c;
|
||||
+ *p = c;
|
||||
+ p++;
|
||||
c = m_ninfo[base ^ c].sibling;
|
||||
} // 0: terminal
|
||||
- if (ORDERED) {
|
||||
- while (c && c < label) {
|
||||
- *++p = c;
|
||||
+ if (ORDERED && label.has_value()) {
|
||||
+ while (c && c < *label) {
|
||||
+ *p = c;
|
||||
+ p++;
|
||||
c = m_ninfo[base ^ c].sibling;
|
||||
}
|
||||
}
|
||||
- if (label != -1) {
|
||||
- *++p = static_cast<uchar>(label);
|
||||
+ if (label.has_value()) {
|
||||
+ *p = *label;
|
||||
+ p++;
|
||||
}
|
||||
while (c) {
|
||||
- *++p = c;
|
||||
+ *p = c;
|
||||
+ p++;
|
||||
c = m_ninfo[base ^ c].sibling;
|
||||
}
|
||||
return p;
|
||||
@@ -925,30 +936,33 @@ class DATriePrivate { (public)
|
||||
= _consult(base_n, base_p, m_ninfo[from_n].child,
|
||||
m_ninfo[from_p].child);
|
||||
uchar child[256];
|
||||
- uchar *const first = &child[0];
|
||||
+ uchar *const first = child;
|
||||
uchar *const last =
|
||||
flag ? _set_child(first, base_n, m_ninfo[from_n].child, label_n)
|
||||
: _set_child(first, base_p, m_ninfo[from_p].child);
|
||||
+ assert(first < last);
|
||||
const int base =
|
||||
- (first == last ? _find_place() : _find_place(first, last)) ^ *first;
|
||||
+ (first + 1 == last ? _find_place() : _find_place(first, last)) ^
|
||||
+ *first;
|
||||
// replace & modify empty list
|
||||
const int from = flag ? static_cast<int>(from_n) : from_p;
|
||||
const int base_ = flag ? base_n : base_p;
|
||||
if (flag && *first == label_n) {
|
||||
m_ninfo[from].child = label_n; // new child
|
||||
}
|
||||
- m_array[from].base = base; // new base
|
||||
- for (const uchar *p = first; p <= last; ++p) { // to_ => to
|
||||
+ m_array[from].base = base; // new base
|
||||
+ for (const uchar *p = first; p < last; ++p) { // to_ => to
|
||||
const int to = _pop_enode(base, *p, from);
|
||||
const int to_ = base_ ^ *p;
|
||||
- m_ninfo[to].sibling = (p == last ? 0 : *(p + 1));
|
||||
+ m_ninfo[to].sibling = (p + 1 == last) ? 0 : *(p + 1);
|
||||
if (flag && to_ == to_pn) {
|
||||
continue; // skip newcomer (no child)
|
||||
}
|
||||
cf(to_, to);
|
||||
node &n = m_array[to];
|
||||
node &n_ = m_array[to_];
|
||||
- if ((n.base = n_.base) > 0 && *p) { // copy base; bug fix
|
||||
+ n.base = n_.base; // copy base; bug fix
|
||||
+ if (n.base > 0 && *p) {
|
||||
uchar c = m_ninfo[to].child = m_ninfo[to_].child;
|
||||
do {
|
||||
m_array[n.base ^ c].check = to; // adjust grand son's check
|
||||
Reference in New Issue
Block a user