summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qunicodetools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qunicodetools.cpp')
-rw-r--r--src/corelib/text/qunicodetools.cpp47
1 files changed, 29 insertions, 18 deletions
diff --git a/src/corelib/text/qunicodetools.cpp b/src/corelib/text/qunicodetools.cpp
index beef159daa..32e791563f 100644
--- a/src/corelib/text/qunicodetools.cpp
+++ b/src/corelib/text/qunicodetools.cpp
@@ -3,12 +3,15 @@
#include "qunicodetools_p.h"
+#include "qmutex.h"
#include "qunicodetables_p.h"
#include "qvarlengtharray.h"
#if QT_CONFIG(library)
#include "qlibrary.h"
#endif
+#include <mutex>
+
#include <limits.h>
#define FLAG(x) (1 << (x))
@@ -17,7 +20,12 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-Q_AUTOTEST_EXPORT int qt_initcharattributes_default_algorithm_only = 0;
+#ifdef QT_BUILD_INTERNAL
+Q_CONSTINIT Q_AUTOTEST_EXPORT
+#else
+constexpr
+#endif
+int qt_initcharattributes_default_algorithm_only = 0;
namespace QUnicodeTools {
@@ -254,7 +262,6 @@ static void getWordBreaks(const char16_t *string, qsizetype len, QCharAttributes
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::WordBreakClass ncls = (QUnicodeTables::WordBreakClass) prop->wordBreakClass;
-#ifdef QT_BUILD_INTERNAL
if (qt_initcharattributes_default_algorithm_only) {
// as of Unicode 5.1, some punctuation marks were mapped to MidLetter and MidNumLet
// which caused "hi.there" to be treated like if it were just a single word;
@@ -265,7 +272,6 @@ static void getWordBreaks(const char16_t *string, qsizetype len, QCharAttributes
else if (ucs4 == 0x003A) // COLON
ncls = QUnicodeTables::WordBreak_MidLetter;
}
-#endif
uchar action = WB::breakTable[cls][ncls];
switch (action) {
@@ -1263,12 +1269,12 @@ static inline Form form(unsigned short uc) {
static qsizetype indic_nextSyllableBoundary(QChar::Script script, const char16_t *s, qsizetype start, qsizetype end, bool *invalid)
{
*invalid = false;
- IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", int(start), int(end));
+ IDEBUG("indic_nextSyllableBoundary: start=%lld, end=%lld", qlonglong(start), qlonglong(end));
const char16_t *uc = s+start;
qsizetype pos = 0;
Form state = form(uc[pos]);
- IDEBUG("state[%d]=%d (uc=%4x)", int(pos), state, uc[pos]);
+ IDEBUG("state[%lld]=%d (uc=%4x)", qlonglong(pos), state, uc[pos]);
pos++;
if (state != Consonant && state != IndependentVowel) {
@@ -1279,7 +1285,7 @@ static qsizetype indic_nextSyllableBoundary(QChar::Script script, const char16_t
while (pos < end - start) {
Form newState = form(uc[pos]);
- IDEBUG("state[%d]=%d (uc=%4x)", int(pos), newState, uc[pos]);
+ IDEBUG("state[%lld]=%d (uc=%4x)", qlonglong(pos), newState, uc[pos]);
switch (newState) {
case Control:
newState = state;
@@ -1405,11 +1411,15 @@ Q_CONSTINIT static th_next_cell_def th_next_cell = nullptr;
static int init_libthai() {
#if QT_CONFIG(library)
- Q_CONSTINIT static bool initialized = false;
- if (!initialized && (!th_brk || !th_next_cell)) {
- th_brk = reinterpret_cast<th_brk_def>(QLibrary::resolve("thai"_L1, static_cast<int>(LIBTHAI_MAJOR), "th_brk"));
- th_next_cell = (th_next_cell_def)QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_next_cell");
- initialized = true;
+ Q_CONSTINIT static QBasicAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(false);
+ Q_CONSTINIT static QBasicMutex mutex;
+ if (!initialized.loadAcquire()) {
+ const auto locker = std::scoped_lock(mutex);
+ if (!initialized.loadAcquire()) {
+ th_brk = reinterpret_cast<th_brk_def>(QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_brk"));
+ th_next_cell = (th_next_cell_def)QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_next_cell");
+ initialized.storeRelease(true);
+ }
}
if (th_brk && th_next_cell)
return 1;
@@ -1444,8 +1454,8 @@ static void thaiAssignAttributes(const char16_t *string, qsizetype len, QCharAtt
char *cstr = s;
int *break_positions = nullptr;
int brp[128];
- int brp_size = 0;
- qsizetype numbreaks, i, j, cell_length;
+ size_t brp_size = 0;
+ qsizetype numbreaks, i;
struct thcell_t tis_cell;
if (!init_libthai())
@@ -1466,7 +1476,7 @@ static void thaiAssignAttributes(const char16_t *string, qsizetype len, QCharAtt
if (len > 128) {
break_positions = static_cast<int *>(malloc (sizeof(int) * len));
memset (break_positions, 0, sizeof(int) * len);
- brp_size = len;
+ brp_size = size_t(len);
}
else {
break_positions = brp;
@@ -1494,11 +1504,12 @@ static void thaiAssignAttributes(const char16_t *string, qsizetype len, QCharAtt
/* manage grapheme boundaries */
i = 0;
while (i < len) {
- cell_length = static_cast<uint>(th_next_cell(reinterpret_cast<const unsigned char *>(cstr) + i, len - i, &tis_cell, true));
+ size_t cell_length = th_next_cell(reinterpret_cast<const unsigned char *>(cstr) + i,
+ size_t(len - i), &tis_cell, true);
attributes[i].graphemeBoundary = true;
- for (j = 1; j < cell_length; j++)
+ for (size_t j = 1; j < cell_length; ++j)
attributes[i + j].graphemeBoundary = false;
i += cell_length;
@@ -1825,7 +1836,7 @@ static qsizetype myanmar_nextSyllableBoundary(const char16_t *s, qsizetype start
if (pos == start)
*invalid = (bool)(charClass & Mymr_CF_DOTTED_CIRCLE);
- MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", int(pos - start), state, charClass, *uc);
+ MMDEBUG("state[%lld]=%d class=%8x (uc=%4x)", qlonglong(pos - start), state, charClass, *uc);
if (state < 0) {
if (state < -1)
@@ -2160,7 +2171,7 @@ static qsizetype khmer_nextSyllableBoundary(const char16_t *s, qsizetype start,
}
state = khmerStateTable[state][charClass & CF_CLASS_MASK];
- KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", int(pos - start), state,
+ KHDEBUG("state[%lld]=%d class=%8lx (uc=%4x)", qlonglong(pos - start), state,
charClass, *uc );
if (state < 0) {