summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/corelib/qurl-generateTLDs/main.cpp163
-rw-r--r--util/glgen/codegenerator.cpp2
-rw-r--r--util/glgen/legacyspecparser.cpp2
-rw-r--r--util/lexgen/generator.cpp6
-rw-r--r--util/lexgen/nfa.cpp2
-rw-r--r--util/local_database/README1
-rwxr-xr-xutil/local_database/cldr2qtimezone.py431
-rw-r--r--util/locale_database/README5
-rwxr-xr-xutil/locale_database/cldr2qlocalexml.py (renamed from util/local_database/cldr2qlocalexml.py)56
-rwxr-xr-xutil/locale_database/cldr2qtimezone.py457
-rwxr-xr-xutil/locale_database/dateconverter.py (renamed from util/local_database/dateconverter.py)0
-rw-r--r--util/locale_database/enumdata.py (renamed from util/local_database/enumdata.py)2
-rw-r--r--util/locale_database/formattags.txt (renamed from util/local_database/formattags.txt)0
-rw-r--r--util/locale_database/localexml.py (renamed from util/local_database/localexml.py)104
-rwxr-xr-xutil/locale_database/qlocalexml2cpp.py (renamed from util/local_database/qlocalexml2cpp.py)140
-rw-r--r--util/locale_database/testlocales/localemodel.cpp (renamed from util/local_database/testlocales/localemodel.cpp)0
-rw-r--r--util/locale_database/testlocales/localemodel.h (renamed from util/local_database/testlocales/localemodel.h)0
-rw-r--r--util/locale_database/testlocales/localewidget.cpp (renamed from util/local_database/testlocales/localewidget.cpp)0
-rw-r--r--util/locale_database/testlocales/localewidget.h (renamed from util/local_database/testlocales/localewidget.h)0
-rw-r--r--util/locale_database/testlocales/main.cpp (renamed from util/local_database/testlocales/main.cpp)0
-rw-r--r--util/locale_database/testlocales/testlocales.pro (renamed from util/local_database/testlocales/testlocales.pro)0
-rw-r--r--util/locale_database/xpathlite.py (renamed from util/local_database/xpathlite.py)28
-rw-r--r--util/qfloat16-tables/gen_qfloat16_tables.cpp163
-rw-r--r--util/qfloat16-tables/qfloat16-tables.pro2
-rw-r--r--util/unicode/README2
-rw-r--r--util/unicode/codecs/big5/main.cpp4
-rw-r--r--util/unicode/main.cpp146
27 files changed, 1038 insertions, 678 deletions
diff --git a/util/corelib/qurl-generateTLDs/main.cpp b/util/corelib/qurl-generateTLDs/main.cpp
index e1fe97646f..e458ea9d53 100644
--- a/util/corelib/qurl-generateTLDs/main.cpp
+++ b/util/corelib/qurl-generateTLDs/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the utils of the Qt Toolkit.
@@ -28,33 +28,66 @@
#include <QtCore>
+const QString quadQuote = QStringLiteral("\"\""); // Closes one string, opens a new one.
+
static QString utf8encode(const QByteArray &array) // turns e.g. tranøy.no to tran\xc3\xb8y.no
{
QString result;
result.reserve(array.length() + array.length() / 3);
+ bool wasHex = false;
for (int i = 0; i < array.length(); ++i) {
char c = array.at(i);
// if char is non-ascii, escape it
if (c < 0x20 || uchar(c) >= 0x7f) {
result += "\\x" + QString::number(uchar(c), 16);
+ wasHex = true;
} else {
// if previous char was escaped, we need to make sure the next char is not
// interpreted as part of the hex value, e.g. "äc.com" -> "\xabc.com"; this
// should be "\xab""c.com"
- QRegExp hexEscape("\\\\x[a-fA-F0-9][a-fA-F0-9]$");
bool isHexChar = ((c >= '0' && c <= '9') ||
- (c >= 'a' && c <= 'f') ||
- (c >= 'A' && c <= 'F'));
- if (result.contains(hexEscape) && isHexChar)
- result += "\"\"";
+ (c >= 'a' && c <= 'f') ||
+ (c >= 'A' && c <= 'F'));
+ if (wasHex && isHexChar)
+ result += quadQuote;
result += c;
+ wasHex = false;
}
}
return result;
}
-int main(int argc, char **argv) {
+/*
+ Digest public suffix data into efficiently-searchable form.
+
+ Takes the public suffix list (see usage message), a list of DNS domains
+ whose child domains should not be presumed to trust one another, and
+ converts it to a form that lets qtbase/src/corelib/io/qtldurl.cpp's query
+ functions find entries efficiently.
+
+ Each line of the suffix file (aside from comments and blanks) gives a suffix
+ (starting with a dot) with an optional prefix of '*' (to include every
+ immediate child) or of '!' (to exclude the suffix, e.g. from a '*' line for
+ a tail of it). A line with neither of these prefixes is an exact match.
+
+ Each line is hashed and the hash is reduced modulo the number of lines
+ (tldCount); lines are grouped by reduced hash and separated by '\0' bytes
+ within each group. Conceptually, the groups are then emitted to a single
+ huge string, along with a table (tldIndices[tldCount]) of indices into that
+ string of the starts of the the various groups.
+
+ However, that huge string would exceed the 64k limit at least one compiler
+ imposes on a single string literal, so we actually split up the huge string
+ into an array of chunks, each less than 64k in size. Each group is written
+ to a single chunk (so we start a new chunk if the next group would take the
+ present chunk over the limit). There are tldChunkCount chunks; their lengths
+ are saved in tldChunks[tldChunkCount]; the chunks themselves in
+ tldData[tldChunkCount]. See qtldurl.cpp's containsTLDEntry() for how to
+ search for a string in the resulting data.
+*/
+int main(int argc, char **argv)
+{
QCoreApplication app(argc, argv);
if (argc < 3) {
printf("\nUsage: ./%s inputFile outputFile\n\n", argv[0]);
@@ -68,14 +101,20 @@ int main(int argc, char **argv) {
return 1;
}
QFile file(argv[1]);
- QFile outFile(argv[2]);
- file.open(QIODevice::ReadOnly);
- outFile.open(QIODevice::WriteOnly);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fprintf("Failed to open input file (%s); see %s -usage", argv[1], argv[0]);
+ return 1;
+ }
- QByteArray outIndicesBufferBA;
- QBuffer outIndicesBuffer(&outIndicesBufferBA);
- outIndicesBuffer.open(QIODevice::WriteOnly);
+ QFile outFile(argv[2]);
+ if (!outFile.open(QIODevice::WriteOnly)) {
+ file.close()
+ fprintf("Failed to open output file (%s); see %s -usage", argv[2], argv[0]);
+ return 1;
+ }
+ // Write tldData[] and tldIndices[] in one scan of the (input) file, but
+ // buffer tldData[] so we don'te interleave them in the outFile.
QByteArray outDataBufferBA;
QBuffer outDataBuffer(&outDataBufferBA);
outDataBuffer.open(QIODevice::WriteOnly);
@@ -85,75 +124,65 @@ int main(int argc, char **argv) {
file.readLine();
lineCount++;
}
+ outFile.write("static const quint16 tldCount = ");
+ outFile.write(QByteArray::number(lineCount));
+ outFile.write(";\n");
+
file.reset();
QVector<QString> strings(lineCount);
while (!file.atEnd()) {
- QString s = QString::fromUtf8(file.readLine());
- QString st = s.trimmed();
+ QString st = QString::fromUtf8(file.readLine()).trimmed();
int num = qt_hash(st) % lineCount;
+ QString &entry = strings[num];
+ st = utf8encode(st.toUtf8());
- QString utf8String = utf8encode(st.toUtf8());
-
- // for domain 1.com, we could get something like
- // a.com\01.com, which would be interpreted as octal 01,
- // so we need to separate those strings with quotes
- QRegExp regexpOctalEscape(QLatin1String("^[0-9]"));
- if (!strings.at(num).isEmpty() && st.contains(regexpOctalEscape))
- strings[num].append("\"\"");
+ // For domain 1.com, we could get something like a.com\01.com, which
+ // would be misinterpreted as octal 01, so we need to separate such
+ // strings with quotes:
+ if (!entry.isEmpty() && st.at(0).isDigit())
+ entry.append(quadQuote);
- strings[num].append(utf8String);
- strings[num].append("\\0");
+ entry.append(st);
+ entry.append("\\0");
}
-
- outIndicesBuffer.write("static const quint16 tldCount = ");
- outIndicesBuffer.write(QByteArray::number(lineCount));
- outIndicesBuffer.write(";\n");
- outIndicesBuffer.write("static const quint32 tldIndices[");
-// outIndicesBuffer.write(QByteArray::number(lineCount+1)); // not needed
- outIndicesBuffer.write("] = {\n");
+ outFile.write("static const quint32 tldIndices[] = {\n");
+ outDataBuffer.write("\nstatic const char *tldData[] = {");
int totalUtf8Size = 0;
int chunkSize = 0; // strlen of the current chunk (sizeof is bigger by 1)
- int stringUtf8Size = 0;
QStringList chunks;
for (int a = 0; a < lineCount; a++) {
- bool lineIsEmpty = strings.at(a).isEmpty();
- if (!lineIsEmpty) {
- strings[a].prepend("\"");
- strings[a].append("\"");
- }
- int zeroCount = strings.at(a).count(QLatin1String("\\0"));
- int utf8CharsCount = strings.at(a).count(QLatin1String("\\x"));
- int quoteCount = strings.at(a).count('"');
- stringUtf8Size = strings.at(a).count() - (zeroCount + quoteCount + utf8CharsCount * 3);
- chunkSize += stringUtf8Size;
- // MSVC 2015 chokes if sizeof(a single string) > 0xffff
- if (chunkSize >= 0xffff) {
- static int chunkCount = 0;
- qWarning() << "chunk" << ++chunkCount << "has length" << chunkSize - stringUtf8Size;
- outDataBuffer.write(",\n\n");
- chunks.append(QByteArray::number(totalUtf8Size));
- chunkSize = 0;
+ outFile.write(QByteArray::number(totalUtf8Size));
+ outFile.write(",\n");
+ const QString &entry = strings.at(a);
+ if (!entry.isEmpty()) {
+ const int zeroCount = entry.count(QLatin1String("\\0"));
+ const int utf8CharsCount = entry.count(QLatin1String("\\x"));
+ const int quoteCount = entry.count('"');
+ const int stringUtf8Size = entry.count() - (zeroCount + quoteCount + utf8CharsCount * 3);
+ chunkSize += stringUtf8Size;
+ // MSVC 2015 chokes if sizeof(a single string) > 0xffff
+ if (chunkSize >= 0xffff) {
+ static int chunkCount = 0;
+ qWarning() << "chunk" << ++chunkCount << "has length" << chunkSize - stringUtf8Size;
+ outDataBuffer.write(",\n");
+ chunks.append(QString::number(totalUtf8Size));
+ chunkSize = 0;
+ }
+ totalUtf8Size += stringUtf8Size;
+
+ outDataBuffer.write("\n\"");
+ outDataBuffer.write(entry.toUtf8());
+ outDataBuffer.write("\"");
}
- outDataBuffer.write(strings.at(a).toUtf8());
- if (!lineIsEmpty)
- outDataBuffer.write("\n");
- outIndicesBuffer.write(QByteArray::number(totalUtf8Size));
- outIndicesBuffer.write(",\n");
- totalUtf8Size += stringUtf8Size;
}
- chunks.append(QByteArray::number(totalUtf8Size));
- outIndicesBuffer.write(QByteArray::number(totalUtf8Size));
- outIndicesBuffer.write("};\n");
- outIndicesBuffer.close();
- outFile.write(outIndicesBufferBA);
+ chunks.append(QString::number(totalUtf8Size));
+ outFile.write(QByteArray::number(totalUtf8Size));
+ outFile.write("\n};\n");
+ outDataBuffer.write("\n};\n");
outDataBuffer.close();
- outFile.write("\nstatic const char *tldData[");
-// outFile.write(QByteArray::number(charSize)); // not needed
- outFile.write("] = {\n");
outFile.write(outDataBufferBA);
- outFile.write("};\n");
// write chunk information
outFile.write("\nstatic const quint16 tldChunkCount = ");
@@ -162,6 +191,6 @@ int main(int argc, char **argv) {
outFile.write(chunks.join(", ").toLatin1());
outFile.write("};\n");
outFile.close();
- printf("data generated to %s . Now copy the data from this file to src/corelib/io/qurltlds_p.h in your Qt repo\n", argv[2]);
- exit(0);
+ printf("Data generated to %s - now revise qtbase/src/corelib/io/qurltlds_p.h to use this data.\n", argv[2]);
+ return 0;
}
diff --git a/util/glgen/codegenerator.cpp b/util/glgen/codegenerator.cpp
index 4627daa48b..08327a62f5 100644
--- a/util/glgen/codegenerator.cpp
+++ b/util/glgen/codegenerator.cpp
@@ -184,7 +184,7 @@ void CodeGenerator::writeCoreFactoryImplementation(const QString &fileName) cons
// Get the set of version functions classes we need to create
QList<Version> versions = m_parser->versions();
- qSort(versions.begin(), versions.end(), qGreater<Version>());
+ std::sort(m_versions.begin(), m_versions.end(), std::greater<Version>());
// Outout the #include statements
stream << QStringLiteral("#if !defined(QT_OPENGL_ES_2)") << endl;
diff --git a/util/glgen/legacyspecparser.cpp b/util/glgen/legacyspecparser.cpp
index 0f4d085bba..ab2c9495e7 100644
--- a/util/glgen/legacyspecparser.cpp
+++ b/util/glgen/legacyspecparser.cpp
@@ -291,7 +291,7 @@ void LegacySpecParser::parseFunctions(QTextStream &stream)
}
m_versions = versions.toList();
- qSort(m_versions);
+ std::sort(m_versions.begin(), m_versions.end());
}
bool LegacySpecParser::inDeprecationException(const QString &functionName) const
diff --git a/util/lexgen/generator.cpp b/util/lexgen/generator.cpp
index 481d586e73..3b966e025b 100644
--- a/util/lexgen/generator.cpp
+++ b/util/lexgen/generator.cpp
@@ -183,7 +183,7 @@ Generator::Generator(const DFA &_dfa, const Config &config)
: dfa(_dfa), cfg(config)
{
QList<InputType> lst = cfg.maxInputSet.toList();
- qSort(lst);
+ std::sort(lst.begin(), lst.end());
minInput = lst.first();
maxInput = lst.last();
@@ -230,7 +230,7 @@ static QVector<Generator::TransitionSequence> convertToSequences(const Transitio
return sequences;
QList<InputType> keys = transitions.keys();
- qSort(keys);
+ std::sort(keys.begin(), keys.end());
int i = 0;
Generator::TransitionSequence sequence;
sequence.first = keys.at(0);
@@ -359,7 +359,7 @@ void Generator::generateTransitions(CodeBlock &body, const TransitionMap &transi
}
} else {
QList<InputType> keys = transitions.keys();
- qSort(keys);
+ std::sort(keys.begin(), keys.end());
body << "switch (ch.unicode()) {";
body.indent();
diff --git a/util/lexgen/nfa.cpp b/util/lexgen/nfa.cpp
index 9047a17fde..f6e3a5c355 100644
--- a/util/lexgen/nfa.cpp
+++ b/util/lexgen/nfa.cpp
@@ -384,7 +384,7 @@ QSet<int> NFA::epsilonClosure(const QSet<int> &initialClosure) const
QStack<int> stateStack;
stateStack.resize(closure.count());
- qCopy(closure.constBegin(), closure.constEnd(), stateStack.begin());
+ std::copy(closure.constBegin(), closure.constEnd(), stateStack.begin());
while (!stateStack.isEmpty()) {
int t = stateStack.pop();
diff --git a/util/local_database/README b/util/local_database/README
deleted file mode 100644
index 23b6a33ad8..0000000000
--- a/util/local_database/README
+++ /dev/null
@@ -1 +0,0 @@
-local_database is used to generate qlocale data from the Common Locale Data Repository (The database for localized names (like date formats, country names etc)).
diff --git a/util/local_database/cldr2qtimezone.py b/util/local_database/cldr2qtimezone.py
deleted file mode 100755
index 7c10b1dfd2..0000000000
--- a/util/local_database/cldr2qtimezone.py
+++ /dev/null
@@ -1,431 +0,0 @@
-#!/usr/bin/env python2
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-"""Parse CLDR data for QTimeZone use with MS-Windows
-
-Script to parse the CLDR supplemental/windowsZones.xml file and encode
-for use in QTimeZone. See ``./cldr2qlocalexml.py`` for where to get
-the CLDR data. Pass its common/ directory as first parameter to this
-script and the qtbase root directory as second parameter. It shall
-update qtbase's src/corelib/tools/qtimezoneprivate_data_p.h ready for
-use.
-
-The XML structure is as follows:
-
- <supplementalData>
- <version number="$Revision: 7825 $"/>
- <generation date="$Date: 2012-10-10 14:45:31 -0700 (Wed, 10 Oct 2012) $"/>
- <windowsZones>
- <mapTimezones otherVersion="7dc0101" typeVersion="2012f">
- <!-- (UTC-08:00) Pacific Time (US & Canada) -->
- <mapZone other="Pacific Standard Time" territory="001" type="America/Los_Angeles"/>
- <mapZone other="Pacific Standard Time" territory="CA" type="America/Vancouver America/Dawson America/Whitehorse"/>
- <mapZone other="Pacific Standard Time" territory="MX" type="America/Tijuana"/>
- <mapZone other="Pacific Standard Time" territory="US" type="America/Los_Angeles"/>
- <mapZone other="Pacific Standard Time" territory="ZZ" type="PST8PDT"/>
- </mapTimezones>
- </windowsZones>
- </supplementalData>
-"""
-
-import os
-import sys
-import datetime
-import tempfile
-import enumdata
-import xpathlite
-from xpathlite import DraftResolution
-import re
-import qlocalexml2cpp
-
-findAlias = xpathlite.findAlias
-findEntry = xpathlite.findEntry
-findEntryInFile = xpathlite._findEntryInFile
-findTagsInFile = xpathlite.findTagsInFile
-unicode2hex = qlocalexml2cpp.unicode2hex
-wrap_list = qlocalexml2cpp.wrap_list
-
-class ByteArrayData:
- def __init__(self):
- self.data = []
- self.hash = {}
- def append(self, s):
- s = s + '\0'
- if s in self.hash:
- return self.hash[s]
-
- lst = unicode2hex(s)
- index = len(self.data)
- if index > 65535:
- print "\n\n\n#error Data index is too big!"
- sys.stderr.write ("\n\n\nERROR: index exceeds the uint16 range! index = %d\n" % index)
- sys.exit(1)
- self.hash[s] = index
- self.data += lst
- return index
-
-# List of currently known Windows IDs. If script fails on missing ID plase add it here
-# Not public so may be safely changed.
-# Windows Key : [ Windows Id, Offset Seconds ]
-windowsIdList = {
- 1 : [ u'Afghanistan Standard Time', 16200 ],
- 2 : [ u'Alaskan Standard Time', -32400 ],
- 3 : [ u'Arab Standard Time', 10800 ],
- 4 : [ u'Arabian Standard Time', 14400 ],
- 5 : [ u'Arabic Standard Time', 10800 ],
- 6 : [ u'Argentina Standard Time', -10800 ],
- 7 : [ u'Atlantic Standard Time', -14400 ],
- 8 : [ u'AUS Central Standard Time', 34200 ],
- 9 : [ u'AUS Eastern Standard Time', 36000 ],
- 10 : [ u'Azerbaijan Standard Time', 14400 ],
- 11 : [ u'Azores Standard Time', -3600 ],
- 12 : [ u'Bahia Standard Time', -10800 ],
- 13 : [ u'Bangladesh Standard Time', 21600 ],
- 14 : [ u'Belarus Standard Time', 10800 ],
- 15 : [ u'Canada Central Standard Time', -21600 ],
- 16 : [ u'Cape Verde Standard Time', -3600 ],
- 17 : [ u'Caucasus Standard Time', 14400 ],
- 18 : [ u'Cen. Australia Standard Time', 34200 ],
- 19 : [ u'Central America Standard Time', -21600 ],
- 20 : [ u'Central Asia Standard Time', 21600 ],
- 21 : [ u'Central Brazilian Standard Time', -14400 ],
- 22 : [ u'Central Europe Standard Time', 3600 ],
- 23 : [ u'Central European Standard Time', 3600 ],
- 24 : [ u'Central Pacific Standard Time', 39600 ],
- 25 : [ u'Central Standard Time (Mexico)', -21600 ],
- 26 : [ u'Central Standard Time', -21600 ],
- 27 : [ u'China Standard Time', 28800 ],
- 28 : [ u'Dateline Standard Time', -43200 ],
- 29 : [ u'E. Africa Standard Time', 10800 ],
- 30 : [ u'E. Australia Standard Time', 36000 ],
- 31 : [ u'E. South America Standard Time', -10800 ],
- 32 : [ u'Eastern Standard Time', -18000 ],
- 33 : [ u'Eastern Standard Time (Mexico)', -18000 ],
- 34 : [ u'Egypt Standard Time', 7200 ],
- 35 : [ u'Ekaterinburg Standard Time', 18000 ],
- 36 : [ u'Fiji Standard Time', 43200 ],
- 37 : [ u'FLE Standard Time', 7200 ],
- 38 : [ u'Georgian Standard Time', 14400 ],
- 39 : [ u'GMT Standard Time', 0 ],
- 40 : [ u'Greenland Standard Time', -10800 ],
- 41 : [ u'Greenwich Standard Time', 0 ],
- 42 : [ u'GTB Standard Time', 7200 ],
- 43 : [ u'Hawaiian Standard Time', -36000 ],
- 44 : [ u'India Standard Time', 19800 ],
- 45 : [ u'Iran Standard Time', 12600 ],
- 46 : [ u'Israel Standard Time', 7200 ],
- 47 : [ u'Jordan Standard Time', 7200 ],
- 48 : [ u'Kaliningrad Standard Time', 7200 ],
- 49 : [ u'Korea Standard Time', 32400 ],
- 50 : [ u'Libya Standard Time', 7200 ],
- 51 : [ u'Line Islands Standard Time', 50400 ],
- 52 : [ u'Magadan Standard Time', 36000 ],
- 53 : [ u'Mauritius Standard Time', 14400 ],
- 54 : [ u'Middle East Standard Time', 7200 ],
- 55 : [ u'Montevideo Standard Time', -10800 ],
- 56 : [ u'Morocco Standard Time', 0 ],
- 57 : [ u'Mountain Standard Time (Mexico)', -25200 ],
- 58 : [ u'Mountain Standard Time', -25200 ],
- 59 : [ u'Myanmar Standard Time', 23400 ],
- 60 : [ u'N. Central Asia Standard Time', 21600 ],
- 61 : [ u'Namibia Standard Time', 3600 ],
- 62 : [ u'Nepal Standard Time', 20700 ],
- 63 : [ u'New Zealand Standard Time', 43200 ],
- 64 : [ u'Newfoundland Standard Time', -12600 ],
- 65 : [ u'North Asia East Standard Time', 28800 ],
- 66 : [ u'North Asia Standard Time', 25200 ],
- 67 : [ u'Pacific SA Standard Time', -10800 ],
- 68 : [ u'E. Europe Standard Time', 7200 ],
- 69 : [ u'Pacific Standard Time', -28800 ],
- 70 : [ u'Pakistan Standard Time', 18000 ],
- 71 : [ u'Paraguay Standard Time', -14400 ],
- 72 : [ u'Romance Standard Time', 3600 ],
- 73 : [ u'Russia Time Zone 3', 14400 ],
- 74 : [ u'Russia Time Zone 10', 39600 ],
- 75 : [ u'Russia Time Zone 11', 43200 ],
- 76 : [ u'Russian Standard Time', 10800 ],
- 77 : [ u'SA Eastern Standard Time', -10800 ],
- 78 : [ u'SA Pacific Standard Time', -18000 ],
- 79 : [ u'SA Western Standard Time', -14400 ],
- 80 : [ u'Samoa Standard Time', 46800 ],
- 81 : [ u'SE Asia Standard Time', 25200 ],
- 82 : [ u'Singapore Standard Time', 28800 ],
- 83 : [ u'South Africa Standard Time', 7200 ],
- 84 : [ u'Sri Lanka Standard Time', 19800 ],
- 85 : [ u'Syria Standard Time', 7200 ],
- 86 : [ u'Taipei Standard Time', 28800 ],
- 87 : [ u'Tasmania Standard Time', 36000 ],
- 88 : [ u'Tokyo Standard Time', 32400 ],
- 89 : [ u'Tonga Standard Time', 46800 ],
- 90 : [ u'Turkey Standard Time', 7200 ],
- 91 : [ u'Ulaanbaatar Standard Time', 28800 ],
- 92 : [ u'US Eastern Standard Time', -18000 ],
- 93 : [ u'US Mountain Standard Time', -25200 ],
- 94 : [ u'UTC-02', -7200 ],
- 95 : [ u'UTC-11', -39600 ],
- 96 : [ u'UTC', 0 ],
- 97 : [ u'UTC+12', 43200 ],
- 98 : [ u'Venezuela Standard Time', -16200 ],
- 99 : [ u'Vladivostok Standard Time', 36000 ],
- 100: [ u'W. Australia Standard Time', 28800 ],
- 101: [ u'W. Central Africa Standard Time', 3600 ],
- 102: [ u'W. Europe Standard Time', 3600 ],
- 103: [ u'West Asia Standard Time', 18000 ],
- 104: [ u'West Pacific Standard Time', 36000 ],
- 105: [ u'Yakutsk Standard Time', 32400 ],
- 106: [ u'North Korea Standard Time', 30600 ]
-}
-
-def windowsIdToKey(windowsId):
- for windowsKey in windowsIdList:
- if windowsIdList[windowsKey][0] == windowsId:
- return windowsKey
- return 0
-
-# List of standard UTC IDs to use. Not public so may be safely changed.
-# Do not remove ID's as is part of API/behavior guarantee
-# Key : [ UTC Id, Offset Seconds ]
-utcIdList = {
- 0 : [ u'UTC', 0 ], # Goes first so is default
- 1 : [ u'UTC-14:00', -50400 ],
- 2 : [ u'UTC-13:00', -46800 ],
- 3 : [ u'UTC-12:00', -43200 ],
- 4 : [ u'UTC-11:00', -39600 ],
- 5 : [ u'UTC-10:00', -36000 ],
- 6 : [ u'UTC-09:00', -32400 ],
- 7 : [ u'UTC-08:00', -28800 ],
- 8 : [ u'UTC-07:00', -25200 ],
- 9 : [ u'UTC-06:00', -21600 ],
- 10 : [ u'UTC-05:00', -18000 ],
- 11 : [ u'UTC-04:30', -16200 ],
- 12 : [ u'UTC-04:00', -14400 ],
- 13 : [ u'UTC-03:30', -12600 ],
- 14 : [ u'UTC-03:00', -10800 ],
- 15 : [ u'UTC-02:00', -7200 ],
- 16 : [ u'UTC-01:00', -3600 ],
- 17 : [ u'UTC-00:00', 0 ],
- 18 : [ u'UTC+00:00', 0 ],
- 19 : [ u'UTC+01:00', 3600 ],
- 20 : [ u'UTC+02:00', 7200 ],
- 21 : [ u'UTC+03:00', 10800 ],
- 22 : [ u'UTC+03:30', 12600 ],
- 23 : [ u'UTC+04:00', 14400 ],
- 24 : [ u'UTC+04:30', 16200 ],
- 25 : [ u'UTC+05:00', 18000 ],
- 26 : [ u'UTC+05:30', 19800 ],
- 27 : [ u'UTC+05:45', 20700 ],
- 28 : [ u'UTC+06:00', 21600 ],
- 29 : [ u'UTC+06:30', 23400 ],
- 30 : [ u'UTC+07:00', 25200 ],
- 31 : [ u'UTC+08:00', 28800 ],
- 32 : [ u'UTC+09:00', 32400 ],
- 33 : [ u'UTC+09:30', 34200 ],
- 34 : [ u'UTC+10:00', 36000 ],
- 35 : [ u'UTC+11:00', 39600 ],
- 36 : [ u'UTC+12:00', 43200 ],
- 37 : [ u'UTC+13:00', 46800 ],
- 38 : [ u'UTC+14:00', 50400 ],
- 39 : [ u'UTC+08:30', 30600 ]
-}
-
-def usage():
- print "Usage: cldr2qtimezone.py <path to cldr core/common> <path to qtbase>"
- sys.exit()
-
-if len(sys.argv) != 3:
- usage()
-
-cldrPath = sys.argv[1]
-qtPath = sys.argv[2]
-
-if not os.path.isdir(cldrPath) or not os.path.isdir(qtPath):
- usage()
-
-windowsZonesPath = cldrPath + "/supplemental/windowsZones.xml"
-tempFileDir = qtPath
-dataFilePath = qtPath + "/src/corelib/tools/qtimezoneprivate_data_p.h"
-
-if not os.path.isfile(windowsZonesPath):
- usage()
-
-if not os.path.isfile(dataFilePath):
- usage()
-
-cldr_version = 'unknown'
-ldml = open(cldrPath + "/dtd/ldml.dtd", "r")
-for line in ldml:
- if 'version cldrVersion CDATA #FIXED' in line:
- cldr_version = line.split('"')[1]
-
-# [[u'version', [(u'number', u'$Revision: 7825 $')]]]
-versionNumber = findTagsInFile(windowsZonesPath, "version")[0][1][0][1]
-
-mapTimezones = findTagsInFile(windowsZonesPath, "windowsZones/mapTimezones")
-
-defaultDict = {}
-windowsIdDict = {}
-
-if mapTimezones:
- for mapZone in mapTimezones:
- # [u'mapZone', [(u'territory', u'MH'), (u'other', u'UTC+12'), (u'type', u'Pacific/Majuro Pacific/Kwajalein')]]
- if mapZone[0] == u'mapZone':
- data = {}
- for attribute in mapZone[1]:
- if attribute[0] == u'other':
- data['windowsId'] = attribute[1]
- if attribute[0] == u'territory':
- data['countryCode'] = attribute[1]
- if attribute[0] == u'type':
- data['ianaList'] = attribute[1]
-
- data['windowsKey'] = windowsIdToKey(data['windowsId'])
- if data['windowsKey'] <= 0:
- raise xpathlite.Error("Unknown Windows ID, please add \"%s\"" % data['windowsId'])
-
- countryId = 0
- if data['countryCode'] == u'001':
- defaultDict[data['windowsKey']] = data['ianaList']
- else:
- data['countryId'] = enumdata.countryCodeToId(data['countryCode'])
- if data['countryId'] < 0:
- raise xpathlite.Error("Unknown Country Code \"%s\"" % data['countryCode'])
- data['country'] = enumdata.country_list[data['countryId']][0]
- windowsIdDict[data['windowsKey'], data['countryId']] = data
-
-print "Input file parsed, now writing data"
-
-GENERATED_BLOCK_START = "// GENERATED PART STARTS HERE\n"
-GENERATED_BLOCK_END = "// GENERATED PART ENDS HERE\n"
-
-# Create a temp file to write the new data into
-(newTempFile, newTempFilePath) = tempfile.mkstemp("qtimezone_data_p", dir=tempFileDir)
-newTempFile = os.fdopen(newTempFile, "w")
-
-# Open the old file and copy over the first non-generated section to the new file
-oldDataFile = open(dataFilePath, "r")
-s = oldDataFile.readline()
-while s and s != GENERATED_BLOCK_START:
- newTempFile.write(s)
- s = oldDataFile.readline()
-
-# Write out generated block start tag and warning
-newTempFile.write(GENERATED_BLOCK_START)
-newTempFile.write("""
-/*
- This part of the file was generated on %s from the
- Common Locale Data Repository v%s supplemental/windowsZones.xml file %s
-
- http://www.unicode.org/cldr/
-
- Do not edit this code: run cldr2qtimezone.py on updated (or
- edited) CLDR data; see qtbase/util/local_database/.
-*/
-
-""" % (str(datetime.date.today()), cldr_version, versionNumber) )
-
-windowsIdData = ByteArrayData()
-ianaIdData = ByteArrayData()
-
-# Write Windows/IANA table
-newTempFile.write("// Windows ID Key, Country Enum, IANA ID Index\n")
-newTempFile.write("static const QZoneData zoneDataTable[] = {\n")
-for index in windowsIdDict:
- data = windowsIdDict[index]
- newTempFile.write(" { %6d,%6d,%6d }, // %s / %s\n"
- % (data['windowsKey'],
- data['countryId'],
- ianaIdData.append(data['ianaList']),
- data['windowsId'],
- data['country']))
-newTempFile.write(" { 0, 0, 0 } // Trailing zeroes\n")
-newTempFile.write("};\n\n")
-
-print "Done Zone Data"
-
-# Write Windows ID key table
-newTempFile.write("// Windows ID Key, Windows ID Index, IANA ID Index, UTC Offset\n")
-newTempFile.write("static const QWindowsData windowsDataTable[] = {\n")
-for windowsKey in windowsIdList:
- newTempFile.write(" { %6d,%6d,%6d,%6d }, // %s\n"
- % (windowsKey,
- windowsIdData.append(windowsIdList[windowsKey][0]),
- ianaIdData.append(defaultDict[windowsKey]),
- windowsIdList[windowsKey][1],
- windowsIdList[windowsKey][0]))
-newTempFile.write(" { 0, 0, 0, 0 } // Trailing zeroes\n")
-newTempFile.write("};\n\n")
-
-print "Done Windows Data Table"
-
-# Write UTC ID key table
-newTempFile.write("// IANA ID Index, UTC Offset\n")
-newTempFile.write("static const QUtcData utcDataTable[] = {\n")
-for index in utcIdList:
- data = utcIdList[index]
- newTempFile.write(" { %6d,%6d }, // %s\n"
- % (ianaIdData.append(data[0]),
- data[1],
- data[0]))
-newTempFile.write(" { 0, 0 } // Trailing zeroes\n")
-newTempFile.write("};\n\n")
-
-print "Done UTC Data Table"
-
-# Write out Windows ID's data
-newTempFile.write("static const char windowsIdData[] = {\n")
-newTempFile.write(wrap_list(windowsIdData.data))
-newTempFile.write("\n};\n\n")
-
-# Write out IANA ID's data
-newTempFile.write("static const char ianaIdData[] = {\n")
-newTempFile.write(wrap_list(ianaIdData.data))
-newTempFile.write("\n};\n")
-
-print "Done ID Data Table"
-
-# Write out the end of generated block tag
-newTempFile.write(GENERATED_BLOCK_END)
-s = oldDataFile.readline()
-
-# Skip through the old generated data in the old file
-while s and s != GENERATED_BLOCK_END:
- s = oldDataFile.readline()
-
-# Now copy the rest of the original file into the new file
-s = oldDataFile.readline()
-while s:
- newTempFile.write(s)
- s = oldDataFile.readline()
-
-# Now close the old and new file, delete the old file and copy the new file in its place
-newTempFile.close()
-oldDataFile.close()
-os.remove(dataFilePath)
-os.rename(newTempFilePath, dataFilePath)
-
-print "Data generation completed, please check the new file at " + dataFilePath
diff --git a/util/locale_database/README b/util/locale_database/README
new file mode 100644
index 0000000000..8654968d66
--- /dev/null
+++ b/util/locale_database/README
@@ -0,0 +1,5 @@
+locale_database is used to generate qlocale data from CLDR.
+
+CLDR is the Common Locale Data Repository, a database for localized
+data (like date formats, country names etc). It is provided by the
+Unicode consortium.
diff --git a/util/local_database/cldr2qlocalexml.py b/util/locale_database/cldr2qlocalexml.py
index 4ce0a6e3b1..072ea9e4ed 100755
--- a/util/local_database/cldr2qlocalexml.py
+++ b/util/locale_database/cldr2qlocalexml.py
@@ -1,7 +1,8 @@
#!/usr/bin/env python2
+# coding=utf8
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of the Qt Toolkit.
@@ -38,13 +39,16 @@ command-line argument. Save its standard output (but not error) to a
file for later processing by ``./qlocalexml2cpp.py``
When you update the CLDR data, be sure to also update
-src/corelib/tools/qt_attribution.json's entry for unicode-cldr. Check
+src/corelib/text/qt_attribution.json's entry for unicode-cldr. Check
this script's output for unknown language, country or script messages;
if any can be resolved, use their entry in common/main/en.xml to
append new entries to enumdata.py's lists and update documentation in
-src/corelib/tools/qlocale.qdoc, adding the new entries in alphabetic
+src/corelib/text/qlocale.qdoc, adding the new entries in alphabetic
order.
+While updating the locale data, check also for updates to MS-Win's
+time zone names; see cldr2qtimezone.py for details.
+
.. _CLDR: ftp://unicode.org/Public/cldr/
"""
@@ -59,6 +63,8 @@ from xpathlite import DraftResolution, findAlias, findEntry, findTagsInFile
from dateconverter import convert_date
from localexml import Locale
+# TODO: make calendars a command-line option
+calendars = ['gregorian', 'persian', 'islamic'] # 'hebrew'
findEntryInFile = xpathlite._findEntryInFile
def wrappedwarn(prefix, tokens):
return sys.stderr.write(
@@ -95,6 +101,34 @@ def parse_number_format(patterns, data):
result.append(pattern)
return result
+def raiseUnknownCode(code, form, cache={}):
+ """Check whether an unknown code could be supported.
+
+ We declare a language, script or country code unknown if it's not
+ known to enumdata.py; however, if it's present in main/en.xml's
+ mapping of codes to names, we have the option of adding support.
+ This caches the necessary look-up (so we only read main/en.xml
+ once) and returns the name we should use if we do add support.
+
+ First parameter, code, is the unknown code. Second parameter,
+ form, is one of 'language', 'script' or 'country' to select the
+ type of code to look up. Do not pass further parameters (the next
+ will deprive you of the cache).
+
+ Raises xpathlite.Error with a suitable message, that includes the
+ unknown code's full name if found.
+
+ Relies on global cldr_dir being set before it's called; see tail
+ of this file.
+ """
+ if not cache:
+ cache.update(xpathlite.codeMapsFromFile(os.path.join(cldr_dir, 'en.xml')))
+ name = cache[form].get(code)
+ msg = 'unknown %s code "%s"' % (form, code)
+ if name:
+ msg += ' - could use "%s"' % name
+ raise xpathlite.Error(msg)
+
def parse_list_pattern_part_format(pattern):
# This is a very limited parsing of the format for list pattern part only.
return pattern.replace("{0}", "%1").replace("{1}", "%2").replace("{2}", "%3")
@@ -193,18 +227,18 @@ def _generateLocaleInfo(path, language_code, script_code, country_code, variant_
language_id = enumdata.languageCodeToId(language_code)
if language_id <= 0:
- raise xpathlite.Error('unknown language code "%s"' % language_code)
+ raiseUnknownCode(language_code, 'language')
script_id = enumdata.scriptCodeToId(script_code)
if script_id == -1:
- raise xpathlite.Error('unknown script code "%s"' % script_code)
+ raiseUnknownCode(script_code, 'script')
# we should handle fully qualified names with the territory
if not country_code:
return {}
country_id = enumdata.countryCodeToId(country_code)
if country_id <= 0:
- raise xpathlite.Error('unknown country code "%s"' % country_code)
+ raiseUnknownCode(country_code, 'country')
# So we say we accept only those values that have "contributed" or
# "approved" resolution. see http://www.unicode.org/cldr/process.html
@@ -364,12 +398,12 @@ def _generateLocaleInfo(path, language_code, script_code, country_code, variant_
('narrow', 'format', 'narrow'),
)
- # Month data:
- for cal in ('gregorian',): # We shall want to add to this
+ # Month names for 12-month calendars:
+ for cal in calendars:
stem = 'dates/calendars/calendar[' + cal + ']/months/'
for (key, mode, size) in namings:
prop = 'monthContext[' + mode + ']/monthWidth[' + size + ']/'
- result[key + 'Months'] = ';'.join(
+ result[key + 'Months_' + cal] = ';'.join(
findEntry(path, stem + prop + "month[%d]" % i)
for i in range(1, 13)) + ';'
@@ -655,9 +689,9 @@ if skips:
wrappedwarn('skipping likelySubtags (for unknown language codes): ', skips)
print " <localeList>"
-Locale.C().toXml()
+Locale.C(calendars).toXml(calendars)
for key in locale_keys:
- locale_database[key].toXml()
+ locale_database[key].toXml(calendars)
print " </localeList>"
print "</localeDatabase>"
diff --git a/util/locale_database/cldr2qtimezone.py b/util/locale_database/cldr2qtimezone.py
new file mode 100755
index 0000000000..c240d0d190
--- /dev/null
+++ b/util/locale_database/cldr2qtimezone.py
@@ -0,0 +1,457 @@
+#!/usr/bin/env python2
+#############################################################################
+##
+## Copyright (C) 2016 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+"""Parse CLDR data for QTimeZone use with MS-Windows
+
+Script to parse the CLDR supplemental/windowsZones.xml file and encode
+for use in QTimeZone. See ``./cldr2qlocalexml.py`` for where to get
+the CLDR data. Pass its common/ directory as first parameter to this
+script and the qtbase root directory as second parameter. It shall
+update qtbase's src/corelib/time/qtimezoneprivate_data_p.h ready for
+use.
+
+The XML structure is as follows:
+
+ <supplementalData>
+ <version number="$Revision:...$"/>
+ <generation date="$Date:...$"/>
+ <windowsZones>
+ <mapTimezones otherVersion="..." typeVersion="...">
+ <!-- (UTC-08:00) Pacific Time (US & Canada) -->
+ <mapZone other="Pacific Standard Time" territory="001" type="America/Los_Angeles"/>
+ <mapZone other="Pacific Standard Time" territory="CA" type="America/Vancouver America/Dawson America/Whitehorse"/>
+ <mapZone other="Pacific Standard Time" territory="US" type="America/Los_Angeles America/Metlakatla"/>
+ <mapZone other="Pacific Standard Time" territory="ZZ" type="PST8PDT"/>
+ </mapTimezones>
+ </windowsZones>
+ </supplementalData>
+"""
+
+import os
+import sys
+import datetime
+import tempfile
+import enumdata
+import xpathlite
+from xpathlite import DraftResolution
+import re
+import qlocalexml2cpp
+
+findAlias = xpathlite.findAlias
+findEntry = xpathlite.findEntry
+findEntryInFile = xpathlite._findEntryInFile
+findTagsInFile = xpathlite.findTagsInFile
+unicode2hex = qlocalexml2cpp.unicode2hex
+wrap_list = qlocalexml2cpp.wrap_list
+
+class ByteArrayData:
+ def __init__(self):
+ self.data = []
+ self.hash = {}
+ def append(self, s):
+ s = s + '\0'
+ if s in self.hash:
+ return self.hash[s]
+
+ lst = unicode2hex(s)
+ index = len(self.data)
+ if index > 65535:
+ print "\n\n\n#error Data index is too big!"
+ sys.stderr.write ("\n\n\nERROR: index exceeds the uint16 range! index = %d\n" % index)
+ sys.exit(1)
+ self.hash[s] = index
+ self.data += lst
+ return index
+
+# List of currently known Windows IDs.
+# If this script reports missing IDs, please add them here.
+# Look up the offset using (google and) timeanddate.com.
+# Not public so may safely be changed. Please keep in alphabetic order by ID.
+# ( Windows Id, Offset Seconds )
+windowsIdList = (
+ (u'Afghanistan Standard Time', 16200),
+ (u'Alaskan Standard Time', -32400),
+ (u'Aleutian Standard Time', -36000),
+ (u'Altai Standard Time', 25200),
+ (u'Arab Standard Time', 10800),
+ (u'Arabian Standard Time', 14400),
+ (u'Arabic Standard Time', 10800),
+ (u'Argentina Standard Time', -10800),
+ (u'Astrakhan Standard Time', 14400),
+ (u'Atlantic Standard Time', -14400),
+ (u'AUS Central Standard Time', 34200),
+ (u'Aus Central W. Standard Time', 31500),
+ (u'AUS Eastern Standard Time', 36000),
+ (u'Azerbaijan Standard Time', 14400),
+ (u'Azores Standard Time', -3600),
+ (u'Bahia Standard Time', -10800),
+ (u'Bangladesh Standard Time', 21600),
+ (u'Belarus Standard Time', 10800),
+ (u'Bougainville Standard Time', 39600),
+ (u'Canada Central Standard Time', -21600),
+ (u'Cape Verde Standard Time', -3600),
+ (u'Caucasus Standard Time', 14400),
+ (u'Cen. Australia Standard Time', 34200),
+ (u'Central America Standard Time', -21600),
+ (u'Central Asia Standard Time', 21600),
+ (u'Central Brazilian Standard Time', -14400),
+ (u'Central Europe Standard Time', 3600),
+ (u'Central European Standard Time', 3600),
+ (u'Central Pacific Standard Time', 39600),
+ (u'Central Standard Time (Mexico)', -21600),
+ (u'Central Standard Time', -21600),
+ (u'China Standard Time', 28800),
+ (u'Chatham Islands Standard Time', 45900),
+ (u'Cuba Standard Time', -18000),
+ (u'Dateline Standard Time', -43200),
+ (u'E. Africa Standard Time', 10800),
+ (u'E. Australia Standard Time', 36000),
+ (u'E. Europe Standard Time', 7200),
+ (u'E. South America Standard Time', -10800),
+ (u'Easter Island Standard Time', -21600),
+ (u'Eastern Standard Time', -18000),
+ (u'Eastern Standard Time (Mexico)', -18000),
+ (u'Egypt Standard Time', 7200),
+ (u'Ekaterinburg Standard Time', 18000),
+ (u'Fiji Standard Time', 43200),
+ (u'FLE Standard Time', 7200),
+ (u'Georgian Standard Time', 14400),
+ (u'GMT Standard Time', 0),
+ (u'Greenland Standard Time', -10800),
+ (u'Greenwich Standard Time', 0),
+ (u'GTB Standard Time', 7200),
+ (u'Haiti Standard Time', -18000),
+ (u'Hawaiian Standard Time', -36000),
+ (u'India Standard Time', 19800),
+ (u'Iran Standard Time', 12600),
+ (u'Israel Standard Time', 7200),
+ (u'Jordan Standard Time', 7200),
+ (u'Kaliningrad Standard Time', 7200),
+ (u'Korea Standard Time', 32400),
+ (u'Libya Standard Time', 7200),
+ (u'Line Islands Standard Time', 50400),
+ (u'Lord Howe Standard Time', 37800),
+ (u'Magadan Standard Time', 36000),
+ (u'Magallanes Standard Time', -10800), # permanent DST
+ (u'Marquesas Standard Time', -34200),
+ (u'Mauritius Standard Time', 14400),
+ (u'Middle East Standard Time', 7200),
+ (u'Montevideo Standard Time', -10800),
+ (u'Morocco Standard Time', 0),
+ (u'Mountain Standard Time (Mexico)', -25200),
+ (u'Mountain Standard Time', -25200),
+ (u'Myanmar Standard Time', 23400),
+ (u'N. Central Asia Standard Time', 21600),
+ (u'Namibia Standard Time', 3600),
+ (u'Nepal Standard Time', 20700),
+ (u'New Zealand Standard Time', 43200),
+ (u'Newfoundland Standard Time', -12600),
+ (u'Norfolk Standard Time', 39600),
+ (u'North Asia East Standard Time', 28800),
+ (u'North Asia Standard Time', 25200),
+ (u'North Korea Standard Time', 30600),
+ (u'Omsk Standard Time', 21600),
+ (u'Pacific SA Standard Time', -10800),
+ (u'Pacific Standard Time', -28800),
+ (u'Pacific Standard Time (Mexico)', -28800),
+ (u'Pakistan Standard Time', 18000),
+ (u'Paraguay Standard Time', -14400),
+ (u'Romance Standard Time', 3600),
+ (u'Russia Time Zone 3', 14400),
+ (u'Russia Time Zone 10', 39600),
+ (u'Russia Time Zone 11', 43200),
+ (u'Russian Standard Time', 10800),
+ (u'SA Eastern Standard Time', -10800),
+ (u'SA Pacific Standard Time', -18000),
+ (u'SA Western Standard Time', -14400),
+ (u'Saint Pierre Standard Time', -10800), # New France
+ (u'Sakhalin Standard Time', 39600),
+ (u'Samoa Standard Time', 46800),
+ (u'Sao Tome Standard Time', 0),
+ (u'Saratov Standard Time', 14400),
+ (u'SE Asia Standard Time', 25200),
+ (u'Singapore Standard Time', 28800),
+ (u'South Africa Standard Time', 7200),
+ (u'Sri Lanka Standard Time', 19800),
+ (u'Sudan Standard Time', 7200), # unless they mean South Sudan, +03:00
+ (u'Syria Standard Time', 7200),
+ (u'Taipei Standard Time', 28800),
+ (u'Tasmania Standard Time', 36000),
+ (u'Tocantins Standard Time', -10800),
+ (u'Tokyo Standard Time', 32400),
+ (u'Tomsk Standard Time', 25200),
+ (u'Tonga Standard Time', 46800),
+ (u'Transbaikal Standard Time', 32400), # Yakutsk
+ (u'Turkey Standard Time', 7200),
+ (u'Turks And Caicos Standard Time', -14400),
+ (u'Ulaanbaatar Standard Time', 28800),
+ (u'US Eastern Standard Time', -18000),
+ (u'US Mountain Standard Time', -25200),
+ (u'UTC-11', -39600),
+ (u'UTC-09', -32400),
+ (u'UTC-08', -28800),
+ (u'UTC-02', -7200),
+ (u'UTC', 0),
+ (u'UTC+12', 43200),
+ (u'UTC+13', 46800),
+ (u'Venezuela Standard Time', -16200),
+ (u'Vladivostok Standard Time', 36000),
+ (u'W. Australia Standard Time', 28800),
+ (u'W. Central Africa Standard Time', 3600),
+ (u'W. Europe Standard Time', 3600),
+ (u'W. Mongolia Standard Time', 25200), # Hovd
+ (u'West Asia Standard Time', 18000),
+ (u'West Bank Standard Time', 7200),
+ (u'West Pacific Standard Time', 36000),
+ (u'Yakutsk Standard Time', 32400),
+)
+
+def windowsIdToKey(windowsId):
+ for index, pair in enumerate(windowsIdList):
+ if pair[0] == windowsId:
+ return index + 1
+ return 0
+
+# List of standard UTC IDs to use. Not public so may be safely changed.
+# Do not remove IDs, as each entry is part of the API/behavior guarantee.
+# ( UTC Id, Offset Seconds )
+utcIdList = (
+ (u'UTC', 0), # Goes first so is default
+ (u'UTC-14:00', -50400),
+ (u'UTC-13:00', -46800),
+ (u'UTC-12:00', -43200),
+ (u'UTC-11:00', -39600),
+ (u'UTC-10:00', -36000),
+ (u'UTC-09:00', -32400),
+ (u'UTC-08:00', -28800),
+ (u'UTC-07:00', -25200),
+ (u'UTC-06:00', -21600),
+ (u'UTC-05:00', -18000),
+ (u'UTC-04:30', -16200),
+ (u'UTC-04:00', -14400),
+ (u'UTC-03:30', -12600),
+ (u'UTC-03:00', -10800),
+ (u'UTC-02:00', -7200),
+ (u'UTC-01:00', -3600),
+ (u'UTC-00:00', 0),
+ (u'UTC+00:00', 0),
+ (u'UTC+01:00', 3600),
+ (u'UTC+02:00', 7200),
+ (u'UTC+03:00', 10800),
+ (u'UTC+03:30', 12600),
+ (u'UTC+04:00', 14400),
+ (u'UTC+04:30', 16200),
+ (u'UTC+05:00', 18000),
+ (u'UTC+05:30', 19800),
+ (u'UTC+05:45', 20700),
+ (u'UTC+06:00', 21600),
+ (u'UTC+06:30', 23400),
+ (u'UTC+07:00', 25200),
+ (u'UTC+08:00', 28800),
+ (u'UTC+08:30', 30600),
+ (u'UTC+09:00', 32400),
+ (u'UTC+09:30', 34200),
+ (u'UTC+10:00', 36000),
+ (u'UTC+11:00', 39600),
+ (u'UTC+12:00', 43200),
+ (u'UTC+13:00', 46800),
+ (u'UTC+14:00', 50400),
+)
+
+def usage():
+ print "Usage: cldr2qtimezone.py <path to cldr core/common> <path to qtbase>"
+ sys.exit()
+
+if len(sys.argv) != 3:
+ usage()
+
+cldrPath = sys.argv[1]
+qtPath = sys.argv[2]
+
+if not os.path.isdir(cldrPath) or not os.path.isdir(qtPath):
+ usage()
+
+windowsZonesPath = cldrPath + "/supplemental/windowsZones.xml"
+tempFileDir = qtPath
+dataFilePath = qtPath + "/src/corelib/time/qtimezoneprivate_data_p.h"
+
+if not (os.path.isfile(windowsZonesPath) and os.path.isfile(dataFilePath)):
+ usage()
+
+cldr_version = 'unknown'
+ldml = open(cldrPath + "/dtd/ldml.dtd", "r")
+for line in ldml:
+ if 'version cldrVersion CDATA #FIXED' in line:
+ cldr_version = line.split('"')[1]
+
+# [[u'version', [(u'number', u'$Revision: 7825 $')]]]
+versionNumber = findTagsInFile(windowsZonesPath, "version")[0][1][0][1]
+
+mapTimezones = findTagsInFile(windowsZonesPath, "windowsZones/mapTimezones")
+
+defaultDict = {}
+windowsIdDict = {}
+
+if mapTimezones:
+ badZones = set()
+ for mapZone in mapTimezones:
+ # [u'mapZone', [(u'territory', u'MH'), (u'other', u'UTC+12'), (u'type', u'Pacific/Majuro Pacific/Kwajalein')]]
+ if mapZone[0] == u'mapZone':
+ data = {}
+ for attribute in mapZone[1]:
+ if attribute[0] == u'other':
+ data['windowsId'] = attribute[1]
+ if attribute[0] == u'territory':
+ data['countryCode'] = attribute[1]
+ if attribute[0] == u'type':
+ data['ianaList'] = attribute[1]
+
+ data['windowsKey'] = windowsIdToKey(data['windowsId'])
+ if data['windowsKey'] <= 0:
+ badZones.add(data['windowsId'])
+
+ countryId = 0
+ if data['countryCode'] == u'001':
+ defaultDict[data['windowsKey']] = data['ianaList']
+ else:
+ data['countryId'] = enumdata.countryCodeToId(data['countryCode'])
+ if data['countryId'] < 0:
+ raise xpathlite.Error("Unknown Country Code \"%s\"" % data['countryCode'])
+ data['country'] = enumdata.country_list[data['countryId']][0]
+ windowsIdDict[data['windowsKey'], data['countryId']] = data
+ if badZones:
+ sys.stderr.write('\n\t'.join(["\nUnknown Windows ID, please add:"] + sorted(badZones))
+ + "\nto the windowIdList in cldr2qtimezone.py\n\n")
+ raise xpathlite.Error("Unknown Windows IDs")
+
+print "Input file parsed, now writing data"
+
+GENERATED_BLOCK_START = "// GENERATED PART STARTS HERE\n"
+GENERATED_BLOCK_END = "// GENERATED PART ENDS HERE\n"
+
+# Create a temp file to write the new data into
+(newTempFile, newTempFilePath) = tempfile.mkstemp("qtimezone_data_p", dir=tempFileDir)
+newTempFile = os.fdopen(newTempFile, "w")
+
+# Open the old file and copy over the first non-generated section to the new file
+oldDataFile = open(dataFilePath, "r")
+s = oldDataFile.readline()
+while s and s != GENERATED_BLOCK_START:
+ newTempFile.write(s)
+ s = oldDataFile.readline()
+
+# Write out generated block start tag and warning
+newTempFile.write(GENERATED_BLOCK_START)
+newTempFile.write("""
+/*
+ This part of the file was generated on %s from the
+ Common Locale Data Repository v%s supplemental/windowsZones.xml file %s
+
+ http://www.unicode.org/cldr/
+
+ Do not edit this code: run cldr2qtimezone.py on updated (or
+ edited) CLDR data; see qtbase/util/locale_database/.
+*/
+
+""" % (str(datetime.date.today()), cldr_version, versionNumber) )
+
+windowsIdData = ByteArrayData()
+ianaIdData = ByteArrayData()
+
+# Write Windows/IANA table
+newTempFile.write("// Windows ID Key, Country Enum, IANA ID Index\n")
+newTempFile.write("static const QZoneData zoneDataTable[] = {\n")
+for index in windowsIdDict:
+ data = windowsIdDict[index]
+ newTempFile.write(" { %6d,%6d,%6d }, // %s / %s\n"
+ % (data['windowsKey'],
+ data['countryId'],
+ ianaIdData.append(data['ianaList']),
+ data['windowsId'],
+ data['country']))
+newTempFile.write(" { 0, 0, 0 } // Trailing zeroes\n")
+newTempFile.write("};\n\n")
+
+print "Done Zone Data"
+
+# Write Windows ID key table
+newTempFile.write("// Windows ID Key, Windows ID Index, IANA ID Index, UTC Offset\n")
+newTempFile.write("static const QWindowsData windowsDataTable[] = {\n")
+for index, pair in enumerate(windowsIdList):
+ newTempFile.write(" { %6d,%6d,%6d,%6d }, // %s\n"
+ % (index + 1, windowsIdData.append(pair[0]),
+ ianaIdData.append(defaultDict[index + 1]), pair[1], pair[0]))
+newTempFile.write(" { 0, 0, 0, 0 } // Trailing zeroes\n")
+newTempFile.write("};\n\n")
+
+print "Done Windows Data Table"
+
+# Write UTC ID key table
+newTempFile.write("// IANA ID Index, UTC Offset\n")
+newTempFile.write("static const QUtcData utcDataTable[] = {\n")
+for pair in utcIdList:
+ newTempFile.write(" { %6d,%6d }, // %s\n"
+ % (ianaIdData.append(pair[0]), pair[1], pair[0]))
+newTempFile.write(" { 0, 0 } // Trailing zeroes\n")
+newTempFile.write("};\n\n")
+
+print "Done UTC Data Table"
+
+# Write out Windows ID's data
+newTempFile.write("static const char windowsIdData[] = {\n")
+newTempFile.write(wrap_list(windowsIdData.data))
+newTempFile.write("\n};\n\n")
+
+# Write out IANA ID's data
+newTempFile.write("static const char ianaIdData[] = {\n")
+newTempFile.write(wrap_list(ianaIdData.data))
+newTempFile.write("\n};\n")
+
+print "Done ID Data Table"
+
+# Write out the end of generated block tag
+newTempFile.write(GENERATED_BLOCK_END)
+s = oldDataFile.readline()
+
+# Skip through the old generated data in the old file
+while s and s != GENERATED_BLOCK_END:
+ s = oldDataFile.readline()
+
+# Now copy the rest of the original file into the new file
+s = oldDataFile.readline()
+while s:
+ newTempFile.write(s)
+ s = oldDataFile.readline()
+
+# Now close the old and new file, delete the old file and copy the new file in its place
+newTempFile.close()
+oldDataFile.close()
+os.remove(dataFilePath)
+os.rename(newTempFilePath, dataFilePath)
+
+print "Data generation completed, please check the new file at " + dataFilePath
diff --git a/util/local_database/dateconverter.py b/util/locale_database/dateconverter.py
index 1990fe0c61..1990fe0c61 100755
--- a/util/local_database/dateconverter.py
+++ b/util/locale_database/dateconverter.py
diff --git a/util/local_database/enumdata.py b/util/locale_database/enumdata.py
index 26bb74d1fe..0e40d8a9ee 100644
--- a/util/local_database/enumdata.py
+++ b/util/locale_database/enumdata.py
@@ -402,6 +402,8 @@ language_list = {
362: ["Sicilian", "scn"],
363: ["Southern Kurdish", "sdh"],
364: ["Western Balochi", "bgn"],
+ 365: ["Cebuano", "ceb"],
+ 366: ["Erzya", "myv"],
}
language_aliases = {
diff --git a/util/local_database/formattags.txt b/util/locale_database/formattags.txt
index 5138c37a81..5138c37a81 100644
--- a/util/local_database/formattags.txt
+++ b/util/locale_database/formattags.txt
diff --git a/util/local_database/localexml.py b/util/locale_database/localexml.py
index e95b3aebcc..9b353f5122 100644
--- a/util/local_database/localexml.py
+++ b/util/locale_database/localexml.py
@@ -1,6 +1,7 @@
+# coding=utf8
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of the Qt Toolkit.
@@ -113,12 +114,11 @@ def convertFormat(format):
return result
class Locale:
- # Tool used during class body (see del below), not method:
- def propsMonthDay(lengths=('long', 'short', 'narrow'), scale=('months', 'days')):
+ @staticmethod
+ def propsMonthDay(scale, lengths=('long', 'short', 'narrow')):
for L in lengths:
- for S in scale:
- yield camelCase((L, S))
- yield camelCase(('standalone', L, S))
+ yield camelCase((L, scale))
+ yield camelCase(('standalone', L, scale))
# Expected to be numbers, read with int():
__asint = ("decimal", "group", "zero",
@@ -137,15 +137,13 @@ class Locale:
"listPatternPartEnd", "listPatternPartTwo", "am", "pm",
'byte_unit', 'byte_si_quantified', 'byte_iec_quantified',
"currencyIsoCode", "currencySymbol", "currencyDisplayName",
- "currencyFormat", "currencyNegativeFormat"
- ) + tuple(propsMonthDay())
- del propsMonthDay
+ "currencyFormat", "currencyNegativeFormat")
# Day-of-Week numbering used by Qt:
__qDoW = {"mon": 1, "tue": 2, "wed": 3, "thu": 4, "fri": 5, "sat": 6, "sun": 7}
@classmethod
- def fromXmlData(cls, lookup):
+ def fromXmlData(cls, lookup, calendars=('gregorian',)):
"""Constructor from the contents of XML elements.
Single parameter, lookup, is called with the names of XML
@@ -170,12 +168,15 @@ class Locale:
for k in cls.__asfmt:
data[k] = convertFormat(lookup(k))
- for k in cls.__astxt:
+ for k in cls.__astxt + tuple(cls.propsMonthDay('days')):
data[k] = lookup(k)
+ for k in cls.propsMonthDay('months'):
+ data[k] = dict((cal, lookup('_'.join((k, cal)))) for cal in calendars)
+
return cls(data)
- def toXml(self, indent=' ', tab=' '):
+ def toXml(self, calendars=('gregorian',), indent=' ', tab=' '):
print indent + '<locale>'
inner = indent + tab
get = lambda k: getattr(self, k)
@@ -199,13 +200,14 @@ class Locale:
'weekendStart', 'weekendEnd',
'longDateFormat', 'shortDateFormat',
'longTimeFormat', 'shortTimeFormat',
- 'standaloneLongMonths', 'standaloneShortMonths',
- 'standaloneNarrowMonths',
- 'longMonths', 'shortMonths', 'narrowMonths',
'longDays', 'shortDays', 'narrowDays',
'standaloneLongDays', 'standaloneShortDays', 'standaloneNarrowDays',
'currencyIsoCode', 'currencySymbol', 'currencyDisplayName',
- 'currencyFormat', 'currencyNegativeFormat'):
+ 'currencyFormat', 'currencyNegativeFormat'
+ ) + tuple(self.propsMonthDay('days')) + tuple(
+ '_'.join((k, cal))
+ for k in self.propsMonthDay('months')
+ for cal in calendars):
ent = camelCase(key.split('_')) if key.endswith('_endonym') else key
print inner + "<%s>%s</%s>" % (ent, escape(get(key)).encode('utf-8'), ent)
@@ -218,16 +220,70 @@ class Locale:
if data: self.__dict__.update(data)
if kw: self.__dict__.update(kw)
+ # Tools used by __monthNames:
+ def fullName(i, name): return name
+ def firstThree(i, name): return name[:3]
+ def initial(i, name): return name[:1]
+ def number(i, name): return str(i + 1)
+ def islamicShort(i, name):
+ if not name: return name
+ if name == 'Shawwal': return 'Shaw.'
+ words = name.split()
+ if words[0].startswith('Dhu'):
+ words[0] = words[0][:7] + '.'
+ elif len(words[0]) > 3:
+ words[0] = words[0][:3] + '.'
+ return ' '.join(words)
+ @staticmethod
+ def __monthNames(calendars,
+ known={ # Map calendar to (names, extractors...):
+ 'gregorian': (('January', 'February', 'March', 'April', 'May', 'June', 'July',
+ 'August', 'September', 'October', 'November', 'December'),
+ # Extractor pairs, (plain, standalone)
+ (fullName, fullName), # long
+ (firstThree, firstThree), # short
+ (number, initial)), # narrow
+ 'persian': (('Farvardin', 'Ordibehesht', 'Khordad', 'Tir', 'Mordad',
+ 'Shahrivar', 'Mehr', 'Aban', 'Azar', 'Dey', 'Bahman', 'Esfand'),
+ (fullName, fullName),
+ (firstThree, firstThree),
+ (number, initial)),
+ 'islamic': ((u'Muharram', u'Safar', u'Rabiʻ I', u'Rabiʻ II', u'Jumada I',
+ u'Jumada II', u'Rajab', u'Shaʻban', u'Ramadan', u'Shawwal',
+ u'Dhuʻl-Qiʻdah', u'Dhuʻl-Hijjah'),
+ (fullName, fullName),
+ (islamicShort, islamicShort),
+ (number, number)),
+ 'hebrew': (('Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar I',
+ 'Adar', 'Nisan', 'Iyar', 'Sivan', 'Tamuz', 'Av'),
+ (fullName, fullName),
+ (fullName, fullName),
+ (number, number)),
+ },
+ sizes=('long', 'short', 'narrow')):
+ for cal in calendars:
+ try:
+ data = known[cal]
+ except KeyError: # Need to add an entry to known, above.
+ print 'Unsupported calendar:', cal
+ raise
+ names, get = data[0] + ('',), data[1:]
+ for n, size in enumerate(sizes):
+ yield ('_'.join((camelCase((size, 'months')), cal)),
+ ';'.join(get[n][0](i, x) for i, x in enumerate(names)))
+ yield ('_'.join((camelCase(('standalone', size, 'months')), cal)),
+ ';'.join(get[n][1](i, x) for i, x in enumerate(names)))
+ del fullName, firstThree, initial, number, islamicShort
+
@classmethod
- def C(cls,
- # Empty entries at end to ensure final separator when join()ed:
- months = ('January', 'February', 'March', 'April', 'May', 'June', 'July',
- 'August', 'September', 'October', 'November', 'December', ''),
+ def C(cls, calendars=('gregorian',),
+ # Empty entry at end to ensure final separator when join()ed:
days = ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday', ''),
quantifiers=('k', 'M', 'G', 'T', 'P', 'E')):
"""Returns an object representing the C locale."""
- return cls(language='C', language_code='0', language_endonym='',
+ return cls(dict(cls.__monthNames(calendars)),
+ language='C', language_code='0', language_endonym='',
script='AnyScript', script_code='0',
country='AnyCountry', country_code='0', country_endonym='',
decimal='.', group=',', list=';', percent='%',
@@ -245,12 +301,6 @@ class Locale:
weekendStart='sat', weekendEnd='sun',
longDateFormat='EEEE, d MMMM yyyy', shortDateFormat='d MMM yyyy',
longTimeFormat='HH:mm:ss z', shortTimeFormat='HH:mm:ss',
- longMonths=';'.join(months),
- shortMonths=';'.join(m[:3] for m in months),
- narrowMonths='1;2;3;4;5;6;7;8;9;10;11;12;',
- standaloneLongMonths=';'.join(months),
- standaloneShortMonths=';'.join(m[:3] for m in months),
- standaloneNarrowMonths=';'.join(m[:1] for m in months),
longDays=';'.join(days),
shortDays=';'.join(d[:3] for d in days),
narrowDays='7;1;2;3;4;5;6;',
diff --git a/util/local_database/qlocalexml2cpp.py b/util/locale_database/qlocalexml2cpp.py
index fb5ae5ba54..a5ff7ebbf4 100755
--- a/util/local_database/qlocalexml2cpp.py
+++ b/util/locale_database/qlocalexml2cpp.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of the Qt Toolkit.
@@ -42,6 +42,24 @@ from enumdata import language_aliases, country_aliases, script_aliases
from localexml import Locale
+# TODO: Make calendars a command-line parameter
+# map { CLDR name: Qt file name }
+calendars = {'gregorian': 'roman', 'persian': 'jalali', 'islamic': 'hijri',} # 'hebrew': 'hebrew',
+
+generated_template = """
+/*
+ This part of the file was generated on %s from the
+ Common Locale Data Repository v%s
+
+ http://www.unicode.org/cldr/
+
+ Do not edit this section: instead regenerate it using
+ cldr2qlocalexml.py and qlocalexml2cpp.py on updated (or
+ edited) CLDR data; see qtbase/util/locale_database/.
+*/
+
+"""
+
class Error:
def __init__(self, msg):
self.msg = msg
@@ -151,7 +169,7 @@ def loadLocaleMap(doc, language_map, script_map, country_map, likely_subtags_map
result = {}
for locale_elt in eachEltInGroup(doc.documentElement, "localeList", "locale"):
- locale = Locale.fromXmlData(lambda k: firstChildText(locale_elt, k))
+ locale = Locale.fromXmlData(lambda k: firstChildText(locale_elt, k), calendars.keys())
language_id = languageNameToId(locale.language, language_map)
if language_id == -1:
sys.stderr.write("Cannot find a language id for '%s'\n" % locale.language)
@@ -254,6 +272,7 @@ class StringData:
self.data = []
self.hash = {}
self.name = name
+
def append(self, s):
if s in self.hash:
return self.hash[s]
@@ -279,6 +298,11 @@ class StringData:
self.data += lst
return token
+ def write(self, fd):
+ fd.write("\nstatic const ushort %s[] = {\n" % self.name)
+ fd.write(wrap_list(self.data))
+ fd.write("\n};\n")
+
def escapedString(s):
result = ""
i = 0
@@ -339,7 +363,7 @@ def main():
(data_temp_file, data_temp_file_path) = tempfile.mkstemp("qlocale_data_p", dir=qtsrcdir)
data_temp_file = os.fdopen(data_temp_file, "w")
- qlocaledata_file = open(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h", "r")
+ qlocaledata_file = open(qtsrcdir + "/src/corelib/text/qlocale_data_p.h", "r")
s = qlocaledata_file.readline()
while s and s != GENERATED_BLOCK_START:
data_temp_file.write(s)
@@ -360,20 +384,7 @@ def main():
dupes = findDupes(language_map, country_map)
cldr_version = firstChildText(doc.documentElement, "version")
-
- data_temp_file.write("""
-/*
- This part of the file was generated on %s from the
- Common Locale Data Repository v%s
-
- http://www.unicode.org/cldr/
-
- Do not edit this section: instead regenerate it using
- cldr2qlocalexml.py and qlocalexml2cpp.py on updated (or
- edited) CLDR data; see qtbase/util/local_database/.
-*/
-
-""" % (str(datetime.date.today()), cldr_version) )
+ data_temp_file.write(generated_template % (datetime.date.today(), cldr_version))
# Likely subtags map
data_temp_file.write("static const QLocaleId likely_subtags[] = {\n")
@@ -442,7 +453,6 @@ def main():
list_pattern_part_data = StringData('list_pattern_part_data')
date_format_data = StringData('date_format_data')
time_format_data = StringData('time_format_data')
- months_data = StringData('months_data')
days_data = StringData('days_data')
am_data = StringData('am_data')
pm_data = StringData('pm_data')
@@ -482,12 +492,6 @@ def main():
+ ' lDtFmt '
+ ' sTmFmt ' # Time format
+ ' lTmFmt '
- + ' ssMonth ' # Months
- + ' slMonth '
- + ' snMonth '
- + ' sMonth '
- + ' lMonth '
- + ' nMonth '
+ ' ssDays ' # Days
+ ' slDays '
+ ' snDays '
@@ -532,7 +536,7 @@ def main():
# Quotation marks:
+ '%8d,' * 4
# List patterns, date/time formats, month/day names, am/pm:
- + '%11s,' * 22
+ + '%11s,' * 16
# SI/IEC byte-unit abbreviations:
+ '%8s,' * 3
# Currency ISO code:
@@ -568,12 +572,6 @@ def main():
date_format_data.append(l.longDateFormat),
time_format_data.append(l.shortTimeFormat),
time_format_data.append(l.longTimeFormat),
- months_data.append(l.standaloneShortMonths),
- months_data.append(l.standaloneLongMonths),
- months_data.append(l.standaloneNarrowMonths),
- months_data.append(l.shortMonths),
- months_data.append(l.longMonths),
- months_data.append(l.narrowMonths),
days_data.append(l.standaloneShortDays),
days_data.append(l.standaloneLongDays),
days_data.append(l.standaloneNarrowDays),
@@ -599,7 +597,7 @@ def main():
l.weekendEnd)
+ ", // %s/%s/%s\n" % (l.language, l.script, l.country))
data_temp_file.write(line_format # All zeros, matching the format:
- % ( (0,) * (3 + 8 + 4) + ("0,0",) * (22 + 3)
+ % ( (0,) * (3 + 8 + 4) + ("0,0",) * (16 + 3)
+ (currencyIsoCodeData(0),)
+ ("0,0",) * 6 + (0,) * (2 + 3))
+ " // trailing 0s\n")
@@ -607,13 +605,11 @@ def main():
# StringData tables:
for data in (list_pattern_part_data, date_format_data,
- time_format_data, months_data, days_data,
+ time_format_data, days_data,
byte_unit_data, am_data, pm_data, currency_symbol_data,
currency_display_name_data, currency_format_data,
endonyms_data):
- data_temp_file.write("\nstatic const ushort %s[] = {\n" % data.name)
- data_temp_file.write(wrap_list(data.data))
- data_temp_file.write("\n};\n")
+ data.write(data_temp_file)
data_temp_file.write("\n")
@@ -735,14 +731,70 @@ def main():
data_temp_file.close()
qlocaledata_file.close()
- os.remove(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h")
- os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale_data_p.h")
+ os.remove(qtsrcdir + "/src/corelib/text/qlocale_data_p.h")
+ os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale_data_p.h")
+
+ # Generate calendar data
+ calendar_format = ' {%6d,%6d,%6d,{%5s},{%5s},{%5s},{%5s},{%5s},{%5s}}, '
+ for calendar, stem in calendars.items():
+ months_data = StringData('months_data')
+ calendar_data_file = "q%scalendar_data_p.h" % stem
+ calendar_template_file = open(os.path.join(qtsrcdir, 'src', 'corelib', 'time',
+ calendar_data_file), "r")
+ (calendar_temp_file, calendar_temp_file_path) = tempfile.mkstemp(calendar_data_file, dir=qtsrcdir)
+ calendar_temp_file = os.fdopen(calendar_temp_file, "w")
+ s = calendar_template_file.readline()
+ while s and s != GENERATED_BLOCK_START:
+ calendar_temp_file.write(s)
+ s = calendar_template_file.readline()
+ calendar_temp_file.write(GENERATED_BLOCK_START)
+ calendar_temp_file.write(generated_template % (datetime.date.today(), cldr_version))
+ calendar_temp_file.write("static const QCalendarLocale locale_data[] = {\n")
+ calendar_temp_file.write(' // '
+ # IDs, width 7 (6 + comma)
+ + ' lang '
+ + ' script'
+ + ' terr '
+ # Month-name start-end pairs, width 8 (5 plus '{},'):
+ + ' sShort '
+ + ' sLong '
+ + ' sNarrow'
+ + ' short '
+ + ' long '
+ + ' narrow'
+ # No trailing space on last; be sure
+ # to pad before adding later entries.
+ + '\n')
+ for key in locale_keys:
+ l = locale_map[key]
+ calendar_temp_file.write(
+ calendar_format
+ % (key[0], key[1], key[2],
+ months_data.append(l.standaloneShortMonths[calendar]),
+ months_data.append(l.standaloneLongMonths[calendar]),
+ months_data.append(l.standaloneNarrowMonths[calendar]),
+ months_data.append(l.shortMonths[calendar]),
+ months_data.append(l.longMonths[calendar]),
+ months_data.append(l.narrowMonths[calendar]))
+ + "// %s/%s/%s\n " % (l.language, l.script, l.country))
+ calendar_temp_file.write(calendar_format % ( (0,) * 3 + ('0,0',) * 6 )
+ + '// trailing zeros\n')
+ calendar_temp_file.write("};\n")
+ months_data.write(calendar_temp_file)
+ s = calendar_template_file.readline()
+ while s and s != GENERATED_BLOCK_END:
+ s = calendar_template_file.readline()
+ while s:
+ calendar_temp_file.write(s)
+ s = calendar_template_file.readline()
+ os.rename(calendar_temp_file_path,
+ os.path.join(qtsrcdir, 'src', 'corelib', 'time', calendar_data_file))
# qlocale.h
(qlocaleh_temp_file, qlocaleh_temp_file_path) = tempfile.mkstemp("qlocale.h", dir=qtsrcdir)
qlocaleh_temp_file = os.fdopen(qlocaleh_temp_file, "w")
- qlocaleh_file = open(qtsrcdir + "/src/corelib/tools/qlocale.h", "r")
+ qlocaleh_file = open(qtsrcdir + "/src/corelib/text/qlocale.h", "r")
s = qlocaleh_file.readline()
while s and s != GENERATED_BLOCK_START:
qlocaleh_temp_file.write(s)
@@ -808,14 +860,14 @@ def main():
qlocaleh_temp_file.close()
qlocaleh_file.close()
- os.remove(qtsrcdir + "/src/corelib/tools/qlocale.h")
- os.rename(qlocaleh_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.h")
+ os.remove(qtsrcdir + "/src/corelib/text/qlocale.h")
+ os.rename(qlocaleh_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale.h")
# qlocale.qdoc
(qlocaleqdoc_temp_file, qlocaleqdoc_temp_file_path) = tempfile.mkstemp("qlocale.qdoc", dir=qtsrcdir)
qlocaleqdoc_temp_file = os.fdopen(qlocaleqdoc_temp_file, "w")
- qlocaleqdoc_file = open(qtsrcdir + "/src/corelib/tools/qlocale.qdoc", "r")
+ qlocaleqdoc_file = open(qtsrcdir + "/src/corelib/text/qlocale.qdoc", "r")
s = qlocaleqdoc_file.readline()
DOCSTRING = " QLocale's data is based on Common Locale Data Repository "
while s:
@@ -827,8 +879,8 @@ def main():
qlocaleqdoc_temp_file.close()
qlocaleqdoc_file.close()
- os.remove(qtsrcdir + "/src/corelib/tools/qlocale.qdoc")
- os.rename(qlocaleqdoc_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.qdoc")
+ os.remove(qtsrcdir + "/src/corelib/text/qlocale.qdoc")
+ os.rename(qlocaleqdoc_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale.qdoc")
if __name__ == "__main__":
main()
diff --git a/util/local_database/testlocales/localemodel.cpp b/util/locale_database/testlocales/localemodel.cpp
index d380d01e09..d380d01e09 100644
--- a/util/local_database/testlocales/localemodel.cpp
+++ b/util/locale_database/testlocales/localemodel.cpp
diff --git a/util/local_database/testlocales/localemodel.h b/util/locale_database/testlocales/localemodel.h
index b24fc5f4c6..b24fc5f4c6 100644
--- a/util/local_database/testlocales/localemodel.h
+++ b/util/locale_database/testlocales/localemodel.h
diff --git a/util/local_database/testlocales/localewidget.cpp b/util/locale_database/testlocales/localewidget.cpp
index 3ff7f73a98..3ff7f73a98 100644
--- a/util/local_database/testlocales/localewidget.cpp
+++ b/util/locale_database/testlocales/localewidget.cpp
diff --git a/util/local_database/testlocales/localewidget.h b/util/locale_database/testlocales/localewidget.h
index 896a6e5229..896a6e5229 100644
--- a/util/local_database/testlocales/localewidget.h
+++ b/util/locale_database/testlocales/localewidget.h
diff --git a/util/local_database/testlocales/main.cpp b/util/locale_database/testlocales/main.cpp
index 0c3c45f989..0c3c45f989 100644
--- a/util/local_database/testlocales/main.cpp
+++ b/util/locale_database/testlocales/main.cpp
diff --git a/util/local_database/testlocales/testlocales.pro b/util/locale_database/testlocales/testlocales.pro
index a9a6247f96..a9a6247f96 100644
--- a/util/local_database/testlocales/testlocales.pro
+++ b/util/locale_database/testlocales/testlocales.pro
diff --git a/util/local_database/xpathlite.py b/util/locale_database/xpathlite.py
index 218135d7a7..97efaaab41 100644
--- a/util/local_database/xpathlite.py
+++ b/util/locale_database/xpathlite.py
@@ -78,14 +78,38 @@ def findChild(parent, tag_name, arg_name=None, arg_value=None, draft=None):
return node
return False
+def codeMapsFromFile(file):
+ """Extract mappings of language, script and country codes to names.
+
+ The file shall typically be common/main/en.xml, which contains a
+ localeDisplayNames element with children languages, scripts and
+ territories; each element in each of these has a code as its type
+ attribute and its name as element content. This returns a mapping
+ withe keys 'language', 'script' and 'country', each of which
+ has, as value, a mapping of the relevant codes to names.
+ """
+ parent = findChild(findChild(parseDoc(file), 'ldml'), 'localeDisplayNames')
+ keys, result = {'languages': 'language', 'scripts': 'script', 'territories': 'country'}, {}
+ for src, dst in keys.items():
+ child = findChild(parent, src)
+ data = result[dst] = {}
+ for elt in child.childNodes:
+ if elt.attributes and elt.attributes.has_key('type'):
+ key, value = elt.attributes['type'].value, elt.childNodes[0].wholeText
+ # Don't over-write previously-read data for an alt form:
+ if elt.attributes.has_key('alt') and data.has_key(key):
+ continue
+ data[key] = value
+
+ return result
+
def findTagsInFile(file, path):
doc = parseDoc(file)
elt = doc.documentElement
tag_spec_list = path.split("/")
last_entry = None
- for i in range(len(tag_spec_list)):
- tag_spec = tag_spec_list[i]
+ for tag_spec in tag_spec_list:
tag_name = tag_spec
arg_name = 'type'
arg_value = ''
diff --git a/util/qfloat16-tables/gen_qfloat16_tables.cpp b/util/qfloat16-tables/gen_qfloat16_tables.cpp
new file mode 100644
index 0000000000..faedb5073c
--- /dev/null
+++ b/util/qfloat16-tables/gen_qfloat16_tables.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 by Southwest Research Institute (R)
+** Copyright (C) 2019 Intel Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+
+/*
+ * This tool generates the tables used by qfloat16 to implement a
+ * software-emulated version of IEEE 754 binary16. qfloat16 automatically uses
+ * CPU instructions to convert to and from float (IEEE 754 binary32), but if
+ * the CPU is not guaranteed to have those instructions available at compile
+ * time, then qfloat16 needs the tables to perform the conversion with
+ * reasonable performance.
+ *
+ * Because Qt requires float to be IEEE 754 binary32, these tables are
+ * platform-independent and will never change.
+ */
+
+uint32_t convertmantissa(int32_t i)
+{
+ uint32_t m = i << 13; // Zero pad mantissa bits
+ uint32_t e = 0; // Zero exponent
+
+ while (!(m & 0x00800000)) { // While not normalized
+ e -= 0x00800000; // Decrement exponent (1<<23)
+ m <<= 1; // Shift mantissa
+ }
+ m &= ~0x00800000; // Clear leading 1 bit
+ e += 0x38800000; // Adjust bias ((127-14)<<23)
+ return m | e; // Return combined number
+}
+
+// we first build these tables up and then print them out as a separate step in order
+// to more closely map the implementation given in the paper.
+uint32_t basetable[512];
+uint32_t shifttable[512];
+
+int main()
+{
+ uint32_t i;
+
+ printf("/* This file was generated by util/qfloat16-tables/gen_qfloat16_tables.cpp */\n\n");
+ printf("#include <QtCore/qfloat16.h>\n\n");
+
+ printf("QT_BEGIN_NAMESPACE\n\n");
+ printf("#if !defined(__F16C__) && !defined(__ARM_FP16_FORMAT_IEEE)\n\n");
+
+ printf("const quint32 qfloat16::mantissatable[2048] = {\n");
+ printf("0,\n");
+ for (i = 1; i < 1024; i++)
+ printf("0x%XU,\n", convertmantissa(i));
+ for (i = 1024; i < 2048; i++)
+ printf("0x%XU,\n", 0x38000000U + ((i - 1024) << 13));
+ printf("};\n\n");
+
+ printf("const quint32 qfloat16::exponenttable[64] = {\n");
+ printf("0,\n");
+ for (i = 1; i < 31; i++)
+ printf("0x%XU,\n", i << 23);
+ printf("0x47800000U,\n"); // 31
+ printf("0x80000000U,\n"); // 32
+ for (i = 33; i < 63; i++)
+ printf("0x%XU,\n", 0x80000000U + ((i - 32) << 23));
+ printf("0xC7800000U,\n"); // 63
+ printf("};\n\n");
+
+ printf("const quint32 qfloat16::offsettable[64] = {\n");
+ printf("0,\n");
+ for (i = 1; i < 32; i++)
+ printf("1024U,\n");
+ printf("0,\n");
+ for (i = 33; i < 64; i++)
+ printf("1024U,\n");
+ printf("};\n\n");
+
+ int32_t e;
+ for (i = 0; i < 256; ++i) {
+ e = i - 127;
+ if (e < -24) { // Very small numbers map to zero
+ basetable[i | 0x000] = 0x0000;
+ basetable[i | 0x100] = 0x8000;
+ shifttable[i | 0x000] = 24;
+ shifttable[i | 0x100] = 24;
+
+ } else if (e < -14) { // Small numbers map to denorms
+ basetable[i | 0x000] = (0x0400 >> (-e - 14));
+ basetable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;
+ shifttable[i | 0x000] = -e - 1;
+ shifttable[i | 0x100] = -e - 1;
+
+ } else if (e <= 15) { // Normal numbers just lose precision
+ basetable[i | 0x000] = ((e + 15) << 10);
+ basetable[i | 0x100] = ((e + 15) << 10) | 0x8000;
+ shifttable[i | 0x000] = 13;
+ shifttable[i | 0x100] = 13;
+
+ } else if (e < 128) { // Large numbers map to Infinity
+ basetable[i | 0x000] = 0x7C00;
+ basetable[i | 0x100] = 0xFC00;
+ shifttable[i | 0x000] = 24;
+ shifttable[i | 0x100] = 24;
+
+ } else { // Infinity and NaN's stay Infinity and NaN's
+ basetable[i | 0x000] = 0x7C00;
+ basetable[i | 0x100] = 0xFC00;
+ shifttable[i | 0x000] = 13;
+ shifttable[i | 0x100] = 13;
+ }
+ }
+
+ printf("const quint32 qfloat16::basetable[512] = {\n");
+ for (i = 0; i < 512; i++)
+ printf("0x%XU,\n", basetable[i]);
+
+ printf("};\n\n");
+
+ printf("const quint32 qfloat16::shifttable[512] = {\n");
+ for (i = 0; i < 512; i++)
+ printf("0x%XU,\n", shifttable[i]);
+
+ printf("};\n\n");
+
+ printf("#endif // !__F16C__ && !__ARM_FP16_FORMAT_IEEE\n\n");
+ printf("QT_END_NAMESPACE\n");
+ return 0;
+}
diff --git a/util/qfloat16-tables/qfloat16-tables.pro b/util/qfloat16-tables/qfloat16-tables.pro
new file mode 100644
index 0000000000..3c9a1e61a3
--- /dev/null
+++ b/util/qfloat16-tables/qfloat16-tables.pro
@@ -0,0 +1,2 @@
+QT = core
+SOURCES += gen_qfloat16_tables.cpp
diff --git a/util/unicode/README b/util/unicode/README
index e52f26175a..87f055d42d 100644
--- a/util/unicode/README
+++ b/util/unicode/README
@@ -19,7 +19,7 @@ To update:
need to be expanded, for example. In some cases QChar may need
additions to some of its enums.
* Build with the modified code, fix any compilation issues.
-* That may have updated qtbase/src/corelib/tools/qunicodetables.cpp;
+* That may have updated qtbase/src/corelib/text/qunicodetables.cpp;
if so the update matters; be sure to commit the changes to data/ at
the same time and update tools/qt_attribution.json to match; use the
UCD Revision number, rather than the Unicode standard number, as the
diff --git a/util/unicode/codecs/big5/main.cpp b/util/unicode/codecs/big5/main.cpp
index 142db74ffd..54d3839755 100644
--- a/util/unicode/codecs/big5/main.cpp
+++ b/util/unicode/codecs/big5/main.cpp
@@ -128,7 +128,7 @@ int main(int argc, char **argv)
list += QByteArray(" { 0x" + QByteArray::number(m.b5, 16) + ", 0x" + QByteArray::number(m.uc, 16) + " }\n");;
}
QByteArray ba;
- qSort(list);
+ std::sort(list.begin(), list.end());
foreach(QByteArray a, list)
ba += a;
qDebug() << "struct B5Map b5_to_uc_map = {\n" << ba + "\n};";
@@ -138,7 +138,7 @@ int main(int argc, char **argv)
if (!b5_ok.contains(m.uc))
list += QByteArray(" { 0x" + QByteArray::number(m.uc, 16) + ", 0x" + QByteArray::number(m.b5, 16) + " }\n");;
ba = QByteArray();
- qSort(list);
+ std::sort(list.begin(), list.end());;
foreach(QByteArray a, list)
ba += a;
qDebug() << "struct B5Map uc_to_b5_map = {\n" << ba + "\n};";
diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp
index 22a4405ca9..26cdab87d6 100644
--- a/util/unicode/main.cpp
+++ b/util/unicode/main.cpp
@@ -789,6 +789,15 @@ static void initScriptMap()
// Keep this one in sync with the code in createPropertyInfo
static const char *property_string =
+ "enum Case {\n"
+ " LowerCase,\n"
+ " UpperCase,\n"
+ " TitleCase,\n"
+ " CaseFold,\n"
+ "\n"
+ " NumCases\n"
+ "};\n"
+ "\n"
"struct Properties {\n"
" ushort category : 8; /* 5 used */\n"
" ushort direction : 8; /* 5 used */\n"
@@ -796,84 +805,51 @@ static const char *property_string =
" ushort joining : 3;\n"
" signed short digitValue : 5;\n"
" signed short mirrorDiff : 16;\n"
- " ushort lowerCaseSpecial : 1;\n"
- " signed short lowerCaseDiff : 15;\n"
+ " ushort unicodeVersion : 8; /* 5 used */\n"
+ " ushort nfQuickCheck : 8;\n" // could be narrowed
"#ifdef Q_OS_WASM\n"
" unsigned char : 0; //wasm 64 packing trick\n"
"#endif\n"
- " ushort upperCaseSpecial : 1;\n"
- " signed short upperCaseDiff : 15;\n"
- " ushort titleCaseSpecial : 1;\n"
- " signed short titleCaseDiff : 15;\n"
- " ushort caseFoldSpecial : 1;\n"
- " signed short caseFoldDiff : 15;\n"
- " ushort unicodeVersion : 8; /* 5 used */\n"
- " ushort nfQuickCheck : 8;\n" // could be narrowed
+ " struct {\n"
+ " ushort special : 1;\n"
+ " signed short diff : 15;\n"
+ " } cases[NumCases];\n"
"#ifdef Q_OS_WASM\n"
" unsigned char : 0; //wasm 64 packing trick\n"
"#endif\n"
" ushort graphemeBreakClass : 5; /* 5 used */\n"
" ushort wordBreakClass : 5; /* 5 used */\n"
- " ushort sentenceBreakClass : 8; /* 4 used */\n"
" ushort lineBreakClass : 6; /* 6 used */\n"
+ " ushort sentenceBreakClass : 8; /* 4 used */\n"
" ushort script : 8;\n"
"};\n\n"
- "Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4) Q_DECL_NOTHROW;\n"
- "Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2) Q_DECL_NOTHROW;\n"
- "\n"
- "struct LowercaseTraits\n"
- "{\n"
- " static inline signed short caseDiff(const Properties *prop)\n"
- " { return prop->lowerCaseDiff; }\n"
- " static inline bool caseSpecial(const Properties *prop)\n"
- " { return prop->lowerCaseSpecial; }\n"
- "};\n"
- "\n"
- "struct UppercaseTraits\n"
- "{\n"
- " static inline signed short caseDiff(const Properties *prop)\n"
- " { return prop->upperCaseDiff; }\n"
- " static inline bool caseSpecial(const Properties *prop)\n"
- " { return prop->upperCaseSpecial; }\n"
- "};\n"
- "\n"
- "struct TitlecaseTraits\n"
- "{\n"
- " static inline signed short caseDiff(const Properties *prop)\n"
- " { return prop->titleCaseDiff; }\n"
- " static inline bool caseSpecial(const Properties *prop)\n"
- " { return prop->titleCaseSpecial; }\n"
- "};\n"
- "\n"
- "struct CasefoldTraits\n"
- "{\n"
- " static inline signed short caseDiff(const Properties *prop)\n"
- " { return prop->caseFoldDiff; }\n"
- " static inline bool caseSpecial(const Properties *prop)\n"
- " { return prop->caseFoldSpecial; }\n"
- "};\n"
+ "Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4) noexcept;\n"
+ "Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2) noexcept;\n"
"\n";
static const char *methods =
- "Q_CORE_EXPORT GraphemeBreakClass QT_FASTCALL graphemeBreakClass(uint ucs4) Q_DECL_NOTHROW;\n"
- "inline GraphemeBreakClass graphemeBreakClass(QChar ch) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT GraphemeBreakClass QT_FASTCALL graphemeBreakClass(uint ucs4) noexcept;\n"
+ "inline GraphemeBreakClass graphemeBreakClass(QChar ch) noexcept\n"
"{ return graphemeBreakClass(ch.unicode()); }\n"
"\n"
- "Q_CORE_EXPORT WordBreakClass QT_FASTCALL wordBreakClass(uint ucs4) Q_DECL_NOTHROW;\n"
- "inline WordBreakClass wordBreakClass(QChar ch) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT WordBreakClass QT_FASTCALL wordBreakClass(uint ucs4) noexcept;\n"
+ "inline WordBreakClass wordBreakClass(QChar ch) noexcept\n"
"{ return wordBreakClass(ch.unicode()); }\n"
"\n"
- "Q_CORE_EXPORT SentenceBreakClass QT_FASTCALL sentenceBreakClass(uint ucs4) Q_DECL_NOTHROW;\n"
- "inline SentenceBreakClass sentenceBreakClass(QChar ch) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT SentenceBreakClass QT_FASTCALL sentenceBreakClass(uint ucs4) noexcept;\n"
+ "inline SentenceBreakClass sentenceBreakClass(QChar ch) noexcept\n"
"{ return sentenceBreakClass(ch.unicode()); }\n"
"\n"
- "Q_CORE_EXPORT LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4) Q_DECL_NOTHROW;\n"
- "inline LineBreakClass lineBreakClass(QChar ch) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4) noexcept;\n"
+ "inline LineBreakClass lineBreakClass(QChar ch) noexcept\n"
"{ return lineBreakClass(ch.unicode()); }\n"
"\n";
static const int SizeOfPropertiesStruct = 20;
+static const QByteArray sizeOfPropertiesStructCheck =
+ "Q_STATIC_ASSERT(sizeof(Properties) == " + QByteArray::number(SizeOfPropertiesStruct) + ");\n\n";
+
struct PropertyFlags {
bool operator==(const PropertyFlags &o) const {
return (combiningClass == o.combiningClass
@@ -2470,48 +2446,45 @@ static QByteArray createPropertyInfo()
// " signed short mirrorDiff : 16;\n"
out += QByteArray::number( p.mirrorDiff );
out += ", ";
-// " ushort lowerCaseSpecial : 1;\n"
-// " signed short lowerCaseDiff : 15;\n"
+// " ushort unicodeVersion : 8; /* 5 used */\n"
+ out += QByteArray::number( p.age );
+ out += ", ";
+// " ushort nfQuickCheck : 8;\n"
+ out += QByteArray::number( p.nfQuickCheck );
+ out += ", ";
+// " struct {\n"
+// " ushort special : 1;\n"
+// " signed short diff : 15;\n"
+// " } cases[NumCases];\n"
+ out += " { {";
out += QByteArray::number( p.lowerCaseSpecial );
out += ", ";
out += QByteArray::number( p.lowerCaseDiff );
- out += ", ";
-// " ushort upperCaseSpecial : 1;\n"
-// " signed short upperCaseDiff : 15;\n"
+ out += "}, {";
out += QByteArray::number( p.upperCaseSpecial );
out += ", ";
out += QByteArray::number( p.upperCaseDiff );
- out += ", ";
-// " ushort titleCaseSpecial : 1;\n"
-// " signed short titleCaseDiff : 15;\n"
+ out += "}, {";
out += QByteArray::number( p.titleCaseSpecial );
out += ", ";
out += QByteArray::number( p.titleCaseDiff );
- out += ", ";
-// " ushort caseFoldSpecial : 1;\n"
-// " signed short caseFoldDiff : 15;\n"
+ out += "}, {";
out += QByteArray::number( p.caseFoldSpecial );
out += ", ";
out += QByteArray::number( p.caseFoldDiff );
- out += ", ";
-// " ushort unicodeVersion : 8; /* 5 used */\n"
- out += QByteArray::number( p.age );
- out += ", ";
-// " ushort nfQuickCheck : 8;\n"
- out += QByteArray::number( p.nfQuickCheck );
- out += ", ";
+ out += "} }, ";
// " ushort graphemeBreakClass : 5; /* 5 used */\n"
// " ushort wordBreakClass : 5; /* 5 used */\n"
-// " ushort sentenceBreakClass : 8; /* 4 used */\n"
// " ushort lineBreakClass : 6; /* 6 used */\n"
out += QByteArray::number( p.graphemeBreakClass );
out += ", ";
out += QByteArray::number( p.wordBreakClass );
out += ", ";
- out += QByteArray::number( p.sentenceBreakClass );
- out += ", ";
out += QByteArray::number( p.lineBreakClass );
out += ", ";
+// " ushort sentenceBreakClass : 8; /* 4 used */\n"
+ out += QByteArray::number( p.sentenceBreakClass );
+ out += ", ";
// " ushort script : 8;\n"
out += QByteArray::number( p.script );
out += " },";
@@ -2521,42 +2494,42 @@ static QByteArray createPropertyInfo()
out += "\n};\n\n";
- out += "Q_DECL_CONST_FUNCTION static inline const Properties *qGetProp(uint ucs4) Q_DECL_NOTHROW\n"
+ out += "Q_DECL_CONST_FUNCTION static inline const Properties *qGetProp(uint ucs4) noexcept\n"
"{\n"
" return uc_properties + GET_PROP_INDEX(ucs4);\n"
"}\n"
"\n"
- "Q_DECL_CONST_FUNCTION static inline const Properties *qGetProp(ushort ucs2) Q_DECL_NOTHROW\n"
+ "Q_DECL_CONST_FUNCTION static inline const Properties *qGetProp(ushort ucs2) noexcept\n"
"{\n"
" return uc_properties + GET_PROP_INDEX_UCS2(ucs2);\n"
"}\n"
"\n"
- "Q_DECL_CONST_FUNCTION Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4) Q_DECL_NOTHROW\n"
+ "Q_DECL_CONST_FUNCTION Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4) noexcept\n"
"{\n"
" return qGetProp(ucs4);\n"
"}\n"
"\n"
- "Q_DECL_CONST_FUNCTION Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2) Q_DECL_NOTHROW\n"
+ "Q_DECL_CONST_FUNCTION Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2) noexcept\n"
"{\n"
" return qGetProp(ucs2);\n"
"}\n\n";
- out += "Q_CORE_EXPORT GraphemeBreakClass QT_FASTCALL graphemeBreakClass(uint ucs4) Q_DECL_NOTHROW\n"
+ out += "Q_CORE_EXPORT GraphemeBreakClass QT_FASTCALL graphemeBreakClass(uint ucs4) noexcept\n"
"{\n"
" return static_cast<GraphemeBreakClass>(qGetProp(ucs4)->graphemeBreakClass);\n"
"}\n"
"\n"
- "Q_CORE_EXPORT WordBreakClass QT_FASTCALL wordBreakClass(uint ucs4) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT WordBreakClass QT_FASTCALL wordBreakClass(uint ucs4) noexcept\n"
"{\n"
" return static_cast<WordBreakClass>(qGetProp(ucs4)->wordBreakClass);\n"
"}\n"
"\n"
- "Q_CORE_EXPORT SentenceBreakClass QT_FASTCALL sentenceBreakClass(uint ucs4) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT SentenceBreakClass QT_FASTCALL sentenceBreakClass(uint ucs4) noexcept\n"
"{\n"
" return static_cast<SentenceBreakClass>(qGetProp(ucs4)->sentenceBreakClass);\n"
"}\n"
"\n"
- "Q_CORE_EXPORT LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4) Q_DECL_NOTHROW\n"
+ "Q_CORE_EXPORT LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4) noexcept\n"
"{\n"
" return static_cast<LineBreakClass>(qGetProp(ucs4)->lineBreakClass);\n"
"}\n"
@@ -2832,7 +2805,7 @@ static QByteArray createLigatureInfo()
QList<Ligature> l = ligatureHashes.value(uc);
if (!l.isEmpty()) {
Q_ASSERT(!QChar::requiresSurrogates(uc));
- qSort(l); // needed for bsearch in ligatureHelper code
+ std::sort(l.begin(), l.end()); // needed for bsearch in ligatureHelper code
ligatures.append(l.size());
for (int j = 0; j < l.size(); ++j) {
@@ -2864,7 +2837,7 @@ static QByteArray createLigatureInfo()
QList<Ligature> l = ligatureHashes.value(uc);
if (!l.isEmpty()) {
Q_ASSERT(QChar::requiresSurrogates(uc));
- qSort(l); // needed for bsearch in ligatureHelper code
+ std::sort(l.begin(), l.end()); // needed for bsearch in ligatureHelper code
ligatures.append(l.size());
for (int j = 0; j < l.size(); ++j) {
@@ -3096,7 +3069,7 @@ int main(int, char **)
"// We mean it.\n"
"//\n\n";
- QFile f("../../src/corelib/tools/qunicodetables.cpp");
+ QFile f("../../src/corelib/text/qunicodetables.cpp");
f.open(QFile::WriteOnly|QFile::Truncate);
f.write(header);
f.write(note);
@@ -3116,7 +3089,7 @@ int main(int, char **)
f.write("QT_END_NAMESPACE\n");
f.close();
- f.setFileName("../../src/corelib/tools/qunicodetables_p.h");
+ f.setFileName("../../src/corelib/text/qunicodetables_p.h");
f.open(QFile::WriteOnly | QFile::Truncate);
f.write(header);
f.write(note);
@@ -3129,6 +3102,7 @@ int main(int, char **)
f.write("#define UNICODE_DATA_VERSION " DATA_VERSION_STR "\n\n");
f.write("namespace QUnicodeTables {\n\n");
f.write(property_string);
+ f.write(sizeOfPropertiesStructCheck);
f.write(grapheme_break_class_string);
f.write(word_break_class_string);
f.write(sentence_break_class_string);